#mod_development

1 messages · Page 158 of 1

sour island
#

Just needs some whippingtraining

thin hornet
#

haha

lone nest
#

it aint happening unless PZ releases source code to public domain.

thin hornet
#

i was pretty amaze last time i ask it how to mod

sour island
#

you can decompile it - that's how the documents are made

cinder kindle
#

For a noob like me It kinda helps for errors in console.txt when I am lazy but otherwise I don't think so ded

thin hornet
#

but its not accurate enough

sour island
#

the modding tools and using an IDE will help avoid alot of issues

thin hornet
#

using pipewrench is the next step to detecting errors and having complete intelisense

cinder kindle
thin hornet
#

we can train a custom model

#

got invited to gpt-4 recently after applying to the whitelist

lone nest
#

please, if machines can feel pain, I would consider teaching it LUA to be cruel and unusual...

thin hornet
#

But honestly i wouldnt train gpt to code mods, but more to be a documentation helper

cinder kindle
#

Let's go, my first mod will be a complete abomination jaques_beaver

#

Konijima suddenly regrets having helped Pseudo

lone nest
#

happiness -60, "a little sad"

thin hornet
#

Well when you are hungry you gotta eat what you got...

cinder kindle
mellow frigate
#

is there already a blinking synchronization mechanism in PZ ?

thin hornet
lone nest
#

... apparently he wants to double down.

ancient grail
mellow frigate
# thin hornet what do you mean?

on complex interfaces, if many things can blink, you need a blinking synchronization. if you do not have one, users are bothered and have more difficulty to follow things. E.g. in planes all the things that can blink are synchronized

viscid drum
#
Events.OnRefreshInventoryWindowContainers.Add(function(_self, event)
    if event ~= 'begin' then
        return;
    end

    local playerObj = getSpecificPlayer(_self.player)
    if _self.onCharacter then
        local it = playerObj:getInventory():getItems()
        for i = 0, it:size()-1 do
            local item = it:get(i)
            local fullType = item:getFullType()
            local isWallet = fullType == "Wallet.Wallet" or fullType == "Wallet.Wallet2" or fullType == "Wallet.Wallet3" or fullType == "Wallet.Wallet4"
            if item:getCategory() == "Container" and isWallet then
                -- found a container, so create a button for it...
                containerButton = _self:addContainerButton(item:getInventory(), item:getTex(), item:getName(), item:getName())
                if(item:getVisual() and item:getClothingItem()) then
                    local tint = item:getVisual():getTint(item:getClothingItem());
                    containerButton:setTextureRGBA(tint:getRedFloat(), tint:getGreenFloat(), tint:getBlueFloat(), 1.0);
                end
            end
        end
    end
end);
thin hornet
#

oh like blinking lights

viscid drum
#

so its not quite working, maybe my item script isn't matching up?

mellow frigate
viscid drum
#
module Wallet {
    imports {
        Base
    }
}

module Base
{
    item Wallet
    {
        DisplayCategory = Container,
        Weight    =    0,
        Type    =    Container,
        DisplayName    =    Wallet,
        Capacity    =    1,
        AcceptItemFunction = WAcceptItemFunction.Wallet,
        Icon    =    Wallet_01,
        WorldStaticModel = Wallet,
    }
    
    item Wallet2
    {
        DisplayCategory = Container,
        Weight    =    0,
        Type    =    Container,
        DisplayName    =    Wallet,
        Capacity    =    1,
        AcceptItemFunction = WAcceptItemFunction.Wallet,
        Icon    =    Wallet_02,
        WorldStaticModel = Wallet2,
    }
    
    item Wallet3
    {
        DisplayCategory = Container,
        Weight    =    0,
        Type    =    Container,
        DisplayName    =    Wallet,
        Capacity    =    1,
        AcceptItemFunction = WAcceptItemFunction.Wallet,
        Icon    =    Wallet_03,
        WorldStaticModel = Wallet3,
    }
    
    item Wallet4
    {
        DisplayCategory = Container,
        Weight    =    0,
        Type    =    Container,
        DisplayName    =    Wallet,
        Capacity    =    1,
        AcceptItemFunction = WAcceptItemFunction.Wallet,
        Icon    =    Wallet_04,
        WorldStaticModel = Wallet4,    
    }

}
bronze yoke
#

your items are in module base

#

you closed the wallet module and then opened module base again

viscid drum
#

i tried it with base as well and it didn't work

#

i'll try swapping it to base again

thin hornet
#

add them to module Wallet

#

it wont overwrite the base wallet but you can replace the Base.Wallet in the distribution later

#

So your custom one spawns

viscid drum
#

I was overwriting the base wallets, should i not do that?

thin hornet
#

then make sure you actually have the Wallet.Wallet1 in your inventory and not the Base.Wallet1

#

You can but from memory i had trouble doing it that way

#

you can also change this:

local itemType = item:getType()
local isWallet = itemType == "Wallet" or itemType == "Wallet2" or itemType == "Wallet3" or itemType == "Wallet4"
#

cause anyway we check if its a container first:

if item:getCategory() == "Container" and isWallet then
viscid drum
#

ty, so i changed the item script

#

and now its working

#

wallet container shows up in the players inventory

viscid drum
#

haha, found a weird visual bug though

#

you can equip the wallet and then you get two loot icons

thin hornet
#

oh easy fix

#
if item:getCategory() == "Container" and not item:isEquipped() and isWallet then
trim mist
#

This is disgusting

#

Unfortunately, I can't think of a better way to determine if one is eating a bug. Apparently Insects don't have their own FoodType

#

and while their Icons have the prefix "Insect_" There doesn't seem to be a way to access that. Therefore.... ifs. lots of ifs

bronze yoke
#

you can use if condition or condition or condition instead of chaining elseifs

trim mist
#

that's fair. I didn't know if that would get prohibitively long

#

I was hoping I could get away from writing so many conditions lol

bronze yoke
#

you can add newlines in the middle for readability, or make it a function that returns true

#

a way i solved a similar issue recently was to parse the items during game load and add a tag to all items that matched the pattern

#

and then just check for the tag

trim mist
#

you know? That's a better idea. It would look a lot better if I could write "hasTag("Insect")" or "IsInsect(foodEaten)" rather than.... that

#

thank you Albion

#

and actually, while I have you here, do you know much about foods resulting from evolvedRecipes?

#

FoodType for those is also lacking. I could search the display name for a vegetable or "vegetable" for example, but it would look much the same. The tag idea wouldn't work as well for that I think

bronze yoke
#

i think they store their ingredients in an array, if you mean you want to include for example a soup with vegetables in it - i'd have to look into the source to see where exactly that's handled though

trim mist
#

I have it decompiled on my machine, if you have any clue what the class name would be, it could help?

bronze yoke
#

getExtraItems() and getSpices() (but you probably only need the former?)

trim mist
#

this seems to be about the right area. Thanks!

cinder kindle
lone nest
#

so calling
return BugTable["Catepillar"]
should return
charBodyDmg:setUnhappinessLevel(BeforeUnhapiness)

bronze yoke
#

that'd call it when the table is initialised, not when you access it

#

the table would store the return value, which is probably nil

#

a lookup table wouldn't be a perfect solution in this case since it checks patterns as well as checking for specific values but i do still recommend using them whenever you're checking a value more than once

lone nest
#

Hm, my approach is initialize all the Global variables (config-related) first and have all subsequent functions refer to them or update them as needed.

#

but yeah, you're right, i'm not sure what the context of his mod is.

#

i just saw "if-else" is disgusting and offered an alternative :P

fast galleon
#

It could be an acceptDisplayName table above though

lone nest
#

alternatively, he can assign an integer value to each of those ... bugs as "keys" and simply call set it as such

["Caterpillar"] = 60,
["Larva"] = 50
};

charBodyDmg:setUnhappinessLevel(BugTable["Caterpillar"]);
fast galleon
#
if acceptDisplayName[foodDisplayName] then
  --do the thing
end
bronze yoke
#

a lookup table should be used but the pattern usage means it's only part of the solution

fast galleon
#

agreed, checking type would be best probably

#

I have no idea where that is used

bronze yoke
#

oh i wasn't even thinking about that, display name definitely shouldn't be used

lone nest
#

well... lua doesn't have type check by default... but if you have VScode and the extensions installed, it'll give you warnings.

tawdry moss
#

trying to use a custom weapon mesh and it doesnt seem to be working, do i need more than this model definition script

neon bronze
#

Check your pathing maybe you messed up there

#

The mesh pathing starts at model_X

tawdry moss
#

pathing looms good

#

im going to bed ill ask again in morning

jovial urchin
# tawdry moss pathing looms good

Messed up a bit with naming yesterday, resulting in my doughnut mesh not showing. Problem solved by fixing name duplicates, well, that is if that was the actual issue. Don't remember what the conflict was between though.

And you may have to add 'scale = x' to your model script if your custom weapon mesh ain't correctly scaled at export.

tawdry moss
#

Right now it’s just invisible

fast galleon
# tawdry moss pathing looms good

here's what a functioning model would look like

    model FishFarmCraftMagazine { mesh = WorldItems/Magazine, texture = WorldItems/FishFarmCraftMagazine, scale =  0.4, }

*mod example

tawdry moss
#

I set the scale to be similar size as machete in blender and copied the model file from the machete, adjusting mesh and texture, but it isn’t working

fast galleon
#

start with exact copy of vanilla woking model, change things 1 by 1

tawdry moss
#

But I already have a model

#

I don’t wanna remake it

jovial urchin
fast galleon
#

