#mod_development

1 messages ยท Page 32 of 1

hollow current
#

aa no. should've been obvious

#

adding it

#

that one, yea?

hearty dew
#

yea. You might have already added it to your utilities functions though. I think I mentioned it to you before

#

.

hollow current
#

yee I should definitely save it for future use

hearty dew
#

ArendemethUtils.printR if you have that

hollow current
#

LOG : General , 1665273317300> [setName] => function 0x766473375

#

It apparently has a setName function, so not sure why wouldn't it work

weak sierra
#

what is the "correct" way to make part of the map load

#

getOrCreateGridSquare enough?

hearty dew
hollow current
#
LOG  : General     , 1665273629998> class zombie.inventory.types.ComboItem
LOG  : General     , 1665273639307> PRINTING CLASS
LOG  : General     , 1665273639307> class zombie.inventory.types.Moveable
LOG  : General     , 1665273649082> PRINTING CLASS
LOG  : General     , 1665273649083> class zombie.inventory.types.ComboItem
LOG  : General     , 1665273654990> PRINTING CLASS
LOG  : General     , 1665273654991> class zombie.inventory.types.Clothing```
#

LOG : General , 1665273639307> PRINTING CLASS LOG : General , 1665273639307> class zombie.inventory.types.Moveable

#

This is the object that doesn't work

#

.Moveable

#

rest are working

hearty dew
#

Maybe check that type's implementation of setName and whatever method prints the name

#

and compare it to ones that do work

hollow current
#

i tried to simply print its name

#

using getName

#

it does print it fine

#

Can it be an overall code limitation? Simply trying to change the name in debug mode using the vanilla "Edit Item" button doesn't work either

hearty dew
hollow current
#

would've been easier if I had known of any vanilla feature that somehow changes such items names as you go, but can't think of one lol

#

imma try searching through the vanilla files tho

#

hmm

#

local option = subMenu:addOption(Translator.getMoveableDisplayName(v.moveProps.name), _data, self.disassemble, v );

#

that looks like something

hearty dew
#

Ah, you could check the type and use that for Moveables

#

vanilla pz gives something is isinstance() to compare java types I think

hollow current
#

I am not sure I am using the function quite correctly in the first place

#
print(getMoveableDisplayName(item:getName()))
print(getMoveableDisplayName(item))```
#

Neither of those work

#

print(item:getMovableFullName()) works

#

now to set it..

#

SetMovableFullName doesn't work ofc, why would it ๐Ÿคฆโ€โ™‚๏ธ

hearty dew
weak sierra
#

i've had to tostring and do string comparisons a few times due to it just failing

#

:p

hearty dew
hollow current
weak sierra
#

there's tons of mods that do that

#

for a container tho? i think uh

#

what was it called..

#

there's a mod that does it but i can't recall the name

#

organized storage or soemthing?

#

it didn't retain data properly tho, so after a relog on mp it's gone

hearty dew
#

He's looking for a way to change moveables (things like table pieces when you pick them up). Their names aren't modified by the methods he's using atm

hollow current
weak sierra
#

mm

#

maybe im confused

#

i found the mod that i thought did it, but i think i misunderstood the purpose of the mod when i was a noob

#

it just sets categories for containers

#

nvm

hollow current
#

it's so irritating to have the mod being alive for a good while and believing its bug free due to how simple it is but no, it must always have some kind of a bug ๐Ÿคฆโ€โ™‚๏ธ

hollow current
bronze yoke
#

nothing is ever safe

weak sierra
#

closest u can get to safe is testing the shit out of it urself

#

and using it constantly

#

but yeah almost any piece of software always has something lurking

bronze yoke
#

yeah, i can't remember if it was a last minute change causing it or what, but it was an optional feature that i didn't actually personally want, so i never caught it after release

hollow current
hollow current
#

Doesn't look like setCustomName is the way to go either

hearty dew
#

I'd look at the implementation of Translator.getMoveableDisplayName() and how you might be able to set (if necessary) v.moveProps.name

pine fiber
#

Is it possible to display the list of items include in this category "zombie.inventory.types.DrainableComboItem" with a simple loop and a print?

hearty dew
#

@hollow current Hey, for admins, isn't there already a way to rename any item? I remember messing with that a long time ago in earlier pz builds. Is that not suitable to use here?

hollow current
hearty dew
#

Oh, okay. Probably the same behavior, that. Didn't know you looked into that

#
local function getMoveableDisplayName(obj)
    if not obj then return nil end
    if not obj:getSprite() then return nil end
    local props = obj:getSprite():getProperties()
    if props:Is("CustomName") then
        local name = props:Val("CustomName")
        if props:Is("GroupName") then
            name = props:Val("GroupName") .. " " .. name
        end
        return Translator.getMoveableDisplayName(name)
    end
    return nil
end
#

It's getting the name from the sprite properties

#

That's for ISWorldObjectContextMenu. Are you wanting to change it there? Or just in the inv context menu?

pine fiber
mystic meteor
#

the part I hate most about coding... writing the same function multiple times to hook it up to someone else's code

#

actually @hearty dew you seem to know fancy ways to call things, is there any Lua/KahLua function to do something like callOnInstance(instance, methodname)?

hearty dew
hollow current
mystic meteor
#

The first option yeah. Most of the code in every one of these functions is the same, it's just the set new value line that's different.

hollow current
#

it's the setName that has the issue

hearty dew
#

If in lua, lua local obj = blah local fn_name = "dothings" obj[fn_name]()

mystic meteor
#

That will do a self-call?

#

so your code is the same as obj:dothings()?

hearty dew
#

if you need to provide self (like obj:dothings() does magically), you would do ```lua
objfn_name

#

and can pass other args after it

#
obj[fn_name](obj, foo, var)
vague quiver
#

How to i install mods

mystic meteor
#

So I could do either of these?

inventoryItem:setMaxRange(protoval);
inventoryItem["setMaxRange"](inventorItem, protoval);
hearty dew
#

right

mystic meteor
#

bless

#

god that's gonna save me so much time, item prototypes have 330 some-odd parameters LutoWheeze

hearty dew
#

They should rename this channel #mod_development maybe. It is a bit confusing as it :p

mystic meteor
#

heh

astral dune
#

ya, comes up a lot

hearty dew
hollow current
hearty dew
#

And do you do anything to display the name? Or just rely on setting it atm (which doesn't work for Moveables)?

hollow current
#

What do you mean with displaying the name? You mean actually having the name take effect after setting it?

hearty dew
#

Yea, in theory you could intercept and modify the functions that render lines in the inventory pane. Just wondering if you are doing that or not

mystic meteor
#

is there anything special about functions like tonumber or can I assign those to variables just like any other function?

hollow current
#
ISRenameEverything.onRenameItem = function(item, player)
    local modal = ISTextBox:new(0, 0, 280, 180, getText("ContextMenu_label"), item:getName(), nil, ISRenameEverything.onRenameItemClick, player, getSpecificPlayer(player), item);
    modal:initialise();
    modal:addToUIManager();
end

function ISRenameEverything:onRenameItemClick(button, player, item)
    if button.internal == "OK" then
        if button.parent.entry:getText() and button.parent.entry:getText() ~= "" then
            item:setName(button.parent.entry:getText());
            local pdata = getPlayerData(player:getPlayerNum());
            pdata.playerInventory:refreshBackpacks();
            pdata.lootInventory:refreshBackpacks();
        end
    end
end```
vague quiver
#

Yall got some recomended beginner mods?

hearty dew
mystic meteor
#

I need to do the reverse of that. Storing the conversion function with each parameter

#

so sounds good

hearty dew
#

like ```lua
local fn = tostring

Yea, that's fine
mystic meteor
#

sick

warped nimbus
#

is there a mod that adds the option to lock/unlock windows

#

to help deal with zombies that can open doors/windows

hollow current
warped nimbus
#

oh gotcha my bad

simple cobalt
#

Sorry if this is a dumb question, but is there any sort of documentation where I can find things such as everything you can do with getCore()? I've been scouring the internet all day and haven't found anything ๐Ÿ˜…

astral dune
#

Core looks like its mostly just getting information about the game window

#

setting options too, although I'd be careful assuming that works outside SP

#

For the record, this ended up working, I just had to make sure it was called server-side

fast laurel
#

Is there such a thing as client side only mods in multiplayer for things like UI that don't affect gameplay or does the mod list have to match the server exactly?

astral dune
#

as far as I know, part of logging into a server is syncing your lua/scripts with the server

low sky
#

Is anyone working on a storm api mod?

astral dune
#

not me but I did recompile part of the game to fix a bug that was bothering me ๐Ÿ˜ฉ

signal frost
#

Do all the images I store in the root folder of my mod (the folder with workshop.txt) get added to the image slideshow on the mod page?

Is there a guide to styling the workshop page?

vast nacelle
signal frost
#

Legend, thanks so much

vast nacelle
#

Is there some property of IsoZombie that will let me know if a certain zombie created by the server is the same one that gets killed by the client? I had hoped getOnlineID would be the same between Server and Client but it appears the value is 'nil' when the zombie reaches the client's OnZombieDeath event, if it was ever even set on the client.

hearty dew
#

    public String getName() {
        if (this.isBroken()) {
            return Translator.getText("IGUI_ItemNaming", (Object)this.brokenString, (Object)this.name);
        }
        if (this.isTaintedWater()) {
            return Translator.getText("IGUI_ItemNameTaintedWater", (Object)this.name);
        }
        if (this.getRemoteControlID() != -1) {
            return Translator.getText("IGUI_ItemNameControllerLinked", (Object)this.name);
        }
        if (this.getMechanicType() > 0) {
            return Translator.getText("IGUI_ItemNameMechanicalType", (Object)this.name, (Object)Translator.getText(invokedynamic(makeConcatWithConstants:(I)Ljava/lang/String;, this.getMechanicType())));
        }
        return this.name;
    }
    
    public void setName(String substring) {
        if (substring.length() > 256) {
            substring = substring.substring(0, Math.min(substring.length(), 256));
        }
        this.name = substring;
    }

That's zombie.inventory.InventoryItem.java

#

    @Override
    public String getName() {
        if ("Moveable Object".equals(this.movableFullName)) {
            return this.name;
        }
        if (this.movableFullName.equals(this.name)) {
            return Translator.getMoveableDisplayName(this.customNameFull);
        }
        return invokedynamic(makeConcatWithConstants:(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;, Translator.getMoveableDisplayName(this.movableFullName), this.customNameFull.substring(this.movableFullName.length()));
    }

That's zombie.inventory.types.Moveable.java

hollow current
gilded hawk
#

Did anyone ever see this happening?

When I equip my custom bag, the character walks like it's injured wtfffff

hearty dew
#

    public Moveable(final String s, final String s2, final String s3, final String s4) {
        super(s, s2, s3, s4);
        this.worldSprite = "";
        this.isLight = false;
        this.lightUseBattery = false;
        this.lightHasBattery = false;
        this.lightBulbItem = "Base.LightBulb";
        this.lightPower = 0.0f;
        this.lightDelta = 2.5E-4f;
        this.lightR = 1.0f;
        this.lightG = 1.0f;
        this.lightB = 1.0f;
        this.isMultiGridAnchor = false;
        this.customNameFull = "Moveable Object";
        this.movableFullName = "Moveable Object";
        this.canBeDroppedOnFloor = false;
        this.hasReadWorldSprite = false;
        this.customItem = null;
        this.cat = ItemType.Moveable;
    }
#

the ctor

#
    public boolean ReadFromWorldSprite(final String s) {
...
                    String val = "Moveable Object";
                    if (properties.Is("CustomName")) {
                        if (properties.Is("GroupName")) {
                            val = invokedynamic(makeConcatWithConstants:(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;, properties.Val("GroupName"), properties.Val("CustomName"));
                        }
                        else {
                            val = properties.Val("CustomName");
                        }
                    }
                    this.movableFullName = val;
                    this.name = val;
                    this.customNameFull = val;
...
}
#

a method that seems to set those 3 name fields based on sprite info

gilded hawk
mystic meteor
hearty dew
mystic meteor
#

but I might be jumping in and providing feedback on the wrong thing NiaKekShake

hearty dew
gilded hawk
hearty dew
#

but wouldn't work outside of debug mode

hearty dew
undone elbow
hearty dew
#

For example, if you took that approach, your mod would be incompatible with Named Literature

#

It's tricky though because the call to getName() is in the middle of that massive function

undone elbow
#

Why overwriting if it's possible to inject?

hearty dew
#

You might be able to prefix patch the function and modify the item list so that later calls to getName return what you want

#

That seems like that best option I can think of

gilded hawk
hearty dew
undone elbow
#

What do you need? To override the name of an item?

hearty dew
undone elbow
#
do -- simple injection
    local m = __classmetatables[zombie.inventory.types.Moveable.class].__index
    local old_fn = m.getName
    m.getName = function(self, ...)
        -- check custom name here
        if self:hasModData() and self:getModData().custom_name then
            return self:getModData().custom_name
        end
        return old_fn(self, ...)
    end
end```
astral dune
#

