#mod_development

1 messages Β· Page 7 of 1

heavy iris
#

Hey, if there a problem with this code?
Its in lua/client. It won't get loaded with PZ's lua whereas other files at the same location will.
I'm sure I tested this code yesterday...

#

`local function DoSpecialTooltip1(objectTooltip, square)
print(objectToolTip.Object:GetSprite:GetName())
end

Events.DoSpecialTooltip.Add(DoSpecialTooltip1)`

lusty nebula
#

yep I know but I think that I remebered badly...the presets I want to add maybe are in the main game folder already...got to check...

heavy iris
#

well, when I start a new game with it and press F11, the .lua file isnt loaded

#

exactly

#

ho ok will do thanks

#

ho

#

becaue even before launching the game I can press f11 and see its not loaded (whereas its neighbor is)

#

I4ll try errors there then

lusty nebula
#

damn I forgot where they are located...any idea where the saved presets about character clothes and professions are saved/stored?

heavy iris
#

and what about the "reset lua" in the main menu, it doest reset all or not?

quiet nebula
#

Lua has many surprises πŸ˜›

#

If I add


    for prop, value in pairs(specialZombieManager) do
        print(prop);
    end
    return;```
To my file, the whole file is not loaded at all
#

Not sure what that's about, haha

#

For reference:
local specialZombieManager = require "SpecialZombies/Manager";
Manager:

    types = {},                             -- List of all special zombie types and their probabilities+stats
    totalWeights = 0,                       -- Total weight, for use in rolling for special zombie type
    specialZombieProbability = 0.1,         -- Probability of a zombie being a special zombie
    specialZombieProbabilityRollMax = 100   -- Max roll for zombie probability roll
};```
#

I'm not sure what determines whether a file gets loaded or not ^^;

#

I'll start trawling through the logs

lusty nebula
#

Found them they are in C:\Users\MYPC\Zomboid\Lua\saved_outfits....
Any way to add them in a mod? ( Because they are saved in the Users -> Zomboid folder... )
Maybe trying to add it in the lua ---> Shared folder?

heavy iris
quiet nebula
#

Hahaha

#

Yeah, one of my files that was loaded so far now doesn't get loaded

#

ExceptionLogger.logException> Exception thrown se.krka.kahlua.vm.KahluaException: ZombieVariety_Shrieker.lua:39: 'end' expected (to close 'function' at line 24) near if at LexState.lexerror line:278..

#

Still the same issue apparently

#

The closure problem

#

Not sure how the code sample I gave above could cause that, though...

heavy iris
#

same kind here with a ":" instead of end

#

I've read 1000 times I dont htink I have a syntax error

lusty nebula
#

be careful about the file name..sometimes a workin file generates error just because the game don't like the name or get confused with a file containing a similar name

quiet nebula
#

Yeah, problem is, the file has already been loaded the past 2 hours, no changes to the filename

#

So I can't imagine the filename is suddenly an issue, after 2 hours

lusty nebula
#

so check for commas puntualisation etc

quiet nebula
#

Or probably longer actually, I haven't changed it since yesterday

lusty nebula
#

normally I get crazy for 1 comma missing LOOL πŸ˜„

#

check in particular line 24 and 278

quiet nebula
#

Aha

#

I'll have to go through it then

lusty nebula
#

Somehow IMHO in previous versions was a lot more easier to understand the error reported in the console file

#

With the new stack thing often is a PITA understanding what causes the error

#

somehow based on my experience that error is given mainly for 2 motives: or a punctualisation error or an item/string using a wrong name

#

sample: Base.Beretta --> Bas.Beretta

#

Look at the bright side..at least for the next 2 hours you are busy LOOL πŸ˜„

quiet nebula
#

Hehehe

#

Okay, the file is only 59 lines long

#

I've gone through it a few times now

#

Could someone with more lua experience give it a quick look?

lusty nebula
#

if it's not secret maybe you can post it

quiet nebula
lusty nebula
#

maybe someone can find the error

quiet nebula
#

I don't see how this bit of code could be a secret πŸ˜›

#

It's not complicated

lusty nebula
#

don't want to be wrong but the event at the end shouldn't be

#

Events.OnZombieUpdate.Add(File name + Shrieker_Update);

#

sample

#

Events.OnGameStart.Add(EMP_MilitarySpawn.RemoveBelt)

#

EMP_MilitarySpawn is my file name

quiet nebula
#

It does?

#

It's worked so far, what does adding the filename do?

lusty nebula
#

that renders your event more unique so you avoid the game confusing it with something else and generating errors hard to pick/be found

quiet nebula
#

Okay, that makes sense

#

My filename is media/lua/shared/ZombieVariety_Shrieker.lua. So it would be Events.OnZombieUpdate.Add(ZombieVariety_Shrieker.Shrieker_Update);?

lusty nebula
#

sometimes the game act strange....yesterday...testing the mod all ok....restarting the game all ok...loading a saved game error...

#

yep correct

#

try also using your original file but in a different lua folder ( client as sample ) and make always a backup first just in case something goes wrong πŸ˜‰

quiet nebula
#

Hehe

#

Thanks for the tips

lusty nebula
#

..and don't forget to kill commas and brackets on sight πŸ˜„

#

was checking...

#

one of the last lines...aren't there too many barckets?
print("Shriek at player " .. target:getUsername());

quiet nebula
#

Did you count them?

#

There aren't that many

#

opening, opening, closing, closing

lusty nebula
#

no wrong that's correct ignore

quiet nebula
#

That line has been there since yesterday πŸ˜›

lusty nebula
#

maybe something stupid in that line...

#

"Shriek at player " ---> Left no space before the word, on the right of the world instead 1 space before the brackets

#

"Shriek at player" instead of the current "Shriek at player "

#

Try this
-- Shriek in the first 5 seconds a player target is spotted if instanceof(target, "IsoPlayer") then print("Shriek at player") target:getUsername() --makeNoise(zombie);

visual steeple
#

Hi!! does anyone know how clothing spawns are handled? Is there a post in the forum about this that I haven't found?

heavy iris
#

Do we have ssomething like
Events.DoSpecialTooltip.Clear() ?
Would help a lot for debug

quiet nebula
#

Yeah, I already figured out that that didn't work the way Robert described it, it failed the moment I tried to load it πŸ™‚

heavy iris
#

(because between two loads of my lua file adding events, the old bad events stay stored cause, as Olipro said, memory isnt erased ><)

#

so to clear

#

I should iterate though Events.DoSpecialTooltip and remove all

#

thanks

#

lol thats what I just figured out

#

looking to get access to callback list now to iterate on it

gilded hawk
#

Is there a mod or debug tool to spawn the garage doors that the Rosewood fire station has?

quiet nebula
#

Setting a zombie's speed is zombie:setSpeedMod(), right?

quiet nebula
#

Nice, my first special infected is done πŸ˜›

#

Basically a screamer

#

Next up, a Boomer

#

Old people zombies, yelling at the player to get off their lawn

heavy iris
#

IS it only a matter of what a cmddo to know if we run this on client, server or shared :
Events.OnAnyEvent.Add(cmd),
or does it also depend on the event OnAnyEvent ?

snow kiln
#

the numbers mason what do they mean?

heavy iris
#

(no custom events here) events are triggered by the game so event type shouldnt matter right?

midnight mica
#

does anyone know of a way to kick a player from the server without an admin being on?

shy radish
#

Is it possible to grab key/values from userdata types?

wraith root
shy radish
#

But I used a type() and it returned userdata, why is that?

#

ProfessionFactory.getProfession(playerProfession):getXPBoostMap()

#

That did work! Thank you πŸ™‚

#

I'm not very familiar with this tech (obviously haha), what would be more efficient, looping through a table, or a string.find()?

#

I mean I guess that would also depend on the size of the table huh, but assuming it's relatively small

wraith root
#

Also depends on the string you are looking for

#

If you are doing a big search over everything in the code, a strong search could have a lot worse time crunch than a table

shy radish
#

both the tables and strings would be relatively small, something like {Cooking=3, SmallBlade=1, Maintenance=1}, but I don't know how this system handles strings. Is it lua that will be doing the string parsing or java? Java I think I would have a better handle on because I come from a C# background

eternal garnet
#

Looking for a Vector artist for some icons.
(Paid)

shy radish
#

Gothca, thank you for the help!

zenith agate
#

Is there any way to edit the grass / road texture / tile on the vanilla map?
I simply wanna do some changes to the texture
(Dont know if this belongs in mapping, modding or modelling)

lusty nebula
#

Ok I have a tricky question for our talented modders. In the path C:\Users\MYPCNAME\Zomboid\Lua there are two saved preset files named " saved_builds " and "saved_outfit". Due to the fact that they are located in a folder that is not present in the main game folders or in the media one is there a way to put them into my mod so that they will be available for the users of it?

thin hornet
lusty nebula
#

Ok but how can I add them in a mod that instead uses files only from the " Media " one?

thin hornet
#

So you want the saved outfit to be presets by your mod kind of?

lusty nebula
#

pretty much yes

#

A friend of mine wrote this function but it doesn't seem to work

vivid imp
#

Hello, do you know if there's a way to spawn items in a certain location? Specifically, a church.

lusty nebula
#

I've put it in lua client folder but no joy so far

thin hornet
#

if i recall getFileReader and getFileWriter can only work inside that Zomboid/lua/ dir

lusty nebula
#

This means no way to include them apart from writing a small READ ME file saying something like " If you want a set of saved presets for clothes and professions download them from here and install them here bla bla bla...

thin hornet
#

Nah you could have a lua script in your mod that writeFile with the preset you want to include