I mean script model

tawdry moss
#

That’s what I did

#

It’s the machete script model

#

With the mesh and textures edited

#

I’m in bed rn so I’m not going to do more until tomorrow because 3 am by me

fast galleon
#

start with non edited values

drifting ore
#

Does anyone know if the latest mission systems framework is out yet? I read a few weeks ago that they were going to release it in a few days. That it was simpler than the previous one.

rancid tendon
#

query; what is the max non lethal sickness value? i’m sure someone in here knows

fast galleon
#

hello, person with non offensive nickname. I think it depends on the person's health, traits and other factors?

sand blaze
#

Hi there, Is there any place has all pz lua functions and documents as well?

fast galleon
#

Steam\steamapps\common\ProjectZomboid\media\lua

sand blaze
#

some lua functions exported from java might not be shown there...

fast galleon
#

They are not Lua function, they are java function.

craggy bridge
#

anyone know if someone has added Marmite already

nimble spoke
nimble spoke
fast galleon
#

Is there a mod that let's you use custom maps with challenges that are set on the main map?

*can easily be done by setting ```lua
challenge.world = "DEFAULT"

nimble spoke
#

It is mainly done through an editor called TileZed

ancient grail
bronze yoke
#

does it just add the file extension?

drifting ore
tawdry moss
#

how do i fix this

tawdry moss
#

i see some models use .fbx instead of .x, can they be used interchangably

tawdry moss
#

i dont know whats going on with this, the model isnt loading

neon bronze
#

Try without the attachment world maybe?

#

Or reload lua altogether

tawdry moss
#

its literally the machete scripting tho

#

just diff mesh and texture

nimble spoke
#

Is your texture inside the textures folder with that name? Is it a proper png image?

tawdry moss
#

its a png directly in the mod texture folder

#

no subfolder

#

okay this one which is literally just the machete script renamed isnt working

#

do i need to fuck with xml

viscid drum
#

so when I tried retexturing a pen that was a .x file I couldn't get it to work :/

#

but then again I don't exactly know what I'm doing

nimble spoke
tawdry moss
#

can i dm you the relevant files in a zip

#

cuz i genuinely have no idea what im doing wrong

minor pumice
#

hey guys! do you know something about the cell loading? I try to make the game load cells in front of direction player is moving when moves at 30 m/h or more

mellow frigate
#

Hi, I tried to use the lua native command 'next' but it was not recognized as a valid keyword in my PZ mod. Do you guys think I made an error or is there a specific reason for it not to be available in PZ lua ?

mellow frigate
bronze yoke
#

next isn't available in kahlua

#

never found out why but i've run into it too

fast galleon
#

no next, but we have table.isempty

coarse sequoia
#

where can i find all 3d models of wall, zombie ??

bronze yoke
#

media/models_x/

#

you will not find models of walls, the world is primarily sprites

winter thunder
#

And yeah, the file path Albion mentioned will take you to the actual 3d models used in game :)

drifting ore
#

How do I transfer poison power from one food item to another when it changes "states" via recipe system, I tried OnCreate and the way fish gets chopped up but doesn't seem to work.

``
function PoisonA_OnCreate(items, result, player)
local sjbulp = nil
for i=0,items:size() - 1 do
if items:get(i):getType() == "SJBulp" then
sjbulp = items:get(i)
break
end
end
if sjbulp then
sjbulp:setPoisonPower(sjbulp:getPoisonPower());
end
end

``

neon bronze
#

You need to set it to the result i think?

bronze yoke
#

yeah, you're setting the item you found's poison to its own poison

coarse sequoia
winter thunder
coarse sequoia
#

yes

#

i have pz moding tools

winter thunder
#

Go to your library, top left

#

Make sure this is clicked on

#

Then search for the PZ modding tools

drifting ore
#

I actually tried it first as a result but didn't work either.

winter thunder
#

When you launch it will ask you which to use, launch TileZed

coarse sequoia
#

ok, but I thought that TileZed and WordZed are only for creating maps, so you can also create models and program things for the game there, right? e.g. weapons

hoary widget
# winter thunder

Hey sorry to add on to this but just 1 question. Can those tools help me make clothing mods?

#

I'll let you help those 2 out first (so it doesn't get confusing) but just curious

winter thunder
#

No- You can use TileZed to specifically get access to the sprite sheets. Those are how all the little item icons in the inventory / the world tiles are stored. If you want to work on creating models, you need to use a 3d modeling software. Blender is the most common, easy to learn (from what I have heard), and can be downloaded for free online

ancient grail
#

No those are for mapping

winter thunder
#

@coarse sequoia

sullen thicket
#

Do you have any estimate of when the mod will be finished?

winter thunder
sullen thicket
#

I lit wanted to ask that 2 weeks ago but I didn't want to till you say something more about the mod hehe

#

sorry if that adds more pressure btw, take your time

winter thunder
#

@coarse sequoia @hoary widget

https://rentry.co/BluesModClues

#

Here is my little collection of stuff for PZ modding :)

#

(also- If anyone else has anything that you think should be added to that, please lmk! I want it to be a bit of a living doc for good resources haha)

hoary widget
winter thunder
#

Where cant you see your model?

#

In the program?

#

Or in game

hoary widget
#

In game

winter thunder
#

Did you make sure it was properly scaled?

hoary widget
#

It shows up on the list but it appears as a blue question mark

winter thunder
#

What were you trying to make?

hoary widget
#

I was trying to make a standard jacket

#

I was following this guide but idk why its not showing up

winter thunder
#

So you made the model. Did you also make an item file, model/texture file, and the xml file?

#

ALSO also- did you put a 3d model in both the model locations?

#

Also also also- It shows that ? because you didnt designate a sprite for it

hoary widget
#

I put one in the world and one in skinned/clothes

winter thunder
#

did you make the other files? You had to have made an item script, since it showed up in game

hoary widget
#

Yes but I'm thinking I made something wrong

#

I have a fileguidtable.xml, a Jacket_SteamGuide.xml , and SteamGuide_modelsItems.txt scripts

winter thunder
#

Well, if you wanna post your item scripts, your model scripts, and your xml - I can help :)

hoary widget
#

THANK YOU

winter thunder
#

Start with the Item and model scripts tho :) You know how to post inline code?

hoary widget
#

uhh no

winter thunder
#

Put these ``` on the first line. Paste in your code. Then end with another set of ```

hoary widget
#
<clothingItem>
 <m_MaleModel>media\models_X\Skinned\Clothes\Jacket_SteamGuide</m_MaleModel>
 <m_FemaleModel>media\models_X\Skinned\Clothes\Jacket_SteamGuide</m_FemaleModel>
 <m_GUID>ad678279-fc59-41c9-91d7-fd39033dbe1c</m_GUID>
 <m_Static>false</m_Static>
 <m_AllowRandomHue>false</m_AllowRandomHue>
 <m_AllowRandomTint>false</m_AllowRandomTint>
 <m_AttachBone></m_AttachBone>
 <m_Masks>13</m_Masks>
 <m_Masks>14</m_Masks>
 <m_Masks>3</m_Masks>
 <m_Masks>5</m_Masks>
 <textureChoices>Clothes\Jacketpadded\WhiteTexture</textureChoices>
</clothingItem>
winter thunder
#
It will look like this! 

Makes typing code so much easier :)
#

Oh cool

#

haha

hoary widget
#

Is there anything wrong with it, or should I just post the next one first?

winter thunder
#

Did you add a texture called WhiteTexture to that location?

coarse sequoia
#

I have a question, can I make a 3D model from this photo in blender?? because this is UV Mapping because I would like to change the appearance of the zombie

winter thunder
coarse sequoia
#

i can't find localization 3D zombie

winter thunder
# hoary widget like this right

Yeah, looks good. The base game xml files dont capitalize the word clothing. I dont think that would effect anything tho. So yee, post those scripts :)

winter thunder
hoary widget
#
module Base
{
 item Jacket_SteamGuide
 {
 DisplayCategory = Clothing,
 Type = Clothing,
 DisplayName = My First Jacket,
 ClothingItem = Jacket_SteamGuide,
 BodyLocation = Jacket,
 Icon = SteamGuideJacket,
 BloodLocation = Jacket,
 RunSpeedModifier = 0.89,
 CombatSpeedModifier = 0.96,
 BiteDefense = 10,
 ScratchDefense = 20,
 NeckProtectionModifier = 0.5,
 Insulation = 1.0,
 WindResistance = 1.0,
 WaterResistance = 0.60,
 Weight = 1,
 WorldStaticModel = JacketSteamGuide_Ground,
 }
}
minor pumice
#

hey guys! do you know something about the cell loading? I try to make the game load cells in front of direction player is moving when moves at 30 m/h or more
can't find any mod that uses similar mechanics or mess with cell loading

#

certainly there's one that works, but I don't know the name

keen silo
#

Hey guys @red tiger I need help making my mod modular

#

currently im getting an error

winter thunder
# hoary widget in scripts, or scripts/clothing

Ok yeah- That tutorial kinda 😬

So. The line "Icon = SteamGuideJacket," is looking for a sprite. Which, going through the tutorial- I dont think they had you add one...

If you wanna try it, I made a little tester icon that you can use. That way it shows up as something ingame too. Make sure the item is named Item_SteamGuideJacket.png and drop it right into the textures file of your mod

abstract sable
keen silo
#

attempted index: addSongs of non-table: null

#

The code is as follows:

RadioWavs.lua:

require "SoundFX/SoundFX"

local RadioWavs = {}

local RadioWavs.soundCache = {}

local RadioWavs.files = {}

function RadioWavs.addSongs(_guid,sound_name)
    RadioWavs.files[_guid] = sound_name
end

//Other local functions that dont matter

return RadioWavs

VRTVs_SoundTable.lua:

local RadioWavs = require "RadioWavs"

RadioWavs.addSongs("ce2f8a16-5c34-45ab-a0fc-42a45bae457d","29f94658-1439-4dce-b764-828960ae641a")
#

does anybody know what is wrong?

bronze yoke
#

are they in the same folder (client/shared/server)? and RadioWavs is the full directory (ignoring the lua/client/ part)?

#

the load order of the folders can cause requires to fail

keen silo
#

the folder is as follows:

lua/client/RadioCom/RadioWavs.lua
lua/client/RadioCom/VRTVs_SoundTable.lua

bronze yoke
#

you should be requiring RadioCom/RadioWavs

keen silo
#

oh

#

thx

#

do they have to be in the same folder?

winter thunder
#

Albion, you have any experience messing with the chat? Have an idea I wanna play with but I havent done much with it lol

hoary widget
neon bronze
#

Modded items dont have icons i the item list

winter thunder
#

Hi Haram

winter thunder
# hoary widget

Oh, true. Those are a separate sprite sheet with their own distinction. Try adding it to your inventory

neon bronze
minor pumice
hoary widget
minor pumice
hoary widget
#

Yeah it doesn't work in mp

#

It also can cause several errors and conflicts so be aware of that. The mod is awesome though

keen silo
#

@bronze yoke the issue persists

#

I have removed almost all local declarations from the first mod

#

I've changed my code a little and removed all local declarations

#

how can I change the files load order, to make sure that is not the issue?

#

the code would be:

RadioWavs.lua:

require "SoundFX/SoundFX"

RadioWavs = {}

local RadioWavs.soundCache = {}

RadioWavs.files = {}

function RadioWavs.addSongs(_guid,sound_name)
    RadioWavs.files[_guid] = sound_name
end

//Other functions that dont matter

return RadioWavs

VRTVs_SoundTable.lua:

local RadioWavs = require "RadioWavs"

RadioWavs.addSongs("ce2f8a16-5c34-45ab-a0fc-42a45bae457d","29f94658-1439-4dce-b764-828960ae641a")
bronze yoke
#

load order isn't an issue with require except for the client/shared/server folders thing

#

require can actually be used to force a certain load order

bronze yoke
#

ah, sorry, i popped out right before you sent that! sorry but i don't have any experience with it

winter thunder
#

All good. Though, is it cool if I still post my idea? Just so you can tell me if it sounds sane lol

bronze yoke
#

sure!

bronze yoke
coarse sequoia
#

Does anyone know if ItemZed still works because I have problems

winter thunder
#

basic idea is that I want to take information from an item that can be edited in game, and use that to post things to the chat.

In practice it would look like-

  • Admin gives themselves the item.
  • Writes a message that they want to quickly be able to send in the chat
  • Right clicks the item, custom context option to "Activate"
  • Posts the message that was typed on the paper in the chat

And bc of the way that pz handles written things, I could make it so that one page is the message, and the other page determines the formatting. First page says "Hello World", second page is a rgb color value that would be set for that chat.

#

@bronze yoke

bronze yoke
#

yeah that's probably pretty doable

keen silo
bronze yoke
#

it doesn't count as a lua error, just a failed message somewhere in the log

keen silo
#

where can I read the logs?

hoary widget
#

@winter thunder So is there an issue with the xml, is it named wrong?

#

Also this is the blender model for anyone wondering

tawdry moss
#

so i got most of the thing done but I want to know how i can have a constant gas hissing noise while the fire is active. i dont want it to be several sounds overlayed on top of each other if i can.

hoary widget
# mellow frigate <#869327724504842330>

I only posted it here because the model isn't showing up in game, and im showing what im using (becuase I was asked if it was scaled right). This is the default (I think?) project zomboid jacket model thats already being used.

#

I don't know if the mods set up right, or if it was the model

coarse sequoia
#

anyone have a link to a blender .x extension that works??

hoary widget
# mellow frigate my bad

No you're good! I could have and should have used that channel yesterday and I will def need it's help later

keen silo
#

hey, one question

#

how can I add logs to my mod?

#

to check what my lua functions are doing

tawdry moss
bronze yoke
keen silo
#

mmm

#

but it isn't showing up

#

in the logs

#

i have print("RadioWavs mod: Checking if " + _guid + " is on the table") but it doesn't appear

#

in console.txt

hoary widget
#

What happens when you put that uv map down there on that image? Also

keen silo
#

ok, I kinda made it work but I've got a big issue

#

somehow, I dont know why, OnDeviceText isn't passing me the _guid parameter

#

when I try to print it it says nil

coarse sequoia
#

I decided to expand the types of zombies and I have a question if anyone knows how to implement a zombie that has changed objects on its body, i.e. some bulges, etc.

keen silo
#

@bronze yoke @red tiger @abstract raptor I have a problem with my mod, no line is giving me their _guid value. they are all nil

#

Im using the OnDeviceText Event, which is supposed to pass the _guid, _interactCodes, _x, _y, _z, _line

Well, just after the function starts I try to print the _guid like this:

function RadioWavs.OnDeviceText( _guid, _interactCodes, _x, _y, _z, _line )
    
    print("RadioWavs mod INFO: OnDeviceText called")

    if _guid ~= nil then print("RadioWavs mod INFO: Playing line " +_guid) end

But it never prints

abstract raptor
#

🤔

#

I've never tried to retrieve the guid

keen silo
#

I know that the mod is properly loaded because I can see the "OnDeviceText called" line in the console

rich hazel
#

Does anyone know if it's possible to hide/remove the default PZ Professions so that only my custom profession is available?

#

And if so, how?

bronze yoke
#

if you're using profession framework i think it has something built in for that, otherwise you should overwrite the vanilla function for adding professions

rich hazel
#

Gotcha, I'll check it out

red tiger
#

Hahaha I wish I was that useful to modders here.

#

I help people here by writing tools, not insight unfortunately.

keen silo
#

God im pissed angry WHY DOESN'T IT SAY THE GUID?

#

I've found other code where they use the _GUID parameter in vanilla (RadioCom/ISRadioInteractions.lua), so it isn't like it should be empty

bronze yoke
#

hmm yeah, i'm not getting guids either

keen silo
#

mmm

#

@bronze yoke @abstract raptor Do you happen to know where is the code that saves the lines the player knows to the /Saves/{Difficulty}/{World_Name}/radio/data/RADIO_SAVE.txt ?

#

because it does save the Guid (of the broadcast IDs at least) there

#

So I know whatever is calling that function is passing the guid correctly

hoary widget
#

@winter thunder Good news I got it to half work, the issue was I had it setup like a steam workshop item instead of a mod item. So now I can see the Icon you made and it shows up...it's invisible so thats not good BUT at least its actually there!

keen silo
#

?

bronze yoke
#

it's java

keen silo
#

I guess I can't read it then....

#

mmm, im getting kinda desperate :v

#

@abstract raptor Im starting to think that the only logical solution to make a modular framework would be:

Make the user add the GUID of the line and the name of the sound to a function.

This function then SEARCHES ON ALL THE FILES inside /radio, and finds the guid there.

It also opens and saves on a text file the number of lines added.

It then modifies the .xml file, adding the appropriate DRU code

And adds one to the count.

Then, it works just as you made it :v

bronze yoke
#

can't you just modify the codes in memory?

#

if you go that route, you don't have to use dru - you can put whatever string you want in codes

abstract raptor
#

i wasn't aware you could modify the xml file from the game itself

keen silo
#

I asked techsupport anyway if there was a way to get the _guid because I don't like the idea of modifying the xml files on boot

#

I feel it could probably break a lot of stuff :v

#

How can I scale this issue to the developers of the game? It feels like they should take a look into it

bronze yoke
#

you can report it on the forums

#

i wouldn't expect much though, they generally don't seem to care too much about bugs that don't affect vanilla content

keen silo
#

Where are the forums? can you pass me a link?

keen silo
#

I've never written a report there

bronze yoke
keen silo
#

@bronze yoke @red tiger do you know how can I open and parse an xml file from lua?

#

Because LUA is in /media/lua/client/RadioCom/RadioWavs.lua and the .xml is in /media/radio/RadioData.xml

bronze yoke
#

there's probably a lua xml library out there somewhere, but i don't think you'll be able to get into the vanilla media folder

#

you can get into a mod's directory with getmodfilewriter/reader but i don't think you can get into the vanilla directory...?

keen silo
#

I dont need vanilla

#

kinda

#

my mod modifies the file in /media/radio/RadioData.xml

#

and it overwrites it with a modified version

#

can I access that?

#

I would need to do that on game world init I guess

bronze yoke
#

yeah, then getmodfilewriter/reader is good

#

it might cause checksum issues though

keen silo
#

for the parser, I tested the following line:

local data = xml.parse(<code>example</code>)```

