Barotrauma

Barotrauma

Not enough ratings
The SHEDU Item Modding GUide
By Destrino
A guide for new modders like me, i went through all the failure and penance to bring my knowledge here....
if you are have VERY specific issues... my discord is here SHEDU#7015
   
Award
Favorite
Favorited
Unfavorite
getting Started (xml declaration)
Go to your localmods folder, the file directory should look like this

"C:\Program Files (x86)\Steam\steamapps\common\Barotrauma\LocalMods"


now create a new folder for your mod; "MyMod" (you obviously will change the name later)
open the folder and create a text file under the name "filelist.xml" enable file name extensions in the view tab MAKE SURE THE FILE IS AN XML AND NOT A ".TXT" OR BAROTRAUMA WONT READ IT.

now inside that XML open it with NOTEPAD++
if you do not have NOTEPAD++ there will be a link at the end


COPY AND PASTE THIS

<?xml version="1.0" encoding="utf-8"?>
<contentpackage name="SHEDU" modversion="1.0.10" corepackage="False" gameversion="0.19.14.0">
<Item file="%ModDir%/SHEDU.xml" />
</contentpackage>

inside the SHEDU bracket replace it wih the name of your mod, (this is how it will appear in the modlist ingame)




file contents for your mod
Now open the contents file and create a new folder named "items" (CASE SENSITIVE) and open that folder and create another folder titled "misc" every folder is case sensitive this will be imprtant later in the upcoming xml stuff




NOW open the misc folder and create a new text file and name it "misc.xml"




NOW YOUR MOD
now there are 2 types of mods i will cover
1. item mod (addinga new item)\

2.OVERRIDE CONTENT (mods that override vanilla content i.e instrument music replacement)


if you want to make a poster mod i highly suggest you go to Dan Murphy's "How to create a poster modification for Barotrauma" https://steamhost.cn/steamcommunity_com/sharedfiles/filedetails/?id=2803126169



Weapon mod
now YOU have decided "Imma make a GUN"


there are two ways to approach this: since it is very unlikely you will be creating a weapon script entirely by scratch or memory so to circumvent this issue you will be using the vanilla weapon scripts provided by BAROTRAUMA, to find those weapon scripts you will need to open the content folder from barotrauma (NOT TO MISTAKEN YOUR MOD "content" FOLDER)
the file directory isn't far from localmods (assuming you have it open) incase you DONT have the directory here it is: C:\Program Files (x86)\Steam\steamapps\common\Barotrauma\Content.
now inside the content folder open items and look for the item folder you want (there will be other item scripts like tools etc)

Method 1: go to your addons folder by the file directory (the appdata folder should be hidden by default so if you don want trouble just search up "gmbH" it will take a while)



Method 2: open the "weapons.xml" \
the script i will be using is the "smg" it should look like this