#

So

#

You make a client script that will simply getFileWriter and write the file mymod_outfit_presets.txt
and in the code snippet you have there you load that file

#
local preset = "VERSION=1
Karin Mullin:gender=1;skincolor=0.8,0.65,0.45;name=Karin|Mullin;hair=Rachel|0.10588235408067703,0.09019608050584793,0.08627451211214066;Tshirt=Base.Tshirt_WhiteLongSleeveTINT|0.3137255012989044,0.6509804129600525,0.5490196347236633;Pants=Base.Trousers_Denim|1;Socks=Base.Socks_Ankle|0.16862745583057404,0.20392157137393951,0.09019608050584793;Shoes=Base.Shoes_TrainerTINT|0.125490203499794,0.13725490868091583,0.13333334028720856;";

local fileWriter = getFileWriter("filename.txt");
fileWriter:write(preset);
fileWriter:close();
#

something like that?

lusty nebula
#

ok so I need one for the clothes ( saved_outfits ) and one for the professions ( saved_builds )or there's a way to condense so to have just one file with all inside?

thin hornet
#

might be better you have different files

wraith root
#

Easier to debig

#

Debug*

thin hornet
#

you can also have your own directory inside of Zomboid/lua

lusty nebula
#

ok many many thanks mate as always you're a Code Jedi LOOL πŸ˜„

thin hornet
#

C:\Users\Konijima\Zomboid\Lua\MyModID\presets_x.txt

lusty nebula
#

especially when I shit LOOL πŸ˜„

thin hornet
#

make sure your mod write the "mod" presets before the code that reads it

lusty nebula
#

how to check it?

thin hornet
#

where is function CharacterCreationMain.readSavedOutfitFile() called

heavy iris
#

we can still read global variables even though they're private can't we?

thin hornet
#

oh wait might wanna add it to that function then

thin hornet
lusty nebula
#

ok You are already in the aramaic territory for me LOOL πŸ˜„

heavy iris
#

I'm thinking about Luamanager.EventList

thin hornet
#

ahh

lapis vigil
#

can I ask do we have any recommended/QoL mod?

thin hornet
#

the private java you cant access it

#

You cannot get the list of all listener added to an events

lusty nebula
#

I'll try to write it then I'll post it here so you can check if I've done it as planned

thin hornet
#

as far as i know

heavy iris
#

I wanted to just change a bit your PZ-Base Mod function Client/Server.AddEvent, checking if the event is a vanilla event, and in such case adding the callback

#

so.. I just have to hard write the list? xD

thin hornet
#

not sure i understand

#
--- Function that initialize the events found in the config
local function internalInitEvent(eventName)
    if not addedEvents:contains(eventName) then
        LuaEventManager.AddEvent(Client.Config.ModName .. "Client" .. eventName);
        addedEvents:add(eventName);
        Client.Log("Created custom client event " .. eventName);
    end
end

the way base mod add custom event is that it append the mod ID and the side from which its declared client/server

#

so any mod can have their own custom events without "stepping" on each other

lusty nebula
#

First file for check ( saved_outfits ). Note that ATM is just a text file I'll save it then to lua

thin hornet
#

i think you can make string literal on multiple lines using [[ ]]

local preset = [[ string
on multiple 
line ]]
#

havent tested in pz kahlua but i supose it should work

heavy iris
lusty nebula
#

@thin hornet for the profession one ( saved_build) at the top of the script, what local preset = I have to use? ( If any )

thin hornet
# lusty nebula or simply
local outfitPresets = "VERSION=1" .. "\n"
outfitPresets = outfitPresets .. "Karin Mullin:gender=1;skincolor=0.8,0.65,0.45;name=Karin|Mullin;hair=Rachel|0.10588235408067703,0.09019608050584793,0.08627451211214066;Tshirt=Base.Tshirt_WhiteLongSleeveTINT|0.3137255012989044,0.6509804129600525,0.5490196347236633;Pants=Base.Trousers_Denim|1;Socks=Base.Socks_Ankle|0.16862745583057404,0.20392157137393951,0.09019608050584793;Shoes=Base.Shoes_TrainerTINT|0.125490203499794,0.13725490868091583,0.13333334028720856;" .. "\n"

local buildPresets = "Lumberjack2:lumberjack;SlowLearner;Hemophobic;Conspicuous;WeakStomach;SlowReader;Dextrous;MarathonRunner;Organized;Athletic;Strong;" .. "\n"
buildPresets = buildPresets .. "Lumberjack:lumberjack;Conspicuous;Smoker;Nightmares;WeakStomach;Clumsy;Pluviophobia;OwlPerson;SpeedDemon;NightVision;Dextrous;Organized;Athletic;Strong;" .. "\n"

local fileWriter;

-- Write outfit presets
fileWriter = getFileWriter("mymod_outfitPresets.txt");
fileWriter:write(outfitPresets);
fileWriter:close();

-- Write build presets
fileWriter = getFileWriter("mymod_buildPresets.txt");
fileWriter:write(buildPresets);
fileWriter:close();
#

something like this?

lusty nebula
#

