#mod_development
1 messages ยท Page 43 of 1
how do i put it in mods folder
i took it out
bc i deleted all my mods
from files
it'll load the mods folder in your workshop folder structure
i dont have mod IN the folders
Just put the zip I sent you in Zomboid/Workshop
oh ight
With all your files in the right subdirectories
it'll appear in the game again after that
here??
And you can test it
Exactly
nO
Wait
Shit
Zomboid / Workshop is not the same as ProjectZomboid / Workshop
Here
does zomboid even load the mods in ProjectZomboid/mods either?
i remember tripping up on that when i very first started
I'm looking for some guideance to get my simple model to work. Currently I have an fbx (ClubV1.fbx) in the models_X folder. I created an item (copy of the nightstick) and tried to use my fbx. But it's not showing something in the hand... What steps do I have to do?
item ClubV1
{
DisplayCategory = Weapon,
MaxRange = 1.2,
WeaponSprite = ClubV1,
MinAngle = 0.72,
Type = Weapon,
MinimumSwingTime = 2,
KnockBackOnNoDeath = FALSE,
SwingAmountBeforeImpact = 0.02,
Categories = SmallBlunt,
ConditionLowerChanceOneIn = 20,
Weight = 1.5,
SplatNumber = 1,
PushBackMod = 0.3,
SubCategory = Swinging,
ConditionMax = 15,
MaxHitCount = 2,
DoorDamage = 1,
SwingAnim = Bat,
DisplayName = Club V1,
MinRange = 0.61,
SwingTime = 2,
KnockdownMod = 0,
SplatBloodOnNoDeath = FALSE,
Icon = RawBat,
RunAnim = Run_Weapon2,
IdleAnim = Idle_Weapon2,
BreakSound = NightstickBreak,
DoorHitSound = NightstickHit,
HitSound = NightstickHit,
HitFloorSound = NightstickHit,
SwingSound = NightstickSwing,
TreeDamage = 0,
CriticalChance = 25,
CritDmgMultiplier = 2,
MinDamage = 0.6,
MaxDamage = 1.1,
BaseSpeed = 1,
WeaponLength = 0.45,
AttachmentType = Nightstick,
}
I renamed the fbx file for the folder (ClubV1.fbx).
this?
yeah!
tysm
Yeah mods in either Workshop or mods (the old place you were testing) will show up as loadable in game
Stella kratao maxairi
yeah it has to be 256x256
there's also a file size restriction but you're unlikely to run into that
ight
@hearty dew Because your my current Java/Lua lowlevel god. Do you know if there's a potential solution for this? The java code has 3 overloads and I would like to call the one with IsoObject (but object is nil).
Tell that to all the poor Rimworld modders
LOL is that a problem in rimworld??
l.inspect(IsoObject)
---------- table ----------
table 0x1899911670 {
[class] => (userdata) class zombie.iso.IsoObject <
. <METATABLE> => table 0x789091424 {
. . [__index] => table 0x682936769 ** PRUNED. Max depth reached **
. }
>
[factoryFromFileInput] => function 0x119961287
[FindExternalWaterSource] => function 0x319974980
[FindWaterSourceOnSquare] => function 0x1463048914
[getNew] => function 0x1413892139
[factoryGetClassID] => function 0x1617071146
[getLastRendered] => function 0x1619177004
[setLastRendered] => function 0x362125860
[getFactoryVehicle] => function 0x1937018797
[getLastRenderedRendered] => function 0x117657141
[setLastRenderedRendered] => function 0x1912955703
[setDefaultCondition] => function 0x1274581993
[factoryFromFileInput_OLD] => function 0x480666844
[factoryClassFromFileInput] => function 0x21619611
[OBF_Highlighted] => (userdata) 1
[OBF_HighlightRenderOnce] => (userdata) 2
[OBF_Blink] => (userdata) 4
[MAX_WALL_SPLATS] => (userdata) 32 <
. <METATABLE> => table 0x431509976 {
. . [__index] => table 0x1658513944 ** PRUNED. Max depth reached **
. }
>
[rmod] => (userdata) 0.0 <
. <METATABLE> => table 0x1477190750 {
. . [__index] => table 0x1466209133 ** PRUNED. Max depth reached **
. }
>
[gmod] => (userdata) 0.0 <
. <METATABLE> => table 0x1477190750 ** PRUNED. Cycle/duplicate detected **
>
[bmod] => (userdata) 0.0 <
. <METATABLE> => table 0x1477190750 ** PRUNED. Cycle/duplicate detected **
>
[LowLightingQualityHack] => false
[new] => function 0x2018221529
}
Try calling the new static method on IsoObject (You'll need to check what the parameter types are in java).
local dummyIsoObject = IsoObject.new(...)
ty for yalls help
Looks fine to me!
Everyone can easily read the name
@blissful salmon Before you do that, actually, what is the parameter used for? Maybe passing it an IsoPlayer or IsoZombie would be appropriate (IsoObject is a superclass for them, iirc)
So if I use the constructor public IsoObject()
I afterwards can set my object = nil?
So:
local dummyIsoObject = IsoObject.new(...)
dummyIsoObject = nil
You didn't seem to give it a type huh?
nahh
couldnt be arsed
its all the same
gonna change icons
well then
The java code passes the nil object without problems I think but if I pass a square like I described in my soundstuff above then the exact coorinats are overwritten by the coordinates of the square...
No, that wouldn't work
So you're trying to pass null to the java method? If so, I misunderstood your initial question
The code for the square call:
public long playSoundImpl(String var1, IsoGridSquare var2) {
this.x = (float)var2.x + 0.5F;
this.y = (float)var2.y + 0.5F;
this.z = (float)var2.z + 0.5F;
return this.playSoundImpl(var1, (IsoObject)null);
}
I want to directly call the return playsound
Trying to call playSoundImpl with null as the 2nd arg?
yes.. but it has 3 overloads (IsoObject, IsoGridSquare, third is irelevant)
is that a good pic for the workshop
Yes, like in the java function (IsoObject)null
I think that might not be possible in kahlua. I assumed kahlua just looksup the java.lang.reflect.Methods for the method name and matches the argument types.. Let me see how this is implemented in kahlua. Hopefully it has some way to do this
Is there a good source for this? So I also can try to check for this kind of stuff? For info I found a very similar call in the CharacterSoundEmitter but there is only one method who is accepting an object. So this works ( from ISAddItemRecipe.lua:
self.sound = self.character:getEmitter():playSoundImpl(soundName, nil)
For each invoker ,it does prepcareCall and then checks if the args are valid in that last link
Here is where it adds multiple java invokers. It just adds additional ones if one with the same method name already exists
I was never a Java developer but I could see that so far... ๐ Bit isn't the problem more on the side what I pass as argument?
What you pass on the lua side is retrieved in prepareCall (looks like by callFrame.get())
To be honest, this is more than my brain could take right now...
ok
What's the exception text you get when you try to pass nil?
Give me a second. I provoke the error.
and stack frame too, actually
I'me confused right now. I call the following:
local player = getPlayer()
if key == Keyboard.KEY_NUMPAD8 then
local square = player:getSquare()
local soundEmitter = getWorld():getFreeEmitter(player:getX(), player:getY(), 0)
--getWorld():takeOwnershipOfEmitter(soundEmitter)
local soundId = soundEmitter:playSoundImpl("ZombieDemonScream", nil)
soundEmitter:setVolume(soundId, 0.55)
end
but now it plays the sound. Don't know why this works now and which method it does choose...
To be clear I call this test with the Event: Events.OnKeyPressed
l.inspectJava(getWorld():getFreeEmitter(getPlayer():getX(), getPlayer():getY(), 0), "playSoundImpl")
========== fmod.fmod.FMODSoundEmitter@f470030 ==========
---------- grep: playSoundImpl ----------
---------- Instance Methods ----------
Return Type Method Name Parameters
long playSoundImpl(String, boolean, IsoObject)
long playSoundImpl(String, IsoGridSquare)
long playSoundImpl(String, IsoObject)
I suspect it selects one of those last two overrides
It kind of have to bi the last, because with the IsoGridSquare it doesn't check for null...
public long playSoundImpl(String string, IsoGridSquare isoGridSquare) {
this.x = (float)isoGridSquare.x + 0.5f;
this.y = (float)isoGridSquare.y + 0.5f;
this.z = (float)isoGridSquare.z + 0.5f;
return this.playSoundImpl(string, (IsoObject)null);
}
Yea, I see what you mean. If it were this override, it would throw a null pointer exception.
exactly... but I don't know why it works now...
public long playSoundImpl(String string, IsoObject isoObject) {
GameSound gameSound = GameSounds.getSound((String)string);
if (gameSound == null) {
return 0L;
}
GameSoundClip gameSoundClip = gameSound.getRandomClip();
return this.playClip(gameSoundClip, isoObject);
}
This one calls playClip, which is public. Maybe you could call playClip directly to not rely on kahlua not selecting the other override that would cause an exception ๐
GameSound and GameSoundClip are exposed, so that should be doable
Maybe I made an error when I tested it before. But I'd rather use the square if I can't say for sure what is called...
Now I feel stupid ๐ฆ
Sure, that makes sense if you have a gridsquare
I'll test...
Is this playing the audio clip with stereo directionality for you?
But I first have to see how I got the GameSound
yes
The emitter plays it from the coordiantes given...
Do it exactly as it does it.```lua
local gameSound = GameSounds.getSound("soundname")
if not gameSound then
-- handle error
end
local gameSoundClip = gameSound:getRandomClip()
return soundEmitter:playClip(gameSoundClip, nil)
Awesome :)
Took me long time to figure this out... ๐
I don't even have stereo, so I didn't know there was directionality in the audio ๐
Think this works. I'll do further testings in multiplayer when I have time ๐ But this all seems promising...
I want the player to say a message. How do I get the local player? AFAIK I can do Player:say("Hello World") but not sure how to get the object
Does anybody can (or is at least willing) to help me with this? A friend made this simple club for me. But I'm just a coder and don't get what exactly to do here.
Generally, you want to get the player object from some other context if you want it to work in split screen mode
getPlayer():Say("Hello World")
thanks โค๏ธ
Sorry, missed the link:
#mod_development message
Hmm, not sure. Haven't fiddled with models yet. The peeps in #modeling might be more familiar with doing that
is there a general list of weapon stats, preferably with brita's weapons?
pzwiki has stats for vanilla weapons
I know the other channel... Hoped someone can help me from coder to coder. Because I have no experience with modeling... ๐
Im brand new to modding pz
ight
All Ive done is look at code and try to pick out patterns
Ive tweaked stats at most
i have not messed with that stuff
idk
@bronze yoke was looking at most popular 6 months and i found this aha
Yea Ive wanted to make a portable wood stove mod for a while
hell yeah
@weak sierra Updated Dawn of the Zed... you can hide the dag'on cursor now. And doing so is optional (in Mod Settings). Thanks again, @bronze yoke
Note that you will have to redo your Mod Options if you had UI default off. This is a result of redoing my Mod Options set-up in a hopefully better way that required keys to change. It is not a bug.
How do you make new items in game?
In the following table snippet, what is the correct syntax to reference the procList fields and properties?
bookstore = {
shelves = {
procedural = true,
procList = {
{name="BookstoreBooks", min=6, max=99, weightChance=100},
{name="BookstoreMisc", min=0, max=99, weightChance=20}
bookstore.shelves.procList[1].name?
bookstore[shelves][procList][1].name?
Something else?
bookstore.shelves.procList[1].name
bookstore["shelves"]["procList"][1]["name"]
Either of those work, but it assumes there is at least 1 value in procList. If there isn't, the value returned by doing [1] will be nil, causing the following .name or ["name"] to cause an error
If you can't guarantee procList has at least one element in it, you'll want to do something different to avoid the error. What are you trying to do to those procList elements? Add one, delete one, find one and modify it's contents?
I'm actually trying to parse Distributions.lua in a C# program. I can enumerate a table down to procList, and at that point I'm trying to get any/all fields and properties within
But honestly this is kind of a headache
Probably easiest to encode to json or similar and then decode in c#
That's a good suggestion, and one that I've come across once or twice so far in my Googling
Did you just have that lying around or did you use a tool to convert it?
Used http://regex.info/blog/lua/json to do it in the pz debug console
Thanks. I'm working with a library that allows me to work with Lua, but I might check that out if I get stumped. Just figured out how to execute a function to get the length of the procList table
so, previously modded this game fine, but now in me and my friend's personal server, it just won't mod at all
i've enabled it both in the menu and the game's server settings but nada
when i press esc and click 'mods' in the bottom right, the section is blank
i also can't access map mod priority order
ah wrong place mb
finally learning what the heck __index and metatables are today. Thank you roblox forums
The lua manual is pretty useful for that too. It's relatively short and succinct in its explanations
this guy described things in a way a 12 year old could understand, which is good because thats about as much mental capacity as I have left at the end of a work day
actually, the 5.4 lua manual is good at describing metatables. The 5.1 isn't :p
The 5.1 manual just gives you code lol
what version is pz anyway?
5.1, but __index is the same between 5.1 and 5.4 as far as I know
5.1*
*: kahlua's 5.1
right, an incomplete 5.1 from what I'm told
Mm, has some missing apis and some bugs here and there
Goodday yal
So if there is an api to wait for a function to complete and you can provide it args and also specify an optional timeout, what would be a good interface?
function awaitTask(func, args, timeout)
-- where args = {arg1, arg2, ...}
function awaitTask(timeout, func, ...)
function awaitTask(func, ...)
-- where args go after func, and the optional timeout is the first param?
Something else?
I like passing an args table because then you don't need to get the order of the inputs correct tbh
if you put in a timeout, it should probably be its own argument, at the end where it can easily be omitted
so the first one
Oh, you'd still need to worry about the order here. The above would be used like:```lua
function myFunc(arg1, arg2)
return arg1 + arg2
end
```lua
function myTask()
local result = awaitTask(myFunc, {5, 10})
end
actually I guess you would still need the order of the inputs correct, because the function isn't going to know what order to unpack them
ya
yea
still the first one though, with the caveat that timeout should just be given some default value if not supplied
curious though, does ... pass by reference like an args table does?
each of the params are passed individually as far as I know (numbers would be passed by value, for example, and table by reference)
same as normal
I wonder if that's better or worse
No chance another else can get MoodleUI's setVisible(false) to hide the Moodle UI is there? I could not figure it out earlier, and my workaround is giving me a headache too, lol, enough so that it would be ideal to avoid the workaround entirely...
I tried so many ways... MoodlesUI.getInstance():setVisible(false), MoodlesUI.getInstance()[0]:setVisible(false), MoodlesUI.getInstance():setVisible(false), UIManager.getMoodleUI(0.0):setVisible (and 1.0), all kinds of stuff failed me ๐ฆ
better or worse in terms of what?
garbage collection, performance
generally I like to pass as much by reference as possible, as long as the data can get closured in some way to prevent any weird behaviour
Oh, not sure. I double it's an issue with a couple hundred function calls. Might be something to measure once you get into 10k function calls
I have a different brain teaser for you, if you're interested
Well, passing some things (e.g. int) by value is often faster than passing by reference
or can be depending on a number of variables (relationship in memory)
I'll take the eye emote as a maybe'
Let's hear it lol
let me see if I can get it as plain as possible
the mod I'm working on is to flesh out the engine and engine mechanics
as such, I've appended a list of parts to the engine as moddata. This includes everything from sparkplugs, connecting rods, lifters, etc etc
damage to the engine, as well as the engine's stats, and various new effects from things like low oil or poor cam timings have been implemented
MoodleUI is nil (i.e. not exposed)? Or am I missing something?
gotcha
I tried a lot of things for about an hour awhile ago, couldn't find the right thing. I know it's exposed. I figure I'm using it wrong but no idea how it wants to be used.
Hmm, not sure. There is a render method on it. I imagine you could patch that to not render
However, there is one last thing missing: I want the parts to only be visible and accessible, if it makes sense. Player's shouldn't be able to check the condition of the piston, for example, without removing the cylinder head. The piston shouldn't be removable without at least pulling off the oil pan and maybe crankshaft. Modeling these relationships in an extendable and logical way has been eluding me
setEnabled might be worth trying
These parts are parts you are adding, I presume? Haven't gotten into the mechanics system far enough to know what's already there
The vehicle has actual Part objects, but my parts are merely small tables in the moddata. The intention is to generate InventoryItems as needed when those parts are removed, but not actually utilize the vanilla parts system
didn't work to make the moodles ui disappear
currently the only Part in the engine is the engine itself, which does nothing aside from take damage, in vanilla
Yeah I tried it a few ways too
I initially thought of having Attachment points on each part, and using keys relate them to the parts that are attached there... but thats clunky and wasteful, there has to be a good way to do this
UIManager.setVisibleAllUI(false) will hide it @hearty dew ... Doesn't help me to know that, but you are, you know, you.
How do you see this being visualized. Like how is the player going to take off the cylinder head and then be able to see the camshafts status?
I've added an "Engine Mechanics" window, almost a carbon copy of the Vehicle Mechanics window, but for the engine alone. Same as the Vehicle Mechanics window, all the parts show up in a list on the right. I plan on greying out any part that is currently not "visible", so that the player would need to pull parts out to get access to it
Hmm, tricky part for me is understanding the nature of all the types of relationships there are between the parts to then come up with a good model
Similar to the vanilla mechanic forcing you to take a tire off before you can remove the brakes, but with an added visibility element
I thought of modeling it as a tree, with the leaves being the external visible parts, but that's not going to work
Something like this where a node (part) is only visible when all nodes with edges pointing to it are visible
What is the issue with that model?
some parts can be accessed in different ways from different directions. Again leaning on the piston example, you can SEE it from above OR below by removing different parts. Also, it can only be removed from below, so I have to decide if I want visibility and accessibility to be different or just say "if you can't get a tool on it, you can't 'see' it"
Right. That's why I was thinking a graph might fit better
you're probably right, just trying to mull over how that would actually work
visibility and accessibility
ah, that complicates it heh
Spark plugs are a good example of that. Immediately accessible, but only "visible" if you pull them out, or take the head off
Might have two graphs based on the same set of vertices, one for visibility and one for accessibility
engines are similar enough that these graphs could potentially be generalized into functions rather than imprinted on the parts themselves, but I'm not sure
Did they have rotary car engines in 1993? ๐
I believe the wankel existed, ya... its in my engine type enum, just in case, lol
seems like I will have to separate accessibility and visibility, something like this:
| Accessible | Not Accessible
Visible | "Exposed" | "Visible"
Not Visible | "Obscured" | "Hidden"
Thinking something like this.. So if you want to check whether the cover gasket can be removed, you'd check all outgoing edges to see whether they have been removed (the head cover, in this example)
and do that recursively
Ignore the cylinder head -> gasket arrow. That doesn't really make sense
Seems simple, so my brain is rejecting it
I think it will work, just have to be smart about it
@candid light If you remember the spawntweaks thing I talked about eons ago, it's nearing a workable state. If you're fine downloading most of the common/less common vehicle mods (soft requirement), I can send you the link for testing ๐ค
It also has support for your zones mod, too.
engineBlock = {
isInstalled = true,
partsBlockingVisibility = {},
partsBlockingAccessibility = {},
}
headGasket = {
isInstalled = true,
partsBlockingVisibility = {},
partsBlockingAccessibility = {},
}
cylinderHead = {
isInstalled = true,
partsBlockingVisibility = {},
partsBlockingAccessibility = {},
}
cylinderHeadCover = {
isInstalled = true,
partsBlockingVisibility = {},
partsBlockingAccessibility = {},
}
cylinderHeadCoverGasket = {
isInstalled = true,
partsBlockingVisibility = {},
partsBlockingAccessibility = {},
}
exhaustManifold = {
isInstalled = true,
partsBlockingVisibility = {},
partsBlockingAccessibility = {},
}
exhaustManifoldGasket = {
isInstalled = true,
partsBlockingVisibility = {},
partsBlockingAccessibility = {},
}
intakeManifold = {
isInstalled = true,
partsBlockingVisibility = {},
partsBlockingAccessibility = {},
}
intakeManifoldGasket = {
isInstalled = true,
partsBlockingVisibility = {},
partsBlockingAccessibility = {},
}
table.insert(engineBlock.partsBlockingAccessibility, cylinderHead)
table.insert(headGasket.partsBlockingAccessibility, cylinderHead)
table.insert(cylinderHead.partsBlockingAccessibility, exhaustManifold)
table.insert(cylinderHead.partsBlockingAccessibility, intakeManifold)
table.insert(cylinderHead.partsBlockingAccessibility, cylinderHeadCover)
table.insert(cylinderHeadCoverGasket.partsBlockingAccessibility, cylinderHead)
table.insert(exhaustManifoldGasket.partsBlockingAccessibility, exhaustManifold)
table.insert(intakeManifoldGasket.partsBlockingAccessibility, intakeManifold)
function isAccessible(part)
for _, p in ipairs(part.partsBlockingAccessibility) do
if p.isInstalled then
return false
end
end
return true
end
table 0x713881734 {
[isInstalled] => true
[partsBlockingVisibility] => table 0x1641781397 {
}
[partsBlockingAccessibility] => table 0x2107390646 {
. [1] => table 0x1511959155 {
. . [isInstalled] => true
. . [partsBlockingVisibility] => table 0x387658110 {
. . }
. . [partsBlockingAccessibility] => table 0x716770360 {
. . . [1] => table 0x921487955 {
. . . . [isInstalled] => true
. . . . [partsBlockingVisibility] => table 0x428782543 {
. . . . }
. . . . [partsBlockingAccessibility] => table 0x1464918337 {
. . . . }
. . . }
. . . [2] => table 0x896204639 {
. . . . [isInstalled] => true
. . . . [partsBlockingVisibility] => table 0x1703151091 {
. . . . }
. . . . [partsBlockingAccessibility] => table 0x167297607 {
. . . . }
. . . }
. . . [3] => table 0x1500668112 {
. . . . [isInstalled] => true
. . . . [partsBlockingVisibility] => table 0x989920422 {
. . . . }
. . . . [partsBlockingAccessibility] => table 0x2121194920 {
. . . . }
. . . }
. . }
. }
}
}
Something like that might work
since approx 1950s ish
Thought they were much newer than that in cars. Wow
I was thinking maybe something like this
AccessGraph = {
[Part.FanBelt] = {},
[Part.Piston] = {{Part.OilPan, Part.CylinderHead},{Part.OilPan, Part.CrankShaft}},
[Part.CrankShaft] = {Part.MainBearing},
[Part.MainBearing] = {Part.OilPan},
[Part.CylinderHead] = {Part.ExhaustManifold, Part.IntakeManifold, Part.CylinderHeadCover},
[Part.CylinderHeadCover] = {},
[Part.Radiator] = {},
[Part.WaterPump] = {},
[Part.HeadGasket] = {Part.CylinderHead},
[Part.SparkPlug] = {},
[Part.IntakeManifold] = {},
[Part.ExhaustManifold] = {},
[Part.Alternator] = {},
[Part.FanBelt] = {},
[Part.AlternatorBelt] = {},
[Part.SuperBelt] = {},
[Part.SerpentineBelt] = {},
[Part.Starter] = {},
[Part.CamShaft]= {},
[Part.Lifters] = {},
[Part.PushRods] = {},
[Part.Valves] = {},
[Part.Distributor] = {},
[Part.Carburetor] = {},
[Part.FuelInjectors] = {},
[Part.AirFilter] = {},
[Part.OilFilter] = {},
[Part.OilPan] = {},
[Part.TimingBelt] = {},
[Part.TimingChain] = {}
}```
then I could treat it like template, have different access graphs for different engine types
First production car with one was in 1967 
just looking for resources on the last engine I owned in the 90s, the LM1, to get an idea of how a GM 350 engine would have been put together
Mm, that will serialize into mod data easier too
I'm thinking leaving the templates outside of the moddata, and storing the installed parts only in the moddata
Well, depends on that those keys are, actually. If they are tables, maybe not
I don't actually know how/if pz serializes tables as keys ๐ค
they are my fancy enums that looks Something like
Parts = {
Sparkplug = "Sparkplug",
Fanbelt = "Fanbelt",
...
}
Tyr, how do bullbars (or other items, really) apply a protective effect on whatever part they're covering? 
Kinda looking at the M998, saw front and rear health but no real modifiers on the entries around the bullbar
I haven't the slightest idea. I think Anonymous looked at that some time ago. Or someone did. I recall a convo about it
from what I've seen, most mods store the condition of all the parts on the vehicle, and check every tick whether they've changed and revert the changes if applicable
that being said, there is a "Front end condition", I can't currently remember how it factors in though
that seems like a PITA.
But yeah, seems to be correct, the M998armor.lua does seem to store part conditions ๐ค
I've come up with some better ways to mitigate damage from zombies, crashes and wear and tear
but I haven't yet figured out how to deal with weapon damage
I am listening with both of my ears and all of the hair on my body 
lol
because the way zombies interact with vehicles in terms of damage (and them slowing down to a crawl) has caused me mental agony
unfortunately we are locked clean out of the physics engine, so its very difficult to impossible to mitigate the slowdown, but the damage is easy to deal with
I noticed that vehicles have physical mass, does that affect anything at all?
yes, mass and engine power control how quickly you accelerate, and also how well you stick to the road
one thing to try is to maybe increase the weight and power equal amounts when you hit a zombie, might make running them over easier, I haven't tried it yet
detecting when you've hit a zombie at speed is easy, I'll give you the secret: any impact with a zombie (and potentially player) that is hard enough to cause damage also leaves some blood on the car. Its very computationally inexpensive to check the blood levels
but if you do that around the corner, handling would be impacted, correct?
Sounds "simple" enough. Sadly I lack the know-how to do these things, the spawntweaks I've made with the help of a buddy is about as far as it goes for me 
it very hard to tell how handling is effected by anything. The game does limit your steering power the faster you go, but I'm pretty sure wheel friction, suspension damping, compression etc all play a part in how a vehicle actually handles, but that's all done in the physics engine, which can't even be decompiled afaik
Override:true doesn't seem to work on recipes for me. Is it broken or am I missing something?
Fair enough. I do hope you're able to release your mod sooner rather than later. It kind of sucks when other vehicles are trivialized by KI5 vehicles solely due to them having a bullbar
Meanwhile other vehicles which have a visual one on their model still fall apart 
Not to mention trucks. 
I'm considering making my vehicle damage detection an api so others can use it as well, but I'm probably not going to release anything until build 42, since there is a vehicle revamp coming then, and also there is an intentional bug in the java code right now that makes it very hard to change engine power
dev said it to me personally in this very channel
lol
I don't think its been mentioned in the blogs
a
it's likely that vehicle armour could be added then anyway
did they go into any detail as to the nature of it or just a "might wanna hold off there for a bit, bud"
they did make it sound like they were putting in means of adding armor as well as detecting damage, which makes a lot of my current work obsolete
Outstanding
That'd allow me to make crazy mods
They better make this in December or January so I can flip off new mods on industrial scale
i would be shocked if b42 was out that soon
Well.. Still would mean that modders would have to update their vehicles, assumedly.
unless they make it a system of "armored doors" instead of normal doors, etc. etc.
They probably won't make it incompatible
You can't just break mods and call it a day
they totally can
Yeah but have they ever
most b40 mods don't work at all
Not like they'd break them, they just wouldn't make use of the new systems, methinks
from the sheer scale of b42 i would expect a lot to break
ya, absolutely
although i wouldn't worry much about things they haven't mentioned specific plans of reworking
p sure they'd give modders time to update their mods ahead of time anyway
unstable branch and such
i don't expect my vehicle armour mod to work in b42, but i'm optimistic that they'll make it obsolete entirely
that's the hope 
devs making the modder's work obsolete is a desirable outcome
basements have been confirmed iirc?
i'm pretty happy with how the models are turning out, but i'm not an artist, tis would do much better
I hope so for me as well. For now I just play with my java modded to what I think build 42 might look like for vehicles, but its unlikely that I'm right
As long as they one up me by a significant margin, I am completely ok with them integrating "my" mod concepts
well like
them revamping the whole coordinate system just to add basements is wild
if they somehow did it worse than me i would just make my mod improve it
Nah they said they were working on it iirc and it may be a thing, and most likely not in B42
such is the nature of the beast.
But it isn't just for that, I think.
Futureproofing, prolly
a
they've definitely mentioned wanting motorbikes and stuff and b42 sounds like the perfect time to add them
seems like B42 is gonna be the feature playground build
can I set up a fake controller for testing
i'm most excited for that skill revamp honestly
hopefully that'll solve the sometimes strange balance
Optimization is the highest factor for me atm
also i'm unreasonably excited for that light propagation stuff, it doesn't have a big gameplay effect i just think it's super cool
Some of my friends' potatoes wanna throw themselves off a cliff.
And even my PC is still working harder than it should
Same here lel
i'm a big fan of playing with pitch black nights so more variance in light levels always sounds good to me
I'd consider it if light levels made more sense. Flashlights would become a bit nicer to use too
full tilt down the highway is like 10fps for me, optimization is definitely very welcome
amen
plus when i was new to the game i thought zombies were attracted to light and was super careful with curtains and stuff and i want to return to that life
and I have a rtx 3080
this game just hammers the CPU
I felt that
Turning off the flashlight and seeing absolutely nothing thinking I was so smart
they do see flashlights
they don't
โ๏ธ
someone's life has been a lie, just not sure whose
turning on lights at night does attract zombies, but it doesn't matter if you have curtains or even a solid wall
lmao
and it's only house lights that does that
Probably due to sound too
yeah it's just a sound
furiously clicks the light
could have sworn I saw it in the code, the flashlight has to be pointed directly at them though
and they have to be turned towards you too
well i'd be happy to be proven wrong
inb4 anon was just dreaming about PZ
I could be imagining things. A quick search shows very few mentions online of it

that they're attracted to light switch noises is dumb though
My friend actually did this to us once and I was so mad lmao
Still need the blinds
well hopefully with light propagation they'll get rid of that
this game uses to many visible/audible and invisible/inaudible sound pulses
๐ค i could probably make zombies attracted to the flashlight
give them pinpoint hearing and they'll instil the fear of god into you
although with my experience with pitch black nights it's not too necessary
if you can see them, they've seen you
one of my runs was ended by me very carefuly fortifying a house, putting up blinds etc, only for a zombie to break in next door and trigger the alarm
LOL
that's cursed
thats what gives this game its charm imo, lol
yeah i never even considered the possibility
everyone gonna double and triple check their neighbors for the next few days 
Hi there, just to let you know the domain zomboid-javadoc.com is going to expire on the 23rd of december. If you're using the website please consider making a donation on my ko-fi (see my discord profile).
Anyone happen to know a good way to get the number of clients connected to a server (server-side in lua)?
Not seeing any useful apis on the GlobalObject.
Can probably do it by inferring which players are splitscreen based on how the server assigns online IDs, but hopefully there is something less brittle to change
Hi, i try to make a mod but none of these two scripts are loaded in the game. I'm unable to start a game with it, and i don't understand why. I think there's an error somewhere but i don't know where.
pigments.txt : https://pastebin.com/Nzm6UHHB
paintbuckets.txt : https://pastebin.com/9mXxaRD7
Can you help me with it ?
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
there is nothing special in the console
Pigments doesn't seem to be closed properly with the module tag
Arf, that's right, i try them again
How Do I actually upload my mod to the workshop?
C:\Users\PCNAME\Zomboid\Workshop here you will find an example
then in the game menu, select "workshop" and then by common sense you will know what to do
thanks
I'm really confused, why database is management from client side(? It isn't a vulnerability?
local playersOnline = getOnlinePlayers():size()
Superb Survivors Window type Quest Dialogue Demo
works with mp?
Hey it's a Nolan sighting
no because this is a quest system for superb survivors and i dont plan to make that mp compatible, would require serious overhaul to do so
I suppose this is MP for people without friends
Hi, do you know how the Heat value work for items ? Actually, Heat:-0.22 in recipe is Hot, but i don't really understand what it really means. Any maths behind this ?
No sorry. I just stuck to it. And used that too for our cup noodles mod
Juat went and used game logic without understanding it ๐
lol okay ! myb we need to ask to a dev
Anyone know where/what to look for to add onto or modify the 'toggle held light' action?
Can't really find any files using 'torch' 'light' 'flashlight'
there's a timed action for lightswitches
media/lua/client/ISUI/ISLightSourceRadialMenu.lua heh
Didn't even know you could activate the radial menu for lights
so I didn't bother checking
getCore():getKey("Equip/Turn On/Off Light Source") helped me find the standard 1 press
I still struggling with adding a weapons using my fbx as model. I also ask my question in the #modeling channel so far but till now didn't get an answer. If someone could give me a hand to add a simple model to the game I would really appreciate it (I absolutely have no clue about this stuff). I described my current situation in the post: #mod_development message
I am having trouble with making a UI panel interactable in the world map screen. Unlike the vanilla ISWorldMapSymbols element, if I create a new ISPanel,ISPanelJoypad or ISCollapsableWindow on the World Map, then I can't click on it, and in the case of the ISCollapsableWindow I also can't close, move or resize it. Therefore, any additional elements within the panel (buttons, checkboxes, etc.) can't be interacted with, the game just behaves as if I was clicking on the map itself and dragging it around instead of my new UI element.
Is there a way I can fix this? I'm trying to look through code for ISWorldMapSymbols in search for something that makess the map screen treat an element as "solid", but so far I've not found anything that would work in my case.
You wanted a link?
https://steamcommunity.com/sharedfiles/filedetails/?id=2881519066
Here
can someone help me with some crafting recipe stuff?
Basically i want my crafting recipe to have 2 different items as output
You'll going to need to make an event for it I believe
you need an OnCreate function
{
CannedTomato,
Result:farming.Tomato=5,
Time:30.0,
OnCreate:Recipe.OnCreate.OpenCannedFood,
Category:Cooking,
OnGiveXP:Recipe.OnGiveXP.None,
}
Like here. Recipe.OnCreate.OpenCannedFood spawns an empty jar in your inventory
so the thing i am testing with is a couch
{
Plank=4,
keep Saw/GardenSaw,
keep Hammer/BallPeenHammer/HammerStone,
Result:Moveables.furniture_storage_01_52,
Time:240.0,
SkillRequired:Woodwork=7,
Category:MathoulDrawers,
AnimNode: BuildLow,
Prop1: Hammer,
Sound: Hammering,
OnGiveXP:Recipe.OnGiveXP.Woodwork11,
}
so i would have to create an on create function like
result:Moveables.furniture_seating_indoor_03_16;
result:Moveables.furniture_seating_indoor_03_17;
end```
?
sry kinda new to that and just learning to make some small things for a server
local jar = items:get(0);
local aged = jar:getAge() / jar:getOffAgeMax();
result:setAge(result:getOffAgeMax() * aged);
player:getInventory():AddItem("Base.EmptyJar");
This is the one that gives you a jar
oh so i will need player:getInventory():AddItem("Base.EmptyJar");
just with the proper item
thank you
yes
I have been trying to use this but I cannot get it to work. I may be misunderstanding how to utilize it. Could you possibly give an example on how to write a lua table to json using this?
So basically what i am trying to craft is this 2 seated couch
For some reason
player:getInventory():AddItem("Moveables.furniture_seating_indoor_03_17");
end ```
Does not spawn the item in however if i change it to "Base.EmptyJar" it gives me a jar
The Result of this recipe works tho but the only issue is i kinda need both halfs to be created and thats what i struggle with rn
``` recipe Test
{
Plank=4,
Nails=2,
Woodglue=2,
Drawer=1,
keep Saw/GardenSaw,
keep Hammer/BallPeenHammer/HammerStone,
Result:Moveables.furniture_seating_indoor_03_16,
Time:240.0,
SkillRequired:Woodwork=7,
Category:TestCouch,
AnimNode: BuildLow,
Prop1: Hammer,
Sound: Hammering,
OnCreate:Recipe.OnCreate.CustomRecipe,
OnGiveXP:Recipe.OnGiveXP.Woodwork11,
}```
ignore the ingredients lol its just a copy paste from a drawer that i created before
it works perfectly fine with single tile items however once its 2 tiles it gets wonky
okay... You might need to add the Module name to the furniture
As in Base. or whatever mod it's from
Also there may be checks in place to not overfill player inventory?
UdderlyVehicleRespawn.GetViaReflection(zone, "public IsoDirections dir")```
--Reflection Wrapper
UdderlyVehicleRespawn.ReflectionCache = {}
function UdderlyVehicleRespawn.GetField(obj, fieldString)
local cachedValue = UdderlyVehicleRespawn.ReflectionCache[fieldString]
if cachedValue == nil then
local num = getNumClassFields(obj)
local idx = nil
local zones = nil
for i=0, num-1 do
local field = getClassField(obj, i)
if tostring(field) == fieldString then
UdderlyVehicleRespawn.ReflectionCache[fieldString] = field
end
end
end
return UdderlyVehicleRespawn.ReflectionCache[fieldString]
end
function UdderlyVehicleRespawn.GetViaReflection(obj, fieldString)
return getClassFieldVal(obj, UdderlyVehicleRespawn.GetField(obj, fieldString))
end
--End Reflection Wrapper```
Q: anyone know why i can't retrieve the field "public IsoDirections dir" from vehiclezone via reflection?
everyone has their own reflection wrapper to make it comfy lol
https://zomboid-javadoc.com/41.65/zombie/iso/IsoMetaGrid.VehicleZone.html#dir
zone is filtered down to vehicle zones only
btw if anyone is unfamiliar with routine caching of things, take a look at how i use a table there to reduce repeated checks to a very fast keyed lookup
can make your mods much faster in some cases
repost of what i asked last night which got buried instantly :P
so it gives me the (1/2) part but not (2/2)
and i use the item type displayed there
u cant make a recipe give you two things
u have to add an OnCreate function
and make it give u the second one
getPlayer():getInventory():addItem("whatever") or etc
That's what he did
oh.
ive never messed with that kind of item, so im not sure if there's any special magic around them
Which makes me think the moveable furniture isn't an item
yeah it's some kind of magic thing
i believe
but it should still be possible shouldn't it
At least it should throw an error or something
yeah but not even an error
its kinda weird
main reason i want to go the crafting menu way and not the RMB menu like carpentry is that if you have too many items its just massive and annoying bloat
i could bypass it by making 2 recipes but i would prefer it to be a single craft else there is bloat in the crafting window ๐
I suppose, try adding the module to the item? How it's defined in the lua files?
this is kinda all i can find when i search for that tile
tho i am only searching in the media folder
No, media should have them all?
I don't know tbh
It should work
Maybe without the Moveables?
moveables are really weird
yeah
some tables if you pick them up their item becomes "Moveables.moveable"
and there is like
500 moveables.moveable
maybe moveables are just one item with different properties...?
Yet listed multiple times, magic nonsense
cant even find this lol
Did you make the tiles sheet?
its base pz
in-game item list doesn't have couches either, i'm guessing multiple part moveables are just a generic item with properties and not unique items
yeah, it's all moddata looks like
i dont understand why they are even 2 items to begin with...
yes some couches are multiple pieces but that couch isnt lol
another thing, are you in debug / do they fit into your inventory
ReadFromWorldSprite(string) seems relevant
I was doing something similar but I added scripts for the moveables, to spawn with debugger easier
hmm
main reason for all this is that its for a RP server and stuff like More builds is just massive clutter and not really something you want on a MP server since it uses wood to create metal objects aka you can craft, disassemble and get metal
itemTest5
{
Type = Moveable,
WorldObjectSprite = test_4,
DisplayName = Moveable,
}
try to create the objects from console and print result
not sure it is moddata actually, can't find anywhere in the lua or java that this moddata is actually set
might just be for modders or something
you mean like this?
itemTest5
{
Type = Moveable,
WorldObjectSprite = furniture_seating_indoor_03_16,
DisplayName = Moveable.seating,
}
just to test i did put in the whole PZ folder lol
will see if i find anything
print(InventoryItemFactory.CreateItem("Moveables.furniture_seating_indoor_03_16"))
getPlayer():getInventory():AddItem('Moveables.Moveable'):ReadFromWorldSprite('furniture_seating_indoor_03_16') spawned the first half
seems perfect except i have no idea how to get 2/2 yet
doesn't work for sprite 17?
that does work, didn't know that was how moveables worked ๐
@devout galleon
getPlayer():getInventory():AddItem('Moveables.Moveable'):ReadFromWorldSprite('furniture_seating_indoor_03_16')
getPlayer():getInventory():AddItem('Moveables.Moveable'):ReadFromWorldSprite('furniture_seating_indoor_03_17')
your oncreate function would look something like this
function Recipe.OnCreate.CustomRecipe(items, result, player)
player:getInventory():AddItem('Moveables.Moveable'):ReadFromWorldSprite('furniture_seating_indoor_03_17')
end
I don't know how heavy it is but might be better to put those on the floor.
yeah it's 15 ๐จ
oh lemme see
oh my god yes it works thank you sooooooooooooooooooo much!
how would i make it that the result is placed on the floor?
might be useful since i plan to allow beds to be crafted too and i doubt someone can carry those kingsize beds haha
is it possible to define the crafting icon in the recipe?
so it does not draw from the result?
getSquare() instead of getInventory() i think
i see will try it
noticed tho if you craft something that goes over your 50kilo limit it drops it on the floor automatically
anyone know where I can find the 3D models for the ammo boxes? I can't find 556 and 308 in the gamefiles
^ok apparently they are only one model and texture. very cool
That's the number of online players. If one client has two players, that result will not be the number of clients connected to a server (e.g. if some client has split screen players)
There is one for coop - I didn't realize what you actually wanted
for playerIndex=0, getNumActivePlayers()-1 do
This one may have to be ran from client side and have information sent over
local json = require("lib/JSON")
ArendamethUtils.writeFile("myserializedtable.json", json.encode_pretty({foo="bar",baz={1,2,3}}))
Plop JSON.lua from http://regex.info/blog/lua/json into media/lua/shared/lib/JSON.lua
I am surprised that getOnlinePlayers wouldn't return the IsoPlayers for everyone though?
@LuaMethod(
name = "getOnlinePlayers",
global = true
)
public static ArrayList getOnlinePlayers() {
if (GameServer.bServer) {
return GameServer.getPlayers();
} else {
return GameClient.bClient ? GameClient.instance.getPlayers() : null;
}
}
public static ArrayList getPlayers(ArrayList var0) {
var0.clear();
for(int var1 = 0; var1 < udpEngine.connections.size(); ++var1) {
UdpConnection var2 = (UdpConnection)udpEngine.connections.get(var1);
for(int var3 = 0; var3 < 4; ++var3) {
IsoPlayer var4 = var2.players[var3];
if (var4 != null && var4.OnlineID != -1) {
var0.add(var4);
}
}
}
return var0;
}
I think getOnlinePlayers is meant to return all players regardless of coop
I don't want coop. You can have one client on a dedicated server that has multiple players. getNumPlayers doesn't work server-side:
Notes:
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
```
It does. That's why it doesn't return the number of clients (it returns the number of players)
Ah I get what you mean now
I'm trying to get the number of clients not players
must have misread
The way the server assigns online ids to players is done in such a way that I should be able to infer which players are from the same client (it seems to assign them in blocks of 4 for each clients to allow for run a 4 online ids for the players on the udp connection for that one client). It's a rather brittle solution though since it is coupled to implementation details, will break if pz devs change it
what about ```java
public static UdpConnection getConnectionFromPlayer(IsoPlayer var0) {
Long var1 = (Long)PlayerToAddressMap.get(var0);
return var1 == null ? null : udpEngine.getActiveConnection(var1);
}
I would assume each client is one connection? You could parse through and not record duplicates
yea, each client is one connection
That's on GameServer, which isn't exposed, I believe? Let me double check
I'm scanning through uses of udpEngine.connections.size to see if there's anything
Yea, GameServer isn't exposed, otherwise this would be too simple ๐
Well sending server commands only goes through 1 connection
You could have a ping-pong of server to client to server
But honestly, checking the online IDs seems like less of a headache
I get you want to look out for maintainability but sometimes that 80% 20% rule kicks in
oh, yea. That wouldn't work for what I'm doing. I'm trying to make a coroutine that blocks until all clients respond to a server command, so would be awful to double the network traffic to do that hehe
yea
I'll just go with inferring based on the online IDs for now. Nothing else seems to stand out as a better option at this point. Thanks
np
Honestly surprised there isn't already a 'getConnections' feature
looking through the java - they use getconnections internally and for loop Isoplayers each time - when it could be it's own function
I presume the devs decided not to expose the connections, as it's be rather powerful to be able to send packets directly. GameClient, GameServer, UdpConnection, all not exposed
Would be quite handy though
Ah
GameServer.udpEngine.connections.size();
is used all over GameServer.
I imagine the first dev did it that way, and the pattern emerged
I mistook each use as also parsing through the 1-4 isoPlayers
weird that gameclient isn't exposed but the lua global object has a getter for it
I recall reading some brief remark from a pz dev (on forum maybe? idk) that suggested that there was a lot more exposed to lua previously (java.lang.reflect.Method, java.lang.reflect.Field, etc) that they have since removed. That getGameClient api might be a left over they missed
Oh, wait, there's a field to get the UdpEngine on the GameClient. If I can get the number of connections via fields alone, that could work :o
On client-side:
on server-side:
๐ญ
If a class is exposed would all the subclasses be as well?
MediaData is exposed but MediaData.MediaLineData is not
java.lang.RuntimeException: attempted index: getTextGuid of non-table: zombie.radio.media.MediaData$MediaLineData@1421bc76
I'm assuming that's why I'm getting this
Not necessarily, no
I was hoping I could get around a really old issue, so I'm trying to take a crack at it
If the guid is readable from a field, you could get it that way
I tried also if mediaLineData.getTextGuid as a means to make it compatible when it can be used - but that also sends the same error
How can I get an instance of a MediaData to check?
function SRJ.getListenedToMedia(player)
local knownMediaLines = {}
local ZR = getZomboidRadio():getRecordedMedia()
local categories = ZR:getCategories()
for i=1,categories:size() do
local category = categories:get(i-1)
local mediaType = RecordedMedia.getMediaTypeForCategory(category)
local list = ZR:getAllMediaForType(mediaType)
for j=1,list:size() do
---@type MediaData
local mediaData = list:get(j-1)
print("Watched - mediaData: ".." ("..mediaData:getId()..") "..mediaData:getLineCount())
for jj=1, mediaData:getLineCount() do
---@type MediaData.MediaLineData
local mediaLineData = mediaData:getLine(jj-1)
if mediaLineData then
--TODO: Bother Nasko about adding: this.setExposed(MediaData.MediaLineData.class); in LuaManager.java
local lineGuid = mediaLineData:getTextGuid()
if lineGuid then
print(" ---getTextGuid: "..tostring(lineGuid))
if player:isKnownMediaLine(lineGuid) then
print("Watched - "..tostring(lineGuid))
table.insert(knownMediaLines, lineGuid)
end
end
end
end
end
end
return knownMediaLines
end
It's a bit buried
I'm trying to fetch and apply known media lines
IsoPlayer's knownMediaLines is unfortunately not gettable
although you can add/remove from it
ah that's right, I forgot debug mode lets you do some checks for that
text is what I'd need
is there a method to finding if an item has a custom name or not? isCustomName doesn't seem to detect any change
yea, debug mode you could write fields and invoke methods
in non-debug, can only read fields
reading would be fine
I've read fields before but then I was trying to set it
didn't know reading works in non-debug
do you have the field stuff handy?
nvm found my old stuff
Oh, wait, the text field has a guid in it. Is that not the guid you are after?
Would need to parse it a bit
the text field is what I need exactly
the knownmedialines in IsoPlayer seems to just be a collection (hasmap if I recall) of those guids
this is what I was doing a while back for setting a field
local function setZombieSpeed(zombie, speedVal)
--TODO: Figure out how to get this to work outside of debug
for i = 0, getNumClassFields(zombie) - 1 do
---@type Field
local javaField = getClassField(zombie, i)
if javaField then
if luautils.stringEnds(tostring(javaField), '.' .. "speedType") then
print("-EHE:SWH: javaField: "..tostring(javaField))
if not javaField.setInt then
print("-EHE:SWH: setZombieSpeed: ERROR: javaField.setInt not found.")
return
else
javaField:setInt(zombie,speedVal)
end
end
end
end
end
do you still need to parse through each field?
yea, have to iterate over them to find the right one
print(l.debugGetFieldValue(l.debugGetFieldValue(getMediaData(),"lines"):get(0),"text"))
function getMediaData()
local player = getPlayer()
local knownMediaLines = {}
local ZR = getZomboidRadio():getRecordedMedia()
local categories = ZR:getCategories()
local category = categories:get(0)
local mediaType = RecordedMedia.getMediaTypeForCategory(category)
local list = ZR:getAllMediaForType(mediaType)
return list:get(0)
end
--[[
Usage example:
ChuckUtils.debugGetFieldValue(getPlayer(), "MaxSpeed")
]]
ChuckUtils.debugGetFieldValue = function(object, fieldName)
for i = 0, getNumClassFields(object) - 1 do
local field = getClassField(object, i)
if string.find(tostring(field), "%."..fieldName) then
local result = getClassFieldVal(object, field)
print(string.format("Field value result:\n%s\n%s", tostring(field), tostring(result)))
return result
end
end
return (ChuckUtils.getFieldValue(object, fieldName))
end
local getFieldValueCache = {}
--[[
Usage example:
local value = ChuckUtils.getFieldValue(getPlayer(), "public float zombie.characters.IsoPlayer.MaxSpeed")
----
local value, cachedField
value, cachedField = ChuckUtils.getFieldValue(object, "private int zombie.iso.Foo.otherthing", cachedField)
]]
ChuckUtils.getFieldValue = function(object, fieldName, field)
if field then
return getClassFieldVal(object, field), field
end
local className
if getmetatable(object) then
className = tostring(object:getClass())
else
className = tostring(object)
className = className:match("([^@]+)@") -- zombie.network.GameClient@c6e80100
if not className then
error(string.format("ChuckUtils.getFieldValue: ERROR: Unexpected format for %s", tostring(object)))
end
end
getFieldValueCache[fieldName] = getFieldValueCache[fieldName] or {}
local cachedField = getFieldValueCache[fieldName][className]
if cachedField then
return getClassFieldVal(object, cachedField), cachedField
end
local numFields = getNumClassFields(object)
for fieldIndex = 0, numFields - 1 do
local field = getClassField(object, fieldIndex)
if fieldName == tostring(field) then
getFieldValueCache[fieldName][className] = field
return getClassFieldVal(object, field), field
end
end
local errorOutput = {"\n"}
table.insert(errorOutput, className.." has the following fields:")
for fieldIndex = 0, numFields - 1 do
table.insert(errorOutput, tostring(getClassField(object, fieldIndex)))
end
table.insert(errorOutput, "\n")
print(table.concat(errorOutput, "\n"))
error("ChuckUtils.getFieldValue: ERROR: Unknown fieldName: "..tostring(fieldName))
end
debugGetFieldValue is easier to use in the console. getFieldValue caches the field object to avoid the cost of looking it up via reflection multiple times
Might be buggy. Haven't used this version with the cache yet aside from testing it a bit. Let me know if there are any issues with it
If you give it a wrong name, it will print out all the proper strings that can be used for the fieldName
What issue is that? Just curious
People can rewatch VHS tapes of TV shows to stack XP
might still be an issue tbh
now that I think about it
welp
having the lines in the journal prevents using the TV shows after reading but I need to figure out how to see if they watched before
Btw, couldn't I just do local lineGuid = getClassFieldVal(mediaLineData,"text") ?
Not with the way it is written above
In debug, because Field is exposed, you can :getName() (I believe) to just do "text". That's the way I had written it at first, but then it wouldn't work in non-debug.
You could write it to parse out the last bit after the final . from the full name of the field though
(sort of like how debugGetFieldValue does)
Instead of```lua
string.find(tostring(field), "%."..fieldName)
could do something like
```lua
string.find(tostring(field), "%."..fieldName.."$")
Whats the difference between getConnectedPlayers() and getOnlinePlayers()?
I'm wondering because both return an array with players...
And before I forget... Still craving for help...
#mod_development message
in VFE they have separate ones
and in most other gun mods
might be why
Notes:
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
getConnectedPlayers seems to be for messing with the scoreboard
and returns 0 or returns stale data most of the time
ok... so what do I use when I want to loop through all current player on the server? getOnlinePlayers()? I thought I read something above that this doesn't work serverside...
yea, getOnlinePlayers() if the code is running server-side
SoulUtils = SoulUtils or {}
--[[
Gets all players matching a predicate. The default predicate is all players that aren't dead.
Usage example:
local all_living_players = SoulUtils.getPlayers()
local all_players_named_bob = SoulUtils.getPlayers(function(p) return p:getDisplayName() == "bob" end)
Notes:
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
]]
SoulUtils.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 == true or 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 == true or predicate(player)) then
table.insert(result, player)
end
end
end
return result
end
for _, player in ipairs(SoulUtils.getPlayers(true)) do
print(player:getDisplayName())
end
It will take care of server-side/client-side specifics
but this uses getOnlinePlayers() on server... so it works?
getOnlinePlayers:
- Singleplayer: nil
- Client: lists all players (including split screen players)
- Server: lists all players (including split screen players)
getOnlinePlayers works on client and server. In singleplayer it returns nil
ok... this is no problem...
Is there an easy way to go through all active zombies in the world on server side? My question above was already for a not so clean solution (iterate the player get the cell get the zombielist). But if there is a better way I open to it...
I see another mod using getCell():getZombieList(). I really don't know. What's a cell vs a world map is something I'm still not clear on yet
public static IsoCell getCell() {
return IsoWorld.instance.getCell();
}
iirc getCell returns the active cell
I presume there is 1 cell per world? Not sure
and cells are 300x300 pieces
300x300 tiles?
and grid squares are blocks of tiles (10x10, or around there, I think it was variable?)
Ah, okay
going back to this though, there is no way to iterate over ever zombie if the player isn't near it - otherwise the zombie is unloaded
going through the players is probably the only logical way to go about it
you could try identifying duplicate cells in the case of multiple players if you were worried about that
or even check the duplicate on the zombies
What is your eventual goal?
so the cell is at a fixed place? not wandering with a player I suppose? If there are multiple players in different parts in the world there should be multiple active cells or did I get this wrong?
I want to go through all active zombies and check if it's time to do a scream...
But if I standing on the edge of a cell do I get the zombies of the cell right next to me?
cells are 300x300, chunks are 10x10
it is not variable
Yes
Ooh, that makes sense. That explains these variables:
IsoChunkMap.ChunkWidthInTiles -> 190
IsoChunkMap.ChunkGridWidth -> 19
clarification: i don't know what it does in memory, but on disk chunks are fixed
the same files for the same cells
the same number of files
The 'Cell' is handled per client - not sure what coop does - maybe it handles up to 4
But why? Is the method description unclear? It's another cell...
i only deal in dedicated mp
From what I understand chunks are not fixed on the map
i can copy a chunk file out of a save
and put it in another save
and it will be the same area
the filenames never change
each cell has the same number
961 files per cell
maybe it's broken down to make the scope easier to read?
makes me think what the point of cells are
map loading
afaik
there's metadata stored at the cell level
then the actual data for the tiles is at the chunk level
ah, like lots and stuff
if u transplant chunks from one save to another without the cell files
u lose all ur items
retain tiles
chunks are only tiles
zombie data is in zpop files
and vehicles are in vehicles.db
so the map is broken down into both cells/chunks
outside of the map files entirely
one of my first mods was in this topic to let me reset cells selectively
but I've seen something that handles the player's scope of whats loading also referred to as a chunk
recommend skimming its code
would probably tell u a lot
or maybe just redundantly what i already told u
idk
that's bad
we call that the reality bubble in my experience
lol
it's 150 around the player
so half a cell in any direction
that sounds familiar
I could have also just misread like I usually do
I for sure never saw reality bubble tho lol
i mean im speaking of what players call it
and modders
i have no idea if the code somewhere refers to it as something else
I'm even more confused... I checked the javacode for getCell():
public IsoCell getCell() { return IsoWorld.instance.CurrentCell; }
So I'm not sure if I can use this on serverside. Because on server side the Worlds CurrentCell can't be the same on every player.
that's just a static instance
So my idea don't work i think.
oh
it isnt it seems
huh
well on the server u can use that
i have done it
but i have no idea what the current cell is in that circumstance
lol
i was calling things that should be static but aren't
so it didn't matter
hmm... I have to inspect further... But sometimes I try to understand what I'm coding ๐
I think the server has it's own 'client' instance - but I don't think it would help in this case
Your code would have to be ran on clientside for getCell() to work
the server is a headless client, yeah
My idea was to do the check every 10 minutes instead of zombieUpdate. just because of performance...
kinda curious how that works
it'd be cool to hijack that to move the "player" around to force load stuff
if it's that complete anyway
but now it seems that the onZombieUpdate is the more safe approach...
you can do a bypass
similar to how ontick houses onhour etc
but I dump shit in updates all the time to no impact lol
also, @hearty dew ๐
I still need to sit down and figure out how to prevent gaining XP from the known media :\
In the case of people watching the VHSs before reading
With this, if they read prior, the TV shows shouldn't do anything
Does it need to be timed to wall clock or in-game time?
What exactly are you trying to achieve again? I don't recall seeing it mentioned
Atm I use the onZombieUpdate to apply settings from the moddata some zombies have. I made a list of all zombies I already checked so I can jump out as soon as possible from onZombieUpdate. when the settings are applied (in my testcase zombies that where resurrected player) I want to do a scream which is hearable by every player. At the moment I did it in the 10minutes function on server to trigger. So far it worked in my solo test... But now I try to make it multiplayer...
Hi, I don't know if this is the channel to ask, but does anyone know how to design textures for vehicles? I have the model but I don't have the knowledge in design
So basically you want to make player deaths generate a scream?
or just zombies that scream every ten minutes
#modeling probably will have more people familiar with doing that
Goal is that it happens to all clients at the same time. I don't know how exact I want to time it... for example every 4th ingame hour... Or maybe add a random range of time do a minimum. For example somewhere between 6 and 10 hours.
Like all zombies?
can anyone confirm if player usernames are/aren't unique? it just uses your steam username right, couldn't two players have the same one?
SteamID is unique
I want to make a scream when the player dies and then from time to time like I described.
So if I understand your requirements.. When a player dies, it emits a scream. And also, all zombies that were previously players should screen at the same time on all clients. The time at which the ex-player zombies scream is still up in the air but it seems to be periodic with perhaps some randomness?
Hi, is there a way to add "pour on ground" option on right click on a new drainable ?
I'm trying to get kind of an all in one solution. I also think about to adding it to modData and the check on the clients... But then I have no event and have to check every tick or zombieUpdate.
Currently I'm using this on server
zombie:addWorldSoundUnlessInvisible(150, 100, false)
and this on client:
Events.OnWorldSound.Add(OnWorldSound)
Events.OnPlayerDeath
There is that for player deaths. Its parameter is the player object.
But im not sure if this is a good option.
you might not need modData tbh
iirc, the game has a variable for former player zombies
public boolean isReanimatedPlayer() {
return this.bReanimatedPlayer;
}
If you wanted them to do it insync
Yes when the player dies. And than per zombie on clients at the same time... so maybe one zombie is earlier one later...
the onPlayerDeath is a good option for the first scream...
so the zombies should be screaming periodically and independently
Okay thanks
Idk if zombies store modData
This Is what I use serverside to apply settings. I have to reapply them every time the server starts... I want do manipulate other zombiestuff later... So I try to get an universal solution.
The first scream is not the problem but I struggle with syncing the others.
they do...
I think modData is on IsoObject...
modData should be universal, but there's some cases where it isn't
you probably don't need modData
Hmm... I wish for some more events ๐
I wonder what would happen if you stored the zombies in a list
and they became unloaded
memory leak I suppose, lol
But I can try to check the modData on every zombie in cell on client cell each 10 ingame minutes...
I really don't know. So far I remove them from my list when they died. I already run into the problem that I got a new zombie which id was already on the list. Maybe I have to get the references or idk...
Idk if the references are kept between loads
you could have the zombieUpdate check for the reanimated boolean, then add itself as a key to a table with a timestamp as the value
then during update it checks for the value against the time and generates a scream + assigns new time stamp
then you wouldn't be parsing through the list
although if the references don't get saved idk if that would cause an issue
+unloaded zombies
We are nearly on line together ๐ But the reanimatedPlayer flag is just for my first step. I want to be able to add stuff to random zombies. Which will be kept when I restart the server. And save as much resources as possible... If the list doesn't work. I can in worst case rely on the modData. Maybe this is not to bad if I can jump out of onZombieUpdate early. The list was an idea for performance.
Let me check something
I don't think zombies retain modData
I've messed with Zombies to make custom AI
they're very particular to any changes done on the fly
you'll have to reapply changes everytime
The way I set my AI was to create an object they wear in a unique slot
I recall hearing something similar from someone. The changes they applied DID persist, but moved to a different zombie, lol
For me the zombies kept the data... At least if I didn't messed up my tests...
Could have been changed since I last saw

it easy to forget they're changing stuff all the time
@hearty dew In order to securely tell how much XP was earned via media lines I have to modify the vanilla event handling the lines as raw text anyway
which I wanted to avoid
all the field stuff was for nothing lol
I'll make a test on this one. I have still a wandering "me" on my multiplayer game. If I can make this stuff all on modData then the scream should lead me to "me" or to another zombie ๐ Or if the modData swaps then my current code gives each zombie with the reanimated flag new modData so there should be many screamers because restarted the server several times...
it'll be interesting to find out
I've noticed that when walked a ways offscreen from a pair of zombies and then returned. I presumed the zombie objects get recycled in an object pool, perhaps. And then the mod datas get mixed around.
ya, I imagine the dev's didn't figure anyone would be able to tell zeds apart
So I'm lost?
As IT engineer I'm a master of dirty/bad and ugly solutions (saw a lot of them)... Maybe I can give the zombie an item with a custom stat that has a number of my mod settings and get the settings from a saved file. But I cry if I had to do it in such ways...
hehehe
my AI code looks for outfits and uses the weapon attachment (the embedded weapons) code
modding this game is all about sacrificing your pride as a programmer and doing dirty hacks
basically it has an invisible weapon jammed in the zombie
๐ญ
If you're okay with some randomness, I'd just do the screams based on probability. Calculate that on the server, and broadcast a server command for the zombie to scream. I think that'd work and be relatively simple
---@param zombie IsoZombie | IsoGameCharacter | IsoObject
---@param apply boolean
function eHelicopter_zombieAI.onUpdate(zombie, apply)
if not zombie or zombie:isDead() then
return
end
local AIs = eHelicopter_zombieAI.checkForAI(zombie)
if AIs then
for AI_ID,_ in pairs(AIs) do
local specialAI = eHelicopter_zombieAI["onUpdate_"..AI_ID]
if specialAI then
if zombie:getModData()["initApply"] ~= true then
--[DEBUG]] print("EHE:SWH:SZ:initApply not true, setting `apply` to true")
apply = true
zombie:getModData()["initApply"] = true
end
specialAI(zombie, apply or false)
end
end
end
end
Events.OnZombieUpdate.Add(eHelicopter_zombieAI.onUpdate)
in this case I rely on the modData not being saved
that's why I confirmed it isn't saved
and this hasn't broken since
local group = AttachedLocations.getGroup("Human")
group:getOrCreateLocation("Special Zombie AI"):setAttachmentName("special_zombie_AI")
AttachedWeaponDefinitions.gottaGoFast = {
chance = 100, weaponLocation = {"Special Zombie AI"}, outfit = {"AlienTourist"},
bloodLocations = nil, addHoles = false, daySurvived = 0, weapons = { "ZombieAI.gottaGoFast" } }
AttachedWeaponDefinitions.attachedWeaponCustomOutfit.AlienTourist = { chance = 100, maxitem = 1, weapons = {AttachedWeaponDefinitions.gottaGoFast} }
module ZombieAI
{
imports
{
Base
}
item gottaGoFast
{
Type = Normal,
}
item nemesis
{
Type = Normal,
}
item licking
{
Type = Normal,
}
item fodder
{
Type = Normal,
}
}
Maybe this can work. It was one on my first approaches. But I had the problem that the command was faster on the client than the new zombie. So the client didn't find the id. Maybe I can go with a mix and make the OnDeath event on the client and the rest as kind of a command system...
Is there a way in discord to bookmark stuff for myself?
you could copy the message link
thats the current way ๐
also, turns out I can't safely/reliably figure out how much XP was gained from TV shows
asfaik it's sort of random
and most of the radiointeraction code is local
Isn't all the XP gain random?
the xp is gained by specific lines in the show, not the show itself, right?
nah
from what it looks like it has a cooldown
that's doubly local
like, the object is localized, and in that localized init - it has local vars
seems like it tries to add an amount everytime and stops per cooldown of 30
I tested a mod which gave the possibility to give an XP multiplier to each perk and also an option to make the XP gain "flat"...
huh. It always seemed that the XP increases happened exactly during a new line appearing above the tv, but could have been confirmation bias
function self.OnTick()
for playerNum=1,4 do
local tbl = cooldowns[playerNum]
if tbl then
for code,value in pairs(tbl) do
if value > 0 then
tbl[code] = value - (1*getGameTime():getMultiplier());
end
end
end
end
end
this is under the radioInteractions object
local code = string.sub(_v, 1, 3);
local op = string.sub(_v, 4, 4);
local amount = code~="RCP" and tonumber(string.sub(_v, 5, _v:len())) or nil;
if amount ~= nil and code~="RCP" then
amount = op=="-" and amount*-1 or amount;
if Interactions[code] ~= nil then
if not cooldowns[playerNum] or not cooldowns[playerNum][code] or cooldowns[playerNum][code]<=0 then
Interactions[code](player, amount, op=="=");
cooldowns[playerNum] = cooldowns[playerNum] or {}
cooldowns[playerNum][code] = 30;
end
end
end
the amount seems to be tied to the line
like you say, but there's also a cooldown
hmm
ok... maybe than it's just random for the stuff like electricity gain when dismantle stuff or whatever...
its possible they put a cooldown in so you can't gain all the XP from a show the first time you watch it, and have to go looking for the VHSes. I'm pretty certain I've gotten XP from a tape of a show I had already seen. I was gonna go look for more copies of the vhs to see if it was just tied to the particular tape, but this makes more sense
does the recovery journal still get eaten if someone has the consume book mod? Got a good laugh when one of my roommates realized his skillbook had disappeared
ive been considering adding that option to my skillbook mod and using it on my server
the reading is done by a looped crafting action
had a chat about it
then saw konijima made a mod for it
doesnt do all the other stuff mine does tho.
Why would people want books consumed?
balance
difficulty
make u raid book stores more
trade in books
etc
speaking of which the named lit mod not having tweakable stats might make me remove it
I experienced the same behavior. I was able to watch the same vhs again for more xp after some time. Don't know if this is intended or not. But my last test with this is a while ago...
imba af atm with fast reading
ye, I like it as a concept, makes the books more consistent with the magazines as well'
i love the RP value but oof
My other mod Named Literature makes rereading books in general return a diminishing return
yeah
but if u read at the speed of a second
it diminishes but never hits zero
and u can spam it
the return would be abysmal under normal circumstances
yeah
i dont doubt it's fine in most cases
but in my case it's a problem xD
i like your mod for the RP value of different book names and such
but the mechanics it introduces don't work for it balance-wise cuz of that
you would want it to lock to 0 forever?
i mean ideally it'd have a configurable "amount of time to get to full value for re-read" setting
xD
maybe also an option to change the actual amount it gives at most
is your named literature mod the one that adds Dragonlance books? I spend a good while trying to collect the whole series in game
I didn't realize it was an issue lol
i reported it at some point i think but u get a lot of crap in there
i still get errors from ur mod interacting with things xD
Couldn't tell you what it actually adds, I spent like a hour scumming goodread's database
lol
LOG : General , 1666980049026> 570,332,378> -------------------------------------------------------------
attempted index: StackableTypes of non-table: null
LOG : General , 1666980049026> 570,332,378> -----------------------------------------
STACK TRACE
-----------------------------------------
function: modifyLitScript -- file: namedLit - ScriptModify.lua line # 3 | MOD: Named Literature
ERROR: General , 1666980049026> 570,332,378> ExceptionLogger.logException> Exception thrown java.lang.RuntimeException: attempted index: StackableTypes of non-table: null at KahluaThread.tableget line:1689.
ERROR: General , 1666980049026> 570,332,378> DebugLogStream.printException> Stack trace:
java.lang.RuntimeException: attempted index: StackableTypes of non-table: null
at se.krka.kahlua.vm.KahluaThread.tableget(KahluaThread.java:1689)
at se.krka.kahlua.vm.KahluaThread.luaMainloop(KahluaThread.java:492)
at se.krka.kahlua.vm.KahluaThread.call(KahluaThread.java:163)
at se.krka.kahlua.vm.KahluaThread.pcall(KahluaThread.java:1980)
at se.krka.kahlua.vm.KahluaThread.pcallvoid(KahluaThread.java:1812)
at se.krka.kahlua.integration.LuaCaller.pcallvoid(LuaCaller.java:66)
at se.krka.kahlua.integration.LuaCaller.protectedCallVoid(LuaCaller.java:139)
at zombie.Lua.Event.trigger(Event.java:64)
at zombie.Lua.LuaEventManager.triggerEvent(LuaEventManager.java:65)
at zombie.network.GameServer.doMinimumInit(GameServer.java:1431)
at zombie.network.GameServer.main(GameServer.java:684)
LOG : General , 1666980049027> 570,332,379> -----------------------------------------
STACK TRACE
-----------------------------------------
function: modifyLitScript -- file: namedLit - ScriptModify.lua line # 3 | MOD: Named Literature
LOG : General , 1666980049027> 570,332,379> Named Literature: ver:0.7.6-REFACTOR-HOTFIX-AUG-12```
Oh that
well, it doesn't implicate anything else
but

i assume it's an interaction since it isn't sorted out by now
that's an issue of client/server
doesn't/shouldn't break anything
yeah the issue is the server is trying to grab something that only clients have
yeah I probably did it in the git repo and never updated
dont get me wrong, sounding like a ball of complaints, i love a lot of your stuff :)
"Time of the Twins (Dragonlance: Legends, #1)", "Margaret Weis",
might be
I'm still waiting for inventoryItems to be able to have independent models
right now it's loaded specifically off the script ๐ฆ
u planning to make them all have appearances?
I'm not looking forward to diving into the inventoryitem world for my mod
that'd be cool
seems to be the case
i assume u've put it in the modder suggestion thread?
I just ping nasko a bunch of stuff once and a while
Helps to have the filenames/lines, specific reason why, etc
does he take kindly to that? i heard someone say they think nasko hates them once for badgering him
xD
i want vehicles.db access
and a syntax checker for scripts
those are my two requests
@bronze yoke @gilded hawk Weeeeeell I'm pretty sure it's done and bug-free, y'all. Please let me know on Discord if you have any issues. I don't mind a DM. I'll try to fix things fast. Also I hate you if you find any bugs. Just kidding. https://steamcommunity.com/sharedfiles/filedetails/?id=2875983658
I didn't assume he likes me more than others
ur pace is admirable.
seriously
xD
idk if ur gonna burn out but it's impressive
Don't stop modding dude ๐
i gave them a bunch of new requirements/requests and they're all in place in 24 hours
hehe
Don't spoiler him the future of every modder ๐
the modify scriptfile is in shared for some reason
wish I commented why
but the stacktypes are in client
i'm definitely going to burn out soon but i'm not quite there yet so i gotta get what i've already done out
pls water filter
i'll probably do that soon, that should be a lot less frustrating than some of the weird stuff i've been doing recently
going to add sandbox options for the diminishing factors + rebund time @weak sierra
Lol I'm slowing down with mods ๐
hey anyone know how to scale an attachement? I want to use the recoil pad with a weapon but the pad is too large for the rifle butt. i've tried scale and scaling in the item doc below offset and rotate but it is not working
I want to finish the editor for the workshop.txt before end of next moth tho, it will be useful for si many modders
Forgot I did a fancy schmancy formula - will have to work on it later
Actually, just going to add another sandbox option "can read passed max".
Is this the best solution for implementing your own "scripts" for object definitions? Or can we use the built in script system for our own stuff?
For your own scripts.. yea, it wouldn't be a bad solution..
If pz's script system is exposed enough to use, that might be good as well. I haven't tried using it in this fashion, so I'm unsure. Maybe it provides some benefits I'm not taking into consideration e.g. it already has logic to merge multiple definitions (e.g. from multiple mods) together into one
I don't think its exposed very well, I've messed with it a little to add things to the vanilla vehicles but I don't think it can be used for stuff other than items, vehicles, etc
With the writeModFile and readModFile apis, it will read to/from the mod file btw
ya, I just poached the JSON api you linked, but that should work pretty good i think. After our discussion yesterday I have a pretty good idea of how I'm going to implement my data structures, but I don't want them taking up a bunch of space in my lua. This will probably do the trick, although I guess I'd have to figure out a way to sync them
It does a pretty good job. I use it to serialize item types selected by the user
I'd probably just stick any data structures that aren't going to be modified into its own lua file though, rather than a json file to be parsed at boot up. If the data structures are going to be changed and that change has to persist, then serializing/deserializing to json makes good sense imo
having a mechanism to load them opens up the ability for end users to add their own fairly easily, which is a nice benefit, While also letting me keep my code clean. Having to sync additions and changes to clients is a stark downside, so I'm still undecided.
Ah, so you're thinking of a system where another mod can come along and add the missing gaskets, washers, etc to the graphs of engine parts
if they want to, sure. For example one file would be a SmallBlockChevy.json or maybe more specific like 79_GMC_LM1.json, and contain the graphs we talk about containing the relationships between the parts. Someone could then later add their own engine blueprints as they like, or change mine to include other parts or whatever
I feel its a pretty elegant solution to how to model different types of engine configurations while still using a small set of standard "parts"
what are you trying to accomplish?
ah config files
theres a much simpler way of pulling it off
pretty much ya, more similar to the template and vehicle scripts tbh
let me grab the system i made for a mod
local listings
Events.OnInitGlobalModData.Add(function(isNewGame)
local fileReader = getFileReader("ServerPointsListings.ini", true)
local lines = {}
local line = fileReader:readLine()
while line do
table.insert(lines, line)
line = fileReader:readLine()
end
fileReader:close()
listings = loadstring(table.concat(lines))() or {["Missing Configuration"] = {}}
end)
this was used for a server side config file
ya thats pretty straightforward. I need a way to serialize and parse some tables though, which is why I thought to lean on the JSON api so I don't have to reinvent any wheels
so you also need to save a table?
several tables of tables, ya, haha. I've paid particular attention not to have any circular references or functions in them so they can be properly serialized
i guess then the json lib could be used
though keep in mind globalmoddata can be used for persistent data
data could change between reloads, no point storing it in the save file tbh
trying to debug an issue with one of my mods, one file's server commands listener seems to have stopped receiving responses 5 hours into a user's session and after countless restarts it refuses to work at all, does anyone know what that could possibly mean? another file in my mod uses *exactly the same code* and has not broken like this
Maybe create a table that stores every customized item on a file
Then read from that if you cant find a method to check name
Cuz if you modify the name then you cant check for it anymore same as the problem i encountered with weight
getWeight == getWeight
After setWeight
that sounds really familiar
the part where u used the same code on two mods
and one breaks somehow
that has happened to me
for me it was some tiny detail in the commands for one and not the other iirc
ive never heard of something like that just pissing off after 5 hours tho
it's been narrowed down to an equally mysterious 'the part of code that requests the data from the server just stopped getting run for some reason'
so it wasn't directly the server commands... thank god
huh
also not only was it 5 hours into a session, but the mod had worked perfectly for a week before that
unfortunately it's a public multiplayer server so i'm reluctant to tell them to wipe
are u sure it's ur mod at this point?
i am not confident it is my mod
mayhap it is not
but it's pretty hard for other mods to interfere with it, it's all local (i grew out of that habit, but it was someone else's mod that i was commissioned to update)
'the part of code that requests the data from the server just stopped getting run for some reason'
How was this determined?
put a print before it, never showed up
i've just discovered that they added a new mod right before the problems happened, so... yeah
Did they provide a full console.txt?
yep, several
That's tricky.. Would it be possible to instrument the code in such a way that the user's logs could print more information of your design that would help narrowing down the issue further?

