#mod_development

1 messages · Page 67 of 1

jagged ingot
#

It's on my xmas wish list.

winter thunder
#

Yeah, you can use anything, was just an example. Can technically use anything

sour island
#

I know, I probably nitpick too much lol

ancient grail
#

Huh? Whats this for and how

sour island
#

In mod info*

#

There's version min and version max, so your mod only activates if true

astral dune
#

can you do a non-inclusive max? like [41.78,42)?

ancient grail
#

Any screeenshot propf of concept

jagged ingot
#

I'm more into the version control for say the mod itself.

#

(Not tied to the PZ version)

sour island
#

Idk if they allow for sub versions

#

Id have to check how it gets parsed

astral dune
#

I just wouldn't want to have to put out tiny updates every time there is a new subversion to bump up the max, but also don't want people to think it will work on 42 since I'm sure that'll break everything, lol

sour island
#

Yeah, I only use min for that reason

#

I guess it's more responsible to version lock it - but honestly most mods will work forever

jagged ingot
#

I'd like to see what the community could come up with to provide ideas on improved version control for mods and the workshop.

sour island
#

The workshop is a mess

jagged ingot
#

It'd probably intersect topics around issues with mod content management in general.

sour island
#

The workshop tags were fixed which helped a lot for browsing

#

But the mod packs and server configs are choking up content lol

astral dune
#

my biggest concerns is things like ItemTweaker, which doesn't really need to exist and makes loading super slow due to print spam. And stuff like that profession framework that has a dozen offshoots and nobody knows which one is the right one. We need some way to handle both of those situations

sour island
#

That'd require someone to spend time curating the workshop

jagged ingot
#

My only current suggestion would be to allow for dependencies of mods or mods in server.ini to have mod_id:version;.. and the folder tree to have content/{version}/...

sour island
#

Not something that impacts anyone enough to do so imo

faint jewel
drifting stump
#

or simply use mod data

winter thunder
# ancient grail Any screeenshot propf of concept

Not atm, was just an idea- not something I have implemented yet.

In theory, you could use it for a lot tho. An idea I had is for crafting items with a lot of interchangeability, or for setting multiple effects simultaneously with varying degrees.

So, if you set the tags like
‘Tags = r.10, g.15, b.100’

You could have those values be the rgb color code associated with an output crafted item/ effect.

So, the function you put into the oncraft/oneat would take the array of tags, break them each down into the variable and number, and then your function would look for those to apply the effects.

winter thunder
# drifting stump or simply use mod data

For sure, but that requires you to set the mod data- this would be entirely contained in the item script files. It’s not anything crazy- but just an interesting concept

drifting stump
#

you can set moddata from the script 🤔

ancient grail
ancient grail
winter thunder
#

Fair lol, but- what is the definition for that? I haven’t messed with mod data set by default, only modifying it on the fly

drifting stump
ancient grail
#

Just make something = to something its auto moddata. I think everything on a script is moddata. Not sure tho.

But what brandon is saying goes beyond moddata

ancient grail
tardy wren
#

I need a value from GameTime. What is the earliest Event I can call it from without it being nil?

#

This is something that should run before the game begins

bronze yoke
#

you don't need to do anything complicated like this

#

instead of putting these in tags, just go

