#mod_development
1 messages ยท Page 114 of 1
i know if it's called like once or not often then w/e
after all this i honestly think i'm shelving the craft speed until next update lol....
Well it depends on what you hope to localize but you can't localize the function your item script needs to call afaik
i'll just stick it to 120 for now
Your item script would have no way of accessing it if it weren't global
Pretty sure the game isn't gonna attempt every conceivable import to try to hunt down a form of local access.
yea i dont localize my sandboxvars
Yeah I would not recommend that either
I mean, you can localize copies of your global functions if you want
I would highly recommend putting everything in a module and returning that module
If you want to make your code more local
other than that mostly everything else has worked. but i'm just trying things for when i'm pulling from global namespace or whatever often
That way people can still get at your data if they need it
(i.e. future modders modding your mods)
Personally localizing stuff like getSpecificPlayer is not worthwhile to me because I call those functions so rarely that they barely affect the speed of execution at all.
so doing somthing like Nipswitch = Nipswitch or {} and prefixing?
do i prefix every function? then
The difference between a single global call to getSpecificPlayer and a call to its local copy might even be immeasurable.
(Feel free to prove me wrong, anyone.)
(A single call, not a group of 100 or 1000.)
To me, a time so brief you might not be able to measure it in ms is not worth optimizing.
yea i agree. for me i only want to make sure whatever im doing isn't the thing thats making someones game run the worst of all other mods ๐
I have done rather complicated things on a single tick and noticed 0 slowdown in gameplay
So I don't think getSpecificPlayer is ever really gonna be a game-breaking difference.
Absolutely
Reasonable
well im not going to lie.. i had really hoping figuring out how to used timed actions were WAY more simple than that
it doesn't seem overly complicated but time consuming
in my head it seemed as simple as adding a timer above my char and make them do animations and not be able to move without canceling timer...
Hey hey people, could I get some feedback on my models? <3
probably going to move right into the light power one
there is a modeling channel. but i dont think anyone would hate it also ๐
Posted an image there! It's just way less active than this channel, so thought I'd ask here as well hehe
share away. it's technically development of a mod hahaha
Bread looking one is heroin, other one is LSD. Small bottles are codeine and morphine.
I'd love to get some feedback on em' if possible! (copy pasted from other channel because I'm lazy :^) )
they are really good! one thing i'd point out is your edges have some lighting thing going on
Thanks! Which ones specifically have it? All of them?
most. the cup up top doesnt on the top half
that codeine bottle is decent
still has a little lighting issue though
im far from pro at this
Hmm, I think that could be attributed to how PZ handles lighting overall
I like the models regardless of the lighting. They look good to me.
i like the bags the best tbh
I think they all might be a bit too colorful, will probably tone that down a bit :x
maybe. but i like that in the bags lol
Ditto
What drug user doesn't like colorful drugs?
Yeah those pills are scary I would die.
lol
honestly smaller would be better imo depending on how many you planned on putting into a bottle
LOL
LOL
It's the default project zomboid antibiotics model with a different texture, on the last pic they were at a scale of 1
Now they're on a scale of 0.01
They're freaking huge
Lmao
honestly if they still look half decent i'd go another 50%
.002 possible?
haha
Not sure actually, but I don't see why not ๐
I'd give something in the 002-004 range a shot
i think it's a double value right
I've been cautious of scaling things down too much because it just turns to a bowl of porridge after a certain point
lmao
Definitely
But those pills are quite vivid in their color so could probably make them smaller
The pills are fortunately just two colors in an oval shape
Yes yes
So even with 2 pixels they would probably look similar
yea the less you have to scale the more it looks like what you intended anyways right?
at least in game*
Depends on how big you made them in your 3d software, like, some models in vanilla PZ are freaking HUGE without scaling them down. If you want to make something at the proper size in blender you need to work with objects that are freaking tiny, so tiny that the software has a hard time rendering it lmao
some of the 3d modeling i've done was lossless scaling also so i'm not sure on this stuff
You could try a pill bottle, too, in theory, with those depicted on the label
If shrinkin them goes too far
insulin box i made for my diabetes trait mod (TBD) lol
Oh! I like that, I actually thought of something similar with what I'm making now
i like the side ish angle
Is that the model or the icon?
technically the icon but the model wont be far off
Check out if there are vanilla models you can just resize or retexture before you make something from scratch
A bit of advice so you save yourself some time
Can I see your .lua file?
I thought of that! But I feel loose pills kinda fit the bill a bit more
I agree actually.
Just throwing things out there.
I like the look even though they're large.
Also made a breathalyzer
for the craft speed? i haven't changed much since i realized i'm going to have to copy and redo 3 functiosn just to make it happen
thats real good
Those pills definitely say, "I sure hope you're ate."
Hahaha
I am actually curious why your code couldn't find your OnCreate function
I have ideas of why.
function Recipe.OnCreate.Switch(items, result, player_num)
local switchSpeed = SandboxVars.Nipswitch.Craftspeed
local player = getSpecificPlayer(player_num)
SwitchCraftAction = ISCraftAction:derive("SwitchCraftAction")
--SwitchCraftAction:new(player, result, switchSpeed, Recipe.Switch, nil, nil)
local SwitchCraftAction = SwitchCraftAction:new(player, result, switchSpeed)
player:getAnimNode("Disassemble")
player:setProp1("Screwdriver")
player:setProp2("lighting_indoor_01_0")
player:getEmitter():playSound("VehicleHotwireStart")
print("Player:", player)
print("Result:", result)
print("Switch Speed:", switchSpeed)
end
was the last thing i had and haven't gotten
i'm assuming because of the function usage you mentioned
I need the rest of the file. The answer is not here.
Oh I see you hope to use Recipe.OnCreate from lua/server/recipecode.lua
Are you clientside?
I wonder if that is relevant...
i figured it would be best since its used for both
Just noticed you went with "player_num". Again, completely nonstandard name for the player index, fwiw to you.
lolol
Game uses playerIndex and playerNum
And player
I think one of those is infinitely more legible and precise than the others.
So I use that one.
But you do you.
it's what i used for the rest of the mod so far lol from the first noobness there
like i said trying to satyt consistent with what i've used in this mod so far
Regardless, I would not for the love of all that is good create a 4th way to write it.
Ctrl + H is your friend.
What mod development does to a mfer
i'll take one last look at this tomorrow. been on this mod literally all day
That's how I was finishing the safehouse/faction UIs a couple days ago
my lady wont let me get away with being useless all day hahaha
got a bit obsessive trying to get them published asap lol
thank you btw. i will come to this convo and learn even more from it
Disregard ladies, acquire internet REP
I so desperately want to finish what I'm working on, but it's a team effort and I don't know jack shit about LUA :^)
How many items can we drop on the floor without crashing the server?
Huh?
dropped thousands of money and now I can't load into the game lol
Lol oof
well yes
there are 5000 instances of that object
and inventory processing is done in array lists
I'm not sure individual items are the best way to track individual bills...
lol
Maybe a Cash item with some mod data would be more efficient.
Just combine cash objects and add their values...
Idk I haven't done a shop mod.
that is indeed the best way
yes, but this scenario can happen
Oof lol is that vanilla money?
players may stack up the bills and accidentally drop it
yes
you wont ever aquire 5000 money in normal gameplay
I never collect money when I play lmao
Seems like the last thing I need
in the apocalypse...
plus vanilla money has weight
I remove the weight lol
maybe I have to rethink
Maybe just mod vanilla money to automatically add its stack to the value of your player's cash data when they acquire it?
And the item disappears?
Badabingbadaboom?
is there any example mod that can do something like that?
Add one item to player inventory that gets its name from your player's cash data?
I mean probably not... but you could in theory get the size of the stack you're adding to your inventory when it gets added, and instead add that stack size to player:getModData().money
OnCreatePlayer, player:getModData().money = 0and add money item to player inventory with default amount of money (maybe a random value from 0-50)... on add inventory item (idk the function name but I'm sure it exists), if the item is a stack of money, player:getModData().money = player:getModData().money + stackSize, remove old money item from your inventory, add new money item where name == player:getModData().money
I am not clear on the details but I strongly suspect this abstract strategy could work.
Maybe this is already how Shops and Traders does it idk
Could check that out
Or Noir's Shops
idk
@cosmic condor I haven't looked closely at any of the shop mods' code bases yet
I may have to add the weight back to limit the number of items
Word fair enough
Just crazy idea ๐
my shop implementation was cash system agnostic
Damn I think the more I look at PZ code the more I see how it's very hard coded x.x
you simply had to overwrite 2 functions i think to patch with any system
What happened to it?
Do people still use that?
Oh does it survive in albion's update to your mod?
it still gets a bunch of subs each day but the release was just a test version
albion picked it up because of william
Makes sense
Is there any way to acess local functions from other scripts?
@rustic garnet On occasion it is not terribly unwieldy to overwrite the global that calls someone's local function, and also rewrite the local function it calls, to do what you need.
If there is no other way.
Yeah, it's mostly because I need something that's inside the HealthClass of PZ and it seems they made a class in it which is local and seems I gotta rewrite the whole thing
What file?
Sorry my bad there!
Was trying to get hold of the BaseHandler
Usually in c++ would be quite easy to do, thought there would be a way around lua by using something similar to the c++ header files or the using in c#
Yeaaaah I'm not seeing any external means to access that definition.
May need to copypaste BaseHandler def.
local BaseHandler = ISBaseObject:derive("BaseHandler")
function BaseHandler:new(panel, bodyPart)
local o = {}
setmetatable(o, self)
self.__index = self
o.panel = panel
o.bodyPart = bodyPart
o.items = {}
return o
end
function BaseHandler:isInjured()
local bodyPart = self.bodyPart
return (bodyPart:HasInjury() or bodyPart:stitched() or bodyPart:getSplintFactor() > 0) and not bodyPart:bandaged()
end
function BaseHandler:checkItems()
for k,v in pairs(self.items) do
table.wipe(v)
end
local containers = ISInventoryPaneContextMenu.getContainers(self:getDoctor())
local done = {}
local childContainers = {}
for i=1,containers:size() do
local container = containers:get(i-1)
done[container] = true
table.wipe(childContainers)
self:checkContainerItems(container, childContainers)
for _,container2 in ipairs(childContainers) do
if not done[container2] then
done[container2] = true
self:checkContainerItems(container2, nil)
end
end
end
end
function BaseHandler:checkContainerItems(container, childContainers)
local containerItems = container:getItems()
for i=1,containerItems:size() do
local item = containerItems:get(i-1)
if item:IsInventoryContainer() then
if childContainers then
table.insert(childContainers, item:getInventory())
end
else
self:checkItem(item)
end
end
end
function BaseHandler:dropItems(items)
return false
end
function BaseHandler:addItem(items, item)
table.insert(items, item)
end
function BaseHandler:getAllItemTypes(items)
local done = {}
local types = {}
for _,item in ipairs(items) do
if not done[item:getFullType()] then
table.insert(types, item:getFullType())
done[item:getFullType()] = true
end
end
return types
end
function BaseHandler:getItemOfType(items, type)
for _,item in ipairs(items) do
if item:getFullType() == type then
return item
end
end
return nil
end
function BaseHandler:getItemOfTag(items, type)
for _,item in ipairs(items) do
if item:hasTag(type) then
return item
end
end
return nil
end
function BaseHandler:getAllItemsOfType(items, type)
local items = {}
for _,item in ipairs(items) do
if item:getFullType() == type then
table.insert(items, item)
end
end
return items
end
function BaseHandler:onMenuOptionSelected(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
ISTimedActionQueue.add(HealthPanelAction:new(self:getDoctor(), self, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8))
end
function BaseHandler:toPlayerInventory(item, previousAction)
if item:getContainer() ~= self:getDoctor():getInventory() then
local action = ISInventoryTransferAction:new(self:getDoctor(), item, item:getContainer(), self:getDoctor():getInventory())
ISTimedActionQueue.addAfter(previousAction, action)
-- FIXME: ISHealthPanel.actions never gets cleared
self.panel.actions = self.panel.actions or {}
self.panel.actions[action] = self.bodyPart
return action
end
return previousAction
end
function BaseHandler:getDoctor()
return self.panel.otherPlayer or self.panel.character
end
function BaseHandler:getPatient()
return self.panel.character
end
Yeah that's what I was starting to do, such a shame though! Hopefully for the future they gives us a external reference to it, or just making it global
Yeah some stuff one would hope to mod is tragically buried, but ultimately duplicating a small class is not a huge deal.
It won't make your mod take endlessly longer to load or anything
Slightly longer, sure
Users will live.
(if the mod is worth it)
That's nice to know though! I suppose won't kill anyone to wait a little bit
I mean it will take a fraction of a second to load a class like the one above on my computer.
Not an amount of time that matters
I wonder if they have anything planned to change it? Otherwise might be worth to recode the whole thing and make an API of sorts. For most of the health stuff you could have easily fixed this problems with a bit more thinking in the structure of the code though
Yeah I don't know. I wouldn't hold my breath. They're very busy with features that most players agree are more important
e.g., NPCs, animals, even shops may be on the way, UI improvements.
I mean they may cover it when they upgrade UI in general.
That is supposedly in the works.
oooo!
Poltergeist wins cleverest modder of the last 2 minutes award?
Sadly :/
What about here?
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
damn, i need to get one of you guys to help me zip up my trucking mod. LOL.
You can derive it but I need specifically the handler since it has the other variables to use in the PZ function
I use it now and then 
^this all the derived classes are also declared local and thats their instantiated use
so cant grab the super from __index
Why not this? I still don't follow.
GlobalHackery = {}
function ISBaseObject:derive(type)
local o = {}
setmetatable(o, self)
self.__index = self
o.Type= type;
if type == "BaseHandler" then
GlobalHackery.BaseHandler = o
end
return o
end
Would this not create a global copy of BaseHandler?
That one could access freely?
This one would be what I needed which derives from ISBaseObject but they made it local
Right, but my override above catches the creation of that object and saves it as a global.
So would it not persist?
And have the same inner keys?
Seems like it should.
I would need to test...
type is just a string
And the call to the global ISBaseObject tells us when the object is a BaseHandler
The kind you need...
I can give it a try, but since I wanna derive and add an extra method from BaseHandler, to have an option like Remove Bandage or Add Bandage not sure.
You could catch them all similarly...
If the above code works, you could rework it like this:
GlobalHackery = {}
GlobalHackery.ISBaseObject = {}
GlobalHackery.ISBaseObject.derive = GlobalHackery.ISBaseObject.derive
function ISBaseObject:derive(type)
local o = GlobalHackery.ISBaseObject.derive(self, type)
if type == "HRemoveBandage" then
GlobalHackery.HRemoveBandage = o
elseif type == "BaseHandler" then
GlobalHackery.BaseHandler = o
end
return o
end
This way you actually decorate the original derive
In case it changes for whatever reason.
Fixed typos above @rustic garnet
Called GlobalHackery GlobalHacker
What do you think @drifting stump ... would the above global table duping fail because they were declared locally?
Or would they persist via their global copy
I think that would work, but if I would want to add my new type deriving from base handler. How could I write that?
Example of the Bandage One
local HApplyBandage = BaseHandler:derive("HApplyBandage")
function HApplyBandage:new(panel, bodyPart)
local o = BaseHandler.new(self, panel, bodyPart)
o.items.ITEMS = {}
return o
end
How would I call mine?
local HCustomHandler = ...:derive()
local HApplyBandage = GlobalHackery.BaseHandler:derive("HApplyBandage")
Honestly if this works it's a bit game-changing for me lol
So many times I've copy-pasted because screw it... lol
Poltergeist's idea might be gold.
Yeah was trying to find a way around it xD
Would you call this at the beginning of the load to cache the BaseHandler?
You wouldn't really call this, it would simply get called whenever things used the derive function
You just throw it in a ModStuff.lua file
Oh gotcha!
Thank you guys, well going to quickly try this
ISHealthPanel is in client so hopefully it'll work out
maybe if you overwrite ISBaseObject file, might cause issues.
GlobalHackery.ISBaseObject.derive = GlobalHackery.ISBaseObject.derive
var = nil
think you meant
GlobalHackery.ISBaseObject.derive = ISBaseObject.derive
When you start the game, try print(GlobalHackery.BaseHandler) in debug console.
If it prints a table, I think you're in business.
(But then you can also try print(GlobalHackery.BaseHandler.new) etc. to make sure you can see its functions, too.)
It seems so far to give an error, seing if I can quickly fix it.
Thank you
Oops
Good catch
@rustic garnet You understand what Browser8 just said?
Use this:
GlobalHackery = {}
GlobalHackery.ISBaseObject = {}
GlobalHackery.ISBaseObject.derive = ISBaseObject.derive
function ISBaseObject:derive(type)
local o = GlobalHackery.ISBaseObject.derive(self, type)
if type == "HRemoveBandage" then
GlobalHackery.HRemoveBandage = o
elseif type == "BaseHandler" then
GlobalHackery.BaseHandler = o
end
return o
end
I accidentally did not copy what I meant to copy on line 3.
Uhum, I had fixed that :p
Oh okay word
It seems the problem is when I derive going to print like you said
see if I can get a reference or I'm getting null
@rustic garnet
put this in shared folder, it needs to happen before vanilla file is loaded.
Ohhhh or you could call reloadLua on that file
Should be harmless right?
should be fine
GlobalHackery = {}
GlobalHackery.ISBaseObject = {}
GlobalHackery.ISBaseObject.derive = ISBaseObject.derive
function ISBaseObject:derive(type)
local o = GlobalHackery.ISBaseObject.derive(self, type)
if type == "HRemoveBandage" then
GlobalHackery.HRemoveBandage = o
elseif type == "BaseHandler" then
GlobalHackery.BaseHandler = o
end
return o
end
reloadLuaFile("media/lua/client/ISHealthPanel.lua") -- Updated based on Poltergeist's suggestion
?
Is that the right command?
you need reloadLuaFile("media/lua/client/... .lua")
As soon as I reload after I put it in the shared folder, it kinda goes black screen and it seems to stay that way
even after restarting the game x.x
check logs for errors, sometime f11 can continue loading
Ayyyyyyy
Now if I can derive is another story haha
What did the final code look like?
same as yours still, but I'm gonna just expand it to take a table of stuff I might need
How are you trying to use them
was just trying to print the reference
๐
lmao I just realized I was printing the ISBaseObject.derive
so not the BaseHandler
anyway I feel like I should say not to require or reload files in folders that are not loaded yet
shared < client < server
let me reload
nice
GlobalHackery = {}
GlobalHackery.ISBaseObject = {}
GlobalHackery.ISBaseObject.derive = ISBaseObject.derive
function ISBaseObject:derive(type)
local o = GlobalHackery.ISBaseObject.derive(self, type)
if type == "BaseHandler" then
GlobalHackery.BaseHandler = o
end
return o
end
function PrintDerive()
print(GlobalHackery.BaseHandler)
getPlayer():Say("Debug")
end
Works still though
so try printing GlobalHackery.BaseHandler.new there.
it's global, you can print from console?
Trying now just need to quit and reload, since you can't hotreload while you are in-game
try from console, no reload required
Yup! much better solution, a lot cleaner
I haven't tried to derive, but I'm assuming it's possible since we have the references
Nice workaround for sure!
but it seems it has troubles deriving
I'm guessing that it tried to derive before the reference exist
its anything but clean
PZ code is not clean sadly is not clean and very hardcoded. They really should hire some to take care of it, could be a lot better.
thats not really the issue
they dont want to break mods
which imo shouldnt even be considered with how the codebase is rn
Is this actually one of the main reasons to not improve how lua codebase is structured? Because it seems counterintuitive. Popular mods will survive and it will enable more people to write mods and more complicated mods to be created
Can I see your derive attempt? Did you use the console?
Still, for the healthclass if they had structure it better would be a lot easier to add stuff into it, and not break anything. You could rewrite the Health to take the table of methods that you can do (Remove Bandage, Apply etc) and let the modders add to that table the extra stuff they would need.
Trying to fiddle with it, it gives me some errors at the beginning trying to see if I can
Yup managed to derive
I split it, I left the Global Hackery in the shared folder, and created the derive in the client one
Seems to get rid of the errors
Also that means you can reload it, since you don't reload the references in Global Hackery
Nice, did you try some data?
local bodyPart = getPlayer():getBodyDamage():getBodyParts():get(1)
local handler = BaseHandler:new(nil, bodyPart)
print(handler:isInjured())
for example?
It works completly fine I managed to add it to the health menu but the drawback is for example in my case I need to store all of this to override this function.
function ISHealthPanel:doBodyPartContextMenu(bodyPart, x, y)
local playerNum = self.otherPlayer and self.otherPlayer:getPlayerNum() or self.character:getPlayerNum()
local context = ISContextMenu.get(playerNum, x + self:getAbsoluteX(), y + self:getAbsoluteY());
print("doBodyPartContextMenu")
local handlers = {}
table.insert(handlers, HRemoveBandage:new(self, bodyPart))
table.insert(handlers, HApplyPlantain:new(self, bodyPart))
table.insert(handlers, HApplyComfrey:new(self, bodyPart))
table.insert(handlers, HApplyGarlic:new(self, bodyPart))
table.insert(handlers, HApplyBandage:new(self, bodyPart))
table.insert(handlers, HDisinfect:new(self, bodyPart))
table.insert(handlers, HStitch:new(self, bodyPart))
table.insert(handlers, HRemoveStitch:new(self, bodyPart))
table.insert(handlers, HRemoveGlass:new(self, bodyPart))
table.insert(handlers, HSplint:new(self, bodyPart))
table.insert(handlers, HRemoveSplint:new(self, bodyPart))
table.insert(handlers, HRemoveBullet:new(self, bodyPart))
table.insert(handlers, HCleanBurn:new(self, bodyPart))
Gotta store all the HRemoveBandage, HApplyPlantain.. and so on
Yeah, you need local copies of the handlers for sure... but ultimately... better than copying the whole classes to get them
Little different than import statements
Do you need to do that every time you grab the menu though?
Oh I guess so
For each body part
only once at the start of the game, first time the GlobalHackery is instanciated
I mean for the references
But yup, everytime you use it calls them but since we store the references in the global Hackery that shouldn't be a problem
You could probably decorate that function for more compatibility with other mods I'm guessing
Presumably it just adds a bunch of options to the context menu it grabs?
You can actually remove and replace options by name
So you could decorate that, and right after it runs, grab and replace the menu options you want to replace.
So if any modded options are added to the list via someone else's decoration, they should be okay.
Is there not an event in that function?
Uh interesting, I suppose just as easily I could add to the context menu?
Not sure let me check,
Not that I see atleast
Oof yeah
nada
Still, you could decorate by getting the context the same way they do
It'll be the same menu object and you can remove/add options to it
Food for thought
I was thinking i could grab them all by something like this
function GlobalHackery.BaseHandler:derive(type)
local o = GlobalHackery.BaseHandler.derive(self, type)
GlobalHackery.AllBaseHandlers.add(o);
end
You could just use BaseHandler:derive if you make your own local copy of BaseHandler based on GlobalHackery.
local BaseHandler = GlobalHackery.BaseHandler
Good morning.
This might be problematic actually. This would redefine GlobalHackery.BaseHandler.derive and then call itself.
I think it would stack overflow in an infinite loop
Yes It would be calling itself, I'm not sure what the actual correct syntax is in lua xD
Can someone make a negan mod
If you decide you want to replace options, here's super simple example of a spelling correction I do. You would want to use the getText("translation_variable") if you were doing this, though.
Yogi.bringBalance = function(playerIndex, menu, objects, test)
if test then return true end
local player = getSpecificPlayer(playerIndex)
-- Hopefully there's no way to generate a context menu when dead.
if menu:getOptionFromName("Sit on ground") then
menu:insertOptionAfter("Sit on ground", "Sit on Ground", player, function() ISWorldObjectContextMenu.onSitOnGround(playerIndex) end)
menu:removeOptionByName("Sit on ground")
end
end
Hi, is it possible to find a place to download/use the full png's used on map.projectzomboid.com? or just a city like louisville?
I'd like to replicate the way the map works and see what fun/community I can add
You would need to back up the original if you wanted to decorate it.
local BaseHandler = GlobalHackery.BaseHandler
local Backup = {
BaseHandler = {
derive = BaseHandler.derive
}
}
function BaseHandler:derive(type)
o = Backup.BaseHandler.derive(self, type)
-- You do you.
return o
end
@rustic garnet I think this would work?
Hey guys... Anyone knows if the OnPlayerUpdate event works fine server side ?
iirc thats client side only
I've got a function on a module that is defined server side that I want to call OnPlayerUpdate
@rustic garnet Almost makes me want to turn Global Hackery into a proper workshop item of its own, where each mod in the workshop item adds a different formerly local file to the GlobalHackery object, for the convenience of other modders... I would probably use such a mod from time to time.
alternatively rewrite the thing and do a pr on the community framework
the community framework ?
Sorry the community framework? Can you submit PRs to Zomboid itself?
But I guess I'll rewrite the thing, thanks
Idk what that is. ๐ฆ
Champy he's talking to me.
there are 3 mods
patches
framework
dev tools
Sorry was afk for a bit
Same! Was expanding mine to add more stuff for convinience
Interesting... Is this also a workshop item? Or do people download what they need from the tools and copy them into their own items?
Going to try this
its on the workshop
This community project is a team effort to centralize quality of life changes or fixes, utility functions, and making the available Lua files easier to work with in respect to both compatibility and modability.
rewriting files fits in the compatibility and modability
What is the name? Trying to search Project Zomboid Community Modding and Community Modding doesn't bring anything up
thought full file replaces should only be done when absolutely necessary
not sure if its unlisted
Fair. I mean I would absolutely submit my gamepad support upgrades to this project. They could be reworked as raw upgrades to the vanilla files. If that is a thing that counts as "compatibility". Seems like it should...
At the very least
The Global thing could obviously be useful too
But I don't know how users use this project...
too hacky to be accepted
like i said a full rewrite is preferable
as for gamepad would be patches
I fully rewrote much of the original files, I just smashed them together into one file.
I didn't make my own classes with fancy names or anything
Just turned ISPanels into ISPanelJoypads
With the relevant bells and whistles.
And necessary added functionality for gamepad support to even be useful in e.g. the trading UI (such as a way to swap in and out of inventory)
I mean that is arguably a little hacky because ISInventoryPane needs a corresponding upgrade to make it useful for trading
But... yeah if slightly hacky and compatible < totally incompatible, fair enough.
Yeah it would be cleaner to rewrite the whole ISHealthPanelClass for the most part
since the project is meant to be a common ground for everything and we make sure to load things first overwrites where it makes sense are preferred to hacky solutions
Absolutely understandable
im working on a new ui system currently
I could mod my gamepad support solution as pure overwrites of ISInventoryPane, ISTradingUI (and its stuff), ISSafehouseUI (and its stuff), and ISFactionUI (and its stuff).
If it would be used in that context.
Oh do you already have gamepad support for the features that are missing it in your new system?
not necessarily
currently writing a new base ui element from which other things will derive from
I guess its goal is not to increase compatibility but something else?
I still think if they added a bit more events, and rewrite a bit the architecture to work to expand which is rather simple. Full overwrites are fine, but if they updated on their end its likely you have to redo it from scratch, no?
Or maybe increase compatibility in a different way?
documentation, performance and usability
I see. Will it be compatible with traditional ways of accessing the elements on which it is based?
yes it has the same concept
Cool
i havent decided yet on the class system
but for example im doing away with initialise and instantiate
I mean those could be called when you make a new object imo
That's standard OOP in a lot of other contexts
you simply create the element and its done
Right
rn i have the concept of initialise done on a spec
That would definitely be nice. Maybe add the ability to call those functions for backwards compatibility?
instantiate just happens inside new
its not meant to replace the vanilla one on what already exists
but be a new base
I see for new mods you mean?
yes which is why its in frameworks
specification
Yeah I don't love the abbreviation of Specification but I do like the general ability there.
so you create a spec which comes with defaults and then you define all the variables which will be used
I might prefer Data
Or something common
But you know
Your thing
Haha
To each their own
i got the idea from discord4j
api for writing discord bots
and they have spec classes for building objects
Right on, it's not terrible. It's something people could get used to. I just don't think it's the most common thing to call constructor data.
I might prefer CFUI:init() where it just sets the object to have the spec.
just because init is a super common abbreviation and slightly shorter.
(and perhaps returns the spec as well for convenience)*
But that's just because I come from languages where init and initialize and new are the terminology, and constructor data and parameters and such are the terminology, so calling all that stuff a "spec" is just a bit foreign to me, though I do understand the lingo fine.
Or CFUI:getDefaults() perhaps
Also would not be bad
CFUI:defaults() if you're a true rebel
like i said i havent decided on the class system
and depending on what i go with this might change
For sure for sure just spitballing no offense intended
rn im focusing on implementing methods and documenting stuff
Also any way I can clean the Errors console?
Wasn't someone doing a mod for that?
for example
---@class TestUIElement
local TestUIElement = {}
---@class TestUIElementInstance
TestUIElement.InstanceMethods = {}
TestUIElement.InstanceMethods.x = 0
---Performs rendering
function TestUIElement.InstanceMethods:render()
end
---@class TestUIElement
TestUIElement.StaticMethods = {}
setmetatable(TestUIElement, TestUIElement)
TestUIElement.__index = TestUIElement.StaticMethods
---comment
---@generic T : TestUIElement
---@param type `T`
---@return T
function TestUIElement.StaticMethods:derive(type)
local o = {}
setmetatable(o, o)
o.StaticMethods = {}
setmetatable(o.StaticMethods, o.StaticMethods)
o.StaticMethods.__index = self.StaticMethods
o.InstanceMethods = {}
setmetatable(o.InstanceMethods, o.InstanceMethods)
o.InstanceMethods.__index = self.InstanceMethods
o.__index = o.StaticMethods
return o
end
---comment
---@return TestUIElementInstance
function TestUIElement.StaticMethods:new()
local o = {}
setmetatable(o, o)
o.__index = self.InstanceMethods
return o
end
CFUI:Init() does sound a bit more standard
one of the concepts i was playing with
completely isolates static and instance methods
ew don't capitalize function names
so you cant call render on the class for example
---@class Test : TestUIElement
local test = TestUIElement:derive("Test")
---@class Test2 : Test
local test2 = test:derive("Test2")
test2:new():render()
Interesting... can you call this just as briefly?
Well I guess they're called automatically
By the game
I like it, actually. But I have an explicit OOP bias.
you can try it on a lua terminal and get a feel for it
Some people will surely disagree with us there
Maybe a default fallback mode as an optional mode of declaration would be appreciated by them
You could try deleting the text of console.txt in %userprofile%/Zomboid
That might start showing you errors again next time an error is generated... unsure
Hassle, but faster than restarting the game...
my only issue with this is how to declare functions you have to do it this way
function TestUIElement.StaticMethods:doAThing()
end
function TestUIElement.InstanceMethods:doAnotherThing()
end
and might not be the most user friendly
Me realizing I forgot to rename the mod to match the workshop in modinfo but I'm too lazy to submit an update over it

Furniture Tweaks is gonna appear as Better Containers in the mod menu cuz that's what it was originally gonna be called and I forgor to change it
That's why I was thinking maybe default to instance mode for people who are uncomfortable naming functions that way, since generally speaking they can call the init function and use data / functions statically through something that is fundamentally intended for instanced use and it doesn't need to be the end of the world
Calling a distance function that takes x1, y1, x2, y2 (due to poor design) in an instance would not do any harm, e.g.
you still call the functions like normal
TestUI:new()
they are just declared within those tables and i do metatable magic to make it work
then its just a matter if i expose static or instance methods depending on what you operate on
Right, exactly... so couldn't you just interpret a definition of function TestUIElement:doAnotherThing() to mean function TestUIElement.InstanceMethods:doAnotherThing(), for example?
no
Hmmm
functions declared like that would be "shared"
yes still works
but doesnt have the isolation
I seeeeeeee
Well... falling back to shared mode is not the end of the world.
People can just use it that way if they're uncomfortable with the extra layer of organization, right?
Or would that have potentially severe user experience consequences?
nope would just behave the way stuff is rn
Well that's not catastrophic
would just defeat the purpose of the system
which is why ive been think thonking of other systems
Fair
let me grab another one
I mean, what about just letting the first variable be static or not?
---@class ExperimentalUIElement
local ExperimentalUIElement = {}
---Performs rendering
function ExperimentalUIElement:render()
end
local ObjectManager = {}
---Creates a new object which has the given object as the super class
---@generic T
---@param class table
---@param newClassName `T`
---@return T
function ObjectManager.derive(class, newClassName)
local o = {}
setmetatable(o, o)
o.__index = class
o.Type = newClassName
return o
end
---Creates an instance of the given class
---@generic T
---@param class T
---@return T
function ObjectManager.new(class)
local o = {}
setmetatable(o, o)
o.__index = class
return o
end
TestUIElement:new(static, . . .)
---@class DerivedUIElement : ExperimentalUIElement
local test = ObjectManager.derive(ExperimentalUIElement, "DerivedUIElement")
local testInstance = ObjectManager.new(test)
in this one all the static stuff would be handled in the ObjectManager
I see. What if you wanted your own static class?
I mean honestly do you need a static class implementation? What's wrong with tables as containers for functions? It's... pretty much the same, no?
You could set custom permissions on your table and whatnot...
it was mostly about documentation and code completion
For sure
Got it.
What about a flag above certain functions used by the code completion engine somehow?
I'm not sure how you're doing code completion, but could a simple comment-like flag above static functions suffice?
@static
@instance
?
im just using vscode with sumneko lua server
and unfortunately it doesnt have something like that
(Shit sorry Static)
Damn because that would feel nice to me personally, if I were into code completion. Tbh I just survive on word completion by opening everything I'm working from lmao
It's really not THAT bad lmao
Hi! Got a questoon isn't about modding, but I think you guys my best bet)
I would like to increase EXP multiplier on a specific skills which are pain to level, like Nimble, Strength, Fitness. But to keep other skills at default multiplier. Is there a config file with a variables for such things so I can just edit it to my liking?
There's a mod called Ultimate XP Tweaker or something like that. You can set multipliers as sandbox settings
Yeah, I've seen this mod, but I figured it would be easier to just edit a few files... I run a dedicated server on my Debian VM and sandbox options are not pleasant to configure
I don't think there's a config file like that
Can anyone give me a hand with Server/Client Commands?
function Recipe.OnCreate.eztTests(items, result, player)
local args = player:getBodyDamage():IsInfected()
sendServerCommand("junk", "sayStuff", player, args)
end```
```lua
local function onCommand(_module, _command, player, args)
if args then
player:Say("Shit, I'm infected.")
else
player:Say("Thank god, I'm not infected.")
end
end
Events.OnServerCommand.Add(onCommand)```
this seems obsolete the recipe function triggers on client, try doing it without command.
do I still need to reference the Module/Command variables?
Like, do I need to do if _module then [work]
just put it all into OnCreate funtion
I want to make a communication framework so bad but need to finish stuff before starting new ones
can't do say on the server side
@drifting stump Dealing with the same funky logic that you did when trying to reinvent the class inheritance thing.
Trying to mimic the same behavior inside of a JS environment with roughly the same call structure.
Are you triggering somehow the recipe or is it vanilla?
I'm triggering it, right click "do recipe" that triggers the onCreate.
so it's client side, not server
as I remember args in send commands accepts only table (even don't single simple value), it isn't?
i fund some wired pills u can pour them into other
i can't help you like these guys can but this mod does something similar to what you are trying to do
https://steamcommunity.com/sharedfiles/filedetails/?id=2697750877 , assuming you are just trying to make the player say something that relays outside of the local user
some mod does that
lol isn't that vanilla usage?
idk
think so
don't remember when play vanilla pz last time 
there is a mod that speeds up adding things to each other. but yea it's vanilla if you have them in your main inventory
but I think vanilla have no this feature
can someone help me with a mod? I am looking to change this so that i can adjust the amount of money you get for each item and also eliminate the ability to exchange clothes. https://steamcommunity.com/sharedfiles/filedetails/?id=2933448776
I tried to move it into client and it won't call it anymore. I think OnCreate can only exist on server.
on server some mods but admin says it is mods for respawning stuff itd
it depends on what it changed. if your mods changes anything vanilla, it will tag item with mod name
unless you turn that off
function ISChat:onCommandEntered()
local command = ISChat.instance.textEntry:getText();
local chat = ISChat.instance;
ISChat.instance:unfocus();
if not command or command == "" then
return;
end
local commandProcessed = false;
local chatCommand;
local chatStreamName;
for _, stream in ipairs(ISChat.allChatStreams) do
chatCommand = nil;
if luautils.stringStarts(command, stream.command) then
chatCommand = stream.command;
elseif stream.shortCommand and luautils.stringStarts(command, stream.shortCommand) then
chatCommand = stream.shortCommand;
end
if chatCommand then
if chat.currentTabID ~= stream.tabID then
showWrongChatTabMessage(chat.currentTabID - 1, stream.tabID - 1, chatCommand); -- from one-based to zero-based
commandProcessed = true;
break;
end
chat.chatText.lastChatCommand = chatCommand;
local originalCommand = command;
command = string.sub(command, #chatCommand);
if command ~= "" and command ~= " " then
chat:logChatCommand(originalCommand);
end
chatStreamName = stream.name;
break;
end
end
``` something like that
sec i will check it in pure vanila
only if edit exactly item
mod can just add context menu option
My God.. I actually got JS code to mimic class constructors and declarations JUST LIKE Lua PZ code does.


good work (anyway won't use it
)
Umm how could you use it lol
It's an experiment to figure out a way to implement pseudo-classes from PZ code.
I'm not talking about the location of your file... I mean client side execution...
I guess I don't follow ๐ฆ
Ummm mods are disabled
and u can stil pour pills
Restart your game. This is a vanilla lighting bug that can happen. Also, painkillers are defined as "drainable" items. You can consolidate pills together just like you can any other drainable. This is a vanilla feature.
I think u will do smth with that (u like to do crazy things) XD
is that a death animation?
How in the god damn did that Skeleton fly without falling apart?
I need answers
Is it possible to change the resulting item for a recipe through an OnCreate? I tried
result = InventoryItemFactory.CreateItem("ezt.ezt_used_pos") but that doesn't seem to be getting 'er done.
that'll just add both items, right?
it will add whatever items you define in additem
you can define more than just items here but yea it works for that
this is pretty good now
aiteron is still working on much of things but also some good updates
i think scripts done first
well, can I remove the resulting item during the OnCreate?
Using x lua and xml? ๐
well, is the result in the player's inv after OnCreate or before
You're a wizard Glytch
Hmmm i should make a deathscythe some time
I don't expect anyone to know what the heck I'm doing.
Im not. Lol credit goes to @dark wedge and @thick karma for teaching me stuff
getInventory():Remove(self.item)
so lua playerInv:DoRemoveItem(result) playerInv:addItem("ezt_used_pos")
Nice I'm glad they're lovely people
What are you doing?
I'm writing a 1:1 Lua to TypeScript transpiler.
I have no Idea what that is
magic things
I see what sort?
also if you are using a custom module, you dont need to prefix, could cause issues.
assuming the item is from your own mod
most interesting thing (for me personally, idk about someone else) is web engine for pz

The quicker I get this transpiler working, the quicker that engine gets fleshed out.
The very basic test for it works right now.

Me neither LOL I have never come in here a lot
So I don't know much
When i fly from ground zero then move up it works
I changed the flight animation from moving forward to just plain idle
Then just move the players xand y axis similar to fastmove
BUT when im on an open rooftop z1
Then i fly
As soon as i reaach the edge i fall animation
then @red tiger is our savior 

Please don't fuel my ego. xD
I see
ahh because your state is still to floor probably
ha-ha
i was so busy trying to figure out my stuff last night i missed your thing
is there any desire for this group of functions?
the static variants draw in the given position regardless of y and x scroll
did you end up trying to mess with ISFastTeleportMove.moveZ ?
it seems to somehow store what level you are at when using fast move
well not somehow, it's there
Jab is my E-son.
lol
he's e-dopted.
debug fast move sets the level on player update, that's my impression
@fast galleon my issue earlier was in the recipe onCreate instead of OnCreate
In other news, what name do you want me to use on my biofuels mod when I give you credit
he who shall not be named
๐คฆโโ๏ธ
glad you figured it out btw
yea, I had to go back and do a print cause something wasn't right. Doing too many things at once right now, haha
Ye idk how to bypass that but to manipulate the fall animation
I did didnt work
Yea, it looks like the result is placed in your inv after the oncreate. Doing this still places both items in my inv.
playerInv:Remove("ezt.ezt_used_neg")
playerInv:AddItem("ezt.ezt_used_pos")```
Is there a way to completely remove the result I wonder?
by chance for fun. did you try to execute this after RemoveResultItem in the script itself?
never tried it but would be funny it is worked
try RemoveResultItem
in the script, prior to calling that?
not really sure how scripts work in that regard but i'd assume worked the same way. total non educated guess
maybe you get the new item and the result of the craft itself doesn't generate what was intended?
oh, you can put RemoveResultItem:true, directly in the script
will it stop the generation from your function though also is what i mean
From vanilla
{
[Recipe.GetItemTypes.RipClothing_Cotton],
Result:RippedSheets,
RemoveResultItem:true,
InSameInventory:true,
Sound:ClothesRipping,
Time:100.0,
AnimNode:RipSheets,
OnCreate:Recipe.OnCreate.RipClothing,
OnTest:Recipe.OnTest.IsWorn,
}```
I'm doing an if/else so I can just add the result in the else
I'm curious about InSameInventory:true, now too, that might be applicable to other recipes I'm making.
One day I will write mod tutorials..

Is there a way to use DoParam at run time?
Atm it looks like DoParam only works before you get in the game
Im pretty sure it works at run time, though youd need to respawn the item you alter
Oh interesting, thank you
It works, thank you
i also saw setCanPerform which i have 0 idea it's usage and dont see any other place it's used as well
but if OnCanPerform sets conditions prior to crafting, maybe it sets after?
it has string param so no idea
getCanPerform also so im sure it can be figured out based on whatever that returns i guess
i also see this
public void DoResult(String var1) {
Recipe.Result var2 = new Recipe.Result();
String[] var3;
if (var1.contains("=")) {
var3 = var1.split("=");
var1 = var3[0].trim();
var2.count = Integer.parseInt(var3[1].trim());
}
if (var1.contains(";")) {
var3 = var1.split(";");
var1 = var3[0].trim();
var2.drainableCount = Integer.parseInt(var3[1].trim());
}
if (var1.contains(".")) {
var2.type = var1.split("\\.")[1];
var2.module = var1.split("\\.")[0];
} else {
var2.type = var1;
}
this.Result = var2;
}
``` looks usable
at this rate there def has to be a way to do what you are trying. since you can see the result and change it
I'm assuming that setCanPerform is adding a CanPerform to the recipe via lua
recipe Take Test
{
[Recipe.GetItemTypes.eztTests],
Result: ezt_used_neg,
RemoveResultItem:true,
Time:200,
OnCreate:Recipe.OnCreate.eztTests,
OnGiveXP:Recipe.OnGiveXP.Medical15,
}```
This worked btw
if player:getBodyDamage():IsInfected() then
player:Say("Shit, I'm infected.")
playerInv:AddItem("ezt.ezt_used_pos")
else
player:Say("Thank god, I'm not infected.")
playerInv:AddItem("ezt.ezt_used_neg")
end```
ahhh sick!
glad to see you getting a W haha
another thing i thought of that might be dumb but for your zombie loot issue
if you just rebuilt the vanilla distro list containing zombies and remerged it with a condition attached, would that work?
like if your mod module detected then return after a certain point
i been trying to think of a way for it to work and since it wasn't working the way you mentioned, thought that might be a possibility
i tested it with my mod. i just put a condition for sandbox option that if it's set to 11 it just doesn't even run the addition to the table
or in your case true
dunno lol pains me to not know enough to have a clear way to handle that but ๐ fun time consuming stuff
it's crazy, cause the removeDistros function is vanilla, so it should work
totally agree lmao
pretty sure that would work if you REALLY wanted to figure it out though and no one has a better idea how to use the Vanilla function
i dont even think the vanilla z distro list is large at all and tbh you'd only need to actually remove the thing you dont want and leave that. and just make a separate function or something that just readds exactly how it would have based on conditions. i take back sandbox since you'd probably have a good reason for replacing the distro on them in the first place
Is there a way to force certain items to respawn? ๐ค
Like what if I want to force respawn all the Military helmets, in all players inventory, and in all containers?
Errors. Errors everywhere.
Thats events on events hooks
hack the inventory page, if container has 0 military helmets then add helmet?
10/10 icon
so i been looking into metatables and how they work for trying to derive a class
this seems less complicated than what i was doing last night
siiiiick
Anyone know if there is a UI element for checkboxes? Can't seem to find it.
Living up to the name I see
i still dont know how to do that z axis thing everythings still on z0
really
i cant make it work wiith z1
from z0 to z1 or z1 to z0
Was gonna say the flying is making me think of Dragonball, but alas, no Z
what did this return? player:getZ()
can't you detect and store that
does it not update without manual intervention?
no matter how you end up doing it, it's sick. but it's still interesting to me
ISTickBox
Its always z0
I need a way to climb up imight makean invisible stair
But only 2 directions idk what to do
level +1 would have a lot of nil squares, trying to move through that would be hell
The falling animation is bugged sometimes
i see
Ive fix that
The player isnt moving by walking its idle
if you are runnin on tick though to detect that z level
The movement comes from fast move pseudo
Its just animating not really setting the x yet
Z imean
Idk how it attacks too
Lol
did you see how that sets Z?
I remember it using on player update function
so that you don't fall
when i made that derived class i thought this was the point of that
NipFly.OnTick = function()
local player = getPlayer()
if player ~= nil and NipFly.currentZ ~= 0 then
player:setZ(NipFly.currentZ)
player:setLz(NipFly.currentZ)
end
end
-- Add OnTick function to the OnTick event
Events.OnTick.Add(NipFly.OnTick)
at least it seems like it
just renamed vanilla after derive but this is how it's written
the way it's animated right now looks good though for how it's moving
Every time I learn something new, I find 10 more things that I have to learn to understand the new thing I learned... lol
The fast move already fixed you on a position so i can freely move the space
Byt the problem is when you are about to fall
Like from a building it wont work like as if you started on an empty tile
I think i need to check how the falling happens
Where is it triggered
ohh i see
you want to fly from any level without pressing anything?
so if you walk off edge it's just to flying
i somehow didn't grasp that earlier
that would most likely be handled by IsoPlayer update
is that related to the PlayerFallingState Class?
every time i think i understand how something is used, it's like used for the exact opposite somehow lol
Uh did Steam just go down?
It tends to go down
lol
I've had the same problem
mmmmmm
Happy.
Wrote a working ArrayAdapter that detects tables used as arrays and translates them to literal arrays in TS. :D
It copies the logic of the Lua code and translates to TypeScript.
That's interesting
i am about to take off but thank you again. i did learn that using a metatable is way easier for my purpose also
Ayyy
You'll figure out what you need to know as it comes up
The entire project has been around 8 months of active work.
Good luck!
tyty
My god
You need a break my guy
That's a lot of work Jab
Around 500-600 hours of work.
I hope you ain't too tired
Those are baby numbers, I put 2.1k Hours into unturned.
It's worth it. People can save countless hours modding in TypeScript because of that work.
And no im not proud of that
My main account from the first MP game I played as a kid has 40K hours.
That's the main account only.
Jesus Christ
Just added that up, That's 1,600 days
I'm sure with logged hours like that there were many AFK hours and accidental naps
Probably like 5000 hours max of that.
I had other accounts which totalled like 10K hours.
Still crazy
So, after looking through vanilla and a few other mods, I'm not not really sure why my distros aren't working, anyone have an idea?
Also a non-central server I used for deving had like maybe 8K more IIRC.
Lost a lot of shit when that server vanished.. =(
I still hurt from that and it happened back in 07
The nice thing about putting a ton of sandbox options in your mod is that you rarely have to deal with people asking you to tweak things to their liking.
The disadvantage is that the backend becomes so much messier...so many conditionals...and God help you if the conditions have branching sub-options... ๐ญ
I generally put my procedural and base distributions in two different files to mirror the vanilla file structure -- but I don't know if that would matter, since you're just inserting into the tables. Have you tried without the spacing?
I haven't, let me give that a shot
I use functions for complex conditionals
If it's more than like 4 conditions, it gets a name.
Maybe 2 functions
Depends on sitch
Yeah, so do I. The pain mostly comes from the fact that these particular options involve zombie clothing options, and because AFAIK you can't give a zombie an item to wear and keep it on w/o using outfits, that means every single tweak needs a new zombie outfit.
Hmmm sounds rough...
So a simple decision tree like:
Blazers or sailor?
2-button or 3-button blazer?
Ribbon style?
Ribbon color?
...generates an absolutely excruciating amount of outfits that then need to be handled... ๐ฅน
I see. How is an outfit defined?
xml file
Oof
Yeeeeeeeeep.
Not jealous of your modding goals
It's one of those things where just slapping something together and getting it to work is easy enough -- so there's that, at least -- but trying to optimize it / make it readable / futureproof / etc. is just awful.
Still no dice
Thhppt. I assume you did all the usual bonehead checks like made sure the path is good and the file is actually being loaded? Item names correct, etc.
Unless I'm missing something in front of my face the statements seem syntactically correct so I'm trying to think of other options.
lowercase i in folder name
items instead of Items
Could be nothing, could be something?
I'm going to comment out the Suburbs Distro and try that
Yeah, see if segregating them helps
Yep, yours looks exactly like mine.
Does anyone still have the isClient isServer image of the table that shows the boolean values depending on SP/MP/Host?
The only differences are:
- My files are segregated into module_Distributions.lua and module_ProceduralDistributions.lua
- My "items" folder is lowercase
- I don't require Distributions, just Suburbs and ProceduralDistributions
look at better tile picker
it has a fly feature already
isClient true for clients in multiplayer
isServer true for servers in multiplayer
both false for singleplayer
Thank you.
yea, so, I made a copy of the mod and put it in the workshop folder. But never changed my working copy's mod ID so it wasn't reading any of my changes.
At least you have a rocket launcher for situations like this.
Or a situation like this, perhaps. Probably won't need it for another.
Knew it was gonna be something silly. :P
Modding PZ is silliness.
silliness is fun 
So good news, Skizot was able to get my gun's model to appear in game. Now I'm having the following problems:
Can not 'rack gun' with X key
Can not equip on the back, like a rifle or long melee weapon.
Can not load a magazine (I specified the M16 magazine for now) because there is no option in the weapon's context menu
Can not attach reddot or any other attachments
Does not highlight a target when aimed at any distance
Does 0dmg or knockback when fired (with unlimited ammo cheat as test tool)
The rate of fire doesn't sound correct, it's a lot slower than .074 shot per second
No repair function in the item's context menu.
The code LOOKS right, but maybe you guys can find something I can't. Current iteration of the script.txt file.
I'll check back tomorrow as I'm getting tired now. Please DM me if you found something, feel free to test the code in your game if you are feeling froggy.
If its still the same like when i last used it i dont think its going to do any help. Ive seen the code before.
Thnx tho
Abt the rack thing
try racking it manually using lua console
If it doesnt do that then your gun has no rack feature
If it did but didnt show
Then the animation is missing
If it worked and it showed then the script is the problem
Or your own keybind could have the problem. To check try other guns
Hope this helps
Im not really familiar with guns stuff
but in general this will be the case
I wish everyone shares yours enthusiasm

I actually burnt out and took a 4-month break. I've recently come back lol

I feel that. Your mods are quite unique and sophiscated from what I've seen and used, thank you for making them.
I made a silly mod for myself
https://steamcommunity.com/sharedfiles/filedetails/?id=2933678076
I'm glad to see that you were able to make your dream mods come true ๐
I really had no idea what a pocket TV was ๐น
Anyone know of a command for getting how many days since a server started?
I'm thinking it's getDaysSinceStart() but I noticed this is part of ZomboidRadio
so i'm wondering if this is the correct method
me neither. I just thought "I wish I could play the first week of PZ without returning to a TV every 4 minutes" and boom ๐
https://projectzomboid.com/modding/zombie/Lua/LuaManager.GlobalObject.html#getGameTime()
https://projectzomboid.com/modding/zombie/Lua/LuaManager.GlobalObject.html#getGametimeTimestamp()
These are global methods. I'm not sure how they interact with multiplayer.
declaration: package: zombie.Lua, class: LuaManager, class: GlobalObject
Thanks, i'll look into these!
if getVariableis('bFalling') then
setVariable('setbFalling', false)
end
is this possible?
whats the proper syntax
any wizard i can summon? to help me with this part hehe
they are sleeping lol
he spelled it wrong anyways lol
too busy testing his mod to fix it lol
isbFalling
isbFalling returns a boolean and setbFalling returns void with param of boolean
will they work though is the real question
If I sponsored a PZ Modding Codejam, would anyone join?
probably would be a gift card or however the winner is legally able to accept their prize
I see a ton of talent and thought it would be fun to see what people come up with, since there will be some vote of sorts from community. something like that. anyways I will for sure do it if it seems like enough people care. the more than are interested, the more i'd be down to offer as a prize
wouldn't be less than 50 USD value for anyone who cares
that would be cool
I failed to submit for the map jam last year because I burnt out before finishing it lol
high expectations come with high pressure
I would probably even without money prize set, but I'm too green to PZ modding to suffice even my ideas right now.
i'll preach to that ๐
I'm still like trying to find a way to spawn vehicle and return it without sending a command to server.
all the super wizards are off and about lol
i'm attempting to create a context menu and sub menu that allows the player to change the strength of lights lol
I'm not sure what the getVariableis function is, but if you're trying to get this on a gamecharacter you can just check: character:isbFalling()
There's a setter too: character:setbFalling(bool)
you really can't move on from the lights ๐น
Thank you!
Hows the off hand mod
almost done
lol i decided that since my first lightswitch mod was just a tile replacement. i'm going to release this as an addon, but requiring the original
this is literally an entire overhaul of lightswitches
the epitome of perfectionism 
the way they works and their limitations haha
even adding battery connectors, or server owner can disable the feature
He will even add a function that if your electrical level is way too low you might get electrocuted
Like 20% chance
And and a 50:50% chance to die if you are not wearing rubber shoes lol
See he might do it lol
Its beyond that
Lol
You might want to centralize that
so many menu additions and removals and icons!!!
I spend 30% of my time coding and 70% of my time editing workshop cover images 
I partially gave up on some parts of this damn thing, as I've re-written the damage function like 3 times now and I'm tired. I mostly can't get zombie damage states to be consistent across MP because you can't easily get zombies by ID, any solution is kinda slow. So, I got a workaround to approximate the damage for the offhand. It gets it pretty close and I'm happy enough with it. I'll revisit it soon enough, but I kinda want to be done already.
honestly i am sure in it's current state is FAR above and beyond anything out there lol
How many days you guys think it might take for me to finish this mod?
The flight
ahh
just the flight? then i'd say another day or 2. it seems to be working already.
Who r u talking to nippy
you haha
gonna do slingshot weapon for my next mod ๐ get back into modeling
wanna use it to make noise and knock zeds down and do like no damage
Idk abt the z axis part
Like how do i collide to the second floor then be teleported there and dont fly up cuz currently all of the things i have are just on z0
yea he's trying to find a way to have the game update the players z level. apparently no matter what floor you are on, the game recognizes you on 0
can you not just use character:setZ(1) or whatever? i'm not sure i understand
same shit for workshop decription