what is this deep magic

hearty dew
#

Oh, cool. There ya go @hollow current . Looks like you can change it via the metatable :)

#

Wasn't sure if they were shared across class instances, but since they are, that should work

hollow current
#

oh. this looks.. a bit beyond my understanding. What's a metatable?

#

thanks nonetheless tho

astral dune
#

lua metatable stuff is still a bit impenetrable for me as well

hearty dew
#

Basically, you will use that to change the behavior of getName on the lua side to do what you want

mystic meteor
#

metatables are just tables that describe how other tables work

undone elbow
#

@hearty dew Actually I wrote a kind of code auto generation for myself. That's why it's so fast and without testing)

astral dune
#

this works because the java function is being called from the lua side, and you're tricking the lua userdata version of moveables to use your function instead of going back to the java, is that right?

hollow current
hearty dew
undone elbow
astral dune
mystic meteor
#

MoriNani hey, does calling tostring() on a string add a period to the end or something?

undone elbow
#

Ofc you need to understand what it does, because it's only additional code to main code that does the main renaming job

hearty dew
hollow current
#

so I should put this within a function, then call that function when I use setName on a moveable object?

mystic meteor
undone elbow
#

@astral dune Actually I'd implement the idea by another way.
In main renaming code something like this:

RENAMED_OBJECTS[item] = 'new_name'

And in injection code something like this:

if RENAMED_OBJECTS[self] then
   return RENAMED_OBJECTS[self]
end

This should work on the client only and will be compatible with multilingual stuff.

#

The custom name in mod data will be transferred to the server and to any client that uses the item later. That's why it's not the best way.

hearty dew
#

If successful, any subsequent calls to getName() will run that implementation of getName instead of the original

hollow current
#

so, just literally copy paste the code into a lua file in client folder and leave everything else as is?

undone elbow
#

No, you still have to provide the custom name. By default the implementation calls the original function, i.e. does nothing. It's just a wrap function

hearty dew
#
        if self:hasModData() and self:getModData().custom_name then
            return self:getModData().custom_name```
That `getName` implementation checks whether there is `custom_name` mod data on the item. If so, it returns that instead of calling into java. You need to set the `custom_name` mod data instead of where you call `setName` now
#

You are putting the user-entered name into mod data, instead of setting/getting it in the java side, if that makes more sense

undone elbow
#

As I said, this is not the most optimized way, imo. But I guess at the first time it should just work, shouldn't it?

hollow current
#

oo i see, that makes more sense now

#

I have never worked with mod data, how do I exactly set it?

bronze yoke
#

:getModData() returns a table

hollow current
#

will try it and come back if I face an issue

bronze yoke
#

that's for global mod data, it's not exactly the same

hollow current
#

oh

bronze yoke
#

mod data is just a table attached to most objects

#

object:getModData().key = value

hollow current
#

so in that sense

#

when setting a new name

#

it'd be like:

undone elbow
#

Btw, I search in all subscribed mods. No one injects like this (except my mods). This is very strange.... because it's very powerful.

hollow current
#

instead of item:setName(button.parent.entry:getText());, we use item:getModData().custom_name = button.parent.entry:getText()

vast nacelle
#

Anyone know how to programmatically add new outfits to the outfit lists? I know how to do it using XMLs that the game reads in, but I could use a way to do it in lua while the game is running.

hollow current
#

okay wow that works

#

Thanks so much!
quick question though. So if I understand this correctly, if the mod is unloaded, the items will shift back to their names, right?

bronze yoke
#

no, moddata is just a table

undone elbow
hollow current
#

Does it need special implementation in MP?

bronze yoke
#

probably not

astral dune
#

Just realized I've spent a couple days attempting to attach an update function to the engine when it already has one that can easily be patched ๐Ÿคฆโ€โ™‚๏ธ

bronze yoke
#

i didn't realise you could do this, this could be a massive efficiency boost to one of my mods

hollow current
#

I seee, so I guess the best course of action is to have normal items names changed using the native setName() function, and using moddata for moveable items

astral dune
#

what are you thinking of doing with it, albion?

bronze yoke
#

i have a mod that lets players spread the infection between each other by proximity

undone elbow
bronze yoke
#

i could replace the every minute checks for infection with just a hook onto the setInfected() function

astral dune
#

interdasting

hollow current
bronze yoke
#

isn't this the mod that lets you rename items yourself? how could you possibly make that multilingual?

hollow current
#

^ Good question, would like to see the global table example tho for any future need

undone elbow
mystic meteor
#

oh shit, arendameth is here
I can yell about a bug NiaKekShake

#

hey arendameth, in the current version renamable-in-vanilla items have two rename options in their right-click

#

for everything has a name

hollow current
#

hours searching for a solution for a bug for Everything has a Name mod and someone already giving me a new bug to fix unhappy

#

i guess it shouldn't be too complex

mystic meteor
bronze yoke
#

suffering from success

mystic meteor
#

it was a mod I wanted for a while (and I think a lot of other people wanted too)

#

...any chance of getting it to work on containers?

#

like, crates and stuff

hollow current
hearty dew
mystic meteor
#

Moveables, I suppose. Crates, cardboard boxes, shelves, etc

#

sounds like you already got it working so MenoPray bless you

astral dune
#

there is already a mod to name them when they're placed in the world, and I believe the names are stored on the movables when picked up, although they're not displayed

#

if Arendameth was feeling cheeky, he could use the same moddata() key that the other mod is using for surprise compatibility

mystic meteor
#

Having them displayed is what I want. Manage Containers technically lets you name them but it doesn't show anywhere except in the mod

hollow current
#

wait what slow down

astral dune
#

yes, but there is another

hollow current
#

display names where?

mystic meteor
#

I'd like them displayed in the name of the container, so like, here

#

where it currently says garbage

astral dune
#

I was just saying there is another mod, called What Did You Put In Here that lets you name movable containers that are placed in the world, and I believe those names are retained on the movables when they're picked up so they have the same name when placed down again. Assuming that name is stored in the modData, you could potentially use the same key value so that when someone picks up a moveable named by that mod, it will show it in the inventory

hollow current
#

also would the most optimal way to check if an item is moveable to check for classes? like so?

local item_class = tostring(item:getClass())
if item_class == "class zombie.inventory.types.Moveable" then
  print("True")
end```
mystic meteor
#

MenoThonk I will look at that

hollow current
mystic meteor
#

As for that, it involves some java reflection, so maybe not

mystic meteor
astral dune
#

its been a lifesaver for me, especially when trying to sort all the Brita ammo, lol

mystic meteor
hollow current
#

yup that definitely looks way more clean, ty

mystic meteor
#

you could also do some cheeky thing like

if nil ~= item.getMoveableFullName then
end

which checks for the existence of the function and should be nil for everything but moveables

#

dunno which is more performant in the end

#

my assumption is that that field is populated during the transition to Lua and should be more performant

hollow current
#

I think I should be using it like so:

function ISRenameEverything:onRenameItemClick(button, player, item)
    if button.internal == "OK" then
        if button.parent.entry:getText() and button.parent.entry:getText() ~= "" then
            if instanceof(item, "Moveable") then
                item:getModData().custom_name = button.parent.entry:getText()
            else
                item:setName(button.parent.entry:getText());
            end
            local pdata = getPlayerData(player:getPlayerNum());
            pdata.playerInventory:refreshBackpacks();
            pdata.lootInventory:refreshBackpacks();
        end
    end
end``` because I will also check for instances of certain items like maps to avoid double rename option
astral dune
hollow current
#

Any idea what are all the objects that are renamable in vanilla?

mystic meteor
#

hm

bronze yoke
#

... stores any number of arguments

mystic meteor
#

there's gotta be a flag for it

astral dune
#

how would you read from them if you don't have names?

bronze yoke
#

it's a table

astral dune
#

is this the equivalent of using _ for when you don't need them

mystic meteor
#

oh speaking of arendameth do you allow any rename length? I could swear I can use names longer than 28 now

hollow current
#

Maps are definitely renameable in vanilla and have a MapItem class so there's that

hollow current
mystic meteor
#

okay, good and bad news
good news: lua/client/ISUI/ISInventoryPaneContextMenu has all the rename flags
bad news: it's just doing comparisons to instanceofs

undone elbow
#

Is there an event to check the appearance of another player in multiplayer on client side? ๐Ÿค”๐Ÿค”๐Ÿค”

bronze yoke
mystic meteor
#

good news again: looks like there's only two instances that allow renames

astral dune
#

ah I see. I'll have to look more into unpack

bronze yoke
#

unpack just returns all the values of a table

mystic meteor
#

maps don't even have that flag

#

ah, it has its own rename menu

hollow current
# mystic meteor ah, it has its own rename menu
ISRenameEverything.createMenu = function(player, context, items)
    local canBeRenamed = nil;

    for i, v in ipairs(items) do
        local item = v;
        
        if not instanceof(v, "InventoryItem") then
            item = v.items[1];
        end
        
        if not instanceof(item, "MapItem") then
            canBeRenamed = item;
        end
    end

    if canBeRenamed then
        context:addOption(getText("ContextMenu_renameButton"), canBeRenamed, ISRenameEverything.onRenameItem, player);
    end
end```
mystic meteor
#

so it's: food, which has its own flag, maps, which has no flag but just does its own check, and those two lines which do some type checks

hollow current
#

current code

#

wait what

#

food can be renamed in vanilla?

mystic meteor
#

so it looks like you really just need to add the keys and keyrings then

#

sort of

#

food lets you rename it under really specific situations

bronze yoke
#

some cooked meals and stuff i think

mystic meteor
#

annoyingly it loses that rename once you put it in bowls

astral dune
#

Well, neat. Thanks to what we all learned here today, I no longer have to overwrite the entire /server/vehicles/vehiclecommands.lua file

mystic meteor
undone elbow
#

How to get nearest players in mp?

mystic meteor
#

so if I'm following this right, addoption takes the text, the item to target with it, the function to call, and then 10 optional parameters?

little girder
#

If I wanted to have someone make my car in the game, how would I go about that? like commisioning a mod maker

hollow current
hearty dew
#

Sorry, missed that question in the convo

astral dune
#