And it loaded the main menu, so I guess it does have the library
keen silo
bronze yoke
#

i don't know whether the radio xml gets checksumed or not, but if it does then it might kick players before they join because the code that edits the file hasn't run yet

keen silo
#

this is for a SP mod, If i want to make it multiplayer i'll get to it when I get to it :v

#

besides, this is more of a 'quality of life' feature for other modders, instead of having to set every code on your .xml file, you just have to write the guid and it sets it for you

#

I guess I could easily make it work with them running a custom py script that does that from their end before they release the mod.....

red tiger
#

Again I can't help you.

#

I work on tools for modders, not mods.

#

Am a career programmer but haven't content modded PZ since 2017.

thin hornet
#

@red tiger how do we ipairs kahlua table in pw?

const [key, item] of items as LuaTable<string, InventoryItem>

compiles to:

for key, item in pairs(items) do
keen silo
#

@bronze yoke thank god the custom tags works perfectly

#

I can't get the GUID from the game, but I can at least write it to the codes

bronze yoke
#

yeah, codes are just a string, you can put whatever you want in there

keen silo
#

I'll make a quick python script that reads from a SoundTable.lua file, goes to the apropriate GUID, checks if it has the UID code and sets the UID code

red tiger
thin hornet
red tiger
#

I'm Ill so am useless