yep mate so just to understand..at the top for each outfit a section the same below for each profession. Just a thing...for the clothes..each section uses the same script ( modified depending on the character ) or I must insert at the end of each " ;" or " end " ( My guess is that ;" .. "\n" is already the closure of each section right? )

#

Sample

outfitPresets = outfitPresets .. "Karin Mullin:gender=1;skincolor=0.8,0.65,0.45;name=Karin|Mullin;hair=Rachel|0.10588235408067703,0.09019608050584793,0.08627451211214066;Tshirt=Base.Tshirt_WhiteLongSleeveTINT|0.3137255012989044,0.6509804129600525,0.5490196347236633;Pants=Base.Trousers_Denim|1;Socks=Base.Socks_Ankle|0.16862745583057404,0.20392157137393951,0.09019608050584793;Shoes=Base.Shoes_TrainerTINT|0.125490203499794,0.13725490868091583,0.13333334028720856;" .. "\n"

outfitPresets = outfitPresets .. "Karina Mullin:gender=1;skincolor=0.8,0.65,0.45;name=Karin|Mullin;hair=Rachel|0.10588235408067703,0.09019608050584793,0.08627451211214066;Tshirt=Base.Tshirt_WhiteLongSleeveTINT|0.3137255012989044,0.6509804129600525,0.5490196347236633;Pants=Base.Trousers_Denim|1;Socks=Base.Socks_Ankle|0.16862745583057404,0.20392157137393951,0.09019608050584793;Shoes=Base.Shoes_TrainerTINT|0.125490203499794,0.13725490868091583,0.13333334028720856;" .. "\n"```
wraith root
#

Oh god that would be so annoying

#

If I delete a mod and it stuck around I'd almost classify that as a neutral maliciousness

#

Pls no

lusty nebula
#

same here πŸ˜„

wraith root
#

Yeah... But it's usually not good to force someone to keep data they don't want / opt out of

#

It's bloatware at that point

lusty nebula
#

I want that if the user delete my mod a pic of my ass will be displayed on his monitor πŸ˜„

wraith root
#

Gruh moment

wraith root
#
Every time you try to delete my mod a random audio file in the game gets extremely loud forever
#

ded ✨

lusty nebula
#

Worst than a curse LOOL πŸ˜„

wraith root
#

Especially if it's the jumpscare noise

lusty nebula
#

..and you character permanently is displayed like this LOOL πŸ˜„

wraith root
#

Hm.

So normal admin powers allow me to make a NO PVP zone

Would it be possible to make an additive tool to admin powers where you can add PVP ON?

Specifically for a server that uses the safety system

I want to be able to have the safety system, no kill zones I define, and then the additional ability to force PVP to be turned on

thin hornet
#

So you want to make a NonPVP area disabled without removing it?

wraith root
#

Well more so like this

#

You know how as an admin I can make custom no kill zones? (no PVP)

thin hornet
#

sure

wraith root
#

I want to design a tool that can do the opposite of that

#

The neutral state of the server would have a safety system

thin hornet
#

hum

#

not sure thats possible

wraith root
#

Hrm...

I guess I can do it the hard way and make a tool that allows easier sets of NOPVP zones in a PVP only server

#

I'm willing to go into Java (one of my main languages) it's just a bit confusing the pipeline of modding with Java

#

This would basically be how I would do it in vanilla without mods

#

It's definitely ugly

thin hornet
#

well you would have to make player not able to attack each other while still being able to attack zombies

wraith root
#

Hm...

#

Maybe more specifically is there a way to disable the safety system or force it to trigger PVP ON by being in a certain area of the map?

#

They dont

#

I think it was a mistype

#

I am the admin

#

πŸ˜†

#

Hm.......

Maybe there is a loop around.

What about a way to check if you are hitting a player with a gun / weapon || (I know there are checks for this due to skills using this mechanic for players and zombies) ||

And when you hit another player in the specific area, you will swap to PVP enabled automatically

#

.

Nah that sounds even more difficult than a simple PVP ONLY zone tool

#

The question is then can you inverse it?

#

That would be the simple method

#

First I need to test vanilla with a safety on system and see if I can turn pvp on in a no kill zone

#

If I can't, then we are good to move to finding out how to make an opposite zone

thin hornet
#

just make the server full pvp no safezone πŸ˜›

wraith root
#

Noooo

thin hornet
#

yaaaasss

wraith root
#

But the new players

thin hornet
#

Its the apocalypse not kindergarden

#

πŸ˜›

wraith root
#

I wanna have a safety on system for people who choose to fight each other (For roleplay)

But in certain areas there would be a KILL ON SIGHT so you could kill anyone in an area, like an arena

#

πŸ€”

#

Which is good

#

But that also means java

#

Hm

#

How come?

#

I mean this location wouldn't move, think of a boxed in area

#

Like a battle royale

#

Indeed

#

So the perimeter, or a depth first search function

#

To find every block in the zone

#

I'd hope so

#

I know the current system just has you mark an initial corner and spread out as a block

#

But the issue is then the shape is only a square/rectangle and not custom

#

One problem at a time

#

I guess lol

lusty nebula
#

@thin hornet replying here because discord don't let me send the PM reply...
ok so
;" .. "\n"
marks the end of each section
perfect

wraith root
#

Nothing I could custom make?

#

Like a variant totally outside of house where I define multiple xy cords to tie them together?

#

Either that or I'm gonna have to make a way to /merge/ zones that are touching which might be a harder problem to solve

#

Laziest method is just using a square and constraining the entire zone to the rectangle and have some areas with PVPON overflow

#

And maybe design my map to block those areas off with decorative stuffs

lusty nebula
#

Edited PMS works as per normal again now

wraith root
#

Well yeah

#

I'm saying in a server where you have toggled PVP on, no tile is safe but the player is

#

I want to force that setting to be turned off and allow PVP on certain defined zones

#

Is having safety turned on in a non safe area considered a safe tile?

#

By safety I mean a players personal safety setting where you can toggle Pvp on and off

The area you are in is not a safe zone, you are as a player just safe

#

You're missing the portion I'm talking about I think

#

No no

#

Here let's remove tiles for a moment in terms of there being a safehouse

#

In the vanilla game there is a setting that allows players to "turn off friendly fire" with a button

#

Nice, what's that func called? I presume it's not exposed to Lua

#

I see

#

Shweet

#

But I can use the safe house and maybe fanangle it

#

Either way,

Onto the next point

#

I think you and I are having a little bit of a miscommunication

Next point!

#

Lol

#

Affecting the pvp Java code wouldn't require players to hand install the Java would it?

#

Should be server side

#

πŸ€”

#

But safe houses isn't

#

So it's not exposed

#

That goes against what you mentioned earlier

#

Exposed to lua

#

Why not override?

#

The function

#

You can in normal Java, which is why I'm wondering

#

Am I not a mod dev looking for the convenience of making this code? Lol

#

Sounds like it's up my alley

#

Override Java with Java, a Java mod that is (hopefully) server side only. If it's not possible to do any PVP / safehouse stuff in server side only then I'll have to find another way

#

Hm... How often would that calculation have to occur?

#

That could slow things down if I'm asking for the entire map to find a minority of the rectangles to exclude

#

Ah

#

Well that should be fine then

#

I can still make an admin tool that can define Pvp only zones

#

squirrel I wish lol

#

Similar idea with zones but for zombies,

I want to see if I can't specify certain areas of the map to only spawn specific zombie types (in this case we will use speed)

I know you can edit a heat map for zombie spawning,

#

But I wonder if you can make it so specific areas spawn sprinters while others spawn shamblers

#

Potentially

#

This might be more a map modding question

#

2% but not for specific areas? Possibly.... There might be a mod I think that spawns zeds that are harder to kill and that are faster only at Fort Knox

#

Hmmm

#

That would be my file

#

Yoink

#

Ahhh yeah that makes sense

#

Would you think the settings extend to their speed and strength as well?

#

I thought those values were server wide only (no specific zone but I haven't checked for those kinds of mods yet)

#

Le pog

#

Indeed

#

.

#

Oops not all of that

rose trail
#

hey i got a question

#

hod does modding copyrigth works?

wraith root
#

Ahh I only thought zombies thumped, didn't realize thumping was a player thing as well

rose trail
#

i mean if a use like the military ponchos and change the model a bit and make other textures, would i need permission form the mod author to put it on steamworkshop?

drifting ore
#

What programs are required for modding a game like pz?

rose trail
#

fair enough

rose trail
wraith root
#

Something that gets a little gray is that the devs have the rights to your idea to use in the base game which modders agree to in the TOS

But they do not have the rights to your code (no one does)

#

Unless you lend those rights / allow a license to use the code in a certain way

#

Indeed

#

But it is worth mentioning since I've seen some people complain when the devs implement a modded feature

#

πŸ˜†

shy radish
#

So what’s the method for updating your mod when a new game update comes out. Is there like a change log for modders release somewhere, or do we just have to play test it with the new version and hope it works

#

Roger that, thank you

#

Yeah I followed a tutorial that Konijima made for doing that (great tut) , and something I will do moving forward

grizzled dawn
#

would it be possible to do a mod that increases the amount of zoom our camera can go?

drifting ore
#

anyone know how to use the NVG's from britas armor pack? I have them equipped, but nothing happens no matter what key i press
or are they just there for decoration?

heavy iris
#

@thin hornet Hey, in ClientModData.lua you use
Client.TriggerEvent("OnModDataInitialized", isNewGame);
without requiring ClientEvents, is that a theoretical problem that never happens to make trouble, or did I misunderstood smth?

shadow geyser
heavy iris
#

Client.TriggerEvent is vanilla?

#

ho ok thanks!

#

because he redefines one so..

shadow geyser
#

is it not? wait, I kind of assumed it was

thin hornet
#

it the same as the on init global moddata, but after the mod moddata is completed

shadow geyser
#

might just be coincidence that the load order for files loads it correctly

thin hornet
#

oh weait

radiant venture
#

does anyone know if aquatsar yacht club is on hiatus or will it just not get updated anymore? i really want to use "kingsmouth in KY" but it depends on the yachts

thin hornet
#

i just understood your question

heavy iris
#

^^

thin hornet
#

ClientModData.lua
When this file load the first thing it does is require Client.lua right?

heavy iris
#

yeah

#

but ClientServer calls client, not the other way

thin hornet
#

but both file will be loaded before Events.OnInitGlobalModData.Add is called

heavy iris
#

ok, there is a dependency

thin hornet
#

all lua files are proccessed at the reloadlua step when loading the game

heavy iris
#

yeah, it's just that I'll write it on the top of the file

#

to take care of dependencies

thin hornet
#

So i assume that the event will be added already when OnInitGlobalModData triggers

heavy iris
#

I can just add require("ClientServer") line 1 it will do no harm right?

#

yes I think your code works for that reason too ^^

thin hornet
#

its not usefull tho

#
--- Core event
internalInitEvent("OnModDataInitialized");
#

this is processed before any other call

heavy iris
#

no I dont get it ^^

#

its like, the first event after all lua files are loaded?

thin hornet
#

these files will all be evaluated before anything else happen

#

the require client.lua just ensure that client is always first as this is the main file

heavy iris
#

ok

thin hornet
#

what ever happen in those files (outside a code block, or event handler) will be ran as soon the file is evaluated

heavy iris
#

ok I got it now

#

ty πŸ™‚

thin hornet
#

so triggering the event inside the OnInitGlobalModData will work, triggering it outside would not unless the event file loaded first

wraith root
#

What is this mod even for?

wraith root
thin hornet
wraith root
#

It's for base mod?

thin hornet
#

yeah

wraith root
#

I don't understand why you'd need to worry about load order

#

Unless you were doing something fairly specific

thin hornet
#

so vanilla has a OnInitGlobalModData event right.
basemod will initialize all moddata in that event and then trigger a custom event named OnModDataInitialized
so OnModDataInitialized aka after init mean all is ready in the moddata

wraith root
#

Isn't that inclusive to the base game?

#

Otherwise mods wouldn't load as they do now I'd think

thin hornet
#

well basemod does some abstraction to help manage global moddata and commands easier

wraith root
#

I guess I'm confused on what this person's goal is

thin hornet
#

He he working on a fork of BaseMod

#

so he had a question related to BaseMod specifictly

wraith root
#

Ah I see

#

What is the specific abstraction you tend to cover? I thought most global Lua vars were fairly explanatory by their names but I haven't read that code yet

#

Looks like a formatting thing that you showed me beforehand

heavy iris
#

Well I just wanna expand a bit BaseMod, all the hard work is done there. I wanna add modules skeletons and a script that write a mod from a datasheet you give him

wraith root
#

You want to autoscript mods?

thin hornet
wraith root
#

That sounds like a massive undertaking

heavy iris
#

(datasheet + tilesheets + .tiles + .packs + textures etc)

#

nono its not that hard

heavy iris
#

its like

#

you have to do "the big form" once

#

that might be a bit long

thin hornet
#

so when making a mod using BaseMod you dont need to touch any of those files

heavy iris
#

then skeletons will have "hashed characters" that will let me search and replace easily all fields

thin hornet
#

you just need to edit the config file lua/shared/MyModName/Config.lua

heavy iris
#

Exactly, thats what I wanna reproduce

thin hornet
#
--- Define Global ModData tables to create on the client
    --- if true, it will always be requested/overwritten by the server
    --- if false, it will only be local
    ClientModData = {
        exampleSync = true,     -- request from server
        exampleLocal = false,   -- local only
    },

    --- Define Global ModData tables to create on the server
    ServerModData = {
        "exampleSync",
    },

    --- Define custom events to add on the client
    ClientEvents = {
        "OnCustomEvent",
    },

    --- Define custom events to add on the server
    ServerEvents = {
        "OnCustomEvent",
    },
wraith root
#

Weird

#

I haven't touched any of those client files in my mod

#

But my mod was a simple recipe mod and nothing more, only a few actual Lua functions and mostly scripts

thin hornet
#

BaseMod is mainly focus for mod that need to have a lot of client/server interaction

quiet nebula
#

Is there a way I can make something like this work?

    return {
        name = "Basic",
        definition = require("SpecialZombies/Definition/Basic"),
        definitionName = "Basic",
        makeNoise = function(zombie, playSound)
            local emitter = zombie:getEmitter();
            if not emitter then
                return;
            end
            addSound(nil, zombie:getX(), zombie:getY(), zombie:getZ(), 250, 250);
            if playSound then
                emitter:playSound(BaseSpecialZombie.getSound(), zombie);
            end
        end,
        getSound = function()
            if not BaseSpecialZombie.definition or not BaseSpecialZombie.definition.sound then
                return "";
            end
            return BaseSpecialZombie.definition.sound;
        end
    }
end```
I want a constructor that returns a base version of an object.
Wait, is it even possible to 'extend' in lua?
#

By doing something like this:

Shrieker.name = "Shrieker";
Shrieker.definition = require("SpecialZombies/Definition/Basic");
Shrieker.definitionName = "Shrieker";```
Does it provide a new instance when I require it or does it provide the previously edited version, if I were to then do:
```local Boomer = require("SpecialZombies/Class/BaseSpecialZombie")();
Boomer.name = "Boomer";
Boomer.definition = require("SpecialZombies/Definition/Boomer");
Boomer.definitionName = "Boomer";```
#

Sorry, that was maybe a bit too long

thin hornet
#

require return the cached result of the lua file evaluation

#

might wanna try dofile()

#

this should do what you expect

heavy iris
#

I had trouble with dofile() today

quiet nebula
#

Thank you!

#

I'll try that out πŸ™‚

wraith root
#

But I didn't believe it

thin hornet
#

i never used dofile no even sure if its suported but if so then great!

quiet nebula
#

Hahaha

#

Otherwise I'll have to add the functions manually to each of the instances of my special zombies

heavy iris
#

Well BaseMods adds custom events and thats huge

thin hornet
#

java server mod is when you want to add functionality unavailable to lua on the server

quiet nebula
thin hornet
#

changed

quiet nebula
#

I see

quiet nebula
#

Haha, thank you

thin hornet
#

its lives inside its "cache"

#

until you "reloadlua file"

quiet nebula
#

Okay, understood πŸ™‚

thin hornet
#

On the java side of require
it check if the file is loaded if not, it loads it evaluate it and return it.
If its already loaded it just return the existing result.

quiet nebula
#

Then I'll see if dofile works and otherwise add all shared functionality to each variant that needs it

#

Gotcha

shut hollow
#

I guess it's not possible to change the entire playermodel.

heavy iris
#

gl ^^

#

no idea for the player model

shut hollow
#

I just use retexture instead of that.

#

Since PZ only need 1 texture for 1 model , can't use multiple texture pics per 1 model.

quiet nebula
#

What sort of a path does dofile require? Is it relative from the file it's called from?

#

Or same as require?

heavy iris
#

(thats the problem I had)

quiet nebula
#

Hahahaha

#

Cool xD

heavy iris
#

how do you run it

#

try putting in same folder and doing dofile("otherfile.lua")

quiet nebula
#
         name = "require",
         global = true
      )
      public static Object require(String var0) {
         String var1 = var0;
         if (!var0.endsWith(".lua")) {
            var1 = var0 + ".lua";
         }

         for(int var2 = 0; var2 < LuaManager.paths.size(); ++var2) {
            String var3 = (String)LuaManager.paths.get(var2);
            String var4 = ZomboidFileSystem.instance.getAbsolutePath(var3 + var1);
            if (var4 != null) {
               return LuaManager.RunLua(ZomboidFileSystem.instance.getString(var4));
            }
         }

         DebugLog.Lua.warn("require(\"" + var0 + "\") failed");
         return null;
      }```
#

This is what require does

heavy iris
#

(I havent solve the problem actually, I stopped debugging events before that)

quiet nebula
#

So I guess you'll have to put in the full path relative to what the ZomboidFileSystem has as its root

shut hollow
#

I never look into server side or client side stuffs. So I wouldn't know about it ._.

heavy iris
quiet nebula
#

Haha

#

It's right there in build/generated/sources/zomboid/zombie/Lua/LuaManager.java

heavy iris
#

yeah, I mean you're right I installed it as well, just didnt though about that ^^'

quiet nebula
#

πŸ˜‰

#

Strange, I can't find the code where it even adds any paths to the LuaManager.paths variable O_o

thin hornet
quiet nebula
#

I'm more trying to figure out the root of the filename/path I need to enter into dofile πŸ˜›

#

I think I'm not quite ready for the runlua analysis

#

All in due time

#

Thanks for the tip, noted πŸ™‚

shut hollow
#

What's the main purpose of making mod from lua script ? I only touch xml files and media folder files.

quiet nebula
#

If you want more custom control over events or objects in the world, you'll need lua

shut hollow
#

Oh.

quiet nebula
#

I've added a zombie that yells and makes noise and screams, for example

#

I don't know if that's possible with only xml and media folder files

#

Though, media/lua is a media folder πŸ˜›

shut hollow
#

Oh.

#

I do re-texture model and custom hat mostly.

quiet nebula
#

Ahh okay

#

Yeah, for that sort of visual stuff, you'll not need lua πŸ˜›

#

But adding custom functionality, you'll need lua

shut hollow
#

I would try lua stuff but main major problem is I'm new to making zomboid mod ._.

quiet nebula
#

So am I πŸ™‚

#

Until last monday, I had not even looked at them

#

You have to start somewhere

#

Heck, I had never seen or done anything with lua until last monday

shy radish
#

Is there an easy way for me to learn what things are server side?

shut hollow
#

I've been busy with custom hat model mostly.

quiet nebula
#

Gotta start somewhere

shut hollow
#

Hm.

quiet nebula
#

And hey, if you're good with making mods that add models, clothing, etc

#

Go for it

shut hollow
#

Is item lootable is count as lua ?

#

Like.

#

Where item spawn.

quiet nebula
#

Sadly, that is something I do not know

thin hornet
# shy radish Is there an easy way for me to learn what things are server side?

the only way is mostly looking through the source and you should see things like

if (GameServer.bServer)

for example

@LuaMethod(
    name = "getPlayerByOnlineID",
    global = true
)
public static IsoPlayer getPlayerByOnlineID(int var0) {
    if (GameServer.bServer) {
    return (IsoPlayer)GameServer.IDToPlayerMap.get((short)var0);
    } else {
    return GameClient.bClient ? (IsoPlayer)GameClient.IDToPlayerMap.get((short)var0) : null;
    }
}
#

that tells you this method can run on both client and server but not in single player

#

if it doesnt have a check for bServer or client then it most likely run anywhere

shy radish
#

Ah gotcha. Thank Konijima, you’re always super helpful ❀️

thin hornet
#

same goes for knowing if an event is ever triggered on server or client or both. You search for that event and will find where ever it is triggered

LuaEventManager.triggerEvent("OnLoadSoundBanks");

thats a lot of research but one day i believe we will have a good documentation of everything.
we can also build a community documentation over time

shut hollow
#

I just use 1080x720 as canvas size and I realize that maxed canvas size for PZ is 256x256 πŸ’€

quiet nebula
#

Oof

shy radish
quiet nebula
#

Ya know what, this has taken long enough. I'm just going to do the less elegant thing for now and just add all generic functionality to every single type πŸ˜›

wraith root
#

Damn some of these names are bad lol

#

Makes reading the code way harder

quiet nebula
#

What do you mean? πŸ˜›

#

I mean, sure, the code isn't always as easy to read

shy radish
#

Does lua, or kuhlua I guess, have type saftey features? Or can I for example change a Boolean to a string without issue

thin hornet
#

yeah lua is not type strict

#

you can check type using type(arg) == "number" but really you can reasign to what eveer

shy radish
#

Okay awesome, thank you!

quiet nebula
#

Can you put functions into variables? Or are functions already tables?

#

As in

thin hornet
#

sure

quiet nebula
#

Is there a difference between:
function A() {return "A"}
and
local A = function() {return "A"}

thin hornet
#
local obj = {};

function obj.func()
end
-- same as
obj.func = function()
end
quiet nebula
#

So if I were to do this, I could get around the lua file caching, right?

local makeNoise = function(zombie, playSound)
            local emitter = zombie:getEmitter();
            if not emitter then
                return;
            end
            addSound(nil, zombie:getX(), zombie:getY(), zombie:getZ(), 250, 250);
            if playSound then
                emitter:playSound(BaseSpecialZombie.getSound(), zombie);
            end
        end
local getSound = function()
            if not BaseSpecialZombie.definition or not BaseSpecialZombie.definition.sound then
                return "";
            end
            return BaseSpecialZombie.definition.sound;
        end
local ObjectA = function()
      return {
        name = "Basic",
        definition = require("SpecialZombies/Definition/Basic"),
        definitionName = "Basic",
        makeNoise = makeNoise,
        getSound = getSound
    }
end```
#

And then I can do require("thisfileabove")(); to get a new instance that shouldn't change the cached result from require

thin hornet
#

function and table become a "reference" hex so it can even be a table key

local obj = {};
local obj2 = {};
obj[obj2] = true;
quiet nebula
#

Aha okay

#

I'm going to try this and see if it works.

thin hornet
quiet nebula
#

Huh

thin hornet
#

its just some pointer to get the function in memory

quiet nebula
#

I see

#

Wait, so wouldn't something like:

  return Class
end``` go around the caching of lua file require outputs?
#

Since it always gives you a new instance

#

Wait, no that returns the pointer in a roundabout way

thin hornet
#

what you are looking for is probably copyTable

quiet nebula
#

I would need to do
return table.clone(Classname); or something

#

Ehm

#

Wait, that's a custom function on the table class?

#
  return {table.unpack(org)}
end

local abc = {5,12,1}
local def = table.clone(abc)```So table.unpack?
thin hornet
#

its an kahlua function

quiet nebula
#

Ohh

thin hornet
#

copyTable is used at many place

quiet nebula
#

Ohh

#

Nice

thin hornet
#

check zomboid\zombie\Lua\LuaManager.java line 1094

quiet nebula
#

Yeah, looking at it now

thin hornet
#

note that it will only copy lua tables if there is a java object reference it wont copy that, so basically that java object reference will be the same in each copy

#

but for a table it will be a complete copy with a new reference id

quiet nebula
#

Okay, so as long as I copy custom tables, it should work

#

That's good!

#

Thank you

thin hornet
#

πŸ˜„

quiet nebula
#

I didn't know this existed, awesome

#

That makes this all a lot simpler, hahaha

#

Now that's a new one

#

[05-08-22 00:24:15.689] LOG : General , 1659651855689> Object table 0x1537339274 did not have __call metatable set.

#

Didn't give me any lines to look at

#

Guess I'll have something to look at tomorrow πŸ˜›

#

It's past midnight, I'd better get to bed, haha

#

Thanks again Konijima for all the help and advice

shy radish
#

What exactly is a grid square? Is it relational to chunks and tiles and all that jazz?

thin hornet
#

IsoGridSquare?

shy radish
#

Yeah, that one

heavy iris
#

its a square πŸ™‚

#

of the map

#

1x1

#

isoGridSquare contains a lot of info, like items on it, the position, the sprites...

#

Anyone knows Dr_Cox1911 that did profeession framework?

#

wanna ask him to take code

shy radish
keen frost
shy radish
#

When you’re in debug mode, is it possible to reload scripts in game or do you have to use the main menu button?

wraith root
heavy iris
#

press F11

#

bot right you have a list of lua files read

#

you can open them to see the current version and press reload

#

if you modify your lua file in parallel and reload, it will load the new version

#

previous iteration of other file versions that had their effects, well, already had their effects and there is nothing more to say ^^.

shy radish
#

Well that is very handy to know. The amount of time I’ve wasted quitting and reloading a save file seems astronomical lol

#

Thank you for the info! πŸ™‚

weak sierra
#

how can i send a servermsg from lua running on the server?

#

i've dug around ISChat and while i can see how it does it on the other end i haven't seen how to trigger that yet

wraith root
weak sierra
#

it seems i can do SendCommandToServer("/servermsg whatever")

#

but im tracking down where that code lives

#

wouldn't be the worst idea to take the restart checking out of the actual server though for performance tbh

wraith root
#

Indeedi

#

Hmm ..

wraith root
#

Damn!

Authentic Z took down every single server it was connected to, at the dead of night

wraith root
#

This is a good case study to learn from I guess

#
WARN : General ItemPickerJava.ExtractContainersFromLua> ignoring invalid ItemPicker item type "AuthenticZClothing.SpiffoPlushieShamrock"
ERROR: General GameServer.main> Exception thrown java.lang.NullPointerException: Cannot invoke "java.lang.Double.doubleValue()" because the return value of "java.util.Map.get(Object)" is null at ItemPickerJava.ExtractContainersFromLua line:290. Message: Exception Thrown
ERROR: General DebugLogStream.printException> Stack trace:
java.lang.NullPointerException: Cannot invoke "java.lang.Double.doubleValue()" because the return value of "java.util.Map.get(Object)" is null
at zombie.inventory.ItemPickerJava.ExtractContainersFromLua(ItemPickerJava.java:290)
at zombie.inventory.ItemPickerJava.ParseProceduralDistributions(ItemPickerJava.java:255)
at zombie.inventory.ItemPickerJava.Parse(ItemPickerJava.java:145)
at zombie.iso.IsoWorld.init(IsoWorld.java:2194)
at zombie.network.GameServer.main(GameServer.java:718)
LOG : General Server Terminated.
#

This is the error thrown by the Auth Z mod, let's see if we can't study the error and find out the issue to learn from it

wraith root
#

The user who posted it didn't provide a mod list or extra logs

#

But we have access to the mod

#

And the null point is a common issue people run into

cosmic condor
#

I'm trying to figure out too

wraith root
#

The first part is more so pointing to the error before it hits a wall

rose trail
#

hello

#

can anyone help

#

im doing a hat but im stuck in this part

wraith root
#
Stack trace:
java.lang.NullPointerException: Cannot invoke "java.lang.Double.doubleValue()" because the return value of "java.util.Map.get(Object)" is null
at zombie.inventory.ItemPickerJava.ExtractContainersFromLua(ItemPickerJava.java:290)
at zombie.inventory.ItemPickerJava.ParseProceduralDistributions(ItemPickerJava.java:255)
at zombie.inventory.ItemPickerJava.Parse(ItemPickerJava.java:145)
at zombie.iso.IsoWorld.init(IsoWorld.java:2194)
at zombie.network.GameServer.main(GameServer.java:718)
LOG : General , 1659674620286> 1,568,439,286> Server Terminated.

here is it

#

Unrelated to you sam sorry

rose trail
#

np

cosmic condor
#

Is this number a memory address? 1659674620286

cosmic condor
#

can't give any advice with less info

rose trail
#

you see im doing hats i have the models and textures, but i dont know if the folders needs to be exactly as the original in the game files

cosmic condor
rose trail
#

oh

#

good

#

thank you very much

#

this is a bit confusing for me

rain iron
#

Hi, is there any good resource or guide on how to make a new custom zombie and AI?

cosmic condor
#

don't think there are any since there are not many custom zombie mods out there

#

you can try reverse engineering though

rain iron
#

Cross checking/referencing between the Lua code and the Java code is gonna be one hell of an attempt stressed

abstract pine
#

What determines how well a vehicle drives offroad? Comparing vehicles that drive very well offroad to ones that don't, I can't see any pattern causing it, and haven't had much success tinkering with the different values.

late hound
# wraith root This is a good case study to learn from I guess

Yeah, so I made the mistake of modding the map content released 5 weeks ago. I should have been more patient for the devs to merge everything into the unstable branch. Everyone having this issue is playing on 41.71 and not on the stable branch. I put new map zones on the new boat area, added in 41.72. Guess I got to revert 5 weeks of work. Just goes to show how quickly TIS works on their game.

cosmic condor
#

Thanks for the details

#

We usually create a mod on 41.73 unstable to make it futureproof, but have to be reminded that MP players are still on 41.71 πŸ˜…

quiet nebula
quiet nebula
#

I may be wrong, but I noticed that while debugging, if I reloaded a file that was required from another file, it would still use the old code and still break on the same errors, even if I removed the script that caused the error

#

I may just not be so well versed in Lua yet, so I don't know what that common pattern is or what it's normally used for πŸ˜›

#

You take a function, put it in another variable, then overwrite the function and run the old function. How does that change the working of the function?

#

It still points to the old function, doesn't it?

quiet nebula
#

Okay, I fail to see what this would do to avoid pointing to the original version of the function.

#

I may have just misunderstood what someone else told me yesterday

#

I thought variables are just pointers to tables/functions in memory.

#

So if you make a variable that contains a function, won't it just point to that function in memory?

#

And why did you paste the same code twice?

#

Reloading copies the code?

#

Okay

#

Yeah

#

I see

#

I don't like the idea of just throwing your variables and functions into global

#

That feels hacky

#

Does this ring a bell to anyone?
Object table 0x1537339274 did not have __call metatable set.

Because I rewrote a good part of the structure of my mod to try to simulate a sort of extension pattern. But using copyTable may have screwed up my entire mod ^^;

#

I see...

#

Time to read up on what metatables are πŸ˜›

#
    name = "Basic",
    definition = require("SpecialZombies/Definition/Basic"),
    definitionName = "Basic"
}

function Base.makeNoise(zombie, playSound)
    local emitter = zombie:getEmitter();
    if not emitter then
        return;
    end
    addSound(nil, zombie:getX(), zombie:getY(), zombie:getZ(), 250, 250);
    if playSound then
        emitter:playSound(Base.getSound(), zombie);
    end
end

function Base.getSound()
    if not Base.definition or not Base.definition.sound then
        return "";
    end
    return Base.definition.sound;
end

return copyTable(Base);```This
#

But I realised now that this doesn't actually do anything to fix the caching issue with extending from multiple files

#

So the copy doesn't actually do anything for me

#

I've since reverted it and am now trying to figure out if I can do something like this:

return function()
    return Base;
end;```
#

Instead

#

I copied the table because I thought that might create a new instance of the Base table, but since the code and its results are cached on require, that doesn't do anything

#

I would need to return a function and have that function return a fresh instance of Base, instead

#

So I can do this:

Shrieker.name = "Shrieker";
Shrieker.definition = require("SpecialZombies/Definition/Shrieker");
Shrieker.definitionName = "Shrieker";```
And:
```local Boomer = require("Base")();
Boomer.name = "Boomer";
Boomer.definition = require("SpecialZombies/Definition/Boomer");
Boomer.definitionName = "Boomer";```
Without Boomer overwriting Shrieker
#

Base isn't global,

#

At least, I don't think so, I didn't say it should be anywhere, I don't even know how I would ^^;

#

Is that just saying global instead of local when instantiating the variable?

#

That's not what I'm worried about

#

I don't care about reloading

#

I want to be able to extend a table/class in multiple other classes

quiet nebula
#

But since the return value of a require is cached into one spot in memory and just gives a pointer to that bit in memory

#

So in order to not overwrite that, I want to get a fresh instance

#

Inheritance, extending

#

Ahh okay

#

So in my example that would be...

local Shrieker = setmetatable({}, { __index = Base });```
#

I require the Base, then set a metatable, so it doesn't overwrite the Base in memory

#

Yeah, in that case it doesn't

#

If I can avoid pointing to the same bit of memory, I don't need it to return a function

#

Ahh

#

Well, I tried returning a function

#

And it just turns into nil

#
[05-08-22 11:08:00.189] WARN : Lua         , 1659690480189> LuaManager$GlobalObject.require> require("Base") failed.
[05-08-22 11:08:00.189] LOG  : General     , 1659690480189> nil.
[05-08-22 11:08:00.189] WARN : Lua         , 1659690480189> LuaManager$GlobalObject.require> require("Base") failed.```
I printed the return value from the require
#

And it just gives me nil

#

It failed the require

#

Okay

#

It didn't really tell me why it failed

#

I'll check

#

That sounds like it'd help a lot, hahaha

#

Okay, what I said about that nil... Was from a typo >_>

#

I'll have to try it again, hahaha

#

Sorry about that

#

Oh... What

#

So if I refactor a variable in IntelliJ and then have it refactor references

#

It removes the modulename structure from the requires

#

That's how it broke

#

Lol

#

It turns SpecialZombies/Class/Basic Into Basic...

#

No wonder it gives nil

#

Awesome

#

Now to see if it all works correctly

#
Boomer.name = "Boomer";
Boomer.definition = require("SpecialZombies/Definition/Boomer");
Boomer.definitionName = "Boomer";

return Boomer;```And no errors
#
    -- Return a fresh instance, not related to Base
    return setmetatable({}, { __index = Basic });
end;```
heavy iris
#

Hey there! OMG a boomer zombies, we're fucked UP !

quiet nebula
#

πŸ˜›

#

"Get off my lawn!"

#

As it shambles toward you

heavy iris
#

Haha

quiet nebula
#

"Damn kids these days"

heavy iris
#

"get work you lazy shit !"

quiet nebula
#

Hahaha

heavy iris
#

"but... You're dead!"

shadow geyser
# quiet nebula ```local Boomer = require("SpecialZombies/Class/Basic")(); Boomer.name = "Boomer...

maybe Ive just missed something from the long thread of messages, but it seems like you are trying to create a base class that will later be inherited for other classes to make an object oriented way for defining them. Why don't you just base it on the way PZ already does that.

---@class ISBaseObject
ISBaseObject = {};

ISBaseObject.Type = "ISBaseObject";

--************************************************************************--
--** ISBaseObject:initialise
--**
--************************************************************************--
function ISBaseObject:initialise()

end

--************************************************************************--
--** ISBaseObject:derive
--**
--************************************************************************--
function ISBaseObject:derive (type)
    local o = {}
    setmetatable(o, self)
    self.__index = self
    o.Type= type;
    return o
end

function ISBaseObject:new()
    local o = {}
    setmetatable(o, self)
    self.__index = self
    return o
end
quiet nebula
#

"Back in my day... grumblegrumble"

quiet nebula
#

What is the difference between . and : when adding variables to tables?

shadow geyser
#

then just use the following to create the sub class

---@class CGlobalObject : ISBaseObject
CGlobalObject = ISBaseObject:derive("CGlobalObject")
quiet nebula
#

I've read that : makes it so the function has a copy of the object it is called on as its first parameter

shadow geyser
#

not sure what you mean by adding a variable to a table using : ?

quiet nebula
#

That would create a new instance with a different type

quiet nebula
#

function ISBaseObject:new()

#

I've only used function Basic.getSound()

#

Is there a functional difference between these two?

shadow geyser
#

ah ok, yeah its only relevant for functions, not values in general which is why I got confused

quiet nebula
#

My bad, I should've been more specific. But I'm not that familiar with lua, so I don't really know what the general difference is between both

quiet nebula
shadow geyser
#

do you know python? the easiest way I can think of to explain it is that using just a dot makes kind of a static function, whereas the : makes a normal instance function that uses self

quiet nebula
#

Ahh okay

shadow geyser
#

basically it is just syntactic sugar. using : means that the function will take self, without you needing to write it in

#

so doing
foo.bar(self, var1, var2)
is equivalent to doing
foo:bar(var1, var2)

quiet nebula
#

Ahh gotcha

#

Makes for a cleaner way of calling a function.

#

So calling it without providing self means it doesn't have a reference to the object it's a part of?

shadow geyser
#

I don't think there is anything actually different in the actual code while executing, but for the lua file, it just makes the file a bit more cleaner, by not requiring you to write self all the time

quiet nebula
#

Ah, gotcha

#

Thanks for the clarification! Very helpful πŸ™‚

quiet nebula
#

I see

#

So you can only use self in a function called like :func?

#

So turning this function from . to : means I can replace Shrieker with self

    local modData = zombie:getModData();
    if not specialZombieManager.isSpecialZombie(zombie) then
        return false;
    end
    return modData.ZombieVariety.type.name == Shrieker.definitionName;
end```And it should function the same
#

Just makes it look cleaner, by referencing self instead of the classname

#

But functionally the same?

#

I'm trying to verify some things based off my own interpretation of this function/feature of lua

#

Yeah, but I mean in my example

#

I currently reference the property of my class by referencing its name

#

But if I call it through :, I can replace that with self and get the same functionality, right?

#

So Shrieker.definitionName would become self.definitionName and work the same

#

If I call it like Shrieker:isShrieker()

#

Okay, gotcha. Thank you πŸ™‚

#

Ahh right, yeah, as I expected from inheritance, it will take the properties of the object it is called on, not the properties of the object it was initially added onto

sleek saffron
#

An example of what Olipro said is this simple logger I have that allows me to identify from which "scope" the print took place.


function My_Logger:LogInfo(msg)
    print(self.scope .. ' INFO: ' .. msg);
end

function My_Logger:new(scope)
    local o = {};
    setmetatable(o, self);
    self.__index = self;

    o.scope = '[' .. scope .. ']';

    return o;
end

return My_Logger;```

This is how i derive My_Logger in different lua files to have different scopes.

```local My_Logger = require 'Logging/My_Logger';
local Logger = My_Logger:new('foobar');
Logger:LogInfo("test");```

In this case, the print statement will translate to
``print("[foobar] INFO: test")``
quiet nebula
#

So like:

  A = "a"
}
function A:giveA() {
  return self.A;
}
Gives "a"
local B = A;
B.A = "b";
B.giveA();
Should give "b", not "a"```
quiet nebula
#

So it would output foobar INFO: test as a log line

sleek saffron
#

Yep, and like that, if i want to derive another My_Logger in another lua file, I can instantiate it with a different scope of the log. Idk if this helps you understand the concept better.

#

I learned most of this stuff from @thin hornet's mods. They're very cleanly written and easy to understand.

quiet nebula
#

Well, the problem isn't in understanding it. It's in verifying the functionality based off my own experience/knowledge from programming, with how lua works

#

Since I've not worked with a programming language before that uses these sorts of things

#

Most I've worked with before use this, which is probably the same as self, though self is usually used in a static context

#

But yeah, thanks, your example did clear some things up

sleek saffron
quiet nebula
#

Hehe ^^;

#

My next thing to figure out will be constructors

#

Though I think I can do that with the :new structure that PZMod has

#

And 'abuse' that to run code that has to run on every new instance of a specific class πŸ˜›

sleek saffron
#

I believe the :new approach is the standard for a "constructor" of derived classes in LUA. Don't forget that technically lua doesn't have the concept of classes like in OOP.

#

Which is what makes it a complete headache to work with sometimes, coming from an OOP background 😁

shadow geyser
#

yeah it took me a while to recognize that stuff as well. basically all the OOP stuff in lua are just implemented by hacking the metatables, which unless you understand how they work, takes a while to understand what it is doing.

sleek saffron
quiet nebula
#

They're basically all tables, right?

#

Just like how in javascript everything is an array

#

In lua everything is a table

#

Oh

#

Yeah, my bad

#

All objects are tables, I meant

#

Oh?

#

I see what you mean

heavy iris
#

yeah functions looks very interesting in lua

quiet nebula
#

A string is technically also an object, but with a string representation and some functions that can be called on it

#

Oh, okay

heavy iris
#

they're prerouted

quiet nebula
#

I see

heavy iris
#

what's userdata?

quiet nebula
#

Was about to ask the same, hahaha

#

Why is that a separate thing πŸ˜›

#

Aha

heavy iris
#

and when you run
local function f()

#

lua just create a route for f, and will pass through it only if later you do f(), right?

#

yeah yeah sry (edited)

sleek saffron
#

From my understanding, that is the same as local function f() right?

heavy iris
#

yes

sleek saffron
#

Yes I'd think so too.

heavy iris
#

yeah I'm wondering the info contained in this var

#

ok, sorry, I'll make my question more precise.

#

ok, I starteed something long, but I have a much simpler statement now

#

but first I wiki stuff

#

well I known nothing about ANSI C but shouldnt be a problem, question would be : how is a lua function implemented in ANSI C ? ^^

heavy iris
#

but java is very close to lua right? so yeah my question here is :
-is there something intereting happening during lua implementation in java ?

  • if not, how are java functions implemented in their source language, which must be more core (but that I'll read on wiki)
#

and, sry for spamming ^^', but I have another question about PZ.

If I run :
local newObject = IsoObject.new(square, sprite); square:AddSpecialObject(newObject); newObject:transmitCompleteItemToServer(); -- this transmit to server ,
once I run transmitCompletedItemToServer(), what happens?
The new object is registered forever in the save database, even if I quit and load, even if I (for instance) leave its area and come back later ?
or is there something more subtle ?

heavy iris
#

ok, so game takes care to keep it alive, thanks πŸ™‚

#

and thanks for that too, I thought the opposite, I'll read about that

quiet nebula
#

Does anyone know how something like this can be caused?
Exception: tried to call a non-function

    for k in self.types do
        totalWeights = totalWeights + self.types[k];
        print("Adding weight " .. self.types[k] .. " for type " .. k);
        i = i + 1;
    end```