no worries

hollow current
#

oki so, I am trying to avoid the double rename option for keys. Initially, I'd check for their class, but they use InventoryContainer, which isn't ideal because the same class applies for other items like fanny packs

#

what's the most optimum way to check for the type of an item after its class?

undone elbow
#

I can get the list of players AND vehicles using getCell():getObjectList(), also using getCell():getLuaObjectList(). But how to get the list of players only?

hearty dew
mystic meteor
hearty dew
# undone elbow How to get nearest players in mp?

I'm curious about this too. I need it for something I'm doing. The best option I've come across atm is to iterate over getOnlinePlayers (and hopefully compare distance to find closest). Not sure if there is something better atm, and haven't even tried it out yet

astral dune
#

I could have sworn there was a getOnlinePlayers() function or something

bronze yoke
#

it depends on the range you want, you can loop through nearby squares and check them for players or loop through all players and test for distance

mystic meteor
#

Yeah, all equipable containers can be renamed to my knowledge.

bronze yoke
#

which one is more efficient depends on your application

hollow current
#

Oh yea that's definitely true

undone elbow
bronze yoke
#

regarding the java hooking discussion, are some classes just not exposed this way? ```lua
local zombiesZoneDefinition = __classmetatables[zombie.characters.ZombiesZoneDefinition.class].__index

undone elbow
#

another_player:getSquare() returns an object even if a mile from me.

hearty dew
bronze yoke
#

that sucks u_u some other related classes were exposed so i'll see if i can do what i wanted in them instead

hearty dew
#

This java method exposes the classes @bronze yoke

hollow current
#

any idea what's the full class meta table name for world contains?

hearty dew
#

It's the java full name. Can look those up in the pz java doc or looking at ProjectZomboid/zombie

#

Or can use ArendamethUtils.printR(__classmetatables, 6) :p

hollow current
# astral dune I was just saying there is another mod, called `What Did You Put In Here` that l...

soo, regarding that, I assume that'd be the correct way to do it?

do -- simple injection
    local m = __classmetatables[zombie.inventory.types.Moveable.class].__index
    local old_fn = m.getName
    m.getName = function(self, ...)
        -- check custom name here
        if self:hasModData() then
            if self:getModData().custom_name then
                return self:getModData().custom_name
            elseif self:getModData().wdypihName then --wdypihName is the value used by the other mod
                return self:getModData().wdypihName
        end
        return old_fn(self, ...)
    end
end```
hollow current
hearty dew
hearty dew
hearty dew
#

You can store that moddata result in a local variable so you don't have to call into java 4 times btw

hollow current
#

That sounds.. sensible

astral dune
echo wadi
#

What are some really good/essential mods I should be using while playing? Either QOL or add content to keep from getting burned out

astral dune
astral dune
#

Does anyone have a tool that will let you watch logs live? I'm using notepad++ which at least tells me when a log has updated and prompt me to refresh, but I'd like to just be able to watch the logs

hearty dew
#

If you have cygwin installed, can do tail -F Zomboid/console.txt

astral dune
#

hmm, I may have installed it at one point, I'll have a look

#

oh @bronze yoke , I've found that part updates on vehicles keep happening if there is nobody inside on one of 2 conditions. Either A) you've left it running or B) it continues for a short period after you get out. I think it continues to update until the engine cools off but I'm not sure

hollow current
#

small bug, when I rename a moveable object, then place it, and pick it up, it resets to its original name, any idea why'd that be?

hearty dew
#

The Moveable might only exist within the context of being in inventories?

bronze yoke
astral dune
#

I imagine you'd need custom code to handle the placing/pickup of the movable to shuffle the moddata over to the tile and back

hearty dew
astral dune
hollow current
#

aaah it can never be simple can it

bronze yoke
#

your update function is on the engine, correct? it would make sense that that continues updating while the engine is still... updating

astral dune
#

yes, true, and I'm only listening for engine updates, its possible other parts update when the mechanics window is open, but the engine doesn't

bronze yoke
#

other parts certainly do

#

i noticed this behaviour with all of my custom parts

hollow current
#

Well I guess this is a bug for another day to fix. I am burnt out for today lol. I really appreciate your help guys!

undone elbow
# hearty dew That's a good question. I'm not sure. Perhaps the list of players returned is di...
--client only
local function getNearestPlayers(me)
    if me ~= getSpecificPlayer(0) then
        return {}
    end
    local result = {}
    
    local online = getOnlinePlayers()
    local objects = getCell():getObjectList()
    
    if online:size() < objects:size() then
        for i=0,online:size()-1 do
            local player = online:get(i)
            if player:getCurrentSquare() and player ~= me then
                table.insert(result, player)
            end
        end
    else
        for i=0,objects:size()-1 do
            local obj = objects:get(i)
            if instanceof(obj, 'IsoPlayer') and obj ~= me then
                table.insert(result, obj)
            end
        end
    end
        
    return result
end```
#

Should work. ๐Ÿ™‚

hearty dew
#

Cool. Thanks :)

#

I'll need to adjust it to work server side. I need to find players near to a zombie :)

swift lagoon
#

I'm editing the script someone made for making isometric. The script doesn't made for PZ, so the size is different. * means multiply, what's the 'divide by'?

#

It's lua

hearty dew
#

/

swift lagoon
#

thank you!

bronze yoke
#

on second thought, i'm getting updates from the engine being left on

#

i must've turned it off every time

astral dune
#

so if you turn it off the updates on your custom parts stop?

bronze yoke
#

not reliably; i am absolutely certain of my earlier observations, so i'm not really sure what happened there

#

the test method has changed but i doubt that's relevantโ€” earlier i was using a print in the function, now i am testing an alternative method so i've removed the update function, and the game is printing errors about that instead

astral dune
#

currently my debug output is to make the driver of the vehicle say the debug messages aloud.... but I want to make them come out of the radio. Anyone know how to do that? lol

#

man, half of the radio methods have like 10-11 unnamed variables. I'll look at this tomorrow

ancient grail
#
function ConnectToServer:OnConnected()
    if not SystemDisabler.getAllowDebugConnections() and getDebug() and not isAdmin() and not isCoopHost() and
            not SystemDisabler.getOverrideServerConnectDebugCheck() then
        forceDisconnect()
        return
    end
    self.connecting = false
    self:setVisible(false)
    local joypadData = JoypadState.getMainMenuJoypad()
    if not checkSavePlayerExists() then
        if MapSpawnSelect.instance:hasChoices() then
            MapSpawnSelect.instance:fillList()
            MapSpawnSelect.instance:setVisible(true, joypadData)
        elseif WorldSelect.instance:hasChoices() then
            WorldSelect.instance:fillList()
            WorldSelect.instance:setVisible(true, joypadData)
        else
            MapSpawnSelect.instance:useDefaultSpawnRegion()
            MainScreen.instance.charCreationProfession.previousScreen = nil
            MainScreen.instance.charCreationProfession:setVisible(true, joypadData)
        end
    else
        GameWindow.doRenderEvent(false)

        forceChangeState(LoadingQueueState.new())
    end
end

hi guys this is a vanila script about connecting players

is it possible that i inject a function here?

like

if  myCustomBanList() then return end```
hearty dew
#

Looks like getNumActivePlayers() and getSpecificPlayer() are for multiple local players running on one client. Has anyone messed with the split screen mode or know how to set it up? Don't even see it as an option

hearty dew
hearty dew
bronze yoke
#

it's drop in, you just press a button on the controller

fast galleon
#

What's a good way to save my keybindings for mods, because when I disable them to test stuff I lose them.

hearty dew
#

Can backup the key.ini file.
Can also start pz with a different config dir for when you are doing development stuff

#

You can have 4 players per udp connection. That must be for 4 players on local split screen joining a remote server

hearty dew
#

Is there a lua console on a dedicated server? Or do you have to build your own?

undone elbow
#

I made my own

#

Client command goes to the server, then it's executed. lua DebugLua = function(player, args) local s, filename = args.param if not s then filename = 'dofile.lua' elseif s:find("%.lua$") then filename = s end if filename then local file = getFileReader(filename, false); local line; local arr = {} while true do line = file:readLine(); if line == nil then file:close(); break; end table.insert(arr, line) end s = table.concat(arr,'\n') end if s then local fn, error = loadstring(s) if fn then fn() else print('SYNTAX ERROR!\n' .. tostring(error)) end end end,

hearty dew
#

Thanks

glad ridge
#
    {
    DisplayCategory = FunTime,
    Type = Normal,
    DisplayName = Dirty Homemade Pocket Pal,
    Icon = PocketPalDirty,
    StaticModel = PocketPalDirty,
    WorldStaticModel = PocketPalDirty,
    Weight = 0.5,
    }

item PocketPalUsed
    {
    DisplayCategory = FunTime,
    Type = Normal,
    DisplayName = Sticky Homemade Pocket Pal,
    Icon = PocketPalUsed,
    StaticModel = PocketPalUsed,
    WorldStaticModel = PocketPalUsed,
    Weight = 0.5,
    Wet = TRUE,
    WetCooldown = 30000,
    ItemWhenDry = PocketPalDirty,
    }

Can anyone tell me why when my used pocket pal drys out it disappears and doesn't turn into a PocketPalDirty? what am i doing wrong here?

#

this pops up in the console after it disappears

#

it used to work just fine, idk if a recent update made it so it doesn't work correctly anymore

spark crystal
#

Hey folks..

Is there some way to reload recipes, while running the game in debug mode?
Does reload lua also do recipes?

glad ridge
#

f11 you can search up the specific lua in the bottom right part

spark crystal
#

It's not lua though, it's a recipe script

glad ridge
#

i don;t believe it reloads your .txts, you have to restart for that to work

hearty dew
#

Not that I've come across, no

spark crystal
#

Okay, thanks, I'll keep up with the restarting.

#

Is there some quick/easy reference for the internal name for sounds to use in crafting recipes, or is it just the filename in the sounds folder?

thick karma
#

This turned out to be exactly what I needed to do. I figured it out by looking at PDFTZ (which I already run). Thanks for offering best idea you had.

dusty raft
#

are all mods broken right now because of the new build?

austere finch
#

I'm trying to implement a category reassignment via ItemTweaker on a number of items which have already been assigned categories in Better Sorting, for example; for some reason, just having an ItemTweaker call to assign a new category to these itemID later in the mod load order doesn't seem to do the trick, as though ItemTweak's going 'This was already given a new category, so I'm skipping it.' It's chiefly to try to update things from 'Junk' that are usable as Crafting, etc. Is there a good way to go about this without the risk of overriding game-relevant item tweaks? (e.g. I don't want to have it drop any mechanical adjustments other mods may have applied, I'm just trying to ensure things get a more up-to-date accurate categorization.)

hearty dew
#

That shouldn't cause a problem. You can look at the output of the items being tweaked to see what it is actually doing. Are you setting the tweak values prior to OnGameBoot?

austere finch
#