thin hornet
#

D:

red tiger
#

I put so many hours into these tools. I do worry if me not being around means that these tools that I wrote won't be useable.

#

Hopefully I am overly concerned over nothing.

#

Am rly ill tho

thin hornet
red tiger
#

Ok

keen silo
#

@bronze yoke The good news is that it works

#

I adapted my mod to use the new system

#

now I want to release it

#

What i'd like to do is split it into 2 parts

#

Is there a way to do this? like, make a collection where a mod requires another mod to work, and if I update the framework to fix some issue, it is fixed for all the mods that use it?

sour island
#

You can set requirments both in the mod and on steam

#

with in the code you can use the require function to properly load needed files in order

bronze yoke
#

yeah, you already made it modular so you just need to separate it into two mods

keen silo
#

and how can I set my mod to require the other on steam?

bronze yoke
#

i don't think you can do it until after upload

keen silo
#

and is there a way to set it in my project?

sour island
#

in modInfo

keen silo
#

so that it takes the framework from steam when I test it

#

?

sour island
#

require=ExpandedHelicopterEvents

bronze yoke
#

i'm not really sure what you mean by in your project

sour island
#

Setting the require in modInfo will require the mod to be qactivated

keen silo
#

oh

#

thx

sour island
#

Setting is on steam will require it to be downloaded

#

If your 2nd mod uses functions from your first you need to ensure you're loading them in the right order

bronze yoke
#

they've made their mod modular already so they know about that

sour island
#

Or you can use ```lua
require "luafile"

#

ah ok

mellow frigate
#

anyone knows why TIS uses generated guid for VHS title and texts ids ?

bronze yoke
#

i'd imagine for mod compatibility, and also because recorded media are generated from a tool and it would be more work to have manually written ids than generated ones

mellow frigate
#

They could have generated from title.

#

IT is pretty much how they did all the rest before.

bronze yoke
#

they could have, you can just set anything as your 'guid', the game doesn't ever check if it's a guid or anything

#

but setting guid as the standard is nice for mod compatibility

mellow frigate
#

I respectfully disaggrea. the same mod compatibility is achieved with type_title_line generated keys

#

and it is less verbose and it is easier to use

bronze yoke
#

well, since they're generated from a tool, it doesn't matter what they are

#

it only matters if you're manually writing them, which they don't do

mellow frigate
#

it also matters when you analyse them or analyse with them which modders do when they have to start modding.

#

and when debugging

sour island
#

media guids are saved into the player's save file - I imagine traditional guids are good for compression and hashmaps and such

#

where strings may not be

#

who is to say though -- they could have just wanted quick and dirty IDs

#

for quite alot of lines - as each can be stored/applied/call events

bronze yoke
#

a guid basically guarantees that you'll never have a conflict, even when you really should, and they're quick and easy

keen silo
#

@sour island @bronze yoke on the require in mod.info, what do I have to write? the mod ID?

bronze yoke
#

yeah

keen silo
#

thank you

#

I'll follow this tomorrow, but before leaving, is there a way to prevent the people who already downloaded my mod to have issues with this update? since it does split it into 2, and they will have to download (and activate) the new framework in their worlds, which might already have my old mod.

#

btw @abstract raptor once I release the framework I'll give you a bunch of py scripts that should adapt your work to the framework. It should make the mods compatible.

#

(I advice you to copy and make a backup of your mod, then check if everything works correctly with the new framework)

cloud plaza
#

alright. What am I doing wrong here

function GiveTraitItems(player)
    if getActivatedMods():contains("trineVFExpansion1") then
        local Inventory = player:getInventory()
        if player:HasTrait("hunk") then
            AddNewItem(Inventory, "Base.MP5SD")
            for i = 0,9,1 do
                AddLoadedMagazine(player, "Base.9mmClip30")
            end
            AddNewItem(Inventory, "Base.Pistol3")
            for i = 0,4,1 do
                AddLoadedMagazine(player, "Base.44Clip")
            end
        end
    end
    if getActivatedMods():contains("RE2_Hunk") then
        local Inventory = player:getInventory()
        if player:HasTrait("coldblooded") then
            AddNewItem(Inventory, "Base.RE2_Hunk")
        end
    end
end

function AddLoadedMagazine(player, magName)
    local Inventory = player:getInventory()
    local Mag = Inventory:AddItem(magName)
    Mag:setCurrentAmmoCount(Mag:getMaxAmmo())
    Inventory:addItemOnServer(Mag)
    return Mag
end

function AddNewItem(inventory, item)
    inventory:AddItem(item)
    inventory:addItemOnServer(item)
end

The GiveTraitItems function only grants "Base.MP5SD" but not anything else. At first I thought maybe there was an issue with AddLoadedMagazine but when I call this function on its own it works

bronze yoke
#

adding dependencies is kind of a nightmare

keen silo
#

Is there at least a solution to fix broken worlds because of the update? That way I can at least write instructions and pin them in the workshop to do that.

Something like activating the new framework on an old world

cloud plaza
#

alright I figured out the issue

bronze yoke
#

all they should have to do is enable the new mod

cloud plaza
#

Inventory:addItemOnServer requires a different object than Inventory:AddItem

#

so I have to get the Item returned from AddItem and add that to addItemOnServer

bronze yoke
#

just a nitpick, but you don't need to call addItemOnServer for player inventories

cloud plaza
#

even for multiplayer compatibility?

bronze yoke
#

yeah, player inventories don't even exist on the server

cloud plaza
#

huh

bronze yoke
#

player inventories only exist on that player's client

#

this is going to change since it's kind of a security flaw, but not for a while

cloud plaza
#

is this why?

bronze yoke
#

they probably just don't know

#

most people are copying from other mods or just guessing what things do, so they don't know when things like this are unneeded

cloud plaza
#

any way to debug? my lua script is crashing and im pretty sure i know where but i wish i could get some sort of useable stacktrace

fast galleon
#

you can breakpoints to your files

cloud plaza
#

you would still have to attach this to like a debugging instance wouldnt you

#

like how do you debug a lua script on project zomboid

#

so far all im using is sublime

fast galleon
#

well prints and breakpoints are easy and don't require other tools / knowledge

#

In-game press F11, filter for your file, double click to show it, double click the line you want.

#

It will pause at that line and you can advance by one action slowly after that.

bronze yoke
#

your game needs to be in debug mode if it's not

#

there should be a stack trace in console.txt either way but debug mode will give you breakpoints and in-game stack traces

cloud plaza
#

alright

#

also

#

im trying to host a server with my custom mod

#

i have tested this in singleplayer

#

but it keeps saying "Server has stopped during launch (NormalTermination)"

#

OK this is what I suspected

#

mod visibility has to be set to public. I had it on friends only

bronze yoke
#

yeah, the server has to download its own copy of the mods and for some reason it does that anonymously

sour island
#

It can still operate with unlisted btw

#

If you want it to be more hidden

sour island
#

I wish Steam descriptions new what sizes image they wanted to use

#

Hate seeing a giant black box lol

#

16:9 on website, squared on mobile

drifting ore
#

Is there any way to edit the message you get when you have made a character and the world is loading, and/or put a video instead?

sour island
#

You can replace it using the translation files

#

If you want more control over it you'd need to recreate it - and blank the vanilla lines.

drifting ore
#

With a mod, without having to replace files manually.

sour island
#

Adding a video - not likely lol

sour island
drifting ore
#

There is no way to put a video inside the game then? I was thinking that when you start with a new character, it will play a "cinematic" (I put it in quotes because it can be a loop of an event and that is activated each time you start with the new character).

#

Honestly, I would like to see when I create a new character, the death of the previous one. Like the "typical cam kill" of some games.

sour island
#

There's nothing in the game that supports a cinematic - so creating one would probably require a ground up approach and some luck with exposed methods.

#

The body is still attached to the player when you die -- I guess you could have it show up somehow but the load in screens are pretty java sided.

foggy prairie
#

Is there a way to decrease chance of police cars spawning as civilian cars without having to edit the entire zone distribution file?
More precisely I want to have it in a new file that just changes a single value (chancetospawnnormal), but doesn't contain all the unnecessary stuff I won't be editing

#

If it's not possible then I guess I'll just copy the entire file and edit this single value

sour island
#

Not familiar with vehicle zone spawns, but if it's a Lua table you can redefine exact entries

foggy prairie
#

Thanks

#

I'll see if that'll work (I'm brand-new to LUA so I'm not that knowledgable about how it works)

silk wadi
#

im starting from rly little knowledge here but any idea if it would be difficult to make a mod for mp that causes fog or other weather to set in for like 12h/day?

trim mist
#

Sounds possible

#

I don't think it would be difficult based on what i know about the Climate Manager, which is very little

#

also. Silly question for y'all

#

how does one check if the game is in debug mode?

#

just wanna use it for some prints

bronze yoke
#

getDebug()

trim mist
#

Anyone have any idea why these might be coming up as nil when referenced?

zenith bobcat
#

stupid question, as my googlefu has failed me. how do I store and retrieve a world object from mod data upon coming back from leaving the game? storing the object directly seems to not be correct, so is there some index or id?

bronze yoke
#

combine the co-ordinates of the square and the index of that object on the square (IsoObject:getObjectIndex())

#

you can then get the object using IsoGridSquare:getObjects():get(index)

zenith bobcat
#

if the object moves to a new square, anything you can do to catch that?

#

index will also survive if objects are added/removed to the square?

#

(thanks for the answers, appreciate it)

bronze yoke
#

you'd probably need to update the saved data when it moves, i don't think there's any kind of specific object identifier

zenith bobcat
#

odd, not how I have implemented game entity systems in professional games. thanks again.

#

one last question (maybe), is there a mechanism to find all objects by type within a radius, so do you have to go through square by square?

neon bronze
bronze yoke
#

i think that's only movingobjects if that matters for you

neon bronze
#

i am actually suprised that getLuaObjectList gives you an actual LuaTable

tranquil kindle
#

While i know that i can open .pack files and export them as png's using project zomboid moding tools, is it possible to make my own .pack with it so i can use new sprites for remote/motion/timed bombs when they're placed when armed, or perhaps there is more straightforward way to add them?

silk wadi
mellow frigate
#

Hi, I am forcing visual for a zombie. It works as expected, but when I reload the game, that visual is overriden. Someone knows how I can force my visual to be the one reloaded instead ?

sour island
mellow frigate
sour island
#

Yeah

mellow frigate
#

And yes my zombie has an outfit

sour island
#

To clarify, you're changing the zombies worn items or you're assigning it an outfitId?

#

Zombies don't actually save much of anything -- everything is loaded from definitions -- so changing stuff on the fly won't save even from unloading chunks

mellow frigate
#

I was doing both (and the outfit was overriding my settings of HumanVisual -not worn items-) Now that you tell me I can set everything through the outfit

#

I want to use outfit for everything and just need to find the hairstyle ans skin texture guid I guess

sour island
#

You'll have to assign it an outfitId with corresponding outfit XMLs OR just set reanimatedPlayer to true which then saves everything

#

You can set hairstyles to outfits as well

#

Shark and I did it for the aliens in super weird heli events

mellow frigate
sour island
#

Unfortunately zombies don't have a saving modData - so stuff has to be done this way

mellow frigate
#

Can we also force color that way ?

#

hair color I mean

mellow frigate
mellow frigate
sour island
#

Hair isn't an item thing, you define hairstyles allowed for the outfit

minor pumice
#

is there a way to change terrain properties? I'd like cars to be fast on dirt, but not by changing all cars one by one (for obvious reason)

mellow frigate
#

anyone has any idea on how to associate the skin color of a zombie to its outfit ? my goal is to have the same controlled skin color of a zombie with outfit when I create it and when I quit and reload the game.

trim mist
#

Hoping someone can tell my why suddenly stinkyDistance doesn't have a value when referenced

trim mist
# trim mist

You can see in here that in here it's coming out as nil. I don't see it being formatting...

#

Not the save file, just started a new test file and coming up with the same error

green rover
#

I'm pretty sure I know the answer to this, but can the required field in a fixing script accept anything but an item name? i.e item type

hoary widget
#

Can anyone tell me why its invisible?

glass basalt
hoary widget
#

Its a modeling issue? I didn't code it wrong?

keen silo
glass basalt
hoary widget
#

Its not the masks defined in the xml?

glass basalt
#

im not sure. There's a guide somewhere in this server...

hoary widget
#

if you mean this one

#

I am following it

glass basalt
#

yeah, that reference guide picture that goes from 1 to 15 are what I wanted to refer to

#
hoary widget
#

so i guess its a model issue of some kind

abstract raptor
keen silo
keen silo
#

@abstract raptor I just tested it and it seems compatible

#

I'll send you a zip if you want to check it out spiffo

#

it seems the zip file is too heavy

glass basalt
#

I need help with a cool mod name. My upcoming mod will remove vanilla vehicles, 100% (normal, burnt, vehicle scenes), and replace them with modded vehicles. What should I call it? I was thinking "Dynamic Vanilla Vehicle Replacer" but it could be better i think.

ocean sphinx
#

does this code to change menu music no longer work?

glass basalt
fast galleon
#

if you change required items for a mod, they are not auto enabled 🤔

ocean sphinx
glass basalt
drifting ore
#

How hard would be to make a mod that won't let you climb ropes when you are too tired, too weak, not fit enough or too fat/think?

#

I think it would be pretty easy.

drifting ore
sour island
#

Hmmm reminds me of SS13's search mechanic

#

That'd be a neat mod to do

#

Timed action to bring up a UI of what's visible on the other player, and more timed actions to open their bags and such -- then a timed action for each item to be taken. The other person can interrupt it by moving or doing something to the searcher.

nimble spoke
drifting ore
fast galleon
#

The timed action is barely used. If you climb from keyboard key press it's not even considered.

drifting ore
#

Hmmmmmmmmmmmmmmmmmmmmmm... how to change that?

#

Where are the key codes?

nimble spoke
fast galleon
autumn garnet
#

oh that never happened ^^ I must be lucky I always used his mod on my server

fast galleon
#

I need help fixing that mod

autumn garnet
drifting ore
#

Thisone I think

autumn garnet
#

the timedAction ^^

fast galleon
#

You could try to eat / consume the key, but I'm not sure if it will work.

autumn garnet
#

for the ladder mod, I was wrong, he hadn't done the feature yet

fast galleon
#

I have some snippets to reverse the climb but it bugged and causes players to fall.

drifting ore
#

Now I remember, I actually have already tried it once and I got this to work but then the issue with pressing E came up and I gave up:

function ISClimbSheetRopeAction:perform()
    if self.down then
        self.character:climbDownSheetRope()
    else
        self.character:climbSheetRope()
    end
    -- needed to remove from queue / start next.
    ISBaseTimedAction.perform(self);
end

sour island
#

There should be a key press event for climbing

drifting ore
#

I added some basic stuff to it to test, like ... endurance I think

autumn garnet
#

"media\lua\client\TimedActions"

#

ISClimbSheetRopeAction.lua

drifting ore
#

Yes, it is from that file

autumn garnet
#

function ISClimbSheetRopeAction:isValid()
    if self.down then
        return self.character:canClimbDownSheetRope(self.character:getCurrentSquare())
    end
    return self.character:canClimbSheetRope(self.character:getCurrentSquare())
end```
#

