#mod_development
1 messages Β· Page 41 of 1
@blissful salmon Haven't verified by testing this, but as far as I understand things at this point, using IsoGameCharacter:playSound() should do what you want for other multiplayer clients. However, there needs to be a GameSound associated with the sound, otherwise the range defaults to 70 (not sure if those distance units are tiles or what). That said, since the client that originates the sound doesn't play it after about 20 tiles, you may have to handle that case specially.
Only other option I'm seeing is to do it yourself via client/server commands
Yea, that's a good use case for it
I should use pcall similarly. I have a thing where I do```lua
local old_isClient = isClient
function isClient() return true end
unsafe_fn()
isClient = old_isClient
Would be bad if `unsafe_fn()` errored π
trying to load a mod into my single player for testing, and I am not getting anything to load properly. Anyone willing to take a look it and see if I messed something up somewhere? it is a mod to add short ranged intercom-style radios to the game for factions in MP and stuff
Any errors/exceptions in console.txt?
no, the mod was showing up in my mods list but would never actually enable lmfao
I got it to enable at first, but after I tweaked some personal mistakes, it will no longer load at all
Unfortunately this cosmetic issue is only fixable using an option that affects gameplay slightly. It temporarily, for 2 seconds, zeroes your HoursSurvived, whenever you are doing something likely to reward XP and thus cause a halo note to appear. If you know any more efficient way to accomplish exactly the same goal, I'm all ears. Therefore I am offering a server setting to admins that allows them to block this feature of the mod if they do not want to allow their players to compromise HoursSurvived variable under any circumstances.
I tried for many, many hours and requested help many times, and to my knowledge no one on this server has any better solution for preventing all halo notes from showing (at least not something doable in Lua and automatically installable via the Workshop).
Please, please prove me wrong.
Tyrir recommended a solution that came close, but ultimately failed in more situations and more variations of halo notes than the one I'm finally settling on.
do i retexture all these
Sure looks relevant to me. @tawdry solar But this assumes you're retexturing his energy drink items... Might be weird because your end result seems like it would be energy drinks that look like beers?
Probably need to play with the Lua a bit so that the things that look like beer say Beer.
But, FYI, it's cool, I established a workaround. I can use the Sandbox Var as an extra condition for the hiding of stuff, no problem afaik.
What do you mean by 'will no longer load'? Are the mod's files not loading? You can check the console.txt output to verify
@thick karma can i use vsc to read lua files
Yeah I use VSC
Like, the mod is listed in the mods list, but when I click to enable it, it doesnt stay enabled. When I press accept, it just doesnt keep the mod on
Notepad++ works great too, tbh. If you just wanna look at basics and stuff
@thick karma how do i change the name?
Never seen that behavior before. I'd expect some error to show up in the logs if it failing like that, but I haven't come across that scenario before
WHEEEY
Somewhere in the Lua presumably.
Ayyyy progress.
i textured it
ight
Also probably some labels in shared/translate if I had to guess
My injections are a bit more complicated. There are double and triple injections. π΅βπ« For example, this is double:
-- main injection
local old_contextMenu = ISVehicleMechanics.doPartContextMenu
function ISVehicleMechanics:doPartContextMenu(...)
local old = ISContextMenu.addOption -- ninja injection
function ISContextMenu:addOption(txt, t, o, a, b, ...)
if b and type(b) == 'userdata' and b.hasModData and b:hasModData() then
local data = b:getModData()
if data.feces then
txt = txt .. 'f'
elseif data.urine then
txt = txt .. 'u'
end
end
return old(self, txt, t, o, a, b, ...)
end
pcall(old_contextMenu, self, ...)
ISContextMenu.addOption = old
end
Now it will finish correctly even if there are errors inside (even if the error is in my own injected function).
whats all this
Looks like they're inserting item objects into a table of items categorized by item type.
Not 100% sure, I've never modded items.
@tawdry solar
How to get name of vehicle, not the id but the name that would be in translation file.
getFullName() and getName() is just the id...
Couldn't find any other methods to do this.
Anyone know anything about making profession mods? im trying to make one and i cant get the professions to show up in character creation
It might be worthwhile to do```lua
local success, result1_or_error, result2 = pcall(unsafe, self, ...)
ISContextMenu.fn = old_fn
if success then
return result1_or_error, result2
else
error(result1_or_error)
end
so that the errors are still visible to fix
from which object type?
pz uses the ProceduralDistributions table to generate loot in containers. If you run pz in debug mode and turn on lootZed, I believe it will display the percentages for you when right-clicking a container
getScriptManager():getAllVehicleScripts()
https://projectzomboid.com/modding/zombie/scripting/objects/VehicleScript.html
declaration: package: zombie.scripting.objects, class: VehicleScript
Here is an example of a simple map mod using custom room definitions, custom loot zones and custom procedural distribution lists using the new loot distribution system (41.51+). 3 gas stations have been placed in a cell intended to be added to the vanilla map via a map mod, the Northern most stat...
Javadoc Project Zomboid Modding API declaration: package: zombie.scripting.objects, class: VehicleScript
That's supposed to be a bit more up to date, not that it helps in this case here
Cheers, I'll note to use that instead. Sadly I see nothing different.
ProjectZomboid/media/lua/client/Vehicles/ISUI/ISVehicleMechanics.lua: local name = getText("IGUI_VehicleName" .. self.vehicle:getScript():getName());
Looks like it isn't done neatly on the java side for ya 
Have to append the id to the prefix used for the ui string id, then look it up using getText
function ISVehicleMenu.getVehicleDisplayName(vehicle)
local name = getText("IGUI_VehicleName" .. vehicle:getScript():getName())
if string.match(vehicle:getScript():getName(), "Burnt") then
local unburnt = string.gsub(vehicle:getScript():getName(), "Burnt", "")
if getTextOrNull("IGUI_VehicleName" .. unburnt) then
name = getText("IGUI_VehicleName" .. unburnt)
end
name = getText("IGUI_VehicleNameBurntCar", name)
end
return name
end
Or just call that function passing it a vehicle object
Errors are still visible anyway
ooo thanks, big help.
i've got a custom server i host. i want to add public locations on the map. is there a way to do this?
this way when a player joins he can press m, open his map and see where certain areas are, or a location. (essentially one shared map controlled by admin that updates onto everyone's map.)
Share annotation mod source may give some ques.
i was looking at that, basically when players join i could share my map possibly? then it would update theres and give them all the custom stuff.
Kinda busy with my own modsanity right now but you should try following this https://m.youtube.com/watch?v=N6tZujOPnDw
This tutorial video will show you how to make a simple drink in Project Zomboid. I will go into the steps involved from start to finish. Read more below.
0:00 intro
1:08 Start
1:44 Searching for images to use in game
2:30 Searching for the Sound Effect
3:06 Creating mod file directory
3:54 Creating mod.info
4:34 Creating a poster
7:14 Adding ne...
It's about making a drink mod
Oh man y'all I'm moving to the test-alongside-70-other-mods stage... wheeee
any devs that specialize in the uis and game mechanics let me know if youre interested on working on some custom mods for my server. i'd love to pay for some cool systems i need.
and im looking to expand my team if you would like to come hangout and work with other modders π
What kind of systems? I wouldn't really say I'm specialized in anything, but I have been messing with UI stuff a fair bit over the last week, especially keyboard / gamepad input and visibility crap. Might be able to figure out some pieces of your puzzle.
we are looking for police related systems, like arresting players and moving them and placing them in cars
we are looking into custom phones to message players.
looking into a respawn system to keep players keys after death and character, however drop all other items
hmm, all kinds of rp related systems
if interested dm me ill get you in the server or we can dm and talk about the ideas we have. we have 100+ members all with at least one idea haha
aiteron normally works on everything for me but hes super busy as they are probably working hard on the actual game right now π
You could use setHaloNote on target players to make soundless green text appear over their heads in response to a command. I might be able to figure out how to get a chat window to do something like this if I spent some time on it.
but you have access to some of the best modders and a game dev on the team!
personally i just founded the server, i manage it, the devs work on it and i come up with the plan and they some how always manage to do it they are so talented haha
personally they make the stuff and i donate to them when they make it happen.
Interesting, I don't know item spawning but I do have a mechanism available for doing something right before anything happens to the player's UI at the moment of death, and then doing something else right away when the player's UI would become visible again after respawn.
I'll consider the texting thing first. If I have any good ideas I'll try some stuff.
yes, a big thing also is the police and emergency system as well
i have tons of ideas lol, we are still in early beta at the moment the server is only open to goverment workers, emergency services, and store owners.
The police system sounds like a very big project. A lot would need to go into that. I can only begin to guess about some of it.
Right now I am finishing up a few more of my own mods but I will look into some other people's issues more after
sort of waiting to get a respawn system built so players dont lose keys at death.
but no problem man just let me know what you can work on or what you think may help the server.
Releasing one mod for hiding UI better than in vanilla (works well for gamepad users, improves things for everyone), another for quickly dismissing windows that clutter the screen (mainly for gamepad users), and another mod that allows me to "meditate" by sitting and thus become invisible to zombies until I move or press buttons. Trying to get all three polished and tested and live asap. Will let you know if I make progress on one of your above ideas after.
awesome
outdated
i tried that
That may be so, but the entire game has not changed in every conceivable way since late 2020... That video is still for build 41, the most recent build of the game. So outdated here means "is no longer correct on a small handful of points at most." I would try to follow it until something doesn't work, and then ask here about exactly the things that don't work... people will probably tell you how to fix you're problem if you can ask specifically enough for the answer.
The loot settings tutorial for Arsenal seems to be broken, does anyone have an alternative link? https://steamcommunity.com/sharedfiles/filedetails/?id=2297098490
the tutorial isn't broken, its deleted. Something about the loot settings not working or being replaced with something else
@hearty dewAny idea how to use self.vehicle:getEnginePower()/10? Been trying past few hours.
Basically trying to dump vehicle stats. So far got id, real name, and some other stats from vehiclescripts.
@wet gorge self is coming from the fact that the function in which you found that is an ISVehicleMechanics object with data including a vehicle object. If you check ISVehicleMechanics, you'll find ISVehicleMechanics:new, which instantiates the menu. If you search all your Lua for ISVehicleMechanics:new, you'll see it gets instantiated as mechanicsUI in ISPlayerDataObject.lua... search for mechanicsUI and you'll find in ISPlayerData a function that returns that mechanicsUI for a given player: getPlayerMechanicsUI(playerIndex). If you call that, you can play with the mechanicsUI object. It will not have a vehicle unless you are actually accessing one.
E.g., here's how I hide that UI:
local mechanicsUI = getPlayerMechanicsUI(playerIndex)
if mechanicsUI and mechanicsUI:isVisible() and interfaceReflexes.options.shortcutsCloseMechanicsMenu then
mechanicsUI:close()
end
close() is always going to be available when it's visible. Presumably vehicle would also be available at this moment.
π€ Confusing.
Are you trying to print out the engine power value?
print(self.vehicle:getEnginePower())
?
Don't understand what you mean by 'use' in your question
Yes, trying to print it along with other stats.
getEnginePower seems to only work when a character is inside vehicle though.
anyone looking to make a quick buck let me know. i need a mod where when you place a item down you can right click on it and there will be a option that says "set price" so players instead of being able to pick it up they would have to pay the amount once they pay it it picks the item up
it would have to work with my servers custom currency mod, aiteron could help you integrate it if needed but hes busy working on the actual game right now haha!
it would some how have to reward the player that set the item down the amount of money paid. whether it gets sent to their inventory or to the bank account i dont care. id prefer to the players inventory but what ever makes that system work.
Hmm, maybe because it is a calculated value when the vehicle is on? I'm unsure
This user is onto something about enginepower in particular.
If you're just interested in dumping general info about vehicles, why not stick to what's available in the VehicleScript objects?
Some of the methods return incorrect values like: getStorageCapacity
Yea, he's done a lot of digging through the vehicle code for stuff he's working on, and it seems largely a mess as I understood his takeaways π
Are you finding that values you're obtaining from BaseVehicle to be better?
Few of them.
Those are the fields of a VehicleScript object. They might have info you are interested in
Yeah storageCapacity is set to 100 for every vehicle for some reason. Thanks for image.
all the get* method results from the first VehicleScript object
PyroUtils = PyroUtils or {}
PyroUtils.debugInvokeMethods = function(object, methodName, ...)
local output = {}
for i = 0, getNumClassFunctions(object) - 1 do
local method = getClassFunction(object, i)
if string.find(tostring(method), "%."..methodName) then
local result = method:invoke(object, ...)
table.insert(output, string.format("Method invocation result:\n%s\n%s", tostring(method), tostring(result)))
end
end
print(table.concat(output, "\n"))
end
did something similar for the fields
PyroUtils.debugInvokeMethods(getScriptManager():getAllVehicleScripts():get(0), "get")
probably some mistakes in that output bc I didn't catch the errors when the get* method expected parameters and none were provided and it thus failed to invoke
Big brain.
how resource intensive are zombie corpses? would a mod to automatically consolidate loot from large piles of corpses into fewer ones be beneficial for crazy population servers?
here a thing
---Override a function.
---@param p1 class
---@param p2 string
---@param p3 function
Utils.overrideFunction = function(p1, p2, p3)
local override = p1[p2];
p1[p2] = function(self, ...)
override(self, ...);
p3(...)
end
end
usage:
UTILS.overrideFunction(ISWorldMap, "onRightMouseUp", function (x, y)
print("x: " .. tostring(x))
print("y: " .. tostring(y))
end)
does anybody have an idea where i could find some reference on how animated tiles work? like for water and fire? am i correct by assuming that the tiles just replace each other on a specific circumstance? so shouldnt it work like this (just example): function replacesprite OnGameTick getSprite x and setSprite y
i would like to make a tile which look different depending on ingame time
but im super bad at all the coding stuff π
like i can do basic recipes but thats about it
thanks in advance for anyone giving me the smallest hint π π
I don't think that they work by replacing tiles, that sounds far too laggy...
Some mods have a base tile and use overlays on top to change it.
anyone know why when i try to repair clothing i get an error bottom right and when my character finishes his action it doesen do anything
its with any type of clothing no matter if modded or unmodded
There's a different channel for mod users
oh yeah just noticed sorry
Is there a somewhat simple mod that implements and uses custom sandbox settings I can refer to when making mine?
Become Brave or Become Desensitized?
Thanks, I'll check them out
guys
what happened with distros
im tyring to find it in zomboid files
i can't
nvm
i found it
Check out portal mod
oh thanks mate, will do!
i think thats what im looking for π₯³ , now i just need to understand how it works, muchas gracias senor! π
sometime I gotta check that mod out, had no idea that thing was animated
Hm...
-- a bit faster if x is global (and is not set):
if x == nil then
-- a bit faster if x is local (and equal to nil):
if not x then
In general "not x" is faster
On a square there are functions: ```lua
:getStaticMovingObjects()
:getObjects()
:getSpecialObjects()
:getMovingObjects()
:getWorldObjects()
What is the difference? What is included in "moving" or "world" objects, or just "objects"?
hm, moving objects are things like player and vehicle(?)
objects is a list of all objects including those you just drop
special objects are usually those you place like moveables and generator
maybe someone has a better defined list
Is there already a function which looksup for example "woodcutting" -> "carpentry" and vise versa? I'm often confused if I have to use the skill or perk name.
and another question: To distinguish between solo and multiplayer I currently use:
return (not isClient() and not isServer())
end```
Is there a better way than this?
SoulMod.shared_isSoloGame = not (isClient() or isServer())
It's calculated once on initialisation, then it's just a boolean variable.
Genius, I didn't thought about that 
What do you guys use to code the mods? I hear some people use Notepad++ and i am confused on why
Notepad++ has syntax highlighting for Lua
Also lets you collapse blocks and switch between files as tabs
Can't you get that with vscode and the right plugins for it?
Yes
But Notepad++ is just more convenient
VSCode works almost like an IDE, whereas N++ is just... An editor
most people here use ides i think
I also started with Notepad++ and then switched to VS Code, because of some code completition. I added the project zomboid lua as "library"...
#mod_development message
I use the sumneko Lua plugin
Ah i see, Thanks a lot
had no idea you could do that, thanks for that!
Hey guys I wanna make a mod that retextures some clothes in game but have no experience in coding and stuff, can anyone help me the basic stuff?
If thereβs like a tutorial vid or anything that would be great
what I'm still missing is the same for the Java/LUA stuff.
I personally started here:
https://pzwiki.net/wiki/Modding
Just be aware there is outdated stuff (if I remember correctly) but it gave me an overview and I was able to start. Same is with youtube stuff. Some videos are outdated but I found my way and used what i could.
I made a quick google search (zomboid modding tutorial) and found this. I remember that I learnd some stuff from it...
https://www.youtube.com/watch?v=N6tZujOPnDw
This tutorial video will show you how to make a simple drink in Project Zomboid. I will go into the steps involved from start to finish. Read more below.
0:00 intro
1:08 Start
1:44 Searching for images to use in game
2:30 Searching for the Sound Effect
3:06 Creating mod file directory
3:54 Creating mod.info
4:34 Creating a poster
7:14 Adding ne...
Ah thank you very much, I'll be asking some questions from time to time so hopefully everyone can help me out with my first steps in modding. Alright thanks for these starters dude I'm gonna take a look at them now.
Oh the video is long this is good
Maybe others here have better sources but this is more or less how I started.
Does someone know how LUA gets the globalobjects from java? Are they created at runtime?
everything is a java object those simply get exposed to the lua interpreter
iirc decompile LuaManager$Exposer.class to see whats exposed
Anyone know how to trigger a doContextualDblClick(item) on your InventoryPane items manually? So far, I've figured out I can get a highlighted item like this (note, I am using gamepad here, so I am interested in identifying the item based on gamepad focus):
bat = getPlayerInventory(0).inventoryPane.items[getPlayerInventory(0).inventoryPane.joyselection + 1]
Though I am not clear what kind of item this gives me, it returns some kind of Lua table. print(bat.name) seems to confirm this is a bat by printing Baseball Bat. However, then I go on to attempt this:
getPlayerInventory(0).inventoryPane:doContextualDblClick(bat)
And even though there are no errors, nothing happens.
I also tried this:
ISInventoryPaneContextMenu.equipWeapon(bat, true, bat:isTwoHandWeapon(), 0)
That one made the compiler mad, but the error gets thrown from some random file (tsarzones.lua?) so I'm unsure of the problem its actually causing
try bat.item
But can I get a list of exposed stuff in lua? I know about the java file where I can check whats exposed. But I'm looking for a way to get these functions from lua:
https://projectzomboid.com/modding/zombie/Lua/LuaManager.GlobalObject.html
Maybe my goal is weird but my idea was to write these functions into a lua file which I can add as library to my Visal Studio Code. So just make them empty functions so my VS accespts dem as recoginzed... Maybe I could also parse the java class but this seems more complicated. So I just hoped I can do this on the fly.
declaration: package: zombie.Lua, class: LuaManager, class: GlobalObject
i was just looking for the same kind of thing and found this tool https://github.com/cocolabs/pz-zdoc but it hasn't been updated in 2 years and doesn't seem to work at all on my computer
there's signs that people have still been using it successfully very recently though, so it may work for you
does this include functions like: getPlayer()?
nil
probably? it doesn't work for me so i can't tell you
You got the class not sure what your issue is
Already have the full list of methods can copy paste then a little replace to convert to lua and done
Ugh I can pull item names from any bag all day π
But doing something with them? Oof.
My goal is that VS Code recognize the functions and don't claim their are missing. I think @bronze yoke probably gave me a possible solution. I just have to check if I can get this to work.
Anyone know how to get this value from a vehicle using VehicleScripts or external method (without using BaseVehicle or something that requires player in vehicle): https://zomboid-javadoc.com/41.65/zombie/scripting/objects/VehicleScript.html#getStorageCapacity() ? getStorageCapacity returns 100 for every vehicle which is incorrect.
Javadoc Project Zomboid Modding API declaration: package: zombie.scripting.objects, class: VehicleScript
recently when i use mods it wont let me pick up anything and when im in the animation of picking something up there is just thousands of errors is there a way to fix it
Unsub to all mods, delete C:\Program Files (x86)\Steam\steamapps\workshop, then verify game files.
Could also probably launch in -debug and identify the mod or mods that are doing this by looking at the source files for the errors, given that game is launching.
Which way is faster kind of depends on you
i am not smart enough to do that but ok
You add -debug to Steam launch options, join your game normally, hit F11 in game, click Errors and read the log to see the source files. If it's a mod's file (if you recognize mod name), disable it.
Repeat
Until errors go away
if you're smart enough to doubt yourself, you're smart enough to do it π€ͺ
Other possibility I had is maybe trying to get the trunk storage with getPartID?
not sure what storage capacity is for, but this is from carwanna to get to the container of a vehicle.
for i = 1, vehicle:getPartCount() do
local part = vehicle:getPartByIndex(i - 1)
local partItem = part:getInventoryItem()
local partId = part:getId()
if partItem then --this part is installed
local container = part:getItemContainer()
if container then --this part is a container.
print("Container: "..container:getItems():size()) --This holds items
end
end
end
feel free to pick apart the code: https://steamcommunity.com/sharedfiles/filedetails/?id=2801264901
You should be able to get the size with container:getMaxCapacity()
You can also just go short hand directly to the part: vehicle:getPartById("Trunk"):getMaxCapacity() but some mods dont use the default Trunk (ki5) so you would need to loop though all the parts anyway
Can I remove a world item from client? I found this code: lua sq:transmitRemoveItemFromSquare(item); item:removeFromWorld() item:removeFromSquare()
LuaManager$Exposer does the work as someone above explained. The globalobjects specifically are in LuaManager$GlobalObjects and LuaManager$Exposer has a line for exposing that class specifically as I recall
might be in the java namespace table that kahlua exposes. It is not unfortunately. It looks to only put its functions into _G, which makes it hard to parse out
Hm... sq:transmitRemoveItemFromSquare(item) causes error.
Should item be InventoryItem or WorldItem?
so, for float values in a sandbox option, I write... float?
It uses double
okay
IsoObject? π
Maybe the java code checks the runtime type and handles it specially if it is a Inv or World item
What are the "Project Zomboid Modding Tools" I've found on the steam?
There should be a directory in your steam games with them all. It includes TileZed... that's all I remember π
did u release this beast yet
Thanks king.
Hey guys, just a theoretical question. Is it possible to make something like a landmines in PZ?
Thanks for the feedback. I already found the functions in _G after my last post. I've created a testfunction:
if type(v) == "function" then
print(i)
end
end```
And next step is to write them to a file like normal lua functions. By adding this to VS Code I think I can solve most of the displayed error and have better integration. I'm not sure but I thought I read something that I can't write to files with the normal LUA function but project zomboid has some support to it? Do you know an example?
that explains wtf _G is, i saw that in a mod recently
was like "where do they define that"
_G = lua environment
_G is the the default space for global stuff in lua. I read about this in the documentation.
You're liable to get a bunch of other functions sitting in _G for other purposes (false positives), but that will at least capture them all, heh
public void exposeGlobalFunctions(Object object) {
Class<?> clazz = object.getClass();
readDebugData(clazz);
for (Method method : clazz.getMethods()) {
LuaMethod luaMethod = AnnotationUtil.getAnnotation(method, LuaMethod.class);
if (luaMethod != null) {
String methodName;
if (luaMethod.name().equals("")) {
methodName = method.getName();
} else {
methodName = luaMethod.name();
}
if (luaMethod.global()) {
exposeGlobalObjectFunction(environment, object, method, methodName);
}
}
}
}
/**
* Creates a global variable in the environment that points to a function
* which calls the specified method on the owner object.
* <p/>
* The name of the global variable is the same as methodName
*
* @param environment
* @param owner
* @param method
* @param methodName the name of the method in Lua
*/
public void exposeGlobalObjectFunction(KahluaTable environment, Object owner, Method method, String methodName) {
Class<? extends Object> clazz = owner.getClass();
readDebugData(clazz);
LuaJavaInvoker invoker = getMethodInvoker(clazz, method, methodName, owner, false);
addInvoker(environment, methodName, invoker);
}
That's how the globals are exposed in lua. So, justs sits in _G
Can use ArendamethUtils.writeFile (or at least look at its implementation)
Ok, I'll take this as the grand approach if my simple solution isn't enought π
sec, trying to format it so I can paste it to discord. Too many characters for discord
Hello. Where can I find documentation with functions and descriptions?
was hoping u'd release it as a mod at some point and lock to admin only for mp use on a server xD
UdderlyEvelynUtils.ANSITerminal = true -- For colors. Only works if your terminal supports ANSI colors
UdderlyEvelynUtils.inspectJava(getPlayer(), "[Ii]nventory")
Oh, the terminal in a chat tab? It's so slow its hard to use atm because it reads console.txt from a FileInputStream. I had to limit it to read 10 lines per tick else it'd lag so bad it triggered anti-cheat 22 or something from blocking the ui thread for too long, lol
I need to go find a better way to read console.txt
This is just the function I use to inspect java objects. It's not related to the chat tab terminal
I renamed them to SoulUtils (like you alway do π ).
But where is the root folder? I used it like:
SoulUtils.writeFile("exposedFunctions.lua", "function " .. i .. " () end", true, true)
but i couldn't find the file...
(though the chat tab terminal supports ansi colors)
that is def still a useful thing
i have no function made for that
i just poke around by hand in debug
<_<
so now i do :)
same, but using that function heh
yeah that'll make it easier
root for that one is ~/Zomboid/Lua
have u tried just activating the debug mode console without debug mode?
and/or seeing how they implemented that
im guessing it's in java or else that'd be super easy
but often debug features can be accessed outside of debug mode
that console does suck tho
It's in java. Yea, I looked at that first. Wanted to make it resizeable, but couldn't
yaeh
the no resizing is my number 1 complaint
followed by it seemingly having EXTRA output that i don't want
which might be jsut cuz debug mode
there might be a setting for that that im ignorant of tho who knows
btw the game is coded in a mixture of lua and java right?
yeah
Javadoc Project Zomboid Modding API package index
from what i am understanding
Doesn't have descriptions though
Is there a mod to pick everything up? Like tvs, water fountains, lamps, etc..?
Or is that a thing already
you can already pick those things up right?
u just use lua, really, u CAN mod in java but there's no hook so the only real way to do java modding is server-side for dedicated
otherwise u have to have users manually install the mods
ok good
u could also use typescript with something called pipewrench if u wanted to
ill try to see if i can understand lua better
but it's a limited implementation of typescript on top of a limited implementation of lua
my coding knowledge is quite limited
How should I understand what each of them do?
it's simpler but has more pitfalls
hmmm i see
If you're just trying to learn to make a mod, probably best to start with a pz mod tutorial or looking through the files of another, simple mod
ok so to edit lua files i have to decompile the .class files and then work on them
no, that's java
oh damn
.
or is editing the game's vanilla code used a ton
like this one π
i even wonder if what i want to do is in the luas
bcs it seems like something that would be out of scripts files
but it isn't there lol
@hearty dew is there a place I can find all these tools you keep posting from time to time? Maybe also add a link to the modding section of wiki.
I need descriptions. Not guides
But as I understand
You can decompile the java and read the code. That's about it as far as understanding the java methods
There's no descs
Also looking at usage examples
I've only posted snippets in here so far
Can I break out of this folder? I tried ../dev/lib/filename or c:\path\to\ or c:/path/to/
It's ok when it's not possible for security reasons or so... Thiniking about that I wouldn't make it possible if I did the stuff...
Can anyone help me make this work as intended?
bat = getPlayerInventory(0).inventoryPane.items[getPlayerInventory(0).inventoryPane.joyselection + 1]
-- intention: get bat item from inventory slot highlighted by joypad focus.
-- result: returns a table of some kind.
print(bat.name)
-- intention: print name of inventory item I grabbed.
-- result: prints "Baseball Bat" (success?)
getPlayerInventory(0).inventoryPane:doContextualDblClick(bat)
-- intention: Trigger a double-click action on the bat in the player's inventory by sending the item to the doContextualDblClick event.
-- result: Nothing happens (no errors).
What exactly I should decompile and how?
Not with that api, no. I don't think any of the writers allow you to get out of that folder. Some of the readers do
This tutorial is still 100% working. I did this just the other day.
https://github.com/Konijima/PZ-Libraries
Fully understandable...
http://www.javadecompilers.com/, the class files in Steam\steamapps\common\ProjectZomboid\zombie\ are usually what you want to decompile
Thanks A LOT
Man
Ure brathetaking
They all have checks like```java
if (string.contains("..")) {
DebugLog.Lua.warn((Object)"relative paths not allowed");
return null;
}
except this one is missing the check:
```java
public static LuaFileWriter getSandboxFileWriter(String string, boolean bl, boolean bl2)
Maybe the LuaFileWriter has some check internally, idk, but you might try that
In Konijima's tutorial, the decompiled build folder appears on the right side of the photos. My decompiled build folders were on the left side of my screen. Just FYI.
Was confusing for like 10 seconds.
I'm fine with the restrictions... Just created a subfolder lib and it already starts working...
I have no idea what that is, where do I find it.
I mean, I've only pasted some code in this channel
like this
btw anyone know how the game correlates an items atribute while being crafted to a certain level of a skill
like how much hunger it will reduce based on cooking
or how high the maintenance of a spear goes up with carpentry
i've tried looking at the lua for recipes or the scripts
can't find anything
those seem like very useful tools for debugging
I'm one step further... First I include your Utils file with the write stuff and then I created a file with the following code:
for i,v in pairs(_G) do
if type(v) == "function" then
SoulUtils.writeFile("lib/exposedFunctions.lua", "function " .. i .. " (var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12, var13, var14, var15, var16, var17, var18, var19, var20) end\n", true, true)
end
end```
Added this under VS Code as Library for the workspace and now the functions are known...
For example:
```function SoulMod.Test(key)
local player = getPlayer()
if key == Keyboard.KEY_NUMPAD1 then
local cell = player:getCell()
if not cell then return end```
The getPlayer() is now an accepted function. But of course player:getCell() is not... Do you have an idea how I can generate the java objects? Is this even possible? Do you think it should be possible by converting the "Grand Solution" to a lua file? I'm not sure if this even doable because the : also means the first parameter is self in lua.
--[[
Usage example:
local function func(arg1, arg2)
print(tostring(arg1))
print(tostring(arg2))
end
local debouncedFunc = MxUtils.debounce(func, 5000)
debouncedFunc("foo", "bar")
]]
MxUtils.debounce = function(func, timeout)
local intervalTimer = MxUtils.createIntervalTimer(timeout, nil, false)
return function(...)
local args = {...}
intervalTimer.intervalElapsedEventHandler = function(timer)
func(unpack(args))
end
intervalTimer.start()
end
end
--[[
Usage example:
local intervalTimer = MxUtils.createIntervalTimer(5000, function()
print("5 seconds have elapsed!")
end)
intervalTimer.start()
-- ...
intervalTimer.stop()
intervalTimer.intervalInMilliseconds = 15000
intervalTimer.intervalElapsedEventHandler = function(timer)
print("15 seconds have elapsed, but it will be 25 seconds next time!")
timer.intervalInMilliseconds = 25000
timer.myData = timer.myData or {}
if not timer.myData.doneSomething then
-- do something
timer.myData.doneSomething = true
end
end
intervalTimer.autoRestart = false
intervalTimer.start()
]]
MxUtils.createIntervalTimer = function(intervalInMilliseconds, intervalElapsedEventHandler,
autoRestart, pollingEventName)
local timer
timer = {
intervalInMilliseconds = intervalInMilliseconds,
intervalElapsedEventHandler = intervalElapsedEventHandler,
pollingEventName = pollingEventName or "OnTick", -- Consider Events.OnTickEvenPaused
autoRestart = autoRestart == nil or autoRestart,
poll = function(tickCounter)
local time = math.floor(os.time() * 1000)
if os.difftime(time, timer.nextIntervalTime) >= 0 then
if not timer.autoRestart then
timer.stop()
end
timer.nextIntervalTime = time + timer.intervalInMilliseconds
timer.intervalElapsedEventHandler(timer)
end
end,
stop = function()
Events[timer.pollingEventName].Remove(timer.poll)
timer.isRunning = false
return timer
end,
start = function()
timer.nextIntervalTime = math.floor(os.time() * 1000) + timer.intervalInMilliseconds
if not timer.isRunning then
Events[timer.pollingEventName].Add(timer.poll)
timer.isRunning = true
end
return timer
end,
}
return timer
end
local function func(arg1, arg2)
print(tostring(arg1))
print(tostring(arg2))
end
local debouncedFunc = MxUtils.debounce(func, 5000)
debouncedFunc("foo", "bar")
debouncedFunc(1, 2)
debouncedFunc("I", "win") -- Only this one is called 5000ms later
I changed the interval timer a bit, and it fit into being used for debouncing a bit better, I think
Amazing job, I like this looks so clean!
It is possible to get the methods and fields from the java objects, yes. #mod_development message does that and prints them out.
I'd have to know a bit more about how your autocompletion system works in order to know how to relate the return types of each global function to the appropriate method/fields. Lua isn't statically typed, so it isn't immediately clear how that autocompletion system does it (maybe there is a way you can annotate each function to say this returns an "IsoPlayer" and also give it another file that says "these are the IsoPlayer functions to use for autocomplete", but I'd have to dig into it to see how it accomplishes that for lua since lua doesn't have a static return type for each function (in fact it can change at runtime)
Also, you could iterate over __classmetatables. In each field, the key is a java Class (so can use getName(), I believe) and the value is the metatable for that type (containing the instance methods).
static methods and static fields are stored in the table that kahlua generates when the type is exposed e.g. zombie.characters.IsoPlayer. Could iterate over those starting from the namespace roots e.g. zombie, fmod, etc
I'm relativly new to VS Code. But so far I found out that I just can add a lua folder in my case "D:\Games\Steam\steamapps\common\ProjectZomboid\media\lua" to the library folder and all the stuff in there is known now.
After this I thought: oh cool, maybe I can just create a lua file for the exposed stuff and add it also as a library folder... oh accidently exposed my name...
So thats were I'm standing now... Maybe there are better ways... The additional Library folder of course will never be included in zomboid at runtime. I just thought about it to fake the exposed stuff in one or more files.
Posted the image again. Didn't managed to replace it in the message above...
When doing that, is vsc's autocompletion smart enough to know that the return value of one function has these functions to autocomplete but this other function's return has these other functions? Or does it just give you all functions as autocomplete options all the time?
I'd like to add "step in shit" feature to Excrementum mod. What do you think about a good balance? By now chances are:
Running = +5%, Sneak = -5%.
Clumsy = +10%, Graceful = -10%.
Unlucky = +5%, Lucky = -5%.
Drunk (level 3 or 4) = +15%.
Tired = +5% (level 1), +10%, +15%, +20%.
Short Sighted = +2% with glasses or +8% without glasses.```
The base chance does not make any sense to me... What does the 10% mean? I can understand relative percentages but the base is incomprehensible...
1 / 10 steps you land in shit?
Seems excessive if so
would make more sense to check zones and surrounding, like toilets have high chance
Somewhing like that? On the ISContextManager. I only had the chance to select getInstance()
Let's say there is a door and feces on the floor. 10% means that you step in it while you are going over it, i.e. the chance counts when you enter in the square with feces.
Ahhhh that makes sense. Not bad. Would be cooler if you could make it based on proximity to a visible object.
Not sure if that's possible
wouldn't sneaking have more chance then, like army training literally has you face in shit
I would prefer to avoid feces mainly by consciousness rather than RPG mechanics, but the idea of being able to get annoyed by stepping in it is classic
Will the smell attract zombies or something?
Or just make your character unhappy?
No, the idea is while you're slow you're less likely to step wrong
We're not army-crawling in the game
Anyway I need to take a break. Hopefully I'm back in an hour or so π but thanks again for your support... If you have an idea or hint how I can reformat the whole output of _G just let me know...
considering you already have feces, the chance should be very high. Make people go around.
Oh, nice. What vsc plugin provides that? Do you know the name?
that one?
Sadly, world_item:getX() is integer. And I'm not sure how to get real coordinates.
I think he is taking about sumneko lua
So that has some info on how to annotate functions
I mean given the limitations of the system, it sounds like a fun optional addition to the mod to me. Especially if the smell would draw zombies or something.
Would be nice to give a way to clean it up instead of taking your chances @undone elbow
Presumably the autocompletion system makes use of that
Oh I found!
world_item:getWorldPosX()
I'm not sure how it works all in all. I installed the following plugins:
For zomboid I can't (or at least don't) use the debugger. So it's only the sumneko Lua Language Server and VSC itself. I just added the folders as libraries to the Workspace Settings...
So these won't affect. Too far))
Okay, uhh...
STACK TRACE
-----------------------------------------
function: JarredFoodAdjuster.lua -- file: JarredFoodAdjuster.lua line # 4 | MOD: Jarred Food Spoilage Adjuster
ERROR: General , 1666813865695> 92Γ‘621Γ‘841> ExceptionLogger.logException> Exception thrown java.lang.RuntimeException: Object tried to call nil in JarredFoodAdjuster.lua at KahluaUtil.fail line:82.
ERROR: General , 1666813865695> 92Γ‘621Γ‘842> DebugLogStream.printException> Stack trace:
java.lang.RuntimeException: Object tried to call nil in JarredFoodAdjuster.lua
at se.krka.kahlua.vm.KahluaUtil.fail(KahluaUtil.java:82)
at se.krka.kahlua.vm.KahluaThread.luaMainloop(KahluaThread.java:973)
at se.krka.kahlua.vm.KahluaThread.call(KahluaThread.java:163)
at se.krka.kahlua.vm.KahluaThread.pcall(KahluaThread.java:1980)
at se.krka.kahlua.vm.KahluaThread.pcall(KahluaThread.java:1782)
at se.krka.kahlua.integration.LuaCaller.pcall(LuaCaller.java:76)
at se.krka.kahlua.integration.LuaCaller.protectedCall(LuaCaller.java:117)
at zombie.Lua.LuaManager.RunLuaInternal(LuaManager.java:559)
at zombie.Lua.LuaManager.RunLua(LuaManager.java:505)
at zombie.Lua.LuaManager.RunLua(LuaManager.java:491)
at zombie.Lua.LuaManager.LoadDirBase(LuaManager.java:334)
at zombie.Lua.LuaManager.LoadDirBase(LuaManager.java:261)
at zombie.network.GameServer.doMinimumInit(GameServer.java:1405)
at zombie.network.GameServer.main(GameServer.java:684)
LOG : General , 1666813865711> 92Γ‘621Γ‘848> -----------------------------------------
STACK TRACE
-----------------------------------------
function: JarredFoodAdjuster.lua -- file: JarredFoodAdjuster.lua line # 4 | MOD: Jarred Food Spoilage Adjuster
What did I screw up
Give me a second I verify this....
local recipes = ScriptManager.instance:getAllRecipes()
for i=0, recipes:size() - 1 do
local recipe = recipes:get(i)
local recipeItems = recipe:getSource():getItems()
if recipeItems:contains("EmptyJar") and recipeItems:contains("JarLid") then
local item = recipe:getResult()
item:DoParam("DaysFresh", 274)
item:DoParam("DaysTotallyRotten", 365)
end
end
@type and @class might be what you want to look at to annotate to support java types
and @return and @param
I just tried on one of my lua functions. By typing 3 dashes --- I can autogenerate the function stuff and then I can read it when I use it.
---@param tbl the table
---@param maxDepth how deep it goes
---@param indent any ident stuff
function SoulMod.shared.tablePrint (tbl, maxDepth, indent)
I'd look at line 4 and print out the variables / table fields you are attemping to call to see which is nil
Can I just "Print" the whole Recipe?
You can use #mod_development message to print it out
But I really need a break now. Hopefully you are still online later π
@hearty dew You are making a lot of amazing utilities, maybe it's time to put all of them in a github repo and as a workshop item π€
So lets say I have 3 items that all will share the same code..
What can I do to like "if var = ALLITEMS" instead of "if var = item1 or var = item2 or var = item3"
Okay, so by breaking up line 4 I found that it nils on getItems...
Also I don't understand what you suggested to me
You'd need to write a function to do that ```lua
local isOneOfThese(lhs, rhs)
if type(rhs) == "table" then
for _, value in ipair(rhs) do
if lhs == value then
return true
end
end
elseif --... other cases
else
error("wtf is rhs")
end
return false
end
if (isOneOfThese(var, {"foo", "bar"})) then
print("yay")
end
something like that
I've seen people use the Tag that are defined in the Item.lua (i think), isn't that a much simpler way of doing it?
Yes, you could use some java method that does it for you
Or like making an array possibly? Items = { Item1, Item2, Item3 }
Not super into LUA which is why i am asking haha
That's what the above code does
If you are dealing with java objects, == for equality comparison may not be what you want to be use though.
If you have a more specific situation, maybe someone could provide a more appropriate solution e.g. trying to check if an item has certain tags or certain name, etc
Oh it's not java objects, it's legit just strings I'd iterate through
So this would work with lua strings
Anybody online right now have any way to trigger a call to equip an item in your inventory manually?
oh, I think I know
GetSource returns me an array, not an object
findSource returns me the object...
GetResult does give me the result object...
It didn't NRE now so I guess that's progress
l.inspectJava(ScriptManager.instance:getAllRecipes():get(0), "Source")
If I'm running using Alt key, player:IsRunning() is false.
That's how you can use that function to see what those methods return
Ah, I see...
Lmao well I just Used my bat.
Result: Bat vanishes from inventory, but still have it...
And can still swing it...
100/100 will love, publishing now
lol
lol I think it did the breaking animation on 1st whack but remained in existence
So it became indestructible
By virtue of defying the Matrix
magic bat
OKAY
To make my bat equip itself, I need the bat object from getInventory():getItems(); then I can simply call getPlayerInventory(0).inventoryPane:doContextualDblClick(bat), and voila, the bat is equipped. The catch is that the index of the bat in the ArrayList returned by getItems() does NOT match the index returned by getPlayerInventory(0).inventoryPane.joyselection... So my last little mission here is to figure out how to translate the bat as getPlayerInventory(0).inventoryPane.items[getPlayerInventory(0).inventoryPane.joyselection + 1] into the bat as getSpecificPlayer(0):getInventory():getItems():get(10) in order to use the highlighted item in the double-click call...
If anyone knows the answer, feel free to chime in... haha
that is.. convoluted more than it has to be iirc
can't u just find the item in the inventory and set primary to it
Well it sounds so simple in English, but I do not know how that looks in Clusterfuck.lua
(the favored library of PZ)
My goal is not simply to equip an item with a given name
I have not explained my goal well, clearly
My goal is to equip the item that I am actively focusing with my joypad.
(it began before that but no worries)
yeah that's gonna be more irritating
Exaaactly
The link between what I'm highlighting with joypad and the actual item data is not obvious
I can get real item data easily from my player, but I cannot easily determine what I'm highlighting
I see that InventoryItem has an ID, but getPlayerInventory(0).inventoryPane.items[getPlayerInventory(0).inventoryPane.joyselection + 1] does not have an id
and isn't even a proper InventoryItem
but getPlayerInventory(0).inventoryPane.joyselection + 1 IS the correct location in inventoryPane.items of the bat.
I COULD use the name of the item
might mistarget
The item's name is accessible
Exactly
I could target an alternate bat
It would not be ideal
what type is the result in the ui layer anyway
Having two unique indexes for the items in my inventory is just one of those special benefits of Clusterfuck.lua
table
huh.
Well fair
But print(type(bat)) also returns "table"
So I have no better info
Afaik its only accessible field is "name"
bat.name = "Baseball Bat"
yeah cuz type is ignorant of kahlua
No WONDER they didn't give us gamepad players a way to activate double-click using our controllers
but it would usuuuuually say something wonky rather than table
like userdata or something
these bits don't seem to be in the javadocs
i'd dig into the decompile
and look at the types returned by items
inventoryPane.items
Right
Lemme see if inventoryPane.items exists in my decompile
Not even inventoryPane exists in camel case
Only shows up in LuaManager.java in Pascal case.
LuaManager is where it maps stuff to lua
so
go look at that
and see what it's mapped to ig
lol only appears here
LuaClosure var1 = getDotDelimitedClosure("ISInventoryPaneContextMenu.dropItem");
caller.pcall(thread, var1, (Object)var0);
}```
Must be Lua side
Ugh why two different indexes there has to be a connection point right?
I mean the gamepad can activate most of the item functions that mouse can
There has to be a way it grabs the actual item object
Ugh
Aha! @weak sierra
for k, v in pairs(bat) do print(k) end revealed secrets!
gud
i think i got it right
setlla
ah ty
mhm
buahaha it's in bat.items[1]... that's the "item" I actually need.
YYYEEEEESSSS @weak sierra
grats
x3
glad i could poke u in right direction
Get Joypad-selected item and equip it:
inventorySelection = getPlayerInventory(0).inventoryPane.items[getPlayerInventory(0).inventoryPane.joyselection + 1]
item = inventorySelection.items[1]
getPlayerInventory(0).inventoryPane:doContextualDblClick(item)
Honestly the key was randomly Googling how to dump the keys of that table in Lua.
That is a crucial trick I will not forget.
Now, to integrate!
If I have a table like this:
local ElectricHeaterObject = {
itemType = "ElectricHeater",
itemName = "Electric Heater",
heatRadius = 15,
heatTemperature = 30,
}
Couldn't I technically call ElectricHeaterObject.itemType and get the string "ElectricHeater"?
For some reason it keeps giving me nil
yup
Yeah that's me hahah, hi!
If I had the table in another lua file, HeaterSettings.lua
And I just use require "HeaterSettings" wouldn't that also be able to be used in the new file?
can also do ElectricHeaterObject["itemType"]
Oh yeah that looks even better
not if it's local
So I would have to remove the local part?
are u trying to reinvent sandbox options?
:P
or is this for an individual heater's settings
It's for a global heater setting
Thank you, couldn't have done it without this discord lol β€οΈ
would this change names
i couldnt of made my mod either
ive been watching it, will probably add it to my server when it's a bit further along
The Heater Mod? β€οΈ
winter is coming on a server i play will ask soon
Yay! Will be using it on my own once it's more stable too
and when indoor heaters are not battery powered
We're doing crazy weather conditions for Season 2 which is why I actually developed the mod hahah
lol
I have the generator heater coded already actually
I resorted to car batteries being used for now instead of regular batteries.. Still a duct tape solution but that has to work until I get along with coding the UI Menu for it
OK that actually worked
I'm crediting you UdderlyEvelyn
You want me to credit some other name? Or is that what you use
If I want a message to pop up above the players head could I just use player:say("Hello World!")
@weak sierra omfg I am jacked about this final touch of awesome for this interface mod...
About to test it
@thick karma this isnt an option in the eng ver only Russian will this change names ?
works in english with _EN
DisplayName works if a language doesn't have a translation file
a lot of steam deck users will love u for this
im sure
tysmm
np
i also have the slow learner trait
how
do i change it
i want to change the name
in eng
bc this is the only thing in the eng file
When I found out y'all could double-click to use and equip items, I was so jealous I went supernova and became a new galaxy.
I already had your inspectJava Util π So I printed out the whole IsoPlayer object via inspectJava(getPlayer()). I have to study the inspectJava source code to fully understand whats possible. Are the Java classes also in the _G table so I can loop through them?
@weak sierra im sorry but i dont really understand what you meant
man i think i might give up on my mod haha
i just can't find the parameter i'm looking for
@blissful salmon Yea, they are in _G in these two ways
it was a fun learning about modding
also thank you soul for helping me so much β€οΈ
I almost forgot... About the sound problem: I didn't understood what you meant in your last post with "handle that case specially". Where should I start for this approach?
I'll already tried to do it with commands from server to client. But I never achieve to hear the sound from father away. (But I'll test this again because I already tested a lot of stuff and maybe I do something better this time).
My worst case scenario is to send the command to the client and calculate the angle between the zombie and the player. Then find the most appropriate square within hearing distance and play the sound from there (and play with the volume if possible).
Oh sorry... I fully missed that one.
Where should I start for this approach?
Meaning on the local client, do a distance calc from sound source to player, and if it is within range, just play the sound for the client (i.e. calling IsoPlayer:playSound() when any splitscreen players are within range of the zombie's x/y coords)
YES! It works! Joypad users rejoice! I can use the double-click shortcut by pressing start on the highlighted item!
My worst case scenario is to send the command to the client and calculate the angle between the zombie and the player.
Yea, that's sort of what I mean. Not sure if the angle is important (if it does surround sound)
(start cannot open menu while inventory is visible on Joypad (in vanilla))
Ok... very similar to the way I tried to describe...
i still cant change name
yeah
cool
i think i might give up on mine
i made stakes fixable but i can't do the third step
where the maintenance is boosted by your level of carpentry
i tried looking at the scripts or the luas and can't find it@tawdry solar π
i did
ill look again
thank you
but you don't have to if it takes a lot of time btw
i don't want to bother you that much
In which way do you want to boost it?
do they? I didn't know that. So the spear has a smaller chance to loose durability if you have a higher level of carpentry?
yes
or don't you talk about the maintenance skill/perk?
ah...
Today I go over all of the skills in the build 41 branch of project zombid, I hope yall pick something up from this guide! :D
0:00 Intro
0:40 Passive Skills
1:28 Agility
2:56 Combat
4:03 Crafting
11:06 Firearms
12:05 Survivalist
Project Zomboid is an open-ended zombie-infested sandbox. It asks one simple question β how will you die?
In the t...
i've heard other people say it but this is the only video that says it
the lua file is /media/lua/server/recipecode.lua
and the function for the spear is:
local conditionMax = 2 + player:getPerkLevel(Perks.Woodwork);
conditionMax = ZombRand(conditionMax, conditionMax + 2);
if conditionMax > result:getConditionMax() then
conditionMax = result:getConditionMax();
end
if conditionMax < 2 then
conditionMax = 2;
end
result:setCondition(conditionMax)
for i=0,items:size() - 1 do
if instanceof (items:get(i), "HandWeapon") and items:get(i):getCategories():contains("SmallBlade") then
items:get(i):setCondition(items:get(i):getCondition() - 1);
end
if items:get(i):getType() == "SharpedStone" and ZombRand(3) == 0 then
player:getInventory():Remove(items:get(i))
end
end
end```
so you have to make your on lua file with your adapted function of this.
learn from you mistakes
In this case you should try to find the same file again to check why you search didn't give you any results.
@weak sierra
getCell():getGridSquare(x, y, z):isVehicleIntersecting()
off of IsoGridSquare
k foud it
thanks
-- get the spear, lower its condition according to woodwork perk level
-- also lower the used knife condition
this isn't code right?
it's just words
-- means comment
ok ok thank you
Know if there is a way to force generate a chunk server side without having a player visit it personally?
How can I print a table? Currently getting like Table 0x32938293823 in the console
if you have to test/debug stuff you can take some stuff out of your code by this and later put it in again by removing the comment.
Or most important you should write in comments what your code does. So you and maybe other have an easy live later.
ok
teleport the admin there
I think other have better stuff than me... But most often this is enough for me:
if not (type(tbl) == "table") then return end
if not indent then indent = 0 end
if not maxDepth then maxDepth = 2 end
if not (indent <= maxDepth) then return end
for k, v in pairs(tbl) do
formatting = string.rep(" ", indent) .. k .. ": "
if type(v) == "table" then
print(formatting)
SoulMod.shared.tablePrint(v, maxDepth, indent+1)
else
print(formatting .. tostring(v))
end
end
end```
so that means means that the max condition will be boosted by carpentry
and that the knife used to make the spear will lose durability
and sharpenedstone
interesting
what would you put in maxDepth and indent?
Like for quick testing purposes
True but server side would be idea.
you can have sub tables and in worstcase loops... so you can put in for example 3 for the maxDepth and in general you don't have to pass an ident.
Sweet! I'll test it
the ident number is how many repeats of the spaces are printed.
But it doesn't do metatable stuff....
I have to check the code π give me a second...
i can send it here
function Recipe.OnCreate.CreateSpear(items, result, player, selectedItem)
local conditionMax = 2 + player:getPerkLevel(Perks.Woodwork);
conditionMax = ZombRand(conditionMax, conditionMax + 2);
if conditionMax > result:getConditionMax() then
conditionMax = result:getConditionMax();
end
if conditionMax < 2 then
conditionMax = 2;
end
result:setCondition(conditionMax)
for i=0,items:size() - 1 do
if instanceof (items:get(i), "HandWeapon") and items:get(i):getCategories():contains("SmallBlade") then
items:get(i):setCondition(items:get(i):getCondition() - 1);
end
if items:get(i):getType() == "SharpedStone" and ZombRand(3) == 0 then
player:getInventory():Remove(items:get(i))
end
end
end
@blissful salmon
im also using this as a kind of way to learn coding haha
you don't have to send me the code again. I just need to have a look to confirm your statements...
ok ok
So the table I'm grabbing is from:
local invItem = self.object:getItem()
local args = heaters[invItem:getID()]
sending the args over the server and getting heaters[args.id]
I'm then doing the table on heaters[args.id]
Values that I find in here, how would I grab them? Say I have variable in there called itemType, could I call it with heaters[args.itemType]? Or would it be heaters[args.id].itemType?
Found out it was heaters[args.id].itemType. Thank you!
ayeee guys, im looking for some decent mods yall have recommendations? specifically PvP faction mods but anything helps
The code does in the first part some calculations for the condition and the sets it to the result with result:setCondition(conditionMax)
after that the code goes through the provided items and checks if its a knife with some conditions (category etc.) if yes it lowers its durability. If the item is a SharpedStone then it will be removed from your inventory.
ok
What I dont know for sure is which items are passed to the function? Maybe someone else can tell you this if needed... But I think you can achive your goal just by copy the function and adapt...
ok ok
ill try changing some things
like i would like to make it so that making the stake take less damage to the knife
but it says getcondition() -1
so is that the smallest unit
can i put -0.5 or something
Did you try to print the table? tablePrint(heaters[args.id])
If it's a javaobject I'm not sure if my simple function can print it.
It worked yes, I got it printed!
Now I'm just struggling with if/ifelse and what not π
it's the smallest. But you can make it random by using somethink like:
if ZombRand(3) == 0 then
items:get(i):setCondition(items:get(i):getCondition() - 1);
end
like the random chance you lose the stone...
so zombrand is just a random value?
What exactly is the problem with if / else?
if args then
if args.state == "On" then
sendClientCommand(self.character, 'heater', 'turnOff', args)
elseif args.itemType == GeneHeaterObject.itemType then
if sq:haveElectricity() == TRUE then
sendClientCommand(self.character, 'heater', 'turnOn', args)
elseif sq:haveElectricity() == FALSE then
print("This is a heater that gets power from Generator. Can't activate due to no generator nearby!")
end
else
sendClientCommand(self.character, 'heater', 'turnOn', args)
end
end
Okay so I'm getting very fucked up in all these if/ifelse statements π
So basically normally allow the item to be turned off/on works. It even works with above code.
What I need is two checks so first:
- Is the item a specific item? args.itemType = GeneHeaterObjec.itemType
- Does the square it's on have electricity?
If both yes turn on.
If no elec on square display print msg
between 0 and the number you give... so if you generate a randomnumber with 3 the possible values are: 0,1,2 and if you compare this to 0 then you have 1/3 chance that the condition is true...
Im curious can you only mod with lua or is java an option too?
dont touch java, java is disgusting. but basically, yeah u can modify the vanilla base files. but obviously u have to somehow share these modified files to the clients if it is client side code as well.
well then thank you, for doing the jobs that i dont wanna do π
Omg
that's so smart
you are a genius
if i release the mod on the workshop i'll probably just say that you made it lmao
you helped me so much
Do they not offer it for security reasons?
for moding purposes they provide their api by using lua. if u want to access stuff that is not provided by the api and neither by patching java functions with lua, then u can modify the original java files. but i think u need a decompiled version of the game files first.
and the java files are not checked for checksum afaik. so that can maybe introduce problems. no there is no java loader afaik.
I would use fernflower if i was interested
why not just use lua?
i feel like the only limiting factor is the sparse documentation and what is provided by the lua / java api globally or by some game manager / service.
but in that specific problem case this awesome community has helped me so many times
I just find it interesting that a java game wouldnt have support for java modding
(hat to reformat it for me):
I'm a little confused why then separate this by elseif? The elseif is only checked if the first if is false.
if both of them have to be true you should use and:
if sq:haveElectricity() == TRUE and sq:haveElectricity() == TRUE then
most games that i am aware of use a scripting language for modding support. in most cases it is lua, sometimes a custom scripting language, and very rarely the original compiled language. scripting languages provide many pros for this purpose. but u probably know this.
there are a lot of reasons why using a compiled language for modding like c or c++ is very impractical, but with java you almost have none of those downsides, thats one of the biggest benefits of writing a game in java i find is that you can use the same source language as the game to write mods in
for clearness what elseif does is kind of a shortcut:
If you write something like:
if condition1 then
print(1)
elseif condition2 then
print(2)
elseif condition3 then
print(3)
else
print(4)
end
means
if conditions1 then
print(1)
else
if condition2 then
print(2)
else
if condition3 then
print(3)
else
print(4)
end
end
end
Someone correct me if I'm telling bullshit...
ok i will bite. what are the pros for using a compiled language like java for writing mods? as far as i know and can tell, lua is blazingly fast, u can also load it as compiled bytecode. object orientation, which java has, is just an abstraction trend/paradigm, and not necessarily needed. i would even argue it would prevent this seemless integration between different mods, which we have right now. what else does java provide? maybe open source frameworks, but they would blow any mod out of proportion.
With the right conditions you can customize and do so much more with java, youll get better perf, as an extreme example if the api was set up right you could write a mod that gives your game vulkan support or you could completely change how the world system works
@left citrus I made some mods for Valheim which is Unity -> C#. Most of the modder used the bebinex with hamony stuff to make mods. There we patched the methods for example manipulate the params bevor or the result after the Methods. What you always try to avoid is overwriting methods. And as far as I can say an often problem was the compatibility between mods.
But I don't know the true reasons the developers had. Maybe also because this is more sandbox like. So the lua can't do much harm on the pc... I didn't check how save it is. But maybe also a reason.
In Valheim I checked every mod I used because they can do a lot of stuff within the rights the user have on the pc...
yea patching sucks but you dont necessarily have to patch mods for it to work
idk if you know about minecraft but minecraft basically has two competing mod platforms, one that uses patches(fabric) and one that uses an api(forge)
Like I said I don't know the true reasons...
i can almost guarantee is security reasons, while you could send java code to the client from the server and have it be secure it would be very easy to fuck up
I'm also not aware of how good java can execute stuff in a sandbox like environment.
not very lmao
the only way to do it would be to analyze the imports of code and check for anything problematic before you run the code
What are you using to see the logs like this? is this some sort of cat tool? Like Tailviewer?
In windows, I prefer to setup cygwin and use tail -F Zomboid/console.txt in the terminal cygwin installs (mintty).
I think windows powershell supports ansi colors too, if you want to use that
Okay thank you!
How to tail a file in powershell
Also, when I mentioned that you should put all your code in a repo I hope you do, all your utils are gold
and they should be preserved if one day this channel gets wiped
just install linux smh
Maybe this is also an approach on windows.But I never tested it so far. Maybe its time to setup my WSL again π
https://devblogs.microsoft.com/commandline/integrate-linux-commands-into-windows-with-powershell-and-the-windows-subsystem-for-linux/
If I could get my in-game ANSI terminal a bit more performant, wouldn't need any of those external terminals :p
Thought I clicked the button to turn off the ping! whoops
Nah it's no biggie
Is this available for everyone?
could you tell me what you think
just post what you have...
function Recipe.OnCreate.CreateStake(items, result, player, selectedItem)
local conditionMax = 1 + player:getPerkLevel(Perks.Woodwork);
conditionMax = ZombRand(conditionMax, conditionMax + 1);
if conditionMax > result:getConditionMax() then
conditionMax = result:getConditionMax();
end
if conditionMax < 1 then
conditionMax = 1 ;
end
result:setCondition(conditionMax)
for i=0,items:size() - 1 do
if instanceof (items:get(i), "HandWeapon") and items:get(i):getCategories():contains("SmallBlade") and ZombRand(3) == 0 then
items:get(i):setCondition(items:get(i):getCondition() - 1);
end
if items:get(i):getType() == "SharpedStone" and ZombRand(6) == 0 then
player:getInventory():Remove(items:get(i))
end
end
end
i tried making the zombrandom thing for the blade
as well as doubling the halfing the chance for the sharped stone to disapear
the thing is idk if for example
zombrand(3) is actually 4 values or 3
like 1,2,3 or 0,1,2,3
No. I need to try to find a better way to read output.txt. Reading from file is too slow. It blocks the ui thread and gets kind of bad if there are more than 10 lines that are written at once
it's actually 0,1,2
It is 3. It should be 0,1,2 as possible outcomes. At least I think thats the case.
ok ok
thank you
i also changed some stuff on the code
local conditionMax = 1 + player:getPerkLevel(Perks.Woodwork);
conditionMax = ZombRand(conditionMax, conditionMax + 1);
if conditionMax < 1 then
conditionMax = 1 ;
end
bcs the condicion lower chance is 1 instead of 2 for the spear
you code should work. But the item Stake has a MaxCondition of 5 so with Woodwork 4 you always reach the max condition.
Since you start with conditionMax = 1 + level you never will get a lower condition with the current calculations.
conditionMax = ZombRand(conditionMax, conditionMax + 1); doesn't do anything, because ZombRand()'s highest possible value is 1 less than the second number
hmmm
what if i could do something like making it + the woodworklevel/2
the game only uses whole numbers
so idk if it could work
Thats true. When you hit something with the stake it's alway -1 but if I remember correctly this is also calculated with your maintenance level so uf your have maintenance level 1 the real lower chance will be one out of 3 I think. I'm not quite sure if it's the ConditionLowerChance + Perklevel * 2 but something like that I think.
hmmm
you can do it like math.floor(woodworklevel/2) to round down or math.ceil(woodworklevel/2) to round up
oh ok ok
did you function work so far? so it creats your stake with the condition you want?
im still writing it
i was trying to make it by myself since i also want to learn about it π
Just take your time.
i'm still taking the information you guys have given me
i think im going to work on it
tomorrow
it's getting a bit old
i mean
late
This channel has been active today. I normally sit down after work and read everything I missed but I had to start skimming this time
Did see someone talking about me, I hope they figured out what they needed
That's why we need forum.
there is a forum
Not that forum)
For the record, since I can't find the conversation again but maybe they'll see this, its not really viable to find the storage capacity of the trunk of a vehicle from the script. Its there but there are no get functions to retrieve it, so you'd have to do a bunch of reflection shenanigans to get the capacity. Not to mention it can be altered, so if you want that information you really should be getting it from the particular instance of the vehicle you're interested in.
Also, the trunk is called TruckBed on all the vanilla vehicles afaik
from base vehicle you just need to do vehicle:getPartById("TruckBed"):getContainerCapacity()
For modded vehicle that doesn't use the TruckBed ID, you'll have to figure out some other way to figure out which part is the trunk. Can't just look for containers, since chairs and the glove compartment, and modded roof racks and stuff all have capacity. Would likely have to write custom checks for each vehicle, bleh
@astral dune Hey there, I managed to get things figured out thanks to Xyberviri, UdderlyEvelyn, and Tyrir.
I do have new weird issue that I'm unsure why it's erroring.
script:getHasSiren()
Javadoc Project Zomboid Modding API declaration: package: zombie.scripting.objects, class: VehicleScript
i don't know why that's giving you an error, but from poking around with it myself it doesn't seem like that even gets set anyway
vehicle:hasLightbar() works for me
anyone have any thoughts on how to prevent melee in vehicles
like swinging weapons from inside of a vehicle?
that's being disabled in 41.78 anyway
Guys I think I'm in an abusive relationship with programming
I have a mod that takes the items on a dead body, adds them to a new container placed in the world, and then removes the corpse but I'm having difficulties getting the container's items to sync in MP.
If I just use container:addItem, none of the items are synced to the server so other clients see an empty container.
If I use container:addItemOnServer, only the first item gets added because I guess I am calling it too quickly?
So what should I be calling to properly sync the container's contents between the client who created it and the server.
How can I check if an item has a property defined at all? Like, how do I check if the item defines daysFresh?
perhaps transmitCompleteItemToServer() on the object?
I often use for example instanceof(object, "IsoZombie"). Is their a similar function which gives me the string of the object?
if they're exposed, there's java functions like that
getSimpleName() likely being the most useful
Thx, I'll test...
Be aware that getSimpleName() and getName() on the Class objects are only available in -debug mode
How can I check if an item defines a field?
Like, if it has "DaysFresh" set to any value?
Thats ok... I'll try to figure out what an event gives me:
print("onWorldSound: source -> " .. objsource:getSimpleName())
if instanceof(objsource, "IsoGameCharacter") then
print("IsoZombie: id -> " .. SoulMod.shared.getZombieId(objsource))
end
end
Events.OnWorldSound.Add(OnWorldSound)```
but I got a try to call nil on :getSImpleName()
wait, I'm confused how do you get others to see the container and not the items, you transmit the item before adding the items?
@vast nacelle
I use isoObject:sendObjectChange("containers") from server if that's of any use to you
local corpseItems = self.corpse:getItemContainer():getItems()
if corpseItems then
local bagItems = bodybag:getItemContainer()
for i=1,corpseItems:size() do
bagItems:addItem(corpseItems:get(0))
end
end```
I'm guessing AddWorldInventoryItem is sending the new item to the server before I start adding items.
Maybe I should instead create the container, then add it to the floor inventory after I've added the items?
@blissful salmon With these functions, I'll usually do something like```lua
f=function(...) l.inspectAll(...) end; Events.OnWorldSound.Add(f)
It will print out the types for most all java objects.
It will give you output like:```
LOG : General , 1666845987273> ----- arg 1/2: string -----
"done!"
LOG : General , 1666845987279> ----- arg 2/2: string -----
"yahoo"
yeah, it transmits the item
@vast nacelle
public InventoryItem AddWorldInventoryItem(InventoryItem var1, float var2, float var3, float var4, boolean var5) {
if (var5) {
if (GameClient.bClient) {
var14.transmitCompleteItemToServer();
}
if (GameServer.bServer) {
var14.transmitCompleteItemToClients();
}
}
Yep. That was really obvious in retrospect. Fill the container then add it to the floor. π΅βπ«
Thanks @fast galleon and @bronze yoke
So, how do I check if an item defines a field?
If you wondering... I just have no solution... I would have answerd you question if I know... π
Hmm, there are a ton of getters in the Item class... Maybe I can null check those
there is also a subclass for food:
https://projectzomboid.com/modding/zombie/inventory/types/Food.html
declaration: package: zombie.inventory.types, class: Food
I don't know if my jarred food is food
You can't exactly eat them straight away
Also it seems like it's for a specific item, whereas I crave general item definition... I think Item is the way
I just was to stupid to uncomment Events.EveryTenMinutes.Add(EveryTenMinutes) event/function so the zombie sound never happend π
Lets create one. Like the unofficial mapping discord server
But for modding related
What is the best way to get world time?
If I call player:getX() or the player:getSquare:getX() is this x an absolut value on the whole map or is this based on the current cell?
What I want to achive is to get a square with an offset to the player for example if I calculated: x = -5, y = 8
I want to get the Square: player:getX() + x, player:getY() + y
I want to track which player build what structure, and later allow them to only sledgehammer destroy their own structures. Which java function is called that has access to the structure/tile id that is being build? Does anyone know?
It's for the whole map. If you use player:getX() you get a float and not an int.
LETS GO I FOUND A DUMBELL
I know. In my case I can round a bit π or just use the square. But how can I get the new square then by my new X and Y?
ah, damn it... there is a Global function:
getSquare(double x, double y, double z)
Moddata probably
Anyone has a snippet of deleting items on the ground? I lost mine
@blissful salmon
for key, value in pairs(someLuaTable) do print (key) end
end```
Legendary
@undone elbow wonder if this works for items, too? Float to float comparison sounds more precise for the poo mod.
Can anyone tell at a glance why this code is hiding my inventory and loot when IR.mod.options.shortcutsCloseInventory is verifiably set to false and the Say(AND I got here...) line is not printing (which should confirm that the chunk with inventory:setVisible(true) is skipped)?
I've been hiding and showing chunks for over an hour (because game so slow to relaunch, and I'm using decorator functions in this mod)... Can't seem to identify the specific moment where inventory would vanish. Makes no sense. It seems like none of the code after inventory is confirmed visible should change that...
I don't get why you mentioned me here...
Oh I misread this my bad
Sorry just woke up
np π
Lol thought you said you would also like to know
In response to him
Obv you said nothing of the sort in retrospect
If have a problem when pressing F11 in debugmode. The debug window opens when I press F11 but it shows me no error. But it breaks on if not ISFastTeleportMove.cheat then return end But this isn't from a mod. Did anybody experienced the same problem?
Or is this just what I have to see by pressing F11?
Just default.
ok
No error indicated.
I was alway confused why it breaks there.
Well it doesn't break per se for me
It just opens and shows that file by default when you open F11
"breaking" is when your code stops running
The Lua has not stopped running in that file
I always think that file has an onKeyboardPressed and is the last thing executed.
does anyone know where i can find a site with all the pz commands for scripting
or a good guide on it
im trying to create an auto turret and all I have so far is a model
which I dont think ive imported correctly
hey guys..I'm tryin to make a function to add a context menu option to the wallet junk item. I've made it equippable (with double-click) but can't sort out how to add the contextual option to equip it. I had a script written that I couldn't get to work, got discouraged and deleted it and gave up. Unfortunately I obsess over crap like this and can't stop thinking about how to make it work. If I were to rewrite it, would anyone be willing to help me sort it out? I don't want to put myself through it all again just to end up in the same place.
sorry for wall of text. I have some mental issues that cause me to hyperfocus and obsess over things
How to create custom texturepacks?
There is also file with "tiles" extension. It seems that this file is needed for the texture pack to work.
One of us. One of us.
I deleted everything and told myself to just forget and cant think about anything else since.
You forgot to delete it from your brain
Worst part is its not even my mod, im just trying to help someone
Let me guess, your delete button isn't working?
I think its busted
I'm not sure how to add context menu options yet. if you ask any specific questions that I can answer along the way and I see them first, I'll probably answer you.
Hey that works for me. Someone elses input on any of it would help greatly
I would guess that the contextual option for items is added by ISInventoryPaneContextMenu.lua
@scenic cradle
In that class there is a function called ISInventoryPaneContextMenu.createMenu
Seems relevant
I believe it appears when you right click an inventory pane item
Thats what i was using actually
i have some code for this, let me get on pc real quick
Oh wow thank you
I could get the option to appear but it didnt work, plus it was throwing errors on any other items I rightclicked
local function onFillInventoryObjectContextMenu(player, context, items)
for i,v in ipairs(items) do
local item = v
if item:getType('desiredType') then
context:addOption('Custom context option', item, yourFunction, arg1, arg2, etc)
end
end
end
Events.OnFillInventoryObjectContextMenu.Add(onFillInventoryObjectContextMenu)
i have runned into problem
i used MX code for pills, all looks great but i can't use option to drain pill cointainer
Best ask in mapping, probably. There's a few videos showing all the steps.
Thank albion, Ill try this and see if i run into/create any problems
i fixed it by adding pills in front of name
do you guys also experience the behavior that the zombie amount and respawn gets less and less over time in MP ? we have set the respawn and and pop to static never changing values. But somehow 1-2 RL months later, the cities are sooo much less populated, even if no one has entered the server for a full day. we play with pop 0.8 and very strong zombies. so i guess this problem is more prominent in our case. we dont have any mods that mess with zombie respawn.
is wordzed still used? the download on the forums is dead
@weak sierra @bronze yoke @gilded hawk Pretty significant new update to Dawn of the Zed. Many improvements! Check the notes!
https://steamcommunity.com/sharedfiles/filedetails/?id=2875983658
Admins: Please disable the ability to hide halo notes in the new Dawn of the Zed Sandbox Settings if you do not like my solution for doing so! More details if you follow the link.
Aaaand... it's finally here! Interface Reflexes! (If you hate the name I'm honestly over it π€ͺ). Do you want to close those annoying pop-ups at server launch by simply aiming (or spamming B on a controller)? Do you need to get your HUD out of your face because a horde just burst through the door? Do you want to rapidly equip items in your inventory while you're playing with a gamepad? Do you want to fully customize all of that, deciding which windows you will or will not close in an emergency? Well, this mod is for you!
https://steamcommunity.com/sharedfiles/filedetails/?id=2880580885
oh i wouldn't know anything about that