I'm just running lines of TweakItem("ItemID","DisplayCategory","NewCat"); after require("ItemTweaker_Copy_CC") if it's a vanilla / base game item, and after a if getActivateDMods():contains(:modID") then if it's from a mod -- there's just a seemingly random subset of items which seem to ignore it for some reason.

#

Where's the best way to check the output, just console.txt?

hearty dew
#

Yea, console.txt

#

Could be something else overwriting your changes?

#

You can check console.txt to verify your file is loaded after itemtweaker's file

#

Also, are those calls run when the file is loaded or called later inside a function?

hearty dew
austere finch
#

I'm setting mine to the very bottom of the load order

hearty dew
#

If so, try changing your filename from myfile.lua to zz_myfile.lua and make sure it is in client/

#

load order doesn't help the order lua files are run

#

The lua file load order is shared/, client/ (unless it is a server), then server/. Within each of those sets, the files are loaded alphabetically

austere finch
#

Dang, that's annoying

austere finch
#

Still not sticking even as prefixed with zz in client

#

Other items in the same lua file inherit their categories correctly

hearty dew
#

Hmm, I'd search console.txt for the item your are having issues with

austere finch
#

LOG : General , 1665328245102> Base.Rubberducky: DisplayCategory, Junk it is the nefarious tyrant, the Rubber Ducky

#

I'm trying to make it not junk

hearty dew
#

Hrm, could be a file in server/ is modifying it since it loads after client/ files

#

or in an event after lua files are loaded

#

If you have a method to, can search your mod directory for Rubberducky

pine fiber
lusty dirge
#

Is there a resource, or a list somewhere that has all the possible container ID's for the procedural distribution list options? (ie. I am modding a firearm pack, and want to spawn them in certain container types)

hearty dew
#

ProjectZomboid/media/lua/server/Items/ProceduralDistributions.lua has all the vanilla ones

#

Mods can add their own. You'd have to check their source to see what they modify or add

#

@undone elbow ```lua

--[[
getNumActivePlayers:
- Singleplayer: number of local players in client (including all split screen players)
- Client: number of local players in client (including all split screen players)
- Server: 1, but getSpecificPlayer() calls always return nil on server

getOnlinePlayers:
- Singleplayer: nil
- Client: lists all players (including split screen players)
- Server: lists all players (including split screen players)

getConnectedPlayers: trash. only seems useful for working with scoreboard?
- Singleplayer: 0
- Client: only updates when a player manually open scoreboard, but lists all players then
- Server: 0

]]
getPlayers = function(predicate)
local result = {}
predicate = predicate or function(player)
return not player:isDead()
-- and player:getCurrentSquare() -- Will filter out players sufficiently far from client that their square isn't loaded
end
if not isClient() and not isServer() then
-- singleplayer
for i = 0, getNumActivePlayers() - 1 do
local player = getSpecificPlayer(i)
if player and predicate(player) then
table.insert(result, player)
end
end
else -- multiplayer
local onlinePlayers = getOnlinePlayers()
for i = 0, onlinePlayers:size() - 1 do
local player = onlinePlayers:get(i)
if player and predicate(player) then
table.insert(result, player)
end
end
end

return result

end

#

Seems to work well on singleplayer, client, or server

thick karma
#

If I use OnKeyPressed, does that go off whenever any player on the server presses the key? Or only when player does it if it's in the Client folder?

hearty dew
#

only on the client

#

It might go off if any local split screen player presses a key, haven't tested that

thick karma
#

Oh crap

#

One sec

#

On multiplayer, this hits all players, right?

    for playerIndex = 0, getNumActivePlayers() - 1 do
        
        -- stuff

    end```
#

I have seen that recommended for MP usage

hearty dew
thick karma
#

I see. In MP, does it get the current player on the client?

#

/ all local players

#

If I am split?

#

Is it like a fake loop?

hearty dew
#

It gets the local players, yea

thick karma
#

Okay sounds good, that's actually what I need it to be doing, wanted to be sure

#

Any ideas on this? It seems pretty straightforward but for some reason isn't workin...

#
local function deactivateDivineProtectionB(player)

    if (player:isInvisible()) then
        
        player:setInvisible(false)

    end

end

local function dispelGraceB(key)

    for playerIndex = 0, getNumActivePlayers() - 1 do
        
        local player = getSpecificPlayer(playerIndex)
        
        deactivateDivineProtectionB(player)

    end

end

Events.OnKeyPressed.Add(dispelGraceB)```
#

Also, for anyone who happens to already know this key-press stuff well, I am extremely interested in doing a follow-up to this mod where I cause all on-screen windows to close using a single button-press... If anyone can help me solve that by pointing me at the right mods or files, โค๏ธ .

glad ridge
#

#mod_development message
anyone know a fix for this? it used to work before recent updates, now when my item dries it just disappears instead of changing to the thing i want it to be

pine fiber
#

Hi. Is it possible to control the volume of a sound emitted by โคต๏ธ ?

:getEmitter():playSound(soundFile)

thick karma
#

But specifically I don't know

#

If neither, then maybe new anticheat limitations I don't know about...?

thick karma
#

I think keypress modification needed to be in my mod at launch because it was totally failing and I just launched and I'm p sure it worked. Gotta die a few more times to be sure

thick karma
#

Any way to catch a gamepad button event? OnKeyStartPressed is ignoring gamepad presses

shadow geyser
#

id take a look at the gamepad UI stuff. you should be able to see how those are triggered, like for example the vehicle scroll wheel

thick karma
shadow geyser
#

just search the vanilla files for "gamepad" or "pad" and im sure youll find something

thick karma
#

I'm seeing stuff like ISPanelJoypad.onJoypadDown(self, button, joypadData) in some places and self.mainPanel.onJoypadDown in others...

#

Is it possible each context has its own joypad listeners?

shadow geyser
#

looks like it

#

ive never actually played with a gamepad so im not sure how different the UI is with them

thick karma
#

Apparently a lot going on... but if I just have to find the right context, I will keep trying

#

I am going to experiment with a function I'm guessing at lol

local function onMainMenuB()
    
    JoypadState.useJoypad()

end
#

Always annoyed me when I load the game with my controller on I have to press a button to get focus

#

This is 100% a real function JoypadState.useKeyboardMouse()

#

useJoypad is a guess

#

HMmmMMmmMMmmm... what do you think about the name of this? JoypadControllerData:onPressButtonNoFocus(button) @shadow geyser

astral dune
#

does anything in game produce something like a smoke effect?

glad ridge
#

I only have icons for these items and they are all in the same folder, and the two other icons I'm using load fine, I can even spawn the one that disappears in admin but when the wetness gets to 0 it just up and vanishes

heavy bridge
#

I'm not seeing one, but is there a mod to can cooked recipes, like can and preserve stews?

#

jar rather

thick karma
#

@hearty dew Ay, I tried your little trickery for adding a small adjustment to the rules of the reading function to catch gamepad input, and it worked!!! ....Kind of...

local function deactivateDivineProtectionB(player)

    if (player:isInvisible()) then
        
        player:setInvisible(false)

    end

end

local function dispelGraceGamepadB()

    for playerIndex = 0, getNumActivePlayers() - 1 do
        
        local player = getSpecificPlayer(playerIndex)

        player:Say("Ayyy!")
        
        if player then 
            deactivateDivineProtectionB(player) 
        end

    end

end

local onPressButtonB = JoypadControllerData.onPressButtonNoFocus

function JoypadControllerData:onPressButtonNoFocus(button)

    dispelGraceGamepadB()

    onPressButtonB(button)

end
#

When I do this, the game says "Ayyy" as expected, but the game throws an exception after that when it tries to run my duplicated version of the file... It gets stuck here:

#

I believe the error is actually referring to line above green highlight, where "self" does not exist and "joypad" is the "index" of self, so-to-speak

#

Question is: how can I take over or add to the joypad button detection event without causing it to start throwing weird exceptions where it no longer recognizes itself (har har)?

weak sierra
#

self is implicitly given to a function when it is called with :

#

it is defined that way so expects it, are you calling it with : or .

#

looks above

#

guessing the game is calling that not u

#

so self should not be nil

#

that said, throw some print statements in there and find out, or use the debug to poke thru the variables

thick karma
#

Yes, the game calls that thing that needs "self" in the screenshot. So I need to figure out what the game uses to call "function JoypadControllerData:onPressButtonNoFocus(button)"?

bronze yoke
#

onPressButtonB(self, button)

#

you're not passing self to the original function after your overwrite runs

#

remember that function JoypadControllerData:onPressButtonNoFocus(button) (with a colon) is the same as writing function JoypadControllerData.onPressButtonNoFocus(self, button)

thick karma
#

But I am thinking maybe source of all the calls is onJoypadRenderTick

#

So I am starting there and trying to find a place to insert myself and add an action when it senses a pressed button

#

    if (player:isInvisible()) then
        
        player:setInvisible(false)

    end

end

local function dispelGraceGamepadB()

    for playerIndex = 0, getNumActivePlayers() - 1 do
        
        local player = getSpecificPlayer(playerIndex)

        player:Say("Ayyy!")
        
        if player then 
            deactivateDivineProtectionB(player) 
        end

    end

end

local onPressButtonB = JoypadControllerData.onPressButton

function JoypadControllerData:onPressButton(button)

    dispelGraceGamepadB()

    onPressButtonB(self, button)

end```
vast veldt
#

So I can create and write files using the getFileWriter() call, and I can read files using the getFileReader() method - but is there any way I can delete files after I am done with them?

glacial flicker
#

How does one add extra functionality to an existing tile in the world? I had a crazy idea of hiding inside one of the big garbage cans

thick karma
#

Sometimes my shared folder doesn't load in Solo when mod testing... anyone know exactly why?

#

The lua is not visible

spark crystal
#

What is the correct name to provide for a sound, when creating a recipe?

It doesn't seem to match exactly what the filename in the media/sounds folder is

weak sierra
#

is there a reason one might code like this..

#
local functionName do
  local something = somethingElse

  function functionName()
    doStuff()
  end
end

function SomeOtherFunction()
  functionName()
end```
#

afaik do/end in this context just makes a new scope

#

but it has a name

#

and it's local

#

so is it actually an alternative way to define a function

#

or when i call functionName() is it just calling the inner one..?

#

why not just

#
local something = somethingElse

local function functionName()
  doStuff()
end

function someOtherFunction()
  functionName()
end```
#

ive got some code i inherited that im afraid to touch cuz i have no idea wtf they're doing with local functionName do wrapping

#

:p

astral dune
#

Lua syntax can be baffling and surreal at times. Why do they need so many ways to define a function? smdh

weak sierra
#

is it even equivalent tho?

#

ive only coded in lua for a few months and only for pz

#

i guess i can putz around on rextester

astral dune
#

no idea tbh

weak sierra
#

it appears to just act as a scope

#

and the "local" and name are pointless?

#

from quick testing

vague quiver
#

Any recommended mods?

thick karma
#

lol I just made one that makes you talk shit when you're killing zeds

#

shrug

#

(Comes as a trait)

#

@vague quiver

#

According to https://projectzomboid.com/modding/zombie/characters/IsoPlayer.html, players have a public field described as public boolean bJoypadMovementActive. I tried accessing this field on my player object and it through weird indexing errors. I'm not sure if it's a cache bug or a bug in the API. Does anyone have a few minutes to run a test for me and see if they can get a true or false response on that field?

astral dune
#

I'm glad there is so many lua resources online, because I have no idea how code like this works but it does ๐Ÿ˜‚

function Object:new(o)
  o = o or {}
  setmetatable(o,self)
  self.__index = self
  return o
end

What I'm really not clear on, because for some reason every tutorial I look at that does this always passes in nil , is what you would actually pass in to this function otherwise

weak sierra
#

after some research earlier im guessing the only way to add a command that the rcon has access to is a java mod, yeah?

weak sierra
#

i have no idea what the index thing does or exactly what a metatable is

#

lol

#

i think a metatable is like.. what the thing itself uses to describe itself

#

both per name and per usage

#

but

#

not specifically

bronze yoke
#

at a guess, it's for derived objects

astral dune
#

haha, this function is what is typically used to create a traditional "Object", so you can have seperate instances of the same thing, I just don't know what you would pass into it if you wanted to

bronze yoke
#
function DerivedObject:new(o)
  o = o or {}
  -- do some stuff to it
  o = Object.new(self, o)
  return o
end
astral dune
#

are you saying the o input is only there for creating derivatives?

weak sierra
weak sierra
#

it's a better guess than i had, which was "what if you want to provide a premade metatable though?"

#

which i guess is related, but less purposeful

#

lol

astral dune
#

I'm wondering, if I create an object like this and assign it to something as ModData, then later come back and load said moddata, if I would need to pass the moddata in to recontextualize it as an "object"

weak sierra
#

you could assign the metadata table to the moddata

#

since moddata is a table

#

i know it isn't typed cuz it's lua but im not sure "any random thing u throw in there" will work

#

at least not for persistence

#

but to more directly answer, yes

#

well wait.. no

#

everything is a table..

#

lua is weird

#

u could probably just put the whole thing in

#

and if u did that then no

#

but again it would probably not persist just anything

#

it persists just strings and numbers iirc

#

it'd temporarily hold it until u relog or restart tho

#

(client-side)

hearty dew
#

I doubt the moddata persistence handles function objects, which it would need to to persist objects like this (tables containing function objects)

#

It could, technically, do it. You can do it in regular lua (not kahlua). It is conceivable it is possible from the java side of kahlua since you could have access to dumping the function objects in a way that can be serialized

#

So, the answer is idk. Haven't tested it ๐Ÿ˜…

undone elbow
#

@hearty dew Thanks. But my goal was to get nearest players in MP on client.

#

Also I was trying to find the most optimised way to do it (with less calculations).

#

That's why there is choice what to loop.

weak sierra
#

you could almost undoubtedly find a pure lua lua serializer

#

and then persist strings fine

#

but it wouldn't be just dumping the object in the moddata raw

#

plus u dont wanna eat the whole moddata object anyway

#

just use one row

#

:p

hearty dew
#

The lua functions to serialize a function don't exist in kahlua. That was an issue I was facing when writing a way to hash a function to fingerprint it a few days ago

weak sierra
#

dont look for them in kahlua

#

just make your own

#

here's a pile of different options

undone elbow
#

To find nearest players on the server is still an issue, because you still have to deal with getX(), getY or DistTo() to check whether it's near or not. Well, not an issue but it seems not optimised for me.

weak sierra
#

you could cache player position periodically

#

throttled

#

to minimize impact

#

and update it on OnPlayerMove

#

like every min or smth

#

less even

#

i run a check every 7 seconds on OnPlayerMove that is position dependent and have no real issues

hearty dew
# weak sierra just make your own

to serialize functions, you'd need lua standard library functions (e.g. string.dump which kahlua doesn't implement). You'd rely on the lua std library to make your own, but the full std lib is missing in kahlua. That's what I'm getting at