<Item name="" identifier="smg" category="Weapon" cargocontaineridentifier="metalcrate" tags="smallautoweapon,smallitem,weapon,gun,gunsmith,mountableweapon" Scale="0.5" impactsoundtag="impact_metal_light">
<PreferredContainer primary="secarmcab" amount="1" spawnprobability="1" notcampaign="true"/>
<PreferredContainer secondary="outpostsecarmcab" amount="1" spawnprobability="0.5"/>
<PreferredContainer secondary="wrecksecarmcab,abandonedsecarmcab" amount="1" spawnprobability="0.25"/>
<PreferredContainer secondary="armcab,weaponholder"/>
<Price baseprice="390" minleveldifficulty="30">
<Price storeidentifier="merchantoutpost" sold="false" multiplier="1.5" />
<Price storeidentifier="merchantcity" multiplier="1.25" minavailable="1" sold="false"/>
<Price storeidentifier="merchantresearch" sold="false" multiplier="1.25" />
<Price storeidentifier="merchantmilitary" multiplier="0.9" minavailable="2" />
<Price storeidentifier="merchantmine" sold="false" multiplier="1.25" />
<Price storeidentifier="merchantarmory" multiplier="0.9" minavailable="2" />
</Price>
<Fabricate suitablefabricators="fabricator" requiredtime="35" requiresrecipe="true">
<RequiredSkill identifier="weapons" level="55" />
<RequiredItem identifier="plastic" />
<RequiredItem identifier="titaniumaluminiumalloy" amount="2" />
</Fabricate>
<Deconstruct time="10">
<Item identifier="plastic" />
<Item identifier="titaniumaluminiumalloy" />
</Deconstruct>
<InventoryIcon texture="Content/Items/InventoryIconAtlas.png" sourcerect="832,830,64,64" origin="0.5,0.5" />
<Sprite texture="Content/Items/Weapons/weapons_new.png" sourcerect="0,121,144,80" depth="0.55" origin="0.5,0.5" />
<Body width="140" height="60" density="25" />
<Holdable slots="Any,RightHand+LeftHand" controlpose="true" holdpos="40,-10" aimpos="45,-10" handle1="-30,-15" handle2="26,5" holdangle="-35" msg="ItemMsgPickUpSelect"/>
<RangedWeapon reload="0.19" weapondamagemodifier="1.3" penetration="0.15" holdtrigger="true" barrelpos="64,9" spread="10" unskilledspread="16" combatPriority="80" drawhudwhenequipped="true" crosshairscale="0.2">
<Crosshair texture="Content/Items/Weapons/Crosshairs.png" sourcerect="0,256,256,256" />
<CrosshairPointer texture="Content/Items/Weapons/Crosshairs.png" sourcerect="256,256,256,256" />
<ParticleEmitter particle="muzzleflash" particleamount="1" velocitymin="0" velocitymax="0" />
<Sound file="Content/Items/Weapons/SMGsingleShot1.ogg" type="OnUse" range="3000" selectionmode="Random" />
<Sound file="Content/Items/Weapons/SMGsingleShot2.ogg" type="OnUse" range="3000" />
<Sound file="Content/Items/Weapons/SMGsingleShot3.ogg" type="OnUse" range="3000" />
<Sound file="Content/Items/Weapons/SMGsingleShot4.ogg" type="OnUse" range="3000" />
<Sound file="Content/Items/Weapons/SMGsingleShot5.ogg" type="OnUse" range="3000" />
<Sound file="Content/Items/Weapons/SMGsingleShot6.ogg" type="OnUse" range="3000" />
<StatusEffect type="OnUse">
<Explosion range="150.0" force="1.5" shockwave="false" smoke="false" flames="false" sparks="false" underwaterbubble="false" camerashake="12.0" />
</StatusEffect>
<!--"Use" contained magazine to spawn projectiles.-->
<StatusEffect type="OnUse" target="Contained">
<Use />
</StatusEffect>
<RequiredItems items="smgammo" type="Contained" msg="ItemMsgAmmoRequired" />
<RequiredSkill identifier="weapons" level="50" />
</RangedWeapon>
<ItemContainer capacity="1" maxstacksize="1" hideitems="false" containedstateindicatorslot="0" containedstateindicatorstyle="bullet" containedspritedepth="0.56">
<Containable items="smgammo" hide="false" itempos="4,-10" rotation="-30"/>
<SlotIcon slotindex="1" texture="Content/UI/CampaignUIAtlas2.png" sourcerect="896,536,128,64" origin="0.45,0.5" />
<SubContainer capacity="1" maxstacksize="1">
<Containable items="flashlight" hide="false" itempos="22,-1" setactive="true"/>
</SubContainer>
</ItemContainer>
<aitarget sightrange="2000" soundrange="4000" fadeouttime="5" />
<Quality>
<QualityStat stattype="FirepowerMultiplier" value="0.1"/>
</Quality>
<Upgrade gameversion="0.10.0.0" scale="0.5" />
</Item>



now that the script is open in another window you will open your misc.xml file that should be empty
and paste the root element

<?xml version="1.0" encoding="utf-8"?>

(erase any extra spaces or the file may have trouble reading)

now past the smg code directly under it
(press enter once and make sure there are no other spaces after the dec)



now your folder will look like this \




Adding Attributes part 1 (sprites,values and names)
Now that you have the script the next step is to add those pesky attributes!!!




you may have noticed that the smg script that he 'name="'
bracket is empty; that bracket will will be the actual name of your item INGAME.
you can add your weapon name to it; For now we will call it "Das gun".

as for the identifier that will be the INGAME id that will show in the dev cosnole (e.g for spawnitem command or using the "requireitem" component when in reference to XML)



NOW FOR THE PESKY PART!!!