How do you think the interface to something like this would look? I'm writing something to do this and curious how others might imagine the interface to it working
interface as in API or as in UI'
api
RequestData(commandName, callback)
RequestData(commandName, args, callback)
or something along those lines
actually could simplify that if the commandname matches a key of callbacks
in a table
to just RequestData(commandName, args)
with args optional
and a table of callbacks["commandName"] = function(args)
and maybe
RegisterCallback(commandName, function)

Mm, I think the premise of his statement was to avoid callbacks specifically since he wanted an interface to "wait for the reply before continuing"
that's irrelevant since the only way is callbacks
:P
has to be based on the command system
so
not really a lot of options
you can make it block on purpose
but there's no getting away from the idea that it is essentially a callback
since to react to the data and collect it it must run through a function in the receiving event
afaik
Yea, that's fine if the implementation uses callbacks, because that can be abstracted away to some degree. I'm just wondering about the interface that looks like it waits for a reply before continuing
i.e. what would be useful to others
Would it be possible to make it look like this (approximately)?
result = client.await(function(inputs))
And then just proceed when the input returns?
WipUtils.CommandModules.CrazyModule = WipUtils.CommandModules.CrazyModule or {}
WipUtils.CommandModules.CrazyModule.request = function(args, player)
print("request received "..tostring(args.callback).." "..tostring(args.callbackArgs).." from "..player:getDisplayName())
WipUtils.sendRemoteCommand("CrazyModule", args.callback, args.callbackArgs, player)
end
WipUtils.CommandModules.CrazyModule.callMeMaybe = function(args, player)
print("I was called maybe!")
end
function requestData(commandName, args, player)
WipUtils.sendRemoteCommand("CrazyModule", "request", {callback = commandName, callbackArgs = args}, player)
end
function testrequest()
requestData("callMeMaybe", {"this is crazy"}, getPlayer())
end
LOG : General , 1666895617765> 1,041,685,768> I was called maybe!
LOG : General , 1666895622165> 1,041,690,168> I was called maybe!
Yea, something like that I was thinking. Not sure what function does there. Is that an anonymous function passed in?
I was thinking you could send it any function name with its args
Maybe await(function, args) or something
Unless I'm misunderstanding the goal here
Then the function will send a server command, and then the server sends a command that tells code to continue from the await?
Or perhaps await will send it after the function has finished
I could imagine that being useful idk if doable
would be sugary to me lol
local function fn(context)
print("starting! waiting for 'go' message..")
context.waitForMessage("go")
print("done!")
end
local x = LUtils.createCoroutine(fn)
x.start()
-- I go on to do other things ...
-- later
x.receiveMessage("go")
Was thinking something like that
That's also great.
I would prefer awaitMessage but that's me hahaha
Not everyone would obv
You could do something like that, but it'd have to be inside a different context I believe (like in a coroutine). You couldn't (or wouldn't want to) block the main ui thread with an await call sitting there waiting on a network request that might not come
Right, I would imagine this would only be done in a function that was already done on its own thread...
I wasn't sure how you would spawn that in this environment, but I assume waiting for signals in general is not a thing in the normal flow of modding most things I see modded in this game
local function fn(context)
print("starting! waiting for 'work results'..")
local result = context.awaitMessage("work results")
print("got results "..result)
end
local x = LUtils.createCoroutine(fn)
x.start()
sendRemoteRequest(function()
local workResult = 1 + 1
sendReply(workResult)
end)
function receiveReply(result)
x.receiveMessage("work results", result)
end
LUtils.createCoroutine(fn) creates the thread?
It's that simple?
or you wrote that function?
Yea, I had the same thought, which is why I put this aside until @astral dune mentioned that statement above and piqued my interest again, heh
That's what I'm writing, yea
Trying to figure out the interface for it still though
Would be super nice. Looks legit.
I am so glad I waited to release Meditation lol
original way this mod worked was wonky a.f.
I am making it so much less demanding (system resource wise) now that I know how to add and remove tick events at good times and decorate more crap
It's gonna be doperino
Meditation is actually an AFK mod for online π
Sit on Ground = become invisible to zombies
(If they have not seen you recently and you haven't seen them recently)
may also become invisible to players, haven't tested / decided what I prefer
May be admin option by the time I'm done
Since pausing clearly is not going to work out in MP
Oh, cool. Didn't end up needing admin/higher privilege to become invis to zombies?
Might need to require people to disable an anticheat. I haven't fully tested that because I already disable anticheats 3 and 12 iirc, but my user had no issues becoming invisible with those off
I will confirm which anticheats need to be off before I release it
it's the callback 
my head is spinnin a bit, maybe someone else can give me some ideas for how to structure this
vehicle respawn mod, fires on player move with throttling
it triggers updates to the last seen variable of a vehicle if it's not set or if it's below X age, but if it's over X then it despawns it and asks the server to generate <some vehicle> at <a place in a zone in a cell randomly>
since that place may not be loaded, it tries, but if it fails it puts it in a table of things to check later
as players move around, it checks each newly loaded cell for any vehicles to spawn there via lookup
this all works great