effect = -10,```any invalid parameter is added as moddata to that item
astral dune
#

neat

bronze yoke
#

i remember someone having trouble with that not supporting a specific data type, i think it was booleans?

#

but other than that that's the easy way of doing that

drifting stump
bronze yoke
#

yeah, they specifically wanted the moddata key to exist and be false, i don't remember exactly why

balmy pike
#

anyone have a link or just some insight into what skill's names i can use in a script? for example:

    SkillRequired:Woodwork=1,
#

im trying to make a recipe need a minimum in aiming / cooking / etc

bronze yoke
#

they should use the names here

tardy wren
#

How can I access the enum MoodleType?

#

I need to go from the internal moodle name to the moodle

manic spoke
#

Hi, maybe this will be easy, but how can I specify if item could be added as a fuel (fire) and how to set its value?

bronze yoke
tardy wren
#

I have the MoodleName stored in a variable

bronze yoke
#

have you tried MoodleType[name]?

tardy wren
#

No, not yet....

#

Although I think my issue lies elsewhere actually

#

Because even if it doesn't grab the moodle correctly, it should print something...

winter thunder
#

Welp

#

That file 😂

manic spoke
#

oh, thanks

tardy wren
#

Well, I have indeed found my issue

#

somehow it's not loading the sandbox settings in correctly... I'll deal with that later

faint jewel
#

should those change to say FROZEN? at some point?

bronze yoke
#

yeah

tardy wren
#

Good news, the mod itself works

#

But it isn't reading or writing the sandbox options correctly

bronze yoke
#

when are you reading them?

#

sandbox options aren't set on launch

tardy wren
#

OnInitGlobalModData

#

I was told they are set there

bronze yoke
#

they should be good then

tardy wren
#

and they aren't null

#

because then it would load the failsafe defaults

#

The error is in my function that converts the string into a proper config...

#

I...

#

I even made comments explaining this for myself

#

and only now do I see that I used the wrong index

#

N wait taht wasn't it, I'm not a full idiot

faint jewel
#

so the icecream froze but stuiipid bacon wont

#

and it unfroze.

#

TF MAN

tardy wren
#

Hmmm

#

It appears I need to convert a number from a string to a number

bronze yoke
#

tonumber(string)

tardy wren
#

yes, my IDE suggested it

#

it finally works!

#

Now people can experience existential dread in zomboid when their characters are hungry

shrewd ice
#

anyone know a mod that removes the chances to break when picking stuff up

winter thunder
faint jewel
#

trying to get the tsarlib freezer to work.

#

and now that i have removed MY code. it's doing NOTHING.

#

it apparently needs to have it's own seat?

sour island
#

I thought of something regarding skillbooks - I'd only do it if I did not have to edit every single action - but it would be neat if having a skillbook in your secondary hand gave you a bonus to skills - but in exchange when you're performing a timed action you have to pause to read a bit from the book.

#

Kind of like double checking yourself

astral dune
#

makes me think of a spellbook. Like you have to study it for an hour every morning to prepare

sour island
#

had the same idea initially, but rather than having to read it as a separate action there's a benefit to it

faint jewel
#

lol i fucked that ALL the way up

bronze yoke
sour island
#

i.e.: you have to wait a bit longer to do XYZ you'd not normally be able to do

bronze yoke
#

make books much faster to read but only a temporary xp boost... that might work

sour island
#

I'd prefer if it were a flat addition

#

but yeah, chances are not possible

astral dune
#

there is a mod that makes books consumed, but they give you xp straight up. Kinda liked that as an alternative, also saves you from constantly trying to filter out books you've already picked up

sour island
#

that's konijima's right?

bronze yoke
#

there's a few like that

astral dune
#

I don't recall

bronze yoke
#

there's cdda reading, evelyn made one, i think konijima did write one too

sour island
#

I kind of hate that books vanish when read lol

#

hence why I wrote named lit

bronze yoke
#

yeah that always bugged me

astral dune
#

I'd be ok with all of them vanishing or none of them, lol

#

instead of skillbooks sticking around and everything else disappearing

sour island
#

that's fair too

bronze yoke
#

the next version of my mod makes them stay, but you can't reread them

sour island
#

skillbooks or regular?

bronze yoke
#

regular, this is the default behaviour of skillbooks anyway

sour island
#

I didn't know you had a reading related mod

astral dune
#

I like named Lit, chuck, because it gives me a reason to collect books. We've talked about this before.

sour island
#

named lit already has sandbox options to control rereadability 👉 👈

astral dune
#

gotta get the whole set

bronze yoke
#

it's actually my most popular mod - i've got a crazy big update coming (the changelog is literally a page long right now) so the current version isn't the absolute best

sour island
#

which?

sour island
# astral dune gotta get the whole set

I have a proclivity for random generation so the mod started as a 'I wonder if this would work', I think it's awesome people actually try to find whole sets lol

astral dune
#

on the flip side I'll be real bummed if a book is missing because it didn't get scraped from whatever db you used, lol

sour island
#

I spent like 2 hours parsing GoodReads

#

top 100 per century, decade, then year

#

idk how they know what the top 100 books for the 4th century were

bronze yoke
#

i think i wrote some stuff to make sure my mod was compatible with named lit, didn't realise it had that feature though

sour island
#

I added it after Udderly requested it lol

#

they didn't like the fact you could reread it up to 3 times

#

upto 3 times - each time expiring after 6 months

#

Which is your mod?

bronze yoke
#

this version is probably compatible - i don't use named lit but i imagine i would've got complaints

#

the currently released version doesn't have any of the features that made me consider compatibility an issue

sour island
#

Ah nice

#

I think the other literacy mod had some issues for a bit - never got complaints for this one

bronze yoke
#

the only compatibility issues i've had with it are with other mods overwriting things, as far as i know this one should play perfectly friendly with other mods

sour island
#

namedlit just adds onto the timed actions

#

it also strips off the vanilla stats for boredom/stress/etc

bronze yoke
#

in my unreleased version read books are kept with a (Read) indicator, so i had to make sure it wouldn't overwrite your book names

#

i'll need to get around to adding some compatibility for your rereading system, probably just make it ignore my re-read blocking system when a sandbox option is enabled

sour island
#
local ISReadABook_perform = ISReadABook.perform
function ISReadABook:perform()
    local bookNameLitInfo = self.item:getModData()["namedLit"]
    if bookNameLitInfo and self.stats then

        ---@type IsoPlayer|IsoGameCharacter
        local player = self.character
        local bodyDamage = player:getBodyDamage()
        local stats = player:getStats()
        local title = bookNameLitInfo["title"]
        local UnhappyChange, StressChange, BoredomChange = namedLit.readerMemory.statsImpact(self.item,title,player)
        local totalTimesRead, timesStampsWhenRead = namedLit.readerMemory.getTotalTimesRead(self.item,title,player)
        local canRead = SandboxVars.NamedLiterature.CanReadPassedMax or (timesStampsWhenRead < namedLit.readerMemory.getMaxTimesReadable())

        if canRead then
            if getDebug() then print("NamedLit: StressChange:"..StressChange.." UnhappyChange: "..UnhappyChange.." BoredomChange:"..BoredomChange) end
            stats:setStress(math.max(0,stats:getStress()+StressChange)/100)
            bodyDamage:setUnhappynessLevel(math.max(0,bodyDamage:getUnhappynessLevel()+UnhappyChange))
            bodyDamage:setBoredomLevel(math.max(0,bodyDamage:getBoredomLevel()+BoredomChange))
        end

        namedLit.readerMemory.addReadTime(self.item,title,self.character)
    end

    ISReadABook_perform(self)
end
#

I also mimic the vanilla stuff for read update that locks the stats in place during reading

#

should be pretty compatible I imagine

bronze yoke
#

yeah i'm pretty sure all i'll need to do is let people turn off the system that stops you from rereading books at all and then yours will kick in instead

sour island
#

lmk if there's anything I can change 👍

bronze yoke
#

will do 👍

sour island
#

also I've added comics and untitled literature in the last update a few weeks ago

#

so stuff like newspapers can also be reread individually

#

where as named literature gets a shared history on title

#

I kind of wish there was a recently updated tab for workshop - although that'd be abused very quickly lol

bronze yoke
#

you can sort by last updated from an actual items list page

#

this page, i mean

sour island
#

oh 😮

#

I never noticed that - I assumed that was just for subscribed items

#

reorder the hotbar looks nice

#

I hope it works with swapit

sand harbor
#

how have you all learned to mod the game? just reverse-engineering other mods and building up your knowledge?

astral dune
#

read the lua docs, then tinkered with other mods, ya

bronze yoke
#

pretty much yeah

#

i started looking at other mods, now i usually just look at vanilla code

drifting stump
#

@willow estuary we hear you and we appreciate it

sour island
#

?

drifting stump
#
Blair is working on a variety of things – and is currently super proud of ‘LootLog’ which he wants advertised so modders are aware of it. This is a dev and modder tool that, once activated, logs every item that spawns around the player rather than wait for the player (or modder/dev) to discover it. Info logged includes a list of items; the room definition in question; the container type in question; and the X, Y and Z coordinates of the container in question.

This is intended as a tool for us and the modding community to evaluate the amounts of loot that spawn, and where it spawns. The blog writer is aware that it isn’t super sexy blog content – but Blair underlines that it is a ‘niche pleaser’ so if you are in that niche: consider yourself pleased.
#

from todays blog

sour island
#

Oh it came out - I tried checking earlier

drifting stump
#

no but blair wanted to be noticed

sour island
#

No, he wanted to please us drunk

faint jewel
#

anyone feel like terrorizing tsar lib for me?

sour island
#

also, cleaner debug tools are very welcomed

fast galleon
faint jewel
#

I need to make a freezertruckbed

#

and everything i try goes to hell.

sour island
#

new ‘filler’ book items with names dreamt up by dreamy Pat_Bren
😮

faint jewel
#

I wand tsar freezer stuff to work on a truck bed. anyone up for the challenge?

#

the danged thing can just be "on" always.

viral karma
# sour island also, cleaner debug tools are very welcomed

I've been redoing the F11 debug window, adding in better windowing, breakpoints, watching for changes, viewing globals, auto-reloading of marked files, and some other goodies.
Been spread a bit thin at work, but will most likely have time to button up the Inspect Item stuff along with this debug stuff over the holidays.
I also started toying around with a "plugin" to Mod Manager that checks for mods that overwrite files, and add a hook for future function analysis (eg. if a mod overwrites a class or function that's already defined).

sour island
#

😮 hot dang

#

idk if you ran into this issue but error print out is split erroneously - the header/footers get cut off

#

doesn't matter in the normal f11 as you can just hit next and keep printing them in a giant log

viral karma
#

yeah, the error output needs some loving. I wanted to have a collapsible list of errors, to make it easier to see what actually happened. If possible, maybe save a snapshot of the stack at that error for debugging (might have this a toggle option, disabled by default).
Also want to improve the lua console, and add the console into the debug window - it'd be super nice to be able to run lua commands against the current stack (kind of like Python's debugger)

sour island
#

you can grab some coroutine stuff but honestly that's a bit above me

#

All I did for errorMagnifier was grab the errors, prevent duplicates, and cleaned up the header/footer

#

and gave it a nice UI with easy to use buttons lol

dull moss
#

ok so I have this line
local bloodlustMeter = player:getModData().DynamicTraitsWorld.Bloodlust.BloodlustMeter;
in 2 functions that are run one after another, and nothing happens between that.
How come
print("Bloodlust Meter: "..bloodlustMeter);
prints 2 different things? NotLikeDis

#

In 1st function it prints one number

#

in 2nd it prints different dumber

#

did I fuck it up here, where I initialize my modData?

local function createModData(playerIndex, player)
    player:getModData().DynamicTraitsWorld = player:getModData().DynamicTraitsWorld or {};
    local modData = player:getModData().DynamicTraitsWorld

    modData.VehiclePartRepairs = modData.VehiclePartRepairs or 0;
    
    modData.Bloodlust = modData.Bloodlust or {};
    modData.Bloodlust.BloodlustMeter = modData.Bloodlust.BloodlustMeter or 0;
    modData.Bloodlust.BloodlustProgress = modData.Bloodlust.BloodlustProgress or 0;
end

Events.OnCreatePlayer.Add(createModData)
sour island
#

Where are the prints?

dull moss
#
local function bloodlustMoodleUpdate(player)
    if player == getPlayer() then
        local moodle = MF.getMoodle("BloodlustMoodle");
        moodle:setThresholds(0.1, 0.2, 0.35, 0.49, 0.5, 0.65, 0.8, 0.9)
        local bloodlustMeter = player:getModData().DynamicTraitsWorld.Bloodlust.BloodlustMeter;
        print("Bloodlust Meter in MoodleUpdate func: "..bloodlustMeter);
        local var = bloodlustMeter / 36;
        print("Var: "..var);
        moodleValue = var;
        moodle:setValue(moodleValue);
    end
end

local function BloodlustKill(zombie)
    local player = getPlayer();
    if SBvars.Bloodlust == true and not player:HasTrait("bloodlust") then
        local bloodlustMeter = player:getModData().DynamicTraitsWorld.Bloodlust.BloodlustMeter;
        local distance = player:DistTo(zombie);
        if distance <= 10 then
            bloodlustMeter = bloodlustMeter + math.min(1 / distance, 1) * SBvars.BloodlustMeterFillMultiplier;
            if bloodlustMeter >= 36 then
                bloodlustMeter = 36;
            end
            print("Bloodlust Meter in BloodlustKill func: "..bloodlustMeter);
            bloodlustMoodleUpdate(player);
        end
    end
end
sour island
#

you're changing it before printing

bronze yoke
#

because you're doing a bunch of maths to the value in BloodlustKill

dull moss
#

no

#

look again, it's print, then moodle update function

bronze yoke
#

it only changes the entry in the table if you access it through the table, otherwise you're making a copy of the value and changing that

#

your maths changes the value that BloodlustKill prints, and then bloodlustMoodleUpdate grabs the original value from the moddata again

dull moss
#

so if I wnat to update value in moddata I can't do local bloodlustMeter = player:getModData().DynamicTraitsWorld.Bloodlust.BloodlustMeter;

#

I need to do getModData fully?

#

doesn't lua works by reference?

bronze yoke
#

only tables and functions work by reference

dull moss
#

oh

bronze yoke
#
local modData = player:getModData().DynamicTraitsWorld.Bloodlust
modData.BloodlustMeter = 5
```changes the original in the player's mod data, but
```lua
local modData = player:getModData().DynamicTraitsWorld.Bloodlust.BloodlustMeter
modData = 5
```does not
dull moss
#

hm

#

I'll definitely fuck this up again

#

in some time

#

so this would be correct approach, right?

