#mod_development
1 messages ยท Page 88 of 1
true, yeah. I might just give that a shot, get the sprite manager funcs out of the way to make sure it's not getting the tiles incorrectly for some reason
that'd probably return a index 1 of 0
#{a=1, 1 = "foo", b =2} == 1
yep, until one is missing
I feel like that can be abused for some fun shenanigans
if you have keys 1 and 3 it also thinks its length 1
...am I misunderstanding #? I thought it was effectively Table.Count()/Table.Length (if this were java/C#/whatever)
it only handles numeric keys
as Lua doesn't have lists or arrays - but tables for both
man fuck lua i hate this shit. idk how I tolerated this back in early gmod days, probably because I didn't know anything about programming
but damn this shit is backwards sometimes

I've taken to using multiple tables with shared keys/values
if I need to sort/count the values
kinda like a hash table/dictionary, right?
yeah, which Lua doesn't really have so I imagine everyone will eventually write their own
same way most people write out a for loop to check for a value
this is what the community patch/framework would address - if I ever set aside time for that and stop trying to polish my other mods lol
especially boilerplate utility functions that are too small to be their own mod
I only stop updating when I stop getting comments
youll never stop updating then...
preemptively took off steam comments for EHE's update - took it to GitHub exclusively
nah, it's honestly not hard to squash 90% of bugs
Idk why players accept error messages and not report the issue -- or why people think having mods means errors are to be expected
mostly if like... if it works... they dont care about the errors
is*
i had one saying that to me when i said that my mod was broken and shouldnt use it
if there's an error it's probably not working as intended to some degree
he just said... i get errors... but it work so i dont care
lol
my minecraft logs are more red than anything else, yet it runs fine,lol
wouldn't that mean that the square variabled passed from the LoadGridsquare event is getting changed to... a floor object? thing?
I guess I am bothered by the notion errors should be expected with mods - but it's hard to explain the nuance of it
I mean make the list the floor objects
you are calling for them anyway
dont remember which mod was it... but i had a mod running that everytime it rained...
it also rained errors
probably won't fix the issue but may shed some light to whats happening in bar()
the rain stoped... the errors stopped
i stopped using the mod... but 90% of the streamer i knew were still using it
and all of them said : its fine... its only when it rains and i never get to winter
I think I found something actually:
run = function(self)
local square,x,y,z = getSquareDelta(2, 2, 0)
local square2,x2,y2,z2 = getSquareDelta(1, 2, 0)
removeAllButFloor(square)
removeAllButFloor(square2)
square:getFloor():setSprite(getSprite("blends_natural_01_21"))
square2:getFloor():setSprite(getSprite("blends_natural_01_21"))
...```
this is the code I was referencing, I wonder if `removeAllButFloor` is the key piece that's making this code not shit the bed
I mean, you're not wrong. I don't want to see any errors, but you do end up having to accept them
either the errors aren't game breaking or the modder isn't responsive or whatever, you just have to live with issues. I hate it tbh
If that's the case it's fine / nothing you can do
if I can't figure it out based on the above, I'll probably just go ahead and switch to the getObjects (or whatever) method you used to avoid all this bullshit
testTheseTiles = {}
local function foo(square)
if not square then return nil end
local sqFloor = square:getFloor()
if sqFloor and sqFloor:getSprite() and sqFloor:getSprite() == getSprite("blends_natural_01_64") then
testTheseTiles[#testTheseTiles+1] = sqFloor
end
end
local function bar()
for _, v in pairs(testTheseTiles) do
v:setSprite(getSprite("blends_natural_01_0"))
end
end
Events.LoadGridsquare.Add(foo);
Events.EveryOneMinute.Add(bar);
This is what I meant
if somehow floor is nothing - then it'd do nothing tho
yeah I get you. it crossed my mind earlier, but I avoided trying that method because I wanted to eventually modify non-floor sprites, but I'm just testing anyways so it doesn't really matter I guess
ah
it really shouldn't be possible for floor to be null if you checked for it before inserting the square in the table, something else is going on
well, actually if you're moving around I'm sure plenty of those squares in that list will get unloaded in some way. I would make it a weak key table maybe
yeah, that's what has me baffled. it seems like any null value shouldn't be able to pass the checkpoint from the first func
you're storing a reference to a piece of the map that may no longer exist when everyoneminute gets around to checking, I'd expect issues now that I think about it
oh shit wait, what you just said made me realize - maybe it's - YEAH

i may be using references to unloaded squares
fuck me. that's probably it.
although I tend to get the breakpoint as soon as I start up the world, so that's weird
ah
i need break... lost 40m because a char case in a var name...
I forget squares might be unloaded lol
god dang it
ikr, me too lmfao
I could probably get the position though, store THAT instead, and then fetch the specific chunk in the second function (if it's loaded)
(or maybe just check if it's loaded in the second function, that'd probably be easier)
you could make it a weak table, so object in it that have been unloaded will be garbage collected, but I'd be worried you could sneak in before the GC does. Just have to check validity in both functions
for loadSquare stuff I'd store x/ys
what's a weak table? my Lua is extremely rusty
essentially the tables are by default "strong", which means objects you've put in there are anchored in memory and can't be garbage collected, but they may become altered in some way to make them invalid, which I think is what is happening here
you can make either the keys or the values or both of a table "weak" so that if they are the only thing still referring to that object, it can be garbage collected and removed from the table
here is the docs on that
https://www.lua.org/pil/17.html
Is there a way to store global mod data between restarts ?
globalModdata is already saved
hmm ok, I'm struggling to sync it between clients and have it work after a restart
syncing with clients is a different ballgame
assuming you have the modData on the server side of things
you have to call ModData.request("x")
I have it on both and i'm transmitting and requesting all the time
but after updates are made
you have to ensure the client's are pulling from server
I do a modData.Remove() on Init
to force clear it
I tried copying the base lua file for a mod to alter the cost of traits and it threw errors anything im doing wrong?
its based off the vanilla code
hmm I havent tried that, ill give it a shot
without seeing the code can't really say
alternatively, the errors would help too
local function foo(square)
if not square then return end
if square:GetObjects() then```
how is this POSSIBLY causing `Object tried to call nil in foo`
i'm so baffled, this API is so counterintuitive and busted lmfao
getObjects
generally everything is in camelCase except for when it's not
absolutely disgusting
has anyone tried to set up actual linting/debugging/etc. for this, aside from the failed CocoLabs thing? having to launch the game only to be frustrated by vague, unhelpful debug info isn't a lot of fun

