#mod_development
1 messages ยท Page 194 of 1
I might be overusing the whole thing a bit...
like some functions could be local and still work,
This does make my mod accessible to... modding
the whole t = t or {} pattern doesn't make sense if you define the table elements within it
okay
If you make the daikons local
i recommend just going for normal modules:```lua
--- shared/SandboxOptionsSyncing.lua
local SandboxOptionsSyncing = {}
function SandboxOptionsSyncing.foo()
-- do something
end
return SandboxOptionsSyncing
--- shared/AnotherFile.lua
local SandboxOptionsSyncing = require "SandboxOptionsSyncing"
SandboxOptionsSyncing.foo()
You can use
local daikon1 = require "file1"
local daikon2 = require "file2"
Okay, thanks
Technically speaking the module name inside the file doesn't matter -- as long as the filename is rememberable
yeah, the variable names don't matter, only the file name
However - I usually name them the same thing cause I can copy paste the file name for faster require typing
Me lazy no type
Yeah
It takes these arguments, which after reading the code, I have no clue what they are
(player, context, items)
I only figured out that player is the player's index...
As in the Local Co-op index
Are you using the events for onfillcontextmenu?
There's two, one for in world, one for inventory
yes
Events.OnFillInventoryObjectContextMenu.Add(Daikon.ApocalypseBiofuels.PourEthanolContextMenu)
There should be more arguments, no?
I will have to explore the world one too, eventually
triggerEvent("OnFillInventoryObjectContextMenu", player, context, items);
Nope, the event has only those three. The function itself has more
context menu... So the whole thing that appears when you right click the item?
Whatever changes you make to the context menu - yes it's the right click
Items should be a table - but Im not sure if it uses the pseudo stack object inventories use
Which would make items have an items variable 
Let me check
I praised the codebase one too many times it seems
for _, v in ipairs(items) do
---@type InventoryItem
local item = v
if not instanceof(v, "InventoryItem") then item = v.items[1] end
Yeah it's one of those pseudo objects - since your clicking the inventory row
It's feeding you the row clicked
so either a table of items or an item?
No... So you know how each row of the inventory can be collapsed?
Even if there's only 1 item 
Oh, right
Yeah... So items in this case is that group
The header item of the group is items.items[1]
For me it just shows the same item again
never expanded a cabbage?
So it's an array of... What exactly
It's the inventory list entries
But specifically the entry clicked
So if you go to ISScrollingList
It shares the same stuff it does
So items.items = a list of items displayed
The problem here is the argument should be 'inventoryRow'
@sour island @bronze yoke I noticed something: when I wear clothes, it calls ModelManager.loadAdditionalModel
It then says the clothing Mesh code to load. Is there a way to change the arguments passed before it is called and make it say a different mesh?
You can set different item visuals for items
I see...
table 0x396001414
table 0x82321303
zombie.inventory.types.DrainableComboItem@6d970989
zombie.inventory.types.DrainableComboItem@6d970989
zombie.inventory.types.DrainableComboItem@6d970989
zombie.inventory.types.DrainableComboItem@6d970989
table 0x1394398871
zombie.inventory.types.ComboItem@3b567f83
zombie.inventory.types.ComboItem@2a8329f6
zombie.inventory.types.ComboItem@14e519aa
zombie.inventory.types.ComboItem@35b47d0f
zombie.inventory.types.ComboItem@3d96a65d
zombie.inventory.types.ComboItem@e69f480
zombie.inventory.types.ComboItem@327d94ae
zombie.inventory.types.ComboItem@3b567f83
zombie.inventory.types.ComboItem@2a8329f6
zombie.inventory.types.ComboItem@14e519aa
zombie.inventory.types.ComboItem@35b47d0f
zombie.inventory.types.ComboItem@3d96a65d
zombie.inventory.types.ComboItem@e69f480
zombie.inventory.types.ComboItem@327d94ae
zombie.inventory.types.ComboItem@3b567f83
zombie.inventory.types.ComboItem@2a8329f6
zombie.inventory.types.ComboItem@14e519aa
zombie.inventory.types.ComboItem@35b47d0f
zombie.inventory.types.ComboItem@3d96a65d
zombie.inventory.types.ComboItem@e69f480
zombie.inventory.types.ComboItem@327d94ae
table 0x1452896648
zombie.inventory.types.DrainableComboItem@2437cbeb
zombie.inventory.types.DrainableComboItem@5bf1a6ab
These are all results of just doing this
for k,v in ipairs(items) do
print(v)
end```
Idk if this is what you mean - but I made this schoolbag look like an alicebag (only when in a car)
and clicking on various items
The context menus items argument is the group of items you have right clicked
If you want the actual items that is items.items
Yeah, I think I see it now
table 0x1794491859
zombie.inventory.types.DrainableComboItem@9a8a4b0
First one is a saucepan with water in a collapsed state
Second one is the same item in an expanded state
InventoryItems get shoved into a ComboItem class when in the menu
I wanna go back to fixing bugs in the engine already
Yes, for display purposes - items only stack visually in the inventory
They don't actually stack into 1 object
so what you posted earlier is the approach I should take?
This isn't really a bug - more of a argument needing to be more clear
Issue is... if you have selected a whole stack of items, expand it, then the function gets called for all of them
if you call it for each item you'll end up with repeated options
I actually need to check that once I'm home
No, that's what happens in the game already
?
table 0x969276697
zombie.inventory.types.ComboItem@2963d57b
zombie.inventory.types.ComboItem@5c2625fc
zombie.inventory.types.ComboItem@2963d57b
zombie.inventory.types.ComboItem@5c2625fc
zombie.inventory.types.ComboItem@2963d57b
zombie.inventory.types.ComboItem@5c2625fc
zombie.inventory.types.ComboItem@2963d57b
zombie.inventory.types.ComboItem@5c2625fc
zombie.inventory.types.ComboItem@2963d57b
First is clicking on a collapsed stack of 8 sheets
next I expand it and right click
it does the call on all of them, since they're automatically selected
The header of the row is a place-in
The expanded rows should be netting the actual item - correct?
Then my code is probably wrong to some degree
So the Event fires for all of the items at the same time
Actually, no
The event fires once
the event fires once with a table of items
yeah
1 table 0x189851768
1 zombie.inventory.types.ComboItem@ac2b4f2
2 zombie.inventory.types.ComboItem@464000d5
3 zombie.inventory.types.ComboItem@4262bfe8
4 zombie.inventory.types.ComboItem@49505f3d
5 zombie.inventory.types.ComboItem@56aa17c1
6 zombie.inventory.types.ComboItem@102ae369
7 zombie.inventory.types.ComboItem@4760837b
if instanceof(items, "InventoryItem") then
print(items:getFullType())
else
for k,v in ipairs(items) do
print(k,v)
end
end
So I guess I can dismiss the call if there's more than one actual item
That's what happens in vanilla with pouring water
That sounds right, items can be 1 item (sub row) or the header which houses a list
Which I usually have it just use the first one if the header is selected
Hence the items.items[1]
And it's always a ComboItem...
Okay...
print(items)
for _, v in ipairs(items) do
print(v.items[1])
end
on a collapsed stack, this works, and v.items[1] gives me a single item. On a multi-selection, it errors regardless of selecting one or multiple
lf an event which would only run once per life
i see a couple of options, onNewGame, OnCreatePlayer, actually i think newGame is more suited for my use.
onnewgame fires when creating a new character
for some reasons im getting player as nil(passed through params) after player death when im creating a new character. Is it because the prev character is ded?
before a new character has been made? or after
made a character, died and tried to make a new one right after that.
interesting so onCreatePlayer is fired on each load of save
ok so that was just me being stupid, OnNewGame works. I was fetching player inside the function isntead of using the one passed through params.
L
OnCreatePlayer did something weird online vs single player if I recall
then it's prolly due to SP, but definitely loaded twice.
Hey, i'm not really normally the type of fox to ask somewhere for help if I don't feel like I fully grasp what i'm working with, but for the sake of not being that idiot who fumbles around pointless for weeks when they could of asked and gotten a simple answer.
I've spent the last 2 days importing my truesona into Zomboid with the Anthro mod, and actually have had pretty much zero issues.
However, right now I noticed I cant wear jackets specifically, though I remember one or two stray items also bugged.
Context being it crumples up my legs or sometimes my hair on my model in my best guess to prevent outfit piece clipping; Though as far as I'm aware because of the way the anthro clothing items are made, they should be exempt from this happening? The base Anthro mod models seem to work fine with everything.
Happy to provide any information / screenshots needed.
I've looked at my files for the mod and nothing seems different from the base mod configurations/other fursona mods using it. Even remade the mod using the tool to generate up the mod scripts in case I did miss something after all but even with basically official anthro mod item configs for my fursona the deflating issue with my legs when wearing a jacket seems to persist and I don't have any idea where to even start to look at fixing this issue.
Thank you for any help in advance
(note: I'm new to PZ modding specifically)
much of the PZ clothing just kinda masks body parts and shows itself instead
so if the anthro model is different shape then it will require a remade version of the clothing model to fit the shape
@cerulean trail
that said im not a clothing maker
and only have done statics with no animations
may wish to ask in #modeling
as more ppl who work with this stuff will be present
That's not quite the issue
Im not worried about clipping of any sorts
Its the fact that wearing jackets, which are proper models on the player model causes the legs of my model to shrink down to crumpled tooth picks. I'll get a screenshot really quick
oh what ?
Okay, so now its properly just culling the model, which makes a little more sense to me but ??? huh?
huh the player model isn't even a weird shape
I know ive had it also just shrink the leg bones to hell and back though
at least not from this angle
yeah just the head
Which is fine
other stuff shud fit fine if it uses the fem build stuff
ive had like maybe one item cause that to also happen to the pony tail but even then thats like
been a single item and truthfully I dont care lol
depends on how the body is modded in ig
if it doesnt replace he player model but instead is clothing itself
the masks could fuck with it perhaps
then perhaps that jacket masks the slot the legs are using
it is it's own hidden category
Yeah, my thought too, interesting though because base anthro mod seems to not have this problem. So Im not sure what ive done differently here.
i bet it's the uvs
when you wear clothing the game uses a texture mask to hide that part of the body
i'm guessing what's normally the chest on the vanilla uvs is the legs on yours
yeah that's what i was getting at, but less specifically
yeah ๐ญ
Okay thank you lol
gl :|
I have a larger texture because I didnt see it actually causing problems
So that'd be why
UV's are misaligned because of that
gl :)
@bronze yoke glad u were able to get that across with a bit more detail
i had like.. a feel for the issue but didnt know the specific thing to say
lol
ive never made clothing
lol regardless thank you so much
both of u
haha shit this is gonna suck
my fault ๐ญ
I spent hours trying to figure out why my lua code doesnt work
And i still dont know why
Is there any tutorial on how to create simple traits/moodles?
i tried the "moodle framework" with an unsuccessful attempt.
my statsapi has a custom moodle api, it's a bit more flexible than moodle framework's but depending on what you're trying to do it could be harder not easier as it expects you to implement the actual logic yourself whereas i understand moodle framework handles most of it for you
if it's very similar to how most vanilla moodles work then moodle framework would be the easier option
For example
i want to create X moodle which goes bad over time just like hunger or thirst. When the player reads a magazine, the moodle will be better.
yeah, from what i can tell that's the kind of thing that framework specialises in
unfortunately i haven't used it myself so i can't help you more with that
well thanks
i just can't figure out how to configure it myself
like i can't even figure out how to make a simple trait/moodle which goes bad over time
i looked at the game files, downloaded peoples mods and examined them
I recommend you take a look on the SOTO mod by @polar gyro, I've learned a lot from traits by looking into that mod's code
thanks
i'll download withsteam cmd
Don't think it adds moodles tho, but should get you somewhere
i also want to create a trait and implement vanilla moodles so this'll help a lot
It should do the trick ๐
LOG : General , 1693958586023> bugged action, cleared queue ISFishingAction
love this highly detailed error
press f11, opens debugger menu. Scroll through lua files, find yours. Server files are loaded first, than shared and then client ones. Open your file, double click to put a break point on a line of code. Play the game and it should stop right there with all the variables populated, use print statement and variables. Debugger is a really great tool if you start to mess around.
it's great i explored the files but there's so many things that it confuses the hell outta me
local9 is a java variable, their names are lost in compilation
the java function is having an unhandled error
i'll keep exploring the single trait mods
dont think it's trying to mention error just had a hiccup and saving itself by clearing whatever caused the issue. I think i dealt with stuff like this when i was trying to hook into Timed actions.
So my mod somehow broke java
When debugging always try to isolate the snippet causing the issue and then you wanna minimize the lines until you find the exact issue.
i think it's something wrong with the recipe, since that's the part of the code that's having issues
It could be the other recipes
But im not sure how that could break it
Then again
Programming is quite a journey
if you have a decompile you can look at the method's source and see where a local could actually be null
I dont have a decompiler with me right now
So i'll scour through my recipe file
And then get vscode or an equivalent
When I was studying it, I was looking just for one trait specific, so I've opened all files and used Ctrl+F to search it in each one
Eg. The alcoholic trait, it is very complex tho
Maybe look for the trait breathing techniques and other simpler ones
This error usually means that the isValid() function of that TimedAction returned false, maybe look into that
Hey, just wanted to thank you again. I just set some custom maks and that fixed my issue entirely without having to remap my entire UV's. 
edited someone elses code
when the player selects the "addict" trait, will they start off with a bit on their arm?
i swear if looked at that code a couple of mods ago, would be totally blank. Learned a bit along the way.
huuh
thinking about pz modding day 1 ๐
I can see how that code goes
that's the hell day
If a client uses the ModData.request(key), the server automatically sends the requested table to the client that requested?
is anyone here available for commission? ive tried looking on reddit, steam discussions, and fiverr, but i cant find anyone to do a mod for me. its a pretty simple one; i just kind of want a mad max style of cab armor for the w900 semi truck mod. im not sure if you can make it an addon for that mod or just a new semi truck all together. please inquire in my dm's for more details.
Glad :)
The petyarbilt already has smth like that, take a peek, but I understand if not what ur after
Okay
I noticed one of my recipes requires an item i havent added yet
But it's a completely different recipe
Than the one causing java errors
yeah i saw that one, wasnt a huge fan of the design for the cab armor, too rounded for my taste
i like stuff like the one in mad max lol
try asking around https://discord.com/channels/136501320340209664/1125248330595848192
ooo thank you im surprised no ones told me about that
Hello everyone! I want to thank you for all the support with my map. I still haven't finished it. But I have it is thanks to you!
https://youtu.be/-EMKI1d7SX8
Un mod para Project Zomboid que intenta recrear el laberinto de Maze Runner (La Pelicula).
Esto es solo una demo con muchos errores sobre todo ortografico, partes no cargan y etc. pero bueno. Muchos me han preguntado como va el proyecto...
Hey all, I'm doing my first mod and wanted to start out by making one that starts a timer when the player is spotted by a zombie. Is there a check/event for this within the zomboid source?
it looks good too bad the walls cant shift. ill probably try it out! do you have translations for the messages you find?
Making a mod that replaces the main rendering pipeline for more visual effects
Hey does Events.OnGameStart.Add start after player is fully loaded in? i have functions that rely on checking traits of the player.
ye i think so but maybe checkout onCreatePlayer
Does this fire only after in-game character creation?
Like. brand new character
ah for that you need OnNewGame
Also, anyone familiar or worked with moodle framework before?
once each run
nah what im doing sticks with the player and changes. so it needs the player to be loaded first before doing anything'
You want it to work each time after player is loaded?
what issues? if you cant pull player obj then its not what you need
Wait yea it def triggers after player obj is loaded
Ok. so its on an issue on my end, good to know
The common hack is to use Events.OnPlayerUpdate
You can add, then remove if it only has to run once
Or make it run only once in a while
One message removed from a suspended account.
Hey, what do you guys think of this :D
https://steamcommunity.com/sharedfiles/filedetails/?id=3031375140
is it possible to make new command?
chat command yea
One message removed from a suspended account.
One message removed from a suspended account.
One message removed from a suspended account.
Well I don't know about the car battery part, but in write to the UI you mean a message above the player's head?
If it is, idk if the server-side can do that, but if you want the server to trigger it, you can use sendServerCommand(module, command, args) and handle it on the client-side
The easiest command to show a message is player:Say(message)
I need help about the translated versions of the notes. I have the folder structure. but for some reason it doesn't work when I call it. I use getText() but I don't get the full text.
For example
getText('NotesItems_01_intro') and the message doesn't appear. instead "NotesItems_01_intro" appears inside the note.
Do you have any idea why the translation doesn't work for me?
Because 'NotesItems' do not exist in vanilla Zomboid
The game doesn't use Notes files as far as I know.
You should use one of these prefixes for getting translated text with getText() func.
This detail is super important, thank you very much!
Is this snippet from game files?
Actually nvm does look like decompiled code
Yes it's decompiled zomboid code
Hey there, quick question for item:DoParam(), how to add an additional param if there's already one exisiting? I am getting this errror __concat not defined for operands: Item{Module: Base, Name:PopBottleEmpty, Type:Normal} and Tags = SlowScoop
PopBottleEmpty has an existing Tags defined Tags = EmptyPetrol,
Does anyone have an example of how to make specific objects appear in specific places?
Away from the current player position and loaded only once in a while when a new game is loaded.
Tags is a tricky one in that it's held as a list - I could be wrong but once the script is parsed it's no longer a string. What I do to get around this is grab the script items tags using getTags() which is an array, and concat the strings from there.
DoParam(concatedString..","..yourTag) would then work.
Alternatively, if the array is exposed you might be able to simply add it.
In that case you wouldn't use doParam
yeah you can just add to the list
I'll have to clean that up in EHE then lol
are you talking about spawning items through distribution files or just spawning on a square or something?
I want to just place an object in a specific place. I have the following code. But it does not work.
local function setNotaInWorld()
local sq = getCell():getOrCreateGridSquare(3148, 7228, 0); -- place where I want a note to appear
if sq ~= nil then
local sqNote = sq:AddWorldInventoryItem("Base.wicked_lab01_SheetPaper", ZombRand(0.1, 0.5), ZombRand(0.1, 0.5), 0);
if sqNote then
sqNote:addPage(1, getText('News_note02'));
end
else
print("ERROR bla bla bla")
end
end
local function OnNewGame(player)
setNotaInWorld()
end
Events.OnNewGame.Add(OnNewGame);
./mods/MapLaberinto/media/lua/client/AddItems.lua
Are you getting error bla bla bla?
yoo ur the ehe dev?!
this is awesome
the prefixes are a necessary part of the getText strings
thanks for making such a fun mod
Thank you ๐
you can't spawn items in unloaded squares
unless the player spawns next to that area this will fail
Theres two APIs that I know of that can do this.
One uses mapping, the other uses Lua and chunk loading
Rather than square Loading
The idea I have is to place notes. in specific places within my map. to guide the player so that he can find clues that help him find the exit.
This is the one that uses Lua: https://steamcommunity.com/sharedfiles/filedetails/?id=2969455858
you have to wait until the square loads to spawn the item
Oh if you're making it for a specific map, maybe the other one will be easier to utilize
I can't say which will be better for what you need, and I've only used the first myself.
never used that api but even just the overhead from having an event function is significant on loadgridsquare so an api would be well needed there
It doesn't use that event ๐ , actually gets around it by using something the game uses for Iso Objects
Far less intensive
it doesn't even use the event? that's even better
Yeah, I may have to update EHE for that as well
Yeah. That's why in the code I have created an LUA code that did that.
local function LoadGridsquare(square)
-- Your code here
end
Events.LoadGridsquare.Add(LoadGridsquare)```
But in this case it is worse. game crashes on loading
yeah you can easily make the game hang with loadgridsquare and some other rapidly called events
You cannot use prints at all
That's why superb survivors hangs for 5 minutes on boot...
you can print as long as they're conditional
Literally just a print left over
when loading in loadgridsquare gets called tens of thousands of times at once so anything intensive on there will just hang
Yeah even doing simple stuff can be pretty gnarly
That's where avoiding for() would be impactful
local NOTE_LAB01 = "test text bla bla";
local function LoadGridsquare(sq)
if sq:getWindow() and sq:getX() == 3148 and sq:getY() == 7317 and sq:getZ() == 0 then
print('1qX ---->' .. sq:getX());
print('1qY ---->' .. sq:getY());
local sqNote = sq:AddWorldInventoryItem("Base.wicked_lab01_SheetPaper", ZombRand(0.1, 0.5), ZombRand(0.1, 0.5), 0);
if sqNote then
sqNote:addPage(1, NOTE_LAB01);
end
end
end
Events.LoadGridsquare.Add(LoadGridsquare); ```
I guess that shouldn't have caused any issues with the print - but idk what the errors in this were
What does square get window do?
If that's not a thing, you'd be calling an undefined function thousands of times
yeah if this function errors the game will also hang because it prints tens of thousands of errors
I think maybe I'm calling it from the wrong place.
This is the route from where I call it:
./mods/MapLaberinto/media/lua/client/ItemSpawner.lua
Nah youre fine, I just checked, isogridsquare does have a getWindow
It could be that getWindow itself is intensive
And it doesn't seem like you need it?
OK I can remove it to test. but do you think it is well located where it is...?
I wouldn't use this event at all
You're going to be firing a XYZ check for every square around the player that is loaded in as he moves - so even the same square multiple times.
I would recommend the first API linked.
Do you have an example code? how would it be?
Do you spawn things on your map or elsewhere?
Yeah things on my map
You could use MapObjects. It has callbacks for when tiles are loaded.
something like this
https://github.com/radx5Blue/ImmersiveSolarArrays/blob/5b23ea5189f62ed27dddcab53db4c4e552589408/Contents/mods/ImmersiveSolarArrays/media/lua/server/World/ISAMapObjects.lua#L19
OnNewWithSprite is for the first time a square loads
IsoWorldInventoryObject is a IsoObject right?
Obviously you can use already existing tiles on the squares or use one that is special and only serves this purpose to improve performance.
You could place special tile on the map and remove it completely when it is loaded.
Shit, i lost file where i saw all attributes for stove building... such as .litsprite etc. ... can you point me where i can find those??? I tried everything using Notepad++ searching tool and found just nothing.
but this event is linked to the load every 10 min.
Events.EveryTenMinutes.Add(debugAcceptItemFunction)
It could work for me but if the character goes very fast through one of the corridors of the maze. the object may not be in place before the player passes through it.
If you search vanilla files for MapObjects.OnNewWithSprite or MapObjects.OnLoadWithSprite you will find more examples.
This is an excellent idea.
the debug was to troubleshoot new features, nobody reported issues so I can remove it safely
public class IsoWorldInventoryObject extends IsoObject
oh litsprite helped, you mean blacksmith furnace
I found just a little piece of example ... cant remember where i saw almost full list of them.
What attributes have ISBSFurnace or ISStove objects when you building it?
.litsprite is only one that i remembered
BSFurnace?
declaration: package: zombie.iso.objects, class: BSFurnace
anyone want to make like $10 for a mod that disables sprinter's random bullshit player slowdown when they get near you
I'm making a mod based on More Builds Reloaded that will allow you to build most of the objects from Dirk Tiles and DylanTiles. I have dealed with ISDoubleTileFurniture, containers, double windows, doors and walls, but now I have reached the furnaces from barrels. They are very cool and I would like to take into account all possible attributes for them that are possible. Please help me.
Oh thanks a lot. I think this ll help.
I saw that in MBReloaded BBQ is declared as ISStove so i need to experiment with it first.
Nope, i dont need to
I'm having issues with this cause i have no idea what i'm doing. in the placebedsheet function it doesn't seem to recognize bed as an isobject giving me attempted index: getSprite of non-table: null as error and any other function i try to use on it. any help appreciated
local function PlaceBedSheet(player, bedSheet, bed)
local bedName = bed:getSprite():getName()
if bedName == "furniture_bedding_01_0" then
bed:setSprite("furniture_bedding_01_2")
end
player:getInventory():Remove(bedSheet)
end
local function addPlaceOptionToBed(player, context, worldobjects, test)
local bed = nil
local player = getSpecificPlayer(0)
for key, value in pairs(worldobjects) do
if value:getProperties():Is(IsoFlagType.bed) then
bed = value
for i = 0, player:getInventory():getItems():size() - 1 do
local bedSheet = player:getInventory():getItems():get(i)
if bedSheet:getName() == "Black Blanket" then
local optionBed = context:addOption(getText("Place Bed Sheet"),player,bedSheet,bed,PlaceBedSheet)
end
end
end
end
end
Events.OnFillWorldObjectContextMenu.Add(addPlaceOptionToBed)
Hello, In the scripts how can use 2 textures in one item model?
you can't
attempted index: getSprite of non-table
weird, shouldn't it say not a function instead because the function is in wrong parameter order?
also bedsheet would be an InventoryItem, what you want is bed:getTextureName()
getTextureName is getSprite + getName with a nil check directly in one call
wait, you probably want to use getType instead on the bedsheet?
what is the proper parameter order? and i didn't catch that getTextureName much easier way of doing that. and yes i getType is what i was looking for i could only find getName at the time and was confused why it was giving me display name
Idk if this is the right place here but a guy named "Glytch3r" (a lot of modders here probably know him) is currently sending scam links to people on Steam. Dont use the login option on the links he sends. You will lose your steam account.
Note the double "i" in the steamcommuniitys. Maybe someone with more connections in the community can make an announcement about it or something. Someone so known as him sending such links might make some people take their guard down. Even though I quickly realized it was a scam even I clicked on the link initially
what is the proper parameter order?
function ISContextMenu:addOption(name, target, onSelect, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10)
good lord
i have my issues with him as many of us do, but i didn't expect this - maybe he fell for one himself and- yeah
just wanted to put this out here as most steam accounts usually have bank or paypal accounts linked to them etc. so this really is no joke. And yeah I was a client of him. I have some some wild stories as well lol
ok so are each of the param variables what is being passed to the function in onSelect?
the order is a bit weird as you see, the onSelect function will be passed the target and up to 10 params.
option.onSelect(option.target, option.param1, option.param2, option.param3, option.param4, option.param5, option.param6, option.param7, option.param8, option.param9, option.param10);
is there a way to give a crafting recipe a custom icon on the context menu
or do i need to have a custom context menu option for that
ie
can i make 'crucify' and 'prepare to throw' have the dead rat icon
I could suggest instead of making a new option, get the option and add an icon. Whatever seems more efficient.
option.iconTexture = bulbPart:getInventoryItem():getTex()
thanks i was trying to find these functions for their parameters before because i had no idea what the parameters were. Now i think i fixed all of that and the log is telling me that my bed object in placeBedSheet is calling nil. which i suppose is getTextureName doing that. which i would assume means that it does not have a texture and i'm pretty sure its lying casue i can see it
you know this is a step up though atleast it knows its an object now
you may wanna report that to mods, assuming you did already?
nooo i want 50$ i'm a poor broke boy
hope y'all are ready
lol sick. go squirrel stapler route allow us to staple rats all over ourselves
I like this idea
update 3.0 may include something like that
must appease the rat god
whats the mod name? i need the rat
lol i love it. i got an unsued pentagram tile it would be sick to sacrifice stuart's soul
I would love that
because
i have this image
having a pentagram in the middle would be PERFECT
ive also just always wanted a pentagram tile
i made a sorta complete list of available items (display name to type mapping) in pz for some usecase i had. Anyway imma share it if anyone might need for any reasons. https://github.com/ankitsmt211/PZ-items/blob/main/itemMapping.txt
Hi guys. I'm currently working on a small mod that allows you to make Improvised Tools with Sturdy Sticks (Stone Knife, Stone Axe, Stone Hammer)
The mod already works but there's one issue. My mod is only adding more recipes instead of modifying the existing ones.
Can someone lend me a hand on how I could be able to modify the vanilla recipes instead of just adding new ones on top?
You can do Overwrite:true,
Or override
Not sure which one is correct
But it should override the recipe with the same name
Can I share the code? Im VERY new to LUA so I wouldn't know in which part I should place the Overwrite function
it's my first mod actually
that's how little I know lol. I thought i was modifying a lua file with that since i'm using Notepad++ I just can't tell the difference
`module ChippedStone
{
imports
{
Base
}
recipe Make Stone Knife
{
TreeBranch/WoodenStick,
SharpedStone,
RippedSheets/Twine/RippedSheetsDirty,
Result:FlintKnife,
Time:80.0,
Category:Survivalist,
}
recipe Make Stone Axe
{
TreeBranch/WoodenStick,
SharpedStone,
RippedSheets/Twine/RippedSheetsDirty,
Result:AxeStone,
Time:80.0,
Category:Survivalist,
}
recipe Make Stone Hammer
{
TreeBranch/WoodenStick,
Stone,
RippedSheets/Twine/RippedSheetsDirty,
Result:HammerStone,
Time:80.0,
Category:Survivalist,
}
recipe Create Spear
{
Plank/TreeBranch/WoodenStick,
keep [Recipe.GetItemTypes.SharpKnife]/SharpedStone/MeatCleaver,
Result:SpearCrafted,
Time:100.0,
OnCreate:Recipe.OnCreate.CreateSpear,
Category:Survivalist,
OnGiveXP:Recipe.OnGiveXP.WoodWork5,
}
}`
where should I place the Overwrite thing?
Overwrite should be in the recipe block
Like this? I'm sorry I'm making so many questions, I have no idea what I'm doing
recipe Item
{
Other values n' stuff
Overwrite:true,
}
Should be noted that only effectively works if the recipe is uniquely named. Using overwrite on recipes with shared names only applies it to the first one found.
Same with obsolete.
So, actually, Lua is more reliable for modifying existing recipes.
Thanks
My mod is kinda small and only intended for those specific recipes, I think I should be OK
appreciate the support guys
What is it you're trying to do/change?
Make it so you can use Sturdy Sticks to make improvised tools and spears
stone knife, axe, hammer, and spears
I see
there was a mod that did that in the workshop but i'ts obsolete, and it still uses the old spear ID
Those recipes should be fine then.
awesome, thanks
the override:true, thing must go on each block, right?
IT WORKED, thank you so so much
i only see 1 recipe now
Does anyone know of a good way to make certain foraged items only appear when wearing a specific item? I'm currently trying to work out a way but I don't know (or think) it will be a good way lol, so I'm just trying to see if anyone's already worked this one out yet
anyone have an idea of why
local getCrucify = context:getOptionFromName("Crucify Stuart Little") or nil
local addCrucify = StuartMenu:addOption(getCrucify.name or "Crucify Stuart Little", isStuartLittle,
(getCrucify.onSelect) or function ()
console.log("test");
end, getCrucify.param1 or true, getCrucify.param2 or true, getCrucify.param3 or true,
getCrucify.param4 or true, getCrucify.param5 or true, getCrucify.param6 or true, getCrucify.param7 or true,
getCrucify.param8 or true, getCrucify.param9 or true, getCrucify.param10 or true)
addCrucify.iconTexture = getTexture('media/textures/item_CrucifiedStuartLittle.png');
if not (getCrucify) then
addCrucify.notAvailable = true
end
Is coming back with a null table error?
i tried to check for every null value I could using that method
basically what i'm trying to do is take all my recipes because theres a lot
copy them into a new submenu
then remove them from the vanilla menu
but i'm having trouble passing the paramaters if the option is not available from the start
i basically want all the recipes to show in the submenu, but only be enabled if the default function is available (if it already existed)
if that makes sense
nvm
got it figured out
now trying to figure out how to copy the default recipe tooltip to the new option
addCrucify.toolTip = getCrucify.toolTip
cool, that works
do you know the default syntax to set a tooltip?
addCrucify.toolTip = getCrucify.toolTi or false returns error
maybe nil is better than false then
found the default tooltip code
i think i found the way to do it
loading in now
if (getCrucify.toolTip) then
addCrucify.toolTip = getCrucify.toolTip
else
addCrucify.toolTip.name = "Crucify"
addCrucify.toolTip.description = "Not enough materials"
addCrucify.toolTip.footNote = "- Materials Needed -"
end
recipe option would be added here I think ISInventoryPaneContextMenu.addDynamicalContextMenu, ISRecipeTooltip is the global variable for the local CraftTooltip
i'm confused, what would I use that for?
dang
addCrucify.toolTip = getCrucify.toolTip only works if it's a single item
if there's multiple stuart littles, so the crafting recipe goes to the submenu, it doesn't get the recipe