weak sierra
#

yeah, i just mean "it should still be doable in some way"

#

:p

#

i realize kahlua is limited

hearty dew
undone elbow
#

OnPlayerMove and OnPlayerUpdate are too high-load in terms of optimization...

weak sierra
#

mm

#

u could javamod the server to expose players.db access and then use that MD_Troll

#

lol

#

performance-wise the real answer is "Read players.db"

#

it costs very little to go "is condition false? no? ok." though

#

so throttling on an update like OnPlayerMove is not a big deal, though if you prefer you could do polling from a method like EveryMinute

#

or whatever it's called

#

and poll each player's position

#

or push it from the client to the server

#

and store it in a table

#

or global moddata

#

and then pull from there when necessary

#

either way what u wanna do is build ur own database

#

and then query that

#

what are you planning to do anyway

drifting ore
#

who r u talking to

weak sierra
#

star

#

the radar mod i run on my server (shows players on map pre-41.73 but also adds new functionality to it post) has a feature for only showing players within N tiles

#

zero is a decent coder, wonder how they went about that

drifting ore
#

hmm yeah

hearty dew
#

Anyone have a write up or explanations on how the coordinate system(s) work in pz? tiles, cells, chunks, regions, etc

undone elbow
#

getX, getY return just tiles

#

getCell() is a kind of getMap(), imo

frosty orchid
hearty dew
#

The code (presumably) uses some code from NPCs/MainCreationMethods. Assuming that, require ensures that that required file is loaded before running the code below it.
If it were the case that the mod's file loads before NPCs/MainCreationMethods and require were not there, that would cause an issue due to using variables that are not yet initialized during the loading of NPCs/MainCreationMethods.

#

It so happens that pz loads lua files thusly: lua files in shared/, then lua files in client/ (this is skipped for servers), then lua files in server/. Within each of those 3 sets, the vanilla files are loaded alphabetically based on the path name (if a mod file has the same path as a vanilla file, it loads that instead), then mod files are loaded alphabetically based on the path name.

#

One option is to rely on that behavior

#

Another option is to explicitly require the files that you need loaded before your code is run

frosty orchid
shadow geyser
# frosty orchid I'm looking at the example for creating a traits mod here: https://github.com/Mr...

pretty sure the require('NPCs/MainCreationMethods') isn't actually needed. The reason why is because vanilla files, are all loaded before mod files. so the require statement in this case doesn't do anything. however it might be put there just for readability. anyone now reading it, knows that that file logically needs the maincreationmethods file to have been executed first, even if that line isn't technically needed to enforce that fact.

frosty orchid
frosty orchid
#

how would I add foraging effects to traits?

frosty orchid
#

anyone know what the forage definitions are for fruit, wild herb and packaged food?

#

im thinking packaged food is JunkFood, no idea what the other two are, but if I had to guess, maybe Fruits and WildHerbs?

#

also dont know what id firewood would fall under too

frosty orchid
#

what dimensions should poster.png be?

glad ridge
#

256 x 256

frosty orchid
#

ty

proven light
#

can you access all java classes from lua or only some?

proven light
#

nvm i found the exposed classes in zombie.Lua.LuaManager$Exposer

late flax
#

Is it able to write a mod to simply reduce all kinds of player damage?
Since mod weapons are too strong, finding a way to balance them, but modifying all stats of mod weapons is not practical

gilded hawk
thick karma
#

Sure. Try driving, try reading, and hit a poll with crash damage on

glad ridge
#

10/10 Will do again

thick karma
#

Lol you just did that?

glad ridge
#

no, just joking but I almost killed myself continuously crashing into trees in my McLaren like an hour ago haha

dire yacht
proper garden
#

Apologies. It's like 6:30 here and I haven't slept yet. If I need a bit of help with a mod I'm working on then do I ask here or the mod_support channel?

hearty dew
#

This channel is for dev help

#

mod_support is more for help using mods

proper garden
#

ah gotcha

hearty dew
#

so ask here :)

proper garden
#

Well I feel super silly and like something is going completely over my head here but. I watched a few videos and one of the guys uses notepad++ and it looks like he has intellisense working. However I have no idea how he is importing the java files into notepad++ so that the lua can access all those functions.

#

I did find a decent tutorial that requires IntelliJ and I'll do that if I need to. Just feels like I'm missing something here.

hearty dew
#

My guess is it is a plugin he has or created. Or perhaps he has opened some source files and notepad++ is using words from those files to fill auto-completion. I haven't messed with notepad++ that much, so I'm unsure

proper garden
#

Ah yeah you're probably right.

#

Thank you very much ๐Ÿ˜„

thick karma
#

@hearty dew I figured it out!

(Joypad button press detection example, feel free to use everyone).

-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! THIS **** RIGHT HERE
require ("JoyPadSetup")
-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! THIS **** RIGHT HERE

local onPressButtonReplacementB = JoypadControllerData.onPressButton

function JoypadControllerData:onPressButton(button)

    for playerIndex = 0, getNumActivePlayers() - 1 do
        
        local player = getSpecificPlayer(playerIndex)
        
        if player then

            -- Do Stuff

        end

    end

    onPressButtonReplacementB(self, button)

end

Testing notes: using onPressButton above "works", but causes two signals to be sent every button press. Using onPressButtonNoFocus will only get one signal. Obviously there are methods by which the double-signal from onPressButton could be ignored, but that could cause issues.

thick karma
#

Quick question: Best (most resource efficient) way to wait 1-2 real-life minutes regardless of server time before triggering an event?

hearty dew
#

It's lua. That means you have to build your own everything, including basic systems functions gygaxhappy

#

Someone posted something that polls on OnTick.. trying to find it. Not super resource efficient, but being lua, you don't have access to OS timers, so not sure there's a much better solution tbh

#

@thick karma

drifting ore
#

Anyone know a mod where depression kills, like you shoot yourself or slit yo wrists?

hearty dew
drifting ore
#

kk

hearty dew
thick karma
#

Was hoping not to do math lol also didn't wanna have to find the dang time speed variable I'll need to learn to interpret

bronze yoke
#

so you just added a require and it worked?

thick karma
#

Yep

#

It was using local variables from that file

#

Needed access to them, too

#

To prevent weird issues on taking over the function

#

So yeah soon I'll be releasing Meditation! Just gotta get the timer to be game-speed independent

#

Seems comparitively easy because I sorta know what to do there

#

Vaguely

#

Become invisible by sitting. For use going AFK offline without disconnecting from server. Plan to only allow it if a zombie has not recently seen you when you start. Already designed it to break if you take action after it activates.

bronze yoke
#

i don't think that's how require works... i really don't get why this works but i'm glad it does anyway

thick karma
#

Well I could be wrong about why it worked, but I tried it as a shot in the dark and the errors went away

bronze yoke
#

i'm trying to make sense of this but i've decided to just accept that some things were not meant to be understood

thick karma
#

Maybe you can run it both ways as a test, study the debug, and get more out of it than I did

#

Basically, I noticed cerain variables called in the function I mod were causing exceptions to be thrown from null errors, so I figured somehow variables were not visible that needed to be, so I tried that.

thick karma
hearty dew
thick karma
#

I figured RenderTick was muuuuch slower

#

Wouldn't rendertick be like 60 times a sec or something nnormal?

hearty dew
#

They both seem to be fired each frame. OnTick just stops firing when the game is paused I think

thick karma
#

Oh crap

hearty dew
#

and in game menus, I'm guessing by the code. Haven't tested that

#

but while in game, they fire at the same rate, each frame

#

OnRenderTick is each frame. OnTick is each frame while the game world isn't paused

ancient grail
hearty dew
#
LOG  : General     , 1665419532157> ontick 1665419532157 10866
LOG  : General     , 1665419532164> onrendertick 1665419532164 nil
LOG  : General     , 1665419532174> ontick 1665419532174 10867
LOG  : General     , 1665419532182> onrendertick 1665419532182 nil
LOG  : General     , 1665419532190> ontick 1665419532190 10868
LOG  : General     , 1665419532197> onrendertick 1665419532197 nil
LOG  : General     , 1665419532207> ontick 1665419532207 10869
LOG  : General     , 1665419532214> onrendertick 1665419532214 nil
LOG  : General     , 1665419532224> ontick 1665419532224 10870
LOG  : General     , 1665419532232> onrendertick 1665419532232 nil
LOG  : General     , 1665419532240> ontick 1665419532240 10871
LOG  : General     , 1665419532247> onrendertick 1665419532247 nil
thick karma
#

I see... Thanks for the info

hearty dew
#
LOG  : General     , 1665420143429> onrendertick 1665420143429 nil
LOG  : General     , 1665420143445> onrendertick 1665420143445 nil
LOG  : General     , 1665420143462> onrendertick 1665420143462 nil
LOG  : General     , 1665420143479> onrendertick 1665420143479 nil
LOG  : General     , 1665420143496> onrendertick 1665420143496 nil
LOG  : General     , 1665420143512> onrendertick 1665420143512 nil
LOG  : General     , 1665420143529> onrendertick 1665420143529 nil
LOG  : General     , 1665420143545> onrendertick 1665420143545 nil
LOG  : General     , 1665420143562> onrendertick 1665420143562 nil
LOG  : General     , 1665420143579> onrendertick 1665420143579 nil
LOG  : General     , 1665420143596> onrendertick 1665420143596 nil