actually the coco-labs thing bared some nice fruit
needed Konijima to decipher Yook's convoluted readMe
and I guess the relaunched pzDocs/pzMod as CAPSID was just decoupling gradle shit from every mod folder
does that allow for actual Lua linting/checking? because I already have everything decompiled
this lets you use the produced files as a global library for every project
it adds autocomplete when typing
as well as some parameter tooltips
does it do the interop between Lua and Java pretty seamlessly? i might look into that, as much as I despise intelliJ
afaik on-top of decompiling the code - it parses the exposed file and creates it's library -- if it doesn't auto complete it isn't exposed to use
interesting. thanks
even Java classes (although that can be hit or miss)
if you're familiar with gradle the libraries only issue would be the fact it doesn't understand classes inherit from eachother
so you may have to get familiar with class trees when using emmyLua
that still sounds like a clusterfuck tbh
ISReadABook = ISBaseTimedAction:derive("ISReadABook");
i've been trying to figure out with derive does but I feel like i'm just getting into nothing
It's by far better than having to keep checking classes
Am I overthinking this
Creates a new pseudo-class based on an existing one
he just named it derive
I just never see it being used in the code so I was wondering why that was there
it's used all over the vanilla Lua
I just couldn't find it on the wiki
I guess I should've looked at the vanilla lua lol
lol
thank you guys
it's used for UI/timed actions for the most part
basically copies the original table with some extra backend stuff going on
I see
I was working on a mod that could modify player's mov speed but it seems like its not possible
other than using the clothing speed modifier
Hey uh, I've got a problem. So when I place a custom attachment (I'm making a silencer) on the ground, it seems fine. Attaching the custom silencer to the gun works as well. However, placing the gun and the silencer down while it's still attached makes it utterly huge. Any advice?
The coding language I use at work is case insensitive, so I've developed some pretty bad habits. Can relate
I used to work at a place that used uppercase for everything
all work notes had to be in uppercase - not really programming related
I think someone higher up had bad eyesight
TIMES NEW ROMAN 35PTS ALL CAPS
unrelated - I updated the debug tool button to include a bluejay
seemed like the right thing to do being it is using AUD as a starting point
I did a couple changes including the remove() and it seems to be working!! thank you!
Glad to hear it ๐
Anyone happens to know what the command was to retrieve the script ID of an item but without the "Base." as prefix? For example, if the ID is "Base.MyItem", I just want to get the string "MyItem".
should be :getType() on InventoryItem
does this mean i can't see the files of the mod
I can't seem to find the folder of it anywhere
Physically, you can still see it - but technically you'd be breaking copyright using it
thx!
yeah i won't use it
I literally can't find it lmao
searching by workshop id on my files
or even the name of it
if you're subbed to it it's in: C:\Program Files (x86)\Steam\steamapps\workshop\content\108600\WORKSHOP_ID
odd
@sour island LOG : General , 1674020450702> Warning, root node parent is always null.
LOG : General , 1674020460661> - EHE: WARN: IsoPlayers can't add; IsoPlayer x/y less than 1:None None
LOG : General , 1674020461026> reanimate: loaded 0 zombies
LOG : General , 1674020461153> game loading took 23 seconds
is this normal?
yeah
good... i thought i broke something again...
just neveer noticed it before... and since im messing around updating my mod and the json that it uses was already getting paranoid
Why would getPlayer():getInventory():getAllCategory("Material") return nothing?
("Food") returns the potato so it's the write call, just not sure why I can't ge tthe tank
afaik, category is related with type of the item, try using getPlayer():getInventory():getAllCategory("Drainable") and probably you will get the propane tank
Yea, I tried that too haha
๐คทโโ๏ธ did you try get his category?
you can do
local inventory = getPlayer():getInventory();
local items = inventory:getItems();
for i = 0, items:size() - 1 do
local item = items:get(i)
print(tostring(item:getFullType()) .. " - " .. tostring(item:getCategory()));
end
the mod you're using might be changing categories for clients and not shared/server ?
had an issue like this for Shops with betterSorting
it didn't work with Tool or Water Container though
there is a displaycategory and category
I tried both
print(getPlayer():getInventory():getItemFromType("Base.PropaneTank"):getCategory())
this returns just Item
so does Base.BlowTorch
strange
Static is the term used for the models that the player carries or uses
And the map are fix afaik excpt for vehicles
The animation set folders are hardcoded? Can i create a folder containing my own set?
Custom set of idle walk run sit etc
what is module Base?
for sound ZombieSurprisedPlayer
hey so
to anyone's knowledge, is there a full list of vanilla clothing GUIDs anywhere?
i'm putting together a bunch of zombie outfits and it's like, insanely annoying to have to dig around for GUIDs
.. actually wait i forgot my XML editor has a find function
can just use that to find them quickly in the fileguidtable i suppose
All im trying to do is change a trait cost from 4 to 8 when I uploaded it I had 2 error boxes from doing so
or any cost within the vanilla traits
Im not sure if I have to rename the file name to a different name if that may cause problems im very new to script writing and references and such
it's originally named MainCreationMethod.lua
If you have a file named the same as one in the base game files and in the same location, the base game file will get overwritten. Something you really shouldn't do unless you have no other choice. You want to limit how much you change the base game code so you don't break other mods.
All you need is a file named something unique and put in media/lua/client that has this and your trait will cost 8
local trait = TraitFactory.getTrait("TheTraitName");
trait:setCost(8);
end
Events.OnGameBoot.Add(changeATraitCost);```
awesome thank you
Is there a way to "create" an item before placing it in an inventory? I'm trying to remove an empty bucket then place a new bucket in the inventory but I want to set the delta to 0 before placing it in the inv.
ah, inv:AddItem("Biofuel.BucketFertilizerFull",0)
that did it
For future reference, you can do this as well when you need to alter an item before adding it to an inventory
-- change item properties (e.g. item:setCondition(10))
player:getInventory():AddItem(item);```
So would it look like something like this?
local trait = TraitFactory.addTrait("Graceful", getText("UI_trait_graceful"), 9, getText("UI_trait_gracefuldesc"), false)
trait:setCost(9);
end
Events.OnGameBoot.Add(changeATraitCost);
ah, itemfactory, I was looking at itempicker but that wasn't wat I needed haha.
That would work if you are creating a new trait.
Graceful already exists, so you should just have local trait = TraitFactory.getTrait("Graceful") to get the existing one
strangely enough it didn't change it from 4 to 9, and i got a error message
@sour island got the ball rolling, finally, just in case you got curious. it'll need lots of limiting code, and I'll probably have to move it from OnRenderTick to OnTick to avoid animations being slowed by the framerate (but I'll have to artificially slow them down, probably via a modulo on the tick delta). but I'm hyped that I got this proof of concept working either way. this takes blends_natural_01_64 and replaces it with the first 16 members of floors_interior_carpet_01, cycling forward a "frame" in the "animation" during every firing of the event. surprisingly not that rough performance-wise yet
(seizure warning)
yet
I think once I start adding more logic, it could drastically slow things down. I'm going to try to put as little code as possible on OnTick though, so we'll see how well that works out 
animated map tiles framework, more or less
that's just a proof of concept - the 16 carpet tiles I cycled through there could instead be 16 frames of an animation
Oh, I guess there isn't a setCost function for traits. Weird. Professions has one.
I guess you do need to recreate traits to update their cost.
You can delete the trait:setCost line then and just use the addTrait.
Working escalators? 
true!
entirely within the realm of possibility
yo if you have experience with animations, IS is looking for you.
this isn't really the kind of "animation" they're looking for, lol
I'm also not an animator by any stretch of imagination, the most experience I have with that sort of thing is using Pivot Stickfigure Animator in like 2006 or something
couldn't you technically make a tv show or something that is actually watchable using that?
technically, yes. practically? probably not, unless your TV show is like... less than 256(?) frames long
figured lol...
Hey, new question for some lua expert:
I've got a table described as follows
Right_Hand = "RightHand",
Right_LowerArm = "RightForearm",
Right_UpperArm = "RightArm",
Left_Hand = "LeftHand",
Left_LowerArm = "LeftForearm",
Left_UpperArm = "LeftArm"
}```
If I try to iterate over it with `pairs` or `ipairs` it won't even loop once, I need to use a numeric for instead. Any ideas why?
i had a feeling it would get nasty after a handful of tiles
I think lua considers this an arraylist instead of a table
I'm still kinda new at lua myself so I can't say for certain, but it sounds like something that would be #justluathings
I'm going to experiment a bit with .pack manip and spritesheet sizing to see what I can cook up, but I'm imagining I won't be able to bend the limits there very much. however, there's a lot you can do even if it's capped at 256 tiles - that's 256 frames for a single object, potentially. could even chain them together even if there is a limit, but it'd make your mod have a fairly large file size I'm sure
so these are all the traits I want to change up, does this look accurate or do I have to write it differently?
local trait = TraitFactory.addTrait("Graceful", getText("UI_trait_graceful"), 9, getText("UI_trait_gracefuldesc"), false)
TraitFactory.addTrait("Cowardly", getText("UI_trait_cowardly"), -3, getText("UI_trait_cowardlydesc"), false);
TraitFactory.addTrait("Clumsy", getText("UI_trait_clumsy"), -5, getText("UI_trait_clumsydesc"), false);
TraitFactory.addTrait("FastLearner", getText("UI_trait_FastLearner"), 9, getText("UI_trait_FastLearnerDesc"), false);
TraitFactory.addTrait("Inconspicuous", getText("UI_trait_Inconspicuous"), 7, getText("UI_trait_InconspicuousDesc"), false);
TraitFactory.addTrait("Smoker", getText("UI_trait_Smoker"), -2, getText("UI_trait_SmokerDesc"), false);
end
Events.OnGameBoot.Add(changeATraitCost);
TV shows don't need to be exact copy, just make a few overlays and throw in a few memorable quotes.
That looks fine, I think
tbf I would automatically code that using python or something, seems like an hassle to do by hand
just a silly idea when i saw that
new to coding so if you look at my workshop, you will see my skills are limited. only been messing with pz and lua for the past month and some
for me, what i can do is far greater than how i can do it easier using something i'm not familiar with ๐
getting there though
having a sick little 5 mins animated short
lua wise, it should work with pairs
that's what I was guessing, so it isn't normal that it's not looping through it, right?
another question, why does it work with numbers? must be a different table?
I expected to get something out of
...
end```
but I can't print even a random print inside of it
well... yeah, you're right
I work-arounded by using two different tables and a numeric for
so yeah, it didn't really work using a numeric for either (didn't really try)
ok, new question then, I tried running it on an online compiler and it works with pairs but not ipairs, why?
because the "i" in ipairs is integer
or, uh, maybe index
but still
you have non-numerical keys, so it's not able to be used with ipairs
Oh, didn't know about that
makes sense
and ipairs only check ordered list
alright, getting back to zomboid, is there a way to set a breakpoint from the menu without having it deleted when I get in game?
works! thank you so much CosmicB!
nice
i wanted to do a lava tile project before
Do the tiles use .pngs? Im not into tiles and such so ive no idea how it works
Watch daddy dirks vid
How could l overwrite them ?
Do i have to restart my dedicated server everytime I change a mod file on the ftp ?
yes, more or less. the PNGs are directly binarized into the .pack files, along with information on the layout/dimensions of each tile within the spritesheet, as well as some other data. mods tend not to use texturepacks unless they're adding new tiles to the game though, because the game can load PNGs directly - they just aren't as optimized as texturepack atlases
Can I have a sandbox option that's an integer?
sandbox-options.txt:
{
type = integer, min = 0, max = 10, default = 5,
page = SomePage, translation = SomeInteger,
}```
It determines the order they appear on the sandbox option menu
is there a way to disable zombie body part damage ?
So that they dont spawn with any damage to their bodies nor do any hits (visually) damage the bodies
I've got the damagemodeldefinitions but dont really see how it could be disabled
okay. I meant the options inside an option, as in the min,max
Don't think so
okay
I am still trying to figure out what this "server-client-communication" as explained here https://steamcommunity.com/sharedfiles/filedetails/?l=koreana&id=2735092774 is good for. Is there a simple (even oversimplified) example where this is needed?
Hi, this might be a bit of an open ended question but how do I make a code which detects if a specific clothing has a flag which tells the game to replace idle animation to whatever the clothing flag says from the txt file?
Here's an outline of what the code will work like
Check current clothing
If current clothing has flag on
new_idle_anim = clothing.idle_anim
Replace vanilla idle_anim with new_idle_anim
Else
Revert back to vanilla idle_anim
Any sort of interaction between players that is outside of what the game code already provides or when the client/server triggers something that needs to be completed on the server/client respectively.
Example: A barber mod that lets one player cut/style the hair of another
- The client of one player can't directly change the player of another client
- So Client A sends a message to the Server saying "I cut Client B's Player's Hair"
- The Server then sends a message to Client B saying "Your player's hair has been cut" and Client B applies the change to their player
- The other players will then see the change when Client B sends the next player update
that's a nice example! thanks for explaining!
yeah but what about sending events from server to server ๐ค
That could actually be interesting, if a bit niche, feature to have added for creating a wider community server network.
Imagine having multiple servers running with each being loaded with entirely different maps and players can travel between each map by using interaction points that transfer the player's data to the other server and then cause the player to reconnect to that server.
World of Project Zomboid.

Sure. I'll get right on that as soon as TIS creates a SendServerToServerCommand. ๐
I wonder if there'd be a way to do raw TCP/UDP connections for stuff like that, and also for like SQL servers and shit
I haven't looked into much in that regard, not sure how much of that (if any) is exposed
I don't have any particular need for that sorta thing, but it's a neat idea
make an external add-on ๐
yeah, but you'd still need some sort of socket wouldn't you? unless you can piggyback off of existing functionality or something like that
currently most player related stuff is client side making it impossible for servers to do that sync
would also need a custom server
I won't bug y'all again about this (promise), but does anyone know whether the pathfinding behavior that is usually wrapped in a TimedAction can be executed successfully outside of a timed action?
Haha just hoping literally 1 person has already solved this but no worries if not.
i dont see why it wouldnt be possible
Well I have been trying it and failing (for several hours tbh lol), so I was curious whether anyone ever had any success doing it. It seems to rely on two functions, but when I call them outside of the TimedAction, they do not behave as expected.
i havent tried it but there should be no reason for it to not work
From within the timed action (btw I've already made an alt version of the vanilla WalkToTimedAction), you go self.player:getPathFindBehavior2():pathToLocation(self.goal:getX(), self.goal:getY(), self.goal:getZ()), and then in the update you go self.result = self.player:getPathFindBehavior2():update()
But if I try pathToLocation and then add update to OnTick, nada.
So there seems to be something unusual that update needs other than firing quickly.
But I don't know what it needs.
(Actually to be clearer, you start walking in place but never make it anywhere.)
did you call :start()?
also, did you use the constructor?
if you want to totally divorce it from ISBaseTimedAction you'll also need to re-implement some functionality from it (if not all of it, if you're just copy/pasting)
I didn't check but I imagine there's some underlying functionality there
also might be worth looking at ISWorldObjectContextMenu.onWalkTo if you truly don't need it to be timed
Ye there is use event
OnZombieUpdate
Fix their dmg
Maybe if the servers doesnt need to restart every goddamn time data is modified then this would be possible
Whats a flag
flag is just another term for a bool, in almost all cases
to be clear I mean anything that is in the txt file of a costume that lua code can read as true/false
maybe as an additional tag or a new property
and then if true, then read a property that indicates which animation will replace the idle
and then, replaces the vanilla idle animation with the one from the the corresponding property
anyone knows what mod "SOTO" refers to ?
If item:getModData().flag == true then setVariables()
"Show Off The Octopus" ?
The way variables work for animations is kinda confusing for me
This is exactly what my project is doing but it doesnt involve clothing. Wana colab?
Nevermind, it's Simple Ovehaul Traits and Occupations apparently
That's really nice of you but I don't think I am free to collab right now
I actually read traits and octopus
I appreciate your invitation tho
Wait isn't start a timed action function? I will revisit base timed action later but I couldn't figure out what it needs from there earlier. I did check.
And what constructor? I use a constructor for my timed action version but I am aware of no required Luaside constructor activity for the pathfinder functionality inside IsoPlayer objects.
I checked that, it uses the timed action.
right, but if you're re-implementing that functionality, you probably want to keep a similar structure - and the issues you're running into are evidence that you're missing some pieces
Sure yeah I'm just not sure exactly what from start I can call that isn't fundamentally a timed action....
why wouldn't you want it to be a timed action?
Context: I have made an autowalking mod. You can toggle autowalking on and off. However, because it's currently a timed action, you cannot do stuff that can normally be done while walking, e.g., eating, smoking, reading (if modded).
I would like the best of all worlds here if possible.
why would you need pathfinding for that? 
you can't really pathfind without a target
I target the squares shortly ahead of the player and continuously update it to keep you walking
but why not just feign forward input instead?
Mainly the joypad question, though I suppose I could reimplement keyboard input that way and work something out.
What I don't know is how to feign forward input on a joypad. I could not figure it out. Using the pathfinder seemed viable and the JoypadManager seemed inadequately exposed.
I could be wrong.
there's a good bit in JoyPadSetup.lua that could be used to your advantage
This game needs more trees, or remove animals if there are no trees.
wym? there's a ton of different trees, and most of the playable map is forested woodland
I haven't loaded my save in a while because there are no trees around anymore.
Mr Axeman has nothing to chop ๐ฆ
so unplayable, but it does send a message: stop chopping trees to not ruin the environment
sure, but now I need to trek to the next batch. What I haven't chopped, the horde on fire burned.
How can I use that file's functions to send a forward joystick press? I've looked all over that file but I am not seeing it there. I clearly do not understand the function that allows me to send that signal if such a function exists there.
I mean yeah I'm flexible about the solution. If there is an easy way to send a forward-movement signal on joypad that does not involve pathfinding, I'm all ears, but I can't find one.
If I update a lua file on my server, do I have to restart the server to test it ?
will this work ??
Events.OnPostDistributionMerge.Add(function()
local vehiclesToDelete = {
"Base.CarNormal",
"Base.Ambulance",
"Base.Sport"
}
local function removeVehicles(vehiclesToDelete)
for key, value in pairs(VehicleZoneDistribution) do
for vehicle, data in pairs(value.vehicles) do
if vehiclesToDelete[vehicle] then
value.vehicles[vehicle] = nil
end
end
end
end
removeVehicles(vehiclesToDelete)
end)
if i want to remove the example vehicles from the distrib
Unsure, but I strongly suspect there's no need for making a global function called removeVehicles to do what you're doing
You could just loop through the vehiclesToDelete array above without creating a function just to call it with data that already exists locally @ancient grail
wait is this for optimization purpose? cuz i only need it to work
Also it looks at a glance like you want to check whether a vehicle name (or category?) is a key in vehiclesToDelete?
Oh yeah Idk sorry, I'm just not sure the connection between vehicle and vehiclesToDelete works how you think... If vehicle above is not an index (1, 2, or 3), vehiclesToDelete[vehicle] will be nil.
That doesn't seem to be your goal but idk
VehicleZoneDistribution.parkingstall.vehicles["Base.somecar"] = {index = -1, spawnChance = 2};
VehicleZoneDistribution.good.vehicles["Base.somecar"] = {index = -1, spawnChance = 2};
VehicleZoneDistribution.spiffo.vehicles["Base.somecar"] = {index = -1, spawnChance = 2};
VehicleZoneDistribution.ambulance.vehicles["Base.somecar"] = {index = -1, spawnChance = 2};
VehicleZoneDistribution.radio.vehicles["Base.somecar"] = {index = -1, spawnChance = 2};
VehicleZoneDistribution.massgenfac.vehicles["Base.somecar"] = {index = -1, spawnChance = 2};
VehicleZoneDistribution.parkingstall.vehicles["Base.somecar"] = {index = -1, spawnChance = 2};
cuz this is what it looks like
parkingstall, good, spiffo, ambulance etc
parkingstall
trailerpark
bad
medium
good
sport
junkyard
trafficjamw
trafficjame
trafficjamn
trafficjams
police
fire
ranger
mccoy
postal
spiffo
ambulance
radio
fossoil
scarlet
massgenfac
transit
network3
kyheralds
lectromax
knoxdisti
normalburnt
specialburnt
Yeah it won't behave how you want.
maybe not then, I didn't look at it exhaustively
if you can't find anything in there, track down the keyboard controls and copy the logic for each movement keypress (more or less)
This part of your code:
local vehiclesToDelete = {
"Base.CarNormal",
"Base.Ambulance",
"Base.Sport"
}
needs to become:
local vehiclesToDelete = {
["Base.CarNormal"] = true,
["Base.Ambulance"] = true,
["Base.Sport"] = true
}
Won't work either. Can't send keyboard movement signals while gamepad connected. Unless you know a workaround there...
WASD are locked during gamepad play
Also, I suspect if I spammed W OnTick, it might just make me stutter around... would have to test that theory, but I'm not sure if the game has other between-tick logic for stuff like movement on the Java side or not.
โค๏ธ
i been silently checking out the controller stuff also lol
So yeah, hence pathfinding, failing a better solution, to which I am entirely 100% open.
you got me interested
ok
thnx
I'm not saying send the keyboard command, I'm saying send the code that the keyboard command triggers
e.g. if key.W == isPressedOrWhatever then moveForward()
you'd want the moveForward() bit, wherever that exists
Also, fwiw, I'm pretty sure this part of your code
local function removeVehicles(vehiclesToDelete)
for key, value in pairs(VehicleZoneDistribution) do
for vehicle, data in pairs(value.vehicles) do
if vehiclesToDelete[vehicle] then
value.vehicles[vehicle] = nil
end
end
end
end
removeVehicles(vehiclesToDelete)
could be this:
for key, value in pairs(VehicleZoneDistribution) do
for vehicle, data in pairs(value.vehicles) do
if vehiclesToDelete[vehicle] then
value.vehicles[vehicle] = nil
end
end
end
But you do you.
Right, I hear you, unfortunately I don't think that command exists Luaside. I've searched for binding_Forward in the Lua, but find no references to it.
Hold on that's weird code that might not be the right reference to Forward
Yeah might be the only reference though...
function MainOptions.loadKeys()
getCore():reinitKeyMaps()
MainOptions.keys = {}
MainOptions.keyBindingLength = 0
local knownKeys = {}
-- keyBinding comes from keyBinding.lua
for i=1, #keyBinding do
bind = {}
bind.key = keyBinding[i].key
bind.value = keyBinding[i].value
if not luautils.stringStarts(keyBinding[i].value, "[") then
-- we add the key binding to the core (java side), so the game will know the key
local bindNbr = tonumber(bind.key);
if getCore():isAzerty() then -- doing azerty special keyboard, a=q, etc...
if bind.value == "Left" then
bindNbr = 16;
elseif bind.value == "Forward" then
bindNbr = 44;
elseif bind.value == "Shout" then
bindNbr = 30;
elseif bind.value == "VehicleHorn" then
bindNbr = 30;
end
end
getCore():addKeyBinding(bind.value, bindNbr)
bind.key = bindNbr;
table.insert(MainOptions.keys, bind)
if getTextManager():MeasureStringX(UIFont.Small, bind.value) > MainOptions.keyBindingLength then
MainOptions.keyBindingLength = getTextManager():MeasureStringX(UIFont.Small, bind.value)
end
knownKeys[bind.value] = bind
else
table.insert(MainOptions.keys, bind)
end
end
This is the only reference to "Forward" I can find in Lua files that include the word "binding" and aren't about "Fast Forward".
And it doesn't seem useful...
it may not need to, necessarily. if the class is public, and the chain is public all the way down, you can just use the Java methods to invoke it.
i see options for moving to a vector, is that not how you are trying to accomplish, or have you tried?
Fair... Only promising thing I found in Java regarding forward motion was https://zomboid-javadoc.com/41.65/zombie/characters/IsoGameCharacter.html#MoveForward(float,float,float,float)
Javadoc Project Zomboid Modding API declaration: package: zombie.characters, class: IsoGameCharacter
yep[
But this command did not work for me
I tried getPlayer():MoveForward(getPlayer():getMoveForwardVec()) iirc
IsoGameCharacter:setMoveForwardVec(arg0)
So I need to set one first?
probably its what the game does
there is other things like setting the direction as well
No wait not that. MoveForward takes 4 args. It was something else...
check what the game does, but if nothing else you should be able to get the facing vector and then add a number to one of the axes to extend the vector to your target
what crater is saying is kinda how i anticipated the controller working out
not sure if there's a Lua pseudoclass constructor for Vector2, but even if there isn't you should be able to modify the individual members (X, Y, maybe getX() etc)
from one of the return values I mentioned above, if they return Vector2s
OnDistributionMerge or OnPostDistributionMerge ???
Events.OnPostDistributionMerge.Add(function()
local vehiclesToDelete = {
["Base.SmallCar"] = true,
["Base.SmallCar02"] = true,
["Base.CarTaxi"] = true
}
for key, value in pairs(VehicleZoneDistribution) do
for vehicle, data in pairs(value.vehicles) do
if vehiclesToDelete[vehicle] then
value.vehicles[vehicle] = nil
end
end
end
end
end)
--[[ to test
local result = ""
for key, value in pairs(VehicleZoneDistribution) do
for vehicle, data in pairs(value.vehicles) do
print(vehicle)
result = result .. tostring(vehicle) .. "\n";
end
end
Clipboard.setClipboard(result);
]]
```
Idk that answer, sorry. I am not familiar with removing vehicles so I don't know the timing. But I do know you have too many ends.
Events.OnPostDistributionMerge.Add(function()
local vehiclesToDelete = {
["Base.SmallCar"] = true,
["Base.SmallCar02"] = true,
["Base.CarTaxi"] = true
}
for key, value in pairs(VehicleZoneDistribution) do
for vehicle, data in pairs(value.vehicles) do
if vehiclesToDelete[vehicle] then
value.vehicles[vehicle] = nil
end
end
end
end)
Okay given p = getPlayer(),
print(p:getForwardDirection()) gives me a V2 with my forward direction... I then try
p:setMoveForwardVec(p:getForwardDirection())
and
print(p:getMoveForwardVec()) gives me a V2 with (X = 0, Y = 0), (L = 0, D = 0), so clearly it's getting immediately reset if it's set...
Not sure how to manually trigger a move from there... Tried MoveForward with the various values available in a V2 and nothing.
@finite radish @drifting ore Lemme know if y'all have any more good idea... I am gonna be busy awhile but I will be back at it later. If there is any possibility at all that I can just fire a forward walking signal, I would obviously prefer to do that than use pathfinding for the autowalk function for many reasons.
Alternatively, pathfinding workarounds that do not require timed actions are welcome.
no worries thnx
can you provide an example ? also trying to prevent it from happening rather than fixing it
Can I have my sandbox options come with a description on mousing over?
yes, just add another translation string with _tooltip added to the end of the translation string name
Neat
Will be great once I figure out why one mod loaded the translation while the other one didn't
most issue with translation show in console if it's not correct
i actually run the game from .bat file so it's always on my screen
you can see most from the box in bottom left tho
even when you don't run it from the batch, it should be open by default
the logs
yeah that's the console, more or less
can also enter lua stuff there also
there's also the lua console with tilde, and F11 opens the breakpoint debugger
oh i didn't know that tilde thing lol
Oh, as in in-game>
I haven't gotten past the sandbox options screen
oh lol...
Well I am trying to fix an error with my translations not loading
did you define the translation name in the sandbox file?
yes
you said you got one working and one isn't?
yes
share them both lol
One mod works, one doesn't
file should be small for translation
not both really just the bad one
it's pretty striaghtforward so the problem should be obvious between the sandbox-options.txt and the sanbox_en.txt or whatever language you are using
Missing what?
In vanilla folder lua/server/recipecode.lua, there is a function called CannedFood_OnCooked and the beginning lines including comments are this:
-- you cook your can, now set the correct food age/max age
function CannedFood_OnCooked(cannedFood)```
Does anyone knows where this "Food.update()" can be found? I searched all files in lua with a search program and didn't find anything so far...
It's in Java. There is a tutorial to decompiling the java code
Ok... thanks! I saw this. But any idea where exactly this Food.update() might be called within the vanilla lua code?
if you follow that guide, it will make your life easier
i wasnt using it as well
but since i went throught the trouble of setting it up... a lot easier to find what you want
and its not that hard to do, and the guide is very easy to follow
it's not that i can see
mentioned 1 time in a comment
food.update() is to be called on a food object i guess
Wasn't there some guide to translations
Yeah. That's exactly what I found out via automated searching. Point is that the update might still be called somewhere in the lua code but then with smth like "item:update()", "x:update()" or anything like that. Problem is that it is impossible to quickly search and find it because just searching for "update()" gives hundreds of results (and item:update() does not give the "update" command I am looking for btw - already checked ofc)
thats why following that guide is usefull
easier do look for whats available and have an idea of how it works
I probably have to go through it I guess...
all i know is since a lot of ppl in here told me to do it, and i dit
my life got a lot easier
i still ask a lot questions but not as many and not as dumb ๐
isn't update just every tick?
i think so but im not sure
since it handles the freezing and age of the food
its probably every tick
or to be correct on every minute
Problem is that my food.update() may or may not be called in lua. It has probably smth to do with "food" ;). Now there are dozens of chunks of lua code which are related to food and they are scattered through different parts of the code. Question is whether reading the java code will tell me anything more precise where to look. I am afraid that the java code may not tell me more than what I already now (namely that it is related to food and possibly called somewhere where food is relevant... )
but as a last resort, might be worth a try...
99% of my errors are typos... dang it... it could be worse...
ExceptionLogger.logException> Exception thrown se.krka.kahlua.vm.KahluaException: TWEEVENTS_Events.lua:89: ')' expected near `then
if you really need to know, hook the metatable to print or something and play for a bit
no prints means it's never called from lua
I am afraid that this might be true. Maybe even easier to find a workaround without that food.update and CannedFood_OnCooked in my case...
What do you need exactly?
yea i wonder what you are trying to accomplish
The function CannedFood_OnCooked is in server. In this function, I need the player who actually cooked the food. Problem is that the function does not have the player as argument and just using getPlayer() will probably not work in multiplayer since it may mess up stuff related to server-client things (or am I wrong...??)
But have already some ideas to work around...
call it on the client, then send a command from the client to the server if you either need 1) to do serverside logic with the result or 2) need to confirm for anticheat/exploit/lag reasons, to check the validity of the result
this sounds like ultimately an XY problem though, given that the function you mentioned says ----- CannedFood_OnCooked IS NOT RECIPE CODE. IT IS CALLED BY Food.update() ----- you're probably using it wrong in the first place
wdym?
Hmm... So, any clue as to why my translation doesn't get loaded?
I mean that you should probably listen to the comment there, because it's spelling out for you in all caps that it isn't to be used a recipe callback
my mod needs to modify this particular function but needs some player data for it. there is no way around for what I want to do...
why?
i don't really see a way to grab the player from it
you shouldn't be accessing the player from that code, otherwise it'd have the player as an argument
(see again: the comment I posted)
I know. This function is called when a jar with food is cooked to preserve it and I specifically need to touch that very point
Why exactly?
totally aware that it is not related to recipes
yes, but you're using it like it's a recipe callback, and that's clearly not what it's for
I think you just misunderstand the code in question, and you're ignoring the warning put there in all caps by the devs lmfao
when it comes to modding you use whatever you can find
can you explain what you want to do?
in fact, what I want to do already works completely fine in singleplayer but I just have the ambition to get it working for mp too. so I just play around with code a bit more
yes: This function sets the durability of a jar when it has been cooked. I want to change the durability and making it last longer when player has a high cooking skill. So I somehow need the cooking skill of the player who actually cooked it.
My current idea is now to figure out where the "cooking" can be catched on the client side and there put the players cooking skill as modData to the jar. The jar is then accessed in server (that's part of the vanilla code). So I hope that I can simply grab the mod data there and have my cooking skill where I need it....
is there even a concrete 'player who cooked this' though?
i think the best i could do is to keep a reference to the player on the item when they put it into the oven
yes, definitely. But the player is not an argument of the CannedFood_OnCooked function.
almost exactly what I want to do but I do not take the whole palyer object but only the cooking skill which is sufficient for me
there is no player, java gets the first player and gives him xp? *same fullname as chef
so keep the cooking skill as moddata on the item
yep!
yes, <food>:getChef()
hmmm i thinkg that only applies when you make food
like a salad
or something in a frying pan
since cooking isn't interactive i can't think of a flawless way to keep track of who cooked it
nono. vanilla game has only CannedFood_OnCooked(cannedFood) where cannedFood contains the jar object. It then sets the duration of that jar
but java clearly does...
#mod_development message
that's kind of a problem but I think I simply take the last player who putted it in the heat source...
on transfer:
if instanceof(self.item, "Food") then
self.item:setChef(self.character:getFullName())
end```
game already does that, see above (although it's who takes it out, not who puts it in)
had a look, vanilla just loops through the player list until it finds someone with the same name as the chef field
i would copy that for consistency
oh, to actually get the player from the chef field? that makes sense, yeah.
yeah, that's how it decides who to give xp to
that's also a philosophical question: who is the cook? the one who puts in the oven? the one who turns the oven on? or the one who takes it out of the oven?? XD
I hate multiplayer!!! XD
if i wanted to be real ๐ค about this i could point out that if two online players have the same character name one of them will be unable to gain xp from cooking in the oven, and the other will gain their xp instead
in this case, it's assigned every time a food item is moved in OR out of a container, even if it wasn't cooked in that container.
I have figured out why my translations weren't working
the cooking code doesn't actually fire until food:update() is called, upon which it actually iterates over the player list using the chef to give the XP
I didn't add a comma after the translation option
where is this code from? from lua?
yes, although setChef() and getChef() are Java methods belonging to the Food class. they're never used in Java though, only in that one spot (and it runs a lot, hence the comment saying it's hacky)
every time you move a food item from one place to another (bag into inventory, inventory into microwave, inventory to floor, etc.) it assigns the Chef field via those methods
it only actually uses the field if the food is successfully cooked though, in order to grant XP
and that occurs inside Food:update()
interesting, make it a bit more realistic. get the chef player and check if he's close / doing other things
Okay, uh... I updated my mod on the workshop but the description was overwritten...
getChef() is definitely also interesting for my purposes... but still have to mess around with interface interactions on the client side to apply this in the right moment...
I uploaded it with a placeholder description, then made it proper on Steam...
Can I somehow roll back to the previous description?
it's not going to be easy, most of the real code that handles the cooking itself (before, during, and after) occurs within the update loop of the Food class itself. you can modify some of the variables it uses within that function, but there's no exposed way to insert your code into that process that I'm aware of. look into :setOnCooked() and :getOnCooked() though - there's a string that may actually be a callback. not sure how that interacts with the _OnCooked function you've been trying to use.
seems like hooking the _OnCooked function is the easiest way to do this, seems basically perfect for your uses and we've worked out how to get the cook anyway
true, maybe? depends on what you're trying to do. I can't even find any references to that function anywhere, so idk
like, you might wanna make sure CannedFood_OnCooked is called at all in the first place
it is
check scripts
I have a much simpler idea now: I simply declare the guy who crafted the jar as chef! then I add the relevant data to the jar's modData in the "recipe.onCreate.Jar(...)" function (which happens to have the player as argument!
oh, it's a script thing, RIP
I don't have scripts in my workplace, need to fix that 
I'm not sure what you mean, but sounds not persistent
what are you actually trying to do
this is what I meant by XY problem
make the jar last longer based on the cook's level
can't he do than when he jars it?
exaplained here: #mod_development message
yeah, jarring isn't even cooking. it's a crafting recipe, isn't it?
why not just use the crafting callback?
yeah but you have to cook the jar afterwards
yes. that's what I am roughly going to do now since this may hopefully avoid all those client-server issues
you mean save-game-persistent? I only need the player's cooking skill which is a numerical value. so should be fine. I'll try now and see how it goes
yeah that sounds like the best way to do it
why not use the crafting callback to set the values, then use the values to assign the duration in the OnCooked callback? or is that what you're saying?
(how you'd actually pass the values isn't immediately obvious to me, but there'd be plenty of ways to do it I imagine)
yes. that's what I am saying
okay yeah, we're on the same page now then. that should work in theory
I give it to the jar's mod data. the jar is then used in CannedFood_OnCooked. So I hope I can safely restore them there
I don't know... you typed function with player
mod data would be a good way to do it, yep. not sure if you'll need to reciprocate it on the server, but it should be fairly straightforward even if you do.
in case you are interested, here is what I am going to do now:
step 1: craft jar; add the player's cooking skill to the jar's mod data (should be possible since the recipe.onCreate seems to have the actual player as argument)
step 2: when the jar is cooked, retrieve the mod data and adjust the jar's durability (should hopefully also work; the CannedFood_OnCooked has the jar as argument)
i would just calculate the actual durability values and store those in the mod data, then just plug them into the durability set functions directly rather than doing the calculations on-callback
probably won't make a big difference either way though
ok. that's also a way to do it!
anyway, thanks for all the suggestions and discussion. has definitely helped to clarify the problem for me!
ok this is nice
Hopefully in future jars have different fresh days based on what's inside
I think this is already the case in vanilla. The pz wiki states that days fresh are always 60 days but this is not true. The time it is fresh is scaled according to the fresh time of the original food item. For example, cabbage is 2 days fresh and rotten after 4. The resulting jar is 45 days fresh and rotten after 90. (So in any case 50% of the overall durability, it is fresh.)
ah, you have a point. They might have same fresh days but the starting age % is lower because the ingredients lose freshness faster.
Modular jarring would be neat
Seeing multiple items for different jarred foods or fluids feels like a bad approach with scaling content
do we have marmelade? I don't see it
at least fluids are getting redone
Jam, jelly, marealade, and pickled stuff would be fun
item JamFruit ๐
oh wait... also possible that they changed it recently to make it so that it fits to what the wiki says. I just checked again... but it has definitely been somehow in the way I described some month ago. I even wrote a bug report several month ago and did a lot of code checking and play-testing. so not 100% sure...
all those features will be part of the mod I'll hope to publish soon: normal jarring (requires only water), pickling (with vinegar) and fruit jams (made of foraged berries or strawberries)
just learned there are both Marmalade vs Marmelade
Sounds good but can we pickle meats too
but wdym with modular jarring?
Not having items scripted for every combination. Have a holder item and its contents handled on the fly.
no. meat preservation is not planned.
The onRecipe for unjarring stuff also doesn't return the lid
I think that one is a bug/oversight
hmm... ok. I only have this to some degree for jams made out of berries. but for the vegetables, I still have a distinct recipe for each
that's also something my mod will do. but I think there are already other mods with this feature
Just a heads up- easy bonus feature ๐
Yep, since I'm in here often enough ๐
is a tick length defined, or is it variable based on performance? i know it's not tied to framerate, but I'm curious if CPU cycles etc. affect the delta
rip us
something 30 times a second iirc
Hello. Decided to join here again. o/
another thing i was looking at with how it auto paths to containers and stuff. i saw something about it marking a spot on the ground and moving to it like an offset position from the playerlocation and then move to that location over and over, and ofcourse it updates as you move since it's offset from the location you are in
That's basically how my mod autowalks. That presumably uses the WalkTo function. No good reason not to.
i dont think it does
let me double check quick. doing 3 things at once but i will forget if i dont let it out now lol
so uh, chatgpt is incredibly useful for debugging wtf
ahhahah some things never change....
trying to catch an error
and apparently nothing was wrong
then i found it... fater like 50m...
had Print
instead of print
.........................
imagine using a language that throws useful exceptions
lua and java are both dogshit
so is python ๐
fax
actually if I'm doing scripting and batch shit, or static regex, python is great
but the syntax is trash
hmm this is driving me nuts
local playerChar = getPlayer()
--local currentTime = pzCalendar:get(Calendar.HOUR_OF_DAY) *60 + pzCalendar:get(Calendar.MINUTE)
print("-----Checking timer trait-----")
print("Current time: " .. pzCalendar:get(Calendar.HOUR_OF_DAY) *60 + pzCalendar:get(Calendar.MINUTE))
print("Finish time: " .. tostring(TraitEndTime))
if TraitEndTime <= (pzCalendar:get(Calendar.HOUR_OF_DAY) *60 + pzCalendar:get(Calendar.MINUTE)) then
player:getTraits():remove(tempTrait);
HaloTextHelper.addTextWithArrow(player, getText("UI_trait_"..TWEtrait), false, HaloTextHelper.getColorRed())
Events.EveryOneMinute.Remove(TWE_TraitCheck)
end
end```
this is a function that check if the timer ran out
but the current time never changes...
if i run it manualy it does...
inside the function that is added as an event
doesnt change the value..
wth am i missing here?!!?!?
i asked the magical all-knowing website and this is what it gave me, its probably crap, but maybe youll have some use of it:
he just added a check for null?!
Are you calling Calender.getInstance() before grabbing the time values? It may need that to update to the latest time.
if i run a function that just prints the current time it works fine
thats why im confused
the explanation it gave is also nonsense
the null check is not needed... since im the one sending the values so...
i only need to do local pzCalendar = PZCalendar.getInstance() once
everytime i call pzCalendar:get(Calendar.HOUR_OF_DAY) or pzCalendar:get(Calendar.MINUTE)
it will get the correct time
but for some reason it doenst work on that function
guess im gonna make a time printing funciont and add it to oneveryminute and see if it does the same... for the 300th time ๐
more nonsense
you have to give it context
like tell it to ignore only being called once since the game has a tool that does it
and if youre lucky in a few hours youll get somewhat of a decent reply
๐
I love how authoritatively chatGPT talks about stuff while being completely wrong.
well if nothing else he would be a good politician
even if wrong, it acts like he is absolutely right
it works pretty well if it has access to a set of libraries but i tried feeding it libraries and it wouldnt accept it
Would anyone here happen to have or know of any resources on modding for splitscreen?
you will never be able to feed that version enough information with 4000 tokens and it only retains around 40000 tokens worth of data
by the time you get to the end of the tokens that are saved. it will start going back tp spitting nonsense
like incoherent nonsense, not nonsense that seems like it makes sense lol
best bet is if you use the api and train it using a parsed version of the api
both java and lua
then you will technically just be able to tell it to make a script and it would be able to do at least 60% without error
maybe more
im gonna waste some money training it and see how it goes
^ yeah thats it. it can understand context but only for so long, then it starts forgetting
if anyone has ever fully parsed the newest PZ api and has it even remotely cleaned up, i would be willing to share it after i train it
i will probably share anyways via some discord at some point if it's not a complete fail
welll at least i learned something out of this... pz log splits every 10 mb ๐
Is there a community consensus yet on how to effectively handle BodyLocations.lua? I know that overwrites are generally a bad idea, and you run into trouble with other mods trying the same thing. But I can't find an agreed-upon method for adding items to the render list without causing this issue.
I know Soul Filcher wrote a system to mitigate this, but that only works with other mods using that same system, right?
for some reason if its added to events.everytenminutes or whatever i wanna use
doesnt update the value of the current time...
print("End time: " .. TraitEndTime)
print("Current Time: " .. PZCalendar.getInstance():get(Calendar.HOUR_OF_DAY) *60 + pzCalendar:get(Calendar.MINUTE))
Events.EveryTenMinutes.Remove(clocktick)
Events.EveryTenMinutes.Add(clocktick)
end```
the value doesnt change
There isn't a consensus but if Soul is spreading an API then it might behoove one to use it.
This sounds like a good candidate for the community framework/patch. ๐ค
i run a similar function without adding it to the events
and everytime i call it, it update properly
There's a few mods on the workshop that break body locations which causes a bug in tooltips too.
That'd generally be my position as well; SF's Dressing Time has been out for a few years now without the method seeming to have been widely adopted, though, so I was curious if that was still a method worth pursuing or if people have moved on to a better solution. Sounds like there isn't.
Getting some progress on my mod, next step is to manage to craft and place the item I created.
I feel like I'm so slow on stupid stuff, it's been a while since I have learned modding this way x)
The values are a part of a table and need to be in order right? You can't modify parts of it?
I vaguely recall trying to resolve the tooltips issue and identify the mods breaking them but they hard overwrite the files so the system registers it as vanilla
Right, you can't inject things where you want them. You can reorder the categories but that requires a full overwrite.
If it's a table you should be able to shift it around but I haven't looked at it in a bit
I don't even think it's a traditional table because if it was you should be able to insert things with usual table manipulation.
There's cross referencing functions right?
You can add to the list but there's no remove or replace?
I faintly recall it now
Correct (I think). All you get is getOrCreateLocation()
Which appends new locations
There's no way to insert something, e.g. between UnderwearBottom and UnderwearTop
Soul Fincher mitigates this by turning it into a table
So that other people using his system can now use standard table index insertions, etc. to mess with it
Yeah, it looks great, but if there's another mod that does the standard "just overwrite BL.lua" then you're screwed
Unfortunately that's true for most mods though
What this really needs is dev implementation, honestly, but until then it's rock vs. hard place
It's still better to use friendlier APIs even if it does break
Agree
do you know which ones? I hate that tooltip bug
In lieu of any other option I'd rather be "the friendly mod that got overwritten by the nasty overwrite mod" than "the bully mod that overwrote everyone else's file"
I do always run that mask one
There's an updated one
are you just trying to create new bodylocations?
Which one?
The old one should really be removed from the workshop or unlisted -- that tooltips bug is so innocuous and hard to track down without decompiling the java
the fact that you can ask "which anime outfit mod for this gritty zombie survival game" is funny af
Uhh I only recall it having maids
The newer attachment mod I think also had it -- I couldn't even get that one to work so I gave up
is the new one just "Undo Mask Exclusion updated" or something?
Yes
I made a mod that patches missing body locations to fix the tooltip
It's not ideal at all tho
I assume it causes issues with rendering as I was told the order is important?
I'm currently rearranging existing locations, but a better solution would be to create a location in the right area so that it doesn't mess w/ vanilla functionality; the issue I'm trying to solve is that swimsuits render beneath underwear, and afaik there's no way to turn off underwear spawns per-outfit, so you get zombies walking around in one-piece swimsuits with bras and panties over top
Of course the hacky solution is just to move my swimsuits to a different, higher-rendering location, but this is actually an issue that affects vanilla clothing as well as mine
cant you just make your own file and add to it and declare render order where you want?
and just add to original without overwrite?
Nope
That's the whole issue with BL.lua
It doesn't play nice like the other tables
You can't insert into it without a full overwrite; you can only add a location to the end of the list, but since rendering is order-dependent, that's no good unless you want your new location to appear above every other clothing item in the game
Yeah that needs a couple new setters/inserters
Clothing needs a layer priority system.
well, tired of messing around and things not making sense... guess ill just time the durantion of the trigger from outside the game
LOG : General , 1674083679654> Starting clocktick
LOG : General , 1674083679654> End time: 1394
LOG : General , 1674083679655> Instance Current Time: 1393
LOG : General , 1674083679655> Tempvar Current time: 1393
LOG : General , 1674083694607> End time: 1394
LOG : General , 1674083694608> Instance Current Time: 1393
LOG : General , 1674083694608> Tempvar Current time: 1393
LOG : General , 1674083719511> End time: 1394
LOG : General , 1674083719512> Instance Current Time: 1393
LOG : General , 1674083719512> Tempvar Current time: 1393
LOG : General , 1674083734444> Traits Triggered
LOG : General , 1674083734444> Starting clocktick
LOG : General , 1674083734445> End time: 1394
LOG : General , 1674083734445> Instance Current Time: 1393
LOG : General , 1674083734445> Tempvar Current time: 1393
LOG : General , 1674083744413> End time: 1394
LOG : General , 1674083744413> Instance Current Time: 1393
LOG : General , 1674083744414> Tempvar Current time: 1393```
i could leave it running for hours and still no change
im trying to think on it without having to have you explain too much of the basics of it. is render-order predefined and not editable whatsoever outside of vanilla bodylocations?
or if you do it's always on top
I'm pretty confident it's not just something I'm missing because every other mod that needs to do something similar, including some written by people much better at this than me, has resorted to the same blunt-force overwrite method. (SF's aforementioned API notwithstanding.)
But yeah, the render order is defined by the order in which locations are declared, and once the location is declared there's no way to insert something before it without redoing the whole process (i.e., overwriting the file).
so, from my understanding, when you add a function to a event ex Events.EveryOneMinute.Add(function), the vars inside that fucntion cant be updated ?!?!?! Like it runs a "snapshot" of the values inside and they cant be changed?!?
depends on how you implement it
?
print("End time: " .. TraitEndTime)
print("Instance Current Time: " .. PZCalendar.getInstance():get(Calendar.HOUR_OF_DAY) *60 + pzCalendar:get(Calendar.MINUTE))
print("Tempvar Current time: " .. tempVar)
Events.EveryTenMinutes.Remove(clocktick)
Events.EveryTenMinutes.Add(clocktick)
end```
if the function you pass to the event is a closure you can definitely have access to the data
even i change the value of the tempVar
it retains the previous value
no matter what i try
plus PZCalendar.getInstance():get(Calendar.HOUR_OF_DAY) *60 + pzCalendar:get(Calendar.MINUTE) outside the event always returns the correct value when time changes
but when inside the function in the event... the value never changes no matter how long has passed
in my stupidity i've tried using an tempvar that another function updates
doesnt work when called from inside the function in the event
it works when i just call it myself
so im at a loss
so the function goes static?!
when added to a timed game event?!
well screw the events in the game, using an external timer... one whole day trying to figure this out, something that should be simple anywhere else... in pz lua is a pain in the bottom
I'm sure it is simple, you're just overlooking something
What are you trying to trigger EveryTenMinutes? Where is tempVar declared?
dude theres like 5 lines of code...
ignore the tempvar
that was a try to solve it
What is your goal?
print("End time: " .. TraitEndTime)
print("Instance Current Time: " .. PZCalendar.getInstance():get(Calendar.HOUR_OF_DAY) *60 + pzCalendar:get(Calendar.MINUTE))
Events.EveryTenMinutes.Remove(clocktick)
Events.EveryTenMinutes.Add(clocktick)
end```
this should work
timervalue in minutes is set to 5
TraitEndTime = pzCalendar:get(Calendar.HOUR_OF_DAY) *60 + pzCalendar:get(Calendar.MINUTE) + timervalue
then i get the time the event is triggered from twitch
all goes well so far
then
that function i only made for testing since it wasnt working on the real function i want to use, so i made something simple to track the changes in the values which is the clocktick above
the full code should be
local playerChar = getPlayer()
--local currentTime = pzCalendar:get(Calendar.HOUR_OF_DAY) *60 + pzCalendar:get(Calendar.MINUTE)
print("-----Checking timer trait-----")
print("Current time: " .. pzCalendar:get(Calendar.HOUR_OF_DAY) *60 + pzCalendar:get(Calendar.MINUTE))
print("Finish time: " .. tostring(TraitEndTime))
if TraitEndTime <= (pzCalendar:get(Calendar.HOUR_OF_DAY) *60 + pzCalendar:get(Calendar.MINUTE)) then
player:getTraits():remove(tempTrait);
HaloTextHelper.addTextWithArrow(player, getText("UI_trait_"..TWEtrait), false, HaloTextHelper.getColorRed())
Events.EveryOneMinute.Remove(TWE_TraitCheck)
end
end```
but it it doesnt update the values in the clocktick i made just to print the time
function clocktick()
print("Instance Current Time (stale): " .. PZCalendar.getInstance():get(Calendar.HOUR_OF_DAY) *60 + pzCalendar:get(Calendar.MINUTE))
print("Instance Current Time (fresh): " .. PZCalendar.getInstance():get(Calendar.HOUR_OF_DAY) *60 + PZCalendar.getInstance():get(Calendar.MINUTE))
end
Events.EveryTenMinutes.Add(clocktick)```
```[18-01-23 17:33:59.246] LOG : General , 1674084839246> Instance Current Time (stale): 1052.
[18-01-23 17:33:59.246] LOG : General , 1674084839246> Instance Current Time (fresh): 1053.
[18-01-23 17:33:59.863] LOG : General , 1674084839863> Instance Current Time (stale): 1052.
[18-01-23 17:33:59.863] LOG : General , 1674084839863> Instance Current Time (fresh): 1053.
[18-01-23 17:34:00.495] LOG : General , 1674084840495> Instance Current Time (stale): 1052.
[18-01-23 17:34:00.495] LOG : General , 1674084840495> Instance Current Time (fresh): 1054.```
Like I told you. pzCalendar is only ever instantiated and never updated.
get(property) just gets the value that was set when it was last updated either through getInstance or getCalendar
print("Instance Current Time: " .. PZCalendar.getInstance():get(Calendar.HOUR_OF_DAY) *60 + pzCalendar:get(Calendar.MINUTE))
print("Instance Current Time (stale): " .. PZCalendar.getInstance():get(Calendar.HOUR_OF_DAY) *60 + pzCalendar:get(Calendar.MINUTE))
i have the sime
same
and changed it after you told me that
You're comparing it to the stale print
The fresh is the one that is updating correctly
Because it's using PZCalendar.getInstance instead of pzCalendar to get the minute
it only updates when getInstance is called? haha thats definitely not intuitive
didnt change this bit pzCalendar:get(Calendar.MINUTE)) ....
Also, I think its giving real world time. Because even on max time setting, it still took a minute RL for it to change.
i know that
Ah, okay then.
thats the point ๐
and done...
everything works...
uff
thanks @vast nacelle
Can anyone assist me with uploading to steam workshop? Ive followed all the steps properly and have it matching a guide exactly but when I go to upload ingame it throws the error that there is no preview.png which it is present in the mod folder with the Contents folder and Workshop.txt
256x256 exactly
hmm I sent it through a program to make it that exactly
size wise
obviously it must be wrong
yep
thank you Nippy Ill report back
perfect for the framework
I'm still debating on separating the patch / framework / debugTools tbh
I've been going back and forth in my head lol
my idea hasnt changed
I'm probably over thinking it - but chances are the patch may need the framework to some degree
patch standalone
framework + debug tools are one workshop mod and 2 ingame
I was thinking the easiest to handle github wise would be 1 workshop 3 in game
i guess only difference would be download size
still gives the option of enabling or not the patches
yeah for sure
Maybe I'm not the right person to ask about download size ๐
I'm no 30GB brita but...
it's only 5MB
That alone is probably larger than all my mods XD
Do you guys know how to set the container icon for an isoObject? Is it part of the tile definition?
why did you disable comments ๐ฅน
roughly remember it getting the container texture from the object name
media/lua/shared/Definitions/ContainerButtonIcons.lua
It's hard defined
they are right but also you can change container type in the properties and it will cahnge it
as long as you are using what they got ๐
You can also define new ones too
well that would make you extra cool
speaking of cool
pulled my ehe debug tests out of general debuggers addPanel process
had to make my own page UI for buttons
going to take this into debug tools - I'm thinking of a control board layout that you can drag and drop buttons for a custom layout
Stupid question but i just wanted to confirm since its been years since i last touched lua
Using itemtweaker, for each property i want to change, i just basically need to tweak them one by one right?
Example: if i wanted M14s to have piercing bullets, it would be like TweakItem("Base.AssaultRifle2","PiercingBullets","TRUE") or am i doing something wrong?
Yes, but you should probably not use ItemTweaker tbh
internally it just uses doParam
itemTweaker afaik causes problems with MP since it's on client-side
what am i doing wrong here ?
@sour island do u know is there any way to create panel with web page content? I mean like web-browser feature
Any way to set a specific generator to be "infinite"? Assuming the exact placement is known.
Not sure but you can have a button open an URL
nah, I just fuked up with all existed in-game ide and want to create one with lua_editor created by github
hmm?
An API method for opening a URL has been broken due to a JVM flag passed when launching the game.
Oh this is useful - can you compile with it?