hook this ?

drifting ore
#

ig by hooking you mean overwrite the entire file then I got you 😄

autumn garnet
#

and add the conditions to know whether or not the player can go down... after you can hook the perform and do a ZombRand() so the player has a chance to let go of the rope if he gets too tired

fast galleon
sour island
#

For when you hold down E?

drifting ore
fast galleon
#

Not sure about holding, I was testing with short presses.

autumn garnet
drifting ore
#

Hmm, but... climbing over a fence should have the same stuff attached to it - can't climb when too tired. But I can't seem to find it on it's timedaction file. So I think it's maybe only defined on what Chuck and poltergeist were talking about?

sour island
#

Could be partly in the anims xmls

#

Started messing with those, and they're pretty potent for features

#

Made a mod that turns off tree scratches just using the xml

#

And a mod that stops zombies from tripping when sprinting

drifting ore
sour island
#

You could call a fail animation and set/check for conditions

fast galleon
#

I'll just mention this in case you didn't consider it.

  if player:isClimbing() then
    --stop climbing
  end
sour island
#

True, in the player update

#

I wonder if there's a way to break down the fencing climbing to 2 steps

#

Climb up and climb down, being able to sit on the fence

drifting ore
#

God damn this scrathes thingy was soo simple Chuck? I would have used it back in the day when I released my map and made all the bushes, tall plants and and some trash have the movement restriction but it also gave scratches so I was figuring how to change that but had to remove some of that stuff instead

sour island
#

Yeah there's a lot of stuff the animation system can handle

#

The issue is there's a lot of stuff from before still around making it bit convoluted

#

Like I'm pretty sure isClimbing probably checks for an animation variable

#

Not home so can't confirm

#

If not it's using a pre-anim field

fast galleon
#

probably a boolean flag

#

but climbing does have an anim variable

sour island
#

Yeah you could set a variable when you're tired

#

Have the climbing animation transition to a slide down animation or even fall

#

But I don't don't modders can define new animation states

fast galleon
#

I think I saw that in vanilla already 🤔

sour island
#

You can call on existing states

fast galleon
#

a check for mood level of endurance

sour island
#

Could be for fences

drifting ore
#

I'll look into the fence anims too, I don't even want to go too deep with this, only a simple check for if the person is generally too weak would be enough

sour island
#

The issue is the E call

drifting ore
#

as a avid junk food enjoyer I can tell I can't probably climb a sheet rope into a second floor

sour island
#

If that can't be properly prevented messing with on update could lock the player

#

While trying to finagle the sprinters to not trip I ended up with frozen zombies

#

And zombies running in slow motion

drifting ore
#

reminds me of max payne

sour island
#

Could make a bullet time using it lol

#

The issue is everything else and sounds

drifting ore
#

so you could Neo yourself out of a sticky situation?

sour island
#

Yeah, you just set a condition to lock up the animations

bronze sinew
#