and while game is paused

ancient grail
#

i wish the modding chat becomes a modding category with all the various topics and what not... it would be alot easier for us to categorize stuff and be able to quickly share what we know abt a certain part of modding

thick karma
#

I actuslly don't think I will need to use OnTick at all. I don't need it to be that precise. Once a minute in game will be fine

hearty dew
#

If you need in-game minutes, there is an EveryMinute event (or spelled similarly)

#

I thought you mean irl minutes

thick karma
#

But I want the activation to track time since last zombie spotted me.... Already have the function for that but needs converted to RT

#

I can trigger the event on in game minutes but I want a condition on event activation that is based on real time

hearty dew
#

Honestly it likely isn't a big issue doing a bit on each frame. At 60 fps, each frame is 16ms. Doubt you need anywhere near that much time

ancient grail
#

wait sorry what r u building again? @thick karma

#

i thought ur done with the walk read mod

thick karma
#

Sorry I can't remember I talked to you about this one my bad for pinging if not

thick karma
#

Doesn't get much faster

#

However if I can avoid it and leave that time available for other modders with more important OnTick stuff, I will

ancient grail
#

only for zed? or players wont see you too?

thick karma
#

Honestly I need to test that but I have no friends who play with me often lol but I imagine the setInvisible function only refers to Zeds seeing you

#

I do not disappear on my own screen so I assume that isn't how it works

#

I may also add God Mode to the state so players can't kill you

ancient grail
#

not sure really its weird on mo
if u set one of em the other one also changes
imean ghost and invi

thick karma
#

Or maybe have two versions

bronze yoke
#

i think it makes you invisible to non-admins

#

unsure exactly, who knows what the difference between invisible and ghost mode is lol

thick karma
ancient grail
#

but will it make u invi really have u done that part of the script where u can atleast togle invi using a non admin acc?

thick karma
#

I am doing it in Solo r.n.

#

Multi may requure anti cheat disables

#

Not sure yet what will be needed

ancient grail
#

well u will have to rework it for mp if u plan the mod to be mp compatible
its alot diffrent

btw theres a mpd that lets u camo using blood . like n TWD
ya might want to check that out

thick karma
ancient grail
#

i guess but invi is admin power tho

summer rune
#

Can i add a helmet item definition with BulletDefense ? Or is this not doing anything, since i can not find any mod with bullet protection for helmets?

thick karma
ancient grail
#

i spawned it once on a server event using debug console
so no mod needed for that

but yeah if it worked on debug would dfntly work as mod

summer rune
#

i guess i have to make my own helmets then ๐Ÿ˜„

ancient grail
#

local head = InventoryItemFactory.CreateItem("Base.Hat_CrashHelmetFULL");
local bag = InventoryItemFactory.CreateItem("AZ.Bag_RoadsideDuffel");
head:setName("SOS Ratrace Event Helmet"); 
head:setCondition(70);
head:setBiteDefense(100);
head:setScratchDefense(100);
head:setBulletDefense(50);
bag:getItemContainer():AddItem("Brit.Hat_Helmet_Headset");    
bag:getItemContainer():AddItem(head);    
getPlayer():setWornItem("Back", bag);
getPlayer():resetModel();```
ancient grail
summer rune
#

thank you, that is a good starting point.

errant bluff
#

Does anyone have the code for the wet towel? I can't find it

balmy glacier
#

is there any way to determine if a zombie has been reused via modData? i can't find any value i can set so i can find out if this zombie has been reused against previous set modData. since there is no onZombieSpawn lua event i try manipulating the zombie inventory whenever i get a new zombie. onTick -> getCell() -> cell.getZombieList()

ancient grail
balmy glacier
# ancient grail what r u trying to build?

i'm the author of worse zombie loot condition https://steamcommunity.com/sharedfiles/filedetails/?id=2867084324 it worsens the condition of zombie clothing etc. onZombieHit and onZombieDeath but i try to find a way to worsen the condtion of these items on spawn or some other way. with my current solution i iterate through all zombies in a cell an worsen the conditions. problem is that i need to skip those zombies that already have been affected. problem is there is no way i know of to again worsen the condition of a zombie that has been reused and his inventory was reset

#

maybe there is an completely easier way on doing this but i just started studying the java code and available lua events

ancient grail
#

maybe you can look at how it spawns in the first place and do something as it spawns or after

thick karma
#

Not 100% sure where you'll find it in the LUA but you don't necessarily need to see find a way to use it

#

You could just call its copy from a duplicate and add your own extra stuff, or even rewrite it if necessary

bronze yoke
#

you can't rewrite java functions, i'm afraid

thick karma
#

It may not exist but I haven't found something yet that didn't exist somewhere in a LUA

#

Not always class defs onv

#

Obv

#

But corresponding functions and events

low sky
#

god fucking damn i wanna use storm api so bad i don't wanna learn lua

#

but i don't understand how to set up a project with it ๐Ÿ˜ญ

undone elbow
#

It takes 15 minutes to learn Lua.
But it'll take forever to learn PZ API.

proper garden
#

Yeah LUA isn't a bad place to start if you're newer to coding. Also it doesn't require compiling so that's a huge plus when you're modding.

proper garden
#

Which IDE do most people seem to use for modding?

undone elbow
#

notepad ๐Ÿ˜

ancient grail
proper garden
#

Are you guys able to get intellisense working with those? Well at least notepad++ haha.

ancient grail
#

not even sure what it does.. i think installed it but i dont feel the difference. does it show tips or posible autocomplete? ireally didnt notice

proper garden
#

Yeah it does for the most part I think. It can be convenient so you don't have to switch screens to look up a function name or something along those lines.

low sky
#

try out intellij

#

that's what intellisense is copied from

#

it just helps you with functions and if it is good like in intellij it will fix your code for you

#

like if there is a better way to do a lil bit of code it will simplify it for you

proper garden
#

Yeah that's what I've been trying to set up today but it keeps freezing. Just giving myself a break mentally before trying again XD

low sky
#

if you want a easy thing to try with intellij just try minecraft

#

there is a intellij plugin you can download that will set up a pre made empty mod for you

ancient grail
low sky
#

for mc stuff

proper garden
proper garden
thick karma
#

Opens almost as fast as vanilla notepad, but not blinding

#

Notepad++ opens a little slower in my experience

thick karma
low sky
#

why are you trying to tell me to look at lua mods

#

i don't wanna make lua mods

#

storm api is java

thick karma
#

Why are you so resistant to LUA? It's all the same...

low sky
#

why should i have to jump through hoops to access the same methods and functions

thick karma
#

I mean is there a way to mod this game using Java?

low sky
#

storm api

thick karma
#

That works for PZ?

thick karma
# low sky storm api

I see now, I misunderstood you as replying to other people, thinking you didn't know how to set up a project in LUA... I thought Storm wasn't available or something and you were down about it... Now I see. Seems like a cool API.

low sky
#

yeah it's a cool api i just need to figure out how it works

#

and ye now you can see what i mean

#

i would rather not jump through extra hoops if i could

#

i REALLY just wish the devs would give us native java mod support

#

that would be super cool

proper garden
#

Agreed!

thick karma
#

Maybe someday but I think there's a good chance it'll be awhile with how much they have on the agenda

low sky
#

it's really not a difficult thing to implement

#

they also can't really use the excuse of not wanting us to see the code since we can already just decompile the game anyway

austere finch
hearty dew
#

In other words, is the tweaker api attempting to apply your change and failing? Or is it not even attemping?

austere finch
#

Not even attempting, mine don't surface in the console for those items

#

But I've been successfully applying to several hundred items, many of which are from the same sources as the ones that won't budge; it's baffling.

hearty dew
#

You might check if you have some mods that are overwriting the API and causing issues. Better sorting does that. I have a mod to remove better sorting's implementation (but that's because it was causing the tweaks to be applied twice, not be not applied). But your situation might be different

hearty dew
#

See what, if anything, changes

#

It should change. It should change the field that contains the category tweak from the previous value to your new value

#

Do you need something to print out tables?

austere finch
#

In my case I'm trying to accomplish it with Better Sorting's copy of it (applying via ItemTweaker_Copy_CC); I'm not familiar how to print them out, admittedly.

hearty dew
#
GaistUtils = GaistUtils or {}

GaistUtils.InspectMetatables = GaistUtils.InspectMetatables or true
GaistUtils.InspectDefaultDepth = GaistUtils.InspectDefaultDepth or 3
GaistUtils.InspectTableIndentWidth = GaistUtils.InspectTableIndentWidth or 4

GaistUtils.inspect = function(t, depth)
    if not depth then
        depth = GaistUtils.InspectDefaultDepth
    end

    local table_cache = {}
    local function inspect_impl(t, depth, indent, prefix)
        local indentLead = prefix and "." or " "
        prefix = prefix or ""
        depth = depth - 1
        local tableIndent = indentLead..string.rep(" ", GaistUtils.InspectTableIndentWidth - 1)
        local prefixIndent = string.rep(" ", string.len(prefix))
        if type(t) == "table" then
            if table_cache[t] then
                print(indent..prefix..tostring(t).."  ** PRUNED. Cycle/duplicate detected **")
                return
            end
            if depth < 0 then
                print (indent..prefix..tostring(t).."  ** PRUNED. Max depth reached **")
                return
            end

            table_cache[t] = true
            print(indent..prefix..tostring(t).." {")
            for k, v in pairs(t) do
                inspect_impl(v, depth, indent..prefixIndent..tableIndent, "["..tostring(k).."] => ")
            end

            local metatable = getmetatable(t)
            if GaistUtils.InspectMetatables and metatable ~= nil then
                inspect_impl(metatable, depth, indent..prefixIndent..tableIndent, "<METATABLE> => ")
            end

            print(indent..prefixIndent.."}")
        elseif type(t) == "userdata" then
            local metatable = getmetatable(t)
            if not GaistUtils.InspectMetatables or metatable == nil then
                print(indent..prefix.."("..type(t)..") "..tostring(t))
                return
            end
            if depth < 0 then
                print (indent..prefix.."("..type(t)..") "..tostring(t).."  ** PRUNED. Max depth reached **")
                return
            end

            print(indent..prefix.."("..type(t)..") "..tostring(t).." <")
            inspect_impl(metatable, depth, 
                    indent..prefixIndent..indentLead..string.rep(" ", string.len("("..type(t)..") ") - 1),
                    "<METATABLE> => ")
            print(indent..prefixIndent..">")
        elseif type(t) == "string" then
            print(indent..prefix..'"'..t..'"')
        else
            print(indent..prefix..tostring(t))
        end
    end

    inspect_impl(t, depth, " ")
    print()
end
GaistUtils.inspect(TweakItemData)
print("calling TweakItem")
TweakItem("Base.Itemname", blah, blah)
GaistUtils.inspect(TweakItemData)

Would see if the field on the TweakItemData table changed or not

austere finch
#

Very kind of you, thank you!

thick karma
low sky
#

fr

#

they just bums

#

๐Ÿคฃ

thick karma
#

Unfortunately when you have a stack of 2000 easy jobs to do, you suddenly, paradoxically, have an impossible job to do.

#

I think a bunch of people want a bunch of things from them and they are a small crew

#

I'm just glad they enabled LUA modding or some modding at all, because the community of free devs saves this game from being (A) boring (B) a victim of an opinionated and small group of people.

#

E.g., we cannot read and walk in vanilla because an opinionated small group of people agreed we can't

low sky
#

if* they add java modding

thick karma
#

That is bad

low sky
#

it would open a huge community up

thick karma
#

I hear you, but, tbh, I think LUA is more accessible to new programmers

#

I learned Java first and like Java and in fact tutor intro Java online

#

So I am not a hater

low sky
#

you really shouldn't be a new programmer trying to make mods ngl

thick karma
#

I am relatively new to LUA

#

But LUA allows new programmers to avoid certain complexities that every Java programmer must understand

thick karma
#

I think modding is the perfect way for kids to learn to program

#

It's much easier than designing a standalone app

low sky
#

i actually can't disagree with you more

thick karma
#

Some of my youngest students learned to program in order to mod games

low sky
#

nowadays devs make it impossible to learn how to even start making a mod for their games

thick karma
low sky
#

if you don't have at least some level of exp it is next to impossible to even start

thick karma
#

If I could not disagree with you more, it follows that you also are at max disagreement from me, insofar as I'm right

#

So sort of we just agreed

low sky
#

if you're lucky you might have a small wiki page like pz

low sky
#

that is so cringe

thick karma
# low sky if you're lucky you might have a small wiki page like pz

Most games, you're right. Games with poor modding doc are not the easiest things to mod, but nevertheless modding certain games can be highly educational. Keep in mind kids know how to use YouTube these days, and experienced devs make instructional vids that those kids watch

#

And they do learn things they're told, though not everything obv

#

But I don't know any adults who learn everything they're told either

#

We learn what we can when we're ready and it's important to us

low sky
#

the only two i have found so far that have been open to helping with issues are mc and pz

thick karma
thick karma
#

Yes, there are limitations

#

Yes, making your own app can teach much more

#

Infinitely more

#

But saying that it teaches nothing to mod a game is wrong

#

If it's true for you, that's just because you have nothing left to learn from doing it

low sky
#

bro what

thick karma
#

Keep in mind, kids spend years learning to make a's.

low sky
#

putting stuff in my mouth much???

#

when did i ever say you don't learn anything from making mods

thick karma
#

Your words were literally impossible and anything at all

#

Lol

#

Just... Reading what you're saying

#

Not trying to put words in your mouth

low sky
#

ew

#

did you actually just...

#

in a convo

thick karma
#

Sorry, almost* impossible, but still wrong.

#

Actually learning something from modding is easy for open-minded kids

low sky
#

your opinion

thick karma
#

The opposite of almost impossible

low sky
thick karma
#

I mean, yes, in my opinion a thing many 12-year-olds can do is not almost impossible

low sky
#

can i ask how old you are?

thick karma
#

But we are each free to use the phrase "almost impossible" according to our own interpretation

low sky
thick karma
#

Old enough not to think it's almost impossible for a kid to learn from modding, and to be tired of kids asking how old I am?

low sky
#

good to know

#

you don't actually have any real world exp

thick karma
#

๐Ÿ˜‚

low sky
#

i will continue this convo with the idea that you are 15

#

until you state otherwise

thick karma
#

I have helped multiple people acquire Master's Degrees and others acquire well-paying jobs in programming, if you really want to know

#

But that's beside the point entirely

low sky
#

that's cool

thick karma
#

Speaking from authority, age, etc. is not logically defending the accuracy of anything

low sky
#

i own a business that made over 2.5m in profit last year :)

#

but that''s beside the point entirely

thick karma
#

Congratulations, as I said, "Speaking from authority, age, etc. is not logically defending the accuracy of anything."

#

That's not how science, logic, or facts work

#

Or causality for that matter

#

Causality doesn't care how much money you made last year any more than I do...

low sky
#

age can show you the emotional maturity of someone

#

and just how their are kids that are more mature then some adults

#

there are some adults who are more immature then some kids

thick karma
#

And asking someone's age in the midst of a conversation about facts and psychology can show not only the emotional age of someone, but their intellectual ability, as well.

#

What is your point?

low sky
#

you wear glasses don't you?

thick karma
#

๐Ÿ˜‚

low sky
#

i am waiting for my wife to finish dinner

thick karma
#

Congratulations

low sky
#

while coding a small game

#

if there is nothing else you wanna say ill just leave it here peace gonna go work on this yk how to contact me โ˜ฎ๏ธ

left plank
#

that seems to have resolved, but if you're going to argue in the future just take it to DMs please ๐Ÿ™‚

hearty dew
undone elbow
#

How does player:getOnlineID() work? Is it unique and immutable?

hearty dew
#

When I was testing it (with only 2 clients, each with 2 split screen players, so 4 players total), the online id was unique and consistent across the server and the 2 client processes

#

I didn't test relogging to see if the id remained the same

#

I think the java server-side had an id->player association stored in a data structure.. I looked at it the other day, but memory is vague now though, I'm not positive now ๐Ÿค”

#
function printOnlinePlayerInfo()
    for _,p in pairs(LUtils.getPlayers()) do
        print(string.format("isServer=%s name=%s onlineid=%s",
            tostring(isServer()),
            tostring(p:getDisplayName()),
            tostring(p:getOnlineID())))
    end
end
LOG  : General     , 1665463671898> 876,781,845> isServer=false name=testnerd onlineid=0
LOG  : General     , 1665463671905> 876,781,852> isServer=false name=Player2 onlineid=1
LOG  : General     , 1665463671913> 876,781,860> isServer=false name=admin onlineid=4
LOG  : General     , 1665463671922> 876,781,868> isServer=false name=Player2g onlineid=5
LOG  : General     , 1665463680752> 876,790,703> isServer=true name=testnerd onlineid=0
LOG  : General     , 1665463680752> 876,790,703> isServer=true name=Player2 onlineid=1
LOG  : General     , 1665463680752> 876,790,703> isServer=true name=admin onlineid=4
LOG  : General     , 1665463680753> 876,790,704> isServer=true name=Player2g onlineid=5```
#

