#mod_development
1 messages ยท Page 248 of 1
Have you stated your model already like in models_items.txt?
no !
wait what
im confused what you mean
Yes. I mean I'm not sure if the game cares about letter casing, but it never hurts to err on the side of exact matching.
steam\steamapps\common\ProjectZomboid\media\scripts then models_items.txt
Here I can only say for a fact that Windows OS doesn't care about casing, but Linux does.
Not to be confused with anything running on top of the OS such as PZ exe
ill do that right now
But you need your own file for that.
yeah !
Or you can do it in same file you have your item script
If thats a small mod then there should be no issues, but for bigger projects i belive its better to have models/items scritps/recipes separate
the game doesn't care but depending on the way you keep mental picture of the project you may separate it into different files
with an asterisk that there may or may not exist special files that are hard-coded to have special funciton
Yea, i meant mental health mostly in mnde
the name of the .x file?
with path
{
mesh = WorldItems/GrilledCheese,
texture = WorldItems/CheeseSandwich_PeanutButterSandwich_BreadSlicesRotten,
scale = 0.3,
}``` like this example
From example above you would use WorldItems=GrilledCheeseRotten,
{
mesh = WorldItems/bossblackcanmodel,
texture = WorldItems/bossblackcantexture,
scale = 0.3,
}```
like that?
Scale is not needed if you have it right sized already in blender
ah shit meant to delete that im too tired for this
do i need to put the module at the top of the script or no
yes
do i have to do that for all scripts?
Im confused
Ahh module base/whatever
I guess im tired too
Yes you do if its separate file
How do I get game's current tick rate?
(besides measuring it manually - this might not be particularly reliable)
Wait. Are ticks = frames? How does this works on a server?
.
About ticks i can't really help you there
Do you have debug on? Does it says something about mesh?
The issue might be, spelling error/wrong locations for model/texture or maybe your 3d model is actually "empty" by mistake?
Can't really help since i dont see what you have there
ive made like double triple extra sure theres no spelling errors
the model is definitely not empty
not sure what to do
the model definition script is a txt, right?
Yea
so I added a new hat to my hats mod, and i think it's breaking the game now. The only thing that's changed is the two new XML files for forward and reverse cap, the updated clothing script, the updated guid list, the new texture and icon, and the updated distributions. Any idea where I should be looking for problems?
I can launch a server fine if i disable the mod, but with it enabled even as the only mod on a server it gets stuck on initializing
You should look in the files you added.
I've looked through all of them and don't see anything that looks wrong, not sure what I could have done
You can troubleshoot it using the substitution method. Replace individual elements with a known working equivalent until it starts to function properly. The last thing you changed was the point of failure.
I'm going to try removing the new distribution location, maybe it isn't liking that for some reason. I would think if that was the issue it would just not spawn there, but idk
I guess I might have to revert to the older version, and then re-add the new hat
It could also be a malformed asset file, or a script that enters an infinite loop.
hmm, i'll keep digging
oh wow this is recent, i didnt know the forums still a thing,
are you doing a java mod cuz im not familliar with java and the syntax isnt lua i think
Iโm using the pipe wrench library, so itโs Typescript
I thought itโd be easier to post code and stuff on the form, but it broke when I replied and submitted the same thing like 3 times ๐๐ญ
local amount = 2
local perk = "Perks.Woodwork"
otherPlayer:getXp():AddXP(perk, amount, false, false, true);
sendAddXp(otherPlayer, perk, amount)
try this
@red tiger
sendAddXp, interesting I havenโt seen that function before
ISPlayerStatsUI.lua
Kegen is here looking for Typescript help using Pipewrench
oh ok sorry
At the bar
Sorry lol
Haha no pressure didn't expect immediate response but you know you're like the guy who does that afaik lol
If you're willing to try to learn to do a mod in Lua a lot of people here may know the way; if doing it in Typescript, fewer know, but Jab might have ideas.
I guess you have to actually set the others players xp AddXP isn't enough?
yeah might end up switching, I was just already familiar with typescript
yep
depends on how you get the other player
from the getOnlinePlayers
If you explain your goal to Jab above he may know whether it can be done in Typescript
I have it written out in the form post https://theindiestone.com/forums/index.php?/topic/71631-help-adding-xp-to-other-player-in-multiplayer/#comment-402593
I'm very new to modding in Project Zomboid so please forgive me if I'm overlooking something. I'm trying to create a mod where if you sitting next to another play that is actively gaining xp then you'll also gain xp. The idea is kind of like an apprenticeship mod, anyways, I'm having trouble addi...
thats what vanilla commonly uses as local var for saying a player but not you
hehe
maybe remotePlayer is better?
cuz ISPlayerStatsUI.lua has the functions for admins to add exp to other players
you just need to take the function and translate it into typescript in your case
if that doesnt work then you can always use the send commands
@red tiger
Anyone know why this doesn't work? I am trying to hide and disable the moodle UI.
local moodle_ui = UIManager.getMoodleUI(player_idx)
moodle_ui:setVisible(false) -- This does nothing at all
moodle_ui:setEnabled(false) -- This only disables the surrounding UI box and not the textures themselves
??
it was wrong ping
ah
Sorry I'm drinking at the bar
Looking at the source code, moodle UI object rendering routine doesn't takes "enabled" and "visible" flags into account
it's weird because settings visible doesnt do anything but setting enabled gets rid of the panel (though the moodle textures still stay on the screen)
wdym "panel"
it has a parent bounding box around where the moodles render
But, I semi-fixed this by calling UIManager.RemoveElement(moodle_ui) after clearing the children and setting it invisible and disabled
ah
well, the moodle UI object calls normal UI element rendering after it's done rendering moodles
I call it during event OnCreateUI and it doesn't seem to want to work (the func callback gets called, just not removing the element and everything else, maybe moodle ui isn't created then?)
So pipewrench can't extend ISBaseObject classes due to translation issues. Other than that api calls are similar.
@winged ocean ^
You don't have to call instanced methods with colons.
I'm allowing pz mods to be coded with JavaScript... And that should probably be considered a war crime
floppa says it's not a war crime if you had fun
Lua 5.1 is just JavaScript ES5.
In that case, I think Java would be a little more like C with extra steps
here's how i disabled them for statsapi:```lua
LuaMoodles.disableVanillaMoodles = function()
local ui = UIManager.getUI()
for i = 0, 3 do
ui:remove(UIManager.getMoodleUI(i))
end
end
Nice, but do you know how I can get the call order for all the events (considering you wrote some docs for events)?
Because I tried disabling in OnCreateUI and OnCreatePlayer but neither works as I am assuming it's too early in the events
wait your stats api already kinda achieves what I want to do 
Why do I find out now aaaaa
i think i used OnGameStart
Does your stats api mod conflict with any mods you know of? I am trying to create my own moodle UI in lua, but it seems you have already done that
If the lua stats part of your mod doesn't affect anything major, I will probably just use your mod in this case and rewrite other sections of the UI
not that i can remember, it's supposed to be indistinguishable from vanilla
Though I might end up rewriting the moodles anyway as I am doing the whole game ui
I see, thanks for helping me tho!
my whole take is anything UI =
and
best ui - no ui. And it's totally not because I suck at making ui
Using OnGameStart works like a charm, thanks!
any documentation on how the new grapple tech system works?
How can i add a new Type to Recipe.GetItemTypes ?
function Recipe.GetItemTypes.NewItemType(scriptItems)
scriptItems:addAll(getScriptManager():getItemsTag("NewItemTag"))
end
Hi! Anyone know if there is a way to spawn only empty/drained items in the loot table? I have a custom room def with propane tanks, but I would like it to only spawn empty propane tanks and not filled ones. Is this possible to do?
I don't think any B42 code or documentation has been released to modders, but I live on Kashyyyk, so I might have missed something.
someone should make a mod for project zomboid, that turns it into decaying winter, so real...
looting during the day, and surviving waves of bandits when it hits night(and you are only allowed to sit in ur base, as storm will murder u :3 )
would be hype
This does not make sense. How are the bandits out at night, while the player cant be?
idk, it just does work like tha
in original game
also uh demons
cant wait for these cuties to appear in pz frfr :3
can someone give me a real crude guide to making a clothing mod? i just wanna make some cowboy clothes and ive never modded before
The bottom one
Heya
I have added a bunch of recipes and items with an own mod and now whenever I open the crafting menu or map, the error magnifier is showing me that there is an issue.
first I thought it was the lua I added (which included foraging stuff) but it still breaks on this after removing the lua files (for opening the crafting menu):
it looks like having added the items / recipes is breaking something in the base code. Did anyone run into a similar error like this?
Hey, what does the ShareDamage property does ?
I'm trying to mod in a volley gun for, huh, reasons ๐
nothing, it is a removed feature
being hit by an error here when trying to remove items from distributions, it was working fine until i added more to the list, idk if its due to how many i have or due to the distribution type im removing from? its getting to the point now where its somewhat fustrating, everytime something is at a working point even the slightest touch completely breaks it
can you show the function call that triggers this error? it implies the arguments are probably wrong
"--BarCounterWeapons
RemoveItemFromDistribution(ProceduralDistributions.list["BarCounterWeapons"], "762x51Box", nil, true);
RemoveItemFromDistribution(ProceduralDistributions.list["BarCounterWeapons"], "M16A2", nil, true);
RemoveItemFromDistribution(ProceduralDistributions.list["BarCounterWeapons"], "FN_FAL", nil, true);
RemoveItemFromDistribution(ProceduralDistributions.list["BarCounterWeapons"], "M60", nil, true);
RemoveItemFromDistribution(ProceduralDistributions.list["BarCounterWeapons"], "Mossberg500Tactical", nil, true);
RemoveItemFromDistribution(ProceduralDistributions.list["BarCounterWeapons"], "M733", nil, true);
RemoveItemFromDistribution(ProceduralDistributions.list["BarCounterWeapons"], "Remington870Wood", nil, true);
RemoveItemFromDistribution(ProceduralDistributions.list["BarCounterWeapons"], "M24Rifle", nil, true);
RemoveItemFromDistribution(ProceduralDistributions.list["BarCounterWeapons"], "GunToolKit", nil, true);
"
its occuring on the FAL line, it was working fine when we only had it removing from the PoliceStorageGuns
i looked into this and idk where the game is even setting these values cause i would've guess an oncreate function but there is none. anyways i would hook into the OnFillContainer event as two of the parameters should be easy to check, although idk what your custom def is... if it is specific container in specific rooms then that will cover it
my first guess is change "BarCounterWeapons" for "BarCounterWeapon". i dont see "BarCounterWeapons" in distributions
omg you might of been right,,,,
nope, the error has stopped but the items are still spawning
specifically just in military so im sure i can fix it
control f through distributions.lua to be sure the locations you want to remove from are spelled correctly
The ModJam will be extended until the 14th. ๐
For anyone not too sure they could get something done.
is there a way i can store an ID of a player and use it to see if the player is still connected later on a server?
its fine if it changes upon reconnect, perferred actually
i just want to lock access until the player leaves the game then unlock it
so as long as the number or whatever stays during the session it would be fine
guessing getPlayer():getID() returns the same "int id" used in getPlayerByOnlineID(int id)
Cant you just use steamid
^
Do you all think that it would be faster to use multiple textures over rendering multiple rects?
I mean I know rects aren't too demanding but I am not sure
I like how dynamic rendering rects are, but the performance cost I am not sure of
:getOnlineID()
thank you, of course just as I want to test this my dedicated server is down for maintenance...
Hi, im trying to fix expoit in some mod. I hooked clientside method, but need to check if player performing an action. local player = getPlayer() then player:isPerformingAnAction() doesnt work since player is null. whats correct way of getting player in client lua?
is there a good forum post or anything for a detailed walkthrough on making traits?
im trying to just reference how other mods do it but im just confused
seems to be simple as
sneaky:addXPBoost(Perks.Sneak, 1) ```
that is correct, when are you calling getPlayer()? on the client it should always return a player unless there isn't one at the time you call it
when i click oven ui, so im alive. also its MP
media/lua/client/
local function hookAnvilTabUI()
if AnvilTabUI then
local original_onMouseDownFurnaceItem = AnvilTabUI.onMouseDownFurnaceItem
if original_onMouseDownFurnaceItem == nil then
return
end
function AnvilTabUI:onMouseDownFurnaceItem(x, y)
local player = getPlayer()
if player:isPerformingAnAction() then
return
end
if original_onMouseDownFurnaceItem then
original_onMouseDownFurnaceItem(self, item)
end
end
end
end
Events.OnGameStart.Add(hookAnvilTabUI)
huh, i have no idea why that wouldn't work
Exception thrown java.lang.RuntimeException: attempted index: player of non-table: null at KahluaThread.tableget line:1689.
sounds like a different issue entirely
attempted index: player of non-table: null means somewhere something is accessing <something>.player but <something> is null
yeah the getPlayer returns null there
oh sorry Exception thrown java.lang.RuntimeException: Object tried to call nil in onMouseDownFurnaceItem at
i notice your function header is AnvilTabUI:onMouseDownFurnaceItem(x, y) but you call the original as original_onMouseDownFurnaceItem(self, item), the arguments don't match?
and item would be expected to be null since no value is assigned to it in your code
oh damn, i was hooked in different method earlier and i absolutely missed this
thank you
but still it dies before it reaches there
your function never accesses player in a table so i think that is probably happening in the original function you're hooking, and usually that would be caused by passing things it doesn't expect
before i sent wrong error, second one is correct where Object tried to call nil
that happens when you try to call a function that doesn't exist, does it say which line this is occuring on?
it doesn't seem like that should be an issue anywhere in your code either
ok i got it working, now failing when i call the original method. no idea why it was failing for player being null, i only removed comments and corrected arguments
__len not defined for operand at KahluaUtil.fail line:82. rings a bell? all i did was calling original method in hook
the original code is calling #foo where foo is not a table but something else
but original code works, only if its called from hook, then it fails. thats really confusing for me because idk if i need to care about initialization of stuff that is initalized in original file. In that case it would be easier just copy whole mod, edit what i need and use it like that
local function hookAnvilTabUI()
if AnvilTabUI then
local original_onMouseDownFurnaceItem = AnvilTabUI.onMouseDownFurnaceItem
if original_onMouseDownFurnaceItem == nil then
return
end
function AnvilTabUI:onMouseDownFurnaceItem(x, y)
local player = getPlayer()
if player:isPerformingAnAction() then
return
end
if original_onMouseDownFurnaceItem then
original_onMouseDownFurnaceItem(x, y)
end
end
end
end
Events.OnGameStart.Add(hookAnvilTabUI)
method im hooking into
function AnvilTabUI:onMouseDownFurnaceItem(x, y)
ISScrollingListBox.onMouseDown(self,x, y)
if self.selectedRow then
local selectedRow = self.items[self.selectedRow]
if not selectedRow then return end
if self.favoriteBtn then
if not (self.parent.tabType == Tab.Inject) then
self.parent:manageFavorites(self.selectedRow)
end
return
end
if self.addBtn then
self.parent:addToCart(self.selectedRow)
end
end
end
all i need is to cancel that when timed action is being performed
ah, you need to pass self original_onMouseDownFurnaceItem(self, x, y)
when a function is declared with : instead of . there's a 'hidden' self parameter
ahaaa, will try, thanks a lot
omg it works, you saved my sanity thank you
Hello! I was trying to create a mod so i can use a bot command to get infos ( it has a flask and bot behind it)
I have some problems with the code of the mod and im not sure what is the problem, can someone help me?
server:
-- Import necessari
require "NPCs/MainCreationMethods"
require "ISUI/ISLayoutManager"
-- Funzione per ottenere le statistiche di un giocatore
local function getPlayerStats(playerName)
for i = 0, getNumActivePlayers() - 1 do
local player = getSpecificPlayer(i)
if player and getUsername() == playerName then
return {
daysSurvived = getHoursSurvived() / 24,
zombieKills = getZombieKills(),
skills = getPlayerSkills(player)
}
end
end
return nil
end
-- Funzione per ottenere le skill di un giocatore
local function getPlayerSkills(player)
local skills = {}
local perkList = PerkFactory.PerkList
for i = 0, perkList:size() - 1 do
local perk = get(i)
local level = getPerkLevel(perk)
if level > 0 then
table.insert(skills, { name = perk:getName(), level = level })
end
end
return skills
end
-- Funzione per gestire i comandi inviati dal client
local function onClientCommand(module, command, player, args)
if module == "ServerInfo" and command == "RequestPlayerStats" then
local playerName = args.playerName
local playerStats = getPlayerStats(playerName)
if playerStats then
sendServerCommand("ServerInfo", "SendPlayerStats", { playerName = playerName, playerStats = playerStats })
else
sendServerCommand("ServerInfo", "SendPlayerStats", { playerName = playerName, error = "Player not found" })
end
end
end
-- Aggiungi la funzione onClientCommand agli eventi
Events.OnClientCommand.Add(onClientCommand)
Shared:
require "ServerInfo"
you don't call global functions through the global object, they're just part of the global namespace
e.g. LuaManager.GlobalObject:getNumActivePlayers() should be getNumActivePlayers()
like this? (i change the message)
You do not need the require lines. Those are vanilla files. They will always load before your mod.
That wouldn't cause errors though; it's just unnecessary code.
It will probably help if you share more details about what doesn't work or the errors you see.
after removing those 2 lines now it works, thanks
idk why tho ahaha
I suspect something else you changed along the way explains it. As far as I know, unless I missed a typo, those lines would just ask the game whether it needs to load files it definitely already loaded.
But yeah glad you're sorted good luck
thank you
yeah, requires can't really change the execution of a file beyond potentially inducing some global changes the file is sensitive to (but that wouldn't happen in this case)
i wish they hadn't named it require, it's really misleading
not that i can think of something succint that's descriptive enough ๐
guys whats the workflow for MP mod development? Uploading every change to workshop to test is not the way right?
during early development i recommend testing as much of your mod in singleplayer as possible as it's much faster and *generally* behaves roughly the same, but of course make sure anything you're unsure of does actually work in multiplayer and by the end you should have actually tested everything in multiplayer
And then you'll realize you have to rewrite your entire code bcs MP sucks ass 
But overall I agree, make it SP compatible then see if MP works
i've never had to make major rewrites for this
for testing multiplayer i recommend running a dedicated server locally, if you set your game to non-steam mode you can run multiple clients locally to test most things that require multiple players without actually going through the hassle of finding someone else who wants to help, sending them the mod, etc
of course this may change with less experience, you need a general idea of what kind of things you need to synchronise and if you're unsure of something you should always check it in multiplayer first
i would rather recommend always testing in multiplayer since that's your target platform but the load time difference between singleplayer and multiplayer is absurd
but basically every change i make, i have to upload to workshop and restart server, or is there another process?
i wouldn't upload to workshop until it's done
you can just run off of your local copy until then
If you want to test it in coop with someone you can always upload it unlisted and provide link to other person
I write everything in a way that should in theory work for both MP and SP from the start so that my code is structured from the start with multiplayer in mind (including any potential compatibility with splitscreen), testing MP and SP back and forth as I go. I do a lot of MP testing and it can be time-consuming; I tend to just do other things to entertain myself while my server loads. Whether I jump back into MP to test something somewhat depends on the code change I'm testing. If I change something that I am fairly certain would have no MP implications, I may wait until right before publishing or some change to an MP feature before I do MP testing again.
Are you thinking you should upload a new change every time because you're getting "file does not match" errors where the live version of your mod doesn't match the workshop folder version that your client loads?
that, but i guess i can an disable checksum, but then how i have up to date files?
I wouldn't disable checksum
An approach I've come to prefer is to edit the mod.info for mods that i am updating
It's minorly risky because you might accidentally disable the mod for people if you forget to fix it berfore updating
But it makes things easy
if you're testing in non-steam mode you won't even have access to workshop mods
Alternatively, unsub from your workshop mod
i do usually test in steam mode but with a separate cache and workshop disabled
Yeah this also. Conflict will never happen in non-Steam mode
having multiple copies can fuck with you in other ways too
Specifically, if I am updating a mod, I just add " X" to its name and "X" to its id in mod.info
And then I have a server config with X in the name
Where I run the X versions of mods I'm updating
Then I can stay subbed and avoid conflict
Or any other fanciness
also, depending on the structure of your mod, not all mods actually need a second player to test if they work in multiplayer
100%
for a lot of mods you just need to confirm that the server and client communicate correctly and you only need one client to check that
rn i mostly doing "fix" mods, learning lua and pz. i was modding rust before but thats entirely different. But my process in PZ is coding > upload to workshop > start server > test > coding and its tedious
Zombies 
if you don't know if something synchronises you should test that in multiplayer first
The problem is a bit worse than that lol
Any action you apply on a zombie needs to be exactly applied for each clients
This removes any possibility for randomness or you need to sync zombies
Which is exactly what I have to do
well, yeah
(which is easier said than done)
does anyone know how i could add custom level up sound
There is plenty of mods that do just that, you could probably reverse engineer it
Check out the mod called "Better Call Saul Level Up"
Where can I find the lua file with professions?
getPlayer():getOnlineID() just returned "0" on my dedicated server test... but getPlayer():getID() returned "2" not exactly what I expected.
Only outputs something server side actually
Now that I think of it
Maybe
ick...
getPlayerByOnlineID(short id) this is off the client but I do not see a function to pull the short id
probably just have to use getPlayerFromUsername(String username) from client and getUsername() from isoplayer
onlineid is what you want
it probably returned player 0 because that was the first player?
doggy is wrong about onlineid only working on the server, the whole point of online ids is for recognising the same player on opposite ends ๐ญ
you can use the global function getPlayerByOnlineID(int id) to get the player object from the id
it looked like the username version worked too
Not I believe it outputs a long number
No ?
no, online ids count from zero
each player who connects reserves four numbers for each player slot
that's interesting
so the first client gets 0-3, then 4-7, 8-11, etc
nobody really plays splitscreen so usually you'll just see 0, 4, 8, ...
so if I getPlayerByOnlineID(0) then it should pull my player that I am testing with and if it was pulled while I was offline it would return nil?
the ids reset when the server restarts, but if a client leaves and rejoins before the server restarts they get their old id back
The goal is to find out if something happens and a player is disconnected so I can release a lock on an object
yeah, if you call that function while the player is offline you'll get nil
thank you so much!
got an issue going, so I am making some new ammo packs for Easy Packing for Gunfighter [2.0] (brita ammo)
the vanilla game ones already have their translations edited when packed
so these new packs need new translation names
can you overwrite translations?
someone give me a tutorial on how to create a mod item drop, I put a vaccine mod for the game and I wanted it to have a chance to drop from the helicopter
update on this, I found the bug
I forgot to add a result for two recipes and that is what broke all the code ๐คฆ
item CmpSyringeWithPlainVaccine {
Type = Normal,
Icon = CmpSyringeWithPlainVaccine,
Weight = 0.2,
DisplayName = CmpSyringeWithPlainVaccine,
Tooltip = Tooltip_CmpSyringeWithPlainVaccine,
WorldStaticModel = LabItems.Item_CmpSyringeWithPlainVaccine,
i need to add this script to this archive
I don't know how to work with scripts
iirc the helicopter events expanded should have something like that, a drop coming from the helicopters, might be worth to see how that modder handled it
this is the mod i'm working on
nvm figured it out ๐
๐ ๐
Does anyone have a mod that removes Lighters as a light source?
My girlfriend keeps running through all her lighters on accident, because she didn't realize the dumb fucking game uses a lighter instead of a flashlight when you tap F
I imagine it'd be a simple overwrite to the Lighter item that removes whatever string allows it to be used as a light source but I have never made a mod before so
Lighters shouldn't even be allowed to be a light source, they suck as one and are finite, it sucks
Perhaps a more complex version of the mod would be one that lets you set a whitelist/blacklist/preferred list for light sources, so you say will always use a certain flashlight or source over another one unless you Hold F and select a different source manually
Because the game really loves to pick some random bullshit light I have in my backpack instead of the one in my main inventory
I'm curious if TIS would adopt a major performance / utility fix for Kahlua2.
It's abandonware if not for the game and the last modifications were over half a decade ago.
Better error-printing for stacktraces and pcalls would be extremely beneficial to mods and the game itself.
Not to mention upgrading Kahlua2's engine to use more modern API for reflection and methodheaders.
Kahlua2 utilizes JDK 1.6 technology which is like mid-2000's grade Java API.
A thought I felt like sharting out here for any discussions or interest in this as a modification to the game. =)
I've rewritten the code in Lua and its still not adding the XP... What am I doing wrong? The print logs are showing the correct information
require "ISPlayerStatsUI.lua"
local maxDistance = 2.5;
local function AddXP(character, perk, level)
local players = getOnlinePlayers();
local array_size = players:size();
local teacher = nil;
for i=0, array_size-1, 1 do
local onlinePlayer = players:get(i);
if onlinePlayer:getDisplayName() == character:getDisplayName() then
teacher = onlinePlayer;
break;
end
end
if teacher ~= nil then
for i=0, array_size-1, 1 do
local onlinePlayer = players:get(i);
if onlinePlayer:getDisplayName() ~= teacher:getDisplayName() then
local distance = math.sqrt((teacher:getX() - onlinePlayer:getX())^2) + ((teacher:getY() - onlinePlayer:getY())^2);
print('Distance: ', distance)
if distance <= maxDistance then
onlinePlayer:getXp():AddXP(perk, 50, false, false, true); -- 50 xp as a test value
sendAddXp(onlinePlayer, perk, 50, false, false, true);
onlinePlayer:setHaloNote("Learning from " .. teacher:getDisplayName());
teacher:setHaloNote("Teaching " .. onlinePlayer:getDisplayName());
print('Teacher: ', teacher:getDisplayName())
print('Student: ', onlinePlayer:getDisplayName())
end
end
end
end
end
--* Events *--
Events.AddXP.Add(AddXP)
updated to use server commands and that works
local xpCommand = "/addxp " .. onlinePlayer:getDisplayName() .. " " .. perk:getId() .. "=50"
SendCommandToServer(xpCommand)
i don't think this will work if the local player isn't an admin
yep, just found this out... Is there another way you could think of?
make user admin and then revoke immediately? lol
such a bad idea ๐
Thatโs what I was thinking toโฆ I do like to live dangerously ๐
are there any good walkthroughs online on how to make custom professions?
Maybe media/lua/shared/NPCs/MainCreationMethods.lua might be able to give you some insight?
ProfessionFactory.addProfession is a function that is used in that file and it's probably the way to create/add a profession!
ill look into it, thanky ou
can someone help me tinker with the code for the "extended helicopter events" mod so that whenever a Drop falls from the sky it has a chance of receiving an item from another mod? pls call me in DM
it's not complicated
i think
yeah i guess albions right it the functions might not work for non admin. so iguess you need to do the send server commands..
and maybe need to check off some anti cheat types
you do but other servers will also take the risk if incase they use your mod
Probably not, I can make that risk know if Iโm posting to the workshop. I mostly wanting to play with my buddy using this mod idea.
just create a consumable that adds experience
easiest route
just one person? then just give em the exp via admin cheats?
I could but itโd just be more fun for it to happen automatically
And I wanted to learn how to mod
awsome!
well yeah in that case you have 2 options
the server client pingpong or the item oncreate thing
i suggest you try and do the function to add exp and do it to your own player to test
use the debug console
Massive victory today. I managed to get TypeScript classes compiling to support extending pre-existing Lua classes.
Technical under-the-hood stuff has to happen for this to work but it's all worked out now for PipeWrench.
@Jab idk why my discord is so fudged but I agree a LOT with what you said about kahlua
Oh? Nice.
I'm very excited that one of the biggest drawbacks to writing Project Zomboid mods in TypeScript is now something that can be overcome and is implemented now into the NodeJS-packaged compiler.
Can someone help out with a tilepack I'm trying to make? I've used tilezed to create the pack file and put it in the texturepacks folder. The .tiles file is in the media folder, and added the tiledefs in the mod file. The tileset isn't showing up in the ingame tile viewer or Better Tiles Picker, and I'm not quite sure why it's not loading.
so it seems like the issue here is that you can't add xp to remote players, that addxp overload is meant to allow for that but i couldn't find a case where the game actually uses it so it wouldn't surprise me too much if it just doesn't work
you can use commands to trigger code on other clients - unfortunately you can't send a command from one client to another, so you need to ping it off the server, which makes this a little more complex than it needs to be ๐
```lua
--- client file
-- assuming player is the player who you want to give xp to, and perk is the perk object
-- the args table will be sent to the server, but only basic types can be sent (not objects)
local args = {target = player:getOnlineID(), perk = perk:getId(), amount = 50}
-- the two strings here are technically just arbitrary strings that get passed along to the event handler, but it's best for the first one to be an identifier for your mod, and the second to be an identifier for the command itself
sendClientCommand("MyMod", "AddXP", args)
--- server file
local function handleClientCommand(module, command, player, args)
-- make sure we only do stuff if it's actually our command
if module == "MyMod" and command == "AddXP" then
local target = getPlayerByOnlineID(args.target)
-- the target argument sends the command to only that client
sendServerCommand(target, "MyMod", "AddXP", args)
end
end
-- triggered when the server receives a command from a client
Events.OnClientCommand.Add(handleClientCommand)
--- more client stuff!
local function handleServerCommand(module, command, args)
if module == "MyMod" and command == "AddXP" then
local target = getPlayerByOnlineID(args.target)
local perk = Perks[args.perk]
target:getXp():AddXP(perk, args.amount)
end
end
-- triggered when the client receives a command from the server
Events.OnServerCommand.Add(handleServerCommand)
Hi! I'm starting to develop my first PZ mod and i was researching how the game works, at this point I've learned a lot but there're some things that i don't get it well and I'm stuck rn.
I want to create an option in the contextMenu when the player rightClick a square that has an item (that i made in a scripts txt) just like a generator, however i saw the game's logic to create the contextMenu for the generator and depends of an isoGenerator that can be storaged in the worldObjects (i can't make an isoObject for my new item, right?).
So, i was wondering how can i make that contextMenu? idk if i need to create an IsoObject or something similar or there's another way to check if a square contains a specific script-made item.
Any help would be a lot appreciated I'm learning on the process hehe
How would I do "if player presses escape exit to menu"?
I got the disconnect code:
getCore():exitToMenu()
And I know I can run Events.OnKeyPressed.Add(func) But how would I check if it's the ESCAPE key?
Have any of y'all tried server-side Java modding yet? I'm looking at a comprehensive nutrition overhaul and I think I can do it all in Java and server-side, but I'm not sure where to start.
Yes. I've done this for over 10 years here now. I don't know exactly how build 41 does nutrition. I believe this is client-side ran for 41. A lot of things are moving to server-side for 42.
Might I ask what you've done server side? And yeah, the more I looked at nutrition, the more I realised it ran client-side for 99% of it.
I've created my own Spigot for PZ called Sledgehammer. It's not updated to the current build at this time since no one currently uses it and I mainly used it for my own server back in the day.
I also run an anti-cheat that people use.
That's pretty cool. With B42 I really look forward to server-side modding.
i still wouldn't expect things like this to move to the server
only some specific systems have been mentioned as being moved
Naturally, but it's a fresh new field of possibilities. Java modding can get quite powerful!
Speaking of servers, though. How can I transmit moddata to the server?
I want to make it so when players interact with a piece of furniture that has a container, compare a stored value from the server against some condition, and if met, save a new value on the furniture.
object:transmitModData()
And the similar object:getModData() will get the fresh stuff from server?
no, that just returns whatever the client/server calling it has
transmit sends what you have to all others
there's no synchronisation beyond that
(never mind that there's a clear race condition here because It Just Doesn't Tend To Be A Problem)
So if I have two players in a room, one of them updates a shelf's moddata and calls transmit, will the second player now have the updated data?
yeah
Okie. And yeah, race condition is a risk but it'll be okie.
in general you should transmit after you make any change to moddata
even if you don't need the moddata from other perspectives for some reason the next transmit will overwrite it
Yeah that makes sense.
And if I add an item to a shelf, do I need to run any sync/transmit command as well? I've only worked with the vanilla transfer thingies before (e.g. the timed actions), and I don't know if they have special handling in their code.
you need to use addItemOnServer for it to sync, if i recall correctly you still need to call the regular addItem too
same for removing items
you won't need to use the OnServer-s for an item entering or leaving a player's inventory though since that isn't synchronised to begin with
Gotcha. Thanks! This is very helpful and I look forward to implementing this. I'm trying to do a like.. "scrounging" skill that lets you find extra loot in containers as a form of loot respawn that isn't limited by the same stuff as vanilla respawn.
Does getTexture only return textures from .pack files?
Tried using getTexture to get a texture in media/ui/test.png and it just does not want to work, giving nil every time
works with getting a vanilla png file in a pack though
had an idea for a mod but i've no got the experience modding to even know where to start, thought I'd post the idea here incase anyone like it:
you get a certain amount of skill xp shared for watching or helping another player do a task such as mechanics or carpentry, as the best way to learn something in real life is from someone with more experience in something. Like say we work on a car together, in vicinity of you I get 25% of the XP or helping you up to 75%, and task also quicker depending on the level of each player in that skill who's helping. I think it would add even more to co op and be a great way to even out skills so we don't have to each focus on one thing.
Player could start task, other player could right click them and choose "help with task" option, otherwise watching mechanic would mean if you are standing within 1-2 metre of other player you get a smaller amount of XP for seeing what they are doing
something like this would be great as there would be lots more reason for co op, and also everyone would be able to have a bit of each skill rather than only focusing on 1 or 2 things each
again no experience modding zomboid so this is just an idea, don't know if something like this is even possible in the game
something this
if key == "Escape" then
tho im using mobile so its hard to check syntax
oh and
theres also a keycode version
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.
try to check your packfile if it has sprite
and
if you did the export wrong or something went wrong the tile property window will show red ???
Aww shoot. I forgot to edit my post. Let me do that real quick. For some reason, having a tilesheet png with an _ just made the tileset not load in PZ. Tried a lot of different things, the moment I changed the name of the png tilesheet and restarted the process from scratch, it worked ๐
did you put your png on both a folder and 2x folder? thats also important
then the tiles and packfiles should be exported to that folder too
oh
so what was the name and whats the new name
cuz i dont think thats a thing . cuz i know you can add _ .. must be something else
It was literally deadtiles_01 and deadtiles01. I know the underscore can be added, which is why it was weird. But in the end that change got it to work :x
then the tiles would become deadtiles01_0, deadtiles01_1 and so on
Oh, yeah. That can end up becoming an issue haha.
the tilesheets name is called deadtiles01
the tiles inside it would be named same but with sufix _0 _1 _2
automatically
also this is more of a #mapping concern
Yeah. Most tilesets (the png files) end with _01.png, 02.png etc. So it seems weird nonetheless
thats how vanilla does it cuz they have locations that uses multiple sprite sheet
you can either adopt or just do your own thing
also just a reminder
pls add your tiledef on the wiki
It's a mod for one specific server, but will do nonetheless, just to prevent issues ๐
Soo.. I did a thing. Can anyone tell my why this is a bad idea?
looks more intuitive than BTSE copy
Yo, I don't know if this is the right place to ask but can someone explain to me how the different music types work in the .bank file. Like as in the different mx's? Like all the mx_action songs seemingly have 2 songs, one made of the different sections and then the whole song in full and it sounds slightly different? Like where do the 2 different songs play??
Also on the mx_exploration tracks some of them have bridges and I can't for the life of me figure out where it goes, I assume the tracks play over each other in game but I can't really be sure.
Also side question, is the in-game music player based on the track's BPM? Only asking because the action intros don't play into the rest of the track and sounds like the track should start halfway through the intro track if that makes sense, I'm not very good at wording stuff like this but hopefully that kind of explains it lol.
they get layered and stuff, the game tries to match the intensity of the music to the game state
i think there might be some outright redundancy with copies of the tracks before they did this?
is that true for the exploration bridges too?
should be yeah
thanks, do you know anything about the BPM thing? its not all that important if not lol
๐ฎ May I interest you in: https://github.com/Project-Zomboid-Community-Modding/pz-community-modding ?
Anyone know if its possible to fly somehow?
Like just floating around at second floor level in god mode?
I tried brute forcing it, but the lighting system became a seizure hazard
I remember there being a fly mode, but I can't remember in which mod that was
maybe better tilespicker?
Yep, I see it. Thanks.
Hmm, the lighting freaking out seems to be the same. Guess its just a side effect of flying :/
I have a question about clothing modding if anyone knows stuff about that
For admin purposes (RP server), I would like to make an invisible piece of clothing (if you put on an dog from the fauna mod, only the animal is visible)
My first instinct was to just make a piece of clothing / copy over the spiffo suit and delete the textures, because I assumed that the player model beneath would be invisible (to avoid clipping) when the suit is equipped
To my surprise... the suit is invisible, the player model isn't
Not second floor but still flying
Interesting, they all suffer from the same issue.
For some reason the game won't update lighting if the player isn't on the ground
However the shadows were last calculated just move around with the cell
So a little unhinged, but I guess I need to make a fly mod that builds an invisible temp floor under the player...
wizardry!
. Am I insane
the way i did was 100% thru animations. player still on the ground. but i added checks for fences and water
then just teleport instead of noclip
ye the lighting is affected on other levels which is why you need to stay on the same level you want to see
is it possible to store the copied area and use later . sorta like create own template or something like that. also does it copy moddatas?
and third question . what happens to the area pasted? is it wiped clean?
yes it is
it's because I forgot to add .png which I forgot getTexture needs ๐ญ
Also I really wonder why there's two MoodleType for hungry: Hungry and FoodEaten which both reference media/ui/Moodles/Moodle_Icon_Hungry.png
Testing to see if the new image appears: https://github.com/Project-Zomboid-Community-Modding/pz-community-modding
Nice, that should save me some time to explain what it is ๐
Welcoming anyone who wants to review code going in, or anyone interested in adding tools, bug fixes, etc
Also welcoming anyone who has ideas/bug reports/requests related to vanilla things
Already working on this haha
"saved copies"
I have something kind of like that.
๐ฎ
Well, would you mind if I borrow some stuff from this? unless you're inclined to add it yourself
cuz i was thinking maybe it was too heavy to store or something
I don't personally own the rights to all of it. For the simple stuff, I am sure its no problem. The bigger things like zones and userdata I woud have to go ask all the contributors
Oh you've had more contributors than I have
The only thing I can boast is probably the debug tool suite, and the fact that it auto uploads from the repo to steam
you're a genius, worked like a charm
factual statement
this is insanely smart, idk why I never thought of using workflows to auto upload!!!
i dontknow why..using lua debug outside of pz the code works fine but when run in game it crash
I have basically created this mod
kahlua doesn't have debug module
well pz does anyways
maybe cuz its from sandbox option?
it has its own module under a different name
debug is undefined
which is by the way how my gamestate emulator can automatically hook itself up when the Lua script is running outside of pz
if not debug then _EMULATION_MODE_ = true
No way, is it uploaded anywhere I could try?
wha so you have like an external terminal?
no i just have a script that defines the same functions as the game and runs a very simple version of them, just barely enough for the mod Lua script to function
it mostly does absolutely nothing, but most of my script doesn't touch the actual game so it's fine
but most of my script doesn't touch the actual game
please enlighten me
the bulk of the code looks like this - note that it doesn't touch the game at all
Not published yet and itโs still in very early stages. It works a little differently than how you described itโs less complex. Basically if you are close enough to another player and that player is actively gaining xp youโll receive 1/5 of their xp gained because they are โteachingโ that skill to you. I can share the code with you if youโd like.
and then the emulator fills in the tiny amount of functionality that the mod script actually needs
That sounds brilliant for a work in progress, no need for code but thank you anyways, very much looking forward to trying it out, I think more interactions between players such as this really add to the co op gameplay