I’m making a profession and how do I do the lua code? I’m using profession framework as a base and im super confused on where I put the files for it all ;-;

drifting ore
bronze sinew
#

Alright thanks! : D

jaunty dirge
#

@dusty wigeon would you mind if I sent you a direct message on discord to discuss your mod being used on a server?

#

Has anyone already made or know of a way to make a mod that reduces overall cooking time needed for recipes. On a real time server it can take 30 minutes to cook some recipes and wondering if there is a way to speed that up.

dusty wigeon
#

@jaunty dirge sure

mellow frigate
jaunty dirge
fast galleon
#

hm, maybe a portal microwave that instantly cooks the food by means of time travel

jaunty dirge
ancient grail
sour island
#

30 minutes to cook what?

wet sandal
#

Anyone know how food is cooked/rots?

#

I can't seem to make any food rot or cook

#

Steaks been in the oven for 3 days ded

#

So the inventory render code is somehow responsible for cooking/rotting

#

nice

#

Ah, ISInventoryPane:drawItemDetails

#

The item doesn't actually change, the inventory just needs to render it appropriately

sour island
#

Those functions are a huge pain to mess with

#

At least if you want it to play nice

ancient grail
#

SetAge i think

wet sandal
#

ISInventoryPane:renderdetails is the one doing it

ancient grail
#

Not sure but
You can get all the syntax from the contextmenu lua

wet sandal
#

I think I just gotta add a few calls to my own render loop I suppose

ancient grail
#

Theres a part there wheere it handles cooking and evolve recipe

ancient grail
#

Ah so you just want to render it specific way and has nothing to do with its properties?

wet sandal
#

The problem im seeing is with my grid inventory nothing is rotting/cooking/ getting wet/ etc

#

renderdetails
has things like this strewn throughout though:

                if instanceof(item, 'InventoryItem') then
                    item:updateAge()
                end
                if instanceof(item, 'Clothing') then
                    item:updateWetness()
                end
#

So I assume thats my issue

ancient grail
#

I dunno how youre handling the ui so im not sure if vanila applies to it

Maybe try drawdirty i think it was?

#

Like a render refresh thing

#

Im on mobile so i cant check

wet sandal
#

Wow, that snippet was all it took

#

Just works now

#

Guess item updates are pull

ancient grail
#

updateAge() ?

#

Nice!

wet sandal
#

I thought it was a bigger problem when leaving a steak in the oven didn't burn the house down

sour island
#

Items only update when seen then?

#

That feels off

#

Makes sense from a performance perspective but I'd assume fires would be started with out the need of being seen

wet sandal
#

Hmm, a fire did start eventually when I wasn't looking

#

I guess my incorrect rendering was breaking it

#

Freezing the items in an uncooked state, preventing the fire or something

twin hawk
#

is learning enough java to make a simple mod for zomboid hard? Considering that i know c++ and python?are there like support tools for modders, or do i basicially have to know entirety of java well? thanks for any advice

tawdry moss
#

So this code snipped works for the person holding the item but for other players on MP, they don’t see the visual change. Is there a way to change that?

I’ve tried having the update hand model be called for all players instead of just the user by running it in OnPlayerUpdate but that didn’t work either.

bronze yoke
#

zomboid is half and half and the official mod support only allows for lua mods

#

you might want to get familiar with java so that you can read the source code to see how the java api actually works but you don't really need to know too much about it

tawdry moss
#

@sour island you’re the guy that made EHE, right?

The Spiffo event gave me an idea for a mod but when I tried figuring it out it didn’t work. I know the gist of it is spawning a zombie with a specific outfit and making it immortal if it’s wearing a specific thing of clothing but I’ve never been able to get it to work. The zombies always spawn with default outfits when I do it.

Don’t have any footage atm and I’ve shelved the mod for a while because I couldn’t figure it out, how did you get the zombies to spawn with the right outfits?

twin hawk
trim mist
final crater
#

Greetings everyone, anyone know if there is a mod that shows the clickable items, Like fences? something like a "show click-box" or something like that, im having a hard time dissasembling small wired fences. The icon for dissasembly doesnt work on fences.

wanton pier
trim mist
#

Anyone know where I should start when I want to modify the UI?

#

Specifically item stat pop ups on hover

final crater
#

thats why im looking for a mod to see the clickable part of items, i dont know if its a bug or the clickable parts its super small

wanton pier
#

I think I'm familiar with the issue. I sometimes notice when trying to right click a sink with a window+shades facing west it is randomly not right-clickable.

#

well, It is, but it does not show 'wash' etc

final crater
wanton pier
#

but finding a magic pixel will bring it up sometimes.

final crater
#

can i send a link of a yt? shows the issue with the normal wired fence, the tall one, its easier with that one, but the small one its almost impossible

wanton pier
#

I dont know of a mod that does that though, I'm sorry.

final crater
wanton pier
#

sure go for it. my friends seem to come across this sort of thing, not with fences but random assets, so it could be worth looking into a fix for

ancient grail
wanton pier
# final crater thank you

I know you said you used the button, but you meant you tried it like this? and also using R to cycle the objects in the tile etc?

https://youtu.be/AP0rRoUyP40

Use this tip to disassemble things faster in Project Zomboid.

▶TWITCH: https://www.twitch.tv/Aidanomic
▶TWITTER: https://twitter.com/Aidanomic
▶DISCORD: https://discord.com/invite/scZpGMq

Ambient Music By Epidemic Sound

#projectzomboid
#projectzomboidbuild41
#aidanomic
#zombiegames
#shorts

▶ Play video
trim mist
#

Like, check if the player viewing it has a trait and change the item description (but not the actual properties of the item itself)

#

Right now i have a trait that if you eat chocolate it poisons you. I'm just trying to think of a way to forewarn a player that they'll be poisoned without them, you know, discovering it by accident

ancient grail
#

Use onfilinventory context menu

bronze yoke
#

i think there's an ISTooltip or something

mellow frigate
#

You want to access a java parameter but TIS did not implement an accessor ?

trim mist
bronze yoke
fading horizon
#

how do I make it so my weapon cannot be equipped in both hands, only primary or secondary?

    {
        DisplayCategory   =     Weapon,
        MaxRange          =    1.23,
        WeaponSprite      =    DragonScimitar,
        MinAngle          =    0.75,
        Type              =    Weapon,
        MinimumSwingTime    =    2,
        KnockBackOnNoDeath   =    FALSE,
        SwingAmountBeforeImpact  =    0.02,
        Categories  =    LongBlade,
        ConditionLowerChanceOneIn    =    30,
        Weight  =    2,
        SplatNumber   =    2,
        PushBackMod   =    0.5,
        SubCategory   =    Swinging,
        ConditionMax  =    25,
        MaxHitCount   =    2,
        DoorDamage    =    7,
        IdleAnim      =    Idle_Weapon2,
        SwingAnim     =    Bat,
        DisplayName   =    Dragon Scimitar,
        MinRange      =    0.61,
        SwingTime     =    3,
        HitAngleMod   =    -30,
        KnockdownMod  =    2,
        SplatBloodOnNoDeath   =    FALSE,
        Icon    =    DragonScimitar,
        RunAnim    =    Run_Weapon2,
        TwoHandWeapon   =     TRUE,
        BreakSound   =   MacheteBreak,
        DoorHitSound    =     MacheteHit,
        HitSound    =     MacheteHit,
        HitFloorSound      =     MacheteHit,
        SwingSound         =     MacheteSwing,
        TreeDamage        =   10,
        CriticalChance                =    20,
        critDmgMultiplier             =     5,
        MinDamage                    =    2,
        MaxDamage                    =    3,
        BaseSpeed                     =     1,
        WeaponLength                 =     0.3,
        AttachmentType                 =     BigBlade,
        DamageCategory                 =     Slash,
        DamageMakeHole                 =     TRUE,
        Tags                        =   CutPlant;SharpKnife,
    }```


I pretty much copied the vanilla machete but for some reason mine has the equip in both hands option
mellow frigate
trim mist
fading horizon
#

thank you

#

i'm blind i guess

trim mist
#

you're welcome. Yesterday I gave up because I was missing a comma and it was breaking everything

#

so you're not alone lol

mellow frigate
nimble spoke
red tiger
#

Using my extension to write scripts? That should show up when typing.

trim mist
#

Additionally would this affect multiplayer at all?

bronze yoke
#

you have to do it yourself, and it shouldn't affect multiplayer as long as the code runs on both sides

trim mist
#

Alrighty, thank you.

trim mist
bronze yoke
#

😇

fading horizon
#

is there a way to make a weapon only useable in both hands? so theres no equip primary or secondary option

trim mist
#

Have you checked the sledgehammer option? I think it works the same way

bronze yoke
#

RequiresEquippedBothHands = TRUE,

fading horizon
#

awesome, ty

#

second weapon is now done!

trim mist
#

Alright i'd like to get an opinion on this: what's the best way to get a list of items to tag?

  1. Put the list of items in a sandbox var, reference
  2. Put the list of items in a .txt file in the modfiles, parse and reference
  3. (be a monster and) hardcode the items in said function
#

My goal is to make it easy for another modder, if they ever decide to add on to this mod, to add items easily

bronze yoke
#

if you want it to be for modders specifically you can just make it a table

trim mist
#

What do you mean?

bronze yoke
#

if your mod is already modular then it's pretty simple to add it to the module, otherwise you could just return that table e.g.```lua
local items = {"Base.Apple", "Base.Banana",}

-- code that actually uses the table

return items

#