At the first line of this for loop (the initiation of the for loop)
#

The object this for loop is run on is:

    types = {},                             -- List of all special zombie types and their probabilities+stats
    totalWeights = 0,                       -- Total weight, for use in rolling for special zombie type
    specialZombieProbability = 0.01,        -- Probability of a zombie being a special zombie
    specialZombieProbabilityRollMax = 100   -- Max roll for zombie probability roll
};```
#

Wait, you need pairs regardless?

#

Ahh

#

I thought that was only for key,value

#

I see

#

Ahh okay

#

Thank you

shy radish
#

Does lua have similar shortcut to JS spread operator?

#

Ohh nice. Thank you!

#

So I couldn’t do
β€˜β€™β€™
local x = unpack(someArray)
β€˜β€™β€™
At the top of a function?

#

Tables are reference types right?

#

so

local newTable = oldTable

would just give me the same reference pointer correct?

#

okay gotcha, ty for the help Oli πŸ™‚

wraith root
#

frog well looks like someone read the book

quiet nebula
#

I'm trying to emulate the effect of the random gunshot event. But I can't seem to get zombies to keep pursuing the sound I'm making. Does someone know how these environmental events are done or what the name of the gunshot event is so I can look it up?

#

I'm generating sound for the zombies to follow, but the zombies seem to just stop after a few seconds of walking.

agile vigil
#

Hey y'all, anyone know how to access localisation data via Lua?

I have a variable local animal = "Base.DeadRat" and I want to update it to be "Dead Rat" via the localisation features (when English is selected).

Looking at Eris' Food Expiry mod, I tried this code:

local animal = "Base.DeadRat";
animal = getTextOrNull("ItemName_" .. animal) or animal;

But I was unable to get a result with this (it just defaulted to my 'null value', being the original Base.DeadRat)

I have confirmed that in the localisation .txt it is indeed called:

ItemName_Base.DeadRat = "Dead Rat",
```Hence why I added the prefix.
#