you have your weapon sprite ready to go; IT MUST BE A PNG. copy the sprite from its original file location (assuming you didnt save the file directly in the misc folder itself, incase you have, dont worry about this part)
NOW PASTE THE PNG FILE IN THE MISC FOLDER!!!!

now for the sprite to work you will go to this specific text

<InventoryIcon texture="Content/Items/InventoryIconAtlas.png" sourcerect="832,830,64,64" origin="0.5,0.5" />
<Sprite texture="Content/Items/Weapons/weapons_new.png" sourcerect="0,121,144,80" depth="0.55" origin="0.5,0.5" />
<Body width="140" height="60" density="25" />

remove the directory for both sprites
and replace it with "%ModDir%/content/Items/misc/YOURSPRITE.png"
the png extension IS CASE SENSITIVE

the sprite you will be using is the custom sprite you have in the misc folder, COPY THE NAME and paste it into the "/weapons_new.png"
same for the inventory parameter




as for source erect this will be the actual dimensions of the sprite itself. "00,00,width,height"
the last two comma brackets will be the dimensions for the sprite eg 150x,150x
the first two comma brackets is the origin (this is where the sprite will render in reference to)

you can use sprite editor ingame via the "spriteeditor" command via dev console for more accurate sizing
adding attributes part 2 (adding custom sounds)
NOW YOU WANNA MAKE A CUSTOM PEW PEW?!??!?

For this you will need a ".ogg" file NOTE: renaming a file end extension to ".ogg" will not work as it will need a manually converted mp4 to .OGG. To make an .OGG file you can always use a third party website to do it for you (though it can be sketchy sometimes)

what i do to get my gun sounds is simply screen record whether im using my computer (WINDOWS+ALT+R screen record shortcut)
and simply convert that video to an ogg




NOW you have your ogg file..... place it in the misc folder

no got back to your xml document
and look for


<Sound file="%ModDir%/content/items/misc/smgsingleshot1.ogg" type="OnUse" range="3000" />


now replace the directory with the one provided earlier and repeat the process, except you are referencing the CUSTOMSHOT.ogg file



you can multiple sounds but the must copy the same attributes all except for the name
and you will need to change the selection mode accordingly
Now the hard part
Some people want their own custom ammo types and stuff.
this gets a little "iffy" at times. When is was creating https://steamhost.cn/steamcommunity_com/sharedfiles/filedetails/?id=2906797987

i had a grueling time with ammunition and condition for it.
i recommend viewing any subscribed addons and analyze the ammo scripts from there if you want to make your own ammunition.
C:\Users\DAS USER\AppData\Local\Daedalic Entertainment GmbH\Barotrauma\WorkshopMods\Installed




now the gun should have a "containable" component, this will be what you can place into the weapon. inside the quotations you will put the ammo you would like to use by its IDENTIFIER.
if you are using a custom magazine or ammo round you will need to put its IDENTIFIER as well.
The "reqiureditem" compnent is what is reqiured for the "statuseffect=use" in short; it is whats required to fire. put the identifiers accordingly

now you want to make a CUSTOM MAGAZINE

its not as simple as it sounds

first you are gonna SNAG the smg magazine code


it should look like this