then other modders can just do```lua
local items = require "Path/File"
table.insert(items, "Base.Pear")

trim mist
#

I'm kind of leaning towards the txt file idea-- is that similarly easy for modders?

bronze yoke
#

they'd have to overwrite your file, unless you make it read from the same file in every loaded mod's directory or something

trim mist
#

🤔

#

Or if they'd like, I could make a table with the items I get from the file. They could either hook into my function or I could add another var they could access that could take their additions in before I assign tags

#

or am I just making this too complicated. lmao

#

I just want it to be easy. Maybe a table is the way to go.

bronze yoke
#

i have a soon to be released mod that looks for a file in every loaded mod's directory as well as the Zomboid/Lua/ directory, but that's sort of a whole system, i'm not sure it'd be called for in your case

trim mist
#

Things to think about!

nimble spoke
#

depending on your objective an item tag could work

trim mist
#
local function addItemTagsFromFile(path, tag)
    if not fileExists(path)
    then
        print("Cannot find file");
        return {};
    end

    local lines = {};
    local foundItem;
    local itemTags;

    for line in io.lines(file)
    do
        lines[#lines + 1] = line;
    end
    for line in lines
    do
        foundItem = getScriptManager().instance:getItem(line);
        if foundItem ~= nil
        then
            itemTags = foundItem:getTags()
            if not itemTags:contains(tag)
            then
                itemTags:add(tag);
            end
        end
    end
end


function ATOnInitWorld()

    addItemTagsFromFile("....ATCarnivoreTag.txt", "ATCarnivore")
    addItemTagsFromFile("....ATHerbivoreTag.txt", "ATHerbivore")
    addItemTagsFromFile("....ATInsectTag.txt", "ATInsect")
end
#

This is what I have so far. Anything glaring wrong? And I made the ATOnInitWorld global so it can be more easily extended

#

idk how I could make this easier for other people.

bronze yoke
#

i don't think the io library is available in kahlua, we usually use java BufferedReaders

#

i'm also not sure what path fileExists works from, it might not match that of the get reader methods

#

i've historically used local reader = getFileReader(params) and then if not reader then return end to check if the file exists, not sure if there's a better way

nimble spoke
#

No idea what the intention is but reading through all script files sound vaguely unnecessary

trim mist
trim mist
thin hornet
trim mist
#

yep. IO isn't a thing

thin hornet
final crater
bronze yoke
#

for your usage getModFileReader would be the most appropriate

thin hornet
#

unless he want to reads from the /lua/ dir

#

from my understanding the person want to read tags from a file so that he can update it later, probably so that it doesnt require a mod update (if it was written directly into the code)

trim mist
thin hornet
#

then try getFileReader and getFileWriter they will write into the lua/ dir of your cachedir

#

C:\Users\Konijima\Zomboid\Lua

#

IO is not exposed as it would be a security issue for malicious mod

mellow frigate
bronze yoke
#

but keep in mind that anything in the Lua folder won't be a part of your mod

thin hornet
#

yeah so you may want to create a default file if none exist.

trim mist
#
local function fileExists(path)

    local reader = getModFileReader(path, "r");
    reader:close();
    if not reader
    then
        return false
    else
        return true
    end
end

local function addItemTagsFromFile(path, tag)
    if not fileExists(path)
    then
        print("Cannot find file");
        return {};
    end
    
    local reader = getModFileReader(path, "r");
    local lines = reader:lines();
    local foundItem;
    local itemTags;

    for line in lines
    do
        foundItem = getScriptManager().instance:getItem(line);
        if foundItem ~= nil
        then
            itemTags = foundItem:getTags()
            if not itemTags:contains(tag)
            then
                itemTags:add(tag);
            end
        end
    end
    reader:close();
end


function ATOnInitWorld()

    addItemTagsFromFile("ATCarnivoreTag.txt", "ATCarnivore")
    addItemTagsFromFile("ATHerbivoreTag.txt", "ATHerbivore")
    addItemTagsFromFile("ATInsectTag.txt", "ATInsect")
end
#

This is what I have now

trim mist
#

wait. not here... further in?

bronze yoke
#

it looks at AnthroTraits

trim mist
#

okay bet

#

No issues are popping up. Just running some tests now

#

Is there a way I can check tags on an item? I forgot to print that somewhere

plush sorrel
#

i noticed the library pzstorm hasn't been updated since 2021 according to the github page i found so i want to make sure

bronze yoke
#

that guide is for lua modding

trim mist
#

602 is this lovely number

#

iiiiii'm gonna double check the docs

bronze yoke
#

getModFileReader(String modId, String filename, boolean createIfNull)

trim mist
#

you know. I was wondering what arg1 and arg2 were

#

decompiling is simultaneously so useful but can also be, uh, misleading

plush sorrel
trim mist
#

I don't think we really do java modding here

bronze yoke
# trim mist

btw, reader:close() might cause issues if the file wasn't found

#

i'd move that next to the return true

#

actually i should doublecheck that...

#

yeah, that's correct

trim mist
bronze yoke
#

i think there's an attachment editor? but not really my area so that might be unrelated

autumn temple
#

would that be in modeling? idk since this part is coding

#

but i doubt thats right

#

I will ask in modeling salute

ancient grail
autumn temple
#

ighto

#

I will move it over

trim mist
plush sorrel
#

lua won't give me enough flexibility/functionality alone

trim mist
#

Hmm. Problem is with modding with Java (afaik) is questionable legality, inability to use the workshop, and having a terrible, terrible time decompiling

plush sorrel
#

okay

#

If indie stone wants they can use my code but I want trains

trim mist
#

I'd highly recommend trying to prototype in Lua. People add in new vehicles all the time. you might be able to make a different model and restrict it to the train tracks

bronze yoke
#

not legal advice, but legality shouldn't be an issue afaik

quasi kernel
#

I mean, to my knowledge, if people can somehow get boats working, a train is only so far away, yeah?

plush sorrel
trim mist
#

Fair enough. You sound like you know what you're doing

plush sorrel
bronze yoke
#

i haven't used the boat mod but i assume boats are just cars on water, trains behave a lot more uniquely

quasi kernel
#

Fair, though would it not be possible to try and constrain a vehicles movement to tracks?

#

I don't know much of the IsoVehicle stuff, but it's just interesting. I feel like there'd be a way.

trim mist
#

🤔 does lua have access to the tiles underneath?

bronze yoke
#

i can't think of a way to do it from lua without it being very janky

plush sorrel
#

I have a specific idea of having a special type of "path" that the train would follow around the map.

plush sorrel
#

it can be done, but it would not be... clean

quasi kernel
#

Hmm..

quasi kernel
bronze yoke
#

it does, it's all IsoObject

#

i'd honestly love to see moving trains, godspeed

quasi kernel
#

Fr

#

Likely won't be easy, but hey, I have a feeling it ain't impossible.

ancient grail
#

Guys what mod is this if you know

#

Oh wrong thread . Im dumb

trim mist
#

Hey this is really silly

#

Why is this giving an error?

#

I've been unable to test the file input because of this lmao

trim mist
ancient grail
#

Im guessing map mod or trait mod

fast galleon
#

could be an npc mod?

fast galleon
trim mist
#

next mod idea: demon-spirits do creepy things

#

oh oops

#

sorry! I should know this

#
[10-05-23 00:55:54.994] LOG  : General     , 1683694554994> -------------------------------------------------------------
attempted index: ATModID of non-table: null.
[10-05-23 00:55:54.997] LOG  : General     , 1683694554997> -----------------------------------------
STACK TRACE
-----------------------------------------
function: addItemTagsFromFile -- file: AnthroTraits.lua line # 613 | MOD: Anthro Traits
function: ATOnInitWorld -- file: AnthroTraits.lua line # 645 | MOD: Anthro Traits.
[10-05-23 00:55:54.998] ERROR: General     , 1683694554998> ExceptionLogger.logException> Exception thrown java.lang.RuntimeException: attempted index: ATModID of non-table: null at KahluaThread.tableget line:1689..
[10-05-23 00:55:54.998] ERROR: General     , 1683694554998> DebugLogStream.printException> Stack trace:.
[10-05-23 00:55:55.034] LOG  : General     , 1683694555034> -----------------------------------------
STACK TRACE
-----------------------------------------
function: addItemTagsFromFile -- file: AnthroTraits.lua line # 613 | MOD: Anthro Traits
function: ATOnInitWorld -- file: AnthroTraits.lua line # 645 | MOD: Anthro Traits.
[10-05-23 00:55:55.035] LOG  : General     , 1683694555035> .
fast galleon
#

This line is really harmless though, only thing that could cause an error is if there's no table 🤔
Is the file with the table loaded at that point?

trim mist
#

Probably not. I was under the impression I could just stick global variables I might need in that file and they'd just... work.

fast galleon
#

folders load in this order sherd -> client -> -> server. If you want to cross reference something in same folder during Lua Loading, you can use require "Globals.lua" for example

drifting ore
#

Hei its that possible to delete all specify items from world with a mod?

trim mist
#

mm. not quite

#

...what am i missing? Intellisense worked. Was making it required not enough to make the table load?

fast galleon
#

move it inside one of the lua subdirectories, unless you want to manually load the file.

#

the simple way: globals in shared, then client / server files don't need to use require

limpid vine
#

can someone help me make nested radial menus in the q menu? like if I wanted to add another submenu inside of the 'Friendly' emote menu, how would i go about doing that? ive been doing a lot of trial and error with no success

limpid vine
#

the dance menus aren't nested, they're only regular menus

#

what i mean is

#

q menu > emote submenu > subsubmenu

drifting ore
#
getScriptManager():getRecipe("Recipe Name"):doSource("NeedToBeLearn = true")

#

Why won't this work? Trying to make a patch to set some recipes to be learned

ancient grail
#

Ughhh whats do source aagain? Albion mentioned this before

drifting ore
#

it should be a doParam for recipes as I read from your quote:D I think

ancient grail
#

Maybe you need to check the lua that handles these things

#

Kust type needtobelearn

#

Just*

#

Search the lua folder

drifting ore
#

my win search has always been broken as F

#

but I got this issue covered already, used something else, I just needed to make a temporary patch between three mods

#

Used these :

#
recipe:setIsHidden(true)
                getScriptManager():getRecipe("Butcher Small Animal"):findSource("Base.DeadMouse"):setCount(69)
#

It seems the setIsHidden(true) alone won't cut it, as the recipe still gets shown when done from inventory and you have the materials, so I had to use that other line as well 😄

fast galleon
#

You can search for recipe yeet

drifting ore
#

there is no such recipes

#

wups i mean, I was already doing another thing with poison 😄

#

now I have a problem where the poison level transfer only when there is one item as input and 1 item as result, but if there are lets say two items, one is poison and one is not and the result is only one item then that one item won't get that poison level

ancient grail
drifting ore
#

Oh THAT yeet 😄

#

i have no idea what lia is

#

I got that issue solved already anyways, im messing with the god damn poison level arghhhh

#

but I FEEEEEEEL IT, I FEEEEL like im close

thin hornet
# trim mist ?

dont put anything inside the /lua directory, there should only be client/ server/ shared/, your global file add it to the shared so it is loaded both on client and server.

ancient grail
drifting ore
#

ohhh 😓

thin hornet
#

also instead of using globals, simply return it at the end of the file and require it where you need it.
shared/myModSettings.lua

local settings = {
  modId = 'myMod'
}

return settings

client/someScript.lua

local settings = require('myModSettings')
print(settings.modId)
drifting ore
#

IT WORKS!

#
function PoisonA1_OnCreate(item)
    if item:getType() == "BerryGeneric1" or item:getType() == "BerryGeneric2" or item:getType() == "BerryGeneric3" or item:getType() == "BerryGeneric4" or item:getType() == "BerryGeneric5" or item:getType() == "BerryBlack" or item:getType() == "BerryBlue" then
        if item:getPoisonPower() > 0 then return false; end
    end
    return true;
end

#

If even one berry is poisonous then the recipe won't work.

thin hornet
#

to optimize this a little you could do this, this would stop calling the function numerous time.

local itemType = item:getType()
if itemType == "BerryGeneric1" or itemType == "BerryGeneric2" or ...
drifting ore
#

Thx! I'll add it. Im usually just too excited when something works that I'm afraid to change anything 😄

#

got tag teamed by team orbit

sour island
#

I think the game stores which berry is poison somewhere

#

I recall there being a function like 'getPoisomBerry'

drifting ore
#

It worked with my earlier method too but the problem was that if the input item is more then one and the output is only one then it didn't transfer over correctly.

#

Ahh you are right, there are one for berry and mushroom too

#

welll... why do it easy way when you can do it hardway too

sour island
#

😅

#

There's been a few times where I've written complicated things and had to troubleshoot issues only to find out there's a utility function buried somewhere

drifting ore
#

typical

#

once when adding/tweaking animations in .xml I constantly reset lua in debug mode and thought why the thing won't work, then I realized i need to restart my game for xml changes :S

#

took me a hour tho

ancient grail
#

local function doBlackCard()    
    if isDebugEnabled() then print('test Black') end 
    --do stuff here
end

local function doBlueCard()    
    if isDebugEnabled() then print('test Blue') end 
    --do stuff here
end

local function doGreenCard()    
    if isDebugEnabled() then print('test Green') end 
    --do stuff here
end

local function doRedCard()
    if isDebugEnabled() then print('test Red') end 
    --do stuff here
end

local function doYellowCard()
    if isDebugEnabled() then print('test Yellow') end 
    --do stuff here
end


if spr and tilecolor and SZC.isCardAvailable(tilecolor) then     
                    context:addOption('use ' .. tilecolor .. ' Keycard', v, function()         
                        print('Swipes '..SZC.CardVariation[tilecolor].card)
                        if  tilecolor == "Black" then doBlackCard() end
                        if  tilecolor == "Blue" then doBlueCard() end
                        if  tilecolor == "Green" then doGreenCard() end    
                        if  tilecolor == "Red" then  doRedCard() end
                        if  tilecolor == "Yellow" then doYellowCard() end
                        
                        
                        --TODO if you have something that will run no matte what color card you use then add that code here . for example audio or emote
                            player:playEmote("sneaksignalok2H") 
                            
                        -- if sq:getModData()['isCallZeds'] == nil then
                            -- Events.OnTick.Add(SZC.callZeds)
                        -- else
                            -- Events.OnTick.Remove(SZC.callZeds)
                        -- end
                    end)
                end
#

Cuz the keycard item , the color and the tile is inside a table

It would be nice if the function too

#

SZC.CareVariation[getTileColor].function

sour island
#

You can include functions in tables

ancient grail
#

Ah damn it

#

Now i know

sour island
#

Needs to be defined before it's referred to

ancient grail
#

Gotcha thnx . Ill use that

frank elbow
#

I think it was something like that one is guaranteed to be poisonous, but others may still be poisonous

#

Unsure bc I forgot to look into it

sour island
#

Careful reading anything in pz_chat lol

frank elbow
#

It was from vets; I had the same assumption as what you said based on looking at the code

sour island
#

Vets or not, a lot of players work on conjecture

frank elbow
#

Fair

sour island
#

"helicopter always comes on day 7"

#

"my cousin survived a bite"

frank elbow
#

I imagine they had experience in this case from seeing other berries be poisonous though lol

sour island
#

Afaik it's 1 type of berry, but there's a random chance for unknown berries to be the poison one

#

So maybe they're conflating it

frank elbow
#

Maybe that was it, could just be me misremembering. Still haven't looked into it so dunno

sour island
#

Yeah, I kind of hope the game gets a more complicated identification system

#

Although I might be in a minority lol

#

Basically not know what food is right away unless you're skilled or made it

#

Same for medication descriptions if medical gets expanded

#

Barotrauma (the game) does this a bit where you get incorrect suggestions for which medicines to use

frank elbow
sour island
#

Even for people who know the information by heart they need to manually select it and can't rely on quickly hitting the suggestion buttons.

#

Really slick design balancing in-game and real-world skills

red tiger
#

They may be a team of modders pumping out a ton of mods however Team asledgehammer has been core-modding and tool-writing for nearly a decade & team member count: 1.

#

No one ever knew that at one point PZ had its own Bukkit mod for the server that fully supported Java plugins & Lua modules that communicate with them.

#

(No one knew because I suck at advertising my works)

quaint mirage
#

A little unrelated to modding, but you guys probably know. If i deleete a user from whitelist, does that delete their char? Just want to reset pw 😛

neon bronze
#

What is the bukkit mod?

red tiger
#

Bukkit is a core-mod for Minecraft that allows people to do what they do with the Java edition.

#

It forwarded and interfaced the game's obfuscated code with human-legible API and allowed for multiple mods to be loaded as plugins that can play with each other nicely.

#

I used my own framework to build things like a custom chat solution & factions back in the day. =)

#

No one knew about it though, even though the server using it thrived for a bit.

#

If I felt like the multiplayer of PZ were to dramatically take off for a bit I might revive that project.

#

The best place to core-mod PZ is the server.

odd notch
red tiger
odd notch
#

having to copy an area based on coordinates then make a grid within a grid that copies the items in your area, their rotations, etc then pasting it somewhere else by saving the previous math and using the new location as the starting value

#

brain hurty

red tiger
#

I'm a career programmer.

odd notch
red tiger
#

My brain hurt when trying to copy all the render cache data from Minecraft when I wrote an exporter mod and import script for Blender.

odd notch
red tiger
#

I know a bit of UI/UX.

odd notch
#

revive the project

#

do it... DO IT.......

#

is that old uhhh whatstheirname chat, the chinese dev

#

from 2018?

#

gatewayroleplay used it i think

red tiger
#

The last UI thing I worked on was a core-mod to support GPU Shader support for UI and a React-library for PZ via Typescript.

odd notch
# red tiger ?

i forgor whose chat that reminds me of, i assume it's theirs

red tiger
#

I made that lol.

odd notch
#

there was a ye olde complete overhaul of chat around 2018 that fell into obscurity

#

carry the torch.........

red tiger
#

Never heard of anyone extending it

#

Maybe they did. If so I'd be happy for them.

odd notch
#

yeah it was ... a whole thing

red tiger
#

Chat today has tabs but doesn't look as clean as my design.

#

I wrote a new chat network protocol and abandoned the simplistic one back then.

#

Now chat has dynamic tab support for vanilla.

#

The code for that old thing is still up on my GitHub org however it won't work with anything today.

odd notch
#

maybe someone will PR them.. one day..

#

👵

red tiger
#

I see that you've made your own Discord bot too.

odd notch
#

am a forker.. we do a littel forking....

red tiger
#

It would be cool to have NPC bot in a very hard-to-reach place that once interacted with gives your Discord account a special role in a Discord server.

odd notch
#

how simpler life would be..

red tiger
#

It's easy to core-mod that for the server.

#

Could write one here on my lunch haha.