Hm.. Do I need to add the default localisation files as a 'prerequisite' to my mod somehow?

#

The localisation I'm using is stored in the default translation files - the ones shipped with the game. I'm not defining any custom translations for ItemName_Base.DeadRat in my mod, and I'm wondering if my mod can find the vanilla translations.

#

And then I just put in "Base.DeadRat" as an argument? πŸ™‚

#

Huzzah, it worked, thank you so much for your assistance πŸ™‚

waxen badge
#

How will the new anticheat affect java modding? I hope it's not something like EAC...

#

I'm thinking about java making mods which would affect rendering of certain tiles.

wraith root
#

I don't think they would ever add EAC

waxen badge
wraith root
#

I hope not lol

#

Da booj

#

The Lua book lol

waxen badge
#

VRChat is a great example of how NOT to deal with problems like this.

wraith root
#

The game was luckily built with modding in mind

agile vigil
#

Ohfuck that moving grass looks trippy. Semi-related question, is it possible to release Java mods to the workshop, yet?

wraith root
#

If there were a turnaround come time with 1.0 releasing to remove modders, the community would probably disintegrate

#

Is that pipe wrench?

agile vigil
#

Genuinely a shame. How does it (if at all) work with Linux and Dedicated Servers?

waxen badge
#

From yesterday's post