The way the server stores players is in blocks of 4 for each client (because each client can have 4 local split screen players). So making (perhaps a bad) assumption from those numbers, the server assigns 0-3 to one client (for each of its 4 possible players), 4-7 to the second client, etc

#

Don't think it's safe to really assume that in lua code though, but that makes sense with what I saw when looking through the server-side java code

austere finch
hearty dew
#

If it didn't, I'd dig into what exactly is going wrong when calling the TweakItem() function.

If it did, I'd dig into what exactly is going wrong when the even handler function (ItemTweaker.tweakItems()) is called when the OnGameBoot event is raised.

#

You can stick some print statements in ItemTweaker_Copy_CC.lua to help debug this btw

#

to triangulate what the issue is

austere finch
#

Trying to narrow down to even just one item to figure it as an example

    {
        DisplayCategory = Material,
        Weight    =    0.3,
        Type    =    Normal,
        DisplayName    =    Box of Rubber Bands,
        Icon    =    RubbersBox,
        WorldStaticModel = RubberBandsBox_Ground,
    }```
From LeGourmetRevolution -> 'TrapItems.txt', module is Base, there is no other external ItemTweaker prompt to affect this item but mine.  I req ItemTweaker_Copy_CC and getActivatedMods for 2719327441 which is accurate to Snake's mod, which includes LGR.  I flag ```TweakItem("Base.RubberBandsBox","DisplayCategory","Crafting");``` but it winds up Material in-game.  In this case I tried to call out Base.RubberBandsBox in the logging util and it threw a stack trace error on me instead.
hearty dew
#

but it winds up Material in-game.
Let's try to look at each step of what the tweak item api does to find where/what is going wrong.

Can you try printing the contents of TweakItemData before and after the call? What is the field for "Base.RubberBandsBox"'s "DisplayCategory" before and after your call of TweakItem?

The answer to that will inform the next step

austere finch
#

Oh for pity's sake, I added a secondary 'or getActivatedMods' specifically for LGR and it seems to have budged -- I was sure that workshop ID was a valid check on that, but it seems in that instance it wants to go all or nothing on subordinate modules for getActivatedMods. Now I'm getting an IGUI_category missing translation style entry when it should be picking up on it, but progress

#

That's an easy whoops, ItemTweak w/ Better sorting's category defs wants Craft instead of Crafting

#

This feels very 'did you plug it in?' now

hearty dew
#
if getActivatedMods():contains("modid") then
  -- stuff
end

fyi, you use the mod id (not workshop id) with this api, btw

austere finch
#

I'd typically had both but had the mistaken assumption I could include workship ID as a catch-all

#

Now I need to puzzle out some missing / needed category additions for better better sorting coverage. At this point I've covered something like 1500 items across 50+ mods not previously supported by Better Sorting / patches thereof

soft jetty
#

Hey! i have a quick question, and i can't find an answer. If the Engine Loudness is 100, what means that in the game? If i drive backwards at max rpm, which distance to be heard is possible?

austere finch
#

I also still need to puzzle out a more sane way of trying to dynamically capture and include like-items in recipes that can pop up across different mods -- like the dozen different variations of empty cans that appear to be the same at first glance to a player but have a kaleidoscope of which ones you can crush, recycle into scrap, recycle into aluminum, etc.

hearty dew
hearty dew
#

And an unknown list of other things related to those added items the mods could potentially have added, specially handling of their versions in lua, for example

austere finch
austere finch
hearty dew
#

For example, with the mods I have atm, it takes ItemTweaker.tweakItems() 20 seconds to run through everything and apply the tweaks OnGameBoot

#

(and because of the way BetterCC implemented their item tweaker api, they cause it to double to 40 seconds. BetterCC registers a duplicate event to OnGameBoot causing it to run twice)

austere finch
#

For the sake of experiment I tried doing a test setup where I disabled BetterCC's redundancy on that and just ran everything through a normal single run but didn't find a load time difference with stopwatch comparisons

#

If you really want a headache there's actually at least two other renamed variations of ItemTweaker besides BetterCC's ItemTweaker_Copy_CC which -also- queue OnGameBoot

hearty dew
#

Yea, I looked into those too. BetterCC's is a problem because they renamed the file. The others that I have installed, didn't rename the file, so pz only loads one of those

#

If there are multiple lua files with the same path, pz will only load the one latest in the mod load order

austere finch
#

01.ItemTweaker_Core.lua and ItemTweaker_Copy_ogsn.lua also exist among mods as renamed files which load OnGameBoot independently.

#

I went down a rabbit hole ferreting out rogue copies of itemtweaker

hearty dew
#

Mm, I don't believe I have those mods, but yea, that's something to watch out for, if you are concerned about the game boot time

austere finch
#

At a point I made a dummied-out killswitch mod that just had the variations of itemtweaker's renamed lua commented out as an end of load order override

hearty dew
#

I solved the issue with my own mod that overwrites those duplicated item tweaker API files

austere finch
#

But that is hardly ideal or something I'd want to sustain, I was curious to see the material difference in redundancy load time

#

For the record, EliazBetterBags & Backpacks is a pretty popular / commonly installed mod example that also has its own copy of ItemTweaker (01.ItemTweaker_Core.lua)

#

Fx Clothes Tweaks has that same renamed lua

#

The OGSN one is found in An Exhilaratingly Organized Literature Mod which is also pretty widely circulated

#

with like almost 300k subscribers

hearty dew
#

It's pain for everyone and annoying to me bc I can't just send a pull request to them to fix all those issues with how steam workshop is set up lol

austere finch
#

OGSN's may be better or worse because it deviates from the normally just renamed itemtweaker cores in that it appends data instead of replaces it, so that it'll stack with other copies of itemtweaker mucking with items

hearty dew
#

I tried posting to a discussion thread about the issue in the BetterCC mod, but it probably won't be seen/read

austere finch
#

I wound up making my patch compilations because BetterCC wasn't implementing pull requests anymore near as I could tell

#

Someone did the legwork for like 200 items for LeGourmentRevolution to append to BetterCC's built-in mod support and it sat there for a long time

hearty dew
austere finch
#

function ogsnItemTweaker.tweakItems() is what they use actually / OGSNTweakItem/ OGSNTweakItemData etc.

hearty dew
#

Ah, then their modifications are isolated from affecting other mods in some ways (the file load order is still an issue, but that is more manageable)

#

What you're working on sounds useful though. It's something I'd like to use. I had the idea of adjusting some item categories myself, but stopped after one or two items and got distracted with other things :p

austere finch
#

Only by virtue of OCD and way too much focus have I been able to go through as much as I have but it has been a gigantic rabbit hole. It started with noting a handful of items that came from newer mods that weren't following the categories at first and then spiraled out to more and more branches of 'Oh, that mod also includes two magazines with recipes' or 'There's weapons not categorized in this mod.' Where I'm brushing into debatable territory is starting to broach new categories in the same spirit as the base BetterCC ones for things that a lot of newer mods have broached that could use them -- which is what wound up butting my head against trying to puzzle out why I can't override a category BetterCC did set on some things, having just re-confirmed that the damn rubber ducky refuses to budge still.

#

the other big one I am on the fence on is there are a lot of situations with things that are both a tool and a weapon -- which in some cases are just vanilla items that way, but then you have some mods that will make tools into weapons too, and then you've got some bigger newer mods with intentional tool-weapons and there's not reaaaaally a category solution for that, since you can't affix multiple categories to something. So you're left with picking one of the two, or making a new combined category, and then deciding which should go first and so on.

#

it's all proven to be enormously time consuming, but if it saves other people a headache or makes things feel more cohesive in the end, all the better

hearty dew
#

Yea, there's a lot of leg work involved, leg work that could be parallelized, like where you have multiple contributors sending pull requests. Unfortunately, it sounds like BetterCC isn't moving along in that direction anymore, or has slowed

austere finch
#

I'm just the weird fool who spent the many many hours deciding I did in fact want to apply Media - Audio to 350 True Music tracks like some kind of putz

#

Pomp's items was another example since it advertises 50 food items but in reality it's actually 264 damned TweakItem entries haha

hearty dew
#

re: the ducky question, I'd

  • verify via logs that only one call to setting the ducky category is occurring (the old ItemTweaker api prints them out. Idk what all the modified versions do, but you could add prints to them for debugging purposes, if they don't have them)
  • verify that the ItemTweakData table field is changed when you call the api
  • if ItemTweakData is changed, track down what might be changing it by adding a conditional to TweakItem e.g.
function TweakItem(itemName, itemProperty, propertyValue)
  if itemName == "Base.Rubberduck" and itemProperty == "DisplayCategory" and propertyValue == "Junk" end
    error("How dare you, sir")
  end
    if not TweakItemData[itemName] then
        TweakItemData[itemName] = {};
    end
    TweakItemData[itemName][itemProperty] = propertyValue;
end
austere finch
#

I think I may have misconstrued how to set up the second parameter set you sent me earlier which is how I wound up getting stack trace errors off it

#

speaking of which my continual quest to try to fix the stack trace errors of -other- mods feels fruitless

hearty dew
#

Well, except one. The author said he isn't going to fix it because it is harmless. -_- I need to get around to fixing that one yet

austere finch
#

There's a trio of persisting ones I've tried to alert their respective modders to (for Rabbit Hash, KY, the SecretZ mod and Duck's Shark and Brita's Compatibility Patch) but beyond that I'm encountering them with context menu opening on fuel containers and that's likely a FuelAPI or some other

hearty dew
#

Oh, I haven't come across those yet (fuelAPI, rabbit hash) or don't have the mod (the rest)

austere finch
#

that's off the cuff guessing re: the fuel one, I just noticed it recently popping up and need to go do more thorough testing and checking on the when or why

austere finch
#

re:

print("calling TweakItem")
TweakItem("Base.Itemname", blah, blah)
GaistUtils.inspect(TweakItemData)```
hearty dew
#

