#mod_development
1 messages · Page 227 of 1
@mellow frigate Sorry to ask, but do you know what "hasSeed" does in your mod?
I'm not familiar with vector2
why would you use getLastAngle since you already have something calculating the angle before ?
me neither
Did you check the documentation ?
Vector2:getDirection()
Probably what you want then
If I looked at it a little bit
I'll check, It must be that is actually is in the last growing state (with fruits available)
in fact it is to possibly distinguish seeds from fruits for trees with both. There is no seed for the coffee tree so it is always false.
Ah I see
more precisely it is a copy from vanilla SFarmingSystem.lua code.
Interesting!
Well, good news is it should carry over that variable to the new system if anything you have relies on it.
The news is that there's 2 other mods that implement coffee, so I'll have to do a quick run-through. I have a good feeling though.
Had to solve a mod priority issue though because your mod's vegetableconf file came alphabetically before mine

After a quick tweak to the Soul Filcher coffee seed packet, I got it playing nicely with yours.
Your seeds seem to be intercompatible..
@mellow frigate Looks like it's compatible. It grew alongside the other 2 coffee plants from Soul Filcher's and LGR just fine.
Awesome, thanx a lot.
Let's hope it will also be ok in mp 😄
One of which could've been simplified.
You literally just needed .cropCode = "Coffee" and it was done LOL
Should I add it to my mod ?
Eh, not 100% necessary.
You can if you want, but it's not like exclusively required. Besides people may want the patcher present out of habit.
@wheat kraken So what was all that buzz about "i need guy makes good UI" 
Plus UpdateFarmingData() is still required to be ran after your mod is fully intialized, so the patcher still needs to exist.
I see, cropCode is a compatibility tool from your mod, not a vanilla nor a FarmingTime thing right ?
Correct, it's a tool dictionary entry used by UFP to "sort" crop types into equivalents.
I just needed to specify yours was "Coffee" and not "CoffeFruit" so it would be sorted into "Coffee" appropriately.
Literally the only issue is on my end so
I see (probably a part of) why you are happy with that new version of the patch.
Yes, it makes it so similar seeds can be used interchangabley and their seed packets can be read to learn every crop of that type.
This version is super overengineered but it pays off
I can only hope for minimal errors

We'll see in the future. Thanx a f*ing lot !
Mhm! Hopefully this takes some weight off your shoulders for compatibility stuff. Sorry again it was so butchered last time.
Hopefully it runs much better now.
yeah, be sorry for helping 😉