#

"Lots of extra security and anti-cheat to MP"

wraith root
#

There aren't very many languages that aren't Linux compatible

#

Hm

#

Ahh wrong link type

#

Well, it's better to know the background of the language than to treat PZ use of Lua like it's the base foundation

#

At least I'd think so, :p

#

.
I wouldn't want to program a web service using only Minecraft's context of Java as my knowledge base

#

Crazy to think how small a language is when you see all of the manual on one page

#

Sadge

#

Trivial until you want to know what is going on behind the scenes like half the people in this channel

devout lynx
#

Does anyone have any idea of what kind of mod would break my ability to open a cars trunk?

#

im not running many, its confusing tf outta me

wraith root
#

Hmmm

#

Beard's server has dedicated kill on sight zones

#

So it is possible

devout lynx
#

nevermind, had no idea you needed to unlock the trunk from in the car lol

thorn musk
#

Anyone know how to use mods?

quiet nebula
#

Thank you, I'll check that out!

cosmic condor
#

ain't nobody got time for that

heavy iris
#

best upgrade πŸ˜„

wraith root
#

How large is comically large?

#

Is that a Java mod?

#

Need me a bic pen I can drive around

#

Or shoot from

#

I luckily have the most experience with 3d models, though PZ is not a very 3d model intensive game unless you're getting to the details