i cant get any more info from a bed object. everything i've tried returns nil. i wanted tile data like its group name but getTile() gets me nothing. ill have to resort to just sprite names which will be hell
actually adore you
our fallen soldier
what was the issue here?
i was passing parameters incorrectly
local getCrucify = context:getOptionFromName("Crucify Stuart Little")
local name = (getCrucify and getCrucify.name) or "Crucify Stuart Little"
local onSelect = (getCrucify and getCrucify.onSelect) or function ()
return
end
local param1 = (getCrucify and getCrucify.param1) or false
local addCrucify = StuartMenu:addOption(name, isStuartLittle, onSelect, param1)
addCrucify.iconTexture = getTexture('media/textures/item_CrucifiedStuartLittle.png')
addCrucify.toolTip = getCrucify.toolTip
if not getCrucify then
addCrucify.notAvailable = true
end
revised code looks like this
i'm trying to figure out a way around the submenu thing and setting a default tooltip currently
local spriteGrid = Context.farmObject:getSprite():getSpriteGrid()
you mean like this?
are you trying to replace the option? Why not just change properties of the option?
basically i'm trying to take the "crucify stuart little" default recipe option shown here to be moved to the "Stuart Little" submenu
is there a way to change a context menu's location via properties?
ah
you'd need some manual code
this is what ive got rn
something similar to
local function addOrGroupContextOption(context, name, ...)
local subMenu
local identifier = "M' "..name
for i,option in ipairs(context.options) do
if option.name == name then
if not option.subOption then
local newOption = context:allocOption(name)
newOption.id = option.id
context.options[i] = newOption
subMenu = context:getNew(context)
context:addSubMenu(newOption,subMenu)
option.id = 1
subMenu.options[1] = option
subMenu.numOptions = 2
else
subMenu = context:getSubMenu(option.subOption)
end
break
end
end
if subMenu then
subMenu:addOption(identifier,...)
else
context:addOption(identifier,...)
end
end
local function addOrReplaceContextOption(context, name,...)
local identifier = "M' "..name
for i,option in ipairs(context.options) do
if option.name == name then
table.insert(context.optionPool, option)
local newOption = context:allocOption(identifier,...)
newOption.id = option.id
context.options[i] = newOption
return newOption
end
end
return context:addOption(identifier,...)
end
to only remove an option, there is context function to remove it
that will just give me the grid coordinates of a sprite group right? it's very useful and i will be using it. i just wanted to group them into categories easier but i think i'll figure that out
it's for tiles that have multiple objects on separate squares.
ah so that'll give me a table of all of the sprites in relation to that one thank you
Bit of a newbie question, but can you do local character = self.character; for functions in the server folder?
If your โselfโ is defined, sure but if not then you can get the player with getSpecificPlayer(0) for mp compatibilty + put a isClient() check to only have it work for client
Client runs (currently) everything
Okay, and just so I'm understanding getSpecificPlayer correctly will getSpecificPlayer(0) return the client player or would it get, like, the first player indexed in the server?
Sorry if I phrased that wrong, still figuring this out lol
Its always the client
Alright thanks!
i think a lot of people here are confused about getSpecificPlayer, i've seen this a couple times recently
How does the indexing for players in mp actually work?
it's not for multiplayer compatibility, getPlayer() functions exactly the same in multiplayer
it's for splitscreen, if your code only uses getPlayer() then your code only affects the most recently added player
if you just drop in replace it with getSpecificPlayer(0) you don't actually solve this problem
as for multiplayer player indexes, online ids are the same across all sides
all other indexes are used exclusively by the client that player comes from and are likely undefined for remote players
So the only reliable way to grab the same player from multiple clients would be through online ids?
yeah
Thats pretty neat, I didnt actually know there was splitscreen support! Truth be told, I think the reason I asked my question in the first place wouldn't actually work, but I'm glad it led to me understanding the function better in the future!
@fast galleon Thank you. I got it working thanks to your code
getSpecificPlayer should be used in a loop to affect all local players, and in a lot of cases i've seen getting the player object is just redundant to begin with (timed actions already know their player, context menu already knows its player, etc)
getSpecificPlayer only works for players that are in the same cell?
in most cases splitscreen support just isn't a priority so not going to that length is fine, but dropping getSpecificPlayer in to replace getPlayer doesn't really improve compatibility
getSpecificPlayer only gets the 1-4 characters from this client
How does it know which players those should be?
Does it just pick the nearest ones in mp?
In coop its obvious
it's the ones playing on that computer
full support in mp
So how does it pick a player for mp? Does it pick them by their online ids? Or better formulated how does it assign the ints to players locally?
Cause the client is always 0 even if its not the case in mp
0 is the client and there aren't indexes for other online players?
the first player to start playing on that client is 0, second is 1, etc
players from other clients are not included in the list it uses
So you couldnt then call getSpecificPlayer(2) in mp without erroring?
Unless you were in mp and also splitscreen LMAO
I suppose I odnt know if you can actually play splitscreen in mp
you would get the third splitscreen player if they exist
Can you play splitscreen in mp?
you can - and the fact that literally no mods support splitscreen caused so many security issues that there's now an option to turn that off for the server
Im just thinking: who would want to play splitscreen in mp?
Fascinating! See, thats the sorta thing I woulda never known about unless I started looking into mod development
Your pal who can't afford the game or an internet connection or a pc so has to couch-coop with you or something i guess?
Then wouldnt you just play coop instead?
Cause coop and mp are two different things in pz if im not wrong
But what if you also wanted to play with your friend in another country?
idk, i didnt even know this functionality existed, im just making stuff up
It's such an esoteric scenario
Its the most fringe case i can think of
yeah, I imagine its only really brought up by people trying to exploit or whatever
well i don't think it was too much effort to support
it might have been harder not to support it even
all of the vanilla code is structured around splitscreen
but i like to imagine there is like one guy who got disappointed because they couldn't play on their buddy's favorite server with them while they were over at their house or something
Is that a thing that's happening?
Inventory will all happen server-side
Yep thatโs great
I've found no way to modify an item's Tags with Lua... There's only a Getter, not a Setter... Anyone experimented with it in the past?
I wonder if I should be writing my stuff differently in preperation or if it'll be as easy as dragging all my lua client files to the server file. I suppose I can't test anything if I don't write things for how they work now but still good to know
you don't need to set it
You could getTags .. your Tags and then doParam
objects are passed by reference
if you get the tags object, add a new tag to it, you are done
Oh, really?
yeah! I actually just did that a couple days ago, looks something like
local tags = item:getTags()
tags:add("TagToAdd")
So I can append stuff to the end? Nice, I can edit items to be ethanol-eligible while maintaining mod compatibility
Oh yeah, it's an ArrayList
Yeah! Mod compatibility was also the reason I was figuring it out so it's nice that its avaliable
So, best I do that in Shared, right?
yep
Alright... I guess I can safely go back to rewriting the water pouring scripts to pour ethanol
How do you spawn a zombie with specific clothing?
"belittle stuart little "
"crucify stuart little "
that went from 0 to 1000 LMAO
better question, where do you find/make outfit IDs?
quality content ๐
you can check the list in debug spawn zombie UI
media\clothing\clothing.xml
that's where outfits are defined
my goth backpacks mod or backpack flags mod adds new simple outfits that are easy to follow if you want an example
is there a way to search the closest tiles for objects other than to go through all of the isodirections and checking them ?
Thanks for the help, but i have to return to the old question now, what i found was some outdated stuff
is it possible to spawn a zombie with specific clothing, and if so, how?
update: sorry might be wrong mod
- get all objects
https://projectzomboid.com/modding/zombie/iso/IsoObject.html#getSpriteGridObjects(java.util.ArrayList)
It needs an array so you would need to create that.
***
I think you might find this mod interesting to check. When adding options it uses vanilla function to get all objects of gridlist and checks if all objects exist or if it's partial / broken.
https://steamcommunity.com/sharedfiles/filedetails/?id=2964456536
https://steamcommunity.com/sharedfiles/filedetails/?id=2971843681
I messed something up LMAO
I think I know how to fix it, just thought it was funny
It was actually a little spooky this late at night (or, well, it's technically early in the morning but i've been up all night and it's dark in my coding dungeon rn)
Anybody know if adding a ReplaceTypes pair that can't be fulfilled(For example EthanolSource WaterBottleWithEthanol) breaks the game somehow? I don't even know how to create my EthanolSource yet
i need to know all of the exact uses for stuart little
What's an event that runs early to modify items?
Probably before the game starts to load a save.
Maybe check OnworldInit
Sorry a bit of a noob question, but how do you call built-in lua functions like math?
tried return tostring(random_gender_and_skincolor[math.random(1, #random_gender_and_skincolor)])
But it says object tried to call nil in functionname
Thank you haram gaming
mind that it runs 0-N while things in lua run 1-N
so in many use cases u wanna +1 to the result
when using it to index into things for instance
Hello,
quick question, why do some filenames in lua scripts start with "IS"?
IndieStone is the company that made PZ
Consider it a finger print
Haha I thought it was too!
Hello everyone, I'm new to working with mods, and I'm trying to translate a mod into my "PTBR" language, but I'm having a problem when translating a mod's description. I create the translation but it doesn't appear inside the game, I've done it with some other mods but this one in particular I'm not getting it, could someone give me a hand?
how do you normally translate a mod description?
I achieved! the "Tooltip" was directly in the script and that's why it wasn't translating, I corrected it and now I managed to create the translation!
ty for answering!
Heyo! Looking to break into modding PZ, was wondering if there are any tools, extensions, etc. to help me get started with the lua side of things
I've got plenty of experience with Lua itself, just looking to see if there are any toolchains, packages, extensions, etc.
you can get typings by loading this project as a library in your ide https://github.com/asledgehammer/Umbrella
there's an extension for zomboid's item/recipe/etc format for vscode, otherwise i don't know of anything
Caused by: java.lang.RuntimeException: unknown location "JawStab"
local mark = zombie:getInventory():AddItem("Base.ScreecherMark")
zombie:setWornItem("JawStab", mark)```
isn't JawStab a vanilla location
but even if it isn't, the mod i am working with does it via attached weapon def
AttachedWeaponDefinitions.ScreecherMark= {
chance = 100,
outfit = {"Screecher","ScreecherNoKatana"},
weaponLocation = {"JawStab"},
bloodLocations = nil,
addHoles = false,
daySurvived = 0,
weapons = {
"Base.ScreecherMark",
},
}```
which would lead one to think that the location exists fine
unless i need some kind of more complex path for the weapon location in this context
appears to be fine, vanilla just does "Back" in places
body locations and attached locations aren't the same thing
how can i manually attach it then
grabbed this ty! but man the Java/Lua thing is confusing me
use setAttachedItem(String location, InventoryItem item)
do I have to really worry about Java when modding in Lua?
at least to some minimal extent
sort of
yeah you'll be playing with java objects most of the time
nah i wanna do more than just scripts
then yeah u'll at least have to learn the basics of interop
okay sick
u dont need to straight-up know java or anything tho
are there any resources for that?
biggest thing to know is java indexes are 0-based, lua is 1-based
you don't really need to understand java, though understanding some of the theory might help if you don't have a background with other languages
I know Java too haha but would rather stick with one language
okay API love that
basically kahlua exposes certain classes and functions to lua
and lua can mess with those
since you know java i recommend decompiling
and then reflect to get access to a few it doesn't (But not just any)
yeah u can reference the source to understand what functions do then
a lot of questions get asked here that can be answered by simply actually checking what a method does
okay I guess what I'm specifically asking about is how the Java code and Lua code interface
never heard of it ๐ญ
they chose which things to allow lua to see/use
it's outdated and obscure
absolutely
it uses metatables to emulate classes, if you've done oop in lua before it should be familiar
yeah I've worked professionally with Lua for years so very familiar with this
great, you should be able to pick things up easily then
zombie.Lua is for stuff that was written specifically for lua usage, most of the stuff in the zombie package is exposed
u can get most of the info u need from the API website(s) but they are out of date and dont always tell u what a function does (usually dont) and def dont explain the args
at which point the decompile is helpful
the website isn't too outdated anymore
well yeah the code got stagnant
there's more than one site tho
some are still 41.65
the site they're on already is the one i'd recommend
just be careful if u end up googling for it multiple sites will come up
yeah classic
like "zomboid isozombie" etc. i tend to google to find stuff faster
it's 41.77 but i haven't noticed a huge amount of api changes, there's a community run site for 41.78 but it has a bit less documentation
41.78 wasn't huge on api yeah
calling it documentation is very approximate but
they broke getOnlinePlayers on purpose (returns empty for non-admins or non-server)
and changed some java things for security that i disagree with
bigget differences in that build imo
there are a few methods with documentation and you at least don't need to decipher what the parameters are supposed to be (in theory)
the other site will show you parameters like boolean bool1, IsoZombie zombie1, it can be really difficult to decipher
I guess I'm struggling with the absolute basics of like, how do I actually interact with the API?
you just type class names and function names either from the base game's lua or from the java
as if they were just in scope
cuz they are
the special exception is any method in zombie.Lua.LuaManager.GlobalObject can be called directly
ah yes
e.g. getPlayer() not GlobalObject.getPlayer() as it would be with other classes' static methods
i feel that it's not actually exposed as a class
cool I think I'm starting to get it haha
will also help to inspect others' mods and the basegame code
find something similar to what u wanna make
poke thru it
yeah that's what I'm doing atm, poking through some mods I like and seeing how they work
i might skip making mods and just create tools first haha
I miss my old workflow
I cant seem to get this working
this is what the directory looks like
It's only adding type hintings for files that are open
Oh do I have to require in first?
i don't really know why that doesn't work, but adding the umbrella folder to the lua extension's library setting does
i don't use vscode myself so i can't be too sure
do you use IDEA by any chance?
yeah!
I was gonna try to use it as that seems to be the default, but its Vim plugin is too slow for me ๐
might be making this harder for myself
i'd stick to vscode, idea's lua plugin is garbage
if you're more comfortable with idea then it might be worthwhile using it instead (though there are caveats to using umbrella with it) but overall i'd recommend vscode
I'm definitely more comfortable with vscode so happy to hear that advice!
It looks like the language server wasn't preloading Umbrella's stuff because they were submodules
so i just deleted the .gitmodules
hacky solution but will do while I'm learning!
ty for your help everyone โจ
How to make/edit maps in PZ?
We have a #mapping channel. The gist of it is You use TileZed program
didn't saw that, even though it's 2 rooms below
and dirk's tutorials on mapping, solid stuff.
Do translation txt files work like the sandbox options txt files, as in they're appended to the big array if they don't specifically overwrite a value?
how's the pouring liquids thing going on? any progress
if i understand your question, yes
Can you spawn blood on the floor? if so how?
What about ambient sound? i want to play some of the vanilla ones.
Well, I'm seeing the initial Pour Into Option
No sub-items yet but I'm working on it now
After that it'll be doing the actual pouring action
might wanna checkout soundmanager i think
sounds great
Thanks. So I don't have to worry about deleting all translations by trying to add my own
Also... is OnGameBoot the earliest event that gets called?
yeah, they aren't file overrides or anything
probably
there could be specific system init events that fire before that but i'm not aware of it
Alright. Suppose it's good for me. Wanted to patch items as early as possible in the game load while still making it an event, so the table of items to patch is externally appendable
if you do it OnInitGlobalModData you'll be able to access sandbox options if that appeals to you
I don't need them in this case, I'm already aware of that
for _,item in ipairs(eligibleFuelItems) do
--check if item is a partially filled item to create the other item's tooltip. Then move to a different function
if instanceof(item, "DrainableComboItem") then
local subOption = subMenu:addOption(item:getName(), items, ISInventoryPaneContextMenu.onTransferWater, ethanolItem, item, player);
local tooltip = ISInventoryPaneContextMenu.addToolTip()
local tx = getTextManager():MeasureStringX(tooltip.font, getText("ContextMenu_EthanolName") .. ":") + 20
tooltip.description = string.format("%s: <SETX:%d> %d / %d",
getText("ContextMenu_EthanolName"), tx, item:getDrainableUsesInt(), 1.0 / item:getUseDelta() + 0.0001)
subOption.toolTip = tooltip
else
subMenu:addOption(item:getName(), items, ISInventoryPaneContextMenu.onTransferWater, ethanolItem, item, player);
end
end
I was hoping I could use the vanilla pouring action, but... That makes the character Reverse Jesus
They turn alcohol into water
Gotta have to write my own fluid transfer code
Maybe I can reuse the timed action at least
IT works
There's just... two issues
One is that items that are full still show up...
Two is that I still have a lot of copied over vanilla code... Which works, but it's not pretty
Hi guys. I need guidance on where (in the code) to look for the stealth mechanics.
I would like to understand how feasible is to make furniture to also affect the player vision cone and also the zombie sight. I would say is impossible due to it being in Java but MAAAAAAAYBE there's a chance?
afaik, java for stealth. except for isoPlayer:setZombiesDontAttack and isoZombie:setUseless but those are not realy stealth related and have unwanted effects on gameplay that are hard to cope with.
for sure java only for vision cone
Supposed that. Sad. That's what missing to sneaking
Hey guys. Thanks for the help with my last mod.
I'm working on something new. I'd like to know how you create mod dependencies and mod modules for the workshop.
Like, when you see that someone else's mod is necessary to run another, and then you can have several sub-mods to choose from in game
mod dependencies are just a require=ModA,ModB,ModC in the mod.info, no spaces between ids
submods are just separate mods all placed into the Contents folder when uploading
cool, thanks mate!
anyone knows where can i find code related to "picking up items" ?
Hey all, is there a guide for adding UI Elements?
Hey y'all, idk if y'all know this but. You can highlight objects without doing it in a render function.
instead you can toggle an IsoObject (or at least a floor) highlight like so:
square:getFloor():setHighlighted(SafehouseMarkers.highlighted, false);
I was under the assumption from my research that setHighlighted only worked if you did it per frame. However, something I didn't notice at the time is that the setHighlight function has an overload, for a variable named "renderOnce"
with no second variable (in this case a bool) provided, it defaults to true, which means your highlight lasts for only one frame or so. if you set it to false, it behaves intuitively.
Figured this could help someone down the line. So just listing it here for posterity
How unethical would it be to make a โmodpack loaderโ which would let modpack creators define a list of mods to load and configs to match? Iโm concerned it could be used to make modpacks without mod author permission, but it could be a fun project (not to mention one I could make use of)
Guys I have an entire model for both back seats,how shhould I assign the model???
Like should I just cut it so I have two different models for both back seats?
one model for each script part makes sense
Unless you have another way to hide it.
Yes,I was thinking to this but it will create confusion
I dont have any other way tho
ill send a ss wait a sec
this are the backseats and it's an entire model basically
if i assign this model to both the rear seats
and i remove one
it would still look liek both of them are there
I think best way would be to uninstall the other seat too when any of them is removed.
hmm,yes,I don;t have any scripting knowledge regarding lua,I only know c++
Ill try tho I think
A part parent is mainly used for syncing animations, perhaps it's something that can be used in this case.
* e.g. You add the seat as main part and 2 children just for the seat areas. Or if it works, you can have one seat for parent part and one as child.
** seats are not assigned to part but to vehicle, so it can be done with one part? In script only the container would be affected by the seat.
hmm
another question
to add individual headlights,I gotta add the templates first,right?
I'm thinking of modifying the game files so heavy-duty armor and clothing doesn't take damage from zombies. Stuff like chain mail and kevlar. How would I do this?
I'm not certain, but I think setting "CanHaveHoles = false" is all you need to do for each item.
Thanks, where would I find that in the files?
is there any way to make new command for server?
can you spawn blood over furniture or terrain?
what do you mean ? like a command that you can type in chat as an admin ?
yeah
if you help i'll be very grateful
I'm not that particularly experienced at that, but I can think of a way
I think that you can write a function that will be triggered on each chat update, which will look for what was said in chat(which will be your command i.e /kill), and then do what it has to do.
this is only the general framework though, I think i might be able to help if you get started
there is 2 lua events OnAddMessage and OnAdminMessage, i tried but it only work with messages like /say message
ohh you mean commands like
i mean entirely independent commands like /safehouse or /faction
I guess there was a lua file that handled those commands, I'll try to check it and maybe it can be reverse engineered
i want just custom command like when admin type /command it prints hello in log
and you want it to be independent from /say
yes
i just want to make commands like default /"name of command"
got it, im trying to think of a way
@vapid quest i guess you can use https://pzwiki.net/wiki/Lua_Events/OnClientCommand to attach it to an event
thats another event just to connect client and server with some function, don't it?
well its been a while but i saw some mods using that for custom commands
ok but what to do now? how to use this for commands?
https://zomboid-javadoc.com/41.78/zombie/commands/serverCommands/AddUserCommand.html
all i can think of is just trial and error, maybe this can help a little
Javadoc Project Zomboid Modding API declaration: package: zombie.commands.serverCommands, class: AddUserCommand
i tried to use this but have no idea what is udpConnection and why theres a string
Well i dont know either, i'll try to look if I can find that mod that adds a command of its own. I guess it will be helpful, will inform you if I do.
ok, thanks you a lot
i didnt help much but thank you as well lol
i can try to do something with onclientcommand, if it'll work i'll say you
alright, i've found a mod that digging in on it could help. will send it from dm
It's not for adding custom commands. It's class for server admin command '/adduser <player> <password>'
insert drake teaching laptop gif
In the vanilla files, in media/scripts/clothing, every hat in clothing_hats.txt has the CanHaveHoles property set to false.
I found it, thank you. I had to add the line "Canhaveholes = false" to most of them. I was able to submit the mod to Steam workshop and subscribed to it to make sure, but I don't see it in the mods tab for the game. Any ideas?
Do I need to write a Lua file for a mod that adds new (already existing in the games code) variables to a mod's txt files?
no, but modifying items through lua is safer than editing the txts
I edited the txt files but saved as, so the original files are still present, and hopefully the new files will change the true/false code
I got the mod to appear in the game. Just have to make sure the values are being changed.
Hey, is there a way i can access the vanilla map cells? i want to modify some of them but i want to retain their original structure
somebody decompiled the vanilla map, it doesn't seem to be pinned but if you ask in #mapping someone probably has it
So I went to testing the armor that I changed so that it wouldn't get holes in it. It's still getting holes so something is missing. I don't want to save the entire mod twice, just trying to make a patch/data value change
You're gonna want to override functions in ISChat.lua
Really should only need one. Its name escapes me at the moment, but you just need to intercept the command handling, check for and handle your command, and defer to the original if it doesn't match (to try to be compatible with other mods that override it)
update: now at my computer to check; it's ISChat:onCommandEntered
I'd like to interact with mechanic responsible for picking up items on double click, is it some timed action i need to look into? Suggestions?
You're referring to double click in the inventory, right? ISInventoryPane.lua has ISInventoryPane:onMouseDoubleClick
not the inv, but like when the items are in the world. You double click to pick em up. Although you could say containers ig.
It's referred to as the "loot inventory" in code, I believeโwhat I really intended to ask was whether you were talking about clicking on objects in the world, because I didn't recall that being a thing ๐
ah so ISInventoryPane:onMouseDoubleClick this is it right? thanks
but how to detect command, also what if i need few arguments for command
Did you look at the vanilla code that I mentioned?
sorry, i can't to do this now
That would be the place to start
ok, i'll check it, thanks
Hey I generated a heatmap with possible sledgehammer locations but I can't really test it's accuracy as I am not that familiar with all of its locations, does this map make sense to you? I know the fire station in rosewood is not showing as a possible location lol
Can lua files change true/false values?
Ive been trying to get the game to detect if the player is in a car but it keeps returning errors, anybody know why? Print(getPlayer():isSeatedInVehicle())
capital P?
otherwise, what's the error?
the capital p seems like the issue
the only other reason this should be able to error is if it's being called before a player exists
omg
thank you
ill be back in a second with results
it works
holy shit ive been trying to fix that code for 2 hours and it never occured to me that my print was capitalized
thank you
Hey guys. Currently working on a mod to change some values for Capacity, weight reduction for some bags.
I don't know what I'm doing wrong but the game is crashing when I load my mod.
These are the files i'm changing and I made sure I didn't place an item from one of them into the other, so I have no idea what could be causing a crash
I literally just copied the data from the game files, put it into my own mod and changed some existing values, didn't add new items, didn't add functions or nothing
so you are just pasting the recipe from the text file in game and pasted it into your own text file?
what did you change in your file
weight, weight reduction and carry capacity for a lot of containers
and the weight of 2 items in the hats file
what is the difference between the clothing_bags file and the newBags file
Which file stores the Non PvP/Safe zone information?
so i checked this and have no idea how to do this
part of code:
local chat = ISChat.instance;
ISChat.instance:unfocus();
if not command or command == "" then
return;
end
local commandProcessed = false;
local chatCommand;
local chatStreamName;
for _, stream in ipairs(ISChat.allChatStreams) do
chatCommand = nil;
if luautils.stringStarts(command, stream.command) then
chatCommand = stream.command;
elseif stream.shortCommand and luautils.stringStarts(command, stream.shortCommand) then
chatCommand = stream.shortCommand;
end
if chatCommand then
if chat.currentTabID ~= stream.tabID then
showWrongChatTabMessage(chat.currentTabID - 1, stream.tabID - 1, chatCommand); -- from one-based to zero-based
commandProcessed = true;
break;
end
chat.chatText.lastChatCommand = chatCommand;
local originalCommand = command;
command = string.sub(command, #chatCommand);
if command ~= "" and command ~= " " then
chat:logChatCommand(originalCommand);
end
chatStreamName = stream.name;
break;
end
end
if not chatCommand then
if luautils.stringStarts(command, "/") then
SendCommandToServer(command);
chat:logChatCommand(command);
commandProcessed = true;
else
local defaultStream = ISChat.defaultTabStream[chat.currentTabID];
chatStreamName = defaultStream.name;
chat:logChatCommand(command);
end
end```
Do you understand what the code is doing?
i think it just checking the command
Okay, that's a good high-level understanding of it. What about at a lower level? Do you see where in the code it's checking the command string, for example?
if luautils.stringStarts(command, stream.command)
Good. What part about it is confusing, then? Are you unsure how you'd go about overriding it?
just how should i add my commands to list of standard commands
There's a second question in that message ๐ Are you familiar with the practice of overwriting vanilla Lua functions & methods?
not really
Okay, that's fine. I explained it a bit up here #mod_development message, but since this is a method here's a more applicable example:
-- where ISChat.someMethod is a method on ISChat
local _someMethod = ISChat.someMethod
function ISChat:someMethod(...)
-- add your override behavior
--- ...
--- if your override isn't necessary, defer
return _someMethod(self, ...)
end
In your case, ... isn't necessary since onCommandEntered doesn't have parameters iirc
sorry, don't get it
Be more specificโwhat don't you get?
just all
So... no part of that message was comprehensible? ๐ It'll be easier to explain if you point out particular things you're unsure about
ok, what is _someMethod?
The purpose of that variable is to save a copy of the existing method
In your case, onCommandEntered; you want a reference to the original function so you can call it in your override
so i need to use ISChat.onCommandEntered if i need this?
Can you rephrase that question? I'm unsure what you're asking
Oh, you mean as the part on the right? Yes
if i need method onCommandEntered i need to replace ISChat.someMethod to ISChat.onCommandEntered?
Yes
what to add in function?
You tell me. First step: look at the vanilla code and think about what it's doing to get the command string
can you explain pls what is this self.textEntry.onCommandEntered = ISChat.onCommandEntered;?
You don't have to worry all that much about that part, but what it's doing is setting the callback function that will be called when text is entered in the ISTextEntryBox to that method
The reason you don't have to worry about it is that it will run after your override has already occurred, assuming you do it in the main body of one of your scripts
also what is this local command = ISChat.instance.textEntry:getText(); local chat = ISChat.instance;?
like how variables are getting
What's your assumption, based on the code around it?
Unsure what you're asking here
what is instance.textEntry using for?
ISChat.instance points to the single instance of ISChat. As you noticed in createChildren, ISChat sets up a text entry box (textEntry). ISChat.instance.textEntry will point to that
chatCommand = stream.command;
elseif stream.shortCommand and luautils.stringStarts(command, stream.shortCommand) then
chatCommand = stream.shortCommand;
end``` i think this part of code is checking the command to its full version or short, yes?
Yes. Do you see where stream comes from?
& where's that
for _, stream in ipairs(ISChat.allChatStreams) do
Do you get what that line is doing?
not really
just don't know what stream is using for
oh i think i found sth
ISChat.allChatStreams[1] = {name = "say", command = "/say ", shortCommand = "/s ", tabID = 1};
ISChat.allChatStreams[2] = {name = "yell", command = "/yell ", shortCommand = "/y ", tabID = 1};
ISChat.allChatStreams[3] = {name = "whisper", command = "/whisper ", shortCommand = "/w ", tabID = 1};
ISChat.allChatStreams[4] = {name = "faction", command = "/faction ", shortCommand = "/f ", tabID = 1};
ISChat.allChatStreams[5] = {name = "safehouse", command = "/safehouse ", shortCommand = "/sh ", tabID = 1};
ISChat.allChatStreams[6] = {name = "general", command = "/all ", tabID = 1};
ISChat.allChatStreams[7] = {name = "admin", command = "/admin ", shortCommand = "/a ", tabID = 2};```
Okay, good. Side note: I highly recommend reading the Lua manual for Lua 5.1โit doesn't map exactly 1:1 with the Lua PZ uses, but it's very close
ok, i'll read it later
Okay. You can find it here: https://www.lua.org/pil/contents.html
thanks
I mention this because being familiar with the language used for modding will be a significant help
Knowing that the above is a loop would help to interpret the code
i don't understand sth
if chat.currentTabID ~= stream.tabID then
showWrongChatTabMessage(chat.currentTabID - 1, stream.tabID - 1, chatCommand); -- from one-based to zero-based
commandProcessed = true;
break;
end
chat.chatText.lastChatCommand = chatCommand;
local originalCommand = command;
command = string.sub(command, #chatCommand);
if command ~= "" and command ~= " " then
chat:logChatCommand(originalCommand);
end
chatStreamName = stream.name;
break;
end```
why are they did these
if they have chatCommand
Take a look at where chatCommand is assigned (other than the nil assignment)โit's in an if statement with an elseif branch. No else branch โ it isn't necessarily set โ it can be nil
They're checking to see if it exists before using it & assigning chatStreamName
also don't understand how can they check if not chatCommand then if in chatCommand have to be something after previous loop
Why does chatCommand have to be something after the previous loop?
because of this chatCommand = stream.command; and this chatCommand = stream.shortCommand; no?
See this message
what is chat:logChatCommand?
Did you search for logChatCommand?
no
Okay, try that
so its just sending commands to log?
Yes, it's just keeping a list of recent commands
so can't i just add my commands to allChatStreams, and just make function like processSayMessage but with my code
ohhhhh
You can do something similar to that, yes. It isn't strictly necessary to add your commands to allChatStreams, since your own code will handle your custom commands
But that is the essential idea. Well done
thanks for help ๐
No problem
also what is tabID?
It specifies which chat tab a stream should be available in. If you haven't played as an admin, you've only ever seen 1 chat tab (which doesn't display the tabs)
thanks
also i don't know how to send messages in chat for all players, i tried some ways but it didn't helped
Unfortunately the game doesn't expose some methods on ChatServer that would make that easy, so the best way that I could figure out for doing that was making a "fake" server message
I'm assuming you're talking about a server message, anyway. Is that not the case?
yes
This is essentially how I implemented it, with some details removed:
local InfoMessage = {
isServerAlert = function(self) return self.isServerAlert end,
getText = function(self) return self.text end,
getTextWithPrefix = function(self)
-- you may want to transform `text` here to match usual server messages
return self.text
end,
new = function(self, text, isServerAlert)
return setmetatable({
text = tostring(text),
isServerAlert = isServerAlert
}, self)
end,
}
InfoMessage.__index = InfoMessage
-- to add a server message:
ISChat.addLineInChat(InfoMessage:new('message text'), ISChat.instance.currentTabID - 1)
You'll need to handle actually sending it to every player, which you can do via client/server commands. These have been covered by others; I'd recommend checking the pins or searching
thanks
also want to ask about SendCommandToServer(), in server code i need to put OnClientCommand like when using SendClientCommand?
SendCommandToServer is not related to those; that's specifically for sending chat commands to the server for handling
In case that doesn't answer: pairs loops all key-value pairs, ipairs loops numeric key-value pairs & assumes they're in order starting at 1 (i.e., it will ignore non-numeric keys & any gaps will terminate the loop)
thanks
The manual also has an index of built-in functions that explains what they do, for similar questions
to my knowledge any case where you can use ipairs, you can use a for i loop instead which runs a lot better
i have an error in this line SendClientCommand("cmd", "hello", {});
its in checking of chatstreams name
SendClientCommand("cmd", "hello", {});```
oh thanks
now i have no errors but still no prints,
server code:
if module == "cmd" and command == "hello" then
print("Hello World!")
end
end
Events.OnClientCommand.Add(cmds) ```
if you're testing in multiplayer, make sure you're checking the right log file
which file i should check?
boolean
thanks
newBags has some vanilla containers that are not present in clothing_bags such as the Gun Cases