<Item name="" identifier="smgmagazine" maxstacksize="2" scale="0.5" category="Weapon" cargocontaineridentifier="metalcrate" linkable="true" tags="smallitem,smgammo" impactsoundtag="impact_metal_light">
<PreferredContainer primary="smg,smgunique,machinepistol" amount="1" spawnprobability="1"/>
<PreferredContainer primary="armcab" amount="1" spawnprobability="1" notcampaign="true"/>
<PreferredContainer secondary="outpostsecarmcab" minamount="1" maxamount="2" spawnprobability="0.5"/>
<PreferredContainer secondary="wrecksecarmcab" minamount="1" maxamount="2" spawnprobability="0.2"/>
<PreferredContainer secondary="secarmcab"/>
<Price baseprice="100" displaynonempty="true" minleveldifficulty="15">
<Price storeidentifier="merchantoutpost" sold="false" multiplier="1.5" />
<Price storeidentifier="merchantcity" multiplier="1.25" minavailable="2" sold="false"/>
<Price storeidentifier="merchantresearch" sold="false" multiplier="1.25" />
<Price storeidentifier="merchantmilitary" multiplier="0.9" minavailable="4" />
<Price storeidentifier="merchantmine" sold="false" multiplier="1.25" />
<Price storeidentifier="merchantarmory" multiplier="0.9" minavailable="4" />
</Price>
<Fabricate suitablefabricators="fabricator" requiredtime="25" requiresrecipe="true">
<RequiredSkill identifier="weapons" level="40" />
<RequiredItem identifier="magnesium" />
<RequiredItem identifier="lead" />
<RequiredItem identifier="steel" />
</Fabricate>
<Fabricate suitablefabricators="fabricator" requiredtime="15" requiresrecipe="true" displayname="recycleitem">
<RequiredSkill identifier="weapons" level="40" />
<RequiredItem identifier="magnesium" />
<RequiredItem identifier="lead" />
<RequiredItem identifier="smgmagazine" mincondition="0.0" usecondition="false"/>
</Fabricate>
<Deconstruct time="10">
<Item identifier="lead" mincondition="0.95"/>
<Item identifier="steel" />
</Deconstruct>
<InventoryIcon texture="Content/Items/InventoryIconAtlas.png" sourcerect="960,960,64,64" />
<Sprite texture="Content/Items/Weapons/weapons_new.png" depth="0.54" sourcerect="146,157,17,44" origin="0.5,0.5" />
<Body width="14" height="40" density="20" />
<ItemContainer hideitems="true" capacity="1" drawinventory="false" canbeselected="false" ShowConditionInContainedStateIndicator="true" SpawnWithId="smground" removecontaineditemsondeconstruct="true" containedstateindicatorstyle="bullet">
<Containable items="smground" />
<!--Spawn an SMG round on use. Condition -4.8 -> 21 shots per magazine.-->
<StatusEffect type="OnUse" target="This" condition="-4.8" disabledeltatime="true">
<SpawnItem identifiers="smground" spawnposition="ThisInventory" />
</StatusEffect>
</ItemContainer>
<!--Magazines can be combined to raise condition.-->
<Holdable canBeCombined="true" slots="Any,RightHand,LeftHand" handle1="0,0" msg="ItemMsgPickUpSelect" />
<Upgrade gameversion="0.10.0.0" scale="0.5" />
</Item>




now that you have the code insert it inside your misc.xml

where the </Item> tag ends from YOUR gun code

press enter once and hit backspace twice
to erase the excess spaces (indentation IS KEY with xml files)

now paste your code


remove all of the original identifiers and add your own and make sure your custom magazine has its own identifier and put said identifier in your gun code above in the "requireditem" and "containable" components (note:make sure you keep some contables the same such as lockers and stuff)
if at any point you are uncertain about where the identifiers go use a modded script or vanilla script for reference



NOW inside the magazine containable you will see a "hideitem" component, this is arbitrary.

inside the spawnitem bracket put your CUSTOM ROUND inside. (if you want infinite ammo you gotta tamper with "condition" components)

now you will make a custom round (REMEBER: all of the ammo stuff can be circumvented if you like using vanilla ammo)


now for the custom round you will want the smg round code from the vanilla weapons.xml

it should look like this



<Item name="" identifier="smground" category="Weapon" interactthroughwalls="true" cargocontaineridentifier="metalcrate" tags="smallitem" impactsoundtag="impact_metal_light" hideinmenus="true" scale="0.5">
<InventoryIcon texture="Content/Items/InventoryIconAtlas.png" sourcerect="896,960,64,64" origin="0.5,0.5" />
<Sprite texture="Content/Items/Weapons/weapons_new.png" sourcerect="195,282,17,6" depth="0.55" origin="0.5,0.5" />
<Body width="40" height="14" density="30" />
<Pickable slots="Any" msg="ItemMsgPickUpSelect"/>
<Projectile characterusable="false" hitscan="true" removeonhit="true">
<ParticleEmitter particle="tracerfirearm" particleamount="1" velocitymin="0" velocitymax="0" colormultiplier="255,255,115,175" scalemultiplier="1,0.6"/>
<Attack structuredamage="5" targetforce="5" itemdamage="10" severlimbsprobability="0.1">
<Affliction identifier="gunshotwound" strength="12.5" />
<Affliction identifier="bleeding" strength="12.5" />
<Affliction identifier="stun" strength="0.2" probability="0.1" />
</Attack>
<StatusEffect type="OnImpact" target="UseTarget">
<ParticleEmitter particle="impactfirearm" particleamount="1" velocitymin="0" velocitymax="0" />
</StatusEffect>
<StatusEffect type="OnImpact" target="UseTarget">
<Conditional entitytype="eq Structure"/>
<Conditional hastag="eq door"/>
<ParticleEmitter particle="spark" copyentityangle="true" anglemin="-10" anglemax="10" particleamount="5" velocitymin="-10" velocitymax="-200" scalemin="0.5" scalemax="1" />
</StatusEffect>
<!-- smg rounds should not exist outside magazines -->
<StatusEffect type="OnNotContained" target="This" stackable="false" delay="1">
<Remove />
</StatusEffect>
</Projectile>
<Upgrade gameversion="0.10.0.0" scale="0.5" />
</Item>