#

Noice

thorn musk
#

alr

#

how come my mods arent working, ive enabled the mods, ive put them in the server im hosting, is there any reason why they still arent working?

cosmic condor
#

what kind of not working?

thorn musk
#

they just arent in the game at all

#

but they work in solo

cosmic condor
#

you have to check your workshop id and mod id settings

#

in the server settings

thorn musk
gilded hawk
#

@craggy furnace Adding a dependency to another mod out of where it's not cool man. Half of my server lost the clothing.

#

I get it that you wanted to add the night vision but at least consider if an update can break other people saves and servers

thorn musk
#

.ini file?

gilded hawk
#

it's a private server with a fairly small mod list, I was not expecting this until I checked why the clothings where not spawning anymore and some of my friends where half naked

thorn musk
gilded hawk
#

mah

thorn musk
#

configure workshop id?

#

is it this?

cosmic condor
thorn musk
#

then what do I do

cosmic condor
#

did you publish your mod?

thorn musk
#

put the mods I want into the list?

#

I did

cosmic condor
#

yes

thorn musk
#

I did that already

cosmic condor
#

do in both workshop and mods

thorn musk
#

I did

#

When I started the server it still didnt work

cosmic condor
#

it should, if it's not then you miss something

thorn musk
#

let me try again

cosmic condor
#

this is a common problem for newcomers

craggy furnace
#

@gilded hawk lmao fuck off

gilded hawk
craggy furnace
#

ill do what i want with my mods as i wish

#

no, the rude part is believing i need to include you in planning and getting mad that i update the mod

gilded hawk
#

Adding dependencies out of nowhere can fuck up server setups and single player saves.

It's already a pain the ass seeing servers repacking my mods into mod packs without asking for permission, and a situation like this will make some server owners feel justified from repacking mods.

And at the end of the day the person getting the shit on is the mod dev and the end users.

And, I'm not mad I'm just a bit annoyed since I got the backups.

EDIT:

And I'm not saying you should include me in your mods planning, you should consider the 170k Subscribers.

cosmic condor
#

solution

  • create your own mod
  • just don't use that mod
  • go full vanilla
gilded hawk
#

lol a Dogecoin 0.00 refund would be nice lol

cosmic condor
#

This is an unnecessary complaint

gilded hawk
#

Yeah, I'm setting up a secondary server to test mod updates

gilded hawk
#

I get the same shit too on my mods, I think I'm not being a lunatic

#

I would not say entitled, but fair enough

sour island
#

Doesn't PZ already have a warning system for maps not being present - perhaps the requirement checks need to flag an alert?

gilded hawk
#

Well, I might have phrased that poorly

wraith root
gilded hawk
#

No warning as far as I'm aware, it just disables the mod that misses a requirement

#

I'm considering making a mod that checks that for me if a mod is being disabled automatically after a server reboot

sour island
#

Should just color the mod red like it does with maps and prevent you/warn you before loading in.

wraith root
#

I still can't imagine running a server with 100-200+ mods that weren't hand made by myself in a pack

