in one of their more recent blog/update posts they mentioned that they changed how progress bars worked so "infinite" timed actions like getting into a vehicle were more obvious. They said they did that explicitely because people were confused by how they were bit through the door by a zombie, since they'd unknowingly canceled the action by opening the map or whatever
#mod_development
1 messages Β· Page 40 of 1
since vanilla cars don't actually show the door open, people were unaware that it was
there is even a timed action called ISEnterVehicle
Most of the related actions don't seem to have a time associated. IsEnterVehicle ISSwitchVehicleSeat, ISOpenVehicleDoor
ISOpenVehicleDoor being the action that actually calls setDoorOpen
ISOpenVehicleDoor:start() sets its time to 5... I assume that's either 5ms or 5 frames? You could try overwriting that function
Do you mean something like this?
---fileA.lua
local example = function()
--TODO
end
return example
---fileB.lua
local example = require('fileA')
example();
Exactly, is it possible?
Those might be seconds. A lot of those actions has such a duration to allow the player to walk to the target
yep, in fact, I do it to create my modules and not interfere with other mods with global variables
and of course, everything is more organized
I think thats what ISPathFindAction:pathToVehicleSeat is doing
So, theoretically I could require the local from another mod too? π€
only if the mod's file returns the function you want
only if they have the local function returned, like in Dislaik's example
ah dammit, they are not returned π¦
Yep I do that with my first mod https://steamcommunity.com/sharedfiles/filedetails/?id=2665369300
---Another mod lua file
local ZombieCamouflage = require "ZombieCamouflage/Functions"
if ZombieCamouflage then
ZombieCamouflage.addKnife("Base.Axe")
end
whatever ISOpenVehicleDoor:start() does, it doesn't do what I want it to
you're going to want to have a close look at ISVehicleMenu.onEnterAux ,onEnter, onEnter2 etc
It's pretty cool but 2313633950\mods\ShowSkillXpGain\media\lua\client\ShowSkillXpGain.lua this mod does no return the local fuction I want to override, which is this one
local function ShowXP(player, skill, level)
if skill ~= nil then
local perkName = skill:getName()
if not player:isNPC() then
if isValid(perkName) then
local showAmountString = ""
if ShowSkillXpGain.showValue then
showAmountString = string.format(" +%.2f", tostring(level))
end
HaloTextHelper.addTextWithArrow(player, perkName .. showAmountString, true, HaloTextHelper.getColorGreen())
end
end
end
end
Mm.. similar to opening windows, it sounds like. Those function by calling a function to walk to the window (asynchronously) while the action to open them is queued
What exactly do you want to override/modify?
ya, the code is literally this after queuing the pathfinding
if not door:isOpen() then
ISTimedActionQueue.add(ISOpenVehicleDoor:new(playerObj, vehicle, doorPart))
end
ISTimedActionQueue.add(ISEnterVehicle:new(playerObj, vehicle, seat))
ISTimedActionQueue.add(ISCloseVehicleDoor:new(playerObj, vehicle, seat))
mb I read wrong, as far as I know, you can't get the local var of a function
I'm trying to apply my debounce code to the showXP function, but I don't want to reupload the original mod just to have the debouncer working
The original mod has that function ShowXP added to the Events.AddXP and I was hoping for a way to avoid reuploading the mod or remaking it from scratch
I tried to get in touch with the mod author but I got no reply
So the way that mod's file is structured is it creates a local function and adds it to Events.AddXP just below creating the function, it sounds like?
Yep
Screen shot for reference
yea
looks like you'll have to use the Event.Add decorator Tyrir made, lol
Event add decorator? π€ π€ π€ π€ π€ π€
stop it from ever being added in the first place... assuming the stars align
this badboy
#mod_development message
Oh wow, that's interesting π€
essentially, you sneak in there and force other mods to use your event handler register instead of the vanilla one.... its heavy handed and if there are several mods doing this at the same time I'm sure it would cause problems, but its kinda the only way I know of to intercept the registration of a local function to an event
I use it to intercept the commands in VehicleCommands.lua, since they are also local and not returned
can anyone reverse engineer a mod for me a little? i have a playershop mod browser8 created for me. he since has become super busy and gave me permission to edit it a little. basically a player can buy a stored item in the shop.. now i want a sell tab where players can go in and sell items to the shop the shop owner sets a buy price for it.
does anyone know what controls the behavior of the vehicle entry zone square that appears when you're next to the door?
What's a way to give a player a trait when they spawn in?
There is an event Events.OnNewGame.Add inside that event you can do player:getTraits():add(TRAITHERE);
Solid, cheers :)
Hrm, looks like I didn't finish that. I must have written it for OnClientCommand, but didn't finish generalizing it to work with any event π
I think its just that print statement that's not general, but I haven't looked at it in a bit so not sure
Has anyone got information or an example mod on adding additional vanilla style text radio stations into the game? I don't want to add any audio, I just want to add a frequency that will display text if the station is broadcasting - like the vanilla radio stations or vanilla the emergency broadcast station.
That middle bit should be something like ```lua
local newEventHandler = function(...)
if isDebugEnabled() then
print(string.format("DEBUG: Decorated handler for Events.%s called", eventName))
end
return eventHandlerDecorator(eventHandler, ...)
end
Didn't test it though :p
@gilded hawk
Does this look well-formed as far as everyone knows? I'm not 100% sure it's necessary for blocking all notifications, but I think it may block obscure ones, so I would like to keep it, just in case. No errors, so if any of these is wrong, at least the patch function fails safely. π€ͺ
local function hidePerkLevelNotifications()
patchJavaMethodB(zombie.characters["IsoGameCharacter$XP"].class, "AddXP",
function(metatableMethod)
return function(...)
-- Before
if dawnOfTheZed["Hide Perk Level-Up Notifications"] then
zeroHoursSurvived()
end
-- Proceed
metatableMethod(...)
-- After
if dawnOfTheZed["Hide Perk Level-Up Notifications"] then
restoreHoursSurvived()
end
end
end
)
patchJavaMethodB(zombie.characters["IsoGameCharacter$XP"].class, "AddXPNoMultiplier",
function(metatableMethod)
return function(...)
-- Before
if dawnOfTheZed["Hide Perk Level-Up Notifications"] then
zeroHoursSurvived()
end
-- Proceed
metatableMethod(...)
-- After
if dawnOfTheZed["Hide Perk Level-Up Notifications"] then
restoreHoursSurvived()
end
end
end
)
patchJavaMethodB(zombie.characters.HaloTextHelper.class, "addTextWithArrow",
function(metatableMethod)
return function(...)
-- Condition
if not dawnOfTheZed["Hide Perk Level-Up Notifications"] then
-- Proceed
metatableMethod(...)
end
-- Otherwise, don't call that method.
end
end
)
patchJavaMethodB(zombie.characters.IsoGameCharacter.class, "LevelPerk",
function(metatableMethod)
return function(...)
-- Before
if dawnOfTheZed["Hide Perk Level-Up Notifications"] then
zeroHoursSurvived()
end
-- Proceed
metatableMethod(...)
-- After
if dawnOfTheZed["Hide Perk Level-Up Notifications"] then
restoreHoursSurvived()
end
end
end
)
end
Is there a mod that reveals my map
Yeah but I meant in an ongoing run so I can enable some sort of mod so I can see it
I don't know about that... sorry.
π
Hey I accidentally enabled the ability to see all sorts of debug info about characters and zombies while I walk around... must have accidentally pressed something... anyone know what I'm talkin about and how to close it?
Never mind it's F6 apparently.
Anyone know how I might store a java list as a lua table? Can't seem to get it right and my googling has failed me
local t = {};
for i = 0, ArrayList:size() - 1 do
table.insert(t, ArrayList:get(i));
end
I try to do a relative simple task.
The outfit chance is controlled by the sandbox settings, which does work so far.
But in case someone doesnt wants to spawn the headhunter outfit for example i also want to set the spawn chance of the secret variations as well to 0% (I have there 100% right now for debug reasons)
`local function DoIt() --It does the thing
local StalkerSpawnrate = SandboxVars.UndeadSurvivor.StalkerChance;
local NomadSpawnrate = SandboxVars.UndeadSurvivor.NomadChance;
local PrepperSpawnrate = SandboxVars.UndeadSurvivor.PrepperChance;
local HeadhunterSpawnrate = SandboxVars.UndeadSurvivor.HeadhunterChance;
local OminousNomadSpawnrate = 0.01;
local DeadlyHeadhunterSpawnrate = 0.01;
if NomadSpawnrate == 0.00 then
OminousNomadSpawnrate = 100;
end
else
OminousNomadSpawnrate = 0.01;
end
if HeadhunterSpawnrate == 0.00 then
DeadlyHeadhunterSpawnrate = 100;
end
else
DeadlyHeadhunterSpawnrate = 0.01;
end
table.insert(ZombiesZoneDefinition.Default,{name = "Stalker", chance = StalkerSpawnrate});
table.insert(ZombiesZoneDefinition.Default,{name = "Nomad", chance = NomadSpawnrate});
table.insert(ZombiesZoneDefinition.Default,{name = "OminousNomad", chance = OminousNomadSpawnrate});
table.insert(ZombiesZoneDefinition.Default,{name = "Prepper", chance = PrepperSpawnrate});
table.insert(ZombiesZoneDefinition.Default,{name = "Headhunter", chance = HeadhunterSpawnrate});
table.insert(ZombiesZoneDefinition.Default,{name = "DeadlyHeadhunter", chance = DeadlyHeadhunterSpawnrate});`
But for some reason the "if" commands wont affect the chance
While i could do add a sandbox settings for those i dont want to do that because they are top secret
How to count seats in vehicle? Is there an API function like seatsCount() ?
By now I can imagine only this:
local function seatsCount(vehicle)
local cnt = 0
while vehicle:isSeatInstalled(cnt) do
cnt = cnt + 1
end
return cnt
end```
Nevermind, that seems to work.
Instead of changing the variables just putting directly a if command for the table insert
What is faster?
if x then
-- OR --
if x ~= nil then
Let's say it can't be "false".
Not sure, but I think you can use os lib to check that
if x seems a bit faster in some cases (depending on what x is). But both are minuscule compared to other things.
l.measureTime("test", function() local x= ""; for i=1,100000 do if x then end end end)
9ms
l.measureTime("test", function() local x= ""; for i=1,100000 do if x~=nil then end end end)
15ms
l.measureTime("test", function() local x= nil; for i=1,100000 do if x then end end end)
12ms
l.measureTime("test", function() local x= nil; for i=1,100000 do if x~=nil then end end end)
12ms
And for comparison:
l.measureTime("test", function() print("hi") end)
6ms
A single print takes 6ms, while 100,000 if comparisons take around 10ms
Globals are slow in general, so x is local variable (not global). Usually it's a number in my case.
l.measureTime("test", function() local x= 5; for i=1,100000 do if x~=nil then end end end)
15ms
l.measureTime("test", function() local x= 5; for i=1,100000 do if x then end end end)
9ms
If I change the above to a global, the numbers become 22ms, and 16ms
which, amortized over 100000 iterations, works out to 70 nanoseconds per var access higher for a global than local
I imagine calling into java to get java objects overshadows most of this
Hmm, let me check
l.measureTime("test", function() local x; for i=1,100000 do x = getPlayer() end end)
112ms
Hmm, slower, but was expecting 100x slower or more. That's actually not so bad, 10x slower
any modders trying to help build a server. i've got tons of work and some cash. let me know, mainly looking for ui and coding modders. looking to build the team we have more.
also is there a server mod that allows the map everyone views to be edited by admin? so when new players join they can see like areas, or buildings they can go to or shops
Using 10 years later and im trying to use the low veg of it, but for some reason its not working, anyone know why?
It works. It's just that the resolution of its options is low. steam://openurl/https://steamcommunity.com/sharedfiles/filedetails/?id=2862873873 has more detailed options
You can look at that to see how its options function and compare the code to 10 years later
Has anyone worked out a way to redirect console.txt output into something usable in lua?
Anyone know the process for editing animations if there is one?
I'm trying to turn the shove into a fast kick to go better with the martial artist trait
i have problem with "Mod options"
well u could catch a lot of it by hooking print
but probably would miss the java-end stuff
I found a way. Thanks
Just opened an input stream to output.txt using apis in GlobalObject. I'll probably just poll read every so often
There's a few more io functions there than I realized. There's even a url reader there I hadn't seen before. Can't wait for the embedded web browser mod heh
Some of the io streams and debug console IU and DebugLog java objects are exposed to lua. There might also be a way by doing something a little more clever (and performant) than simply reading the file directly, but for now, this will do
Hey everyone, is there an easy way to add another flag to the game such as the USA flag but with different textures?
I already did some stuff regarding the spawntables and the texture etc
though I used an outdated tutorial and thus could need someone to give me a small guide string, thanks in advance for any responses!
stream youtube to the in-game TV
:p
Anyone know any good truck mods? Like those big american trucks?
I think some of the tsar vehicle mods include trucks. Try searching the pz steam workshop for "tsar". Might ask in #mod_support too. That channel will be more suitable for general mod questions like that
ATA Petyarbilt, KI5 Ohskosh M911, W900, and P.A.R.C. includes some Russian semis.
that's literally all of them afaik
lol
for bonus trailers you can install Water Trailers
where are the trash cans in the game located? Trying to add some to maps and i can't find them in any item folder or as an admin in-game from the "item list viewer" under the words bin/trash/dumpster.
Moveables
I see a mod on the workshop that says you must put it in a certain order in the mod load order. I thought the mod load order didn't do anything?
It breaks ties where two mods have lua files with the same path
so he's overriding entire files
Possibly, yea
It might affect other things too, idk. I do know for lua files it only comes into play where multiple mods have the same lua file path
May also be misunderstanding. I've seen plenty instances of people suggesting changing mod load order when it isn't relevant
With PZ, in some case instances, such as mods overwriting/patching other mods, or otherwise being dependant on other mods, load order might matter, but in general as a gross generalization, load order doesn't matter.
But I gather that load order is important for many other games that have mods? Maybe especially when people are running 200-mod behemoths with the games.
@woeful relic Are you sure?
@undone elbow looks like he posted more info about it in #mod_support , #mod_support message
is there any mod that lets you deck out cars?
hey guys i'm trying to upload my mod but i'm getting a failure to upload. is there a language filter in workshop? my mod is called "The Bastard Sword" and i'm wondering if that's the issue lol
Might try asking in #mod_support. They generally field those end-user mod questions there
Do you get an error code or message?
code 15
I think that's the associated error code that PZ surfaces from steam
k_EResultAccessDenied 15 Access is denied.
so access might be denied bc of "Bastard" you think?
I don't know. I was hoping the error code would be a little more explanatory to what you know about the situation
Thx man
How could I make an item be powered by a generator?
Can I just give it a tag or does it require additional coding
Hey guys I published my mod. Adds a very rare and durable sword to the game. Keeps true to vanilla for the most part. Check it out if you'd like.
^thanks to everyone for the help
How did you resolve the upload issue?
I fixed some conflicting stuff in the mod.info file and let steam generate the steam id for the mod. I thought I had to make it up myself.
Ah, that error code makes sense now
Looks good, will install this on my server after a test.
:)
hey quick question. if i were to input a directx file into my mod and when i made it in blender i added animations would the animations automatically stay in and play in game
hey awesome thank you! I appreciate your comment and award. let me know if you have any suggestions. enjoy!
About B41 firearms
I am not able to put on attachments, only take off
yes i have everything in my main inventory, please help
#mod_support does mod support
oh whoops
Anyone know if itβs possible to disable cancelling out of a timed action?
Alternatively, as a temporary solution, has anyone had any luck disabling keybinds? Couldnβt find documentation on that and eatKeyPress() doesnβt seem to work either
hit esc
:)
lol
in code tho
self:forceStop()
from within the action anyway
depends on the context
I think he wants to prevent an action from stopping, not stop it himsef
Yeah, right now Iβm looking into temporarily disabling the keybinds for esc and melee, both of which cancel timed actions
You could search for how those keys cancel the timed actions and try to circumvent that
I had a foolish idea for a mod
A mod, that burns the ground all starting towns!
like the burnt down rare house story, everything burned down, a way, to force the player to move around and start building.
The only problem is, I have no idea how to implement this
I think it would be a great mod if combined with 10 years later and and it would made it expansive to build a base, something that I'm feeling it's getting a bit to easy to fortify a place after 600 hours
I like limiting respawns so that you can clear an area and keep it clear as long as you sweep through every week or so. But you end up in a situation where you have no reason to even have doors on your house because no neighbours ever come knocking. Once I'm done my mod I'm going to be spending a bunch of time experimenting with the mods that add hordes that spawn at night or whatever to give base fortification a purpose
maybe when they reimplement sleep events...
Looks like all timed actions are instances of IsBaseTimedAction, and this function here causes the interruption. Wondering if I can add a different version that my time based action can derive off of
function ISBaseTimedAction:stop()
ISTimedActionQueue.getTimedActionQueue(self.character):resetQueue();
end
are you writing your own timed action or trying to change one that already exists?
Writing my own
anyone able to help me find the spawn id for white carpet tiles?
then just implement stop and make it do nothing
:P
if that doesn't work then override ISBaseTimedAction.stop and go "if action is X then return"
I tried that and it still just cancels the action
hmmm, let me give that a shot
I think there is a forcestop or something as well that may need to be overshadowed
ah, yeah I missed that one. let's see if that fixes it
Yo guys, anyone know a good trade mod?
i used to use sharks but wanted to trade all things not just canned goods
big fan! finally a viable katana alternative that isn't busted beyond belief/too weak
Is there any variabel I can use to change item drop speed?
I notice that change item's weight affect the item drop time, Can I keep the weight but still able to change the item drop time?
hey thank you! I spent some time thinking about the balancing so iβm glad to hear I found the sweet spot. enjoy!
Any suggestions on how to deal with another modder that decided to override some function and made impossible to hook to the functions?
I was thinking about changing the name of my files to ensure the load after that mod, but it seems like a shit fix
How would I go about having an item powered by a generator? Like the fridge or the lights you can put outside.
This is a good idea, although it looks like starting a war between modders.
Anyone knows how to refresh a UI? Specifically the total inventory weight part of the inventory ui
Create movables like lamps
Ways I've done it are 1) to make a file to overwrite their file (then patch in their functionality in a better way), 2) have a file that loads before theirs, save the original, force their file to run at an earlier time with require, then patch things up somehow (depends on specifics)
In deciced to take the simplest approach and I just added ~ to my mod file name so that it loads last, it's not a great fix, but it work well enough
I'm hooking to their function (when present) and made a small tweak to ensure it's working
I'm not sure what you means but this may be helpful ```lua
ISInventoryPage.renderDirty = true
Manage to patch that file local function that was added into to an event that you encountered yesterday?
The event add decorator is unrelated to this issue of overriding files
And no I put that project on hold for now
Anyone know of a good reason the text panel/layout (like the one used for the chat window) obliterates all whitespace runs? e.g. text more text -> text more text
Seems more of an accident of how it parses rich tags than intentional e.g. <RBG:1,1,1>
@undone elbow If the vanilla code were written that way, then it'd be clear it was intentional π
It acts like markup language parser.
For example, HTML is parsed the same way (unless you used <pre> or <code> tag).
Mm, true. XML does that
html is a subset of xml (more or less).
Mm
Unfortunately, it doesn't handle xml entities properly. Handles > and <, but not
Yes, it's different, but the most rules are the same.
Odd choice of theirs to parse text that comes as user input in this way. Anyhow, I suppose I can derive a subclass of it and modify it to work differently on whitespace runs
:drawText( ........ ,r,g,b, .... font ) won't parse the string π
giving it a try now
@undone elbow
π¦
require "ISUI/ISInventoryPage"
require "defines"
WetWeight = WetWeight or {}
function WetWeight.Do()
local modif = 0
local pl = getPlayer()
local inv = getPlayer():getInventory()
local it = getPlayer():getInventory():getItems()
local originalWeight = 0
local isize = getPlayer():getInventory():getItems():size()
local wetns = 0
local capacity = inv:getEffectiveCapacity(pl)
if it:isEmpty() then return end
for i = 0, isize - 1 do
originalWeight=it:get(i):getWeight()
if it:get(i):isWet() then
wetn = it:get(i):getWetness()
modif=(originalWeight+( wetns * 0.01));
it:get(i):setActualWeight(modif);
else
it:get(i):setActualWeight(originalWeight);
end
inv:setDrawDirty(true);
ISInventoryPage.dirtyUI()
ISInventoryPage.renderDirty = true
pl:getHumanVisual()
end
end
function isWet(item)
if item:IsClothing() and item:getWetness() ~= nil and item:getWetness() > 0 then
return true end
end
function WetWeight.Check()
if not getPlayer():isUnlimitedCarry() then
Events.OnKeyPressed.Add(WetWeight.Do);
Events.OnContainerUpdate.Add(WetWeight.Do);
Events.OnGameStart.Add(WetWeight.Do);
end
end
Events.OnPlayerUpdate.Add(WetWeight.Check)
https://steamcommunity.com/sharedfiles/filedetails/?id=1920135086
Ill try refer to this one
Which u also made
If it works with this mod enabled i might just require this π
Gee, didn't think I'd ever join this discord, let alone do modding...
Right, so... I wanna do something similar to mods that exist on the workshop, but somewhat differently
Do I just... Start by dissecting the existing mods?
looking at how other people do things can be very helpful, ya, there are also a couple guides that other modders have written
I don't think any of them are super complete, but I like this one in particular
https://github.com/FWolfe/Zomboid-Modding-Guide
Would it not be possible to do it with inventory items that are placed?
I mean I assume I could hardcode it if you can get power source from tile
Thanks... Frankly, what I wanted to do already exists in two or three mods I've seen, but either with issues or actually being too much...
I hate these XP notifications so much for being so hard to hide without causing gameplay issues. sigh There seem to be so many ways for player to gain XP and thus level that I cannot figure out how to catch them all manually. Various notifications keep getting through my patches and tricks.
I'm trying to move the player to a specific location on new game. i'm using onnewgame but it doesn't seem to work
Unless the function I'm doing is incorrect
local function TeleportHideoutOnNewGame(player, square)
player:setX(9145);
player:setY(4951);
player:setZ(0);
end
Events.OnNewGame.Add(TeleportHideoutOnNewGame);
teleport stuff is very iffy in the game. try to copy the debug mode utilities for the teleporting
also i think Onnewgame might be too early as well. you might need to use ongamestart
and have a flag
hmm okay thanks i'll look into everything
You have to a sendcommandtoserver i believe
You could try your function from terminal, to see if it works. I also use setLx, setLy, setLz. No idea why, just copied it from debugger.
i did notice the lx ly stuff
well
the Lx stuff worked
weirdly lol
yeah it did nothing for me without those too
you can make code run later if you add it to an on game start event to ensure it runs after everything else loads
i do that with a few things i've done
Would this work for hooks too?
if u did then u'd want it to run before things
so
i assume it's fine for ur use case if u want it to load last atm
lol
i mean ~ works
but that's another way
If I were to hook calls to getHoursSurvived, would there any way to determine the name of the function that called getHoursSurvived?
so i was able to get the player moved to a spot on newgame hook
but now i'm trying to make it that a recipe can move you
and somehow it doesn't work..
with very similar code
ZomboidExtract.MarchRidge.SpawnPoints = {
{ x = 9913, y = 12953 },
{ x = 10103, y = 12749 }
}
function ZomboidExtract.MarchRidge.Spawn(items, result, player)
local size = #(ZomboidExtract.MarchRidge.SpawnPoints);
local index = ZombRand(1, size + 1);
local point = ZomboidExtract.MarchRidge.SpawnPoints[index];
print("x: "..point.x.." y: "..point.y);
getPlayer():setX(point.x);
getPlayer():setY(point.y);
getPlayer():setZ(0);
getPlayer():setLx(point.x);
getPlayer():setLy(point.y);
getPlayer():setLz(0);
end
I know the recipe calls it because it shows print
with correct data
require "ISUI/ISInventoryPage"
require "defines"
function WetWeight()
local inv = getPlayer():getInventory(); local it = inv:getItems(); local isize = it:size();
for i = 0, isize - 1 do
if it:get(i):IsClothing() and it:get(i):getWetness() ~= nil and it:get(i):getWetness()~= 0 then
it:get(i):setActualWeight(it:get(i):getWetness()/35)
ISInventoryPage.renderDirty = true;
ISInventoryPage.dirtyUI();
inv:setDrawDirty(true);
end
end
end
Events.OnContainerUpdate.Add(WetWeight);
Events.EveryTenMinutes.Add(WetWeight);
IT FINALLY WORKS
i also figured that if i store the variable like
origWeight=
it wont matter when you change it it will get the new one
which was kinda hard to deal with cuz what happens is it exponentially adds the weight
so i had to think of some solution to prevent that aswell as getting the refresh.. and finally the simplest solution is just take the wetness and forget abt the original weight totally and it works
i think my script vefore actually did work.
its just that equipped weight is the one thats being measured on the capacity and so the added weight didnt even really mattered probably cuz of weight reduction
anyways thnx to those who helped me and thank you @undone elbow for the
ISInventoryPage.renderDirty = true;
Might try OnLoad. That seems to be the last event prior to OnTick beginning (at least in single player)
I was already able to resolve that. I'm now trying to do the same thing on recipe's create
what happens if in the console you call ZomboidExtract.MarchRidge.Spawn directly?
(as an aside, you may want to use player instead of getPlayer() if you want it to work in split screen)
oh sorry i was just experimenting with everything
getspecific, player, getplayer
trying to get it to work
Yea, I gotcha. Just making that remark just in case it was helpful
yeah i appreciate it
i didnt know about the difference tbh
but will be keeping that in mind
Does anything happen at all besides the print? Does the game world go black for a moment as if the player is being teleported (but fails)?
hmm it just worked now
I did the ZomboidExtract.MarchRidge.Spawn(nil, nil, getPlayer())
and it worked
but if i try to craft
it doesnt work.
it does print the xyz but nothing beyond
π€
i wonder if crafting something sets player's position as well
and oncreate precedes it
Maybe it's something like that, yea. Could be some flag set that indicates the player position should be changed on next update tick, but the crafting process does something to unset it. I'd have to dig into IsoPlayer or IsoGameCharacter to figure out how those two things interact
You might try Adding an event handler to OnPlayerUpdate or OnTick that does the setX/Y/Z and also Removes itself 
If you use this with runOnce set, it will do that
so..
it does appear that whenever player crafts something, for some ungodly reasons it does set position to wherever they first crafted
I just did a delayed teleport with a timer
@visual abyss
Here are references i hope this helps
||https://steamcommunity.com/sharedfiles/filedetails/?id=2850098970||
||https://steamcommunity.com/sharedfiles/filedetails/?id=2849247394||
||https://steamcommunity.com/sharedfiles/filedetails/?id=2815106582||
I'm helping someone with a modded item and all I have left to do is get the option to equip it to appear in the context menu. Can someone point me in the right direction?
Double-clicking it equips it just fine
yeah we used this on our server.. you cant use it if you place it on the top floor cuz the sprite reaches the top
also it doesnt provide a 1 way direction
or somesort of an option that you can only use this if you have this or seomthing like that.. which is probably a good mod if someone wants to do that and just contact the author for permissions and what not
that's just all recipes
u want learned recipes
im about to do that as well for my recipe yeeter
Is there any way to, uhh... Look at the game's Item definitions?
from in game as admin go to admin on the left and then "Item Viewer" or "Item List" or whatever it's called
if out of game it's spread across multiple files
items.txt, newitems.txt
and then modded stuff in each mod
an item's full type is module.type
Can anyone give me an idea of how I can learn to add context menu options to an item?
If you've made an event handler yet, its quite easy to do it that way. add a handler to Events.OnFillInventoryObjectContextMenu that checks if the item is yours and adds the context you want to the menu
there is also a Events.OnPreFillInventoryObjectContextMenu if you want your context item or submenu to be at the top
Havent yet but I will figure it out! Thank you very very much!
What are my options for modifying items? There's an item in a different mod, but I don't want to make a full override of it... Is there maybe a way to modify them via Lua? I'm talking the base item definition
hey all sorry to bother, is there a way to change where my mods are downloaded?
i just wanna change the drive
are there mods to make the game look more horror ?
They download to the workshop folder where steam/pz is installed.
So youd have to change that
how do I change that? Im sorry im uber dumb
Oh, you would have to uninstall and reinstall steam to where youre wanting
its weird as everything including games and workshop content installs where I want it to? even project zomboid itself is installed where I want it to be?
Workshop content installs to the steam workshop folder
right click zomboid in steam, and go to properties, then choose the move install folder option
it still says its installed in my d drive (where I want everything) but the mods install to my c drive?
Are you sure about that? mods from the workshop should install themselves into which ever game directory the game is installed in for example mine are installed here "D:\Steam Library\steamapps\workshop\content\108600"
there is a Zomboid folder which installs itself into your home folder but that only contains saves and manually installed mods
mmm, idk then, thanks though!
console.txt output in a chat tab with ANSI colors (sort of)
The monospace font in pz is really bad. Text doesn't line up quite right. Also need to find a better way to get the console.txt stream, because the java FileInputStream is awfully slow
looks neat
YES PLS
can u make one that sends server-side one to someone with admin rights too? 
looks like BaseVehicle:transmitModData and BaseVehicle:transmitPartModData both still only work from the server side, they don't transmit from the client. I'm not surprised but was told it worked differently. Always good to verify for yourself!
hey guys
if this is a very hard question to answer im sorry to bother and you don't have to answer
but
how does someone start modding
i have ideas that i would like to see being made into mods but instead of waiting for someone to do it i would like to do them myself as to not bother anyone
if someone could tell me how to start i would really a appreciate it
have you programmed before?
kind of?
i have coding a bit in school
it started late and it's a weirdo language it's not even in english
but i kind of get like what you do
what language?
haha, ya googling visual g gives me only sites from brazil
anyway, modding project zomboid uses Lua, so you may want to read some tutorials on how it works
hmmmm
i see
isn't lua related to like
text or something?
i remember i did something with luas for a fighting game
and it was on notepad
haha
all programming languages are text, haha'
Lua is an extremely fast, and extremely barebones scripting language. Its used all the time for modding because it interfaces very well with C++. Project Zomboid is Java however, but they use a Lua library called Kahlua to make the lua scripts and java talk together
none of that is all that important though, you just need to learn some lua
ok i see
also before i try to do it
how hard would it be to make a new crafting recipe
with already existing items
things like crafting recipes are pretty easy, that is done with scripts, you don't have to write any code for those
unless you want them to do something out of the ordinary
Ow what the?! U made this console? Awsome! Is it in the workshop?
don't the game files have a doc with all the recipes or something?
i saw that on the zomboid modding tutorial
i heard it's outdated
ya, there are a lot of outdated guides out there, and the rest are incomplete
its a good idea to download mods that do things you like and try to figure out how they do it
is this one one of those incomplete ones
that guide is pretty good
oh ok
ye that's how i did it when i did stuff with luas without even knowing what it was
Theres a startup parameter to change the cachedir.
Program Files\Steam\steamapps\common\ProjectZomboid\media\scripts has the scripts you'll want to look at, especially recipes.txt
oh wow
thanks
for that thing with using current mods to do my idea
are the mods i subscribe to
on the folder for the game
or do i have to use steamcdm
What mods are you planning to do? Perhaps we can help by letting you know which ones are easy and which ones are hard?
if I remember correctly, they should be in Program Files\Steam\steamapps\workshop\content\108600
one would be to make it so you can make stakes out of planks
you'll have to look for the URL in the mods you like to figure out what folder you want though, they all are just numbers
ok ok
Ahh that would be easy you only need script doesnt require u to make a lua file. Unless u want to spawn multiple planks
multiple planks?
Imean stakes sorry
oh ok
actually that would be something i was considering
like
a plank could make like 2 stakes right?
idk ill have to think about it
huh i did that search in my file explorer
I trying to make some zombies scream and used :playSound("soundfile") to play the scream sound. But now I struggle to make itbe hearable from farther away. I have to stay in like 15 tiles or so... Is there a way to extend this range?
i didn't find zomboid
it'll be wherever you have steam installed. check Program Files(x86) or something
There is but i think zombies will hear it..
I don't know if its "the solution" but I'd like to try it...
Just joined the conversation... I your using steam you can rightclick on the game -> Manage -> Browslocal files or something like this...
getSoundManager():PlayWorldSound("ZombieSurprisedPlayer", getPlayer():getSquare(), 0, radius, volume, _iswav);
addSound(getPlayer(), getPlayer():getX(), getPlayer():getY(), getPlayer():getZ(), radius, volume);
oh ok thanks
ok i found the txt file
so should i like
copy one of the recipes
I tryed it this way:
local x, y, z = zombie:getX(), zombie:getY(), zombie:getZ();
addSound(zombie, x, y, z, 250, 250)
Can I hear the direction it's coming from with your code?
like 3d? idont know how that functions yet.. i tested this before and the recieving end player said its still the same but we are not sure cuz he might be using mono audio system or his setup isnt really ideal to notice the direction pan
The goal is to hear the direction like the footsteps. I can hear from which side their coming or the shots far away...
recipe Make Stake
{
Plank,
keep [Recipe.GetItemTypes.SharpKnife]/MeatCleaver,
Result:Stake=2,
Time:80.0,
Category:Survivalist,
OnGiveXP:Recipe.OnGiveXP.WoodWork5,
}
would this work?
so I can find the more dangerous zombies...
for making 2 stakes
theres a mod for this
i did what i saw for opening the box of naisl
it indicates the sound direction
=x amount after the result
Do you know the name?
@astral dune
what do you think?
unfortunately I can't help you much with that, my experience is mostly just messing with the vehicle physics
hmmmm ok ok
@clear bloom
if you want to figure it out by yourself then dont open this till you give up i guess.. hehe
this is exactly what you are trying to do ...i think?
|| recipe Make Stake
{
Plank,
keep [Recipe.GetItemTypes.SharpKnife]/MeatCleaver,
Result:Stake,
Time:80.0,
Category:Survivalist,
OnGiveXP:Recipe.OnGiveXP.WoodWork5,
}||
just try it...
oh ye
ow snap you figured it out already lol
Did you created this in your mod directory or changed the original?
with Result:Stake=20
*=2
oh damn it was the original
im so dumb
aaaaaa
i hope i didn't destroy the game or something
lmao
@clear bloom soul has a point you need to make another script file and make it a mod instead of doing that to the orig file .you wont be able to play MP if you do that
just verify file on steam
hmmmm ok ok
Did you meant this one?
https://steamcommunity.com/sharedfiles/filedetails/?id=2560478285&searchtext=sound
In case of yes I don't looking for visuals I can hear in game where the sounds are coming from. I just can't increase the distance where my sound is hearable.
btw while this is verifying the game files
i gotta say
thank you all
you have all been so helpful
im so slow with these things so i'm glad you helped me
ok it is done
it says 1 file failed and will be reacquired
is that something that will be done automatically or do i need to do something
this is done automatically
you think you can only see it in the downloads that zomboid downloaded something.
oh ok
oh also btw
besides the stakes mod
another one i wanted to make could be harder
it would be like tweaks and maybe adding features to the farming skill
then you probably have an error... π
so can you show me your whole recipes file from the mod?
this is no problem afaik...
but did let all recipes in the file? you only need the ones you change or create new.
i kept all the recipes on that file
the mod file
only has the recipe i made
here
my current file for example looks like this:
{
imports {
Base
}
recipe SoulModCreateBaitMaggots
{
Maggots=5,
Result:SoulMod.BaitMaggots,
Time:150.0,
Category:Trapper,
SkillRequired:Trapping=1,
}
}```
I'm not sure with overwriting recipes...
I'll have to check if I find an example of overwrite a recipe...
in the original you get one stake and as far I understand you now want to get 2 (or more). So I don't know exactly how to achieve that zomboid changes the original to yours... I only added new recipes so far...
but isn't it a new recipe?
it's just another recipe for making stakes
unless the result is the only thing that matters
can you add
Override:true, at the end of your recipe? and give it a module name (for example a short for your mod)
so make it similar to my example...
ill try
like this:
{
imports {
Base
}
recipe Make Stake
{
Plank,
keep [Recipe.GetItemTypes.SharpKnife]/MeatCleaver,
Result:Stake=3,
Time:80.0,
Category:Survivalist,
OnGiveXP:Recipe.OnGiveXP.WoodWork5,
Override:true,
}
}```
hmmmmm i see
but
if i do this won't it replace the original recipe?
with the tree branch
I thought you took the original and only changed the result.
then remove the override from my example.
that the Base stuff is known I think... I never tried without it...
ok ok ok
so it knows for example plank. but you still can test it after it works...
If you get errors on start you will find them in the console.txt or coop-console.txt in the folder:
%userprofile%\Zomboid
ok
did it work?
idk if it's an error but the game
is stuck
on "loading scripts"
at least it seems to be stuck
on the scripts folder
while its stuck.
or did you want me to put in the recipes
from your mod or the original folder?
i put the crafting recipe in it's own txt file and put it in the scripts folder
you need to create a seperat modfolder for your mod...
oh damn
i thought just changing putting the script in there would be fine just for testing haha
sorry
you add this to the moddirectory...
you have a mod directory where you can create your structure...
oh ok
i see
you can use the examplemod and make a copy...
then edit mod.info as you need it and create the scripts folder in media
there goes your new recipes.txt
don't forget the remove the stuff you dont need from the examplemod.
in your case you only need the scripts folder... may be create an empty lua folder for later stuff...
ok ok
I have to go off... hope you can manage it from here. or someone else can give you a hand...
why does my icon (of an item) show up in game as a ? mark?
thank you dude
like
its in /textures folder
really
thank you so fucking much
im so slow
and bad at stuff like this
thank you for sticking with me
im sorry π
how did you name it? normally ? means it was not found...
the name shoud be without an extension...
its just icon: name,
no extension
idk why it doesnt load honestly
or rather icon=name
{
Weight = 2.0,
Type = Normal,
DisplayName = Unfinished Bat,
DisplayCategory = Tool,
WorldStaticModel = Log,
Icon = RawBat,
Tags = SoulMod_UnfinishedWoodItem,
ResultItem = BaseballBat,
RequiredSkill = Carpentry 1,
TotalWorkUnits = 10,
}```
my item above and my png below:
`Item_RawBat.png`
I think Item_ is important...
oh hm that might have been the problem i was using module name instead
nope didnt work 
@undone elbow Hey, sorry to bug you, but I'm curious what unresolved issues exist with Mod Options' Sandbox Options. I imagine they must at least work in some cases or you wouldn't have gone to the trouble of writing up usage instructions? But you warn us that you don't recommend following said instructions... it's a bit confusing. π€ͺ
someone figured out how to make the sandbox options load on demand and that we shud put it on PreDistributionMerge to allow mods using it in PostDistributionMerge to have sandbox access
i cannot find that by search, maybe i had bad terms idk
but if anyone has that or can find that
pls ping and link or copy it to me
(or DM, whatever)
doesn't fit your exact description, but putting ItemPickerJava.Parse() after setting stuff in OnInitGlobalModData was brought up here before
@weak sierra this?
yess thanks
there's existing mods that use sandbox options for loot dist stuff
and i'd love if they'd like.. work right
:P
so im gonna try it
omg! im playing with the lua console
acidentaly discovered this and now i cant go back lol
local pl = getPlayer()
UIManager.setFadeBeforeUI(pl:getPlayerNum(), true)
UIManager.FadeOut(pl:getPlayerNum(), 1)
whats your icon size
Is there a way to edit zombie HP manually in the Lua scripts?
i want to edit them based on speed, slow = high hp & fast is low HP
ALSO! how can i remove traits that are modded into the trait menu, or at least make them cost 100+, as they break the consistency of the 100+ mods & 15 custom mods ive made... they ruin the realism if picked.
i changed the trait & profession cost of the defualt in game traits & professions
but cannot change the modded ones, cant find the proper file
been modding & searching for mods & reading them to edit them for obver 60+ hours now
to create what i consider, the perfect game
yes, i want these changes made before the world is created
so on a new world, for example, Action Hero perk will cost 100+
without the ability to change these, i will have to run on an "honor system" with those that join my game, & trust that they do not pick [Exciled perks modded into the game from workshop]
the zombie speed hp % change based on speed is nice, but not as important as revoking players from breaking my game with perks they should not pick
are you just overwriting the files to change costs? you can do that with mods too if you find the relevant files, but keep in mind you'll need the original author's permission to release anything like that publicly
i want to get all this done before i start the game, i plan on running my server for over a year in real time, i cannot have loopholes & work based on trust, as most people think its funny to troll
i looked into the "more traits mod" that contains the Action Hero + others that i need removed... i looked for over 30m & could not find, i will try again now, maybe i missed it....
So how do I modify items? I want to add an event to the item when it's created, or change two values in it
My item looks something like this:
item CannedCabbage
{
DisplayCategory = Food,
Type = Food,
DisplayName = Jar of Cabbage,
Icon = JarGreen,
Weight = 0.5,
DaysFresh = 60,
DaysTotallyRotten = 90,
IsCookable = TRUE,
MinutesToBurn = 120,
MinutesToCook = 60,
StaticModel = CanClosed,
WorldStaticModel = JarFoodCabbage_Ground,
}
I want to add to it OnCooked = CannedFood_OnCooked,
would help if i could.... im at a loss
not a great modder either, someone else will be better suited to help you
I've heard that I can fully overwrite items... So redefine it with my properties... But there's some different way I heard?
I was told these are my options, but... I don't know how to do either, or how they interact
tweak them with DoParam in shared during startup
override whole files```
getScriptManager():getItem('Module.Item'):DoParam('OnCooked = CannedFood_OnCooked')
i think the same syntax works
So DoParam sets a parameter, which adds or overwrites it?
yeah pretty much!
Alrighty...
Now. I'm modifying items in a different mods. Any way I can ensure they don't error when said mod isn't installed?
so noone at the moment can give me advice here?
struggling really hard
if getActivatedMods():contains('ModID') then
of course ^^
That should be enough to make all the jarred foods last a sensible time...
overriding the mod's definition of these traits is the easiest way to do this, i don't know why you can't find it, maybe i can have a look for you when i'm next at my pc
im editing a workshop mod, i have no issues editing the default traits or professions
i need help with editing other people mods so they dont break the game ive spent 60+ hours fine tuning for the experience i want
Any easy tutorial on how to make a menu replacer? I just want to add a new background is all
There were issues and I can't reproduce it (probably there were game bugs, maybe fixed). Anyway now it's deprecated because there is such a vanilla feature using sandbox-options.txt
So if you want custom sandbox options, just use sandbox-options.txt. It's a bit confusing in mp bucause it's not accessible before events but I think it's better and simpler.
Subscribe to any such mod and see files/folders.
In a Lua file:
ScriptManager.instance:getItem("Base.CannedCabbage"):DoParam("OnCooked = CannedFood_OnCooked")
Not sure π I guess it's the same.
Ah
But "instance" should be a bit faster.
And I do it in shared scripts on startup?
What is "startup" for you?
Dunno. When the game is loading, I want the item definitions to change
Just put in in a file. Should work. Yes, shared is a good place.
K
Do you know if I can somehow remove a property?
I suppose I can set a boolean to false actually
have you tried itemtweaker?
Oh, via the API?
I need to check if... If it's in the pack I'm working fir
But if I can get the Lua code to do it without the API, I might as well do that
Oh hey we do have that API
I still have troubles to get my ZombieScream working. As my post from earlier describe I want hear my zombie scream sound from father away. So players are able to figure out where the zombie might be.
#mod_development message
The suggestet solution from @ancient grail didn't work for me:
#mod_development message
I hoped that the following line will do the trick but it didn't work for me.
getSoundManager():PlayWorldSound("ZombieDemonScream", zombie:getSquare(), 0, 450, 1, false);
I still have to go in between around 15 tiles or so to the zombie. As far as I understand addSound(...) only makes zombies in the given range hear the sound.
Does anyone have another idea what to do?
Hmmm ok... I'll look into that, thanks. I was hoping to give server hosts an option to disable part of my mod when they host the game and set sandbox options... Didn't want them to need to leave game. Will consider my options.
Didn't want them to need to leave game.
With sandbox-options.txt they don't have to.
Oh really? Clearly I don't know how that file works
Search this filename in steam workshop mods folder π
i just wish @weak sierra would just share the recipe yeeter code
So I'm trying to hide a Mod Options setting when a SandboxVars setting is false... Currently, I'm trying this:
\
local dawnOfTheZed = {}
if SandboxVars.DawnOfTheZed.CanHideHaloNotifications then
dawnOfTheZed = {
["Gamepad Shortcut (R3)"] = true,
["Hide All Player Names"] = true,
["Hide All Halo Notifications"] = true,
["Hide User Interface By Default"] = false
}
else
dawnOfTheZed = {
["Gamepad Shortcut (R3)"] = true,
["Hide All Player Names"] = true,
["Hide User Interface By Default"] = false
}
end```
Unfortunately, when I load up the settings in game, Mod Options still shows `Hide All Halo Notifications`, even though console confirms that the game recognizes `SandboxVars.DawnOfTheZed.CanHideHaloNotifications` as `false` while the game is running. Anyone have any guesses why? Maybe because I already have `Hide All Halo Notifications` checked in my own local settings, it just shows up regardless? Or perhaps `SandboxVars.DawnOfTheZed.CanHideHaloNotifications` somehow becomes `false` *after* it already told `dawnOfTheZed` to create 4 fields instead of 3?
@blissful salmon hey dude
the mod works
and i can make stakes out of planks
thank you so much for your help
now i just need to upload it to the workshop
nice π
@blissful salmonone thing that i kind of want to do is make it seem like the character is making 3 stakes
not just 1 stakes that turns into 3
like instead of a single loading bar you see 3 loading bars like on at a time
not possible thru script. it has to be done 3x by the user or make an OnCreate via lua
hmmm i see
also on the game it says to craft stake
but since it's 3 it should be stakes
can i just put stakes instead of stake in the code
do i need to do something like stake"s" or whatever
recipe whatever nameyou put here will work
{
OnCreate:hereyoucannotaddspaces,
heres the recipe txt script
function Recipe.OnCreate.CheckInfection(items, result, player)
if player:getBodyDamage():IsInfected() then player:Say(getText("Infected")); end
end
heres the lua counterpart
function Recipe.OnCreate.CheckInfection(items, result, player)
if player:getBodyDamage():IsInfected() then player:Say(getText("Infected")); end
end
it's better not to use the api - it causes a lot of lag on startup and it really doesn't do anything except DoParam()
Just to throw this in. A bunch of custom tiles I made for you mappers out there. Hope you don't mind me to advertise in here.
https://steamcommunity.com/sharedfiles/filedetails/?id=2879745353
hows our mod @bronze yoke ? half way there?
can we see a screenshot
ow nvm its there
Thanks for the tip. I'll look into why that mod is in the modlist and if I can do anything, mention it to the admin
Anyone happen to know what triggers the tooltips to appear when you mouse over options in your settings menu?
Trying to make them appear when they are selected with Joypad...
some mods do require it, so if you already have it you probably can't remove it - all we can do is not use it in our own mods
actually i've taken a break to work on some commissioned work and such so i haven't made much progress
Well
The admin is dedicated enough to try and make a server-only copy of the mods I believe
i only know about the items
but heres where i would start to experiment if i needed tooltips
local toolTip = ISToolTip:new();
toolTip:initialise();
toolTip:setVisible(false);
pls share me your snippets when you learned how to man
ow wow nice
if you have them make a version of item tweaker with the prints removed it'll make loading screens much faster without needing to adjust every mod individually - one user on here mentioned they saved twenty seconds like this
how come you didnt post this on mapping chat
howcome theres no
SkillRequired:Farming=2,
???
@ancient grail I don't even know where that code would go or when it needs to happen. Before I can do anything, I need to figure out two key details. (A) What method triggers the appearance of a tooltip in the Options menu on mouseover? (B) By what mechanism is the gamepad-active setting enclosed with the white box that tells the user which setting they're going to toggle when they press Xbox A (PlayStation X) on the gamepad?
If I knew B, I could call A when B occurs.
In general chat they sent me over here. I'm new to this channel. Should I post this in mapping then?
right
its welcome here as far as i know but it its better suited there
Easy. Thanks for the advice.
i plan to im just super busy and it isn't done
im gonna make it a dependency mod u can use
there's a problem with it where if a user has the recipe already before it's yeeted they retain it
i need to write up some code that removes it from players on login
not complex but haven't gotten to it yet
after that i will release it
if nothing else comes up maybe ill do that today
i run a server so my priorities shift as things happen there
guys anyone has any idea on how i transfer a oncreate to a world right click instead of rightclicking on the items
I don't understand the question... @ancient grail You just want to detect when a player right clicks and they are not in a menu or something?
imean using oncreate its always done when you right click objects
what if instead of that id rather have the options visible when you right click on the foloor
@bronze yoke @weak sierra Did either of you get this to work? When I tried it several days ago, it only loaded the sandbox defaults (rather than the actual configured values). Maybe I called ItemPickerJava.Parse() too early, idk
i have not done it yet
it works perfectly for me when i call it OnInitGlobalModData
i was planning on doing the "dirty" way tho
thinking it might apply more
but i dont know how the second one works
getSandboxOptions().load() loads the sandbox options early, ItemPickerJava.Parse() applies the distributions late
Oh, I see.. Both OnPreDistributionMerge and OnInitGlobalModData occur quite late in the game boot process. Both occur after server/ lua scripts are loaded, which is too late for what I'm doing, which is patching shared/ and client/ lua files of other mods
Thanks
If you pass -Ddebug=true to the java process (not the same as command lines arguments that are passed to the PZ server/client), it puts the server into debug mode so that isDebugEnabled() can be used server-side.
".\jre64\bin\java.exe" -Ddebug=true [snip...] zombie.network.GameServer -servername servertest
Sharing
My newly finished mod
https://steamcommunity.com/sharedfiles/filedetails/?id=2879848416
nice!
Great idea @ancient grail
Don't anybody know about my problem? I didn't found a way by myself to solve this. Is it really "uncharted land" or did I described it bad? Just tell me... I'm not english native so I probably explaind it not understandable or just bad. I'm a little desperate at the moment...
i really don't know anything about that, but isn't the audible range in the sound script or something?
I only found the SoundBanks.lua so far. But most of the stuff in there is commented like:
-- { alias = "assaultrifledistant", file = "media/sound/assaultrifledistant2.wav", gain = ambientDefaultGain, minrange = 0.001, maxrange = 1000, maxreverbrange = 1000, reverbfactor = 1, preferedTriggerRange=defaultTriggerRange},
I'm not sure if this is deprecated or if I can use this in some way.
At first I want the sound be hearable by the players. If I have the option to attract zombies in special cases it would be nice. But as I mentioned I think attract zombies can be done with the addsound(...) stuff...
As for example I hoped I could use this:
https://projectzomboid.com/modding/zombie/SoundManager.html#PlayWorldSound(java.lang.String,zombie.iso.IsoGridSquare,float,float,float,int,boolean)
But the radius doesn't seem to affect the range. I tried it for example with:
getSoundManager():PlayWorldSound("ZombieDemonScream", zombie:getSquare(), 0, 1450, 1, false);
declaration: package: zombie, class: SoundManager
that is pretty cool
Not sure about audible sounds that players can hear, but this is what I used to draw the attention of zombies based on range. There is no actual audio played, as this is for chat text that is intended to produce a sound (like whispering or speaking).
WorldSoundManager.instance:addSound(player,
player:getX(), player:getY(), player:getZ(), radius, volume)
I used the same value for radius and volume (Didn't dig deep enough to figure out how pz handles those values differently)
The values seemed roughly equivalent to number of tiles
Looking at the IsoGameCharacter:playSound() implementation, that seems to call into an FMODSoundEmitter. I think there is a method to get sound emitters from the IsoGameCharacter? I'll have to check a bit later
Thanks for feedback. Thats the part I think I've understand (like I've mentioned as addSound() stuff). But my real goal is to make a zombie periodically hearable. May be as second goal make the zombie attract other zombies when the zombie gets a player as a target.
This would be nice. I also looked at this stuff in java. But I didn't get deep enough to understand it.
DebugOptions.instance.Character.Debug.PlaySoundWhenInvisible```
There's a debug option (under the `Options` button in the debug UI) to play sounds when invis fyi
:O
your mod concept sounds very very interesting to me