you can play with afflictions and stuff BUT you might wanna open the barotrauma afflictions prefab xml's and stuff because identifiers can be a little troublesome
Override mod
Say YOU wanna replace the bike horn with a cheeky sound, or override a creature to make questionable sounds...

For this guide i will use my laughing bike horn mod as reference (however since you hopefully know how to snag vanilla item scripts so you can overirde them with fun SOUNDS or etcetera)

https://steamhost.cn/steamcommunity_com/sharedfiles/filedetails/?id=2904211748


NOW you will repeat the same process as before with the folders and filelist and misc xml's





inside your new misc.xml you will use this example as a reference, or copy it into your XML



<?xml version="1.0" encoding="utf-8"?>
<Override>
<Items>
<Item name="" identifier="bikehorn" category="Misc" tags="smallitem,hornitem" scale="0.5" cargocontaineridentifier="metalcrate" description="HONK">
<PreferredContainer primary="crewcab" spawnprobability="0.05" notcampaign="true"/>
<PreferredContainer secondary="wreckcrewcab,abandonedcrewcab" spawnprobability="0.05"/>
<Price baseprice="1" canbespecial="false">
<Price storeidentifier="merchantoutpost" minavailable="1"/>
<Price storeidentifier="merchantcity" minavailable="1"/>
<Price storeidentifier="merchantresearch" sold="false" />
<Price storeidentifier="merchantmilitary" sold="false" />
<Price storeidentifier="merchantmine" sold="false" />
</Price>
<InventoryIcon texture="Content/Items/InventoryIconAtlas.png" sourcerect="769,385,64,64" depth="0.55" origin="0.5,0.5" />
<Sprite texture="Content/Items/Misc/Misc.png" sourcerect="101,45,53,22" depth="0.55" />
<Body width="50" height="20" density="15" />
<Holdable slots="Any,RightHand,LeftHand" aimpos="100,0" handle1="-15,-3" msg="ItemMsgPickUpSelect" />
<RangedWeapon reload="2">
<Sound file="%ModDir%/Content/Items/Misc/LAUGHOFTHEDAMNED.ogg" type="OnUse" />
</RangedWeapon>
<aitarget soundrange="100000" fadeouttime="5" />
<Upgrade gameversion="0.10.0.0" scale="0.5" />
</Item>
</Items>
</Override>






no this part is self explanatory since YOU know what you wanna replace sincethe first mod showed you how to import stuff etc etc
Finishing up and publishing
Now you have created either mod....

YOU WANNA PUBLISH IT!!!

open barotrauma and open the mod settings and click publish on the top right
and you should see a list of you localmods.

PUBLISH






















Done.
Possible issues
If you have a start tag not matching ENd tag e.g "items start tag doesnt match the end tag items"
it means you have a root issues... to circumvent this you must inspect you tags because if they contain "/>" at the end it means its a end tag if it doesn't vice versa.

COULDNT FIND PREFAB

change the name or identifier of said prefab

Expected hash calculation returned "hexadecimal value too long for me to include"
you must have copied it from a subscribed addon, remove the expected hash parameter or put 1 inside the quotation marks


MISSING ROOT ELEMENT

you are missing the <?xml version="1.0" encoding="utf-8"?>

root element is different from the declaration since declaration is inside your filelist document
2 Comments
Banjo37 14 Sep, 2024 @ 4:39pm 
THANK YOU
Dan Murphy Jr. 1 May, 2023 @ 7:41am 
You might want to add indents for the XML that should be copied. Also, you might want to check out Steam's text formatting guide and add a few 'code' tags.
https://steamhost.cn/steamcommunity_com/comment/Announcement/formattinghelp
:captainclown::captainsmooth::barotrauma: