#mod_development

1 messages · Page 368 of 1

tough oxide
#

For me - a 700+ line file is insane

#

Good for indie but not for me

willow tulip
#

if they had broken it down into smaller useful functions I wouldn't have to -_-

tough oxide
#

And I’m happy to hear why I’m wrong

willow tulip
frank elbow
#

I'm not sure there is a right or wrong to that sort of thing, more appropriately "advisable for X reasons" and "inadvisable for X reasons"

willow tulip
#

Good development enviroments also make large files easier to handle

tough oxide
#

Sure - if you load files - cache it but otherwise break it up unless it creates a lot of method/function calls

grizzled fulcrum
#

large files are unavoidable for pz UI

#

or at least b41 ui

tough oxide
#

Basic C says don’t call functions in a loop

grizzled fulcrum
#

this was me for carwanna but instead I just decided to rewrite the entire mod because it irked me so bad

willow tulip
bronze yoke
#

i've come to believe that rewrites might be more valuable than refactors in a lot of cases

tough oxide
bronze yoke
#

if you know how to do something better the old structure is quite likely to hold you back

#

with the horse mod we kind of ended up in a spiral for a bit where we would refactor things we already refactored because it still wasn't good enough

grizzled fulcrum
#

half the time programming is just redoing things over and over as you get more insight

bronze yoke
#

whereas the ground-up rewrite modules have stayed pretty solid

tough oxide
#

If they didn’t do the thing they did I wouldn’t have done the thing I did

bronze yoke
#

there's no downside to thanking someone, even if a mod was purely inspiration it's the nice thing to do

tough oxide
#

I haven’t put it on the workshop yet but I’ve already put the link in the code

#

Beyond nice - in my core it feels like the right thing

#

Speaking of such - I asked myself why there are so many iso objects

#

ISO means something different for me then I realized ‘Indie Stone Object’

grizzled fulcrum
#

Isometric

tough oxide
#

The actual game style

grizzled fulcrum
#

yes but i think its ISOmetric

#

i cant see why they would name it Indie Stone Object when their package name contains their unique stuff

tough oxide
#

Okay - I’m new here but (inserts opinion)

#

They seem to really want people to understand why you should name things with your own prefix

#

I have to imagine there are a huge amount of mods created by people who don’t know the word “instantiating”

#

But they still created something cool because the entry level was low

bronze yoke
#

it's definitely Isometric but i think some of the people they hired on didn't know that and it ended up assigned to a lot of nonsense

#

for their lua classes, IS stands for Indie Stone, but most mods name their classes IS.. too 😅

tough oxide
#

I’ll fight you over this

#

The IS prefix is just for Indie Stone

#

Isometric isn’t part of that

#

/me punches limp plastic bag

grizzled fulcrum
#

like ISObject or ISPanel, thats to avoid collisions with their loading the lua files

#

which you can avoid totally by just putting your lua files in a subfolder with your mod name

tough oxide
#

I’m still not sold on lua unless you have a bunch of automation tools

grizzled fulcrum
#

its one of the best and easiest ways to sandbox

tough oxide
#

Also they seemed to, I’m new, give a ton of access via lua

grizzled fulcrum
#

b42 made a lot of more things exposed

#

but its still controlled relatively

tough oxide
#

There’s a part of me that wants to deep dive that

grizzled fulcrum
#

for example you can't use most of the os things in lua, or any debug things

tough oxide
#

Just to open source and expose

grizzled fulcrum
#

and you cant just call some java function to get remote code execution on the player's computer

#

not to mention how easy lua is on a level of just pure language

#

of course I mean that as in, not exploiting any TIS provided functions

tough oxide
#

I haven’t seen an eval or whatever yet

frank elbow
#

I enjoy using Lua*, especially with type annotations. Much quicker and less boilerplate involved (coming from someone who's written a lot of C#, before top level statements were a thing)

*except for the lack of continue

tough oxide
#

Dotnet 10 has been fun

grizzled fulcrum
#

I think typescript could be a worthy contender (something Jab realised too) but to each language has its downsides

tough oxide
#

And I’m coming in fresh

frank elbow
#

I enjoy TS but I'm not entirely sold on transpiling it to Lua, for my own use anyway

tough oxide
#

As much as I’d like to see some version of ecma - just stay with lua

frank elbow
#

I think if people want to do it or even just experiment then they certainly should

#

But I personally agree

tough oxide
#

I mean the ecosystem out of the box

#

Imagine people debating over preact for the ui stuff

frank elbow
#

To clarify, the TypeScript thing isn't a suggestion for what the devs would move to—it was/is a project for transpiling TypeScript to Lua for PZ mods

bronze yoke
#

i'm very fond of lua

frank elbow
#

I recall a friend who hasn't touched it asking me whether I like it or tolerate it & I came to the same conclusion

tough oxide
#

Legit Omar - that actually gave me some inspiration

#

I just don’t want to go from lua to ts

#

But ts to lua

bronze yoke
#

there's a couple things i definitely don't like about it (how globals work, lack of typing) but overall i find it quite easy to work with and very flexible

grizzled fulcrum
#

I didnt mean TS stuff for implementation stuff, but javascript is easy to sandbox and typescript provides a good type system (i didnt mean transpiling but if TIS could go back, I mean)

tough oxide
#

Globals should die

frank elbow
#

Oh I guess it was the thing I said it wasn't lol

#

I think at the time they added mod support TS must have still been fairly new

tough oxide
#

It’s the worst thing someone new to programming should learn or see

frank elbow
#

I think it's just something misunderstood in many languages, although in many still the usual wisdom is “typically, don't”

tough oxide
#

Global should be an exception

bronze yoke
#

lua 5.5 introduces a keyword that lets you remove globals from a scope entirely (lexically) but it's still global by default

#

and of course we'll never be using lua 5.5 in pz

winter bolt
#

i swear as soon as you mod a game once its like cursed forever and almost impossible to play again

#

ive been getting into deadlock again but all i can think about it making custom skins now whenever i play it

tough oxide
#

There should never be a variable in scope that you didn’t know about or intend (corporate mind) but I understand games are more fun in that way

frank elbow
#

The joy of creation just seems to beat the joy of play every time (but man, really need to make some time to play eventually... one more mod change)

bronze yoke
#

i'm strict 'no globals' too, i've just accepted it as an avoidable flaw of the language

#

you can have language servers tell you off for writing globals which usually catches accidental usages

#

but i do find the design of 'global by default, local with a keyword' absolutely baffling

tough oxide
#

I got bit in my early dev life with “change at* a distance”*

mellow frigate
bronze yoke
#

if they use modules it's fine

tough oxide
#

I’ve already made modules when I decided I’m taking it over

bronze yoke
#

i'm admittedly guilty of not including plenty of my variables in the module though but if i were using a global instead i'd do exactly the same thing

tough oxide
#

Lua accessors?

mellow frigate
#

I may have a gap with modules, I never know when I'm isntanciating new stuff and when I'm accessing the instance I want

grizzled fulcrum
#

modules dont need to have an instantiation structure

#

you can just use modules like any other

tough oxide
#

You should toy with that until you understand

#

I took over a mod that’s most important part was a lua table and I broke all of that out into its own file

#

If it changes again I hope to fix one small file and move on

frank elbow
tough oxide
#

Literally what I did

mellow frigate
frank elbow
#

Instances aren't really a thing here

#

If there's no metatables or otherwise faked “classes” involved it's just a table

tough oxide
#

I was gonna say assigning is the instance

frank elbow
#

Oh I misunderstood the question because I read the word instance lol

#

Yes it's a singleton in that sense

tough oxide
#

As far as accessing and garbage collection it seems to be handled nearly the same

#

Unless you say local - it’s a god object

frank elbow
#

But that's more a question about how require works—once it's called once it'll reuse the return value of the first require (details excluded in this simplified explanation, and the details are also different for Kahlua)

tough oxide
#

Which is a great feature

#

And everyone should read that

#

It’s important

#

That was literally my low hanging fruit when I was bringing this mod up to date

bronze yoke
#

require does two things:

  1. run the file if it hasn't been run already
  2. return whatever the file returned whenever it ran
#

since tables are always passed by reference in lua, a file that returns a table always returns the same table to all requires

tough oxide
#

local details = require(“structuredTable.lua)

#

Didn’t even think about point 1

#

Cause my file just returns

#

But another solid point

#

Also in a game are we thinking about the filesystem that much after it loads?

#

Generally the file system is just reload state and then* we doing it live

bronze yoke
#

because lua files are functions, load order can be more important than it intuitively should be, and require can be used to manipulate that

tough oxide
#

Sure - you got an exploit in mind? Otherwise it’s base game then mods - which seems to allow monkey patching - totally cool - then whatever user is the *
running *the gui

#

I run a server in a container so i refuse to care as much as I should

frank elbow
#

I imagine it was “manipulate” in the sense of “control,” without the negative connotation—so not something to exploit, necessarily, just something to use to affect the load order

#

That was my interpretation, anyway

brittle spruce
#

...Outfits are tricky. Am struggling a bit with getting them to 'stick' on a spawned zombie.

#

Half the time they seem to revert back to randomised attire.

willow tulip
#

and.. timed actions?

#

Well.. shit.

#

Anyway, spices now work for my new cooking menu, yay.

#

now to rewrite how happiness actually works when cooking...

#

Make it actually based on cooking skill and time spent cooking instead of... how many random ingredients you managed to cram into one meal

#

Anyway, Good day 1 development of mod.

#

Now more or less processes cooking like vanilla does.

#

(though I suspect adding poison is broken since its a private function to addpoision and I have to port that to LUA too but meh)

#

<player tries to troll other players by poisoning food, gets trolled instead because I never got around to fixing that>

#

Also, hu at the math for extra items...

#
                local changer = 0;
        local extraItems = baseItem:getExtraItems()
                if extraItems ~= nil then
                    for i = 0, extraItems:size()-1 do
                        if (extraItems:get(i) == usedItem:getFullType()) then
                            changer = changer + 1;
                        end
                    end
                end
                if extraItems ~= nil and extraItems:size() - 2 > cookingLvl then
                    changer = changer + extraItems:size() - 2 - cookingLvl * 3;
                end
                ...
                baseItem:setUnhappyChange(food:getUnhappyChangeUnmodified() - (5 - changer * 5));
                if baseItem:getUnhappyChange() > 25.0 then
                    baseItem:setUnhappyChange(25.0);
                end
#

Im... Honestly confused by the intent of the middle part.

#
if extraItems ~= nil and extraItems:size() - 2 > cookingLvl then
    changer = changer + extraItems:size() - 2 - cookingLvl * 3;
end
#

seems to suggest it would increase the penality at very low cooking level... but maybe decrease it at certain higher levels but not if your too high?

#

like I feel they forgot to math.max(0, extraItems:size() - 2 - cookingLvl * 3)

#

also, TIL there is: local nutritionBoost = cookingLvl / 15.0 + 1.0;

#

so in vanilla, level 10 cooking gives you.. 75% more calories?

bronze yoke
#

no

#

the amount of food you take is also reduced and both multipliers are applied to the nutrition added

#

it does increase but not nearly as much as that would suggest

#

at level 10, the amount of nutrition actually goes down from level 9 (by an incredibly insignificant amount)

willow tulip
#

balanced out (not perfectly) by

#
local realUsedHunger = usedHunger - 3 * cookingLvl / 100.0 * usedHunger;
local percentageUsed = math.abs(realUsedHunger / usedItemFood:getHungChange());
bronze yoke
#

you still get 75% more nutrition out of a whole food item but the amount you add to the meal each time is more like +30% iirc

#

at level 10, which nobody would ever be because cooking is pointless 😅

willow tulip
#

no you add less of an ingredient as you level up

#

like the UI says you use 10 hunger right?

bronze yoke
#

yeah that's what i'm saying?

willow tulip
#

but at level 10 you only use 6 or whatever!!

#

AND ITS CURSED

#

because you'll have this stupid 4 leftover!

#

so your like cool, I'll use the 4

bronze yoke
#

you get more nutrition but you add less so the amount of nutrition compared to base is not as high as the base nutrition multiplier

willow tulip
#

NOPE now you have a 1 leftover because it 'saved' you 25%

bronze yoke
#

but after you've used the whole thing you will have had the full multiplier's worth of nutrition, it's just divided into more portions than base

willow tulip
#

and then you just rewrite the entire code from scratch in a fit of rage.

#

Like I just hate the idea that a good cook can get 'more' nutrition... Except by maybe like, not wasting so much when cutting vegis up? but that'd be like a cooking 0~3 skill issue.

#

it should be: a good cook can chop shit fast, without giving you food poisoning by chopping his finger off into your food in the process.

bronze yoke
#

you might as well just remove the cooking skill is the issue

willow tulip
#

Nah, im going to keep cooking, but it will be tied to happyness of meals, and how long it takes to you to safely chop up stuff.

#

And.. chance of food poisoning, along with how clean you are

#

Like imagine: an actual reason to wash yourself/your clothing besides RP/looks.

#

Or change clothing when you get home -_-

bronze yoke
#

the problem is the game doesn't have a real health system so i'm not sure if there's a point to that either

#

either it kills you (dumb and annoying) or does nothing

willow tulip
#

Im thinking that, at low cooking skill, especially if you 'rush' things, you'll have a chance of basically ruining a meal at making it add unhappyness instead of cure it. But thats still calories... So do you eat it, or dump it?

willow tulip
#

maybe its own moodle?

#

thats drops your max HP/speed or something?

bronze yoke
#

it'd have to be it's own thing, being sick doesn't do anything except kill you

willow tulip
#

good, good, good, dead.

#

theres no like.. oh im sick, I move slower, puke sometimes, etc.

bronze yoke
#

i mean it bugs me too but when i think about it, it just doesn't make sense for this game to have a health system

willow tulip
#

It doesn't so much need a health system as just some of the intermediate moodles doing some speed/attack/etc debuffs and maybe drop your max health like being over carry weight does.

#

and like.... just a BIT at first.. unlike tireness/exhaustion....

#

I don't want -50% at first tier moodle lol, -20% is fine plz

#

-20% you can feel but isn't a death sentence... -50% outta nowhere is basically a death sentence since exhaustion per swing stays the same -_-

#

But id also be Ok with more moodles having debuffs.. Like why not give hunger/thrist some 10/20/30% debuffs to speed/attack.

normal moth
#

Can I use the model parameters to rotate the models in game?

I have some time today, and I was planning on tackling this.

I assume I just tweak the rotate value right for attachment points?

Do I need to add a different attachment point for hand slots vs hip slots or back slots??

tranquil kindle
normal moth
tranquil kindle
#

⁨```
model G11Rifle
{
mesh = HKG11K2/G11Rifle,
texture = HKG11K2/G11Rifle,

    attachment muzzle
    {
        offset = 0.0000 0.2655 0.0302,
        rotate = -90.0000 0.0560 -180.0000,
    }

    attachment rifle_back
    {
        offset = 0.0000 0.0767 0.0394,
        rotate = 0.0000 0.0000 0.0000,
    }

    attachment rifle_back_bag
    {
        offset = 0.0000 0.0810 -0.0066,
        rotate = 0.0000 0.0000 0.0000,
    }
}
Here is example of what i did with Rifle. You find attachment name/bone and adjust it with numbers or attachment editor
#

I'd recommend searching for vanila model scripts inside game files and see if any of the weapon models have something similar

#

Honestly i don't recommend doing it this way most of the cases

full flame
#

my gpt chat says that the id in mod.info should match the name of the mod folder, is this true?

devout breach
#

It seems that 42.13.2 introduced an issue where mod data gets reset. I don’t know what triggers it. Maybe this is already known, but if anyone has more information, I’d really appreciate it.

ivory gyro
#

Hey, someone know what that mean ?

    craftRecipe CraftBarrelEmptyBiofuel
    {
        time = 600,
        SkillRequired = Metalworking:2,
        NeedToBeLearn = true,
        timedAction = MakingHammer_Surface,
        xpAward = Metalworking:100,
        AutoLearnAll = Metalworking:10,
        Tags = Biofuel,
        category = Tools,
        inputs
        {
            item 10 [Base.Plank],
            item 4 [Base.Nails],
        }
        outputs
        {
            item 1 Base.EmptyBarrelBiofuel
        }
    }
mellow frigate
devout breach
#

Are you playing lately?

mellow frigate
mellow frigate
bronze yoke
#

yeah that's probably not anything to do with you

#

that would be three separate systems failing at once, somehow all caused by you

mellow frigate
bronze yoke
#

servers just don't handle mods that well currently and also the average server host has always been kind of stupid so i tend to wait for reproduction before i even consider a bug real

tough oxide
#

damn it. my mod worked perfectly fine on my computer, but now that i put it on the workshop.. nothing...

devout breach
#

I apologize for assuming it was something general. I’m probably mixing my own experience (where I clearly have an installation issue) with the reports I’ve been receiving in my mods.

#

I work as a designer, not as a programmer, so I don’t always know how to handle reports when I receive them.

ebon chasm
#

guys how hard would it be for me to get into making a MP compatible mod that adds bone structures Thonk3D thought I should ask before I leap into the rabbit hole

#

it should be a pretty simple thing unless I want to add new functionality assuming I spend the time to make textures, right?

tough oxide
#

i think the bone structures are currently disabled for mp

ebon chasm
#

wait they exist?

bronze yoke
#

what do you mean by bone structures? like constructions made of bones?

ebon chasm
#

like walls and stuff

tough oxide
#

ooooh

#

i was thinking about the stuff they added for ragdoll

bronze yoke
#

yeah that should be fine, shouldn't even need any networking code

ebon chasm
#

I added a mod to my game that lets me get bones from zombies but I'm swimming in bones now and want to make or obtain a mod that lets me make bone walls and stuff

#

Going full primitive

#

might need to throw in a skull throne while im at it

tough oxide
paper ibex
marble marten
#

hey guys, have an issue with the ZomboidSounds.bank file that is the last roadblock hindering me from releasing my mod

I extract the .wav files using the FMOD Bank Tools application --> I replace the sound files with the ones I want to play in-game and made sure to rename my modded sounds in place of the default noises --> Rebuild the Zomboidsounds.bank file and put it back where it's supposed to go and yet surprisingly enough I go ingame and the zombies don't use my modded sound files, they use the ones that I thought were completely gone and replaced.

I think the issue is stemming from the rebuilding of the .bank file but I'm at a total loss. Any and all help would be appreciated.

If I can't figure out the issue I'll probably just release my mod without the reworked zombie noises so it's not critical that it gets fixed but I'd definitely prefer it.

willow tulip
#

I say this because for every sound zomboid has like 5~10 files -_-

marble marten
#

I can tell you the noises I replaced one second

#

I replaced all of the zombie_sprinter_male_vocal_A and B aggro/death/idle sounds, same with the female versions.

#

Someone was saying sprinters also have a vocal_C but when I searched the folder there was no vocal_C variant

willow tulip
#

Ok, so whats the modified date on the .bank file you moved back over?

#

some of those .bank programs put their output in.. wierd places

#

Make sure it has changed size(?) or at least date

marble marten
#

I should've mentioned that too, the rebuilt .bank that is supposed to contain my new sounds is the exact size, down to the byte, as the original .bank

#

I can check the modified date hold on.

dusky quiver
marble marten
#

Okay I'm a fucking idiot, I was looking in the bank folder and not the build folder, the audio is good in-game and works as intended. Thank you for the help @willow tulip

willow tulip
rugged trail
#

Hello!

I have a question about modding policy: does implementing a fix/file replacement via my mod on other author's mod that is "On Lockdown" violate mod permissions, if I post it for public (and if not for public, then by link only)? It's just I haven't found any clear information about that anywhere, yet I saw a lot of mods that do stuff like that. Don't really wanna barge in breaking the rules.

tranquil kindle
rugged trail
jagged fulcrum
tranquil kindle
#

I personally don't mind any patches, if my original mod is required and i kinda feel honored, if someone uses my stuff for Screenshots/videos but i do appreciate credits

woeful osprey
#

Sorry this is super late response but geez that's sick. Are you ever gonna release it the public because I would love to play a 28 years later inspired mod pacjk

analog mesa
#

Can't for the life of me get this mod to show up in the menu, it was on there for a bit but seems to have disappeared sometime after I put EmmyLua extension on(probably not actually related). It's got a common folder, I replaced the fields in the root mod.info and the mod.info in the 42 folder its just refusing to work

#

Oh I see theres a third mfing folder called mods

bronze yoke
#

should be in ⁨%UserProfile%/Zomboid/Workshop⁩ not the steam folder

small topaz
#

I am testing one of my mods in multiplayer and get the following error in the coop-console.txt:
ERROR: General f:9, t:1769896494815, st:1,517,785> GameServer.mainLoopDealWithNetData > Error with packet of type: GameCharacterAttachedItem for 1769896054173276 ERROR: General f:9, t:1769896494816, st:1,517,786> GameServer.mainLoopDealWithNetData> Exception thrown java.lang.NullPointerException: Cannot invoke "zombie.characters.IsoPlayer.getInventory()" because the return value of "zombie.network.fields.character.PlayerID.getPlayer()" is null at ContainerID.findObject(ContainerID.java:390). Message: Stack trace: zombie.network.fields.ContainerID.findObject(ContainerID.java:390) zombie.network.fields.ContainerID.parse(ContainerID.java:316) zombie.network.packets.GameCharacterAttachedItemPacket.parse(GameCharacterAttachedItemPacket.java:83) zombie.network.packets.INetworkPacket.parseServer(INetworkPacket.java:55) zombie.network.PacketTypes$PacketType.onServerPacket(PacketTypes.java:923) zombie.network.GameServer.mainLoopDealWithNetData(GameServer.java:1593) zombie.network.GameServer.main(GameServer.java:897)
Problem is that the error message does not show whether it is triggered by my code and if it is, what line of my code causes the problem. Any idea where this error might come from?

bronze yoke
#

an item that does not exist on the server is being sent to a timed action's constructor

#

this may be to do with an attached item update rather than a timed action actually

small topaz
#

I am indeed manually attaching items (gun to holster) but only on client-side. Maybe that causes the problem (although the gun is created before on server). Strange thing is that vanilla code also does this only client-side from what I've seen (and they even call syncItemFields() on client-side afterwards). But I'll just try doing the same in my code and see what happens...

analog mesa
analog mesa
#

Is there more steps to adding an occupation then defining it then registering it?
Its not showing up

#

Made a translation page for the text name/desc as well

marble folio
analog mesa
#

Doesn't really seem like it, this is one of the mods i'm using for reference

bright fog
#

imports are useless

#

What I would test rn

  • have your registries references in the scripts to lowercase (I've yet to confirm it matters, I think it doesn't as the game puts them in lowercase)
  • put your profession definition in the Base module instead
bronze yoke
#

while we recommend custom modules generally, the module a profession is in doesn't matter whatsoever

small topaz
#

Is there a known issue when adding a mod to an existing multiplayer game? Just editing the server settings doesn't work for me.

outer crypt
#

on a server, is there a time after the mods and moddata is loaded that I can have it run a function? Would that be OnServerStarted()? Answered it myself in testing, this function works fine for pulling moddata as the server is ready for clients. 🙂

willow tulip
small topaz
#

I just detected that the game in multiplayer doesn't detect my mod at all when I try it via subscription on steam! It works fine singleplayer and in multiplayer when I manually put it into my Zomboid/mods folder! But not in multiplayer via a regular steam subscription! What's going on here?

#

Is there a known issue in 42.13.2?? Maybe linux related?

willow tulip
small topaz
#

Oh no! what did they do to linux??

willow tulip
#

like, if your \common folder is \Common, KABOOM.

#

that and stuff like mod.info may need to be all lowercase(?)

#

and shared/client/server/etc etc

small topaz
#

That should be always correct in my case. Only thing is that some folders and lua files have capital letters in it. Not the the standard folders like server/client/shared but some custom files and folders...

willow tulip
#

I think those are OK so long as they are not XML files (Someone else will know better)

#

some mod authors have just lowercased their entire mod -_-;

small topaz
#

works fine in singleplayer btw and when I have the mod in my Zomboids/mods folder

willow tulip
#

you add it to BOTH places in MP right?

#

the 'used mods' and the 'used steam workshop items'?

#

and any mods its dependant on?

#

(to both)

#

(Iv made that mistake lol)

small topaz
#

Only happens when I try to run it via the steam subscription. (In this case, I do not have it in Zomboid/mods or Zomboid/workshop folder ofc).

#

No, no dependency in my case.

willow tulip
#

Ok so you went into the server settings editor right?

small topaz
#

Yes.

willow tulip
#

did you your mod to the mod menu, and then, after hitting next (And it lagging for awhile), add it again to the 'steam workshop' list?

#

on the menu that you'd think is just sandbox settings

#

It works 'locally' without the 2nd step, but not if your trying to use the steam workshop version/let other people join.

analog mesa
#

Currently I only have that registries.lua file and the professions.txt one, is there some sort of file structure or another file I might need that I missed? I'm just tearing apart professionmods that I found that working

small topaz
willow tulip
#

it has to know what 'workshop items' to use for a mod because.. its apparently too dumb to figure that out from the 1st step like every other game.

small topaz
#

Lol! Maybe I write a little extra function which puts it there automatically cause the current situation is not super user friendly I'd say...

willow tulip
#

Right? would save a lot of time and weirdness

#

I had one where I didn't add the mod it was dependent on to steam workshop

#

and then it wouldn't load the other mod, but it would show me all it sandbox settings like it WAS loaded

#

but they would reset every time I loaded the server and I had no idea why this mods sandbox settings wouldn't save!

paper ibex
#

Can this work as a linter? Somehow, when I miss entering a newline before {, the game does not load the script correctly.

bright fog
#

Not every syntax mistakes are implemented in the tool yet tho

#

As for newline before { it really depends what's before {

paper ibex
#

for my case

Items { not work
but
Items
{

#

cost me hours to solve the single newline break

bright fog
#

Items ?

paper ibex
#

oh sorry, i mean
item ItemName {
model ModelName {

bright fog
#

That does work

paper ibex
#

hmmm not for me from my end, doesnt load, let me open computer and give screenshot

paper ibex
paper ibex
bright fog
#

It's usually something pretty obvious

paper ibex
#

yes, it is so hard to pinpoint which one is causing the errors.

bright fog
#

And tbh I suggest using it eitherway

#

Moving over to VSCode is better to manage your project and with all the tools available for PZ dev

paper ibex
#

Yes, im using VSCode and sticking with it. I also use EmmyLua and ZedScript and pzstudio. But no formatter yet for scripts

bright fog
#

Wdym by formatter for scripts ?

paper ibex
bright fog
#

Yea

paper ibex
#

but it again cannot detect the script when i use this: module Base { item RubberChicken_Small {

bright fog
#

Tho the format is not something I usually use and it's from the old extension (PZ Script Support)

paper ibex
#

also cannot detect item RubberChicken_Small {
the { same line cause format for that block on save/format

paper ibex
bright fog
#

The formatter is not up-to-date in the extension, don't trust it

bright fog
bright fog
#

I've got plans for it haha

ivory gyro
#

Hey, someone know why i dont have my output item in my recipe ?

ivory gyro
#

Oh fuck

#

Thanks you men

#

(3 hour for resolve it)

dull moss
#

hey, so I got question regarding this.

Yea this doesnt work, got any idea why?

registries.lua :

ETWRegistry = ETWRegistry or {}

ETWRegistry.traits = {
    GYM_RAT = CharacterTrait.register("ETW:GymRat"),
}

local UNFIT = CharacterTraitDefinition.getCharacterTraitDefinition(CharacterTrait.UNFIT)
-- what I tried
UNFIT:getMutuallyExclusiveTraits():add(ETWRegistry.traits.GYM_RAT)
UNFIT:addMutuallyExclusiveTrait(ETWRegistry.traits.GYM_RAT)

I double-checked https://demiurgequantified.github.io/ProjectZomboidJavaDocs/zombie/characters/traits/CharacterTraitDefinition.html

however when launching the game I get error that

ERROR: General      f:0, t:1769918302334> ExceptionLogger.logException> Exception thrown
    java.lang.RuntimeException: attempted index: addMutuallyExclusiveTrait of non-table: null at KahluaThread.tableget(KahluaThread.java:1447).

So yea idk where to go from here

#

According to docs UNFIT:addMutuallyExclusiveTrait(ETWRegistry.traits.GYM_RAT) should work

halcyon frost
#

I am trying to add a hotkey or a mod click on on an item in the loot panel. I cant seem to find any on hover like commands in the api docs.

#

I am creating a mod for Set Unwanted and am trying to create a faster way to perform the action so you do not have to right click the item each time and go to the right click menu option.

bronze yoke
#

oh i do know actually

#

don't do it in ⁨registries.lua⁩, that's way too early

#

do it in a regular lua file in shared

dull moss
#

ah

bronze yoke
#

registries.lua⁩'s job is to create registries for scripts to be able to reference, so the scripts which add those definitions haven't been loaded yet so trying to get the definitions returns null

dull moss
#

fair. I had assumption that it might be too early and thats why it returns null but for some reason I was mistakenly confident that I have to do this in registries.lua KekW

bronze yoke
#

the only thing you have to do in registries.lua is register registries, everything else should be fine later (until we inevitably find some exploit from the fact that registries is crazy early in load order compared to other lua files)

dull moss
#

Ye, that fixes it, thanks. Interestingly enough

local ETWRegistries = require ("ETWRegistry")
local ETWTraitsRegistry = ETWRegistries.traits

local UNFIT = CharacterTraitDefinition.getCharacterTraitDefinition(CharacterTrait.UNFIT)
UNFIT:addMutuallyExclusiveTrait(ETWTraitsRegistry.GYM_RAT)

still doesn't work, while

CharacterTraitDefinition.setMutualExclusive(CharacterTrait.UNFIT, ETWTraitsRegistry.GYM_RAT)

works just fine

#

regardless, setMutualExclusive works so that's good enough for me PepeLaugh

torn igloo
#

⁨⁨⁨getUsedDelta⁩⁩⁩ doesn't seem to work for b42. Any way I can get the ratio of the drainable item?

ivory gyro
#

Hey, someone know how to add fluid to my Base.Pot in the outputs of my recipe ?

    craftRecipe MakeMashedVegetable
    {
        time = 120,
        NeedToBeLearn = true,
        timedAction = MakingHammer_Surface,
        category = Tools,
        tags = Distiller_Bench,
        inputs
        {
            item 5 [Base.Potato;Base.Corn;Base.Carrots;Base.Cabbage;Base.Pumpkin;Base.Apple;Base.Tomato;Base.Peach;Base.BerryBlack],
            item 1 [Base.Pot] mode:keep,
            item 1 [Base.MortarPestle] mode:keep,
        }
        outputs
        {
            item 1 Base.Pot, 
        }
    }
analog mesa
#

Anyone know where the professions icons are stored? I can only find the tailoring one thats sitting in media/textures alone for whatever reason

ivory gyro
#

\ProjectZomboid\medianewtiledefinitions.tiles

analog mesa
#

Found the raw images online

lost kite
lost kite
mellow frigate
#

or maybe this works in the craftRecipe: ⁨⁨```
OnCreate = RecipeCodeOnCreate.yourModdedFunction,

lost kite
# mellow frigate this is how I add fluid component to the Moats at creation time ⁨```lua if isoOb...

Pretty nice, thanks. I need to get into lua scripting first. At the moment I just defined some items and recipes. So I did it this way:
⁨⁨```
item LyeBottle
{
DisplayCategory = Household,
ItemType = base:normal,
Weight = 1.0,
Icon = GlassBottle,
IconFluidMask = GlassBottle_Mask,
WorldStaticModel = BottleCrafted_Ground,
FillFromDispenserSound = GetWaterFromDispenserGlass,
FillFromLakeSound = GetWaterFromLakeBottle,
FillFromTapSound = GetWaterFromTapGlass,
FillFromToiletSound = GetWaterFromToilet,
Tags = base:glass;base:glassbottle,
component FluidContainer
{
ContainerName = Bottle,
Capacity = 1.0,
CustomDrinkSound = DrinkingFromBottleGlass,
Fluids
{
fluid = Lye:1.0,
}
}
}

Then I use a glass bottle as one of the inputs and my bottle as output.
⁩
But your way is much smarter 😉
quick harbor
#

hi there, im working on a mod that requires a fake player to be made and since isoplayers dont render in build 42, does anybody know what could be a workaround on giving player states or how to convert player states to a isozombie compatible state? the bandits mod could do it and i want to know how i could do that for my mod

tough oxide
#

Anyone considered wrapping the games lua functions and calls to specific game objects?

#

At least the few you might use in your own mod?

bright fog
#

Do you have an example ?

tough oxide
#

yeah, im working on one now that isn't really that beneficial, but a good test

#
local PzNative = {}

function PzNative.getText(string)
    return getText(string)
end

return PzNative
#

im more interested*, for my purposes, to wrap something like player:getStats():get(CharacterStat.HUNGER)

#

as that was broken from 41 to 42

#

and having this wrapper makes it easy to fix or version

#

the big benefit i have is helping my IDE not complain constantly

#

at the moment

#

but

bright fog
tough oxide
#

it doesnt know what getText() is as an example

#

yeah, thats why i was asking

bright fog
#

Because you don't use Umbrella ?

tough oxide
#

i do have umbrella, but i probably need to toy with it

bright fog
tough oxide
#

yeah

#

is it a performance concern with wrapping the calls? basically increasing the number of method/function calls per loop

bright fog
#

It is and just makes your code messy

#

For things that require multiple function calls, like sure yea you can do that, there's a point

#

But when it's a function call doing a single function call ... that sounds fucking stupid lmao

#

Also it technically doesn't remove the problem that your code has no idea what it's fiddling with

tough oxide
#

sure, in my mind it just makes it easier to deal with broken calls when the api changes

tough oxide
#

cause you change it in one place and you're good to go

bright fog
#

That's probably the only advantage to it, but Umbrella already does that

#

Because if Umbrella screams at you: you fix it

#

And when the API changes, Umbrella updates and Umbrella screams at you for broken functions

#

So a properly managed code already handles that

tough oxide
#

damn it

#

i need to fix umbrella

#

this is why i asked cause i figured i was being a bit niave and i could see how it can create overhead depending on where and what im calling

bright fog
#

The ONLY advantage related to that is not having to change stuff everywhere in the code I suppose, so you only need to change a single function rather than many, but that really doesn't outweight the problems that come with:

  • having to constantly check what that function calls to know what API elements it involves
  • makes it messy to manage
  • adds extra functions calls
tough oxide
#

Alright - I think I have it working and it’s complaining a lot about existing code so now the fun part is figuring out how much is actually a problem

ebon chasm
#

ok I remember someone saying there's a special plugin or something I should get from visual studio code other than the ones on the wiki?

ebon chasm
#

I ended up giving up for now 😅 umbrella wouldnt show up and my github was being wonky so I couldn't clone the repository. I'll try again in a couple days probably

#

thank you though!

#

I'd forgotten how much of a pain it is to set up your first environment when modding a game

bright fog
#

Don't worry it's not that bad

#

EmmyLua needs to be reloaded when you've set up your configuration file

tough oxide
#

yeah, its not a complete pain but be sure to read through everything and clone the repo

#

i only say clone cause it should be easier to grab updates

#

for the umbrella stuff

#

also make sure you get the right plugin - theres a few clones

pearl prism
#

Guys, do you have a more practical method for writing descriptions for the mods you publish? I do everything by hand and the result is disastrous.

small topaz
# analog mesa Do you know where I can find the documentation on CharacterProfessionDefinition?...

⁨⁨⁨getType()⁩⁩⁩ can be applied to a ⁨⁨⁨CharacterProfessionDefinition⁩⁩⁩ object and yields the corresponding ⁨⁨⁨CharacterProfession⁩⁩⁩ object (the latter are the things you denote by ⁨⁨⁨CharacterProfession.BURGER_FLIPPER⁩⁩⁩ for example). The ⁨⁨⁨CharacterProfessionDefinition⁩⁩⁩ objects can come by using
⁨⁨⁨local professionList = CharacterProfessionDefinition.getProfessions(); for i = 0, professionList:size() - 1 do local profession = professionList:get(i) -- this is a CharacterProfessionDefinition object end⁩⁩⁩
So to get the ⁨⁨⁨CharacterProfession⁩⁩⁩ from the above, you need to use ⁨⁨⁨profession:getType()⁩⁩⁩ command to get smth like ⁨⁨⁨CharacterProfession.BURGER_FLIPPER⁩⁩⁩ which is what you will need most of the time when working on a profession mod.

small topaz
analog mesa
small topaz
analog mesa
#

There a simple way to change/remove the default clothes you can pick from the editor when making a character? I need to make sure players on the server show up in crafted clothes

small topaz
upbeat turtle
#

i’ve got my workshop descriptions saved as backups too just in case of steam wonkiness Xd

pearl prism
#

At least I don't know any

willow tulip
#

Imagine: Actually knowing how much food you have at a glance

#

(looks at every accessible container from where your standing)

#

Actually I guess this only shows ingredients of certian meals atm.. I could have an overview mode though I guess.

#

Other cursed ideas include: allowing anything to be an evolved recipe ingredient. Add chips to your roast? why not. Gummy bears in your sandwich? Sure.

bronze yoke
#

i've adopted the trick of 'write as little as possible or else nobody will actually read it' which saves a lot of time writing descriptions

willow tulip
#

You can put all the details there if you feel the need 😉

bronze yoke
#

i'd just host a wiki or something on pages at that point

willow tulip
#

that seems like more work then I want lol

bronze yoke
#

it's shockingly easy

dull moss
#

In a process of updating my mod I came across func that I used to set player carry weight and it made me sad cuz on my side I have to add all possible weight changes that might come from other mods. So I was thinking about maybe making like a mini-framework that can be used to merge all weight changes from multiple mods without having mod authors do all that extra stuff and that way existing mods don't have to keep adding support for other mods and instead can just say "go tell this other mod that sets weight limit to use the framework"

Base version would be say few tables like
⁨```
baseWeightModifiers = {} -- here ppl can insert changes to base weight, say "-2" or "*1.5"
weightAfterStrModifiers = {} -- same as before but applied to carry weight after str is accounted for

and maybe some form of priority in the tables, so you could make your jacket increase carry weight by +1 before some trait, for example, applies carry weight multiplier of 1.1

Thoughts?
#

Cuz currently any carry weight changes are just overwritten by whoever fires their set weight func on every tick

bronze yoke
#

sounds cool, that system is annoying enough that mods just don't really touch it

dull moss
#

You'd think so but I have 4 mods referenced in my weight limit func cuz ppl were reporting other mods not working (cuz both mods were fighting for setting carry weight)

paper ibex
tough oxide
#

ill check it out, but im having a reasonably good time with Emmy plugin

#

ive been fixing and refactoring a mod that was apparently made from a mod

#

so ive been pulling out parts of the original mod that it was derived from that arent needed and trying to pull together this 1000 line file into something more reasonable

merry osprey
#

Anyone know of a working more that allows the creation of engine parts?

paper ibex
tough oxide
#

yeah, im running the emmylua extension and got it configured

#

zedscript i disabled for now because i dont have a need yet

analog mesa
bright fog
tough oxide
#

any one mess around with modding using PipeWrench?

#

nevermind

#

it looks abandoned

analog mesa
#

Does chance actually do anything when it comes to starting clothes? I've never really noticed a difference in what I can pick besides clothes provided by the professions

tough oxide
#

am i reading correctly - i should set custom properties prior to setmetadata?

bronze yoke
tough oxide
#

when deriving

bronze yoke
#

so when i select that profession the initial clothing is based on the chances, and i think hitting the randomise button uses it too, but all clothing is always available

tough oxide
#

im used to OOP so im trying to merge those ideas with lua so im pretty green

bronze yoke
tough oxide
#

cause its just a pointer?

#

ill figure it out - just fighting with some IDE complaints - everything works fine but if it can be better..

bronze yoke
#

you usually need to ignore language server complaints about constructors, they just aren't represented very well

tough oxide
#

Nice - the metatable stuff is a bunch fun magic

sour island
#

PSA / Looking for modders: I updated Error Magnifier to include per mod error logging, and for good measure added a custom debug report API. You can include useful information along with any errors tied to your mod for an easier time when people report things to you. If this sounds interesting lmk what you think / if you find issues / have ideas, etc.

https://steamcommunity.com/sharedfiles/filedetails/?id=2896041179 👍

#

example output for Skill Recovery Journal:
⁨⁨⁨```
[SkillRecoveryJournal - Mod Report]
Version = "42.13.1 1267173a2044ba62aa3d0a0e9899b15e9057de5c 2025-12-18 10:34:47 (ZB) (Steam)"
Mode = "SINGLE PLAYER"
SANDBOX = {
RecoveryPercentage = 100
TranscribeSpeed = 1
ReadTimeSpeed = 1
RecoverProfessionAndTraitsBonuses = false
TranscribeTVXP = false
RecoverPassiveSkills = 0
RecoverPhysicalCategorySkills = -1
RecoverCombatSkills = -1
RecoverFirearmSkills = -1
RecoverCraftingSkills = -1
RecoverSurvivalistSkills = -1
RecoverFarmingCategorySkills = -1
KillsTrack = 0
RecoverRecipes = true
RecoveryJournalUsed = false
SecurityFeatures = 1
CraftRecipeNeedLearn = false
CraftRecipe = ""
ModDataTrack = ""
}
CHARACTER = "NONE"
JOURNALS = "NONE"

willow tulip
#

Mmm cursed sandwich

willow tulip
#

But yea, iv now got it using multiple ingredients on a single click, yay.

#

.. without making killer sandwiches

#

Next step: the 'add water' command for pots, and... Timed actions I guess.

#

I noticed that all of the cooking things don't work in vanilla if the item isn't in your inventory...

#

I assume something goes on when the inventory transaction occurs? Like the qued event loses the reference to the food because it moved containers?

willow tulip
#

... Random mod thought: Calcium oxide (Heated limestone) + carbon (charcoal) = calcium carbonate + water = acetylene.. Renewable welding torch refill method?

silent zealot
#

A use for glassmaking, to make the glassware to do chemisty?

umbral totem
tough oxide
#

should i use mouseDown or mouseUp for typical click events? i feel like ive always used up

#

thats a nice UI - maybe in the future you can skill gate some of the stats

#

or its accuracy

sour island
bronze yoke
#

i feel like most things use up

sour island
#

99% of the time yeah

#

But I saw a video interview with a really old school game dev and he went off the rails about it and its sat with me

#

I think it depends on the action if it's for gameplay

#

Shooting a bow and arrow feels right to have it on Up

#

(immersive to feel like you're holding the pull)

#

But shooting or swinging feels like it would be mouse down unless there's a similar wind up mechanic

#

The interview was about menus though 😅

tough oxide
#

yeah, i just took a break and talked myself into Up - i feel like i only used down for like.. selecting items?

bronze yoke
#

attacking would typically be mouse down you're right

tough oxide
#

but if im gonna be popping out a menu - i think Up is better for "feel"

sour island
#

It was John Carmack of Doom

#

He has a few tweets about it 😅

tough oxide
#

wasnt he also the one that came up with the constant that allowed 3d games to be written on that old hardware?

small topaz
#

In multiplayer B42, is there a command to check whether a building has been claimed by some player?

tough oxide
#

it was some vertices calculation or something

sour island
#

No clue, old school game devs were basically wizards

tough oxide
#

actually true

sour island
#

They abused consoles and PCs to do so much lol

#

Reminds me more of us modders breaking PZ over and over

tough oxide
#

im just getting my feet wet at this point

#

so i keep seeing return true on these click events to prevent propagation (for UI elements) - is that a thing?

sour island
#

More often than not those events are fed back up the chain with the derived UI "classes" (Lua doesn't have classes in the truest sense)

frank elbow
#

The return value prevents propagation in some contexts, idk about all of them

tough oxide
frank elbow
tough oxide
#

i keep closing that file

#

i dont know why

frank elbow
ebon chasm
#

before I go too far down the rabbit hole, is there a function call or something I can use to make zombies take damage when they attack a specific structure? Akin to how hitting a window without a weapon would cause you to take damage

#

Actually I should probably just look at how they did it for windows, huh...

ebon chasm
#

do we have a list of functions and language stuff here somewhere? like I'm trying to figure out what "LogicClass" does for a wall for example

bright fog
#

See my pinned message

ebon chasm
#

Which one? the migration? The TIS thingy? The Wiki? 😅

#

I did go through a couple of the pinned threads and looked across the wiki but I'm a little lost honestly

small topaz
#

In pre-42.13 times, we had a global command getCell() which returned the IsoCell around the player (only for single player games). Now I see that we have a command IsoPlayer.getCell(). So, do you think it is save to assume that we can use player:getCell() on server-side to get the cell around the player?

bronze yoke
#

no

#

all getCell() functions are deprecated wrappers around the global getCell()

#

there is only ever one cell

#

IsoCell used to correspond to specific regions on the map, which is why a lot of API implies that objects/squares belong to a specific cell, but it was made global years ago

small topaz
#

But what happens then when I call player:getCell() on server? What and where is the IsoCell which is returned?

For context: In single player, I used getCell() to get a list of all zombies around the player when game starts and it always worked fined for me. So I used

local zombies = cell:getZombieList()
if cell then
  for i=zombies:size(),1,-1 do
    -- do smth with the zombies
  end
end```
ebon chasm
#

thank you!

bronze yoke
bright fog
#

I need to make a dictionary on the wiki for useful pages

bronze yoke
#

things like the zombie list in the server cell may not be reliable, the server does not really use IsoCell the same way the client does

#

the server really uses entirely separate logic in ServerMap that is not accessible to lua at all

small topaz
#

Ok... then I'll probably just disable that feature from my mod on multiplayer altogether. In single player, I used it to make a custom spawn logic for the player when game starts. I used the zombieList from the IsoCell to remove all zombies from the spawn area. But I guess that's not so easy to do in mp on server side anymore.

severe ore
#

Sorry for this question, but i think i read the docs, tried pretty much everything and can't see my mod showing up in the mods panel.
So i am in a Mac and i am trying to test my simple mod.
My mod info is in folder MyMod1/42/mod.info
I have zomboid on stream, and i have these 3 folders:
~/Library/Application Support/Steam/steamapps/workshop/content/108600
~/Zomboid/Workshop
~/Zomboid/mods
Tried to put my MyMod1 folder in all the 3:
In the 1st nested in a bogus <workshopid>/<gameid>
In the 2nd either directly or nested in MyMod/Contents/mods
In the 3rd directly
In all cases in the Mods selector panel i never saw my mod.
Where should i put the mod files to actually show up for activation?
Thanks in advance

bronze yoke
#

does your mod have a common folder

severe ore
#

ahh! Client!

#

i misses the client folder in between

bronze yoke
severe ore
#

Yes! It worked!
I actually had my script under 42/media/lua/client, but forgot to mention.
So the empty common folder was the problem.
Thank you very much!

tough oxide
#

ugh.. the static analysis is so bad for lua..

#

but its fine.. its making me create docblocks which is for the best

small topaz
#

When using object:setMaxHealth(n) and object:setHealth(n) on server where object is a thumpable (a wall or a door), is there a special sync command I need to use to sync it with the clients? The objects in question are already on the map.

In vanilla, all I can find in such a context is object:transmitCompleteItemToClients() but not sure if this can be applied in my situation since vanilla only seems to use it when the object is newly constructed and added to the map.

#

There is also the command object:sync() which might be relevant...

bronze yoke
#

object:sync() is generally what's used

#

it's not clear currently exactly what does and doesn't get synced

#

transmitCompleteItemToClients might cause issues, at least in b41 this would create a duplicate object on the clients rather than updating the current one

tough oxide
#

Wasn’t there talk a few days ago of the sync command being called “automatically”?

bronze yoke
#

player stuff often gets synced on its own after a bit, but things like world objects that don't change often usually won't send updates on their own

tough oxide
#

Right - probably until they are interacted with at the worst or “in sight” at the best

small topaz
#

Thanks!

#

Another question: when I have a thumpable object on the map and I know on client which object it is, how an I identify and access the object on server? Problem is that I cannot send those objects via sendClientCommands.

bronze yoke
#

send the x, y, z and object index

small topaz
#

Ah! Object index is pbbly the thing! Already thought about the coordinates but there can be more than one thumpable on a square.

So how do I get the object index? Is this just the index from the list I grab by square:getObjects() ?

#

And it is guaranteed that the index agrees on server and client for that list?

bronze yoke
#
-- client:
local x = object:getX()
local y = object:getY()
local z = object:getZ()
local i = object:getObjectIndex()

-- server:
local square = getSquare(x, y, z)
if square then
    local objects = square:getObjects()
    if i < objects:size() then
        local object = objects:get(i)
    end
end
bronze yoke
#

the only time they should be different is if the server has added/removed an object and the client doesn't know about it yet

#

so it should be very rare and only for a moment

small topaz
#

Great! Many thanks!

tough oxide
#

another beginner question - is using


---@type table
o = ISPanel:new(x, y, width, height)

a reasonable fix for the IDE complaints about fields not being able to be injected into...

bright fog
#

No that's an awful fix lol

tough oxide
#

lol

bronze yoke
#

you're basically just turning off type checking when you do that

tough oxide
#

this is why i ask

bright fog
#

Because you remove any intellisense for o

tough oxide
#

yeah, but im getting complained to about adding properties to ISPanel in the :new method

bright fog
#

In a derived UI element ?

tough oxide
#

yeah, let me scale it down for posting

#
function StatsUI:new(x, y, width, height)
    local isPanel = {}
    isPanel = ISPanel:new(x, y, width, height)
    setmetatable(isPanel, self)
    self.__index = self

    isPanel.targetAlpha = 1.0
#

i get complaints at targetAlpha

bright fog
#

You need to define your StatsUI as a class which takes on ISPanel

tough oxide
#

sure


---@class StatsUI : ISPanel
---@field targetAlpha number
---@field bars StatsBar[]|table
local StatsUI = ISPanel:derive("StatsUI")

bright fog
#

Then you need to make isPanel that class

#

Not table

tough oxide
#

i started that way

bronze yoke
#

the usual pattern would be```lua
local o = ISPanel.new(self, x, y, width, height) ---@as StatsUI

tough oxide
#

yeah, thats what i had

#

oh dope

#

the . notation

bright fog
#

Yea

#

That's a common mistake

tough oxide
#

gotcha

#

yeah, already had it once today

#

i know everyone uses o but i have a disdane for single letter vars outside of like a for loop

#

so

function StatsUI:new(x, y, width, height)
    local isPanel = ISPanel.new(self, x, y, width, height)
    setmetatable(isPanel, self)
    self.__index = self

    isPanel.targetAlpha = 1.0
#

would be reasonable?

bright fog
#

You're still not setting isPanel type

#

Define the params and returns of :new

tough oxide
#

docblock it?

bright fog
#

You'll quickly see why you need to set its type

#

param and return annotations

tough oxide
#

gotcha

bright fog
#
---@param x number
---@return StatsUI
function StatsUI:new(x...)
tough oxide
#

amazing

bronze yoke
sour island
#

the sacred o

bright fog
#

o

sour island
#

Updating errorMag with some feedback/ideas I got

  • Added handy useful PZ-info dump as standard header.
    Includes game version, game-mode, and luachecksum flag.
frank elbow
#

I've taken to using local this in constructors so I can piss off Java and JS devs who read my Lua code (not really, just because it's like self but dissimilar enough that I won't mix them up)

sour island
#

pain Basically every question I ask commentors who say stuff is breaking in ways that are unexplainable

frank elbow
#

Sounds handy

tough oxide
sour island
#

I also added an API for custom debug dumps

frank elbow
#

instance seems better to me tbh, but honestly names are names at the end of the day

frank elbow
sour island
#
=== Zomboid Settings ===
Version: 42.13.1 1267173a2044ba62aa3d0a0e9899b15e9057de5c 2025-12-18 10:34:47 (ZB) (Steam)
Mode: SINGLE PLAYER

[SkillRecoveryJournal - Mod Report]
SANDBOX = {
 [...snip...]
}
CHARACTER = "NONE"
JOURNALS = "NONE"
bronze yoke
#

i added one for the horse mod this morning but i haven't merged it yet

sour island
tough oxide
sour island
#

I made it required for this purpose - for my own sake and sanity

frank elbow
bronze yoke
frank elbow
#

Yeah, that's the only reason I don't just use that—would certainly be the most Lua-like option

sour island
#

I stand by that players just need guide rails to provide useful reports

#

and leaning on the guiderail metaphor, guiderails > tour-guides (mod authors repeating themselves)

#

really stings when a player butchers a stacktrace error and leaves it on a steam comment 😅

small topaz
#

Does Zomboid's lua version supports the check if math.type(x) == "integer" then?

willow tulip
sour island
#

Yeah in the same vein as updating errormag to be more proactive -- i've been thinking up something

frank elbow
sour island
#

going to see if I can make something of a (semiverified) github issue maker with a template/form from a redirect from steam

#

I've made github a central place to report issues but it just trims too much fat from the pool of people willing to share information

frank elbow
tough oxide
#

and this is why ive left my mod unlisted for awhile

small topaz
#

Can a thumpable object have modData on server?

bronze yoke
#

yeah

sour island
#

Also unrelated - but I wish there was a workshop policy to disclose AI use and maybe to what degree

#

alot of mods look... weird... (not even talking about posters which are whatever) the features discussed are just insane sounding + if you look inside it's all garbage

bronze yoke
#

yeah it's been getting worse and worse

sour island
tough oxide
#

yeah, i had to turn it off on VSCode

#

ive been trying to do some stuff i havent tried before in c# and its so verbose and opinionated

#

if it wasnt giving* bad answers it was also ruining the discovery

#

also thanks for ide/instantiation advice - no errors or kinda false alarm warnings now without supressing

small topaz
#

Has anyone an idea why vanilla game has the TimedAction ISBuildAction still defined in the client folder? From what I see, this is the action which is executed when players build new stuff like walls, doors etc. Shouldn't such a TimedAction have stuff which is executed on server-side when in multiplayer?

bronze yoke
small topaz
#

So, in B42 single player, it is still the code which is executed when building stuff. Don't know how it behaves in multiplayer though.

bronze yoke
#

oh i see

#

building uses custom sync compared to regular actions

mellow frigate
#

Inventory transfer uses some specific transation protocole. it may be similar for that

bronze yoke
#

the building code is really convoluted 😅 hard to see what's used where

#

it is a special cased type of action in the java side of the game

small topaz
#

So they use some custom sync for that and therefore it works although they have it in the client folder?

bronze yoke
#

actions don't *have* to be in shared, it's just generally convenient for them to be

#

they are still allowed to run entirely on the client

small topaz
#

Strange thing is that this action doesn't have a complete() function and the new object seems to be created and added in the perform() function.

What I also found out: on server (!!), they use the command
buildAction = ISBuildAction:new(playerObj, selfCopy, x, y, z, self.north, self:getSprite(), maxTime, containers)
So they may somehow call and execute the whole action on server somehow?

bronze yoke
#

complete() functions are only for networked timed actions, if that function doesn't exist it's a client-only action

small topaz
#

Strange is that if it would be client-side only, how do they sync the new objects added by the client with the server game world?

bronze yoke
#

the function returns before creating the object in multiplayer```lua
if isClient() then
if self.item.completionSound ~= nil and self.item.completionSound ~= "" then
self.character:playSound(self.item.completionSound)
end
ISBaseTimedAction.perform(self);
return
end

#

most likely that server code only actually executes on the client (all build cursors are in server/ despite only running on the client)

#

there is some custom sync going on that i don't see immediately but it is related to the BuildAction stuff i talked about, that triggers object creation too through an event

small topaz
#

Hmmm I see... but where do they create the actual object then when in MP? Or is this somehow done because they add this TimedAction to the queue on server side? So that the server also executes the perform() function?

bronze yoke
#

i think it is only created that way on the client side, the server (by a method i have not worked out yet) creates a BuildAction instead, which has a complete() function (kind of, it is java so it's not exactly the same) that triggers OnProcessAction

#

it uses createBuildAction in its start() function to tell the server to create this action

small topaz
#

The server file ISBuildingObject.lua has this code:

    local square = getCell():getGridSquare(x, y, z)
    local playerObj = getSpecificPlayer(self.player)
    local playerInv = playerObj:getInventory()
    
    -- create build action, early, so we can call startCraftAction before walkTo
    local buildAction = nil;
    if not self.skipBuildAction then

        -- [[ some code ]]--

        buildAction = ISBuildAction:new(playerObj, selfCopy, x, y, z, self.north, self:getSprite(), maxTime, containers);
    end

    -- [[ some code ]] --
    if smth then

        ISTimedActionQueue.add(buildAction)
    
    else
        print("ISBuildingObject -> tryBuild - cannot walkTo target")
        self:onActionComplete();
        return nil;
    end
    
    return buildAction```

so they somehow seem to create and execute the action on server side...?
bronze yoke
#

this is almost definitely running on the client

#

this is a cursor and cursors do not run on the server, remember that code in the server/ folder is not necessarily server code

small topaz
#

Ahh ok... didn't know that... Looks super mysterious to me.

So my problem: To make a mod of mine work in multiplayer, I have to catch the moment where a certain thumpable object has been build by the player and is present on server (the objects in question are doors and walls). In singleplayer, I can simply hook the perform() function from the ISBuildAction but I am afraid now that this might not work in mp...

bronze yoke
#

try hooking Actions.build instead

#

or perhaps in addition, i think this is probably not used in singleplayer?

small topaz
#

where to find that Actions.build function?

#

ah I see, ActionManager in shared

torn igloo
#

Does client's timedactionforceStop get transmitted to server? I got this perform error on server-side whenever I execute a forcestop command on client.

small topaz
#

Omg! If they just created this TimedAction with a complete() function as they did for almost all other actions, it would take me 2 minutes to make my mod ready for mp! Now it is complicated, requires super long and repeated multiplayer testing and... #!$!X(!!(!!#$%!!

willow tulip
#

Nothing is stopping you from just.. adding another function to the global table that is that TimedAction

bronze yoke
#

you would have to make it load on the server

#

otherwise the server can't create the action and bad things happen

#

it would be better to work out how this all really works in mp (i am sure it still goes through lua enough for your needs) than to hack something together like that, that's likely to break with updates

fervent wraith
#

I’m working on a large multiplayer mod that pushes pretty hard into custom ISUI, server-authoritative state, and long-term persistence. Before we lock in some core patterns, I’d really appreciate sanity checks from people who’ve already fought the engine in these areas.

This isn’t a beginner mod, we’re deliberately avoiding "hacks/workaround" where possible and want to build something that survives long-running servers.

-In custom-drawn ISUI panels (not ISScrollingListBox), which mouse callbacks actually fire reliably?
onRightMouseDown
onRightMouseUp
onMouseDown with RMB
Are there known cases where RMB is swallowed by parent containers?

  • When multiple ISUIElements overlap, what actually determines which one receives mouse input?
    Is bringToTop() enough, or can parents still intercept events?

For “card/list” style UIs, what’s considered the least brittle long-term approach?

  • ISScrollingListBox
  • child ISUIElement rows
  • manual draw + hit testing
bright fog
#

The mouse events should work, I'm not aware of any issues

#

For a list, depends what you want really. If you want a selectable list, yea probably go with that

#

If you want an list, there might some UI elements specialized in that, else I'd say make a list isuielement if you want interactions with them, also probably more flexible

fervent wraith
willow tulip
#

So what moodle framework is most commonly used? or do people just impliment it themselves?

#

(Can you impliment custom moodles without conflicting with other moodle mods? easily?)

bright fog
#

People use the moodle framework usually

willow tulip
#

trying to add 'food poisoning' if your filthy when you cook but realizing the vanilla PZ system is.... realllyyy bad about poison being either nearly unnoticable or deadly

#

I want more the 'slowly murders you with thrist/hunger/loss of calories/low max HP' kinda sickness, and not the straight up murder you kind

umbral totem
#

People unsafely adding icons to the left menu is a PITA for making mods isn't it

dull moss
tranquil kindle
tulip valve
#

I guess that they post a small portion of the stack trace error and think its enough

dull moss
#

That's exactly what he means

#

Classic steam report

mellow frigate
frank elbow
#

I have to know what inspired this pattern & similar in PrintMedia code rather than just using tonumber

if key == "width" then
    local val2 = loadstring("return " .. value)()
    self:setWidth(val2)
elseif key == "height" then
    local val2 = loadstring("return " .. value)()
    self:setHeight(val2)
end
#

The only benefit I can imagine is arbitrary expressions, but that sounds less like a benefit and more like a nightmare & it doesn't appear to be used (width and height is always a number, at least in Print_Media_EN)

#

I just noticed the textures are just getTexture calls

mellow frigate
frank elbow
#

It seems very odd to imagine someone knows loadstring and not tonumber, so I believe it was an intentional decision

tough oxide
#

when im troubleshooting a stack trace how do i see the ".... 10 more"?

#

im in debug mode

frank elbow
#

If you're in the debugger (F11), you can view the stack directly

tough oxide
#

thank you

#

i made too many "clever" changes at once and im trying to see where i got too clever

sour island
#

It stings because they're trying to be useful but don't know how -- and if their mental bandwidth for the day is spent you'll probably never get a follow-up

tough oxide
#

to be fair, so far, the default stack traces for me stop too soon

sour island
#

There's a weird logging issue where they sometimes get sent to print too soon so you may see 2 headers for 1 error

#

It's something errorMagnifier also corrects

limber solar
#

hi guys! i was wondering if the levelup sound is not working for you as well or it's one of our mods! thank you and kudos

tulip valve
#

Anyway I can check if the player is in Combat Stance?

I know if isSprinting, isWalking, isRunning, isSneaking but what about when player is in Combat Stance?

bronze yoke
#

isAiming()

tulip valve
#

thank you

small topaz
# willow tulip ... Just add a complete function to it? 🙂

That probably won't work cause they have some specific and convoluted extra logic on server-side which is used when building stuff like walls. Just adding a complete() function would probably involve disabling their whole custom logic to avoid conflicts which would be quite complicated I guess.

#

When hooking their server-building action, I have still problems to set the maxHealth of a building object on server. It seems to have no effect or is not properly synced with the client.

Here is my code where I hook the server-side Actions.build function:

local vanilla_build = Actions.build
function Actions.build(character, args, ...)

    local isOldObject = {} -- store walls or doors which are already present so we don't accidently assign them the new hp
    local recipeName = nil
    local square = nil

    if isServer() and args and args.item and args.item.craftRecipe then
        
        recipeName = args.item.craftRecipe:getName()
        if character:getDescriptor():getCharacterProfession() == Regs.NewProfs.rasArchitect 
           and (isWall[recipeName] or isDoor[recipeName]) then
            square = getSquare(args.x, args.y, args.z)
            if square then
                local oldObjects = square:getObjects()        
                for i=0, oldObjects:size() - 1 do
                    local object = oldObjects:get(i)
                    if object:getName() == recipeName then
                        isOldObject[object] = true -- store old walls or doors
                    end
                end
            end
        end       
    end
  
    vanilla_build(character, args, ...)  -- execute vanilla code

    if square then
        local newObjects = square:getObjects()
        for i=0, newObjects:size() - 1 do
            local object = newObjects:get(i)
            if object:getName() == recipeName and not isOldObject[object] then
                local newMaxHealth = math.floor(object:getMaxHealth() * 1.2)
                local newHealth = math.floor(object:getHealth() * 1.2)
                object:setMaxHealth(newMaxHealth) -- extra hp
                object:sync() 
                object:setHealth(newHealth)
                object:sync()
                break
            end
        end
    end
end```
#

What works is the setHealth() command. What doesn't work is the setMaxHealth() command. So in the UI, the health of the building object is shown is as 588/490.
The essential part in the above code is the second if-condition with if square then.

willow tulip
#

add a custom server->client packet to setMaxHealth() on client side

small topaz
#

So you think it is only due to wrong syncing?

willow tulip
#

Yea they prob never considered maxHealth changing

small topaz
#

Good idea. Definitely worth a try!

#

Hmm... problem is that I have to send this to all the clients then and to all the clients who may enter the game at some time in future (and for all the affected objects which have been build at some time). Maybe impossible doing this but requires some complicated and over-the-top coding to just fix such a little issue...

bronze yoke
#

no, only the clients who currently have the object loaded need to know

#

clients don't know about an object until the server tells them about it, so they will get all information from the server at that time

small topaz
#

So you mean that a new client logging in later will automatically get told about the correct maxHealth value from server?

EDIT: Yesss! can confirm that this works. After logging out and in again, the maxHealth is displayed correctly. So it should suffice to only send info to the clients who are actually logged in!

#

That's probably not too complicated...

bronze yoke
#

it should be fine even if a client isn't near the object, so if the square returns nil it's fine

#

you only need to update the max health for the clients that currently have that object loaded

small topaz
#

Is there an easy way to get exactly those clients? Or wouldn't it be easier to just do it for all clients logged in?

bronze yoke
#

send it to all clients, but if they don't find the object it's fine

willow tulip
#

Ohh

#

You can try this hack that iv used to sync stuff that won't sync:

#

Just remove the item from the world and readd it.

#

ie: transmitRemoveItemFromSquare() then transmitCompleteItemToClients()

#

From what I can tell, the game sends a lot more sync information when an object is first 'added' vs any of the sync functions

bronze yoke
#

of course it does, when an object is added it needs to tell the client literally every single thing about that object

#

the client doesn't know anything about it

small topaz
tough oxide
#

So with lua requires - is it from the base “client/server/shared” of your mod? So a file in a child folder of let’s say client like “client/ui” would just require it as though it were in the same folder? It being a file in the root

#

Seems like something changed and the dot notation wasn’t working

frank elbow
severe ore
#

I have a question regarding getting information about food (such as DaysFresh, DaysTotallyRotten, etc...).
I know all this information is in media/scripts/generated/items/food.txt
Do you know of any API way to obtain this information from lua?
I know i can always read this file from Lua and parse this data myself (and maybe there are even builtin Lua functions to facilitate that), but anything already in the API would be even better.
I am not talking about current property values of concrete food items in the game, but values about the type of food.

willow tulip
#

did you want every item or a specific item?

#

Either way it comes down to this API for an 'item script'

severe ore
#

Does an instance of Item relates to a concrete item, or to an item type?
Example.. will we have one instance for Broccoli, or one instance for every Broccoli in the game (or known/visited cells)?

willow tulip
#

the definition of every broccoli in the game, is an Item

#

you use inventoryItem:getScriptItem() to get the item from the inventoryItem

severe ore
#

Ahh! so InventoryItem is a concrete item and Item is the type

willow tulip
#

basically.

#

do note a lot of properties get copyed into inventoryItem when created and won't be updated if you change Item later, but SOME will.

severe ore
#

yes, i was trying to understand if those get updated

willow tulip
#

PS: in item, its getDaysTotallyRotten() and getDaysFresh() for the rotten/stale timers

bronze yoke
#

not all properties have a getter either, and some that don't have a getter do on InventoryItem which means you may need to instance the item to get it 😅

severe ore
#

DaysFresh and DaysTotallyRotten. I wouldn´t expect, as it would be a lot of work to be reducing the value of all InventoryItems as time passes

severe ore
bronze yoke
#

no it's just random

#

it's not decided by any logic more than 'did they remember to add one'

severe ore
#

DaysTotallyRotten, for example, is both public and has setter/getter. A bit of redundancy there

#

Ok, so from Item i can get all that data. Is there an API to get all Items in the game?

#

probably is such method exists, it will be in the GlobalObject

bronze yoke
#

you can get all items from the script manager

willow tulip
severe ore
#

public fields are not encouraged in Java language, but i guess here they come in handy

willow tulip
severe ore
#

but it´s good to know Lua accesses them in the "right" way

willow tulip
#

getAllItems

severe ore
bronze yoke
#

the reflection lua can use to access fields doesn't care about accessibility modifiers

willow tulip
#
local allItems = getScriptManager():getAllItems()
for i=1,allItems:size() do
  local item = allItems:get(i-1)
-- do stuff with item
end
bronze yoke
#

i-1 🙁

severe ore
willow tulip
willow tulip
#

ISLiteratureUI:setLists()

frank elbow
#

That's odd, typically you'd find Java-like patterns in vanilla Lua (sometimes to the detriment of said Lua)—wonder who wrote that one 🤔

severe ore
#

I'm still relatively new in Lua. Started it a couple of years ago, playing around with Defold engine. Its a simple and nice language, but i don't master those metatables (yet) and all the tricks

#

but anyway, i am sure getAllItems() it´s something not to be called all the time. I expect to call it only once, in the start

severe ore
willow tulip
bronze yoke
#

specifically it's a complaint that when looping over java collections you should do for i = 0, list:size() -1 instead of subtracting 1 from i every iteration

severe ore
#

only now i noticed. so allItems() returns a Java list (0-based), not a Lua table (1-based)

willow tulip
#

is the preferred method to save a -1 every loop.

bronze yoke
#

in newer versions of lua it would even crash to do it the other way

severe ore
#

indeed. Only computes -1 once

willow tulip
bronze yoke
willow tulip
#

lua code generally returns tables.

willow tulip
bronze yoke
#

oops 😅

frank elbow
#

imo the biggest benefit isn't really optimization, just that it's cleaner to look at—you're getting the index at i

bronze yoke
#

still, it's weird if index doesn't-- yeah

frank elbow
#

Subtraction isn't all that expensive

#

Some would even say it's a constant time operation (I would say that too, because it's true)

bronze yoke
#

if you're iterating over a collection and the variable specifically claiming to be an index into that collection isn't, that's poor style

willow tulip
severe ore
willow tulip
frank elbow
#

I think if you're dealing in something 0-indexed the loop should be 0-indexed, if it's 1-indexed it should be 1 indexed

willow tulip
#

LUA is just weird with its 1 based arrays and all people should be subjected to the concept of 0 based indexing if they wish to program.

bronze yoke
#

i don't seriously worry about the cost, subtraction is essentially free, but it's a lot easier to convince people if it's slower than if it just looks bad

willow tulip
#

off by 1 errors are a beautiful thing that we need to subject the youth of tomorrow to at every opportunity.

frank elbow
frank elbow
willow tulip
#

shrugs

#

lUa, now in camelCase!

severe ore
willow tulip
severe ore
#

Yes, i can imagine. Even sorting algos have their own sweetspot. Some are faster for small lists, other for long, and some even for something in the middle

willow tulip
#

"Ok so turns out we've been doing this wrong all along, it should be

local allItems = getScriptManager():getAllItems()
for i=allItems:size()-1,0,-1 do
  local item = allItems:get(i)
-- do stuff with item
end
willow tulip
severe ore
#

what is the 0 and -1? termination and step? Are we traversing in reverse?

willow tulip
#

Its faster to compare against 0 on the x86 and most processors than it is to compare against arbitrary values since there is often a 0 register.

#

Of course... have fun dealing with cache misses and such.

#

so of course 'it depends'

bronze yoke
#

every day i thank god that i'm mostly writing gameplay code that doesn't really need to be significantly optimised

willow tulip
#

inner loops where the loop is only doing a few math operations, the loop starts becoming a signfiicant cost lol

willow tulip
#

If your doing an event spawned by some NPC that you have 100's of, spamming that event every frame.. Now you have problems and better get that code running fast.

#

I spent wayy too much time optimizing UI stuff before I realized most UI buttons had a click frequency of <0.1hz -_-;

bronze yoke
#

the problem is we usually think of performance in percentage increases ('it is 20% faster') etc and don't think about what it's 20% of

willow tulip
#

yea, making the code that eats 1% of your cpu time 99% faster does nothing. Making the code that eats 90% of your cpu time 10% faster is decent gains.

bronze yoke
#

your maths code should be fast, your gameplay code should be pretty

willow tulip
#

And even then... gains are often situation dependent...

#

I recall one game dev testing a fix I gave.. saying it only did 5~10% FPS so not worth it...

#

... Except the most popular mod on the workshop spammed the ever living hell outta the entity that needed culling, meaning with that mod the fix was more like +25~50% FPS

#

and made the maps 2x bigger (4x area), so there was like 10x as many entities

bronze yoke
#

% of fps is a meaningless statistic in the abstract 😅 the cost of a frame decreases as framerate increases

willow tulip
#

Not entirely due to that issue, but sure didn't help.

#

Other fun things it was doing: you know how video cards can.. tile a texture?

#

And many games, especially 2d ones will use a repeating texture?

#

Yea.... their engine broke down any polygon with a UV repeat style texture.. into separate draw calls for every repeat of the texture.

#

This wouldn't have been... that horrible, had one of there 'used absolutely everywhere' signs not had a like 16x16 tile background repeated over 100x300+ pixels

#

a tile background that was essentially just black + 2% random noise.

#

did they fix the engine to use shaders to properly UV repeat polygons? Hell no.
They just changed the sign background to be bigger and it increased their FPS by 20~30% on most vanilla ships -_-;

small topaz
#

I am currenly trying to modify a building object's maxHealth on server via this construction:

 object:removeFromWorld()
 object:removeFromSquare()

 object:setMaxHealth(newMaxHealth) -- extra hp                
 object:setHealth(newHealth) 
 object:setIsThumpable(true)
 object:sync()

 square:AddTileObject(object)
 object:transmitCompleteItemToClients()```
Problem is that for such an object (which is a wooden wall in my case), it somehow hasn't any hit-detection anymore. When I manually hit it with a hammer, there is no hitting sound and the health is not reduced.
willow tulip
#

I don't think you want the lines:

 object:removeFromWorld()
 object:removeFromSquare()
#

but I could be wrong.

#

I also recommend not bothing with object:sync()

#
 object:setMaxHealth(newMaxHealth) -- extra hp                
 object:setHealth(newHealth) 
 object:setIsThumpable(true)
 square:transmitRemoveItemFromSquare(object)
 object:transmitCompleteItemToClients()
#

is basically what I would do (though your free to have the remove at the start, it doesn't really matter)

#

the remove/send process should sync everything

bronze yoke
#

i wouldn't overcomplicate adding/removing objects like this

willow tulip
#

And you don't actually need to remove/readd to the square on the server side, just tell the client you did.

bronze yoke
#

all you need to add or remove an object is```lua
--add
square:transmitAddObjectToSquare(object, -1)
--remove
square:transmitRemoveItemFromSquare(object)

willow tulip
#

transmitAddObjectToSquare is more symetrical though..

bronze yoke
#

transmitAddObjectToSquare adds it to the square for you

willow tulip
bronze yoke
#

code for adding objects in excavation literally just looks like this:```lua
local obj = IsoObject.getNew(square, sprite, nil, false)
square:transmitAddObjectToSquare(obj, -1)

willow tulip
#

Hes not adding an item, hes editing an existing one and just fake removing/readding it to make the game sync stuff it doesn't normally sync

#

Hmm nm transmitRemoveItemFromSquare does remove it from the world too

bronze yoke
#

you want to readd it or the object doesn't exist on the server and all kinds of issues are going to come up but especially 'the object will disappear when you reload the area'

willow tulip
#

didn't realize transmitRemoveItemFromSquare actually removes it.

#

I thought it was like the add/remove container transmits.. wait do they?

bronze yoke
#

they don't

willow tulip
#

yea just checked, lol.

#

bloody inconsistencies.

willow tulip
willow tulip
#

Like a custom sync packet is.. likely the 'best' way, but if this works... its the simplest way.

bronze yoke
#

since you're doing this on object creation the ideal solution would be to find some way to slip between creation and transmission

willow tulip
willow tulip
small topaz
willow tulip
#

Yea, so try what I posted without any other sync code.

#

btw im pretty sure removeFromWorld tries to delete the object itself.

#

so, don't call that.

#

(likely why the object acts like a ghost afterwards)

#
 object:setMaxHealth(newMaxHealth) -- extra hp                
 object:setHealth(newHealth) 
 object:setIsThumpable(true)
 square:transmitRemoveItemFromSquare(object)
 square:transmitAddObjectToSquare(object, -1)
#

(remove can happen after the settings are made, because changing those settings doesn't sync anything anyway)

#

and doing the remove/add syncs everything (hopefully)

mellow frigate
bronze yoke
#

is there a way to batch sync objects?

#

excavation does often create a decent amount of objects at once (~11 additions and 3 deletions can happen in one action) but i didn't think i had any choice but to sync them all separately

small topaz
#

So no matter what version and order of commands I try, fake-removal of the object always destroys the hit-detection for me. But manually syncing the maxHealth by sending commands to the client seems to work without destroying the hit-detection. So I just take that as a solution...

#

However, syncing the maxHealth worked indeed fine with the fake-removal trick but this just introduced the new problem with the hit-detection. Some weird side-effects which I wasn't able to anticipate nor to understand...

mellow frigate
tough oxide
#

you find a clean way to make the ui elements?

#

i was just complaining to myself about how quickly it gets out of hand

tough oxide
#

alright, misery loves company

#

ive been trying to abstract away certain parts of it and im like.. should i even be doing this in Lua?

small topaz
#

So in singleplayer, the event OnNewGame always fires when character dies and then the game starts with a new character fter selecting "continue with new character". This isn't the case in multiplayer anymore?

#

What is the event I can use in multiplayer then?

winter bolt
tough oxide
#

just a quick search of the events EmmyLua put together theres an OnCharacterDeath with the note Triggered when any character dies, including zombies, players and animals.

#

which seems like a lot to hook into, but quick escapes could make it okay?

#

and it passes in the character that died

bronze yoke
#

i wouldn't worry about it

#

it's not like hundreds of things die a tick

#

don't do unnecessary work of course but it'll be fine

tough oxide
#

albion the* pragmatic one

small topaz
# winter bolt fuck lmao i didnt know about this that explains some of the bug reports i keep g...

I haven't any bug reports yet but I guess they will come soon. (My updated mod is online for only a few days.)

It's probably about your character customisation mod? So for me in my mod, characters don't get their modded "body items" equipped after they die and choose "continue with new character". They are just vanilla then. But better test this yourself to be sure. Possible that there is another problem in my code (although I get the exact same problem in two of my mods.)

winter bolt
#

i need to test it yeah

#

testing b42 mp is such a fucking pain in the ass though it takes about 10+ minutes just to get past all the loading

small topaz
#

Yeah, and even worse that we have to test the spawn mechanics, constantly creating new characters...

tough oxide
#

is there a quick way to kill your character or do you need to write your own stuff for testing?

bronze yoke
#

getPlayer():die()

severe ore
#

maybe reduce health, programatically

tough oxide
#

is there a way in the lua to detect if -debug is active?

severe ore
#

if lua can reach java env i think so

willow tulip
tough oxide
#

really?

#

pretty close i think

#

alright, this might change some things for me - though you can join servers with the flag enabled i think so - worth keeping in mind maybe

severe ore
#

yes, i just saw some vanilla lua scripts with that function call

#

isDebugEnabled()

#

greping into lua scripts, either vanilla or from mods is a good way to search for things

tough oxide
#

yeah, thats a better way^ than me opening my decompiled source and ctrl+clicking and doing something else while it searches

severe ore
#

i also grep in the java decompiled code, but javadocs is better

tough oxide
#

i havent gotten proficient at reading those yet..

#

i still end up looking at all damned classes or methods half the time

severe ore
#

readind the java sources?

tough oxide
#

the community maintained javadocs

severe ore
#

the type hierarchy?

#

not exactly like that, but... you can see the parent and children classes

bronze yoke
#

i plan to merge both of these into one custom site with better presentation eventually but i'm pretty burnt out on tools projects for now

severe ore
#

only direct. So there is no fancy diagram with type hierarchy

tough oxide
shy mantle
#

Question: There are several states you can spawn a zombie into, but is that one crawling animation through a window on top of something like a table one of them?

small topaz
# winter bolt i need to test it yeah

I just tested it a bit more: The event seems to fire as expected but for some reason, it doesn't execute the custom spawn logic for me anymore. So characters do not get equipped their correct items on start... That's even more weird!

#

So maybe we need to wait even longer before we can send smth to server after we choose "continue with new character"??? my default way to go is waiting 2 ticks...

mellow frigate
#

was this a long time thing that food cooking in a stove does not update its cooking time when far out of sight ? (I guess uloaded)

tough oxide
#

so whats the goal?

#

respawn with the already created character and their inventory?

small topaz
tough oxide
#

like a starter kit?

severe ore
#

do you know where he dies the last time? do you keep that data?

#

died

small topaz
severe ore
#

ahh, so the problem is which event you should wait to trigger the requip code, right?

small topaz
#

Yes somehow. For me, the thing is that the event OnNewGame fires then but in this particular situation, it doesn't put the new stuff to the inventory

winter bolt
severe ore
#

maybe that is not a new game

tough oxide
#

seems like you could use a combo of OnCharacterDeath and OnCreatePlayer but im not sure if you get any information about the player logged in

small topaz
tough oxide
#

like if you stored info about the player that died and find a way to link it to the created player you might be able do what you are looking for

#

im for sure spit-balling and giving a naive answer

severe ore
#

i think the problem is not that.. so the event triggers but the callback code doesn't run?

tough oxide
#

have you done the basic "print" method to see if you see anything in the console?

willow tulip
#

How does one get the icon of an isoobject? (Like what shows up when you right click it, in the context menu?)

bronze yoke
#

isn't that usually just its world sprite

willow tulip
#

so isoObject:getSprite(): something?

small topaz
#

Situation is really bad. Even if I wait 30 ticks, it simply doesn't send anything to the server...

severe ore
#

ahh yes... send to server. It´s a MP game

#

isn't there some sync() method?

small topaz
#

I am afraid not for what I need to do...

severe ore
#

maybe you need to recurse into all the objects

#

sync player, sync InventoryItems

#

etc etc

small topaz
#

But here it is: I just waited 1000 ticks and then it worked! XD

severe ore
#

voilá! Patience solves it always 😄

small topaz
#

@winter bolt if you really can confirm that you have the same problem like me (i.e. server doesn't add/equip correct items after player death and choosing "continue with new character"), try waiting 1000 ticks before you send commands from client to server after the new character has spawned in. That seems to work for me. The event OnNewGame seems to be still the correct event for this. Only the waiting time gets longer.

willow tulip
severe ore
#

Behare the toilet seat.
Toilets should have a warning sign "Carefull with the toilet seat when consuming drinks"

tough oxide
#

not gonna lie - lua is annoying, but it reminds me of my roots with duck/loosely typed languages and the interesting features that kinda let you implement more oop-based patterns

#

though im curious what the implications of instances are for memory

#

do they "compile" the lua on launch?

frank elbow
#

What do you mean by compile, exactly? The Lua is loaded and executed by (modified) Kahlua

tough oxide
#

i should probably just look at kahlua

#

already a solid read

frank elbow
#

Should probably check out the game's version in particular; Kahlua itself is unmaintained

tough oxide
#

this was already something i ran up against while "type-hinting" Numbers are mapped to Double.

#

it wasnt an actual code issue, but im very nutty about making sure my IDE knows my intentions

#

especially in these languages

#

im not as good at holding long-term states in my head anymore so i need my cheat codes

bright fog
tough oxide
#

yeah, it looks like its just interpreted and translated to java