local function BloodlustKill(zombie)
    local player = getPlayer();
    if SBvars.Bloodlust == true and not player:HasTrait("bloodlust") then
        local bloodlust = player:getModData().DynamicTraitsWorld.Bloodlust;
        local distance = player:DistTo(zombie);
        if distance <= 10 then
            bloodlust.BloodlustMeter = bloodlust.BloodlustMeter + math.min(1 / distance, 1) * SBvars.BloodlustMeterFillMultiplier;
            if bloodlust.BloodlustMeter >= 36 then
                bloodlust.BloodlustMeter = 36;
            end
            print("Bloodlust Meter in BloodlustKill func: "..bloodlust.BloodlustMeter);
            bloodlustMoodleUpdate(player);
        end
    end
end
bronze yoke
#

looks good to me

dull moss
#

cheers

#

yep, works as intended

#

ty

ruby urchin
#

what's the difference between prerender, render, and update on UI (ISPanel)? low ticks maybe?

sour island
#

if I had to guess prerender is before the actual render - and update is called after certain types of events?

#

I'm not sure what the benefit between prerender and render would be - but I've used prerender to render background elements as to not interfere with other UI stuff

ruby urchin
#

sweeet, thx, so I'm right way

viral karma
jagged ingot
#

Good evening.

#

Going to pull an all-nighter tonight for some of my projects. =3

faint jewel
#

YASSSS

astral dune
#

how many ticks are in a second in game? Its different on the server vs client too right?

jagged ingot
#

ups?

#

Either 50 or 60.

#

I think 60 is the target.

astral dune
#

thats on the client for sure, I think its a lot less on the server

jagged ingot
#

Been years since I looked & I can only remember Minecraft stuff.

#

The server doesn't need 60 since it only bounces client-authoritative zombies.

marsh gale
#

        final float sqrt = Math.sqrt(2048.0f);
        GL11.glScalef(-sqrt, sqrt, sqrt);
        GL11.glMatrixMode(5888);
        GL11.glPushMatrix();
        GL11.glLoadIdentity();
        GL11.glTranslatef(n4, n5, n6);
        GL11.glRotatef(30.0f, 1.0f, 0.0f, 0.0f);
        GL11.glRotated(Math.toDegrees((double)this.m_useAngle) + 45.0, 0.0, 1.0, 0.0);
        GL11.glDepthRange(0.0, 1.0);
        GL11.glDepthMask(this.bDepthMask);
    }

So I just found this chunk in OpenGL "Charactermodelcamera.class"
Does anyone happen to know if this is a controller for the camera's rotation angle?

jagged ingot
#

For what? 3D models?

marsh gale
#

For the game camera

jagged ingot
#

The game camera statically points to the offset of the player in Iso coordinates..

#

I don't think it rotates in 3D space.

astral dune
#

collision is handled partially server side, which is why I'm trying to figure out whats going on. Essentially I have the linear velocity of a vehicle and I think I need to divide it by ticks per second to get how far it moved since the last tick

marsh gale
#

This is the closest I've found but IDK just how related this is since there's like 50 different .class files of similar contents
(isocamera.class)

jagged ingot
#

Not sure what you're trying to locate and modify.

#

Rotate the camera for what? The world?

marsh gale
#

I'm trying to add a rotation to the camera

jagged ingot
#

I know that the SpriteRenderer does a batched render of OpenGL commands.

#

Maybe look into that and how that is set up with the camera?

#

I've yet to try to rotate the camera.

marsh gale
#

I'm working on adding a rotation/ Yaw adjustment before I continue making 3d models of all the objects and tiles

jagged ingot
#

You wish to modify the game to render the game in 3D?

marsh gale
#

The game is technically already in 3d, There's just a good chunk of things that are in 2D that would need to be remade so they can be viewed differently

jagged ingot
#

A lot of work to do for certain.. I had this view as well.

#

Yeah this game would benefit from being completely brought over to 3D.

marsh gale
#

I'm hoping to get something similar to Don't Starve

#

Not everything needs to be made 3D. Trees and foliage can just be cutouts to face the player

jagged ingot
#

Fun. I'm working on a Java-mod that provides immersion modding utilities for themes like Don't Starve right now.

#

Like a GLSL uniform modifier API.

#

It's already in working order. =3

marsh gale
#

That would be super useful. I'm used to modding Unity so I'm in new territory RN

bronze yoke
#

wasn't somebody already doing this? wonder how that's going

jagged ingot
#

The 2nd picture is a GLSL live test of modifying the shader for the panic moodle.

#

The screen pulses and aberrates when max panic.

marsh gale
#

That's pretty neat actually

#

would I be able to DM you by chance?

jagged ingot
#

I wrote a sub-sound engine that sends live sound data as API that I connect to the GLSL API.

jagged ingot
faint jewel
#

le sigh

ruby urchin
faint jewel
#

THAT PUPPY SCARES ME

#

esta CHUPACABRA!

jagged ingot
#

Item with spritesheet that updates frames?

#

Pseudo vehicle with a dog model?

ruby urchin
#

just a IsoPlayer with clothing lol

jagged ingot
#

This was also a project I sort of tried back in the mid 2010's. 🙂

#