Last version was a buggy mess of manual data entry that aged within a week
I'm much prouder of this version
does anyone know how to make the server do a function/run code so it has authority over players locations?
I do such thing to teleport players in BattleRoyale. (BattleRoyaleSafeZone.lua)
thee tchernobill helll yeah
(downloading to look ty)
it looks like you teleport both client side and server side to avoid desync is that correct?
If I remember correctly the server sends a command to do the teleport client side only.
can I dm you so I can paste code and not spam chat?
k
Has anyone an idea why when I create a floor with tile name blends_natural_02_0 server side it transforms into a blends_natural_02_8 client side and back to blends_natural_02_0 on the client side when they quit and rejoin the server ?
Whaaaaaaaaa? Sounds mysterious a.f. lol
I would need to see methodology to begin to guess, but I'm not a tile guy so I might not have very good guesses very quickly.
@mellow frigate Hate to bother ya, just wanted to let you know that it seems to be working - at least according to the testing I've done.
Only thing I had to overwrite was your getSprite and getObjectName functions iirc, which resulted in translation issues in the new system.
Thanks for the help
np
i come up with some ui by myself, from scratch, using vanilla tooltip, and it does result in more fancy, and auto resize content embeded by tooltip
but if anyone can improve the ui, feel free to do it,
i just upload the version that dont need the discord bot, and make it fully all in-game features
--
and sharing with (a brutal) sincerity and transparent, and feedback about was it was on contacting you, even if i did received a bit hints on the code not related to ui,
i feel from you, too much negativity/toxicty/(feeling yourself superior from others somehow oO and dont know why of that, while intrigred and looking for find a reason for that, i discover that is a dev too, and stream, and i conclude that is kinda your default behavior based on text and video clips) and appearing to underevaluating the tool/my dev skills, or treating like a newbie or poor skilled, so i vanished myself from your contact and interaction
some small bit parts was indeed constructive, but overall it was not a good interaction, and mostly bully approach (really dont know why, maybe its your natural way of be/treat others)
i suggests a feedback to you be more kind and treat others with equality, or apply recursively filters or just check on chatgpt analyse if the message you are about to send are depreceative or rude or toxic or contains some negativity
whats its about (context):
recently i reach out some modders with mods related to interface and ui, to check if they got interested, time, or want to be part of, so when they can or want to join and co-create,
because i come up with never yet seen/developed community tool, with content made by both players and modders and automatically updated for all others, but useful for unveil hidden gem mods (from 300 to 200k subscribers), for the mods not be hidden forever burried on workshop pages
--
chatgpt version, to show that it really can really suppress negativity and toxicity, and make my point, i really dont like superb people
chatgpt version come with this:
Your message seems clear and direct, but it's important to ensure it's constructive and avoids escalating the situation. Here's a revised version that maintains your intent but might come across as less confrontational:
"I've developed some UI improvements independently, including a custom tooltip that enhances the visual appeal and automatically resizes embedded content. If anyone wants to further improve the UI, feel free to do so.
I've also uploaded a version that doesn't require the Discord bot and includes all in-game features.
Regarding our previous interaction, I want to share some feedback. I felt there was a lot of negativity and perhaps a sense of superiority in your communication. While some of your comments were constructive, overall, it was not a positive interaction for me. I suggest considering a more respectful and equal approach in your interactions with others, as it can make a big difference in fostering a collaborative and positive community."
the only info that i know is that the last number on tile is refer to index position on image, starting from 1 to length-1
try using 1 in client instead of 0
(probably is cycling back to the tail, as fallback, to avoid the non 0 index)
on firetrail, i didnt sync the tiles sprites with server, (someday will do maybe) just the position but i use from [1 to length -2]
hope this helps someway
i got this hint from vanilla
anyone know how to parse the args from a client command being received? Compacted all the args into one bracket to send off to the server, but how do I actually unpack them from the "args" value
would it be args.playertotparg
args.x
or args["x"]
it is an lua table access
yes
mad lad ty
i used like this on pack
["x"]= square:getX()
and args.x
if encounter problems, use this notation
poltergeist helped me with that, long time ago
i don't understand the ["x"]= syntax or what you mean by this ?_?
maybe you dont need this, can do directly, its is equivalent maybe
but i use that way i mention, with no problems so far
but only be aware that need to be primary types, no objects
are you trying to tp player?
send their id instead
While I have you, does the TPGroup list actually work?
It's a global val (this is a shared file)
it was really hard to do, but on my rtr bus mod, i manage to tp only two "simultaneos"
i cant more than that,
you can check my mod if enconter problem, and test and try if you can more than 2 xP
its grabbing a group of players via location in game and then storing them to a list, and then later teleporting those players in that list
ooh, so you indeed are trying to tp multiple players, if you make it, mention me!
it was really hard times trying this,
i would update my mod if you acomplish,
and share with me
do you know if the TPGroup list actually works? as in does the code I show fill up the list with player objects?
i have less then 12 hours to finish this T_T
is that server side? or client side?
Shared, its called by a client via a menu
tpgroup will not work as intended
any particular reason ?_?
try use table.insert(tpgroup, playerid)
it will get only last player and self pointer
you will use it where? are you sure you can use player value?
player value seemed to work, the function seemed to work fine just client side,
I was adding a "store the player" variable so I could get all the players into a list and then teleport them at a later time
i really want to do that too xP
a long time ago, but it was very hard, and only achieve 2
you can try what i mention, using the value, if you will keep on shared server side
if you want to create a list,
maybe you will need create a class for that
-- Define a function to create a new node
local function new_node(value)
local node = {}
node.value = value
node.next = nil
return node
end
-- Define a list object with a head node
local list = {}
list.head = nil
-- Function to insert a new node at the beginning of the list
function list:insert(value)
local new_node = new_node(value)
new_node.next = self.head
self.head = new_node
end
try this, and if/when got mention me :))
finally working tp group player
nice list approach
you need to keep the head outside the for, to keep their address, and not override it
does :size() return the size of the array?
no
what's the need for a linked list here anyway? why not just a table?
what returns the size of the array ?_?
add a variable for that
doing # in front*
its is all tables pal, lua is table everywhere
even array is table {0=..., 1= ...}
local TPGroup = {}
local onlinePlayers = getOnlinePlayers()
for i = 0, onlinePlayers:size()-1 do
local playerToTp = onlinePlayers:get(i)
if (etc etc) then
table.insert(TPGroup, playerToTp)
end
end
i think you're overcomplicating things trying to make it into a linked list
but for some reason, my players inside a car, never tp everyone, just two
instead onlineplayers was playersinsidevehicle
whats the way to "clear" a table?
do i just set it to nil?
depends on how exactly you're using the table
function commands.RTR_TpPlayer(player,args) --a client give the server a list of players to get tp triggered on theirs clients
local vehicle = playersVehicles[args.user]
local data = {
vehicleDestination_X=args.vehicleDestination_X,
vehicleDestination_Y=args.vehicleDestination_Y,
vehicleDestination_Z=args.vehicleDestination_Z,
bus_id = vehicle:getId(),
paymentMethod=args.paymentMethod,
travelcost=args.travelcost
}
for i=0, #args.playerSeated_onlineIDTable do
data.playerSeated_onlineID = args.playerSeated_onlineIDTable[i]
sendServerCommand(getPlayerByOnlineID(args.playerSeated_onlineIDTable[i]),"RTR", "ReceiveTpOrder_fromServer", data)
end
end
this tp only two ._.
if you want to make it empty and you only access it through one variable you can just do TPGroup = {} again
through one variable?
I mean clear as in like
reset back to no entries
no index no nothin
local TPGroup = {}
local anotherReference = TPGroup
-- both point to the same table
table.insert(TPGroup, "foo")
-- both will see the new entry as they're references to the same table internally
TPGroup = {}
-- now TPGroup points to a new empty table, but anotherReference still points to the original table with foo in it
if you have multiple references to that table then you need to actually loop through and remove all entries in the table, but if you have only one then you can just do = {} to replace it with a new empty table
how would I loop through all entries in the table and then remove them?
Im assuming for loop but how would I remove it
or would it just be
the length
and then setting to nil?
for i = 1, #t do
t[i] = nil
end
ye ok cool ty mad lad
would this be ["x"]=square:getX(), ["y"]=... , ["z"]=...
?_?
how do I get a reference to myself as a player? in client I mean
My code is still happening only on my side/client side, the other clients aren't having the code called by this function run on their machines, thoughts?
IE on my screen they teleport to me, but on their screen they do not and as such rubber band/desync back to where they are really in the world
how do I send a server command to another client? because it seems like my command is only being sent to my own client
I sent a client command from the shared file using UI [which goes to the server lua file] [or potentially sending none at all]
the server lua file is SUPPOSED to send a server command to the target client [it seems to only be sending one to me or even potentially not sending one at all,]
going to keep debugging but man this sucks
Hello everyone, I came with a question about modding, I want to create my own weapon (firearms or melee, I don't care). I have only modeling skills. I am completely zero about the other aspects of modding in zomboid.
Suggest resources where I can find out about it.
Jeez. So you decided im toxic and negative because I asked you some important questions such as what is the point of that mod and gave you remarks about technical side and the fact that I don't really need a whole team to make that mod? I'm not feeling superior to anyone here or there mate, in fact I come into this particular chat to ask about things I don't know 80% of times, sometimes giving answers myself its how it works here. Not really SUPERIOR behavior right?
I'll end up this conversation because its public place and I can't DM you anymore, but you better check your own behavior first when you ask people to make a mod, ghost them and then write a 2000 line text about how toxic they are. Kinda nasty.
You can in fact add compatibility yourself tho I suggest you let me or the dev of Susceptible do it. That way if there is any important changes you won't have to manage it yourself
The item is added to a list with its ID and is linked to a protection type with the durability of the protection
But yeah it's better if you let me handle it :)
Easier for me to keep track of compatible mods and their compatible items + easier to change something
You can attempt to refactor my code from Jumper if you're still struggling with this. It can teleport a group of players who are standing together to a location chosen by one of them.
If you are curious on how Susceptible handles mod compatibility, this is how:
Basically it defines a global dict to access anywhere that is every single item IDs with theirs types + their durability (how fast their protection type will drain, tho the damage to those depends on the type of protection too)
So whenever I add a mod compatibility I just do that:
I add it to mask_data then just add the new keys to the global dict of SusceptibleMaskItems
You could do it yourself but then I would rather you add a check to verify that your entry to the table isn't already in so you don't overwrite my changes (else I'm fucked and would have to replace your file that does it, which I would rather not)
And I don't suggest anyone doing it either way, just DM me and I'll add it, you could even suggest me what durability and type it should be, write the line and send it whatever, I'll do it either way
Maybe this would be answered by looking at the file (currently on mobile, so it's not expanded), but why would an overwrite mean anything bad if it'd presumably be the same or similar data? Is your concern future compatibility changes?
I have an immediate thought, but I'll hold back the feedback unless you're interested since you didn't ask for it
You mean me appending the table instead of copy pasta it and just add new entries ?
I haven't seen the file, so I don't know. What I mean is, if the added entry is effectively “registering” an item it seems like you'd be doing the same thing
I'm overwriting it yes
Which should be fine ever way since I doubt Susceptible will change the durability or else
I could in fact check if the key is already in yeah
Interested in my two cents I referred to here?
Sure
My issue with other clothing mods doing it, is that I have ideas of possibly adding entries for my own features to the list, and if he ends up adding his key but replacing my own, it could just break stuff
Overall my idea is centralize everything
It could be nice to expose an API function for registering an item. This would mean you still have control over how it's done—so future changes to how you store the data wouldn't break consumers—while allowing people to add their item themselves if they want
So have modders add the compatibility themselves ?
They wouldn't have to. You could still very well call the function yourself, or continue to represent their items in your internal data however you please. This just gives them the option
While allowing you to easily maintain your data structure & whatever concerns you have about overwriting
Hmm I think there's no point to it for simple reasons:
-Not everyone will use my Overhaul mod + Susceptible, so if clothing mod adds a small .lua file to handle this and add their clothing it would need to have my overhaul mod downloaded to use the API, but not everyone will use my Overhaul so API might not be here and then they just don't add their clothing
-To this similar issue, adding your own item is just adding a new key to the table, and that's fairly easy to do with 2 lines of code tbf
-If it's not for someone's clothing mod, what would be the use of it ?
It wouldn't need your mod downloaded if it's a soft dependency, but fair enough if you don't think it's worth it. Personally I wouldn't see myself reaching out to ask someone to make my mod compatible with theirs unless it's just not possible to do it myself
But again, just my two cents—exposing an API is much preferred to a global table imo
Yes I meant it would still check that my mod is downloaded but if it's not it wouldn't add compatibility to it
The global table is how it is, if I want to improve that with a module I would need to change every single Susceptible's files
And that's not the plan of my mod, in fact I try to stay as less as intrusive as possible compared to how I added new mods before (I modified the file and the table itself but now I just append it)
And yeah I get the point of not expecting another modder to do it, but people never bothered making their clothing pack's compatible before so why would they even care now lmao
Like I said, it takes 2 lines to make your mod compatible with Susceptible, but no one ever did it because no one fucking cares
My phrasing of “much preferred” wasn't meant to mean “instead of” (i.e., they can coexist), but I see how it read that way
So just let me do it and boom we're done, I'm doing the job for you, having something centralized
Also features I add to my overhaul mod can ALL be toggled off in case someone just wants the new compatible clothings added in
I thought Susceptible was your mod from the set of messages; it being something you have less control over makes it less feasible (still possible! but less ideal state)
Yeah Susceptible isn't my mod, I just made an addon to improve upon it
So like if people want an API to add their own mod, what's the point when my mod already adds compatibility to their mods lol
The only issue with this system is that it depends on me having knowledge of mods that need new compatibilities
Ease-of-use and not having to reach out to someone for it 😄 but if it doesn't seem valuable then it doesn't
I'm subbed to every single clothing mods I add compatibility for Susceptible and I always check mods that get updated so I shouldn't miss one of those, but new mods is something else
Like I said, if someone wants to add their own compatibilities go for it, but ultimately it could become incompatible with my Overhaul mod if I add features by adding new tags to the list and the items
So if someone adds its own key without the tag I use in my mod, their item would miss features from my mod
And ultimately, if someone downloads a clothing mod that isn't compatible, I explicitely tell people to come and tell me mods that require new compatibilities and I add them very quickly
Sure it's an issue if I ever retire from modding PZ, but isn't that an issue with every single mods on the workshop ?
Not ones that provide an API, until they break
That won't fix the issue, that's the problem. Let's say I add an API to add new compatible items, that doesn't remove the problem that clothing mods will be compatible with Susceptible only if the guy that uses their clothing mod has both Susceptible AND my Overhaul mod:
first problem
Now second problem: let's say there's a bunch of mods that used that API and now I decide to add my new tag to items, those other mods wouldn't have added theirs and I end up with the exact same issue. Let's say I make something to automatically add the missing tags: how do I know what tag to use ? Depending on what my tag defines, how tf do I even automatically add other mods items the RIGHT tag to them ?
One idea I had for example, is to add a tag to check if the mask has opened vision for the eyes or not. Why do that ? Bcs for Spore Zone addon, in TLOU the spores can go through your eyes but currently it's impossible to check for that. And in this example I guess I could set automatically the tag to "mask eyes opened" but that would just not be nice at all
If I manage every new items compatibilities myself, I just add the tags myself and no item is missing. Then the only issue is just having items get reported to me to add the compatibilities
These questions have answers, but I'm guessing you don't actually want those answers lol
No no give them
This might be a silly question, but I'm having an issue updating a mod on steam. When updating the mod in PZ it says it's updated successfully, but the changes aren't showing on the workshop
If you have an idea go for it
Redownload the mod
Oh okay, I was getting the vibe that you weren't interested in the idea so I didn't want to bother
Dev probably changes some files' names or removed some
I'm trying to update a mod I made
No but just I see clear issues with this way of doing it. No clothing modder ever gave a shit about Susceptible and I doubt that will ever change
And I'm fine with it, that's how it has always worked
You have the mod locally + downloaded on the workshop so they clash with each others ?
Huh, good idea. I'll give that a try. I did have it downloaded
And I guess you could blame Susceptible for that, they did the entire job for the clothing modders but tbf that's really how it should be done, full control from original mod to handle those
For the first problem: this is circling back to the soft dependency thing. Consumers could check for whether the mods are enabled, if they so choose. You could still continue to register items manually, but this gives modders a choice.
Second problem: if they're using an API, you can just change the API to handle that. In my mind, the “register” function takes the item type at minimum (you'd probably want to take a table arg, to make it easy to extend in the future with optional inputs). You could use a DoParam call to make modifications to the item type, which could change as you see fit. To know what tag to use for a new tag, you'd use the inputs & have a sensible default for those that don't provide it (the “not nice at all” would then fall back to the mod creator to update it, or you could still very well do it yourself if you find out their integration is out of date)
Meant to reply, whoops
Gave it a shot, unsubscribed from my own entry, deleted the file from the steam mod folder and restarted PZ. Same thing. Upload success, but no changes on steam
No changes as in there's no changelog entry when you click that, the workshop description, or the content?
All 3, a combination?
The description didn't change, the update date didn't change. I haven't checked the content itself for changes, however
If there's no changelog entry I imagine not. Unfortunately I haven't run into that problem myself
Content didn't change, just checked to be sure.
And yeah, no entry, sorry
I'll give it a try again later, restart steam as well. Maybe the servers are having some issue
The first idea I already know about it for the soft dependency thing, but then their mods doesn't work with Susceptible if the guy doesn't have my overhaul mod and then they should add a way to check that someone has Susceptible but not my overhaul and append the table normally but what's the point, just append the table yourself overhaul mod or not (and then have features break) but really that's too much work for simple clothing mods. A lot of clothing modders don't know shit about lua tbf, I'm not going to expect anyone to add the compatibility. Like I said no one ever gave a shit and no one ever realized it's very easy to add compatibility with Susceptible. Just let others do it
Second idea, if you're talking about the script files I will never touch those and I don't plan on touching those, my custom tags would be added the global table of Susceptible with every item IDs. And for the not nice at all aspect and your idea of waiting for modders to update it, well then I end up being dependent on other modders to update it ? I could check if modders have added it and shit but why even bother doing that tbf, just have clothing modders not add their item compatibility at all or have them make their mod is loaded before my overhaul so my overhaul just overwrites their addition to the table
Technically I could even add something to check that the mod that adds the items is present, then make sure it's loaded before I add my items to the least, else if item already added overwrite it and shit but that sounds like a lot of work for a feature no one even fucking cared about before and that only like 1 modder at best will use and that's if he even understands the point of using it
You start adding safe guards upon safe guards while you could just keep it in the state that it currently is
The issue with mod compatibilities is the inactivity of the original devs of Susceptible
Point 1: like I said, wouldn't see myself bothering to ask someone else to add compat for my mod (but I'm not a clothing modder)
Point 2: not talking about creating script files; you can dynamically update those scripts with Lua using the script manager
I never talked about creating script files either
Yeah there are concerns to address, but it really wouldn't be that significant. Again, though, if you're not interested you can just not do it lol—don't need to justify it to me 🤷🏾
Just Susceptible does absolutely nothing with script files and there's no point for the mod to modify the clothing script files
My main issue is:
Why add a feature that allows other modders to add compatibility when I already add it myself ?
Refer to point 1
yeah
For future reference, in case someone else gets the issue. Restarted my PC, somehow resolved the issue.
Reason: Bad word usage
Someone help me, please
Thank you very much 😉 Perfect
Thanks
np. It is a good start to get solid basic knowledge of how mods work
In case anyone was wondering, you can add images to sandbox options
defuck?
Awesome, is there an exemple ?
yup lol
what type in option is that even
Sandbox_Susceptible_TimeForNaturalDrain = "Time for realistic mode drain",
Sandbox_Susceptible_TimeForNaturalDrain_tooltip = "<IMAGE:media/ui/Realistic_mode.png> <LINE>Protections will be drained based on this factor. Exhaustion exponentially increases the durability consumption, meaning removing a gas mask, or it's filter at a minimum, when exhausted might be important. <LINE><LINE>0.25 means fully depleted after 9 days when not exhausted and after half a day of being fully exhausted. <LINE>0.08 means fully depleted after 270 days or 14 days exhausted. <LINE>0.55 is depleted after 20 hours or 1 hour of being exhausted.",
Example of the line of this option
Only in the tooltip you can add images
<IMAGE> lmao
That can be really helpful considering how many questions people ask when they scroll sandbox options
definitely will start using that anywhere where it makes sense.
Tho you should keep this minimalistic I feel like
It might not adapt well when lowering resolution
i wonder what other text preprocessor thing are out there
ISRichTextPanel tags:
<LINE>
<BR>
<SPACE>
<H1>
<H2>
<TEXT>
<CENTRE>
<LEFT>
<RIGHT>
PUSHRGB:R,G,B
<POPRGB>
RGB:R,G,B
<RED>
<ORANGE>
<GREEN>
SIZE:small/medium/large
<IMAGE:path/to/image, width, height>
<MAGECENTRE:path/to/image, width, height>
INDENT:number
<JOYPAD:key from Joypad.Texture, width, height>
SETX:number
examples for IMAGE
IMAGE:media/ui/spiffo/packing.png
or texture name IMAGE:Item_Plank, IMAGE:location_entertainment_gallery_01_8
From Elyon
That should be pinned or posted somewhere on wiki if it isnt
but that means you can create your own tags lmao
I mean you can overload function ISRichTextPanel:processCommand(command, x, y, lineImageHeight, lineHeight) with your own stuff
its just a function so yes.
I think I'll put that list here with explanations
yeah would be useful
ISRichTextPanel tags (text that can be in Tooltips):
<LINE>: starts a new line, resetting the X position to 0 and moving the Y position down by one line height
<BR>: similar to <LINE>, but it creates a larger space between lines, effectively creating a double line break
<SPACE>: adds a space character's width to the current X position, used for inline spacing
<H1>: formats text with H1 properties, making it centered and setting the font to large
<H2>: formats text with H2 properties, aligning it to the left and setting the font to medium
<TEXT>: resets text properties to defaults for the body text, using a smaller font than headers
<CENTRE>, <LEFT>, <RIGHT>: aligns the text to the center, left, or right of the line respectively
<PUSHRGB:R,G,B> saves the current color state onto a stack and sets the new text color according to the provided RGB values
<POPRGB>: restores the last text color from the stack, reversing the effect of the most recent <PUSHRGB>
<RGB:R,G,B>: sets the current text color to the specified RGB values without affecting the stack
<RED>, <ORANGE>, <GREEN>: sets the current text color to red, orange, or green respectively
<SIZE:small/medium/large>: changes the font size to small, medium, or large
<IMAGE:path/to/image,width,height>: inserts an image at the specified path with given width and height (width and height are optional)
<IMAGECENTRE:path/to/image,width,height>: inserts an image and centers it horizontally on the line, with specified width and height (width and height are optional)
<INDENT:int>: indents the current line by the specified number of pixels
<JOYPAD:key from Joypad.Texture,width,height>: inserts an image from the Joypad.Texture table with a specified key label and dimensions (see below)
<SETX:int>: sets the X position to a specific pixel position, overriding the text flow
examples for IMAGE
<IMAGE:media/ui/spiffo/packing.png>
or texture name <IMAGE:Item_Plank>, <IMAGE:location_entertainment_gallery_01_8>
width, height in pixels
Joypad.Texture = {AButton, BButton, XButton, YButton, LBumper, RBumper, DPadLeft, DPadRight, DPadUp, DPadDown, DPad, LStick, RStick, LTrigger, RTrigger, Menu, View, Back, Start}
send that in modding discord too so we pin it there too
Yeah that's a really good application for that
As I said I'm impressed enough to want to use it myself now.
i wonder if that works in chat panel since its a rich text presumably the same way
I know that you can use colors and icons in "Say" chat https://projectzomboid.com/chat_colours.txt
the chat panel doesn't support full rich text, you can see this because it doesn't even support the features that the vanilla radio uses 😓
i don't remember the exact output but when the radio uses 🎵 to express music the chat box displays it as plain text
addLineChatElements probably supports it tho
awesome, thx for the tip !
Yeah that's amazing stuff :D
Definitely the kind of stuff here that's great
I'm wondering if you could show gif in it too
not by just putting a gif: java.util.concurrent.ExecutionException: java.io.IOException: Not a valid PNG file
hmm
or webm?
Yeah likely, but GIF support isn't much better IIRC
still frames might be an option to fake a gif
Maybe a pedantic distinction, but the chat panel itself does support it—it's certain streams that don't
That is, you can use *music* on /say but not /all (& most others)
huh! i'm surprised they're rendered differently
I wish they weren't 😢 I added an icon picker to my chat mod (currently soft-removed bc I wasn't happy with it) & because of that I had to check the input to determine whether it should be enabled
This is neat btw, thanks for sharing—I knew they supported rich text but never thought to try images. Somewhat cursed & seeing it made me laugh, but I can see that being useful
Better use case :)
Or like Tcherno shared above
That one looks nice. I think larger images look strange, but nonetheless useful context
yeah definitely, the example I first sent was just me testing it haha
I am not able to put text on the whole line. there are some forced carriage return. But you seem to not have them. do you do something special ?
You mean the text not going further than the image border ?
Sandbox_Susceptible_TimeForNaturalDrain = "Time for realistic mode drain",
Sandbox_Susceptible_TimeForNaturalDrain_tooltip = "Protections will be drained based on this factor. Exhaustion exponentially increases the durability consumption, <LINE>meaning removing a gas mask, or it's filter at a minimum, when exhausted might be important. <BR> <IMAGECENTRE:media/ui/Realistic_mode_data.png>",
the entire thing for the screenshot above if you are curious
I actually cheat and break line at a part of the text for it not to be too wide
I also thought this would work with any custom tooltips of inventory panel
eeeh
op nvm
ISInventoryPane uses ISToolTipInv
It doesn't use rich text UI component sadly
But in general this is all Lua abstraction you can do whatever you want until it hits java objects
yeah
Trading Spot Mod:
- Find Magazine that allows for creation of hidden Trade Spot. (Post-apocalypse notes left by other survivors)
- Create Trade Spot.
- Use Radio, Paper, Cardboard Box/Garbage Bag/PlasticBag/Duffelbag/Satchel/Backpack, along with items (Food, Weapons, Tools, etc) to create a Trade Offer.
- Leave Trade Offer in Trade Spot. (Trade offer is an item that rots and becomes a Trade Package after a day. Ideally a variance of 1 to 3 days but I don't think that can be done with a rotten item. Immersive Hunting Mod does something like this.)
- Trade Package can be created into goods (Food, Weapons, Tools, etc) and returned container at the Trade Spot.
Trade Spots would be similar to the crafting table mods with a tiny compartment for the Trade Offer and Trade Package. They would appear to be hidden stashes. (Log with a hole, large rock with a hole underneath, half-hidden crate, stuff similar to the Secret Entrances in the Building Menu mod) They must be built outside.
Trade Offers and Packages would be similar to Dynamic Trading mod. For example, trading two shotgun boxes for some cans of food.
This would fit better in 6 months later, or 10 years later assuming a hostile world where survivors prefer to interact from a distance. Maybe in the future add a small chance for your items to be stolen, but kinda lame without being able to track down the trader who done it.
Any suggestions/tips?
This close to getting llthreads working for zomboid lua lol its driving me nuts 🙃
Hello, im setting up a mod developing environment on IntelliJ IDEA (on Windows 10) with CAPSID. After initializing the plugin and running the "CreateRunConfiguration" task smoothly, i get an error while trying to reloading Gradle:
A problem occurred configuring root project 'Capsid'.
Could not create task ':updateZomboidLua'.
Could not create task ':zomboidVersion'.
'org.gradle.api.tasks.JavaExec io.pzstorm.capsid.zomboid.task.ZomboidVersionTask.setMain(java.lang.String)'
And sub error says simply:
'org.gradle.api.tasks.JavaExec io.pzstorm.capsid.zomboid.task.ZomboidVersionTask.setMain(java.lang.String)'
Does any modder that uses the same workspace can help me resolve this ?
I just copied the example mod, deleted what I didn't need, and opened a VSCode folder workspace at the mod start folder
Ok ill try this
Why are you going to that trouble?
I want stable 120 player multiplayer servers and I'm not waiting for the zomboid devs to figure it out lol
Also, gmod lua did not prepare me for zomboid lua. Or at least the methodology/paradigm 🙃
Nor did being a senior game dev lol Lord Lua is weird
Out of curiosity, what specifically do you hope to thread from Lua in order to make servers more stable?
Hi I am planning to make a simple mode (breaking stone with hammer give u 4x chipped stone). Do I need to use: "OnCreate:Recipe.OnCreate" fuction. I am watching tutorial on how to make mode and that part confuse me alot.
How does the game keep track of zombie locations when none are on a player's screen? Is there a database of some kind?
Does that work for dedicated servers?
hmmm don't know
I'll try with an admin account. I just add -debugmode to the start command?
oh whoa, this is a very different view
I'm not too sure
Why you want that ?
No. That is to call a function for additional processing, not needed for simple things like your's.
tnx
Installed lua ?
Curiosity I guess. I'm interested in modding zombie population
That will probably be in the java
Is that open source?
Not exactly
You can make java mods but they are usually not recommended doing
Tho I'm not familiar where it's exactly handled
But I wouldn't be surprised if it was in the java
The rendering of zombies for example is handled there
it's stored in the zpop files in the save folder
there's some kind of meta simulation for zombies out of range, something about migration and stuff, but i'm not sure how deep it is
it wouldn't be anything you can touch from lua
Could someone help me or guide me so that this code returns the list.
Instead of Object tried to call nil in VehicleManager.instance():getVehicles().
At first, specifically test with a mod that would manage move tracking for both zombies and players and also a level of movement prediction/interpolation.
Main goal, but first is just getting to to work in Lua test wise. I'm looking at the possibility of this still needing edits to Java stuff which I'd share with indie stone of it got to that lol
multithreading is not natively supported by kahlua, and integrating it, especially the PZ engine, which was not designed with concurrency in mind, would be a monumental task
it's not just about adding or modifying the Lua layer; it's about the core architecture of the game engine itself
multithreading would mean ensuring thread safety across the entire engine, which could involve extensive rewrites of the core systems to prevent race conditions, deadlocks, and other concurrency issues
the lua is explicitly ran in a single thread, you cannot implement multithreading through it in any form
Does anyone know where and how the Capacity of a freezer is set? Like, I know I can use self:getParent():getProperties():Val("ContainerCapacity") to get the capacity of a fridge, but not of a frezer.
Can someone help me with this?
I think you can loop through the object ItemContainers
I did but I can't seem to find the source of the different capacities
https://pzwiki.net/wiki/Appliances#Refrigerators
In the docs the fridge and frezer containers have different sizes, but when I used this code, the value of parentCapacity and spriteCapacity is always the same 😦
local ContainerUpgradesModData = require "ContainerUpgrades/ContainerUpgradesModData"
local getObjectContainerCapacity = require "MxUtilities/getObjectContainerCapacity"
---@diagnostic disable: duplicate-set-field
---@class ItemContainerMx: ItemContainer
local ItemContainerMx = __classmetatables[ItemContainer.class].__index
ItemContainerMx.getBaseCapacity = function(self)
local parentCapacity = self:getParent() and self:getParent():getProperties():Val("ContainerCapacity")
local spriteCapacity = self:getParent() and self:getParent():getSprite() and self:getParent():getSprite():getProperties():Val("ContainerCapacity")
return getObjectContainerCapacity(self:getParent())
end
Hi, I'm creating this quick, effective and cheap (only the graphic part) homemade alarm system. A must-have in a zombie apocalypse. I was wondering if someone who knows how to program would like to collaborate with me to make it.
https://imgur.com/mFD5Wv8
Hello everyone, please tell me where to start learning so that I can create mods?
Hey, I would be interested maybe, I invite you to create a post in the passion-project channel of the modding community to have a better follow of this
If you are already skilled at OOP of any sorts you can just get into any mods and reverse engineer what people do there. All mods (scripted) are open and Lua.
Can I somehow write an RP MOD about acceptance in society and make ranks? RMB on character/assign profession, issue rank/select rank (1-9)/The selected character is given a role and the necessary skills not through administrator rights.
Eh llthread is basically a wrapper system that allows you to launch multiple lua runs with communication betwene threads through another Lua add on.
I'm digging more into it and it requires some Java modification, not impossible; but tracking what's depending on what I'd need to change is rough given limited api at the Java level
Yeah, thats pretty doable, its more difficult to make a functional system for that, that actually does something about it.
You can use Events.OnFillWorldObjectContextMenu to add something to world context, including players
Found how freezer capacity is set! The key is FreezerCapacity 🎉
Can anyone help me write this function?
You can use my script here for reference of how to make world context interact with anything.
Water machine, Works like a well
I think you can only getVehicles() on cells, you can't list all the active vehicles in game. You also not able to access vehicles DB from lua, at least I am not aware of any method to access vehicles DB.
Technically you can access database, but with only game/server offline, because it locks it when its up.
On other hand you can access all vehicles in the game, but only on client and only within loaded cell range.
local vehicles = getCell():getVehicles();
for i=0, vehicles:size() - 1 do
...
end
I wanted to obtain the list so I could increase the normal lower condition of the parts of each vehicle by 2
thank you for explaining to me
Oh you wanna modify vehicle scripts?
if so I think you can only do that once when game loads
I think so but I don't know how to do it exactly. Could you tell me where I could start if it's not too much trouble?
I wanna context option, that will send window like trade window to the recipient with yes / no, in vanilla is using event Request Trade, say me pls how can I send this window cuz my attempts run into the fact that the window is sent to the self requester
ISWorldObjectContextMenu.CreateContextOption = function(worldobjects, player, otherPlayer)
ISTradingUI.Showchoosewindow(player, otherPlayer)
end
ISTradingUI.Showchoosewindow = function (player, otherPlayer)
local modal = ISModalDialog:new(getCore():getScreenWidth() / 2 - 175,getCore():getScreenHeight() / 2 - 75, 350, 150, getText("IGUI_TradingUI_RequestTrade12", player:getDisplayName()), true, nil, ISTradingUI.onAnswerTradeRequestsomething);
modal:initialise()
modal:addToUIManager()
modal.requester = player;
modal.recipient = otherPlayer;
modal.moveWithMouse = true;
ISTradingUI.tradeQuestionUI = modal;
end
Events.RequestTrade.Add(ISTradingUI.Showchoosewindow)
Never really done that buts its possible only within this event AFAIK
https://pzwiki.net/wiki/Lua_Events/OnGameBoot
People used some item tweaker thing from what I seen that copypasted everywhere that changed scripts of items on-fly that way.
Allowed you to tweak any field of items without modifying them directly in their scripts
you don't need to wait until ongameboot, scripts load before lua does
item tweaker does more harm than good, never heard of vehicle tweaker causing problems but neither of them really simplify anything
the syntax for vehicle edits is a little weirder than items but in either case you're only saving yourself from writing maybe two lines of code by using those tools
local vehicle = ScriptManager.instance:getVehicle("Base.CarNormal")
if vehicle then
vehicle:Load("Base.CarNormal", "{ parameter = value, }"
end
Is there a way to make it so that my function is the last of the Events.OnGameBoot I need to make sure my function runs after all the mods otherwise it won't catch all the use cases
Would this be enough?
local function initRespawnTrait()
end
Events.OnGameBoot.Add(function()
Events.OnGameBoot.Add(initRespawnTrait)
end)
What the goal of your function ?
i don't think that will work, the range of the event callbacks list would have been evaluated already so your function would be out of range of the loop
I need to make sure that my trait is exclusive with all the traits
local MxDebug = require "MxUtilities/MxDebug"
local function initRespawnTrait()
MxDebug:print('initRespawnTrait')
TraitFactory.addTrait("RespawnTrait", getText("UI_trait_RespawnTrait"), 0, getText("UI_trait_RespawnTrait_desc"), true);
local traits = TraitFactory.getTraits();
for i = 0, traits:size() - 1 do
TraitFactory.setMutualExclusive("RespawnTrait", traits:get(i):getType());
end
end
Events.OnGameBoot.Add(function()
Events.OnGameBoot.Add(initRespawnTrait)
end)
Vanilla and modded ?
Vanilla and modded
maybe a hack like this?```lua
Events.OnGameBoot.Add(runLast)
local old_add = Events.OnGameBoot.Add
Events.OnGameBoot.Add = function(callback)
Events.OnGameBoot.Remove(runLast)
old_add(callback)
Events.OnGameBoot.Add(runLast)
end
Surely that doesn't sus asf lmao
Why have the first Events.OnGameBoot.Add(runLast) tho ?
That's so hacky, it's beautiful
if no other mod calls Events.OnGameBoot.Add after this it won't be added
You put it in the list and then adjust its position
so we add it first before changing the function
I do something like this in Jumper to force that way up the context menu when people want it on top
I wanna context option, that will send window like trade window to the recipient with yes / no, in vanilla is using event Request Trade, say me pls how can I send this window cuz my attempts run into the fact that the window is sent to the self requester
ISWorldObjectContextMenu.CreateContextOption = function(worldobjects, player, otherPlayer)
ISTradingUI.Showchoosewindow(player, otherPlayer)
end
ISTradingUI.Showchoosewindow = function (player, otherPlayer)
local modal = ISModalDialog:new(getCore():getScreenWidth() / 2 - 175,getCore():getScreenHeight() / 2 - 75, 350, 150, getText("IGUI_TradingUI_RequestTrade12", player:getDisplayName()), true, nil, ISTradingUI.onAnswerTradeRequestsomething);
modal:initialise()
modal:addToUIManager()
modal.requester = player;
modal.recipient = otherPlayer;
modal.moveWithMouse = true;
ISTradingUI.tradeQuestionUI = modal;
end
Events.RequestTrade.Add(ISTradingUI.Showchoosewindow)
does anyone know what method i need to use in order to let my blackouts mod prevent players from using fuel pumps when the power is out?
it seems that when you turn off the power via getWorld():setHydroPowerOn(false) (even in debug without mods) fuel pumps will still work if you have already used it before. and it looks like it is because the fuel context activates whether the power is on or not, as long as you haven't reached the shutoff date
if haveFuel and ((SandboxVars.AllowExteriorGenerator and haveFuel:getSquare():haveElectricity()) or (SandboxVars.ElecShutModifier > -1 and GameTime:getInstance():getNightsSurvived() < SandboxVars.ElecShutModifier)) then
if test == true then return true; end
-- context:addOption(getText("ContextMenu_TakeGasFromPump"), worldobjects, ISWorldObjectContextMenu.onTakeFuel, playerObj, haveFuel);
ISWorldObjectContextMenu.doFillFuelMenu(haveFuel, player, context);
end
if fuelStation then
local square = fuelStation:getSquare();
if square and ((SandboxVars.AllowExteriorGenerator and square:haveElectricity()) or (SandboxVars.ElecShutModifier > -1 and GameTime:getInstance():getNightsSurvived() < SandboxVars.ElecShutModifier)) then
if square and part:getContainerContentAmount() < part:getContainerCapacity() then
if slice then
slice:addSlice(getText("ContextMenu_VehicleRefuelFromPump"), getTexture("media/ui/vehicles/vehicle_refuel_from_pump.png"), ISVehiclePartMenu.onPumpGasoline, playerObj, part)
else
context:addOption(getText("ContextMenu_VehicleRefuelFromPump"), playerObj, ISVehiclePartMenu.onPumpGasoline, part)
end
end
end
end
these are lines from ISWorldObjectContextMenu and ISVehicleMenu
can something like this be solved with decoration or do i need to do something else? if it can be solved with decoration, how do i decorate?
honestly it just looks like i would just need to add a condition like and not ModData.getOrCreate("tmrblackouts").eventplaying or something
maybe you can change the vanilla files when the blackout starts to make it impossible to interact with the gas station`s context menu
however, i think i need to do more than that, considering there are probably other instances that use the same checks
while gas pumps seem to be the main one affected by this, i also received a report that the jukebox mod still plays music when a blackout plays
so i want to have a fix that can solve many similar problems instead of manually going through each one case by case
(although the jukebox one might be a different issue entirely)
what about vanilla blackout? Maybe you can try looking in the game files for lines that are responsible for turning off all currently running devices when the day of the power outage arrives, this may solve most problems with currently running devices
well when i turn off the power, it looks like pretty much everything properly turns off except fuel stations with queried fuel counts
but there are probably others like this that are undiscovered
if you go to a new fuel pump (that has never been used before), then it functions properly: you cannot use it when the power is out
however, if you go to a fuel pump that has been used before, then it will let you use it regardless of if the power is on or off, as long as you havent reached the official shutoff date
and this applies to using both using a gas can or right clicking/pressing v on a vehicle
Have you tried to add a variable in vanilla files, to simple check for blackout, like this?
if not blackout then
if slice then
slice:addSlice(getText("ContextMenu_VehicleRefuelFromPump"), getTexture("media/ui/vehicles/vehicle_refuel_from_pump.png"), ISVehiclePartMenu.onPumpGasoline, playerObj, part)
else
context:addOption(getText("ContextMenu_VehicleRefuelFromPump"), playerObj, ISVehiclePartMenu.onPumpGasoline, part)
end
i havent. i dont know how to use these, but Burryaga has been helping with the mod and probably would be able to explain this to me
is this how decoration works?
decoration?
burryaga told me about decorating files but i dont know how it works as we havent needed it yet. and it is supposed to be a method you can use to modify other files without rewriting and replacing them
anyway, i think that's what i need to do, most likely, but i just need more explanation on how it works
you can replace functions
i'd rather not replace functions, as that can cause compatibility issues with other mods that use the vanilla functions
but apparently decoration can achieve the same thing without replacing
i'll just sit on this for now since im really busy lately, but that's where im at rn
but also the fuel thing is a pretty important bug i need to fix
Anyone here know how I could learn to make a mod for pz
I want to make an immortal snail mod, but with a zombie instead of a snail
hi good night
https://steamcommunity.com/sharedfiles/filedetails/?id=3035712003
someone knows if this guide still works in 2024 ?
or it's outdated?
I used it, it's still working
the only thing it doesn't tell you is where to put the files and what the xml stuff you need is
put the animation fbx under media/anims_X/ and put the animation xml in media/AnimSets/player
the xml stuff you can look at the vanilla game ones for understanding
maybe removeOptionByName(getText("ContextMenu_VehicleRefuelFromPump")) for removing a context option... might help.
thanks! also saw your dm but i will take a look at the contents of it later
hi I'm creating a mod of a car but the wheels don't want to be there :/ that's why someone could tell me why
Thank you so much :)
I want to translate my mod from English to Ukrainian, I obviously did it wrong and the game doesn't see the translation, can you help me?
missing closing brackets
}?
yep
and if that alone isn't enough, i'm not sure the left-side (left from the equal (=) sign) is allowed to have spaces (unsure however)
If that alone doesn't fix it you could try to replace the spaces with underscores (_) (in both itemscripts and translation file)
Wire Baseball Bat (Lucy) - it's item id or DisplayName?
i mean like item in script:
item Wire Baseball Bat (Lucy) {
-- stats here
}
I want there to be a different name of the subject that you chose the language
i understood, i mean you should use item id, not DisplayName
That is, to do Display Name?
for example my item in scripts:
module Base
{
/* HELMETS */
item zReV2_1ECO_fullhelmet1
{
-- stat here
DisplayName = ECO-13 Helmet,
}
}
my translation should be like:
ItemName_RU = {
/* clothes */
ItemName_Base.zReV2_1ECO_fullhelmet1 = "Противогаз ECO-13.1",
}
if u work with DisplayItem (not all moded items contain this and some mods can contain same displayname for another items, better translate by item ID)
u should translate with Items_UA.txt
Items_UA = {
DisplayName_Sleeping Bag = "Спальний мішок",
}
but recommend first (with ItemName_X.txt)
How to find Id?
and look into head of file, where module.
most mod uses personal module
in screen it's Base, then translate line looks like ItemName_Base.zReV2_1ECO_fullhelmet1 = "Противогаз ECO-13.1",
if it be not Base, for ex Papupi then line should looks like ItemName_Papupi.zReV2_1ECO_fullhelmet1 = "Противогаз ECO-13.1",
please ?
I do not understand what you trying to correct from my statement, because you just rephrasing what I wrote.
@verbal yewSorry for the ping here, did I do everything right?
Probably misread something then.
folder yep i think
encoding windows 1251
Hello everyone.
How can I determine on the script side what type of map I am currently playing,
for example, is it Knox Country, Kingsmouth, or Studio?
Sorry, I solved it myself.
"getCore():getGameMode()" seems to be able to determine it, so I will try there.
is there a limit on the size of txt scripts file
Hello! For Gun-Mods, What is the difference between SoundRadius and SoundVolume? More specifically what is the SoundVolume?
@sour island , I noticed that the Named Literature mod doesn't seem to coordinate book names between different players in MP (example, Player 1 might see Life of Pi on a shelf, and when Player 2 inspects the shelf, it's The Holy Bible).
I was thinking about developing a different approach, but I was wondering if I could ask you a couple questions about the development process so I can better understand what I'm getting myself into?
I was under the impression they did sync
35kb
I used the mod in MP for the first time last night, so I'll do a quick test in a bit so I'm not just throwing anecdotes at you.
If I find anything, do you have a github or somewhere to share the report, or is here / dm fine?
I wanna context option, that will send window like trade window to the recipient with yes / no, in vanilla is using event Request Trade, say me pls how can I send this window cuz my attempts run into the fact that the window is sent to the self requester
ISWorldObjectContextMenu.CreateContextOption = function(worldobjects, player, otherPlayer)
ISTradingUI.Showchoosewindow(player, otherPlayer)
end
ISTradingUI.Showchoosewindow = function (player, otherPlayer)
local modal = ISModalDialog:new(getCore():getScreenWidth() / 2 - 175,getCore():getScreenHeight() / 2 - 75, 350, 150, getText("IGUI_TradingUI_RequestTrade12", player:getDisplayName()), true, nil, ISTradingUI.onAnswerTradeRequestsomething);
modal:initialise()
modal:addToUIManager()
modal.requester = player;
modal.recipient = otherPlayer;
modal.moveWithMouse = true;
ISTradingUI.tradeQuestionUI = modal;
end
Events.RequestTrade.Add(ISTradingUI.Showchoosewindow)
any guide how to create an item similar to a campfire?
I want to run something if someone connects to MP for the first time - OnGameStart, OnCreatePlayer,OnNewGame but I dont know what they really do in MP context
Only want to run a function for the first time - not again when they respawn, or reconnect
anyone can give me tip? ^.^
Is there any way to see the distanceMin and distanceMax of an event (walking, attack, door close), either visually or in text? I'm digging around debug mode, but not able to find anything.
Hey yule. Maybe this will help (if you haven't seen it already)? https://github.com/demiurgeQuantified/PZEventDoc/blob/develop/docs/Events.md
Is your function supposed to happen client side? Server side? Both?
There is a repo - https://github.com/Chuckleberry-Finn/Named-Literature
Mod for Project Zomboid which applies randomized names for books from a list of 3000+ titles. - Chuckleberry-Finn/Named-Literature
I would appreciate info there, as it's easy to lose it here 😅
My only tests were with local hosted MP
100%, easier when you keep everything in place. I hosted a steam session, but I'll try a couple different options to try to find edge cases and consistencies.
Named Literature is a dope mod by the way Mr. Finn. I haven't played without it since I found it on Steam. 100% fanatic over mods that improve immersion. ❤️
thank you, thats super useful version of the javadoc 😄
Any time!
Named lit is one of my favorite projects. Very quick development, fun to mess with string manipulation.
In the same vein, the new MTG addon for Game Night -
Randomization in moderation 😅
Okay... I'm working on writing a mod that allows you to globally adjust the cooking time on food. This is so people can extend/shorten cooking times in order to make things a bit less hectic on shorter day/night cycles and less boring on long day/night cycles. I'm torn on how I want to go about it though... I can either loop through every item in game, check the type to make sure it's food, check to make sure the food is cookable then adjust the cooking time by whatever percentage is set in the sandbox options, or overwrite some lower level cooking functionality to do that for me...
The first seems inefficient, but I'm well aware of how to pull it off. The second seems like the better way to go about it, but I have to go digging for functions in that case (and hope what I need to pull it off is actually exposed). 😅
That's pretty awesome. Is it just randomizing your deck builds then? lol
This is for found decks in schools
I actually play an older card game named Rage, where you play a pack of werewolves fighting against other werewolves (and other things). Maybe I should make a deck randomizer.
I didn't want the found ones to just be a bunch of random cards with no reasoning
Wait... what? You're just finding random decks in schools? I'm confused. 🤣
Yeah the distro will have decks in schools and where games are found. Stores will have packs and kits
OMG... you are talking about the mod Game Night and you are adding MTG to it... 🤦🏻♂️ I'm dense. lol
No worries 😅
Hey Chuck, I'm still going to submit it to github for tracking and organizational purposes, but it turns out the book titles only sync after they've been "handled".
Makes sense, could also help my other mod(s) to figure out how to change modData for items that are not picked up.
Are there any specific logs you need?
wdym ?
For my GitHub issue submission for chuckleberryfinn , sorry I didn’t tag my reply
No there's no specific tags. 👍
radius is the radius in which zombies will hear it, volume is basically a tie breaker for zombies who have heard multiple sounds recently, they prefer to go to louder sounds
Hey @sour island do you use any specific IDE for modding PZ? I have been using Sublime Text but starting to wonder if I should use something a little more powerful. 😁
I suggest VS code
Since Albion here has an addon for PZ autocompletion
Oh snap. That would be awesome.
It's called Umbrela
While in VS code, press CTRL SHIFT P > Open addon manager > Search Umbrela > Active it
Thank you. Going to look into that. VS Code will run in Linux I believe, yeah?
No idea
Yeah
Nice!
Sublime Text will do autocompletion as well, but it didn't look like anyone had made a library for PZ modding for it and I don't really want to take the time to do it myself. 😅
umbrella might work for other ides too, they just need to support luacats/emmylua annotations
the target platform for umbrella was originally actually intellij, but i don't recommend it for pz anymore
How does the Discord interactions work in Lua?
For example: How do I send a Message to Discord In Lua?
I wanna make context option, that will send window like trade window to the recipient with yes / no, in vanilla is using event Request Trade, say me pls how can I send this window cuz my attempts run into the fact that the window is sent to the self requester
ISWorldObjectContextMenu.CreateContextOption = function(worldobjects, player, otherPlayer)
ISTradingUI.Showchoosewindow(player, otherPlayer)
end
ISTradingUI.Showchoosewindow = function (player, otherPlayer)
local modal = ISModalDialog:new(getCore():getScreenWidth() / 2 - 175,getCore():getScreenHeight() / 2 - 75, 350, 150, getText("IGUI_TradingUI_RequestTrade12", player:getDisplayName()), true, nil, ISTradingUI.onAnswerTradeRequestsomething);
modal:initialise()
modal:addToUIManager()
modal.requester = player;
modal.recipient = otherPlayer;
modal.moveWithMouse = true;
ISTradingUI.tradeQuestionUI = modal;
end
Events.RequestTrade.Add(ISTradingUI.Showchoosewindow)
Create a webhook in discord for your server and then send a post request to the webhook endpoint from lua (discord has docs on how to format the body)
You could probably use luasocket lib maybe for http stuff
How can I add an image to a trait? TraitFactory.add has no params for image name
I think by just having the image be in media/ui/Traits/ and called something like trait_id.png so
TraitFactory.addTrait(StringID, LocalizedName, Cost, LocalizedDescription, singleplayerOnly?)
-- ex.: TraitFactory.addTrait("Custom", getText("trait_custom"), 0, getText("trait_customDesc"), false);
-- ^-^-^-^ Determines the file name
-- image will be taken from: [media\ui\Traits\trait_custom.png]
```(ALTHOUGH I might be wrong, but I think that was the case)
ooo
I went through the hassle of packing my images like the game does in media/texturepacks lol
fun fact the last parameter is whether the trait is a profession
||psssht, don't let anyone know I have no clue!|| Good to know 👀
dw this is my first mod 😭
Guys, who know how to transfer tiles from existing game like:
i create game, build construction with my tileset, after i change tileset number for my mod - tiles continue exist in world, but invisible, i can bump with them
No clue myself, however, I'd reckon people over at #mapping might have potentially stumpled upon such an issue before and might have a workaround solution, considering it's related to tiles
And that's why you don't change tiledef number mid-save. This is how chunks can be corrupted.
i can smash them with sledgehammer 
but okay
just i think here should be workaround, like okay, i change tiledef number, but this tile should be set in world with their name lake demonius_vaccine_01_0 for example, but yep, it's invisible now, and if we make some stuff with Events.LoadGridsquare.Add(onLoadGridsquare); and getObjects() in square and do something stuff like setSpriteFromName() (how would we reload the sprite something like that) with some flag (in modData for example) for not trigger everytime... But im not sure how it's should be in complete code...
and will it work at all?! idk
---@param square IsoGridSquare
local function GetOldTileSetFromSqure(square)
if square then
local objects = square:getObjects();
for i=1, objects:size()-1 do
---@type IsoObject
local isoObject = objects:get(i);
if isoObject:???() then -- Take name from tiles... not sure how it be...
return isoObject;
end
end
end
end
---@param _square IsoGridSquare
local function zReVAC2TransferFrom1to2(_square)
local LabMoveablesTileNew = GetOldTileSetFromSqure(_square);
local modData = LabMoveablesTileNew:getModData();
local flag = modData.zReTransferTilesFlag;
if LabMoveablesTileNew and not flag then
LabMoveablesTileNew:setSpriteFromName(?!?!); -- something here should be...
if isServer() then
LabMoveablesTileNew:transmitUpdatedSpriteToClients();
LabMoveablesTileNew:transmitModData();
end
flag = true;
print("Reloaded LabMoveables at [x:" .. LabMoveablesTileNew:getX() .. " y:" .. LabMoveablesTileNew:getY() .. " z:" .. LabMoveablesTileNew:getZ() .. "]");
end
end
Events.LoadGridsquare.Add(zReVAC2TransferFrom1to2);
+-
Well that's the problem, iirc IsoSprite is null for those objects.
And you can't tell the difference between them.
okay, sprite null, but this is tile exist in world like object(invisible object), then we can set sprite for them, nope?
changed tiledef number => isoSprite swap to null (nil etc) => just getObject and setSprite again?!
But how do you know what sprite it had before you changed the number.
F2 and select the tile
See ? That s the issue
OU OU OU!!!
Here contain modData! if i'm drop something in modData before change tileDef it's should be transfer when im change tileDef number?
That is, in essence, i can trigger an object based on the contents in modData
and remove from world (easy way for not swap every tile)
Well, yeah. But you want you to change tiledef to an already released mod?
i'm released vaccine 2.0 and change tiledef number, because author of Enhanced Enviroment (spoon) use same tiledef number and and I'm tired of explaining to everyone why the mod doesn't work for them.
People want to switch on 2.0, but it's have problem with this about we speak
For now I recommend everyone to start a new game, but im trying figure out into switch solution
in old mod -> event drop flag in mod data
in new mod -> event remove object with flag in mod data
Those who are unlucky are unlucky - they will have to wave a sledgehammer into the void...
it's right method for trying return object by name like:
---@param square IsoGridSquare
local function GetOldTileSetFromSqure(square)
if square then
local objects = square:getObjects();
for i=1, objects:size()-1 do
---@type IsoObject
local isoObject = objects:get(i);
if string.find(isoObject:getName(),"demonius_vaccine_") then -- <<< HERE
return isoObject;
end
end
end
end
---@param _square IsoGridSquare
local function zReVAC2TransferFrom1to2(_square)
local LabMoveablesTileNew = GetOldTileSetFromSqure(_square);
local modData = LabMoveablesTileNew:getModData();
local flag = modData.zReVACTransferTilesFlag;
if LabMoveablesTileNew and not flag then
flag = true;
if isServer() then
LabMoveablesTileNew:transmitUpdatedSpriteToClients();
LabMoveablesTileNew:transmitModData();
end
print("Flagged for LabMoveables at [x:" .. LabMoveablesTileNew:getX() .. " y:" .. LabMoveablesTileNew:getY() .. " z:" .. LabMoveablesTileNew:getZ() .. "]");
end
end
Events.LoadGridsquare.Add(zReVAC2TransferFrom1to2);
nobody can help my ?
Ask in #modeling more people worked on vehicles there
thanks
i want to increase the fall/failure chance for climbing walls and fences. Does someone know what the lua file for that would be?
You need to save the texture in modData, so that after changing the tiledef number you can change to the new one (which will have the same name).
-- Lookup table for better performance
local vaccineTextures = {
["demonius_vaccine_1"] = true,
["demonius_vaccine_2"] = true,
["demonius_vaccine_3"] = true,
["demonius_vaccine_4"] = true,
};
---Finds an IsoObject with a texture name present in the vaccineTextures table.
---@param square IsoGridSquare
---@return IsoObject, string The IsoObject and its texture name if found, nil otherwise.
local function findVaccineIsoObject(square)
local objects = square:getObjects();
for i = 1, objects:size() - 1 do
local isoObject = objects:get(i);
local textureName = isoObject:getTextureName();
if textureName and vaccineTextures[textureName] then
return isoObject, textureName;
end
end
return nil, nil;
end
---Transfers vaccine-related object texture from one IsoObject to another in a given square.
---@param square IsoGridSquare
local function transferVaccineData(square)
if not square then return; end
local vaccineIsoObject, vaccineTexture = findVaccineIsoObject(square);
if not vaccineIsoObject then return; end
local modData = vaccineIsoObject:getModData();
local transferTileTexture = modData.zReVacTransferTileTexture;
if not transferTileTexture then
transferTileTexture = vaccineTexture;
vaccineIsoObject:transmitModData();
print(string.format("Flagged for LabMoveables at [x:%d y:%d z:%d]", vaccineIsoObject:getX(), vaccineIsoObject:getY(), vaccineIsoObject:getZ()));
end
end
Events.LoadGridsquare.Add(transferVaccineData)
holycode
okay, it's keep in moddata TextureName, but how to rebuild this after
we came to something like that
local BlaBlaBlator = {
["demonius_vaccine_01_0"] = true,
["demonius_vaccine_01_1"] = true,
...
["demonius_vaccine_01_100"] = true,
}
---@param square IsoGridSquare
local function zReVAC2TransferFrom1to2(square)
local objects = square:getObjects();
for i = 1, objects:size() - 1 do
local object = objects:get(i);
if BlaBlaBlator[object:getTextureName()] then
object:removeFromSquare();
object:removeFromWorld();
if isServer() then
object:transmitUpdatedSpriteToClients();
end
print("Removed LabMoveables at [x:" .. object:getX() .. " y:" .. object:getY() .. " z:" .. object:getZ() .. "]");
end
end
end
Events.LoadGridsquare.Add(zReVAC2TransferFrom1to2);
but it's rough method with remove xD
Then don't, you can set the sprite back.
---@param square IsoGridSquare
local function resetVaccineObjectSprite(square)
if not square then return; end
local vaccineIsoObject, _ = findVaccineIsoObject(square);
if not vaccineIsoObject then return; end
local modData = vaccineIsoObject:getModData();
local transferTileTexture = modData.zReVacTransferTileTexture;
if transferTileTexture then
vaccineIsoObject:setSprite(transferTileTexture);
vaccineIsoObject:getSprite():setName(transferTileTexture);
if isServer() then
vaccineIsoObject:transmitUpdatedSpriteToClients();
else
vaccineIsoObject:transmitUpdatedSpriteToServer();
end
print(string.format("Reset sprite for LabMoveables at [x:%d y:%d z:%d]", vaccineIsoObject:getX(), vaccineIsoObject:getY(), vaccineIsoObject:getZ()))
else
print("No transfer texture set in modData, unable to reset sprite.")
end
end
Events.LoadGridsquare.Add(resetVaccineObjectSprite)
MOTHER EARTH WILL PROTECT YOU
Just posting that here in case any mod creator need it, but if you need some French translations for your mods, don't hesitate to ask me 🙂
I'm absolutely interested in getting translations 😄
I’ve been mulling over an idea and am curious. Is a complete overhaul possible? And if so should it wait till close to or for 1.0? I recall reading somewhere some big back end changes were coming I think.
Cool, is it for one of your mod? a mod on the workshop?
Yep! I'm going to be updating it very soon, though, and the update will have some new strings—is it okay if I DM/mention you when they're ready?
ok 🙂 yeah sure ! send me the files when its all good for you !
I think I need to add the necessary meta files to make the propane stations mod I inherited capable of being translated... I should really get on that.
Anyone have used SF's Vehicle Tweaker to add skin texture?
I tried this and it won't work
TweakVehicle("Base.63Type2VanApocalypse", "skin", "Vehicles/Vehicles_63Type2VanApocalypse")
TweakVehicle("Base.ATASamaraClassic", "skin", "Vehicles/ATA_Samara")
Based on this it should load like this
if t:contains("skin") then
vehicle:Load(name, "{".."skin".."{ texture ="..y..",}".."}");
{ skin { texture = "Vehicles/<yourvehicleskinpng>", } }
but it won't work for me
looks good now i missed this part
require("VehicleTweaker_Core");
Hi guys I'm using
player:getEmitter():stopSoundByName(sound)
to stop a sound emitted by a player, the problem is that is stopping the sound just for the player emitting it, not for the whole server...
what should I use instead?
getSoundManager():PlayWorldSoundImpl("BreakMetalItem", false, FightStep.zombieMomSpawnX, FightStep.zombieMomSpawnY, 0, 0, 20, 1, false);
try this maybe
if getSoundManager():isPlayingMusic() then getSoundmanager():Stop() end
I'm curious as well so i checked
uhm, is this working when the emitter is a player?
I haven't tried but that's from vanilla, just set the X, Y, Z to player's location
https://projectzomboid.com/modding/zombie/BaseSoundManager.html you can find more here. Try the functions available
declaration: package: zombie, class: BaseSoundManager
where is your player:getEmitter():stopSoundByName(sound) located? client folder? you may need to have it on server or shared
it's on server
is playing fine for everybody, but when I try to stop it stops just for the player that is the "emitter"
try stopAll()
I have this though it's from zombie but I'm sure they have the same getEmitter() function
zombie:getEmitter():playSound("your sound file")
if (zombie:getEmitter():isPlaying("your sound file") then
zombie:getEmitter():stopAll()
end
uhm... could work
Working for me so worth a try to check
What's the best way to inject tooltips? I keep getting comments that my mods are interfeering with other mods tooltip, and I'm not sure about what todo 😅
it depends on where you wanna add them. you can just do like vanilla does in similar places.
I need to add text under the item tooltip, example, like this:
@pseudo apex are you just trying to make all literature be replaced with paper after it's been read?
If so, there is an even easier way to go about this, and you can do it with a loop. One second and I can show you.
Yes, papper or another items. I just want to learn for now 😄
You can find all of the methods for ScriptManager here: https://projectzomboid.com/modding/zombie/scripting/ScriptManager.html
In there you will find the method getItemsByType
declaration: package: zombie.scripting, class: ScriptManager
and then replace the itemtype ?
so the problem is to modify existing tooltip, I do not know much about compat there. Maybe check food expiry mods (there are at least 2) or ExtraSauce Quality of Life.
Nope, that will just change the type of the item, and not the item itself.
You should be able to do:
local Literature = ScriptManager.instance:getItemsByType("Literature");
for i,Item in ipairs(Literature) do
if Item then
Item:DoParam("ReplaceOnUse = SheetPaper2")
end
end
That should make it so any time you use a literature item it is replaced with the SheetPaper2 item.
Thank you, I'll have a look
Hello guys
I am trying to foraging a new item, but i am not able to find it... is this code right?
**
require "Farming/ScavengeDefinition";
-- forest
local PiecesOakWood = {};
PiecesOakWood.type = "Base.PiecesOakWood";
PiecesOakWood.minCount = 1;
PiecesOakWood.maxCount = 2;
PiecesOakWood.skill = 1;
table.insert(scavenges.forestGoods, PiecesOakWood);
table.insert(scavenges.Metals, PiecesOakWood);
table.insert(scavenges.medicinalPlants, PiecesOakWood);
table.insert(scavenges.Dyes, PiecesOakWood);
table.insert(scavenges.insects, PiecesOakWood);
**
how do i make my own 3d model? i would like to make my own mod. A 3d model of rick grimes belt
You should ask in #modeling I would think. The people in that channel are going to be more knowledgeable in regards to your question.
okay, thank you
What item/furniture property denotes an object has additional game functions? such, where do I define that an item is a stove, for example
This is just a hunch, but I don't think inserting data into a table is going to achieve what you want here. You have to remember that the lua (Kahlua in this case) is just providing an API for modding. I don't think there is a 1:1 correlation with a Lua table and a Java array (as in the Java side just accepts an insert into that table and updates the array on it's side) and that makes that specific table "read only" from the Lua side in that sense. I could be wrong...
Give me a second and I'll look around for instructions on adding items to scavenging groups.
I believe that falls under tile properties. I remember looking into it before, but I don't remember specifics, sorry. Here's the wiki page on tile properties though: https://pzwiki.net/wiki/Tile_properties
Great, thanks, I'll take a look
Follow up question, I've found the tile tag for what i need, but notepad++ doesnt render all the characters in a .tiles file, whats the common editor/is there an extension needed for tiles files?
i will take a look. thanks!
That response was for Kopernicus. Still looking around for scavenging stuff. 😂
oh yea I realized right now xD
You need to open that file in TileZed, search for Project Zomboid Modding Tools in your library
And then in Steam folder
Got it, I downloaded it from the forums, was trying to open a tiles file as a map, watching dirkies tutorial now lol
Yeah, that's what I was gonna recommend, waching DDD's tutorials.
So I see where you got this info from, but I think the foraging system was updated since this post was made? You got it from here, correct? https://theindiestone.com/forums/index.php?/topic/22582-question-is-there-way-to-make-forageable-items/#comment-257886
Yeah, with lua. File created should be placed in MyMod/media/lua/server/Farming/ require "Farming/ScavengeDefinition"; local MyItemThingy = {}; MyItemThingy.type = "MyModModule.MyItem"; MyItemThingy.minCount = 1; MyItemThingy.maxCount = 1; MyItemThingy.skill = 3; table.insert(scavenges.forestGood...
Interesting, just saw your post in modeling @manic magnet , with the mod you took over for propane filling. I'm workoing on a nomad/camping series of items, currently working on a propane 2 burner camping stove
Nice!
I saw theres an old mod for small propane bottles, but I'm not sure if I should just implement my own small propane bottle
to keep away from any additional mod requirements
The current ones don't work for you?
Oh... burner stove.
Yeah, those might be a bit oversized for that. 😂
Yeah thinking those little green disposable bottles
also helps to balance out that you'd have a stove you could carry in your backpack/put on a container, if the resource to use it isn't super common
That would be dope. Let me know if you do that and I'll add compatibility for using them in the Propane Station mod.
That way you can fill em up. 😂
Just getting into PZ modding, so I'll need to take a look at how to add compat without require a mod. I assume I can/on your end you can do an if else to allow interaction without requiring/importing?
Yep. Exactly. Just a conditional checking for the existence of the other mod. It would be easier to do it on my end otherwise you would end up having to rewrite the function I use for refilling the tanks, or basically copy and paste it into your mod. For me it's going to be just adding the new propane tank to the list of ones you can refill. 😂
Great, if you don't mind im going to send a DM with just a reminder to message you when I get to that point of modeling the bottle
@pseudo apex did you message me here? I am unable to see what you wrote, for some reason.
I tried this but couldn't get it to work.
I think I'm doing something wrong.
Anyone know a way to get from Item to AlarmClock type without converting the item type to AlarmClockClothing?
Was there an error?
getItemsByType means 'type' as in the unique name of the item, this would only return items named Literature
also, you cannot use ipairs to loop through an arraylist
No,
local Literature = ScriptManager.instance:getItemsByType("Literature");
for i,Item in ipairs(Literature) do
if Item then
Item:DoParam("ReplaceOnUse = SheetPaper2")
end
end
What?
Also what?
'type' refers to the script name of the item (e.g. 'Base.Apple') in most places in the code
but they also use 'type' to mean what you're intending so the language is really just inherently confusing 😓
that method returns an arraylist, ipairs and pairs are only for looping through lua tables
Well... that's silly...
something like this would be closer to what you're intending:```lua
local items = ScriptManager.instance:getAllItems()
for i = 0, items:size()-1 do
local item = items:get(i)
if item:getTypeString() == "Literature" then
item:DoParam("ReplaceOnUse = SheetPaper2")
end
end
Yep, that's basically what I was about to suggest moving to.
getAllItems then check for the type. Maybe I should write a library for making this stuff more intuitive.

So basically... I gave you some bad info there, sorry @pseudo apex 🤣
It doesn't help when you get bad advice from someone. 😂 I get now that they were going for more of an "objType" sort of reference, but that's super confusing given that Items have a Paramater called Type. 🤪
Magazines turn into sheets of paper, but books don't.
I had forgotten that table != array. Good looking out! ❤️
Actually... looking at it more, I think that might just be a Kahlua thing. I'm pretty sure there is no such thing as an arraylist in standard Lua, which would explain why I confused that as well. 😂
Yes i got it from there... is there someplace where new system is defined?
I'm not even certain there is a new system, or if so, that it is defined anywhere. It looks like people saying there was a new foraging system created in 4.1 but I don't remember now how long ago 4.1 released. 😂
I've got a mind like a sieve. 😁
oK!
that's right! an arraylist is a java object
it's not unusual for lua implementations to give you 'foreign' objects like that, though i've seen many of them put more effort into making things seamless (such as letting you loop with pairs)
Thanks for the help @bronze yoke, you're awesome. 😁
I seriously think I'm going to write a lua library for managing things in ScriptManager... even if it's just doing basic things like adding the ability to search through the Items to find Items by a specific type, or pushing an arraylist into a table for reading instead. 🤪
Check out my latest mod. Enjoy! 😉
https://steamcommunity.com/sharedfiles/filedetails/?id=3217685049
I like the Jeep looking things and the Hearses. 😂
the new foraging system is entirely lua, i think it mostly lives in shared/Foraging/ and client/Foraging/
Yeah. I actually should have realized this. A long long time ago (like in 2008? 2009? maybe it was earlier... I forget) I actually wrote my own module for Apache that embedded Lua and exposed the Apache SAPI methods to it so I could write web apps in Lua.
People since have done it way better and less crude than I did, but I was definitely one of the first people doing it. I remember struggling with similar issues then and having to figure them out.
Correct! shared/Foraging is what you want to understand here @rough aurora
Specifically ProjectZomboid\media\lua\shared\Foraging and there are two files there forageDefinitions.lua and forageSystem.lua
Those are what I am looking at right now, trying to figure out if there is a function here that will allow you to simply insert a new item into the foraging loot table...
I see on forageDefnitons the same i did
--old scavenges table (for backwards compatibility)
scavenges.forestGoods = {};
i will take a look both files
Yep. You are correct. However I am also seeing these local functions in forageDefinitions these local functions like:
generateBerryDefs()
...
generateMushroomDefs()
...
generateHerbDefs()
And those appear to have static item tables like this:
local items = {
generic = {
chance = 1,
spawnFuncs = { doWildFoodSpawn, doRandomAgeSpawn },
items = {
Basil = "Base.Basil",
Chives = "Base.Chives",
Cilantro = "Base.Cilantro",
Oregano = "Base.Oregano",
Parsley = "Base.Parsley",
Rosemary = "Base.Rosemary",
Sage = "Base.Sage",
Thyme = "Base.Thyme",
},
},
};
And the weird thing is... the function is declared and then called immediately after. 🤔
Oooooh... No I get it now!
local function generateHerbDefs()
local items = {
generic = {
chance = 1,
spawnFuncs = { doWildFoodSpawn, doRandomAgeSpawn },
items = {
Basil = "Base.Basil",
Chives = "Base.Chives",
Cilantro = "Base.Cilantro",
Oregano = "Base.Oregano",
Parsley = "Base.Parsley",
Rosemary = "Base.Rosemary",
Sage = "Base.Sage",
Thyme = "Base.Thyme",
},
},
};
for _, spawnTable in pairs(items) do
for itemName, itemFullName in pairs(spawnTable.items) do
forageDefs[itemName] = {
type = itemFullName,
minCount = 1,
maxCount = 3,
xp = 5,
rainChance = 15,
categories = { "WildHerbs" },
zones = {
Forest = spawnTable.chance,
DeepForest = spawnTable.chance,
Vegitation = spawnTable.chance,
FarmLand = spawnTable.chance,
Farm = spawnTable.chance,
TrailerPark = spawnTable.chance,
TownZone = spawnTable.chance,
Nav = spawnTable.chance,
},
months = { 3, 4, 5, 6, 7, 8, 9, 10, 11 },
bonusMonths = { 8, 9, 10 },
malusMonths = { 3, 4 },
spawnFuncs = spawnTable.spawnFuncs,
};
end;
end;
end
generateHerbDefs();;
Dangit... There, that's better.
Use the back tick three times to format code. ` <-- This character. Also sometimes called a 'grave'.
i dont know how to quote xD
It shares the same key as the Tilde. 😁
And then you can close it with three more back ticks.
Sorry. So three back ticks on the top and then three underneath. Yep!
`
require "media/lua/shared/Foraging/ScavengeDefinition";
local function generateNewItems()
local items = {
generic = {
chance = 1,
spawnFuncs = { doWildFoodSpawn, doRandomAgeSpawn },
items = {
newitem = "Base.newitem",
},
},
};
for _, spawnTable in pairs(items) do
for itemName, itemFullName in pairs(spawnTable.items) do
forageDefs[itemName] = {
type = itemFullName,
minCount = 1,
maxCount = 3,
xp = 5,
rainChance = 15,
categories = { "WildHerbs" },
zones = {
Forest = spawnTable.chance,
},
months = { 3, 4, 5, 6, 7, 8, 9, 10, 11 },
bonusMonths = { 8, 9, 10 },
malusMonths = { 3, 4 },
spawnFuncs = spawnTable.spawnFuncs,
};
end;
end;
end
generateNewItems();;
I think that might work, because forageDefs is the table you are trying to update here, yes...
i am just starting modding the last week and trying to figure out too many things jajaj
I totally understand. 😂
i will come back if it works 🙂
I've spent way too much time modding games instead of playing them. It's an entire rabbit hole. 😂
well, and if it is not working jajaj
if you open with ```lua it'll have syntax highlighting too
albion out here with the real tips. 😁
is there a function in the game that removes traits so they dont appear in the character creation screen?
or do I just edit the already existing code for those traits so that they cant be picked
This is a fake link. Please don't click it. <@&671452400221159444> might want to remove this.
Thanks, they were already banned but that wasn't caught for some reason
It is working! At least doing the following 🙂
´´´
require "Foraging/forageDefinitions";
forageDefs.PiecesOakWood = {
type = "Base.PiecesOakWood",
skill = 0,
xp = 5,
categories = { "Insects", "FishBait", "Firewood" },
zones = {
DeepForest = 15,
Forest = 15,
Vegitation = 10,
FarmLand = 10,
Farm = 10,
TrailerPark = 5,
TownZone = 5,
Nav = 5,
},
bonusMonths = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 },
itemSizeModifier = 5,
isItemOverrideSize = true,
}
´´´
nvm I think I figured it out
Great job! I am super happy that you got it figured out! ❤️
how do I spawn a zombie through lua scripting (latest stable release)
I also just need the function name i've been scripting for 5 years 💀
I am encountering an error where the mod breaks the game due to the metatable not being properly initialized
first script returning the list of the traits
local old_getRightLabel
if Trait and Trait.class and __classmetatables[Trait.class] and __classmetatables[Trait.class].__index then
metatable = __classmetatables[Trait.class].__index
old_getRightLabel = metatable.getRightLabel
metatable.getRightLabel = function(self)
local label = self:getLabel()
local volatileStruct = volatileTraits[label]
if volatileStruct and volatileStruct.costFunc then
local cost = volatileStruct.costFunc(volatileTraits)
local sign = (cost > 0) and "-" or (cost < 0) and "+" or ""
cost = math.abs(cost)
return sign .. cost
end
return old_getRightLabel(self)
end
end```
second script checking if the names = the name of the trait that's supposed to be removed
```local RemoveTraits = {}
RemoveTraits.RemoveTrait = function()
local ccp = MainScreen.instance.charCreationProfession
local traits = TraitFactory.getTraits()
for _, trait in pairs(traits) do
if trait then
local label = trait:getLabel()
-- Check if the trait label matches "Resilient" or "ProneToIllness" and remove it
if label == "Resilient" or label == "ProneToIllness" then
ccp.listboxTrait:removeItem(label)
ccp.listboxBadTrait:removeItem(label)
print("Removed trait: " .. label)
end
end
end
end
Events.OnConnected.Add(RemoveTraits.RemoveTrait)
return RemoveTraits```
revised it a couple of times but still the same error
it always breaks on speed demon for some reason
what error are you getting?
where is volatileTraits declared?
in here (line 10-11) I think I have a feeling what the problem is
local old_getRightLabel
if Trait and Trait.class and __classmetatables[Trait.class] and __classmetatables[Trait.class].__index then
metatable = __classmetatables[Trait.class].__index
old_getRightLabel = metatable.getRightLabel
metatable.getRightLabel = function(self)
local label = self:getLabel()
local volatileStruct = volatileTraits[label]
if volatileStruct and volatileStruct.costFunc then
local cost = volatileStruct.costFunc(volatileTraits)
local sign = (cost > 0) and "-" or (cost < 0) and "+" or ""
cost = math.abs(cost)
return sign .. cost
end
return old_getRightLabel(self)
end
end```
that's volatileTraits being used, where is that table actually created?
Sorry. I looked all over for it, but couldn't find it.
I didn't have it before
aren't you the guy who made Balance Traits?
tcherno made balance traits, but it's based on something i wrote for one of my mods
I used some code of yours and changed it around to see if I could get it to do a different thing
its for a private server with a few friends so I wont publicly release it anyway
albion is a gal. 😅
don't worry, doesn't bother me, it's been planned to end up in a public library forever but i haven't gotten around to it yet
I use it regardless of gender but if she prefers somethings else thats fine with me lol
Anyone know if there is already an existing function to determine what platform a player is on? IE Windows, Mac, Linux... Implementing platform specific wrapper logic
Yeah, it's not uncommon for people to say "Hey guys" or the like to a group of people of various genders for sure. lol
I just try not to myself. Not a critique, just an observation in case you weren't aware. 😁
There are some ways in Lua, but they are cumbersome and unsure if zomboid devs have anything already in their code.
idk if this structuring even makes sense this is like my third mod and first trait mod
phat rip
alright I just straight up deleted GetTraitList and instead used VolatileTraits and it gave me the same error message as before
VolatileTraits
local function setVolatileTrait(trait, func)
local initialCost = trait:getCost()
volatileTraits[trait:getLabel()] = {trait = trait, cost = initialCost, costFunc = func}
end
local function getVolatileTraits()
return volatileTraits
end```
RemoveTraits
```local RemoveTraits = {}
RemoveTraits.RemoveTrait = function()
local ccp = MainScreen.instance.charCreationProfession
local volatileTraits = getVolatileTraits()
for _, volatileStruct in pairs(volatileTraits) do
local trait = volatileStruct.trait
local label = trait:getLabel()
if label == "Resilient" or label == "ProneToIllness" then
ccp.listboxTrait:removeItem(label)
ccp.listboxBadTrait:removeItem(label)
print("Removed trait: " .. label)
end
end
end
Events.OnConnected.Add(RemoveTraits.RemoveTrait)
return RemoveTraits```
getVolatileTraits is a local function, you can't call it from another file
but volatileTraits has to be in the traits folder
spawning zombies might be a Java specific call thing?
Made a way to determine platform 🙃 tis messy but works
can I just make it global
honestly it's 5 am right now where I am I think I am cooked
this could have saved me alot of time I think this will finally be my salvation
ehh xD it's good, but after swap tileset moddata from invisible object drops too 
@bronze yoke also just realised he also credited you for helping him seems like you know your way around traits
Any chance any modders could tell me how I could attach custom data to a vanilla corpse?
Like globally synced custom data attached to a corpse? [I'm guessing using the mod-data but I don't know if thats just for data or item data]
Any chance anyone could also tell me any leads how I could call a function to attach said data to the item upon the death of the zombie?
[My best guess is I'd send it from the client that killed the zombie to the server once they kill the zombie, then the server would propagate it to all the clients maybe.]
(I'm going to start reading the documentation n see if theres any leads there)
Seems like I found the event called "OnZombieDead" going to be looking into that more...
Does changing an item's category change it's spawnrate? I can't tell if it's placeabo effect or maybe I am just lucky.
Noticed a bug in VehicleZOneDefinition.lua
Any way to verify if devs are aware of this?
considering there's not a single instance as far as I can see where this value is ever set above 0 and not all parts including this field - i think it's just leftovers from initial copy-paste with no real effect whatsoever, since it's always set to 0 in trailerpark case. (~~I'd assume 0 would be taken as default as well, if none is provided, so 🤷♂️ ~~ correction: default seems to be 5 supposedly. So unsure if those one's should've been set to 0 or are just leftovers from copying) Though that'd just be my guesses
Maybe it's to be sure that trailerpark won't spawn in those specific areas ? (if there are some generic spawn rates somewhere) Like an overwrite of some sort.
it's not targeting those zones though, it's setting the same value on the trailerpark zone repeatedly, it's definitely a typo
i'd search the forums for it and make a post if there isn't one, but i wouldn't really expect much to come of it
the game isn't really receiving updates right now and they don't tend to pay much attention to 'invisible' issues like this (has *anybody* noticed the effects of this?)
Anyone knows if @keen frost is still around ? I would like to implement Insurgent Mod backpacks support in Noir Attachements .
Can furniture from 2 tiles be added together or does everything have to be separate?
#mapping message
You can specify the tile position in a multi-tile object via the SpriteGridPos property.
Are there any other m_AttachBone specifications other than the wrist and the head?
Maybe I just don't know where to look for them but I'm making a new static item that I don't want to model onto the head or a wrist 😄
Found 'em. If anyone ever wonders about this they're in the base character model, and you can find 'em in Blender
Hi all
I was working on my mod and ran into issues communicating tile interactions between server and client
Long story short I am trying to add a charcoal mound to my mod (placeable by build menu) and I am trying to mimic the interaction that is avaliable on the metal drum, just to light it, a timer while its burning, then harvest when its ready
But I've tried to mimic the simple system that exists on the tent tile and was getting no communication between server and client, so instead I pivoted to trying to replicate the MetalDrum configuration and still no sign of any communication when trying to send commands between server and client
if anyone is familiar with these systems or has any experience in doing anything similar I'd really appreciate any help or examples
Those are Global Object. You can use Global Object interface from TchernoLib mod that I (subjectively) consider simpler than Vanilla Global Object Management. Everything is described in TchernoLib dedicated thread. Moats and Portal Gun mods are exemples that use this. Moat is simpler.
thanks you so much friend
this sounds perfect for what I need, and I was really struggling to find any answers on my own, will give it a try
Reason: Bad word usage
hey would anyone be willing to make a stat change mod for fixing facemask insulation? 🙂
it would be great for cryogenic winter, currently a dust mask makes your head perfectly insulated
it would be nice to let my character freeze to death like they deserve
maybe you can use the "remove fabric" from ReCut mod. https://steamcommunity.com/sharedfiles/filedetails/?id=2889428155
Hey, i've added an item of type moveable like this
item EmptyPot
{
Type = Moveable,
Icon = Pot1,
Weight = 2.0,
DisplayName = Empty Pot,
WorldObjectSprite = pot1,
DisplayCategory = Gardening,
}
pot1 present is in my .pack file, also the icon is correctly found in textures folder
The problem is that the item cannot be placed to the world - place item option does not do anything. Also when I add item to my inventory via admin, it gives an error: "Warning: moveable not valid"
What am I missing here? Do I need to make tiles file for that to work?
Anyone know where I can find information on vehicle spawning conditions that aren't covered in VehicleZoneDefinition.lua? Looking for specific conditions like the tire change event, manhole event, and pedestrian collision, and car collision events
vehicle stories are handled in java, poke around the zombie.randomizedWorld.randomizedVehicleStory package
mind pointing me further where I can find that? Is that in the same higher-level path that shared/ is located in?
Hey modders, i would like to do a simple thing, its to add an item to the zombies loot table. Anyone could tell me how i can do that? thanks 🙂. I would prefer create my own "mod" than editing the base game files.
from what i just read on google, i have to make a .lua with first line "require items/suburbdistributions" and then after add the insert() lines but im not sure how to write them correctly, if i have to add other things to the file etc..
@lusty karma I try to answer you simply, you need to make a .lua file, with a function (let calls it "addLootToZombie"), and add at the end of your file : Events.OnZombieDead.Add(addLootToZombie);
This will call the function when a Zombie dies. And in your function you can do whatever you want.
Example :
function addLootToZombie(zombie)
local inv = zombie:getInventory();
inv:AddItems("Base.Nails", 1);
end
This will spawn 1 Nail in every zombie that dies.
If you want to randomize a little you can add something like :
if ZombRand (1, 101) >= 50 then
inv:AddItems("Base.Nails", 1);
end
then it will have about 50% chance to spawn a Nail. It's a little raw, but I think you can start from here.
put your .lua in mods>Yourmod>media>lua>server for example.
Anyone have any leads on mod data? I'm reading the documentation and I'm a little lost on it (bit rusty with mod data).
Also, does anyone know if I can call code based on the creation of a corpse? [first one is corpse class, second is isoplayer]
Oh thanks a lot for that explaination, really appreciate. Yeah what i want to try to do is to add the Makarov pistol (from VFE Stalker) to be able to be looted from Zombies, but i want to make them rare. I'll try to make that file tomorrow (its late where i live :p),thanks again, will ask if i need help ^^
how does one see when events get called? Like in the game cause some aren't completely self-explanatory
OnContainerUpdate specifically
AAA
OnContainerUpdate doesn't seem to be firing at all.. wait I think corpses are just zombies lying down? lmao?
Hey guys, I'm trying my hands out at modding, and I'm struggling to understand how sound is handled. I know what sound file I want to play, but I don't know how to know what "sound SoundName" is associated with it.
What are you trying to do Chopie? Container aren't corpses.
And vice-versa.
But when a corpse is created* it calles the oncontainerupdate function
Does it? Are you certain? 🤔
just tested it rn
albeit in singleplayer client side
and corpses are under the container section on the wiki
Oh... that's wild. I am almost certain that was not the case before...
I have no idea might be bugged lmao im rolling with it tho cause i'd rather do this then use invis items in their inventories ¯_(ツ)_/¯
speaking of which looking at a cannibal mod for reference, im confused is token_Infected and token_Uninfected actually items in the base game?
corpses are containers
your google doc is very cool ty
Was it always that way? I remember trying to use container events on corpses in the past and them not working. 🤔
Maybe I was encountering a bug back then...
while I have some people's attention/there are people here, if any of you have good references for mod data in general lmk
oh and also this threw an error in the OnContainerUpdate, going to debug it more/fix it but just in case heh
I had to restart my world for the event to start to pick up corpses for some reason I dont know why lol
they don't correctly fire all related events, but they are containers
I see.
I must have just tried a couple events that didn't work and then assumed they didn't count as containers.
Things like this infuriate me about modding PZ. 🤣
Bumping my question. All I'm searching for is the file where all the sound files (.ogg) are used so that I can find the one that interests me.
I just want to come back and say you were right, the last parameter is singleplayer only. Before that though there is a profession boolean parameter like this:
TraitFactory.addTrait(id, name, cost, description, isProfession, singleplayerOnly)

I only know that ogg is found under media/sounds and media/music. Maybe look at the example mod as it has some random music stuff in there? or maybe find other mod that uses sound effect
how would I get the MovingObject ID from a subclass? used GetID got a number, but uncertain on if its an ID that is specific to each zombie or not
Oh and also what is the little string/data at the end of the zombie mean?
why kERTHUS XD
my nick without T lol xD
I can only answer the last question which is most likely the address in memory where the instance is at (probably)
Created a new re-texture mod
Boiling Rash
Trypophobia Warning for all these images
Took over a month to finally finish this but I think I got everything properly disgusting enough
Anyone know if the ID from MovingObject is unique and persistent through restarts? (testing now just asking)
also niceee
@gleaming sorrel Holy crap that is gross. Amazing job!
Thank you
This is the first time I've actively focused on making something gross rather than scary
I'm glad it seems to have worked
Now I will brainstorm my next horrendous creation
While again trying to get the moodles of this mod to work
I apologize for bringing up this message from forever ago, but is the ID that gets returned unique and consistent through worlds/saves/loads?
it isn't
is there an ID for zombies that is unique through saves/loads? Or a base ID? Or an item ID?
I'd like to get/make mod data associated with a specific instance of a zombie in the world
could I just use the IsoZombie actually..? as the key I mean
a zombie's persistentoutfitid is mostly* persistent and mostly* unique
like how it says zombie.characters.IsoZombie@278d6ff1
is that unique/what is that ?_?
no, object references are volatile and zombie objects in particular get recycled when they unload
278d6ff1 is the memory address the object is stored at
what about containers or items/objects ?_?
and is that consistent among clients? (both the persistentoutfitid and the memory address, im guessing the memory address is not but yknow)
the outfit id is, the memory address is not
but isn't the outfit ID not unique ?_? or is that the ID used for other stuff like corpses
persistent outfits are zombie-specific (sort of)
they have a separate id space per outfit so there's no conflicts cross-outfit but the zombie-specific part is actually just randomly picking a number between 0 and 500 when it spawns for the first time
so there's no reason it can't have the same id as another zombie, it just usually won't
also if a zombie spawns with a hat, when it falls off their persistent outfit id changes
im trying to get a unique ID associated with the a specific zombie (that hopefully would be the same accross clients like an entity ID or something... but worse case scenario ig I could have the server do most of the grabbing of ID's etc..?)
does the movingobjects ID reference only one moving object per ID per session or does it recycle upon creation of new moving objects/restart of world/server?
also what is the getUID from IsoGameCharacter? (Same questions basically lmao sorry for being insanely annoying)
Im guessing remoteID's are for local multiplayer/remote play or something*
getKeyId from IsoObject ?_?
moving object ids are assigned sequentially from zero in whatever order objects spawn, they don't get recycled but if the object unloads and loads it will have a new id assigned, not the old one
in the case of zombies, a zombie object is never truly destroyed, when they unload they get put into a pool for recycling, so the same id can end up referring to a different zombie
Is it possible to attach items to zombies then? Or even players...? As in give them items that don't despawn when they reload into players views etc?
(I'm starting to think it might be easier to just make invisible items maybe? if thats possible? that contain the data I want and attach them to the zombies.)
(also the getKeyId from IsoObject sounds semi-promising although I don't know what it refers to.. the UID I assume is UI, and the remote is for splitscreen im guessing..)
players can be identified by their usernames
i know you can't put items in zombie inventories and expect them to save but maybe something through the whole attached weapons system might work to that end
In my experience working 20+ years in IT, UID usually stands for either Unique ID or User ID, but I'm absolutely not confident that's what it refers to here in PZ land. 🤣
key id is for doors and locked crates iirc, i don't remember what uid is, remote id confuses me because i know what ids they use for networking and it's not that
You can set player corpses and player transformed zombies to never despawn, I am pretty certain... not sure if that means they would retain any unique identifier through a restart or not, though.
What exactly are you trying to do @abstract cairn? lol
remote id looks like legacy code, it's used in a couple places but it's never set to anything, so it's always the default value of -1
uid isn't used for anything at all and doesn't look persistent
very kewl stuff
Boo. There is a lot of that in the PZ code base as well. lol
so UId, keyId, remoteId, and other dont worky...
Does the server have authority/propogate the ID to the clients or what?
also the attached weapons system as in like attaching weapons to zombies backs n stuff ?_?
Also, I just noticed you mentioned a Google Doc from albion? Why wasn't I informed of a Google Doc? Got a link? 😅
dmed it 👍
the WORST possible case scenario I could try to make a nightmare of a code using times and locations to create data for each zombie retroactively... using mod data I mean..
Turns out, I already knew about the github* doc... I just didn't realize you wrote that tool @bronze yoke 🤣
crap im going to have to do a mix of both items and the custom mod data AAAAAugh
but thatll be expensive to track..
you can mark zombies as revived players to make them save/load properly, including mod data
but if you're trying to do this on a large scale it's not a good idea
Yeah... that would get stupid expensive.
actually could I just use the OnPlayergetDamage, cause apparently it only fires on server for zombies
NP, feel free to tag me again. I think we live in the same country 😉
actually wait how do the server ID's and the client ID's relate like I'm assuming they aren't the same but the server should be somewhat consistent unless restarting no?
[for like using the IsoZombie as an ID I mean]
online id is used for identifying the same zombie on each end
it's used for players too
👀
huge?
but online ids aren't persistent and for zombies they get reused
but at the time of the "event firing" it would be consistent between the client and the server?
By default there is actually a lot of control that clients exhibit over zombies, and that I DO know for certain. As in, clients can request the server to delete zombies (in order to help with client load) if there is over 100 (pretty sure it was 100) on screen at once.
we love the zombie despawn fix mod someone made to avoid the culling of large pops
Yep. I am aware of the patch, but it's done in Java. 🤣
it would, yes
are they persistent through sessions? as in if the server restarts obvi they get a new ID but are they persistent for the time the server is online?
not for zombies
If you needed zombies to have a forever unique ID you could patch it in Java as well, though...
I think theres a way to circumvent it
if the OnlineID for the zombie is the same as server, EVEN if it gets reused later etc, would that be the same OnlineID the client has for the zombie?
I would assume the server has to tell the client what the OnlineID for a zombie is, so that would have to be "yes", right?
I can do rough checks to avoid lag and avoid accidentally adding more data then what it should be/avoid the edge cases of it reusing but if the onlineID is consistent for all clients and servers in the same moment then it should be do-able
yeah, that's what they're for
Huge W
when does it reuse it? in case I can figure out ways to avoid the edge cases lol
I've accepted they aren't going to be consistent through world restarts etc. but I want to know if it reuses it when the zombie dies or somethin like do the ID's "shift" down at a zombie death or player disconnect or no?
it's when the zombie object gets recycled, either when it dies or just gets unloaded
Probably any time a zombie gets unloaded by a client would be one scenario, I would guess.
do the other zombies and other ID's shift though or no
let me check my information here actually
you are a godsend btw if that wasnt apparent
i would guess the ids don't shift down though as that would be kind of expensive and pointless
for players they don't but that is a separate id space
actually huge W you are amazing ty
the only thing I'd need to conceptually understand now/cant figure out would be how the tokens work for the cannibalism core mod
as in this
Zomboid doesn't really have a concept of persistent zombies at all other than player zombies. When your client loads a cell, it loads the zombies in. Those are all randomly generated at that moment. That much I do know. That's why if you move far enough away from a cell that it unloads the cell and the zombies inside it, when you come back they are not the same zombies as before. The server has a concept for the number of zombies in any given cell, but they don't "persist" after the cell is unloaded. That much I am certain of.
yeah, whenever they die or unload on the server (no client is near them) the zombie's id gets unassigned
nothing changes to other zombies' ids
wait nvm i found it
I am in debt to you lmao
they are actually somewhat persistent, the persistent outfit system stores some information about them, mostly appearance
does anyone know if this makes the item invisible/moveable? It gets added to the corpses but I assume it cant be grabbed or seen...
(as well as if I could add custom data types for the items + access that data while it is in a container)
interesting solution, i think moddata would've been simpler though...?
is there a unique ID for containers?
i'm not sure if zombie corpse moddata is persistent, player corpse moddata is, but you can check if a corpse came from a zombie and all zombies are infected
that is persistent through loads*
oh this was just example I'm not using this lmao
I'm more asking if I can attach custom data to a dead body/corpse (and this is how the cannibalism core mod does it so im like "interesting...")
And also if I can access items within a container, and then the data within those items.
and it gets removed when it despawns yes? (so I dont even have to do that now? 👀 )
also do you have any references on how I'd add this or use this/do this?
I know it's possible but I haven't seen any mods that attach custom mod data- except ig for the firearms one? but that seems to just overwrite the items and I dont know if that would cause errors if I just made an item Corpse.Male etc... and added custom data for it
local function onZombieDead(zombie)
zombie:getModData().myKey = 5
end
-- mod data tranfers to the corpse so it should be safe to add it on death
Events.OnZombieDead.Add(onZombieDead)
MOD DATA TRANSFERS TO CORPSE?? THATS INSANE
Waiwaiwai so how would I add it to the zombies then? Would it be like zombie:addModdata()?
that is good to know, glad I lurk on here a lot
been watching me lose my mind then in the past week lmao
you just use getModData(), you don't need to initialise it
So if I attach mod data to the zombie, and they die, it gets transfered to the corpse? So I don't even need to mess with the corpses really except for the reading of the data? (Unless I wanted to mess with the data after they die)
and getModData() can add mod data to it?
also I apologize for asking such newbie questions I haven't messed with mod data in so long I genuinely forgot most of it and you have made me ESTATIC by this possibility
moddata is just a lua table that's attached to an object and saves/loads with it, you don't need to do anything special with it
Can clients attach mod data or can only the server? IE would I have to have the client tell the server to add it or could I literally just add it via the client?
both iirc
I know you can def do it on the client because thats how I do it :p
i'm honestly not really sure what the moddata client/server behaviour with zombies is
zombie moddata isn't persistent so i haven't really used it
and there seems to be different rules for everything 😅
I wonder if you are not allowed to access mod data for zombies if they're not loaded/are culled on the client?
It's not the end of the world if it gets unloaded when the zombie gets recycled or the server restarts etc.
or gets removed even
but if I can literally just attach mod data to the zombie in the world that is a GAME changer
for items only clients can change their moddata and it doesn't save if it's not put into a player inventory afterwards, for most objects both sides can change it but they *must* call obj:transmitModData() or it's at risk of being overwritten by other clients (and whatever state ends up on the server is the one that saves), for players transmission doesn't work at all and only the moddata on that player's client saves (and it only loads there too)
I think I found another bug with vehicle spawn rate
so ideally we have the server handle the saving and transmission
I think that just means that all three types for spawn chance aren't active at once... might be wrong.
As in the spawn zones can only have 100.. or maybe it lies and it can go to 150 lmaO
they also appear to be very similar and have the same index
index determines the skin so that is probably right
do I have to call transmitModData() for player mod data too? Currently I have it so that the client player sets it's own mod data (my mod is pretty much clientside, no serverside code because it doesn't really need any serverside code).
you don't, and in fact it doesn't work for players at all
I have been only testing on solo and have yet to test on server
moddata on that player's client is the only side that saves, you can technically set it from any client/the server but it won't save and it isn't synchronised with the 'real' mod data
So for players I have to manually add it to the corpse?
or do player corpses also inheret moddata from the player
they do
does the mod-data transfer to the zombie if they reanimate? from the corpse I mean
it does
albion if I could I'd buy you a cookie you are a god send ty so much
[10-04-24 21:48:07.283] LOG : General , 1712785687283> 10,057,779,669> -------------------------------------------------------------
attempted index: getBodyDamage of non-table: null.
[10-04-24 21:48:07.285] LOG : General , 1712785687285> 10,057,779,671> -----------------------------------------
STACK TRACE
-----------------------------------------
function: LabRecipes_AdjustPlayerStress -- file: zReVAC2_LabModEngine.lua line # 1046 | MOD: zRe Vaccine 2.0 ReMod by kERHUS.
[10-04-24 21:48:07.286] ERROR: General , 1712785687286> 10,057,779,672> ExceptionLogger.logException> Exception thrown java.lang.RuntimeException: attempted index: getBodyDamage of non-table: null at KahluaThread.tableget line:1689..
[10-04-24 21:48:07.286] ERROR: General , 1712785687286> 10,057,779,672> DebugLogStream.printException> Stack trace:.
[10-04-24 21:48:07.287] LOG : General , 1712785687287> 10,057,779,673> -----------------------------------------
local function LabRecipes_AdjustPlayerStress()
local player = getPlayer();
local pBody = player:getBodyDamage(); -- < 1046 LINE
local pMod = player:getModData();
local pStats = player:getStats();
local pChangesStress = 0;
local pChangerStress = 0.09; -- accumulate ~0.0125 stress per 10 ingame min -- 0,075 per hour
local pChangerStress2 = 0.078; -- accumulate ~0.0125 stress per 10 ingame min (for antibodies) -- 0,075 per hour
if pBody:isInfected() and (pMod.VaccineDecreaseStress ~= nil) and (pMod.VaccineDecreaseStress ~= 0) and not player:HasTrait("zReAntibodies") then
pMod.VaccineDecreaseStress = pMod.VaccineDecreaseStress - 1;
pChangesStress = pStats:getStress() - pChangerStress;
if pChangesStress < 0 then
pChangesStress = 0;
end
pStats:setStress(pChangesStress);
elseif not pBody:isInfected() then
pMod.VaccineDecreaseStress = 0;
end
if pBody:isInfected() and player:HasTrait("zReAntibodies") then
pMod.VaccineDecreaseStress = 0;
pChangesStress = pStats:getStress() - pChangerStress2;
if pChangesStress < 0 then
pChangesStress = 0;
end
pStats:setStress(pChangesStress);
end
end
how local pBody = player:getBodyDamage(); can drop error?!
Events.EveryHours.Add(LabRecipes_AdjustPlayerStress);
if you're testing in multiplayer, getPlayer() doesn't return anything on the server
emmm....
and how to fix it? Oo
getPlayerByOnlineID?
this code seems like it should just run on the client only
oh, u mean this code should be in lua/client?
Placing code in lua/client runs it on the client. Correct.
@hollow wind us getItem(name) from ScriptManager. One second and I can give you an example. https://projectzomboid.com/modding/zombie/scripting/ScriptManager.html#getItem(java.lang.String)
declaration: package: zombie.scripting, class: ScriptManager
this
@hollow wind
local SomeCassette = ScriptManager.instance:getItem("ModuleName.CassetteName");
if SomeCassette then
SomeCassette:DoParam("Weight = 0.1")
end
Then just do that for every cassette you want to update the weight on. Also, you should check to make sure the other mod is installed first. I can't remember how to do that off the top of my head, though.
what if i want to update every casette? is that even possible with multiple true music addons?
Obviously you want to set variables to something that is actually more descriptive and you need to change ModuleName.CassetteName to the actual item.
If cassettes have a distinct type, then probably? Otherwise you would have to do them one at a time.
If they do, use albion's example here but obviously replace the relevant bits. #mod_development message
I'm still iffy on the mod data, is this correct? [the doc]
https://github.com/MrBounty/PZ-Mod---Doc/blob/main/How to use global modData.md
Currently I'm doing to initialize/reset the mod data for the clients character (oncreatelivingcharacter)
local playerObj = getSpecificPlayer(playerOrSurvivor);
playerObj:getModData().ModnameMainData = {};
playerObj:transmitModData();
yeah, though transmitting moddata on player objects doesn't do anything
the mod data is a table yes? so I can add to it as I would a normal table and insert more tables into it as well?
[I'm probably going to make a culling function to remove unneeded data and shift everything for when I iterate over it in the future]
zombie globals
StressFromBiteOrScratch = 0.00005
how much it be for 10 ingame minute?
yeah!
does this get called on the victim and the attacker? or just the attacker? or all clients?
(if it's all clients I can make it only edit the mod data of the victim or attacker by checking the local IsoPlayer against it yeah?)
IDFK MAN I'M SORRY I KEEP MAKING THE MISTAKE BUT I FIXED IT SRY 
It sounds more natural in french possibly lol, also a character ik that's named Karthus so I keep fucking it up xD

Also my new phone making me dyslexic with the new letter positions
can u explain this randomizer function?
local function LabRecipes_RandNorm(min, max, mean, dev)
local u1 = ZombRandFloat(0.01,0.99);
local u2 = ZombRandFloat(0.01,0.99);
local rnd = mean*math.abs(1+math.sqrt(-2*(math.log(u1)))*math.cos(2*math.pi*u2)*dev);
return min+math.floor(rnd/2*(max-min)+0.5);
end
local function BlaBlaBla()
print(LabRecipes_RandNorm(0, 30, 1.1, 0.35))
end
I'm wondering what the range is here.
and what is the difference from ZombRand(N1,N2)?
ZombRand only returns integers
mhmhmh...
but in func return min+math.floor(rnd/2*(max-min)+0.5);, math.floor, +- same, nope?!
i'm guessing it's some kind of weighted random but i'm too tired to work out exactly what it's doing
it generates pseudo-random numbers with a normal distribution. mean (or average) = the value of the distribution. dev = deviation of the normal distribution, which measures the spread of the distribution. The expression used to calculate rnd is the Box-Muller transform which produces a standard normally distributed value. Then this value is then scaled to the desired mean and standard deviation by multiplying by dev and adding mean. Then the result is scaled to the range [min, max] through a complex expression that doesn't directly fit a standard normalization approach.
TLDR: ZombRand(N1,N2) generates a uniformly distributed integer between N1 (inclusive) and N2 (exclusive), each number within the range has an equal probability of being selected.
LabRecipes_RandNorm generates numbers based on a normal distribution, where numbers closer to the mean are more likely to be selected than those far from the mean then tries to fit these normally distributed values into a specific range.
local function generateNormalRandom(mean, stdDev)
local u1 = ZombRandFloat(0.01,0.99);
local u2 = ZombRandFloat(0.01,0.99);
local z0 = math.sqrt(-2.0 * math.log(u1)) * math.cos(2.0 * math.pi * u2)
return z0 * stdDev + mean
end
local function scaleToRange(value, originalMin, originalMax, targetMin, targetMax)
local scaleFactor = (targetMax - targetMin) / (originalMax - originalMin)
return (value - originalMin) * scaleFactor + targetMin
end
local function LabRecipes_RandNorm(min, max, mean, dev)
local normalRandom = generateNormalRandom(mean, dev)
local originalMin = mean - 3 * dev
local originalMax = mean + 3 * dev
local scaledValue = scaleToRange(normalRandom, originalMin, originalMax, min, max)
scaledValue = math.max(min, math.min(max, scaledValue))
return math.floor(scaledValue + 0.5)
end
Fixed the code
thanks king!
conditionally, cutting off all the subtleties.
LabRecipes_RandNorm(0, 30, 1.1, 0.35) same as ZombRand(0,30)?
No, that function's intent is to produce values that are more likely to be near the mean, with the likelihood decreasing as values move away from the mean. ZombRand generates numbers uniformly between 0 and 30 (exclusive), meaning each number within this range has an equal chance of being selected, without any weighting towards a central value or distribution pattern. Here's a simulation to better understand this with 1000 random numbers
I just want to know the range of numbers in this parameter
to see if I understood correctly
I understood about the weight, yep, thanks
but without frequency, LabRecipes_RandNorm(0, 30, 1.1, 0.35) has same range* as ZombRand(0,30)?
I apologize for the problem with the wording of the question, I think it will be clearer this way
Ah, yes it will output a number between 0 and 30
thanks, king :з
where i can try play with this pattern?
python
ahh...
Can someone tell me why this isn't working? (Having trouble with netcode, went into a hosted world to test it).
(Server file)
local function CA_OnZombieDeadServer(zombie)
zombie:getModData().CAMainData = {}
print("Zombie Died Server Side!")
sendServerCommand('CA', 'TestCommand', { message = "Hello! This is sent to client!" })
end
Events.OnZombieDead.Add(CA_OnZombieDeadServer)
(Client file)
local MyModuleServerCommands = {}
function MyModuleServerCommands.TestCommand(args)
print(args.message)
for playerIndex = 0, getNumActivePlayers() -1 do
local playerObj = getSpecificPlayer(playerIndex)
playerObj:Say("Received Message!002");
end
end
local function OnServerCommand(module, command, args)
for playerIndex = 0, getNumActivePlayers() -1 do
local playerObj = getSpecificPlayer(playerIndex)
playerObj:Say("Received Message!001");
end
if module == 'CA' then
MyModuleServerCommands[command](args)
end
end
Events.OnServerCommand.Add(OnServerCommand)
Tooltip_EN = {
Tooltip_MyTooltip = "This is %1%",
}
getText("Tooltip_MyTooltip", 20);
Will do that, thanks 🙂