Oh, I added a line the top that I initially forgot. Might be that

#
GaistUtils = GaistUtils or {}
austere finch
#

of the other trio

ERROR: General     , 1665463056995> ExceptionLogger.logException> Exception thrown java.lang.RuntimeException: attempted index of non-table at KahluaUtil.fail line:82.```
They're generally all non-table errors
hearty dew
#

I forgot to initialize GaistUtils

hearty dew
austere finch
#

I will have to mess with it more tomorrow, but I am pretty curious which mods you run in general just for comparison

hearty dew
# austere finch I will have to mess with it more tomorrow, but I am pretty curious which mods yo...
28dayslater
80kz1000
82oshkoshM911
85merc
86oshkoshP19A
88golfMk2
88jettaMk2
89def110
AAApoc
ATA_Bus
ATA_Jeep
ATA_Petyarbuilt
AliceSPack
AquatsarYachtClub
Arsenal(26)GunFighter
AuthenticAnimations
AwesomeTime
BBVehicles
BB_Throwables
BB_Utils
Barco Abandonado
BarricadedWorld
Basements
BatesMetalicosRevived
BedfordFalls
BetterFlashlights
BetterSortCC
Brita
Brita_2
Chestown
CleanDirt
ClothesBoxRedux
Computer
ComputerClassicsGamePack
ComputerCorporalsGamePack
CraftHelperContinued
CrashedCarsMod
CustomMapBridge
DD_Zombie
DLTS
DRAW_ON_MAP
Diederiks Tile Palooza
DylansTiles
EasyConfigChucked
EerieCountry
ExpandedHelicopterEvents
ExtraMapSymbols
ExtraMapSymbolsUI
FH
FRUsedCars
FRUsedCarsNLF
Factory
FencingKits
FuelAPI
FuelTanksMod
Grapeseed
HandmadeWeapons
ISA
ImprovisedBackpacks
ItemTweakerAPI
LeGourmetRevolution
LongLifeBulbs
LootZetaEnhancedEdition
MapLegendUI
MapSymbolSizeSlider
MilitaryComplex
MiniHealthPanel
MinimalDisplayBars
ModManager
MonkeysLib
MoreBuildsLite
MoreCLR_desc4mood
MoreDescriptionForTraits4166
NRK_NeedLightToRead
Named Literature
NightVisionChucked
OutTheWindow
P4HasBeenRead
PSurvival
PantryPacking
PertsPartyTiles
PlayersOnMap
ProximityInventory
PwSleepingbags
QNW_Ladder
QNW_QNWLibrary
RPropaneTank
RV_Interior
RabbitHashKY
RainWash
RebalancedCalorieBurning
Remastered Kitsune's Crossbow Mod
Riverside Gunstore
SCKCO
SCKCOAccessories
SLEO
SMUI
SYMS
ScrapArmor(new version)
ScrapGuns(new version)
ScrapWeapons(new version)
SearchModeAPI41
SimpleOverhaulTraitsAndOccupations
SimplePlayablePianos4150
SimpleReadWhileWalking41
SkillRecoveryJournal
SkillsMag
SnakeClothingMod
SnakeMansion
SnakeUtilsPack
SpnCloth
SpnHair
SwapIt
TKS
TMC_Trolley
TMC_TrueActions
TableSaw
TallerMecanico
TheStar
TheWorkshop(new version)
Trash and Corpses
TrippingZombies
TrueActionsDancing
TrueActionsDancingVHS
TrueActionsDancingVHS_MAG
TrueActionsPatch4173
TwinkiesVan
VehicleRecycling
Video_Game_Consoles
Visible Generators and Corpses
WDYPIH
WaterGoesBad
Worse Vehicle Condition
YakiHS
YakiMC
YakiMCSkill
YouDriveISleep
agrotsar
amclub
autotsartrailers
blkt_crosshair
coavinsfirearms
coavinssupport2
eris_nightvision_goggles
expandedhotwire
fastkeys41
fuelsideindicator
iMeds
improvedhairmenu
isoContainers
lakeivytownship
lgd_antibodies
lx_autotsartrailers
lx_autotsartrailers_plus
manageContainers
miscpatches
modoptions
moodle_quarters
morefastkeys
nattachments
noirrsling
nostartingbelts
nostartingbelts_addcraftablebelts
pass-out
radialmenuapi
ridiculouslyrareb4173orabove
sapphcooking
sapphcookingbettersorting
tailoringfix41
tkTiles_01
tsarslib
ornate flax
#

If anyone can help me out I'd appreciate it a lot. Trying to make a mod that simply invokes sendClientCommand() when the player uses (and destroys) a particular item. I looked at recipes but they just convert one set of items to another. Any existing mods I can look at as an example?

hearty dew
#

What do you mean specifically by use (and destroy) an item?

ornate flax
#

I had a look at this mod, I just need to call sendClientCommand()

#

So I need a recipe to consume cash items, and send the command to add Server Points

hearty dew
#

So you might add a context menu entry when right-clicking the money in the inventory. Then in the callback for that context menu entry, do the sendClientCommand() and remove the item

ornate flax
#

Yeah that would work, but i'm a real novice at modding. Is there an existing mod that does something similar I could look at for a guide?

hearty dew
ornate flax
#

Whatever works.

#

I'll do what I can make work ๐Ÿ˜†

hearty dew
#

Probably easiest development wise to make a recipe

ornate flax
#

Ok

hearty dew
#

trying to find an example

hearty dew
#
    recipe Build Spiked Baseball Bat
    {
       BaseballBat,
       Nails=5,
       keep [Recipe.GetItemTypes.Hammer],

       Result:BaseballBatNails,
       Sound:Hammering,
       Time:150.0,
       Category:Carpentry,
       OnCreate:Recipe.OnCreate.SpikedBat,
    }

Recipes have events, like this one has OnCreate. When that event happens (which should happen when it is created), the function Recipe.OnCreate.SpikedBat is called

ornate flax
#

Ok I can have a look at the vanilla code

hearty dew
#

so you might have in media/scripts/mymodid_recipes.txt: ```json
recipe Buy Server Points
{
CashItemName,
Time:100,
Category:IdkAtm,
OnCreate:MyMod.BuyServerPoints,
}

Then in `media/lua/client/mymodid_buyserverpoints.lua`:
```lua
MyMod = {}
function MyMod.BuyServerPoints(parameters)
  -- Maybe some other stuff
  sendClientCommand(argumentstofigureout)
end
#

that's kind of the gist of it

ornate flax
#

Yeah this gives me enough to make a start - much thanks for the help ๐Ÿ‘

teal island
#

There wouldn't happen to be a dyed leather strips mod for tailoring, is there?

#

I see a texture replacer that makes the patches black leather.

ancient grail
#

when is a goodtime to use
tostring()
and
String.format()
?

ashen nova
#

Does anyone know
getPlayer():getPrimaryHandItem():getScriptItem():getSoundRadius()
and
getPlayer():getPrimaryHandItem():getSoundRadius()
difference?

bronze yoke
#

the former will return the sound radius in the script, the latter will return the sound radius of that instance of the item

hearty dew
#

Anyone know what's necessary to get a non-admin account in a client with -debug enabled to join a dedicated server?

hearty dew
#

Found an undocumented server command, /dragons ๐Ÿ˜ฎ

#

There definitely be dragons in that java code

hollow current
hearty dew
#

noper. Already had that off

#

Thanks though