cosmic condor
#
versionMax=41.71```
sour island
#

That sounds like a nightmare to maintain

wraith root
#

It's probably much easier when it's your own ecosystem

cosmic condor
#

require= ?

wraith root
#

I wanna make DDR for PZ lol

cosmic condor
#

not enough?

cosmic condor
#

create 1st mod that require 2nd mod > hide it > create 2nd mod > publish

sour island
#

I mean, that would break alot more than just throwing up an error saying "missing required mod, download? y/n"

cosmic condor
#

oh, it's working for mp server only lol. forget it

sour island
#

I don't think that's what happened.

#

Shark added a new requirement

#

MX's server booted up - and in the process identified SMUI was missing a requirement - and disabled SMUI

#

Yes

shy radish
#

Possibly stupid question but is regex the same in lua as it is everywhere or does lua have its own regex syntax?

shy radish
gilded hawk
#

Yeah

cosmic condor
lusty nebula
#

Guys I need a bit of help...
I want to add the attachments for the 40HE and 40INC rounds from the Brita's mod to the vest I've created but I have no idea about 2 things:

1- What name I have to use?
So far I have used for the 40HE rounds = Shells
and for the 40INC rounds = Projectiles
( Sample: attachment Webbing_Shell_Left and attachment Webbing_Projectile_Left )
but they don't work.
I see the other attachments use names like Knife, Walkie, Rope, Wrench, Pan and so on...so which ones I have to use for the 40 HE rounds and for the 40 INC rounds???

2- Where is located and what is the file that define the item used by the attachment? I can't find, related to the attachments, any file with written items like Base.40HERound, Base.40INCRound, Base.Knife, Base.Rope and so on

cosmic condor
#

oh, good to know, maybe I'm not dive deep enough

wraith root
#

Close enough

worn verge
#

HI! i have a question and i think this is the correct channel to make it. I want to modify a mod and change the time that a addon vegetable need to get bigger and can be harvested. Can i made it? Can i made it from the server options? i change the option from the server but when i save the changes and i start the word i get an error. has it solution or no? i only want to make it faster. i agree the mod link https://steamcommunity.com/sharedfiles/filedetails/?id=1703604612&searchtext=green+fire.

and that's the archive than i can change 4 make it faster but it give me the error.

#

if this isnΒ΄t the correct channel i change the message from other one sorry...

shy radish
#

Anyone out there good with lua patterns. I'm apparently awful and cannot use them lol

#

Yeah apparently lua has it's own thing similar to regex but slightly different. I havent used regex in ages either so I'm doubly bad at this lol http://www.lua.org/pil/20.2.html

#

"Collection(x,y,z)" I wanna get xyz

wraith root
#

Is there a simpler way to parse ints out of a string?

shy radish
#

well xyz in this case are actually words not numbers

crude zinc
#

Does any of you by any chance know which mod or mod type might give you another belt at spawn?

drifting ore
# worn verge HI! i have a question and i think this is the correct channel to make it. I want...

hi there my dude, i'm new here as well but I think I can help. in order to change the time the plants take to grow you would have to edit a lua file. I'm pretty sure the code that controls the growth time is in media/lua/client/Timed/GFtimetracker_definitions.lua. Here's part of that code:

--11 to 17 days to dry if untrimmed
ItemTimeTrackerMod["FreshUnCanna"] = {};
ItemTimeTrackerMod["FreshUnCanna"]["Life"] = ZombRand(264, 408)/div;
ItemTimeTrackerMod["FreshUnCanna"]["TurnInto"] = "Greenfire.DryUnCanna";
--5 to 14 days to dry if trimmed
ItemTimeTrackerMod["FreshTCanna"] = {};
ItemTimeTrackerMod["FreshTCanna"]["Life"] = ZombRand(120, 336)/div;
ItemTimeTrackerMod["FreshTCanna"]["TurnInto"] = "Greenfire.DryTCanna"

So the part you'd need to change would be the numbers in ZombRand() to fit whatever new time you want.

Here's the thing though, if you are running a server then everyone that joins your server will need that updated file. And if the mod author updates his mod then it might overwrite your changes. So really, it's not set up to be changed easily in a server setting. You could probably make that change in singleplayer though if you wanted. Hope that helps!

shy radish
#

oooo tyty Oli!

drifting ore
#

i read somewhere that zombie ai is controlled through mods pretty much exclusively through sound events. is that true, and if so, is something like making a single zombie in a horde stop in place not feasible?

#

that's totally fine, this is a cursory idea tbh. i have a backlog of... easier mods to write first but I will definitely update you eventually!

#

the idea is basically bear traps. chance to recover trap tied to trapping skill. ideas are a dime a dozen though πŸ˜…

crude zinc
#

Is a text-to-speech mod possible for player voicelines or for the mod " Conditional Speech "

#

would be really funny to see and hear

drifting ore
#

what's the mod that allows zombie to revive with chances?

void bay
#

hi, is there tutorial about adding starter items?

drifting ore
#

i think getPlayer() isn't used as much anymore but whatever your player object is, those are the functions you can call to populate it

#

anyone happen to know how to do lua syntax highlighting in discord btw

#

oh perfect, thanks a lot!

thin hornet
#

can try csharp

drifting ore
#

i don't know enough about lua to recognize proper syntax highlighting anyway. as long as the funny colors show up i'm happy

wraith root
#

Mobile doesn't have syntax highlighting unfortunately but it shows for PC users

#

Even then it's pretty terrible highlighting

thin hornet
#

it just works lol

wraith root
#

I found a wild cousin of @thin hornet

#

on code academy lol

toxic walrus
#

Is there anyway to get an item property thats not included in the get method?

winter bolt
#

gonna lose my mind

shadow geyser
#

but like does it require it or just "require it"

wraith root
gilded hawk
#

Can it happen that in a server the modded maps randomly stop working?

Apprently on my server I got only the vanila map now

#

these are my settings tho

# Enter the foldername of the mod found in \Steam\steamapps\workshop\modID\mods\modName\media\maps\
Map=Muldraugh, KY;AZSpawn;Blackwood;FortRedstone;Fort Rock Ridge;Grapeseed;NewEkron;researchbase;researchbaseroad
#

I'm supposed to have the military base here, but now it's only forest wtf happened O.o

#

Research facity is working tho

#

I never had this problem in 300 hours in SP, what is this?

#

Same problem with Blackwood;FortRedstone;Fort Rock Ridge;Grapeseed;NewEkron;

shy radish
#

For the "random" sandbox options in zombie lore, does anyone know how that works on the back end? Does the zombie get assigned a random value between 1 and 3?

mellow oyster
#

So does anyone know how to display a custom png when i select a specific option on an item, like a map does?

thin hornet
thin hornet
shy radish
gilded hawk
#

Like, the map has the place, but the place is not there.

#

And all other mods that add new places are just not there wtf 😐

wraith root
unkempt bronze
#

Hi guys, might a be a dumb question. But is their a specific mod that allows you to attach a radio and join tcs ex. tunein 001

?

wraith root
#

?

unkempt bronze
thin hornet
mellow oyster
thin hornet
late otter
#

Okay, so I realized that I cannot for the life of me find a mod out there that adds in rechargeable batteries. I have never modded a game before, let alone Project Zomboid, but I feel compelled to fix this. That said, I would welcome help in figuring out how to do this.

#

For example, the PZ modding guide by Fenris Wolf doesn't explain what the 'item block' is when scripting.

mellow oyster
thin hornet
#

You need to find example of what you need inside
C:\Program Files (x86)\Steam\steamapps\common\ProjectZomboid\media\lua\client\ISUI

#

UI can be complicated when starting out

shy radish
#

Has anyone come across a bug where when your character dies, all the UI gets black squares around everything? I’m wondering if this is a regular bug or my mod is breaking something haha

humble oriole
#

Is there any documentation that explains the send command to console logic? I'm having trouble wrapping my head around it and my google fu is failing me

mellow oyster
wraith root
#

But not recharge

late otter
#

Fair enough. I dunno, I think that rechargeable batteries would be good if balanced properly- having to craft them using scrap metal and electronic components, needing... I'd say 4 Electrical skill? 5 or 6 maybe? And you can slowly recharge them in an item you can plop down in any powered tile, but once the power goes out, that's going to drain your generator further, and rechargeable batteries back then took hours to recharge even for something as small as a AA.

shy radish
#

What's the difference between these three?
OnCreateLivingCharacter
OnCreatePlayer
OnCreateSurvivor

rain iron
#

Hi, what would actually be the correct way to set the amount of spawnable loots on a specific type of zombie? I'm pretty sure I am mixing up loot distribution with loot amount atm.

rain iron
#

ahh, I actually saw that post yesterday but I wasn't sure if it also works the same way on zombies instead of on containers

drifting ore
#

ah no worries, that's actually my bad ^^ full disclosure I haven't messed with distributions myself yet. But take a look at media/lua/server/Items/Distributions.lua. Specifically there's distributionTable.all.inventorymale and distributionTable.all.inventoryfemale.

Also! at the end of distributionTable.all there's what looks like a good example:

        -- This is an example to add a specific distribution on a dead corpse according to his outfit
        Outfit_Generic99 = {
            rolls = 1,
            items = {
                "Wallet", 100,
            }
        },

if you figure out how to tell which outfits represent which let me know ;)

rain iron
#

Thank you, it's going to take me quite a while since this is my first time coding in Lua actually pancakes_hedgehog

drifting ore
#

hey same here lol, that's why i'm lurking this channel seeing if I can learn more by trying to help

#

plunger gang lets go

drifting ore
rain iron
#

thank you!

#

Actually I think my zombies will need a custom model too, is it possible to implement an entire new zombie model, or at least a zombie with unremovable clothes?

drifting ore
#

no idea on that one unfortunately hehe

quiet nebula
# shy radish What's the difference between these three? OnCreateLivingCharacter OnCreatePlaye...

Looks like LuaEventManager.triggerEvent("OnCreateSurvivor", this); LuaEventManager.triggerEvent("OnCreateLivingCharacter", this, this.descriptor);are triggered together whenever a IsoSurvivor is instantiated. Though I don't know if IsoSurvivor is even used in the current game.

But only LuaEventManager.triggerEvent("OnCreateLivingCharacter", this, this.descriptor); is triggered on instantiating IsoPlayer

OnCreatePlayer is triggered when a Coop player is added and when you exit the loadingscreen. So it all depends on when you want something to trigger

late otter
#

Huh. Interesting, thanks!

#

It didn't mention that in the mod description or name, so I didn't find it before.

lusty nebula
#

Sorry guys a very stupid question but sometimes with different languages can be hard getting the sense of certain things...I've read often thing like " Lore friendly, Zombie Lore, etc...
What does it mean " Lore "? ( Translator return me odd results )
Thanks! πŸ˜‰

quiet nebula
#

Lore means the backstory/world of a work.

#

Lore is usually used to mean backstory or history of a world

lusty nebula
#

Thanks mate, you've been very kind! πŸ˜‰

quiet nebula
#

So lore friendly means it doesn't take you out of the fantasy and it should fit in the world as it is

#

So adding something like laser guns wouldn't be lore friendly