I use this for testing out Lua stuff I'm not familiar with: https://www.lua.org/demo.html
Actually.,,......
if I could open this page on panel in the game then it will be so powerful
loadstring() + seever-side server commands - separate process + file reader = ghetto http service.
I'm writing a html render engine in PZ btw using React.
What he wants is to straight up render a web page ingame
Yuuuuup
That's probably a no-go lol
Or you could just write UI with custom HTML and CSS for pz
the open URL uses local browser too - not even Steams (for better for for worse)
Doesnt openurl just open it in steam overlay
Doesn't for me
local browser?
wat
default browser for computer
ah
Set java.awt.headless=false to fix openURL()
That's the offending JVM arg
I reported this issue and got a silly response
Used to use openURL() to make a discord invite button on my server
It's a useful API call and it needs to be fixed. This is the fix......
poor in-game console and no web content feature
really pain in da ass
rn just doing code in real ide and just reload the file in-game
very cool

Real ide?
I use vscode for both vanilla Lua mods and Typescript mods.
me too
IntelliJ IDEA for Java modding.
Used to use eclipse with my CLI fernflower ...
I have decompiles of PZ from build 31 lol
I want web in-game ide at least for tab feature..
meme
Well I'm unironically building CSS and HTML render engine in PZ so I think that you might be interested in that. XD
empty words for ppl that uses tab = 4 spaces 
yeaaah, I'll be looking forward to it
I just worked on a Java mod that implements what's needed for backdrop-filter
Althought I think for pz it's not so useful
Response UI in PZ would be insane
local player = getPlayer()
local currentTime = 0
local hour = PZCalendar.getInstance():get(Calendar.HOUR_OF_DAY)
local minute = PZCalendar.getInstance():get(Calendar.MINUTE)
local second = PZCalendar.getInstance():get(Calendar.SECOND)
if hour == 0 then --check if its 0, if true replaces 0 with 24
currentTime = (24 * 60 + minute) * 60 + second
else
currentTime = (hour * 60 + minute) * 60 + second
end
for i, v in ipairs(Traits) do
local trait = v.trait
local endtime = v.endtime
if endtime <= currentTime then
player:getTraits():remove(trait);
HaloTextHelper.addTextWithArrow(player, getText("UI_trait_"..trait), false, HaloTextHelper.getColorRed())
Events.EveryOneMinute.Remove(TWE_TraitCheck)
end
end
end```
is this good enough or can i improve it?
Assign redundant calls to variables
the table is example ```local Traits = {
{trait = "Trait1", endtime = 120000},
{trait = "Trait2", endtime = 240000},
{trait = "Trait3", endtime = 360000}
}
?
what redundant calls?
i have to check the time in realtime so that has to run everytime the function is called
i fail to see where i could assign anything else to a var
but do tell
PZ calendar calls
put PZCalendar.getInstance() in var
put player:getTraits() in var
Assign those redundant chained calls as a local variable.
if i dont do it that way
still didnt work
also tried
OnDistributionMerge
OnSpawnRegionsLoaded
OnDistributionMerge
OnSpawnRegionsLoaded
will not update the value
i can remove the vars and do the full code with the call to pzcalendar
just optimization
on functions that are added to events
the var keeps the initial value
since im calling an instance of pzcalendar
thats the only way i got it to work
i could like i said just call the instance directly and remove the vars
even so
but that changes little
u can local this in event function scope
the vars are local to that function
You asked how to make your code better. It's your call.
baaad
local hour = PZCalendar.getInstance():get(Calendar.HOUR_OF_DAY)
local minute = PZCalendar.getInstance():get(Calendar.MINUTE)
local second = PZCalendar.getInstance():get(Calendar.SECOND)
goood
local calendar = PZCalendar.getInstance()
local hour = calendar:get(Calendar.HOUR_OF_DAY)
local minute = calendar:get(Calendar.MINUTE)
local second = calendar:get(Calendar.SECOND)
doesnt work
It's a bad practice because this code is vulnerable to wasteful calculations.
i thought the same but its not
everytime you want to get the time ( current time )
you need to do PZCalendar.getinstance
or in your case
calendar.getinstance
you don't need to grab it three times every frame though, it's not changing between each time
you can grab the instance once and use it for the rest of the function
it can't be
albion doesnt work that way
lost a whole day trying to figure out why the values were static
till cosmic i think
showed me the solution
Huh?
function clocktick()
print("Instance Current Time (stale): " .. PZCalendar.getInstance():get(Calendar.HOUR_OF_DAY) *60 + pzCalendar:get(Calendar.MINUTE))
print("Instance Current Time (fresh): " .. PZCalendar.getInstance():get(Calendar.HOUR_OF_DAY) *60 + PZCalendar.getInstance():get(Calendar.MINUTE))
end```
it needs the getInstance on every get
or will not be the current time
did u do local calendar inside event function scope?
here
Yeah so get it once?
its outside
do inside
Put it inside the func?