i like my players to suffer
I know, I'm the player
one of them
But she's also real nice when bullcrap happens
otherwise you're cow food
Okay, so I need to modify an item that I know is a result of a recipe
item:DoParam("DaysFresh", value)
item:DoParam("DaysTotallyRotten", value)```
Do I do it something like this?
Been experimenting with the ModData serialization. As we've already known, functions and userdata doesn't get preserved, only base stuff like tables, doubles, strings...
But another thing to keep in mind is references are flattened out. For example, if you have something like
local md = object:getModData()
local test = {"Test" ,"Table"}
md.test1 = test
me.test2 = test
md.test1 and md.test2 will be the same reference until its serialized, then they become copies and no longer maintain their relation
I just try to do some random stuff that I like to see in the game π If I can complete it I'd like to share the stuff but at the moment I have several problems to solve... But step by step... I currently working on the sound thing and after that I think I go back to the model stuff...
:)
best to store an identifier that u can retrieve the reference from then instead
yes, if you have a convoluted self-referencing table setup, best to use keys. Same with storing functions, could save a string representation of the function name or something
knowing db design well sounds very helpful for this
lol
i think im gonna stick to storing simple data myself
me too. I'm just struggling to come up with a data structure for what I want to store, so I figured I'd test the edges of the system to see what I can get away with
Yea, that's how you'd do something like sending a message to the server that sends another message to a different client to call a specific function
chatty client-to-client messaging
ya, you just can't store bespoke anonymous functions, closures, things like that
Still trying to figure out a way to have client side code request data from the server and wait for the reply before continuing π€
callback
theres
OnReceiveClientCommand
and OnReceiveServerCommand
so client sends to server
it processes it
You can't really. The lua thread is the UI thread, so you'd block everything
it registers callback with the client end for that command
and then upon receiving the right kind of command in the other dir
it responds with code
coroutines are not possible in kahlua?
they are, and also are not necessary for what was specified here?
they never said blocking the thread to wait
they just said to wait
They are, but they aren't threads. They are just saved execution state that resumes at a later time
I suppose you can enclose locals into the callback if you're good
You could integrate it into a coroutine, but it'd still amount to putting an event handler to receive the reply as @weak sierra described above and that event handler telling the coroutine it is time to resume
I just hate splitting code up like that, makes code hard to follow. Everytime I'm rooting around in the java code and I see it call the Packet methods I know I'll never figure out where that went, lol
that's.. possible but like - why
lol
just store it with a unique ID in a table on the client
and then send that ID to the server
and then have it send it back
then the locals are read back from the table
when it executes on the response
It might be kind of nice to have something like this to keep the general logic readable```lua
function()
h = spawn_zombie_horde()
s = play("scary_zombie_sounds")
wait(end_of(s))
wait(until_receive_message("start_zombie_movement"))
h:chase_player()
-- more stuff
wait(until_receive_message("stop_zombie_movement"))
end
argument in favor of coroutine u mean?
ive spent a lot of time in client/server land and multithreading land so reading callbacks doesnt bug me as long as they are named and stored in a sensible way
yea, that's one thing coroutines do. They keep the some execution encapsulated in one location and maintains the state too
im not too familiar with coroutines in lua except knowing they exist
so im like "that's spooky let's just"
but that is probably unfounded
anyway the base point stands, callbacks are the way to set up the logic
whether in a coroutine or in discrete functions
not really any other way afaik
yea, behind the scenes, pz only gives you events and event handlers to do messaging like this, so even if you use coroutines, you'll need to implement that on top of the events/callbacks. Now if you've done that work and packaged into into something reusable, you don't have to mess with them after that so much :)
public class PlayWorldSoundPacket
implements INetworkPacket {
String name;
int x;
int y;
byte z;
public void set(String string, int n, int n2, byte by) {
this.name = string;
this.x = n;
this.y = n2;
this.z = by;
}
public void process() {
SoundManager.instance.PlayWorldSoundImpl(this.name, false, this.x, this.y, (int)this.z, 1.0f, 20.0f, 2.0f, false);
}
public Audio PlayWorldSound(String string, boolean bl, IsoGridSquare isoGridSquare, float f, float f2, float f3, boolean bl2) {
if (GameServer.bServer || isoGridSquare == null) {
return null;
}
if (GameClient.bClient) {
GameClient.instance.PlayWorldSound(string, isoGridSquare.x, isoGridSquare.y, (byte)isoGridSquare.z);
}
return this.PlayWorldSoundImpl(string, bl, isoGridSquare.getX(), isoGridSquare.getY(), isoGridSquare.getZ(), f, f2, f3, bl2);
}
Going through PlayWorldSound seems to lose the range value, using that hardcoded 20 value instead (at least in multiplayer). So don't think that fits your requirements
And in singleplayer, f2 (the range) seems to never be used π€
AmbientSoundManager does those long-range event sounds, like gun shots and wolf howls, but it's not exposed to lua
Hmm.. Can players hear other players' gunshots from a far distance?
why are so many obvious things not exposed to lua π
so u can hear voip with configurable range
could perhaps be able to trigger voip from a given distance
if exposed to lua, again, lol
Anyone know how to dump all the items in-game to a text file easily? Need it formatted like: ID : Category : Name : Plus any stats.
declaration: package: zombie.scripting, class: ScriptManager
loop thru that
pull info and turn into a string
write to file
im not writin the whole thing for u tho
Ma man. Does that list modded items too?
it would.
Can you write the whole thing for me? XD
OK
alright fair nuff
Can I mail you a cheque.
..no :P
Thanks though, truly. That is more than helpful what you just linked.
So AmbientStreamManger is exposed, but not AmbientSoundManager...
getAmbientStreamManager():addAmbient("bottlesmash", getPlayer():getX(), getPlayer():getY(), 200, 200)
That seems to do the trick. There's a catch though. It only works on the client in multiplayer. For no apparent good reason it excludes singleplayer. I imagine the author meant to prevent it from doing anything on the server-side, but excluded single player too
if (!GameClient.bClient) {
return;
}
@blissful salmon nm, that doesn't actually work once you are about 20 tiles away from the x/y coords :/
Does anyone know if the devs take requests on new events, and where the best place to ask them might be?
there's a feature request for modders place on the forum
a thread
whether they'll listen who knows
but that's the "correct" place
I was exactly on the same function and what you write was also my observation. Then I tried to check other possibiliies like the ambient sound. But I couldn't figure out how they do the gunshots in the far or similar sounds.
They select a random player and play the sound at the player's coordinates. Then do a WorldSound at a nearby random coordinate to attract the zombies to
I also don't know this... I'll test this tomorrow I think.
I'm not seeing any APIs that play sounds based on coordinates beyond roughly gridsquare distance (20x20 tiles)
This might be a good thing to investigate. I don't know how player gunshot sounds work
I have a suspicion that if they are heard long range, it is done by doing a distance calc serverside and sending a PlayWorldSoundPacket to nearby player's clients
But I tought my mates can also hear this farther than 20tiles.
Hmm.. Don't see anything about multiplayer (only split screen) in AmbientStreamManager. Not sure.
Is there any reason to ever spam the A button in this game on a controller?
Anything that can be rapidly accomplished by pressing A repeatedly and nothing else?
Wondering if it would be a pretty safe triple-tap bind.
AmbientSoundManager (not exposed) does multiplayer, not AmbientStreamManager (exposed)
I read about a sound radius in the wiki:
https://pzwiki.net/wiki/Weapons
But I don't know where these values come from and how accurate this is. In the items_weapons.txt i only found SoundVolume but nothing with the distance. And where they are defined. So I have to asume they are completly in java or defined with the soundeffect itself. But I'm not that far in the code to examine this stuff right know. Also the SoundBanks.lua seems kind of deprecated for the effects I think.
I overlookt it multiple times... The item has a SoundRadius definition....
Serverside, AmbientSoundManager sends packets to each client. Client-side, AmbientStreamManager receives it and adds a new Ambient object and plays it```java
public AmbientStreamManager.Ambient(String string, float f, float f2, float f3, float f4, boolean bl) {
this.name = string;
this.x = f;
this.y = f2;
this.radius = f3;
this.volume = f4;
this.emitter.x = f;
this.emitter.y = f2;
this.emitter.z = 0.0f;
this.emitter.playAmbientSound(string);
this.update();
LuaEventManager.triggerEvent((String)"OnAmbientSound", (Object)string, (Object)Float.valueOf(f), (Object)Float.valueOf(f2));
}
The radius and volume there are sent in the packet, but `this.radius` and `this.volume` are never used. The emitter only gets the x/y coords. Hrm
I unexpectetly found the following codeblock in the ISReloadWeaponAction.lua:
-- need a chambered round
ISReloadWeaponAction.attackHook = function(character, chargeDelta, weapon)
ISTimedActionQueue.clear(character)
if character:isAttackStarted() then return; end
if instanceof(character, "IsoPlayer") and not character:isAuthorizeMeleeAction() then
return;
end
if weapon:isRanged() and not character:isDoShove() then
if ISReloadWeaponAction.canShoot(weapon) then
character:playSound(weapon:getSwingSound());
local radius = weapon:getSoundRadius();
if isClient() then -- limit sound radius in MP
radius = radius / 1.8;
end
character:addWorldSoundUnlessInvisible(radius, weapon:getSoundVolume(), false);
character:startMuzzleFlash()
character:DoAttack(0);
else
character:DoAttack(0);
character:setRangedWeaponEmpty(true);
end
else
ISTimedActionQueue.clear(character)
if(chargeDelta == nil) then
character:DoAttack(0);
else
character:DoAttack(chargeDelta);
end
end
end
I didn't see this one till now. But I'm not sure if or how character:playSound() work with character:addWorldSoundUnlessInvisible()
local radius = weapon:getSoundRadius();
if isClient() then -- limit sound radius in MP
radius = radius / 1.8;
end
character:addWorldSoundUnlessInvisible(radius, weapon:getSoundVolume(), false);
character:startMuzzleFlash()
character:DoAttack(0);
Oh, looking at same thing π
Would a technique for binding multi-tap controller button signals be useful to anyone here?
If character:addWorldSoundUnlessInvisible() is anything like the WorldSound I mentioned earlier, all that does is attract zombies based on radius/volume, not actually play sound that is audible to a client
public void addWorldSoundUnlessInvisible(int n, int n2, boolean bl) {
if (this.isInvisible()) {
return;
}
WorldSoundManager.instance.addSound((Object)this, (int)this.getX(), (int)this.getY(), (int)this.getZ(), n, n2, bl);
}
This is very likely the case...
Yea, that just attracts zombies
damn...
Do you know where the sound in the item definition comes from? For example the "MagnumShoot"? Is this packed in the sound/banks/Desktop/ZomboidSound.bank? Do you know if the banks only contain the sounds or additional infos? But at the moment I fear the the hearable range atm is always the a default distance....
I think I give up for today... I'll make a few more test tomorrow and if I find nothing new then I wait with this and try to solve another problem... But many thanks for your help/assistence π
Don't see it anywhere. It may be compressed in those bank files so it isn't showing up with a simple string search
im kind of late to the party, and did some scrolling, have you seen this link @blissful salmon https://github.com/FWolfe/Zomboid-Modding-Guide/blob/master/scripts/README.md at the bottom they had the sound of the shotgun as a block.
idk if its out of date
$ file ProjectZomboid/media/sound/banks/Desktop/ZomboidSound.bank ProjectZomboid/media/sound/banks/Desktop/ZomboidSound.strings.bank
ProjectZomboid/media/sound/banks/Desktop/ZomboidSound.bank: RIFF (little-endian) data
ProjectZomboid/media/sound/banks/Desktop/ZomboidSound.strings.bank: RIFF (little-endian) data
https://en.wikipedia.org/wiki/Resource_Interchange_File_Format
sound radius is the sound zombies hear it at, and distancemax is the range other players will hear it
Looks similar to the shoutgun sound name, DoubleBarrelShotgunShoot
static void receivePlaySound(ByteBuffer byteBuffer, UdpConnection udpConnection, short s) {
GameSoundClip gameSoundClip;
int n;
PlaySoundPacket playSoundPacket = new PlaySoundPacket();
playSoundPacket.parse(byteBuffer, udpConnection);
IsoMovingObject isoMovingObject = playSoundPacket.getMovingObject();
if (!playSoundPacket.isConsistent()) {
return;
}
int n2 = 70;
GameSound gameSound = GameSounds.getSound((String)playSoundPacket.getName());
if (gameSound != null) {
for (n = 0; n < gameSound.clips.size(); ++n) {
gameSoundClip = (GameSoundClip)gameSound.clips.get(n);
if (!gameSoundClip.hasMaxDistance()) continue;
n2 = Math.max(n2, (int)gameSoundClip.distanceMax);
}
}
for (n = 0; n < GameServer.udpEngine.connections.size(); ++n) {
IsoPlayer isoPlayer;
gameSoundClip = (UdpConnection)GameServer.udpEngine.connections.get(n);
if (gameSoundClip.getConnectedGUID() == udpConnection.getConnectedGUID() || !gameSoundClip.isFullyConnected() || (isoPlayer = GameServer.getAnyPlayerFromConnection((UdpConnection)gameSoundClip)) == null || isoMovingObject != null && !gameSoundClip.RelevantTo(isoMovingObject.getX(), isoMovingObject.getY(), (float)n2)) continue;
ByteBufferWriter byteBufferWriter = gameSoundClip.startPacket();
PacketTypes.PacketType.PlaySound.doPacket(byteBufferWriter);
playSoundPacket.write(byteBufferWriter);
PacketTypes.PacketType.PlaySound.send((UdpConnection)gameSoundClip);
}
}
There's where the server sends the packet to play audible sounds (not WorldSounds, there's a separate method for those) to the players' clients
public boolean RelevantTo(float f, float f2, float f3) {
for (int i = 0; i < 4; ++i) {
if (this.connectArea[i] != null) {
int n = (int)this.connectArea[i].z;
int n2 = (int)(this.connectArea[i].x - (float)(n / 2)) * 10;
int n3 = (int)(this.connectArea[i].y - (float)(n / 2)) * 10;
int n4 = n2 + n * 10;
int n5 = n3 + n * 10;
if (f >= (float)n2 && f < (float)n4 && f2 >= (float)n3 && f2 < (float)n5) {
return true;
}
}
if (this.ReleventPos[i] == null || !(Math.abs(this.ReleventPos[i].x - f) <= f3) || !(Math.abs(this.ReleventPos[i].y - f2) <= f3)) continue;
return true;
}
return false;
}
There it checks if any of the 4 connectAreas (for the 4 splitscreen players on the client) are nearby the x/y of the sound to determine whether to send the packet to the client or not
Does anyone have any mod recommendations for single player?
im looking to make a drink mod idk where to start tho
Wdym by a drink mod?
Oh mb lol thanks
If youβre gonna make a drink mod I would definitely say add like a moonshine distillery barrel or something so you can make moonshine for Molotovβs or just to drink
naw im making a proper British stella
adding a watermelon too
ill keep it in mind
Ye, sounds like a good mod though
anyone alive?
fr? ong?
I honestly don't know, now that I think about it.
What if I'm not?
Oh, God, what if I'm not?
are you dead??
Bruh I cannot stop adding little improvements to these mods before I push em, losing it lol
by the offchance you do how do you make a drink mod
I do not, however . . .
awh
If I wanted to make a drinks mod
I would find a 5-star drinks mod like this one: https://steamcommunity.com/sharedfiles/filedetails/?id=2674541310&searchtext=drink
And then I would go to the steamapps folder for games on the same drive as your Zomboid install, and from there navigate to steamapps\workshop\content\.
ok ok
Then I would search for something key to the name of the mod, e.g., "Energy", or "Drinks"
Or, alternatively, find the folder number that matches the mod's Workshop ID
alr
In there, you can actually read the .lua files and see the image files that the modder above used to add energy drinks.
And just... try to change the right stuff
Until it stops crashing!
π€ͺ
I mean, if you want to make your own version, you'll probably need to change things
E.g., what image files you include
What variables reference them
ill focus on the content first
How the drinks are defined
etc.
What the drinks do.
All that can be adjusted
So, you know, adjust it, just not wrong, or it stops working
i litterally want to change some textures
If you borrow terribly heavily from that modder's code and style, asking for permission before uploading or perhaps giving a shout-out to the modder whose code you used is obviously polite, but if you just learn the functions you need and use them in a fairly individual way, and you use all of your own variable names and your own logical flow of events and such, I don't think anyone can legitimately be mad at you for learning which functions exist by looking at their code.
alright
Probably could learn it from that mod. No clue. But since they added new drinks, I'm guessing they added new textures.
i have no clue where the pz folder is
--To match our tweak to the SPAS12.
table.insert(ProceduralDistributions.list.ArmyStorageGuns.items, "GWP.R870Police")
table.insert(ProceduralDIstributions.list.ArmyStorageGuns.items, 0.2)
--To make it available in the gun stores *at all*.
table.insert(ProceduralDistributions.list.GunStoreDisplayCase.items, "GWP.R870Police")
table.insert(ProceduralDistributions.list.GunStoreDisplayCase.items, 0.2)```
for the SECOND line there
oh
nvm
i see it
:)
rofl
happy to have helped. my work here is done
Could I:
A) Have a drainable item take a Car Battery instead of a regular battery without altering the code? Ofcourse I'd check for car battery on "Insert Battery" and such but would it actually drain it?
B) I have asked this before but sadly I can't find it. If I have 4 items that will use the same LUA code, instead of typing:
If ITEM = ITEM1 or ITEM = ITEM2 or ITEM = ITEM3
Can I somehow make a global tag?
108600, but again you could just search a keyword from the mod
ight ty
Sorry trying to finish up some of my own insanity
no worries
This mod to make UI more manageable on controller has spiraled completely out of . . . control.
π¦
Let ModOptions to manage only client options, and Sandbox Var to manage only server options. Don't mix it, because it's different. Halo text should be client I guess, because it's cosmetic and each user should be able to tune it on client. Other options that affect gameplay should be set by admins only, so it' related to sandbox options.
@hearty dew Check pcall() please π How is it fast in terms of performance?
some_fn()
--- vs ---
pcall(some_fn)
It's a kind of try-catch, but description says that it's a kind of sandbox for a function. I'm not sure what it means.
some_fn = function() end; l.measureTime("test", function() for i=1,100000 do pcall(some_fn) end end)
112ms
some_fn = function() end; l.measureTime("test", function() for i=1,100000 do some_fn() end end)
37ms
Basically if some_fn() throws an error, pcall will simply return true/false as a result, iirc
pcall (f, arg1, Β·Β·Β·)
Calls function f with the given arguments in protected mode. This means that any error inside f is not propagated; instead, pcall catches the error and returns a status code. Its first result is the status code (a boolean), which is true if the call succeeds without errors. In such case, pcall also returns all results from the call, after this first result. In case of any error, pcall returns false plus the error message.```
What about?..
some_fn = function() for j=1,1000 do x=7 end end;
l.measureTime("test", function() for i=1,100 do pcall(some_fn) end end)
so pcall will return true/false, followed by the normal return values of some_fn()
btw guys do any of you know how the game handles the spear durability with carpentry
im pretty sure that your spears have better durability the higher your carpentry skill
and i want to do something equal to that
to another weapon
hey kop
hey dude
I know how it works. I wonder how it works inside, is it just "put callback in stack" or something else.
im finally working on the mod
which one?
i see
some_fn = function() for j=1,1000 do x=7 end end; l.measureTime("test", function() for i=1,100 do pcall(some_fn) end end)
22ms
some_fn = function() for j=1,1000 do x=7 end end; l.measureTime("test", function() for i=1,100 do some_fn() end end)
21ms
basically the same with so few function calls. 1000 vs 100000
i don't think i've ever seen it
@tawdry solarbtw do you have any idea on this?
do you think it would be in the scripts?
it would make sense for me
Seems pcall is expensive enough. 1 ms per 100 calls.
it isn't in recipes
That might have just been a precision error since it was so small, 21 vs 22
i thought there would be something
or in the weapons
but i can't find anything
weird
it def feels like something that would be in the scripts
no-pcall
LOG : General , 1666739821346> 885,890,904> LUtils(0).test: 21ms
LOG : General , 1666739822349> 885,891,907> LUtils(0).test: 21ms
LOG : General , 1666739823345> 885,892,903> LUtils(0).test: 21ms
LOG : General , 1666739824696> 885,894,254> LUtils(0).test: 23ms
LOG : General , 1666739825845> 885,895,403> LUtils(0).test: 21ms
LOG : General , 1666739826846> 885,896,404> LUtils(0).test: 21ms
LOG : General , 1666739827945> 885,897,504> LUtils(0).test: 21ms
LOG : General , 1666739829445> 885,899,004> LUtils(0).test: 21ms
LOG : General , 1666739830692> 885,900,250> LUtils(0).test: 22ms
pcall
LOG : General , 1666739874846> 885,944,404> LUtils(0).test: 21ms
LOG : General , 1666739876746> 885,946,304> LUtils(0).test: 21ms
LOG : General , 1666739878446> 885,948,003> LUtils(0).test: 22ms
LOG : General , 1666739879745> 885,949,303> LUtils(0).test: 21ms
LOG : General , 1666739880845> 885,950,403> LUtils(0).test: 21ms
LOG : General , 1666739882745> 885,952,303> LUtils(0).test: 21ms
LOG : General , 1666739883845> 885,953,403> LUtils(0).test: 21ms
LOG : General , 1666739885546> 885,955,103> LUtils(0).test: 21ms
LOG : General , 1666739886746> 885,956,303> LUtils(0).test: 21ms
LOG : General , 1666739887946> 885,957,503> LUtils(0).test: 21ms
LOG : General , 1666739889646> 885,959,203> LUtils(0).test: 22ms
(112-37)/100000 = 0.00075ms overhead per pcall
So pcall all you want π
im starting to question if it is even in the game
i'm starting to use it π
isnt it to do with maintenance
idk
the skill
but then what about carpentry
thats in the game then
its not a prof its a skill
you level it up by killing zeds
hmmmm
ye i get maintnence
but what about the incorporation with carpentry
im pretty sure spears get a bonus the higher your carpentry is
@hearty dew I have some habits where errors are not allowed, e.g.:
local old = getText -- ninja injection
getText = function(...) ...... end
pcall(old_fn)
getText = old
who is this table imposter i see...