it turns out the complex string is whats causeing the error, i minimized it and it didnt crash..
finally figured it out...
anyways
sandbox option only has 5
what im trying to achieve is this
string double enum bool integer
i want to add customizeable table
function parse_outfits(str)
local outfits = {}
local parts = {}
for part in string.gmatch(str, "[^;]+") do
table.insert(parts, part)
end
for _, part in ipairs(parts) do
local outfit_name, statements_str = string.match(part, "([^=]+)=(.+)")
if outfit_name and statements_str then
local statements = {}
for statement in string.gmatch(statements_str, "[^:;]+") do
if statement ~= "" then
table.insert(statements, statement)
end
end
outfits[outfit_name] = statements
end
end
return outfits
end
---string "Outfit_Ranger=Howdy?:Yeehaw!;Outfit_Survivalist=...:Blend with the shadows;Outfit_Farmer=Time to work!:What time is it?:So Tired;Outfit_Bandit=Hey buddy:How Can I help You?"
local string = SandboxVars.NPC.Statements
local parsed_outfits = parse_outfits(string)
for outfit, statements in pairs(parsed_outfits) do
print(outfit)
for _, statement in ipairs(statements) do
print(statement)
end
end
so apparently kahlua's require is also not the same as in normal Lua. It only accepts the slash notation even though it doesn't work on folders.
Hey there, I am new to modding in general and just started playing with Zomboid mods. I have been able to test a few things and see it actually working. Add a few functions to events, etc.
I am now trying to get a custom /command or something like that.
I have add a very simple code (as per below) just to try to see it working before adding my logic to it. If I invoke the function itself from the Zomboid lua command line, it works. But using the:
sendClientCommand() or sendServerCommand() doesn't.
Any help is appreciated
print("hi")
player:Say("hi")
end
function OnClientCommandServerCommand(module, command, player, args)
print("hi")
player:Say("hi")
end
-- Register the command with the server
Events.OnClientCommand.Add(OnClientCommand)
Events.OnServerCommand.Add(OnServerCommand)
Just to add a bit more info, I think my problem could be just the confusion of server/client. I have been trying to test that opening Zomboid64 as debug and nosteam and going through Host.
foodeaten is the buff you get for eating while already full
i don't know who decided to remove the dot notation support from require but they should've disabled the slash notation instead. Would've prevented people from attempting require "../../util.lua"
(which by the way doesn't work because require operates on modules, not folders)
client/server commands are for code client/server communication, they aren't related to the chat /commands
it comes up every so often here and it seems like there really is no modding support for chat commands, you can hook into chat to catch when someone says something manually or look if someone's already made a library mod for this
it makes sense, but I still have the issue of not being able replicate the use of sendClient/sendServer commands just to see it actually working. I have been issuing the commands via the Lua Command Line, not with /command on the chat
I thought about doing via filtering the chat, it's probably enough for my use case. Just would like to be able to parse the command from rcon as well
your client command handler isn't being added to the event because you made a typo in the name, and the client can't send server commands
@bronze yoke the more you know
i think Say isn't networked so you would only know if it worked if you see the print in the server log
I have been doing a tail on all the log files being generated
oh i was just curious what you meant by 'modules not folders'?
anyone knows if I can change a fix recipe for a weapon via lua code? I want to make it editable on sandboxoptions
it's what it says on the tin. Require loads a module, not a file. And it looks for modules specified in package.path , which is obviously incompatible with the very idea of specifying a filesystem entry to require. Though modules are usually simply single files and module path is usually the same as folder path, though both is just one of the options. The confusion is normally avoided by using the dot notation everywhere and by encouraging users to also only use the dot notation. But in PZ dot notation is disabled and using it causes require to fail.
This + the fact that only the slash notation is used everywhere in PZ files, gives unwary users the wrong impression that require loads a specified file in the filesystem, rather a module by the given name.
Do I even need to verify that PZ's package.path is missing an entry like ?/init.lua?
I guess I should mention WTH is even "dot notation"? Normally in Lua you use require("cpml.matrix"). The module path separator is a dot - it's the dot notation. It's also valid to use require("cpml/matrix") which is the slash notation. Since, as I said, require doesn't actually loads files by filepath, using dot notation is normally encouraged to avoid any confusion.
it's maybe a little strange that the dot annotation isn't supported at all but pz's require really does just follow filepath exclusively
as a sanity check I did the require "../test.lua" which simply says print("REQUIRE TEST") and sure enough it showed up in the log as require failed.
require uses absolute paths, not relative
project zomboid's implementation does
kahlua doesn't implement the package library at all
what it does is this fusion thing where every media/Lua folder counts as the same place, which can contain files by identical name and I'm not sure what require does about it, but I do know that it allows your mod to require other mod's Lua files, and it doesn't allows loading from parent folder as in the aforementioned example
I mean it's in line with normal Lua operation.
It's just it's conspicuously missing the dot notation option.
in the case of identical filenames, it prioritises shared -> client -> server
literally just because it searches each path in order and not because they actually thought of this and handled it ๐
Heck yea!
Flight with working lighting
Now I just gotta lock the player, make them invisible, and my free cam is complete.
Noclip with fast move ? Or another method which doesn t require disabling the anticheat ?
What's shown is noclip and fast move, but I'm keeping an invisible floor under the player because lighting doesn't work while the player is airborne for some reason.
I haven't looked into online at all, as this freecam is not a stand alone mod, just a needed feature for a larger mod I'm working on.
ty!
is it possible to supress the vanilla behaviour of an event? say it got into my custom function and I would like to just stop whatever action was doing. I tried return but the event still happens
probably better if I add more info on what I am doing. I added a function on Events.OnAddMessage to capture a rcon servermsg <something -- I am able to filter that, do a setServerAlert(false) (that make it as it doesn't show the red message anymore). However, the message is still showing on the chat. I've tried setShowInChat(false) and it doesn't work
I am kind of moving that way to create some custom /commands
you can try removing vanilla event handler from it
but i would not recommend doing that. You never know what important functionality hinges on it executing on time.
More importantly, if unimportant functionality becomes critically important in the future.
I am not sure if you know this, but Events has like a callback list. When you add your function to OnAddMessage like Events.OnAddMessage.Add(my_func), you are adding my_func to the list of callbacks that the event OnAddMessage then executes when the game globally calls the event. Returning from your callback my_func will return out of your callback and only your callback. The event still executes all of the other callbacks that other mods and the vanilla game has set up.
This is only how I understand events so far, and even if there is no callback pool per-se, the concept is relatively close to the actual functionality (I am going for ease-of-reading over accuracy)
Adding to that ^ you can do the reverse of Add
trueee
Events.OnAddMessage.Remove(some_existing_handler_function)
that makes sense but as you said too dangerous to handle that way
You just gotta know what exactly is the handler function
Well you intended to bypass the functionality entirely so it can't go any more wrong than that.
if the setShowInChat(false) actually worked, my problem was solved ๐
well not entirely true. what I was thinking in achieve is if the message follows a specific pattern, then yeah, could just stop the action
Maybe you can do it in another fasion? What's your goal exactly?
Sounds like you want to send an internal system message. Not a visible chat message.
To that end you can implement any fashion of OnClientCommand and OnServerCommand callback handlers. They both can carry pretty much arbitrary payloads.
I want to be able to pass a command via rcon message to then run some others functions. Kind of create some custom /commands
this will be further automated via discord bot
you can intercept outgoing messages
the OnAddMessage was the event that I could find that was capturing the rcon message
yeah that one
but I could only get to that event with the servermsg <message> command. And that is a general broadcast message, so that's why I was trying to supress the vanilla behaviour
and you said a bunch of related functions didn't work anyway
so uh, I suppose you can add a GUI box and do away with the /command stuff entirely
You cannot create new commands for RCON. You need a java patch for that:
https://steamcommunity.com/sharedfiles/filedetails/?id=3243738892
And here examples on how to create RCON commands
https://steamcommunity.com/sharedfiles/filedetails/?id=3243741273&searchtext=commands
yeah I saw that but I am trying to avoid the java patch path.. I am also new on modding Zomboid, so just having fun exploring what is possible to achieve
just realised this isn't a good way to handle that. OnAddMessage gets fired for everyone that receives the servermsg haha
don't you love it when you were working on your code and when you went back to test it, suddenly there's so much lag that even Windows is stuttering
wow so you this is via lua? incredible
you might be able to figure out 100% see everything via lua if you keep at it
you can use the msg event and have it detect specific string
but im not sure if the game will treat rcon commands like regular chat. so if it doesnt then you might not be able to capture it
package zombie.characters;
import zombie.iso.IsoCamera;
import zombie.iso.IsoCell;
public final class IsoDummyCameraCharacter extends IsoGameCharacter {
public IsoDummyCameraCharacter(float var1, float var2, float var3) {
super((IsoCell)null, var1, var2, var3);
IsoCamera.CamCharacter = this;
}
public void update() {
}
}
it is probably to heavy to transfer through MP mod data during save.
What steps do I take to start making jacket and pants and how do I set it up
Hey I've got a table in Lua like so:
-- The table outline (what it looks like)
self.texture_table = {
base = getTexture(...)
}
-- Accessing the table, causes error here
self.texture_height = self.texture_table.base:getHeightOrig()
But it errors upon accessing the base texture. It's getHeightOrig of non-table: null which means somehow base is nil? But it's clearly not, before this line I can easily print(tostring(self.texture_table.base)) and it will print something along the lines of Texture{ "media/path/to/tex", w:32, h:32 } so it definitely does exist. How is this even possible??
There is not much else to show from my actual code, as it's pretty much exactly this.
The texture_table field is set when the new func of the class is called, so it is definitely correct. The arg that gets copied to the new func exists and does contain a texture, so it's not that.
it is likely searching for it in getHeightOrig() and it doesn't exist there. are you sure this is the proper way to call this function?
yes, I use this func on other textures too
It might be due to the table being copied in the new constructor so maybe the texture doesnt pass through properly, ill test that rn
ok nevermind, now it's nil before I pass it to the constructor, give me a sec
i dont know the structure to a Texture object, which is what getHeightOrig() uses . i dont have knowledge on the functions your using. does self.texture_table.base directly call a texture object?
self.texture_table.base is a Texture
and the Texture class is what getTexture("path/to/tex") returns
well i know im not helping a lot... your print does not print out nil at all? my first thing i would do is add a check for nil when making the table as i assume it is passing something other than a texture at some point
hmm I do a nil check at the end but not at the start as it shouldn't ever be nil anyway, I can still add one
It passes the nil check but then still says it's nil ๐
self.texture_tables[moodle_str] = interface.texture_table_dummy
local texture_table = self.texture_tables[moodle_str]
if self.texture_tables == nil or texture_table == nil then
logger:error("Tex table was nil before assign!")
return
end
texture_table.base = getTexture(key:format(moodle_str, ""))
logger:debug("Texture 'base' after assignment: " .. tostring(texture_table.base:toString())) -- error here, base is non-table (nil)
nevermind I believe I now know why
and I think it's too embarrasing to say
you check for nil after you already indexed the table. If there was an error the check is guarding against, the program would crash before the check can execute.
as for error here the "base" might simply be incorrect spelling, though I never checked the details so it's just a speculation
yes, but I don't see how this could cause an error. This is a simplified version of what my code is doing:
-- ctor
o.tbl = {}
-- init
self.tbl["test"] = { test = 3 }
local my_tbl = self.tbl["test"]
-- my_tbl can never be null here anyway...
alternatively it can be non-exposed java class variable, which is indexed as nil
I already fixed the error, it was a letter that was accidentally capitalised
in the texture string that I pass to getTexture
the best way to avoid typos is to never use literals
In my case I cannot as far as I know
I mean there's the whole "magic numbers" thing. String literals is just a text version of that.
I can't get the path of the texture without also having the texture already
so I just format a str with the texture name in a loop
nevermind apparently its still happening even after fixing the texture string
EDIT: It's fixed again. I seriously don't fucking know. It's not broken now and I have no idea how so I won't say anything else.
Screenshot bc itโs convenient
You may want to look at these vanilla game files for reference:
media/lua/shared/Translate/EN/DynamicRadio_EN.txt
media/lua/shared/Translate/EN/Recorded_Media_EN.txt
If you want to know how to generally start a mod, read the PZwiki
got it
look at first pin
thanks a lot
Guys uhhhh it's my first time modding PZ (i've pretty decent knowledge of LUA, because i've used RoLUA)
How should i detect the jumpscare? (like the zomboid appears suddenly with a loud sound)
i ended up checking and there arent any files accounting for TV/news stations, only the AEBS - Recorded_Media_EN includes the CDs, VHS etc
still gonna keep giving it a shot for sure but holy crap this is way more difficult then i imagined lol
ok maybe media/radio/RadioData.xml? I have never checked this stuff so I have no idea
you could probably just search for a line of text in the media folder and find where it resides
the jumpscare is done in the function updateLOS() within the IsoPlayer class. The way it is done it is not a simple check. i honestly think it would be easiest to use the BaseSoundEmitter class and check if the emitter is playing "ZombieSurprisedPlayer"
Do you have an example string of a text that is on the TV?
ill pull one up real quick
this is the right spot
Most of the stuff in there I found to also be in Recorded_Media_EN.txt too btw
idk if it's just specific stuff but idk it's weird
given the event Events.EveryOneMinute.Add(function) is there a way to see if the function is still being run in the event? I suspect that the function I added randomly stops running as the print statements just stop. trying to detect it and see if I can re-add it if it fails.
im just gonna have to figure out if i want to re-write some lines from what already exists or find out how to make my own randomized files lol
add a print that only runs if your function wouldn't. so for your entry if statement make a seperate if statement that only works in the opposite case essentially thats the only way i would think...
I think I could make another event every 10 minutes that checks a time stamp and if the function has not been run it would re-add the original function every minute. It just seems like a lot for a simple query. like maybe a list of functions that are in the event.
it doesn't throw any errors, just seems to stop running
that would work. and yeah that is a lot to do lol
thanks, going to do some more investigating, maybe its not stopping just a wierd bug...
Is there an official place to send bug reports?
Found an interesting one while working on a mod.
High cheating/abuse potential in MP
still in the suspicious territory that my logic is failed... trying to figure out why something works 99% of the time but not 100% and not failing the same way twice is annoying...
The forums afaik
Bugs go here. Please save us the time to translate all the posts in different languages and post them in English instead.
Thanks, im doing a Heart attack trait as a meme right now...
so if you see a zombie, you die?
"Tiny chance"
could be a really cool trait in reverse though. Something like "snake reflex". When you get startled by a very closeby zombie, you automatically push it so hard it always falls on the ground.
need those nitro pills...
I feel like making bad things a very small chance makes it a worse experience than if it was straight up bad. People get accustomed to never seeing the effects so they expect it to never happen, and so it's always a huge issue when it does.
You can try this fun experiment at home: add random zombies mod and set sprinters to 0.5%. You will die to random sprinters a lot more than if there were 20% of them, purely because they're so rare you never expect to deal with them, and when they attack you're completely unprepared.
you can read my paper work for more detailed
i don't think i can finish this project
maybe this would be a good idea for a better modder
It's kind of like using car seatbelts. What are the odds they will ever come into play, right? You could drive your entire life and never have seatbelts be anything more than a mild annoyance. Most people use seatbelts because not doing it is punishable by law. But you do make good use of seatbelts if you drive like me, where you can very easily get removed from the driver's seat by the lateral g-forces, and where you can very easily end up in a rollover accident.
I like this aspect, keeps you trying to expect the unexpected and still die :p
That's how the Project zomboid gameplay used to be, Expect, and still die
"That's how you die" - Project zomboid long ass loading screen
yeah well most people don't appreciate when their game ends purely due to a single bad RNG roll, particulalry when the odds are low and you can progress a lot before it happens
PROC is fine but it shouldn't be game-ending with no recourse whatsoever
happened to me more than once and I barely play the game, all my hours are in modding and not playing so I'd expect more experienced players to have it happen more often
true, there must be a better mechanic than just dying on the spot
I mean literally a handful of heart attacks you don't die on the spot
it's like an hour after or something
on my end I just play with transmission disabled. If I die, I want it to happen due to a series of bad decisions leading to me getting mauled to death by a huge horde of zombies. Not because I got a papercut and the RNJesus decided it'll get infected with Z-virus.
I would've played with bites on if there was a way to counter bites using skill. Because whether a zombie attack results in a scratch, laceration or bite is also pure RNG
when rendering textures above their original resolution, files from packs are rendered with nearest neighbour interpolation, loose files are rendered with bilinear interpolation
so loose files will usually look blurry
you can put it in a pack file
Ideally you would create a world 3d model
Not sure what you mean by that but there's already scripts for .pack files
Am I stupid?
for _, pile in pairs(piles) do
if master ~= pile then
master.merge[pile] = true
end
end```
``` for p, _ in pairs(master.merge) do pile = p; break end
if pile.allCount > master.allCount then --[[attempted index: allCount of non-table: true]]--
master, pile = pile, master
end```
for _, pile in PAIRS(piles) do
table.insert(matches, pile)
matches[pile] = true
end```
It gets worse. The merge list should only contain piles, but somehow there's an entirely different type of object and I have no idea how it got there.
@drifting ore <- becareful of suspicious DMs from this person. ๐จ
Also, can't believe 'Gee guys, where can I commission a mod?' actually fished a scammer
While as an admin of a discord dedicated to PZ modding no less
lol, that's insane
Did you ever figure this out?
I mean, you have the Key ring which would have the character name, so unless the players use Random every time, that's a starting point.
I would imagine the body keeps the survivorDesc object or copies some info? Otherwise one could write a onDeath event for it.
i've used old keyrings before for reasons i cannot explain
and character name doesn't necessarily equate to username, which is more important
i thought about using the player mod data, but iirc the mod data does not persist across restarts for zombies and the player mod data may simply disappear
It does actually contain a SurvivorDesc
theres just no getter for it
There's a way to grab javaFields though
Actually player zombies retain modData - as does any zombie with reanimatedPlayer flag
๐ฎ
People bad at the game pay a performance penalty 
assumed it got the zmoddata treatment of being flushed on restart
if thats the case then we're in business
It saves everything due to how the inventory works
true, it must otherwise the inventory would disappear
That might be why they're changing inventory logic ๐ค
B42 will solve world hunger
Too many bad players cooking servers
i'm still trying to figure out where the vanilla logging function that logs item transactions exists
There's a transaction java event
steamid, player, +/-#, container, and x/y/z
to prevent item duplication (or tries to)
oh i've been going deep into patching the weird duping stuff that happens with item transadtion, its a rabbit hole for sure
zombie\network\ItemTransactionManager.java
I ended up making my own version of server-sided management for game night
if its java i might not be able to disable it via lua then
i wrote my own logging stuff that collects all item transactions and dumps it in one go in a single string, instead of doing it in individual transactions
but i cant disable the vanilla logging, so its kind of sad
Item manipulation (afaik can only occur on client side) - so I have clients store what they planned to do; send a request to the server -> the server holds a cooldown, and sends back approval/denial to the client -> client checks their stored moves and confirms it was approved.
I hate it so much, but it eliminated 99% of issues
most companies would accept a 90% solution, 99% is basically 100% lol
Well the issues were with items being touched too soon/frequently by other players
oh yea thats a client-side thing, your solution solves that for sure
Looks like the transaction manager prints right to log, in a private method no less
Oh wait, what about this one
public static void receiveOnClient(ByteBuffer var0, short var1) {
try {
byte var2 = var0.get();
int var3 = var0.getInt();
int var4 = var0.getInt();
int var5 = var0.getInt();
DebugLog.Multiplayer.debugln("%d [ %d : %d => %d ]", var2, var3, var4, var5);
requests.stream().filter((var3x) -> {
return var0 == var3x.itemID && var1 == var3x.srcID && var2 == var3x.dstID;
}).forEach((var1x) -> {
var1x.setState(var2);
});
} catch (Exception var6) {
DebugLog.Multiplayer.printException(var6, "ReceiveOnClient: failed", LogSeverity.Error);
}
}
it goes timestamp -> steamid -> username -> container/floor -> # of items -> x/y/z -> [item]
I'm gonna pull hairs. I have a function that populates a table, and then a function that consumes that table. There's nothing else touching the table. The first function populates it with correct data, it passes verification. When the second function runs, the data is corrupted.
When you say consumes
It uses "->" in a string?
i'd have to see the lua to give any advice on that
it's 700 lines across 2 files
[10-07-24 14:09:21.659] STEAMID "USER" container +0 11299,8706,0 [Base.BlowTorch].
example^
Based on the 'consume' I imagine he would need to work backward so the table's order isn't broken
it pulls the first entry in the table and removes it. That's beside the point.
You know best. ๐
what's the second function do, and what does corrupted mean? how is your table setup and what are you putting in there?
All entries must be of "pile" class. All of them are of "pile" class during data generation and handling. When the second function runs, at some point one of the entries is "bodylist" class, complete with list of body IDs inside. Which is not a valid "pile" set of data.
I mean here's literally every instance where the table is accessed in any fashion.
pile.merging = pool_fetch()
local function delete(pile)
pool_return(pile.merging)
local function merge(piles)
for _, master in ipairs(piles) do
if master.allCount > biggest.allCount then biggest = master end
for _, pile in ipairs(piles) do
if master ~= pile then
master.merging[pile] = true
end
end
end
end
local function _merge(master)
for p, _ in pairs(master.merging) do pile = p; break end
for k, v in pairs(pile.merging) do
master.merging[k] = v
end
master.merging[pile] = nil
master.merging[master] = nil
In fact it's literally every instance the table is mentioned.
the merge function takes array-type list of piles taken from findPiles and they're all "pile" type.
the search function works off spatial indexing grid and the only information inserted in it is the "pile" objects
I could've blamed it on a faulty table pool but I've disabled it entirely and the problem didn't go away
And of course it used to work if I were to merge all piles immediately, instead of deferring it for later. But WTF is this problem where some completely extraneous piece of data gets in through who knows what crevice?!
What is a pile data set?
It's exactly what it sounds like.
You'll notice it contains a bunch of tables under "bodies". Well one "bodylist" exactly like it ends up in the "merging" table.
This piles table (not an array) contains a table of bodies, as well as a table of merging of previous entries to bodies?
merging contains references to other piles
Just working through the concept, sorry for the redundant questions, your goal is to simply merge pile data sets
for p, _ in pairs(master.merging) do pile = p; break end
if not pile then return end
for k, v in pairs(pile.pending) do
master.pending[k] = v
end
for k, v in pairs(pile.merging) do
master.merging[k] = v
end
for postr, list in pairs(pile.bodies) do
pile.bodies[postr] = nil
master.bodies[postr] = list
world.bySquare[postr] = master
end
master.x1, master.x2 = min(master.x1, pile.x1), max(master.x2, pile.x2)
master.y1, master.y2 = min(master.y1, pile.y1), max(master.y2, pile.y2)
master.oldCount = master.oldCount + pile.oldCount
master.allCount = master.allCount + pile.allCount
master.merging[pile] = nil
master.merging[master] = nil
grid.replace(world.gridSquares, master.x1, master.y1, master.x2, master.y2, GRIDSIZE, nil, nil, pile, master)
delete(pile)
That's why I hate coding
hang on
I might be having negative braincells there.
frickin short selling $BCLL because people value it less and less
have so much braincells in the negatives that world's economist are eternally puzzled that global IQ is above net zero
Actually no nevermind. I mean I wasn't wrong but that moment of epiphany was just a brain fart.
for a second I thought I forgot to delete the merged pile from the merge list. But the line is right there.
I'm not sure if this is related but variables being defined as tables take on references to the table - it doesn't copy it.
I also don't see where a bodies entry could get slipped in to the merge list
That's exactly the problem. How does it even get there?
the piles table passed to merge definitely doesn't contain a bodylist? i don't see anywhere else an unknown value can enter merging
Spent all day implementing some loot generation code. Finally able to test it - ready for the world to explode 
Where is pending defined?
master.merging[master] = nil this also makes me irrationally uncomfortable
it's because it merges the merging tables of other piles into it, which could contain master, and it would try to merge itself
you said it passes 'verification' at one point, i don't know if you meant manually but if you have a function to do that you can throw that around a few times as an assertion and see when exactly it fails and you'll know exactly what part of the code is doing it
the one findPiles returns? Yeah 100%. This code is never triggered.
if type(pile) ~= "table" or not pile.allCount then printsquares = true end
It's not a super thorough verification but considering that the whole thing crashes when it tries to access pile<actually bodylist>.allCount
it crashes the game or throws an error?
Just throws a Lua error yeah. Comparison operator is not defined for nil.
For which line?
specifically for this
master, pile = pile, master
end```
i didn't include it because it was super extraneous
I have a feeling cross referencing tables is leading you to nil one - and nuking the other references - and there isn't a bodies list in the piles list at all
var = table in Lua creates a reference
if you want to copy a table you can use copyTable(), or while reiterating, define each key/value as long as they aren't also tables
well i don't intend to make copies. None of that needs to be a seprate object from whatever came in through function arguments or was grabbed from a table.
in fact using the same object is what enables a lot of hashing lookup optimization shenanigans
Can you include a print right before the comparator to show what is being compared?
print("compare: ", pile, "(", pile.allCount, ") >", master, "(", master.allCount, ")")
Can you provide that again? (I don't see the printout anywhere)
Hey anyone that uses player moddata/global moddata. is there a sync issue sometimes between clients or client to server? i have code that seems to be working just fine but the player moddata i see is diferent from what it actualy is
are you trying to store objects in moddata by chance?
oh, actually, i don't think player moddata syncs at all
basically i have put a timer on the players moddata, and it goes down by 1 every X ammount of time. when they die, it saves that data to the global moddata. and when they respawn it takes the values from the gobal moddata to restore the players moddata. so that way it kind of persists across characters. but when im looking at the players moddata when they die, its a diferent value from what gets saved to the server, and then when the player respawns it correctly applies the right values but i see diferent values
and if their timer goes to like 20, and i relog, it starts back from the top
There's a client-sided globalModData object
depending on where the call to GlobalModData occurs it could be writing to the client's or server's
afaik the only time it's sync'd is on logins
Had a rude awakening trying to be clever and having GlobalModData.transmit
the global moddatas writing to the server, if i log into another character i can see all the globalmoddata
but player moddata is out of sync between cleints
You're sending the value changes over command?
yeah i use onplayerdath event to capture the players modddat then using SendClientCommand i send it to the server to be saved to the glboal moddata
and then send a command back with the modData?
Do client's ever interact with eachother's modData (?)
uuh heres the code for the ondeath
function StipendClient.OnPlayerDeath(player)
local username = player:getUsername()
local modData = player:getModData().stipend
if modData then
local args = {username = username, modData = modData}
sendClientCommand("StipendSystem", "SaveModDataOnDeath", args)
end
end
Events.OnPlayerDeath.Add(StipendClient.OnPlayerDeath)```
then savemoddataondeath is this function
```function StipendServer.SaveModDataOnDeath(module, command, player, args)
local username = args.username
local modData = args.modData
local globalModData = ModData.getOrCreate("PlayerStipendData")
globalModData[username] = modData
ModData.transmit("PlayerStipendData")
end```
but when i apply the new moddata to the player i dont use a command
ModData.transmit( ?
i do that after i save the global moddata yea ModData.transmit("PlayerStipendData")
This sends the entire table over network
this is how i reapply the moddata to the player
function StipendClient.OnCreatePlayer(playerNum, player)
local username = player:getUsername()
local globalModData = ModData.getOrCreate("PlayerStipendData")
local savedData = globalModData[username]
if savedData then
-- Initialize stipend if it doesn't exist
local modData = player:getModData()
if not modData.stipend then
modData.stipend = {}
end
modData.stipend = savedData
-- Send command to server to clear the global mod data
local args = {username = username}
sendClientCommand("StipendSystem", "ClearModDataOnServer", args)
end
end
Events.OnCreatePlayer.Add(StipendClient.OnCreatePlayer)```
I would recommend not using globalModData on the client's side
it sounds like you don't need it anyway
I'd also not use transmit that way on the server
You could have ClearModDataOnServer be restoring it while clearing
You'd need to send a command back to update the player
i thought thats how i would sync it
I'm also curious if other player's can see other player's modData to begin with
It can, but transmit sends the entire table - if you have alot of players this table can be very large.
well whatever im doing i can for my stipend stuff. but this is also the first time ive every played with global moddata/player moddata in this way so
You're better off using commands with key/values
I've used it extensively for shops, and zone API, and it's by far the most annoying feature to interact with.
oh well after the player respawns it deletes teh global moddata entry. i guess if alot of people rage quit and never come back the table could get large
i duno if there is a better way to do it, but i just wanted a way to transfer over the stipend countdown after the player dies
You can just do what you're doing, but remove the client side references to globalModData
so i would have to send a command to the server, then send one back to apply the player moddata?
Yes, you can use getPlayerFromUsername for the server to find the right player
ive only learned about all this stuff the past 3 days and its been alot of trial and error XD
What I kept running into was the client/server vs server stuff - as players run server code too
and the GMD would keep fighting itself
i wonder wth im doing to be able to see player mod data though. cuz i did notice there was like my stipend stuff and like 2 other tables. and my player moddata had WAY more than that
oh shit, probably because the file that handles all that is done on the server, but thats cuz i couldnt get it to work right on the client.... ok im gonna take a good long look at all the code and change it around
You can inspect players using the community debug tools
yeah thats what im using
If you don't need players to be able to see eachother's stipends then I would just send the data back and forth as needed
You can view other player's modData? ๐ค
when you transmit the mod data, the server doesnt actually do anything with it unless you tell it specifically what to do
yaeh OnReceiveglobalmodata or wtv
including Init, Request, etc
so you need to write it to a local file, or write it to the global mod data
so if you're not doing that, then nothing will persist
no, when i use it i see my stipend table and like 1 or 2 other tables. usualy theres douzens. but its most likely becasue im putting that file in the server folder. cuz it wasnt working in the client folder
It depends how player modData works
viewing the global modata with the tools views your own
as client's have a version of globalModData
i think i figured it out. And how come it's linked to not having the merge function run immediately.
There can be more than 2-way merge scenarios. In which case every other pile that was in the same merge did not get the update that one of the piles was deleted, and tried to merge with it.
when server receives gmd, you need to do something with the info received, so you need to setup a function and add with the received event to process the information however you need to
and global mod data that you see as a player is entirely local, and may not necessarily even be synced with anything that is going on the server side
ah, so basically. my mod was probably working as is 3 days ago before i started changing everything to be server side global moddata because i couldnt confirm it was working while checking the players moddata/global moddata cuz it was client saved
if you delete your MP save, you'll see that your gMD gets wiped completely
well shite XD
or you can just delete the .bin file it does the same
so if you're using local file to store moneys and rewards, then you're going to run into issues with people who delete the file etc.
cuz i had it perfectly working like 4 days ago. but then when i tested with a player, viewing their moddata and seeing if it saved to the global moddata thinking it was only working for me. but all their stuff woul dhave been saved client side too so i wouldnt ahve been able to see it
nope just at timer. when the tiemr hits 0 it spawns items in their inventory
so like if its set to 24 hours (in game hours) using the everyhours event it -1 to the timer
you can do hacky stuff by using getGameTime():getModData() (i think?) from the server, then use servercommand to spit that info back to recipient players
if you dont wanna mess with the global mod data transaction
the global moddata is only used cuz when the player dies their moddata gets wiped. so if their timer was like 1 hour away from their daily stipend and they die the timer restarts and they miss out
so im savign that data globally to restore after they spawn, then erase the glboal moddata entry
suggest you look at UKO mod and see how evelyn did it
she does pretty much what you describe
she's a smart bovine
I never did. There's no "direct" way to do it. I think there are plenty of workarounds though. I honestly don't remember what I needed this for but I ended up throwing the idea away
You can fetch the field for SurvivorDesc using some hacky means
This can be streamlined/optimized more but:
https://github.com/Project-Zomboid-Community-Modding/pz-community-modding/issues/55
You can get, but no set
Unless in debug*
that's really interesting
@fleet bridge Could probably be helpful to you ^
By the way, is there a way to intialize and use Timed Actions' progress bar when not actually in a timed action?
couldn't you just access fields as in normal lua? I could've sworn it worked.
you can't
The only place something like that appears to work is if the game exposes and assigns the class to a table.
The main issue here is bodies don't have an exposed getter for the Description which is copied from the person dying.
I need some info:
local moodleList = player:getMoodles()
local moodles = {}
for i = 0, moodleList:size() - 1 do
local moodle = moodleList:get(i)
local moodleData = {
name = moodle:getName(),
severity = moodle:getSeverity(),
duration = moodle:getDuration(),
endTime = moodle:getEndTime()
}
table.insert(moodles, moodleData)
end
playerData.moodles = moodles
i am still trying to get him to work (prolly its the wrong use of this function) but i dont what to do rn haha. Keep stucking on the 4th line (obv is part of a bigger code)
Sorry i am super new.
Hi, i'm trying to create a function that will be called after crafting an item. So.. I have created function in my server lua file and added that function into script file with onCreate. Now, I get an error after loading world that just names my function. And if I try to craft an item I get an error that there's no such function. I couldn't find anything that could help me on internet ๐ซ
function doesnt go in script file, it needs its own Lua file
Yeah, function is in server lua file
I just don't know why it says that there's no such function. How then I can call a function after crafting custom item?
how to import/export .x files in blender?
you need the direct x import/export plugin
where can i find a working one?
it is in the addon tab of blender, it works fine for me
edit/preferences/addons : Import-Export: DirectX Importer
which version of the add-on do you have?
sry, had to search. This one: https://github.com/poikilos/io_import_x
thanks
Ok, I fixed it, nvm. Now I'll try to fix another problem
Hi guys, the collision of an item is defenied in the tiledefinintion ?... and which option is active for my item to have collision ?
ask on #mod_support
Hi, iยดm having troubles with the function getCell:setDrag. When my mod call it, it throws an Error: attempted index: setDrag of non-table: getCell, but i verify that the parameters i send is in fact a table and the playerยดs num, idk whatยดs happening, can someone see what am I doing wrong?
getCell()
Hiii, I'm trying to do few recipes using some herbs, but when the herb has (Wild) attribute my recipe don't recognize it.
Same happens when the mushroom is not fresh. Can anyone help me to workaround this? Thanks ๐
๐๐ I'm stupid, thank you dude
Does anyone have any idea what animations do and don't work with mannequins, or if there's any way to tell? I got deadbody_default.xml to work, but most other things default to the idle animation. Surrender just contorts the body
Okay even weirder, setting the animation to Loot.xml causes the mannequin to go into the surrender animation?
not exactly what youre asking but lool at this for reference
#1070852229654917180 message
Sorry, should've been a bit more specific. I'm trying to get mannequins to use player animations, to mixed success
I've looked at that guide but it isn't quite what I needed, I'm able to get the mannequin scripts to load in, but the animations are just borked 90% of the time
ive only done poses..i havent tried animating them cuz i just thought it wont work, goodluck tho...
They don't animate, I've been using animation files in hopes that it would do something like take the first frame and use that as the pose, but everything just defaults to the idle animation, dead on back animation, or just seems to pick something at random like in the case of the Loot animation
I'll just keep experimenting until I either figure it out or determine that is not viable to make a mod like this
does OnCreatePlayer fire off late the first time the character is created? im using it to spawn an item into the players inventory but it only works after the first time they die and not when they first spawn in fresh
Use onplayermove
doesnt that event get called everytime a player moves though?
OnCreatePlayer has a delay of a frame or two in MP
Yes. The function that executed can also remove the event
It's an annoying issue that renders the event useless (imo)
You can also use OnPlayerUpdate
You'd just need to confirm the player is "correct" so to speak
I like onplayermove in case of severe login delay lol
You could make it count down 5 ticks, which would be barely noticable
True, but it depends what they're trying to do as well.
True I think slappy is trying to deposit a login reward
welcome package yea
function checks if the player already recieved one by checking a .txt file. if theres no match it spawns the welcome package
ill figure it all out tomorrow kind of tired right now
well it works consistantly after a player dies. but for the very first time they create a character/load in its not working
That's cause of the connection being made
For a frame or two the person's IsoPlayer is not loaded in
yeah i figured it was something like that
took another look at your guide and realized I had completely overlooked the xml file portion of it. I made new XML files that uses player animations and it works perfectly, thanks!

does anyone know if its possible to have a int such as 0.1 as a default value in sandbox-options.txt Every time I set it the option doesn't show up in game
option Apprenticeship.studentBoredomReduction
{
type = integer,
min = 0,
max = 10,
default = 0.1,
page = Apprenticeship,
translation = Apprenticeship_studentBoredomReduction,
}
edit: I've also tried float but also didn't work
You cannot, and I believe there is no float, only double which is just a 8 bytes instead of float which is 4 bytes
You can have a default value of 0.1 if it's a double
You can use double like
option MyMod.MyOption
{
type = double,
min = 0.0,
max = 10.0,
default = 0.1,
}
and since lua takes number as any number including int and float and double, you can just truncate it when you read it in lua
like ```lua
local opt = math.floor(SandboxOptions["Apprenticeship"].studentBoredomReduction)
but keep in mind floor only removes all the bits to the right of the decimal, not round
At that point it might as well just be an integer; I imagine they just meant โnumberโ (i.e., I don't think they actually want an integer, because it's logically incompatible with the desired default)
well I guess in options you could just make it integer and then divide in lua like min = 0 max = 100 default = 1 and then divide the result by 10 like
--- @type float
local opt = SandboxOptions["Apprenticeship"].studentBoredomReduction / 10
I think the suggestion of using the double option type was plenty lol
Very helpful, thank you
all the ones you can use are
boolean, integer, double, string, enum
I'm sure there's a better version of this somewhere, but quick reference: #mod_development message
Does anyone know how the Home_VHS get limited to one spawn each?
RecordedMedia.java LN234
not this particularly I don't think
sadly homeVhsSpawned is not exposed to lua but some funcs are
idk maybe it's possible to cook something up
Atm the most I can think of is to clone everything and rename it as retail, but that is a shitty way to do it IMO
I wonder if I can force the variable be cleaned
well I think you might be able to add your own as like an override in lua?
I can't cook anything rn since im writing notes for my uni but give me like 30 minutes and I can start testing somethigns
but you may want to look at this javadoc
https://www.projectzomboid.com/modding/zombie/radio/media/RecordedMedia.html
declaration: package: zombie.radio.media, class: RecordedMedia
So what I'd do is try and replicate what the java is doing in lua, so getting teh categorizedMap (which is probably getRandomFromCategory or getAllmediaForType or something along those lines that returns an Arraylist
idk some black magic
I dont think this part the lua deals with that
I think this is mostly to mark if you 've saw it yet or not
I know that on ProjectZomboid\media\lua\client\Context\Inventory\InvContextMedia.lua it has the admin command to force a VHS to be a specific media
Line 723 of ItemPickerJava has this
I am sure that's to handle some sort of distribution stuff
If I am reading this right
It just get another VHS in case a Home-VHS spawns and there is no avaliable Home-VHS
So it gets converted to Retail-VHS
Because here it doesnt deal with the situation where it spawned a Home-VHS and all of them already spawned
So it deals on it later
I think
yea
oh you mean like a check to see if there is already an existing home vhs?
It does check if it already exists. But it only writes mediaData on it in case it doesnt
So you get a Home-VHS with null mediaData
Then the other check updates the null Home-VHS to a Retail-VHS instead
I think this will require a patch like Jab did with luacmd
To literally alter the zomboid server code
Update on the mannequin stuff, got all the poses I wanted sorted and added the ability to give mannequins any hair, beard, and hair color
if someone is interested i finish my first version of the botlog + mod implementation for admins controls (not all infos are send to the bot but you can check those via files) (also gives igt, online count and position)
Very cool Agam!
Anyone have any idea where the file is that handles the crafting recipe of this item: https://pzwiki.net/wiki/Big_Double_Pole_Gate
ProjectZomboid\media\lua\client\Blacksmith\ISUI\ISBlacksmithMenu.lua, line 246
Thank you โค๏ธ
If any skilled modder reads this here
Please create a Propane-Tank backpack connected to the blowtorch for auto refill
Hey everyone, calling for some support again. Currently having an issue where an IsoObject duplicates whenever I try using transmitCompleteItemToServer. Figured it may have been an issue transmitting from the client, so I tried sending the object to the server, calling transmitCompleteItemToClients, then deleting the object client side using sledgeDestroy and transmitRemoveItemFromSquare. Moddata does not save the properties of the IsoObject.
Anyone know why this duplication happens or how to prevent it?
what are you trying to do? this is the expected behaviour of these methods
Transmitting changes of the HumanVisuals of mannequins to the server. I've managed to allow server admins to add hair and beards to mannequins. When I transmit the object, it duplicates and I haven't figured out a way to get rid of the duplicate.
usually you need to synchronise object changes manually with client/server commands
the transmitCompleteItem methods are for telling the server/client about a new object, they don't check for an existing object to update
Got it, will give it a try. Thanks for the help.
You could probably make it yourself, just look at similar mods and youโll find it easier than you think
dont want to cause everytime i start creating mods i fall into a rabbithole and at the end of it i lose complete interest in the game - happend so many times, Kingdome Come, Witcher3, Divinity 2...and so on
why do you think you lose interest?
Lol thatโs a good idea bro. Hopefully one of the pros take it on 
Well its basically because i loose touch with the game from a player perspective
And then i end up changing tables, adjusting numbers and scripting stuff
And then after some weeks i feel like bored out because i lost connection to playing the game
Hey, noob question here, i never modded but wanted to mod the existing cities in the game map to make them more interesting, is that possible?
Kingdome Come my worst experience in this regard - completely fell in love with the game
Started a big Archery+Armor overhaul and the idea was great and would have probably seen thousand downloads
But everytime i got lost in the busy work and never even finished the game coming back 3 times to it...
Theres plenty map mods - so yea its actually a common modding activity in Zomboid
Yeah, there are a lot, but i noticed none of them modify the vanilla cities, only adds more maps, so im starting to think it`s no possible
I cant be the first one to have the idea haha
(exception to 10 years later i guess)
what do you mean? there's plenty that do this
do you have an example?
west point expansion used to be one of the most popular maps
So, that`s not the case, in that case it >expands< the city, but dont mess around with the vanilla one
i mean mods that reworks the vanilla cities, change the buildings, settings, like making the west point police station a 3 floor building for example
there's a lot of mods that redo the existing cities, i'm not sure i know of one that only makes smaller changes
there's a dump of the vanilla map on github somewhere you can edit
i swear the only one i saw doing that was 10 years later
i may be wrong tho
ekron goes for this but it's essentially a new city in place of the old one (especially apparent now that people have realised that that city was never even meant to be ekron ๐ )
there's a few mods that add single new buildings to existing towns and a few that add whole sectors to them
I think i have seen plenty small reworks - like police or firestations
but im not into map stuff rn
thats cool, i`ll see if i can find it
probally will just mess around and try to learn something
kk
hey guys I really want to know how scripts inside scripts folder work
is there a source code which handles those or it's purely handled by java?
they are handled by java
I'm really new to modding so I'm just trying to figure out how to work with it
there is a fuction that shows how many cells a player discovered?
first time modding project z
should i uninstall all mods in the game b4 getting started?
Why ?
Why would you need to uninstall all mods lmao
ive never modded b4, im considering the idea of mod conflicts or something along those lines.
But i suppose its not a concern considering the response
Well if you don't activate the mod in your mod list, it's not active and can't conflict with other mods
Unless you share mod IDs (in mod.info)
Then mods will merge and that can do some shit
its a good practice to isolate the mod your working on but you dont need to unistall other mods.
if you have mods activated then deactivate it .
this isnt necessary but it be easier to manage the mod and whats going on with the game if there are less stuff that are happening
how does one get started in modding?
like do i need to know coding for lua or anything?
- Decide a mod must exist.
- Determine how to make it exist.
- ???
- Profit
In a sense, you don't need to know anything really, but you need to be ready to learn what you don't know. A baby could mod this game. It would just take many years for them to figure everything out.
That said, a lot of fundamental skills including but not limited to programming in Lua will surely help accelerate the process.
@sonic oyster Maybe that variable doesn't persist between sessions. Unsure. Player mod data might be more reliable.
I would just increment a mod data variable EveryHours or whatever that event is called
(If no built-in variable works)
Apologies for posting in the wrong chat! I do believe it persists, it's stored with other player data like hunger and thirst, and previously it would steadily increase until reaching a max of 10. I can do that, and I am keeping a variable for other stuff, but if this variable is completely broken, I can't track when people smoke to reset the timer. There is no "player smoked" event trigger, to my knowledge
You could check that variable EveryOneMinute pretty easily of it's reliable. Idk what you mean when you say variable is broken
This is the variable I am referring to. The setters work to change it. The expected behavior is that it slowly increments over time to a max float of 10. Once you smoke, it goes back to 0 and increments again. It is no longer incrementing, nor resetting after a cigarette is smoked
You could hook the function that fires when you finish a cigarette
Do you know what that would be? I wasn't able to find anything like that in docs