(MisterInsayne's model that I rigged in Blender)

#

But seriously, good freaking job @ruby urchin . Can't wait to see what you'd do in B42.

opal rivet
jagged ingot
#

If you can get a fake player AI for dogs in B41, it'll catch on like fire.

astral dune
#

This isn't as impressive, but I've managed to fix my highspeed collision detection

jagged ingot
#

Nice.

astral dune
#

I think thats the last case I have to handle, so over christmas holidays I should hopefully have time to button up my vehicle damage events mod. I want to add features like being able to tell which zombie is attacking your vehicle at any given moment, but I can add that stuff later

faint jewel
faint jewel
#

anyone? the freezer version worked great. the fridge one not so much.

cosmic condor
winter thunder
ancient grail
fast galleon
#

Now throw this on top of superb survivors and you have something.

thick karma
#

Does anyone know how the game draws those green prompts near car doors that tell you which door you're about to enter?

#

Also, random different question... Is it possible to recompile Java classes and throw them in your mods folder beside media in the zombie folder where they belong and thus publish Zomboid mods via Steam that include Java code modding? If this is possible, would you be able to independently recompile the Java file somehow, or would it be necessary to recompile the full library of functions because of how Java works?

manic relic
#

anyone got a idea what kind of gloves I can add

#

basically I wanted to add some new gloves to the game

#

and kinda ran out of ideas

thick karma
#

Wolverine gauntlets

manic relic
#

and so far I got:
Working gloves
Black Latex gloves used by the police in my country
and sniper gloves

manic relic
thick karma
#

Haha what that's not a hip style?

#

Fingerless gloves?

#

Are those a thing yet?

manic relic
#

yes

thick karma
#

How about a pair of gloves that just looks like you wear brass knuckles all day

manic relic
#

idk seem like a better weapon idea

thick karma
#

No punching yet afaik

#

But it would put some pressure on somebody to add it lol

#

To make the knuckles more valuable

#

And would be an essential component of brass knuckles once punching IS added

manic relic
#

I think thats a bit over what I can

sour island
#

Mittens?

fast galleon
#

hoofs

manic relic
#

like the wooly gloves

fast galleon
#

Muppets

manic relic
#

xD

sour island
#

I've never seen any tbh

#

Would be funny if they lowered dexterity tho

dull moss
#

anyone ever found a way to bypass player max weight limit of 50?

#

or is that hardcoded

royal stirrup
#

the fallout terminal, WIP

dull moss
#

Yo, I can't just put stuf like

local modData = getPlayer():getModData().DynamicTraitsWorld;

at the start of my lua file cuz it'll throw error on load since there's no player yet, right?

#

From testing confirmed I assumed correct

fast galleon
faint jewel
dull moss
#

why the hell would this throw error

-- this line is in function, player is getPlayer()
applyXPBoost(player, Perks.Electricity, 1);
--
local function applyXPBoost(player, perk, boostLevel)
    local newBoost = player:getXp():getPerkBoost(perk) + boostLevel;
    if newBoost > 3 then
        player:getXp():setPerkBoost(perk, 3);
    else
        player:getXp():setPerkBoost(perk, newBoost);
    end
end

it's literally same code I used in my other mod and there it works

function: traitsGainsBySkill -- file: DTWBySkills.lua line # 149 | MOD: Dynamic Traits World
Callframe at: se.krka.kahlua.integration.expose.MultiLuaJavaInvoker@51ae9641
function: onOptionMouseDown -- file: ISPlayerStatsUI.lua line # 635 | Vanilla
function: onMouseUp -- file: ISButton.lua line # 56 | Vanilla
#

oh wait im r-word

#

i put it under function where its called

#

it needs to be above

sour island
dull moss
sour island
#

Is there something you're trying to do?

#

you can always change the display to your own number

#

I dont think weight has any bearing except for how quickly you burn calories

faint jewel
#

could make an extra variable called "ExtraWeight" that is maxweight + your additional.

finite radish
dull moss
#

Why does this reset the data when I call it OnCreatePlayer

    player:getModData().KillCount = player:getModData().KillCount or {};
    player:getModData().KillCount.WeaponCategory = player:getModData().WeaponCategory or {};
    player:getModData().KillCount.WeaponCategory["Axe"] = player:getModData().KillCount.WeaponCategory["Axe"] or {count = 0, WeaponType = {}};
#

shouldn't it load Axe since its already there

faint jewel
sour island
#

Perhaps the issue is that it's not being added to correctly - I don't see an issue with this part

faint jewel
#
function CommonTemplates.createActivePart(part)
    if not part:getLight() then
        part:createSpotLight(1000, 1000, 0.001, 0, 100, 0)
    end
end``` oh sumbitch. it;s just a LIGHT?
finite radish
#

may want to read functions before you use them KEKW

faint jewel
#

i couldn't find that dumb function lol i thought it was the item name that was the issue.

dull moss
#

check screenshots

#

there's tab that gets updated

#
if weapon then
            local weaponCategory = KillCountWeaponType.GetWeaponCategoryFromWeapon(weapon)
            local weaponType = KillCountWeaponType.GetWeaponTypeFromWeapon(weapon)
            if weaponType and weaponCategory then
                if not wielderModData.KillCount.WeaponCategory then 
                    wielderModData.KillCount.WeaponCategory = {} 
                end
                if not wielderModData.KillCount.WeaponCategory[weaponCategory] then 
                    wielderModData.KillCount.WeaponCategory[weaponCategory] = {count=0,WeaponType={}} 
                end
                wielderModData.KillCount.WeaponCategory[weaponCategory].count = wielderModData.KillCount.WeaponCategory[weaponCategory].count + 1;
                if not wielderModData.KillCount.WeaponCategory[weaponCategory].WeaponType[weaponType] then 
                    wielderModData.KillCount.WeaponCategory[weaponCategory].WeaponType[weaponType] = 0 
                 end
                wielderModData.KillCount.WeaponCategory[weaponCategory].WeaponType[weaponType] = wielderModData.KillCount.WeaponCategory[weaponCategory].WeaponType[weaponType] + 1;
            end
            if KillCountWeaponType.Verbose and weaponType and weaponCategory then print ("KillCountWeaponType.addToKillCount "..tostring(weaponType or "nil").." "..tostring(wielderModData.KillCount.WeaponCategory[weaponCategory].WeaponType[weaponType] or "nil")..", "..tostring(weaponCategory or "nil").." "..tostring(wielderModData.KillCount.WeaponCategory[weaponCategory].count or "nil")) end
        end
#

god this is disgusting to read

#

aka long lines, not the code itself

#

there' edited it a bit

faint jewel
#

better question.... WHY DID THE FREEZER ONE WORK?

#

is has the same shit lol.

#

omfg.

dull moss
#

ah im dented

#
    player:getModData().KillCount.WeaponCategory = player:getModData().WeaponCategory or {};```
faint jewel
#

okay so now all i gotta do is get my dumb garbage truck to sync and we are in bitness!

dull moss
#

missed .KillCount in 2nd line

finite radish
faint jewel
#

i am, but ctrl shift f is for notepad++ 😛 i'm not gonna have vs code search my entire mods folders.

finite radish
#

notepad++ is an axe to VSCode's chainsaw

faint jewel
#

now you're speaking voodoo again.

#

lol

finite radish
#

ez pz

#

you can also save the workspace config so that you don't have to redo that every time, along with a bunch of other workspace-specific settings n stuff

sour island
dull moss
#

lul

#

wasnt local fault

#

gonna remake it back to locals xd

sour island
#

Btw, if that kill counter is using drawText you could instead add a UI element (label even) and have the verbose stuff show on tooltip when you hover over it

stuck river
#

does anyone know the name of the mod that allows you to open the sandbox menu during the game?

sour island
#

Change Sandbox Options

dull moss
#

Already got stuff to work

#

And you know how it is, if it works - don't touch it

#

On one hand i want to move to Inteliji over weekend, on other hand i wanna finish my mod PepeThink

#

But then again there should be big mod update for Imperator Rome this weekend so idk when I'll ever do any of those things KekW

#

Is there an event for first time player is created? I need to update some moddata values if player starts with a trait, for example.

#

Crude way to do it would be creating bool in moddata and change it to true after it fires once on OnCreatePlayer

#

But I hoped there's more elegant solution

sour island
#

First time a player is created can be when your modData is initialized

#

Unless there's a scenario you have in mind? Like activating the mod I'm an ongoing save

faint jewel
#

stupid client commands.
sendClientCommand("GarbageTruck", "EmptyTrunk", {GTvehicle = vehicle});
should fire this right?

local Commands = {};
Commands.GarbageTruck = {};

Commands.GarbageTruck.EmptyTrunk = function(player, args)    
    print("it fired")
    print(module)
    local vehicle = args.GTvehicle
    local TrashBox = vehicle:getPartById("TruckBed"):getItemContainer()
    TrashBox:clear()
end


local onClientCommand = function(module, command, player, args)
    if Commands[module] and Commands[module][command] then
    Commands[module][command](player, args);
    end
   end

Events.OnClientCommand.Add(onClientCommand);
dull moss
#

So it fires every time player loads in

#

Afaik

bronze yoke
dull moss
#

Wdym

bronze yoke
#
if not player:getModData().KillCount then
    -- trait stuff
end
-- make sure to do this before this part:
player:getModData().KillCount = player:getModData().KillCount or {}
dull moss
#

Hm

#

I see

#

That wouldn't be pretty since i have separate Lua where I initialize all my moddata

#

Sadly

sour island
#

You can grab the first time it's initlized in onCreate

#

You aren't "initilizing" it everytime

dull moss
#

I'll check that when back home, ty

sour island
#

That's what the 'or' is for

dull moss
#

Well ye

#

If it exists already

#

It doesn't touch it

#

If it doesn't it creates it

sour island
#

Yes, so you can just add another if at first to flag that it's the first time

dull moss
#

Ye

sour island
#

Or change the current if

dull moss
#

Smort smort

sour island
#

Out of curiosity, why do you need to know the first time?

dull moss
#

I got a trait that you can earn/loose based on value on moddata that you increase by killing Z near you. And it decays over time. You earn it by reaching X on that value and you loose it by reaching X/2. So if someone would start with it, their X would be 0.

bronze yoke
#

so just

if player:HasTrait('Trait') and not player:getModData().x then
    player:getModData().x = 0
end
```?
dull moss
#

Smort

#

Except for 0 it's X as if value is at point where you'd get the trait

faint jewel
#

sumbitch. it's not freezing again. ARGH

dull moss
faint jewel
#

WHY

dull moss
#

You could also try looking inside code of CoolBag mod

#

Maybe that'll help

faint jewel
#

i have... it was freezingyesterday

#

now it just decides NAH we good.

dull moss
#

One-time use freezer Kpog

faint jewel
#

it's caught the dumb.

lusty marsh
#

Can I control the load order of files in my mod? I have HairAvatar.lua that depends on VisualAvatar.lua however the hair loads first. is there any problem using lua's require()? currently I'm just prefixing them with a/b but I was hoping for something better

bronze yoke
#

you can just use require

sour island
#

Careful about renaming files if you've already uploaded them -- Steam doesn't remove files

lusty marsh
lusty marsh
agile vigil
#

Yeah pretty much. You'll need to place empty dummy files in place of the old stuff.

lusty marsh
#

yeah that's what I was thinking, thanks!

agile vigil
#

Alternatively, you can release a whole new mod with a new ID, if you want to do a lot of file changing.

lusty marsh
#

nah it's not that extensive I've basically just broke down a few larger files into smaller ones

bronze yoke
#

it's pretty frustrating, one of my mods has entire structures of dummy files LOL

thick karma
bronze yoke
#

i've come up with a couple ways to maybe get rid of them but i need to test them

#

that's one of them

sour island
#

I put a --TODO: Remove in a month -date

#

and when ever I notice the files again I'll do a sweep

agile vigil
bronze yoke
#

it does

agile vigil
#

A month seems a bit short to me. My setup on the desktop PC still has stuff from like June.

bronze yoke
#

can you actually delete a file with the filewriter though?

#

i'm pretty sure all you can do is replace it with an empty file, which doesn't really help LOL

agile vigil
#

Perhaps not, but removing all contents in the file is just as well - it removes it from the mod itself.

#

It helps the moddev and keeps it clean for new installations 🙂

#

Now you just have one .lua file with a list of files to clean if they exist 😄

bronze yoke
#

servers would get missing file errors though

agile vigil
#

Surely the server would run the same cleaner script, no?

bronze yoke
#

but the idea here is to remove the files from the workshop upload and automatically empty old files if they exist, right?

agile vigil
#

Correct.

bronze yoke
#

so:
if a player has an older version, their files don't exist on the server, and they won't be allowed to join
if the server has an older version, the client doesn't have files that exist on the server, and they won't be allowed to join

agile vigil
#

So you include a single lua script in the workshop upload, which is prefixed such that it runs before all your other scripts - and then deletes the things that has to be empty.

Ah, yeah, fair. I suppose in my head you always have the lua script checking disabled, because on my server that was the case, but that's... Not universally true.

bronze yoke
#

i have a solution that i think would work a lot better, but i need to test it

agile vigil
#

Fingers crossed it works!

bronze yoke
#

the basic concept is to move everything to a new mod folder that uses the same mod id, and include a blank mod.info in the old folder

#

since the old folder doesn't have a mod id it shouldn't get loaded ever and shouldn't cause any consistency errors

agile vigil
#

So essentially you'd end up with a version number on your directory, and ship some dummy-empty ones? Not a bad solution.

faint jewel
#

@finite radish can i bug ya?

thick karma
grim pike
#

me and my friend are having difficulty loading maps onto our gportal is there anybody with experience in this

bronze yoke
#

does anyone know of a way to keep a persistent variable that needs to be checked before global mod data loads? i thought about reading and writing a file but i only need a single bool... does anyone know a better way?

vast nacelle
bronze yoke
#

actually this needs to run even before that, and it needs to be per-client

sour island
#

Thinking of handling withdrawing and depositing using a single slider

#

Not sure if I'm over thinking it

#

Total slider would be banked cash + wallet cash

#

default being inbetween (banked cash)

#

displays 0 / no changes

#

🤔

bronze yoke
#

think i'll just have to write a file - seems a little overcomplex but oh well

finite radish
#

is I/O even exposed via Lua? I was under the assumption it wasn't, but I haven't checked

bronze yoke
#

there's specific file writers and readers we can use

#

one for a mod's directory, one for the Zomboid/Lua/ folder, and... a writer for the sandbox folder, that doesn't have a matching reader, so we can't really use it for much

grim pike
bronze yoke
sour island
#

yeah, I'm trying to debate on it

#

making an ATM UI would be neat and all, but it's not really intended for immersive gameplay lol

astral dune
#

you sure? Adding ATM tiles that have to be powered to transfer money would be neat

bronze yoke
#

project rp has an atm ui, sounds like it took them a while to get that working

bronze yoke
#

really? i must've misremembered something

drifting stump
#

also what you talked about removing files wont work because of the checksum verification

#

it happens before anything is loaded at all

bronze yoke
#

oh, it checksums the entire workshop item?

drifting stump
#

indeed it checksums all files

bronze yoke
#

but surely it doesn't checksum workshop items that the server isn't using?

#

not that that really helps anything

#

what a pain...

drifting stump
#

best way to deal with it is really deleting all contents and leaving it there

#

could check if theres a way to tell it to unsub from mods and then resub

sour island
#

Although I do agree having functional ATMs could be neat - idk if it would fit what they want

humble oriole
#

After I do my timed action on a building object my sprite goes invisible, anyone have an idea why that happens? The Object still exists, but the sprite is invisible.

#

that gets written to the log

bronze yoke
#

are you changing the sprite with the timed action?

humble oriole
#

no, immediately after it's built it goes invisible.

#

the "ghost" is the correct sprite

#

and it flashes for a second and then evaporates

scarlet basin
#

Hello, is there any mod existing wich i can repair my m16 without having another one? Cas it sucks when it is very high demaged and i cant use it

humble oriole
#

I think it has something to do with this portion of the Map Object, but when I set any part of these to line break it doesn't catch I'm not sure if it's not getting called correctly.

humble oriole
finite radish
#

if not, there's a handful of vanilla sprites that are hardcoded to only exist in certain circumstances (trees being the first that come to mind, but there are others)

finite radish
#

(when I say "that object" I mean the square, not the object that I assume you were trying to target)

humble oriole
#

This sprite is the metal fire pit

bronze yoke
#

there can only be one lua object per square

finite radish
humble oriole
#

I think those log lines are from this code.

        isoObject:sendObjectChange('name')
        isoObject:sendObjectChange('sprite')
        isoObject:transmitModData()
    end```
#

but I don't know what the 'sprite' is referencing

#

I don't need to change the sprite information, can I just take that out?

#

I actually don't need to change the name either, I just need the mod data to update

bronze yoke
#

yeah you can just take it out

robust jetty
#

anyone knows wich lua file manages the inventory folders ?

finite radish
robust jetty
#

Ty @finite radish

finite radish
#

(also ISInventoryPaneContextMenu for right click actions, I believe)

sour island
finite radish
#

chuck im gonna shoot you irl if you don't allow manual value entry. slider-only for complex numerical values is the work of satan

#

like have the slider too, cool, but i should also be able to manually change it

robust jetty
#

XD

sour island
#

Also, yeah probably need to add that

#

vanilla sliders have a click to slide increment as well as a shift click increment

#

in this case 0.01 and 0.5

finite radish
#

true, which isn't as bad as "slider only" interfaces, but if I know for a fact that I want $350.00 even then I don't want to have to "feel around" on the slider for where 350 is, end up somewhere like $354.39, and then spam-click the arrows until I get the right value

sour island
#

fair

finite radish
#

i honestly feel deep in my heart that any value that can't be represented without numbers shouldn't be a slider. hue, saturation, volume, etc... sure. but money? NAH MAN. NAHHHH

finite radish
finite radish
#

I'm gonna throw up man

#

phsyically nauseous looking at that

#

i can't even spell physically right

sour island
#

I thought it was kind of clever - especially the default being in the middle 😦

bronze yoke
#

it's not so bad

sour island
#

I wonder if I can convert the display into an input that plays nice with the slider

finite radish
#

just convert the entire game to be played with sliders. because why not. you've already committed the crimes, may as well go all the way

#

wanna eat an orange? gotta open the "Use Item" slider and slide it from 0.0000 to 1.0000

sour island
#

that'd be a good april fool's mod

#

every timed action requires you to slide a slider

finite radish
#

also, the only food item that spawns are sliders. as in, mini hamburgers

sour island
#

👍

finite radish
#

we're gonna be rich

sour island
#

QTE sliders

finite radish
#

dear god

#

"move slider to exactly 395.332 or that scratch is now a bite"

sour island
#

like those games with button hold QTEs that reverse the events if you let go for some reason

#

you have to slide the slider at a certain speed for your attack to land

finite radish
#

all the vehicle mechanics also run on sliders, so you need a slider for the gas, the brakes, and the steering. also one for horn activation and horn volume

#

(they can't be controlled with keyboard input either, so better be fast!)

sour island
#

also, having sliders for money creates an immersive experience as if shuffling your change around

#

🧠

finite radish
#

i really don't miss that era of human life i'm gonna be honest

#

people only use cards now for a reason

#

i don't need to emulate the nightmare of awkwardly forking through a handful of dirty, ancient coins

#

i'm fully immersed without that

bronze yoke
#

i just can't believe i'm in 1993 kentucky without awkwardly shuffling change

finite radish
sour island
#

penny for your troubles?

finite radish
#

man i sure love being able to click a singular button to subtract a singular penny from my potentially 6+ digit money balance

bronze yoke
#

i just wouldn't have six figures in my inventory

#

what kind of messed up economy is that

finite radish
#

it's not much better even if you only had $20 in your inventory

#

there's still a hundred pennies in a dollar

#

at least the slider would be easier to get close to what you actually want, but still

#

pls no cancer ui

sour island
#

I guess I could make a button that flips display for withdraw/deposit

#

brb

drifting ore
#

i'm still digging in but also trying to save some research time. am I able to add a custom item stat to any item? i'm working on diabetes dynamic trait mod where the goal is to add custom sugar stat values to most foods in game and utilize some checks to lipids and carbs to make some mix/max effect type of thing. noting up front that i am good with logic but literally newish to programming in general but not an idiot. i've been referencing many other instances of this type of usage across other mods to get an idea. but i haven't noticed an instance of someone adding custom stat values to items

bronze yoke
#

you can - anyUnrecognisedParameter = value, in an item script will have every item of that type spawn with the mod data anyUnrecognisedParameter = value

drifting ore
#

oh sick thank you

#

hoping to make it thoughtfully and complex. can't wait to share!

bronze yoke
#

i hope it goes well!

drifting ore
humble oriole
#

is it possible to debug server side lua?

jagged ingot
#

Good afternoon.

finite radish
astral dune
#

debug in the client is clientside only, unfortunately

jagged ingot
astral dune
#

if you want breakpoints

humble oriole
#

I'm not able to figure out if my MO and Server system and Global Objects are even being called. There's no clear link between the Building Object and Client Side System/Object

jagged ingot
#

You won't have the benefits of what the client-side gives however you can debug it just fine.

humble oriole
#

I'm still up against a wall with these sprites not showing up

#

and I don't understand why :/

fast galleon
#

fortune cookie says add more print

astral dune
#

pretty much, ya

jagged ingot
#

I managed to get my first working prototype last night of TS React & my mock HTML rendering engine for PZ UI.

dull moss
#

this require shit aint working

jagged ingot
#
/** @jsx PipeWrenchUI.createElement */

import * as Events from '@asledgehammer/pipewrench-events';
import { PipeWrenchUI, createUI } from '../../shared/pipewrench-ui/React';

Events.onMainMenuEnter.addListener(() => {
  createUI(
    <element
      class="my-element"
      style="top: 64px; left: 64px; width: 50%; height: 512px; background-color: #80ced6;"
    ></element>
  );
});
dull moss
#
-- DTWActionsOverride.lua
DTWActionsOverride = {};
function DTWActionsOverride.bodyworkEnthusiastCheck()
  -- code
end
return DTWActionsOverride;

-- DTWBySkills.lua
local DTWActionsOverride = require "DTWActionsOverride";
local function abc()
  -- code
  DTWActionsOverride.bodyworkEnthusiastCheck();
end
java.lang.RuntimeException: attempted index: bodyworkEnthusiastCheck of non-table: null```
can sm1 help?
#

i did as someone showed in this channel

#

unless i missed something

bronze yoke
#

is the directory correct? it should include all folders after server/client/shared

dull moss
#

oh

#

i was told it'll find it anyway

stone garden
jagged ingot
#

Is the file for DTWActionsOverride called DTWActionsOverride? Is it in client, server, or shared?

bronze yoke
#

e.g. shared/overrides/overrides.lua needs require 'overrides/overrides'

jagged ingot
#

require points to a Lua file, not the name of the library.

dull moss
#

yea i have to add TimedActions

jagged ingot
#

It's in TimedActions.

jagged ingot
dull moss
#

how does one include files other way around then? PepeThink

bronze yoke
#

what do you mean?

dull moss
#

like if i would want to include DTWByKills.lua in DTWActionsOverride.lua

jagged ingot
#

Relative pathing?

bronze yoke
#

require always searches from the start

dull moss
#

and start is in?

bronze yoke
#

so just require 'DTWByKills'

jagged ingot
#

client, server, or shared.

dull moss
#

ah

#

gotcha

#

thanks

jagged ingot
#

all three are roots.

#

server-side doesn't load client however the client loads all three.

dull moss
#

dont think that it'd matter for me but out of general curiosity does that mean that you can require lua from server folder?

astral dune
#

only from files in the server folder, otherwise it hasn't been loaded yet

dull moss
#

cheers

jagged ingot
#

Actually there's technical ways you can however it wouldn't be wise if you're doing simple stuff.

#

Wouldn't make sense.

#

You might as well code modules in shared.

dull moss
#

So I have this called on OnCreatePlayer

    player:getModData().DynamicTraitsWorld = player:getModData().DynamicTraitsWorld or {};
    local modData = player:getModData().DynamicTraitsWorld

    modData.VehiclePartRepairs = modData.VehiclePartRepairs or 0;

why this throws nul error on repairs? I thought when I loaded player I either loaded existing modData or made the value 0?

local modData = player:getModData().DynamicTraitsWorld;
local repairs = modData.DynamicTraitsWorld.vehiclePartRepairs;
jagged ingot
#

Hmm first I'd say you could clean this code up a fair bit. Cleaner code helps make your debugging much easier.

dull moss
#

i mean i dont want to create local variable for thing that's called once

#

sure i can shorten player:getPerkLevel(Perks.MetalWelding) to local var called metalworking

#

but it's used once in whole function

jagged ingot
#

Hmm ok. A suggestion.

#

Condition blocks that are this long smacks me in the head when reading. xD

dull moss
#

Ye I get that too KekW

#

fixed

#

hom i know what i'll do, brb

#

ah yes

dull moss
#

I don't think this works
modData.VehiclePartRepairs = modData.VehiclePartRepairs or 0;

lusty marsh
#

Hey everyone I've just updated my mod after a while away and just wanted to say thank you to everyone in the channel for helping with all my questions!

dull moss
#

I'm about to bullyping albion Angryloaf
jkjk

stone garden
bronze yoke
dull moss
#

throws nul at repairs

dull moss
#

BRAH

#

small v

#

i hate my life

#

literally a typo mistake dented

#

certified classic

astral dune
#

still shouldn't throw an error unless you tried to do something with repairs, haha

dull moss
#

it does cuz

#
local modData = player:getModData().DynamicTraitsWorld;
local repairs = modData.DynamicTraitsWorld.vehiclePartRepairs;

so
repairs = player:getModData().DynamicTraitsWorld.DynamicTraitsWorld.vehiclePartRepairs

#

i typed extra modID

astral dune
#

ah, lol, ya that'll do it

dull moss
#

ok i don't get, this exact code worked when i initially tested and now it doesn't and I really haven't changed anything.

local original_fix_perform = ISFixAction.perform;
function ISFixAction:perform()
    local player = self.character;
    local modData = player:getModData().DynamicTraitsWorld;
    local vehiclePartCondition = 0;
    if self.vehiclePart then
        vehiclePartCondition = self.vehiclePart:getCondition();
    end
    original_fix_perform(self);
end

throws error inside if loop. I looked at game ISFixAction and it uses similar if, from my understanding it should update vehiclePartCondition with condition of the part that's being repaired in case its a vehicle part? And it literally worked before, the onlything that changed is that I made this lua required in other place, but I don't see how it would break it. Or can it?

#

For reference this is base game isfix

#

on other hand it does also use condition = self.item:getCondition()

#

but then why it worked before? i don't get it

#

java.lang.RuntimeException: __add not defined for operands in perform

#

I'm not even adding anything???

sour island
#

@finite radish

dull moss
#

daymn

sour island
#

pretty happy with it

dull moss
#

ye, looks sick

sour island
#

going to rework the split/withdraw in shops

robust jetty
#

Anyone knows how to make "isEquipped()" work with a if?

ancient grail
#

its a boolean it checks if the item is equipped but also for some weird reason interfaces has it too

bronze yoke
#

if item:isEquipped() then

dull moss
#

Are luas ran in alphabetical order? So if I have 2 luas that both have OnCreatePlayer event, they will go off in file alphabetical order?

ancient grail
#

i was wrong

ancient grail
#

its just for items

dull moss
#

fuck

#

guess i have to rename my beautiful files

bronze yoke
#

events fire in the order they were added

#

you can require the file you want to run first in the file you want to run later to force it to run first

dull moss
#

Need ModData fire before anything else KekW

#

oh

#

ye i'll do require stuff

ancient grail
#

ye just require

dull moss
#

require "DTWModData" is enough right?

bronze yoke
#

yeah

dull moss
#

cheers

#

I was like "why does this moodle isnt showing up"

#

ah right

#

cuz it uses data thats initialized later

robust jetty
#

u too @ancient grail

dull moss
#

when you test if stuff is working your saves go

bronze yoke
#

i made a habit of deleting all the old ones

dull moss
#

I will

#

when im done with the mod

#

cuz i dont wanna do it in PZ

#

i'll jsut yeet folders from wherever saves are

#

cuz deleteing them 1by1 is pain

#

phew

#

part 1 of mod done

#

now part 2

#

part one was taking perks from non-maintained mod and rewriting them from the ground

sour island
#

Dynamic traits isn't maintained?

dull moss
#

not that

#

Simple Traits or something

#

dont rememebr

#

last update like a year ago and code in some places was a mess

#

More Traits doing fine

#

140 sandbox options will haunt me forever

#

if I add recipes to playerRecipes and it's already there, is it fine or do i need to check if it's already known?
to player:getKnownRecipes() that is

sour island
#

I think you need to check first - atleast based on vanilla code they use isknown first

dull moss
sour island
#

got a santa event while testing

#

._.

#

dudes unloading

#

guess that holiday date code works

finite radish
sour island
#

weird, using the confirm button doesn't update the window :\

dull moss
#

where can i find base game icons for traits?

#

ui/traits has like 5 pngs

#

I'm bout to get big mad, there are literally no trait icons in game folders

bronze yoke
#

they're in texture packs

#

i forget what the tool to extract them is called, but they're all in profession framework anyway

dull moss
#

Guess off I go downloading from wiki

#

Can't seem to overwrite base game traits

#

so im just disabling them and adding edited copy KekW

#

wait actually that'd be a bad idea to do that

#

cuz if other mods use base game traits for their stuff it'd fuck them up

#

Ok, new question

#

I can't seem to overwrite base game traits. I only need to change displayed name but if I do, description disappears and it refuses to even show perk gains when u hover over perk. For example,

#

I can overwrite the name, and i don't change anything else but it refuses to show original description

#

or ANY description, at that point

#

even if I make an entry in UI_EN

#

UI_trait_FirstAidDesc = "test",

#

ok nevermind i can load in my own desc

#

and technically as long as I don't change 1st param in traitfactory i can overwrite the traits with my own descriptions and expect it to work with mods that rely on using those perks

ancient grail
#

just sharing

#

thnx for all of those who supported =p

sour island
#

Nice work!

thick karma
#

Can someone help me understand why the verbose call on my expanded table viewing function gets caught in an apparently infinite loop and triggers a stack overflow? I am just not seeing it.

BS.reveal = function(someTable, verbose, prefix)
    if not (someTable and type(someTable) == "table") then return "" end

    if not prefix then prefix = "" end

    local result = ""
    
    for key, value in pairs(someTable) do 
        result = result .. tostring(key) .. "\n"
        if verbose then
            local subresult = BS.reveal(value, verbose, prefix .. "  ")
            if subresult then result = result .. "\n" .. subresult end
        end
    end

    if prefix == "" then
        Clipboard.setClipboard(result)
        print(result)
    end

    return result
end
lusty marsh
#

ngl I think you could use a while loop here instead of recursion?

sour island
#

Are you trying to print a tables contents?

thick karma
#

Yeah just print each table element of a given table the same way I print the first level of the table @sour island

thick karma
#

Currently just trying to get this right rather than start from scratch

sour island
#
function _internal.tableToString(object,nesting)
    nesting = nesting or 0
    local text = ""..string.rep("  ", nesting)
    if type(object) == 'table' then
        local s = "{\n"
        for k,v in pairs(object) do
            s = s..string.rep("  ", nesting+1).."\[\""..k.."\"\] = ".._internal.tableToString(v,nesting+1)..",\n"
        end
        text = s..string.rep("  ", nesting).."}"
    else
        if type(object) == "string" then text = "\""..tostring(object).."\""
        else text = tostring(object)
        end
    end
    return text
end


function _internal.stringToTable(inputstr)
    local tblTbl = loadstring("return "..inputstr)()
    return tblTbl
end
#

prints it in lua format

#

for reloading purposes

#

Not sure if you want to keep a specific format - but I've written something like this 3 times - so I know the pain

dull moss
#

I fucking hate that pz devs made trait called "Angler" but gave it internal handler "Fishing"

#

makes my code ugly and inconsistent

sour island
#

Wait till you see the traits with typos

dull moss
sour island
#

jokes aside, not changing names for aesthetics probably benefits not breaking something and going on an expedition

#
  • all our mods still work months later cause the devs seem to take extra care not to shift too much around
thick karma
bronze yoke
#

yeah, making changes like that when you really don't need to is inadvisable

thick karma
#

I copypasted what you sent, literally ONLY changed the name of the container object from _internal to an existing table in my mods (BS)

sour island
bronze yoke
#

breaking everything that uses a function is worse than a function having an annoying typo

thick karma
#
function BS.tableToString(object,nesting)
    nesting = nesting or 0
    local text = ""..string.rep("  ", nesting)
    if type(object) == 'table' then
        local s = "{\n"
        for k,v in pairs(object) do
            s = s..string.rep("  ", nesting+1).."\[\""..k.."\"\] = "..BS.tableToString(v,nesting+1)..",\n"
        end
        text = s..string.rep("  ", nesting).."}"
    else
        if type(object) == "string" then text = "\""..tostring(object).."\""
        else text = tostring(object)
        end
    end
    return text
end


function BS.stringToTable(inputstr)
    local tblTbl = loadstring("return "..inputstr)()
    return tblTbl
end
sour island
#

what is the table you're tying to print?

thick karma
#

Pasted this in terminal... called BS.tableToString(Jumper, 0) on the main table of my Jumper mod

#

My function can print the first level of Jumper just fine, but breaks the way my copypaste of your function breaks when I try to use it recursively

sour island
#

no need to have ,0

astral dune
#

your table doesn't refer to itself, does it?

sour island
#

but what does Jumper look like?

thick karma
thick karma
#

and some variables

sour island
#

I didn't think of self references

#

🤔

thick karma
#

You mean do I somewhere say Jumper.whatAmIEvenDoing = Jumper?

#

If so, absolutely not.

sour island
#

could be unintentional

#

in f11

thick karma
#

Hmm I just don't see how but fair enough

sour island
#

under locals

astral dune
#

anywhere where there is a circular reference of tables containing each other

sour island
#

is key = jumper?

thick karma
sour island
#

I wonder how I can change my code to identify recursive tables

dull moss
sour island
#

it's not clear sometimes but it should have a break down

thick karma
#

I mean I guess it's the likeliest explanation that something obscure like this is happening

#

If the code looks like it would work for non-circular tables.

sour island
#

I can modify my code to print out circular references

thick karma
#

Where does it say "Locals"?

sour island
#

I guess storing tables as a temporary list to referback to would work

thick karma
#

Yeah I was thinking I could add a table of found locations and skip processed tables in my loop.

#

Oh crap

sour island
#

would be beneficial to know where it's triggering

thick karma
#

Underneath the error window

#

got it

sand harbor
#

how would I make a test mod that I can just play around with? I tried copying (in workshop/content/108600) a pre-existing mod and changing the name & ID but it doesn't show up. Do I have to publish something as a workshop mod first?

sour island
# thick karma got it
function _internal.tableToString(object,nesting,tblLog)
    nesting = nesting or 0
    tblLog = tblLog or {}
    local text = ""..string.rep("  ", nesting)
    if type(object) == 'table' and not tblLog[object] then
        tblLog[object] = true
        local s = "{\n"
        for k,v in pairs(object) do
            s = s..string.rep("  ", nesting+1).."\[\""..k.."\"\] = ".._internal.tableToString(v,nesting+1,tblLog)..",\n"
        end
        text = s..string.rep("  ", nesting).."}"
    else
        if type(object) == "string" then text = "\""..tostring(object).."\""
        else text = tostring(object)
        end
    end
    return text
end
#

tested and works 👍

#

recursive tables will be printed as a string instead

#

I figured a part of your table might reference another part as well

lusty marsh
#

@thick karma Here's my while loop solution

    if not (someTable and type(someTable) == "table") then return "" end

    local queue = {
        {table = someTable, indent = ""}
    }
    local finished = {}
    local result = ""

    while #queue ~= 0 do
        local t = table.remove(queue, 1)

        local found = false
        for t2 in pairs(finished) do
            if t.table == t2 then 
                found == true
            end
        end

        if not found then
            table.insert(finished, t.table)
            for k,v in pairs(t.table) do
                result = result .. t.indent .. tostring(k) .. "\n"
                if verbose and type(v) == "table" then
                    table.insert(queue, {table = v, indent = t.indent .. "  "})
                end
            end
        end
    end

    return result
end```
sour island
thick karma
sour island
#

they follow different folder structure - but there's a template mod in Workshop

lusty marsh
thick karma
#

There would be countless other substrings passing that point that would not be finalized and no point in sending to clipboard

lusty marsh
thick karma
#

Irrelevant to while solution.

#

Yours wouldn't need something like that.

#

Yeah

#

lmao in my quest to make this gd function work I've gone from throwing exceptions to outright crashing the game

#

Nice.

#

I'm good at this.

#

lmao @sour island gonna try what you sent soon

#

I tried this and crashed (or possibly got impatient and killed Zomboid but I'm pretty sure it was going to crash):

BS.reveal = function(someTable, verbose, prefix, found)

    if not (someTable and type(someTable) == "table") then return "" end

    found = found or {}

    prefix = prefix or ""

    found[someTable] = true

    local result = ""
    
    for key, value in pairs(someTable) do
        result = result .. tostring(key) .. "\n"
        if verbose and not found[value] then
            local subresult = BS.reveal(value, verbose, prefix .. "  ", found)
            if subresult then result = result .. "\n" .. subresult end
        end
    end

    if prefix == "" then
        Clipboard.setClipboard(result)
        print(result)
    end

    return result
end
sour island
#

if you have a recursive reference it's going to break - unless the code prevents it

thick karma
#

I tried to by preventing the verbose descent when found[value] == true but no dice

sour island
#

you're already parsing the table though

#

it's too late at that point

thick karma
#

I seeeeee

#

So I should return sooner

sour island
#

you have to avoid passing sometable I imagine

#

the verbose thing is throwing me off a bit

#

verbose is a table right?

thick karma
#

verbose is a boolean

sour island
#

Oh here if not (someTable and type(someTable) == "table") then return "" end

#

add the found[someTable] here

thick karma
#

If it's not in verbose mode it doesn't recurse

#

Tried this:

BS.reveal = function(someTable, verbose, prefix, found)

    if not (someTable and type(someTable) == "table") then return "" end

    found = found or {}

    if found[someTable] then return "" else found[someTable] = true end

    prefix = prefix or ""

    local result = ""
    
    for key, value in pairs(someTable) do
        result = result .. tostring(key) .. "\n"
        if verbose then
            local subresult = BS.reveal(value, verbose, prefix .. "  ", found)
            if subresult then result = result .. "\n" .. subresult end
        end
    end

    if prefix == "" then
        Clipboard.setClipboard(result)
        print(result)
    end

    return result

end
#

Still crashed

#

Gah just realized I returned nil and need to return ""

#

But no exception, just crash?

sour island
thick karma
#

I notice you do a max degree of nesting... is that required? Could you loop to the maximum possible depth? Or does that conversion lead to issues?

sour island
#

There is no max on my nesting

#

each recursive call adds on 1

thick karma
#

So I could just say nesting level 33094 and your function would be cool with that

sour island
#

for indentation purposes mostly

thick karma
#

Got it

#

Oh wait

#

Nesting is indent?

sour island
#

yes

dull moss
#

TraitFactory.addTrait("Graceful", getText("UI_trait_graceful"), 4, getText("UI_trait_gracefuldesc"), false);
why is name from capital and in UI it's not

thick karma
#

Ahhhhh

#

string.rep(" ", nesting+1)

sour island
#

yes, rep = repeat

thick karma
#

Repeat " " * nesting

#

got it

ancient grail
dull moss
#

yes i know how it works, im saying its inconsistent as fuck

#

some traits start from capital letter and inside UI string its also capital

#

some other way around

#

some both from capital

ancient grail
#

👌

dull moss
#

if i make function that takes 5 arguments, can I call it like this to skip arg 3 and 4 for example, func(a, b, nil, nil, e)?

sour island
#

yes

dull moss
#

are nil needed or can i just leve empty space and it passes nil by default?

sour island
#

not declaring arguments also = nil

dull moss
#

yep

thick karma
sour island
#

it needs nil inbetween

dull moss
#

wdym inbetween

sour island
thick karma
#

Intriguing

sour island
dull moss
#

ah

#

i see

#

but fun(a,b,c) is ok

#

cut out last X arguments

sour island
#

yes

ancient grail
#

Yep

dull moss
#

gotcha

#

will this work?

local function createTrait(name, cost, forcedName, forcedUI, isProfExclusive, isDisabled)
    isProfExclusive = isProfExclusive or false;
    isDisabled = isDisabled or false;
    if forcedName or forcedUI then
        name = forcedName or name;
        local UI = forcedUI or name;```
#

so it uses forced name if its present

#

and if not, just name

sour island
#

what are you trying to avoid/do?

dull moss
#

Im marking all traits that can be dynamically obtained with D

#

if submod is present

sour island
#

getTextOrNull() can be used

#

to or it to another name

dull moss
#

I mean it works already

#

just tested 😄

sour island
#

yes but your if chain troubles me

thick karma
#

@sour island Okay when I added a depth feature and used it to limit my depth, it did not crash 2 levels deep

dull moss
sour island
#

Idk, I'm just being nitpicky

dull moss
sour island
#

I don't like seeing copy pasted code

dull moss
#

Yea it's not pretty

#

I was pretty when I didnt do base game traits

sour island
#

as small as it is - it's nice to be able to change 1 line and have it change everything else

dull moss
#

But hey now I have to account all the fucking inconsistencies in base game

thick karma
#
mod
  options
    soundEnabled
    animationEnabled
    showGroupJumpOptions
    neverForgetWhereYouComeFrom
    showRecentlyVisitedLocations
    groupJumpingHasPriority
    onlyBringFactionMembers
    singleMenuMode
  names
    soundEnabled
    animationEnabled
    showGroupJumpOptions
    neverForgetWhereYouComeFrom
    showRecentlyVisitedLocations
    groupJumpingHasPriority
    onlyBringFactionMembers
    singleMenuMode
  mod_id
  mod_shortname
  . . . 
bronze yoke
#

it's an issue of maintainability, i would recommend cleaning it up

thick karma
#

Clearly I was not terminating the recursion somehow

#

Or at least... not for a long time

#

Idk

dull moss
sour island
bronze yoke
#

the only difference is in one place you swap ui for name right?

thick karma
#

A really large table lol

sour island
thick karma
#

But it's not like unfathomably large

#

It's just a single mod file

dull moss
#
local function createTrait(name, cost, forcedName, forcedUI, isProfExclusive, isDisabled)
    isProfExclusive = isProfExclusive or false;
    isDisabled = isDisabled or false;
    if forcedName or forcedUI then
        name = forcedName or name;
        local UI = forcedUI or name;
        if getActivatedMods():contains("DynamicTraitsWorldMarkDynamicTraits") then
            return TraitFactory.addTrait(name, getText("UI_trait_" .. name .. "Marked"), cost, getText("UI_trait_" .. UI .."Desc"), isProfExclusive, isDisabled);
        else
            return TraitFactory.addTrait(name, getText("UI_trait_" .. name), cost, getText("UI_trait_" .. UI .."Desc"), isProfExclusive, isDisabled);
        end
    else
        if getActivatedMods():contains("DynamicTraitsWorldMarkDynamicTraits") then
            return TraitFactory.addTrait(name, getText("UI_trait_" .. name .. "Marked"), cost, getText("UI_trait_" .. name .."Desc"), isProfExclusive, isDisabled);
        else
            return TraitFactory.addTrait(name, getText("UI_trait_" .. name), cost, getText("UI_trait_" .. name .."Desc"), isProfExclusive, isDisabled);
        end
    end
end```
dull moss
#

cuz you see, for mod traits i can make stuff consistent but for base game i have to catch stuff like that so my name overwrite works with other mods

thick karma
#

@sour island Increasing max depth to 10 led to lock up and crash

sour island
# dull moss cuz you see, for mod traits i can make stuff consistent but for base game i have...
local function createTrait(name, cost, isProfExclusive, isDisabled)
    isProfExclusive = isProfExclusive or false;
    isDisabled = isDisabled or false;

    local marked = (getActivatedMods():contains("DynamicTraitsWorldMarkDynamicTraits") and "Marked") or ""
    local fetchedName = getTextOrNull("UI_trait_"..string.lower(name)..marked) or getTextOrNull("UI_trait_"..name:gsub("^%l", string.upper)..marked)
    local fetchedDesc = getTextOrNull("UI_trait_"..string.lower(name).."Desc") or getTextOrNull("UI_trait_"..name:gsub("^%l", string.upper).."Desc")
    
    return TraitFactory.addTrait(name, fetchedName, cost, fetchedDesc, isProfExclusive, isDisabled);
end```
dull moss
sour island
#

not sure about the name handling

dull moss
#

It may be shorter but it for sure aint more understandable

sour island
#

but this will grab something if its all lowercase or capitalized

dull moss
#

but that's the thing

#

Some base game traits use capitalized in both name and UI

#

Some have just name capitalized

sour island
#

this should catch either

#

regardless of what you enter as the argument

dull moss
#

ok lemme try

sour island
#

I messed up on the desc part tho

#

let me rewrite it a bit

bronze yoke
#
local function createTrait(name, cost, forcedName, forcedUI, isProfExclusive, isDisabled)
    isProfExclusive = isProfExclusive or false;
    isDisabled = isDisabled or false;

    local UI = forcedUI or name
    name = forcedName or name
    if getActivatedMods():contains("DynamicTraitsWorldMarkDynamicTraits") then
        name = name .. 'Marked'
    end

    local desc = getTextOrNull("UI_trait_"..UI.."Desc") or getText("UI_trait_"..UI.."desc")

    return TraitFactory.addTrait(name, getText("UI_trait_"..name), cost, desc, isProfExclusive, isDisabled);
end
dull moss
#
TraitFactory.addTrait("Graceful", getText("UI_trait_graceful"), 4, getText("UI_trait_gracefuldesc"), false);
TraitFactory.addTrait("SpeedDemon", getText("UI_trait_SpeedDemon"), 1, getText("UI_trait_SpeedDemonDesc"), false);```
#

^ both base game perks

#

for example

#

albion way seem more readable KekW

bronze yoke
#

it won't handle those annoying capitalisation variances unfortunately

sour island
#

updated mine

#

local marked = (getActivatedMods():contains("DynamicTraitsWorldMarkDynamicTraits") and "Marked")
returns "Marked" if the first thing is true

dull moss
#

if it'll work I'll bully you for detailed explanation how it works

bronze yoke
#

something like that might work

sour island
#

oh I realized it needs a or ""

#

updated, again

dull moss
#

k

#

I dont see how it would work when u pass only 4 arguments to it, honestly

thick karma
#

@sour island I am safely at depth 7 and seeing crap like this:

------------children
--------------3524
--------------3525
--------------3526
--------------3527
--------------3528
--------------3529
--------------3530
--------------3531
--------------3532
--------------3533
--------------3534
--------------3535
--------------3536
--------------3537
sour island
#

getTextOrNull returns null if the getText can't be processed - getText() returns the original text back to you

thick karma
#

14 dashes = 7 layers deep into Jumper

sour island
#

same logic, if the first thing is false/nil it goes to the next after or

sour island
thick karma
#

No a table of functions, variables, and tables. It's essentially a class

sour island
#

shouldn't matter

dull moss
thick karma
#

PS, 8 levels deep is where things broke for my function. Just crashed at 8 deep

dull moss
#

it wont me launch game

sour island
#

I think it's just triggering infinite loop failsafes

#

uh

thick karma
#

Yeah may be

sour island
#

I can't test it as is, but I may have a typo

thick karma
#

Oh well, that's life, I will just cap the depth at what appears to be safe.

sour island
#

you have

local function createTrait(name, cost, isProfExclusive, isDisabled)
    isProfExclusive = isProfExclusive or false;
    isDisabled = isDisabled or false;

    local marked = (getActivatedMods():contains("DynamicTraitsWorldMarkDynamicTraits") and "Marked") or ""
    local fetchedName = getTextOrNull("UI_trait_"..string.lower(name)..marked) or getTextOrNull("UI_trait_"..name:gsub("^%l", string.upper)..marked)
    local fetchedDesc = getTextOrNull("UI_trait_"..string.lower(name).."Desc") or getTextOrNull("UI_trait_"..name:gsub("^%l", string.upper).."Desc")

    return TraitFactory.addTrait(name, fetchedName, cost, fetchedDesc, isProfExclusive, isDisabled);
end