Thousands of Build 41 mods don't work in Build 42, and many of their authors have moved on. The good news is that most of the changes are mechanical: you can fix them with find and replace, as long as you know what to look for. This guide collects everything we had to change in our own mods, checked against the game's own files (B42.21).
1. The folder structure
In B41 the files went straight into the mod folder. In B42 they go inside a folder named after the version:
B41 B42
Contents/mods/MiMod/ Contents/mods/MiMod/
βββ mod.info βββ 42/
βββ poster.png β βββ mod.info
βββ media/ β βββ poster.png
β βββ media/
βββ common/ (optional)- Move
mod.info, the images andmedia/into42/. common/is for files that work on any version. It's optional.- In
mod.info, addversionMin=42.0.0, or whatever version you actually need.
2. Items: Type becomes ItemType
In B42 no vanilla item uses Type =: they all use ItemType with a base: prefix.
| B41 | B42 |
|---|---|
Type = Food, | ItemType = base:food, |
Type = Weapon, | ItemType = base:weapon, |
Type = Clothing, | ItemType = base:clothing, |
Type = Normal, | ItemType = base:normal, |
Type = Drainable, | ItemType = base:drainable, |
The 15 types that exist in B42 are: base:normal, base:food, base:weapon, base:clothing, base:drainable, base:container, base:literature, base:moveable, base:radio, base:key, base:map, base:weaponpart, base:alarmclock, base:alarmclockclothing and base:animal. For examples of each, look up a similar item in the item reference.
3. Tags, BodyLocations and categories take base:
| What | B41 | B42 |
|---|---|---|
| Tags | Tags = Hammer, | Tags = base:hammer, |
| Where clothing is worn | BodyLocation = Shoes, | BodyLocation = base:shoes, |
| Weapon category | Categories = SmallBlunt, | Categories = base:smallblunt, |
The exact values are in the tag reference and the BodyLocations reference. Watch out: some names aren't just "add base:" (for example, there's base:tshirt, base:shortsleeveshirt, base:zeddmg). Copy them from the reference.
4. Recipes: recipe becomes craftRecipe
B42 doesn't have a single recipe in the old format: there are almost a thousand craftRecipe and zero recipe. The format is completely different:
craftRecipe MakeCompletoItaliano
{
timedAction = Making,
time = 60,
Tags = InHandCraft;Cooking,
category = Cooking,
inputs
{
item 1 [CompleteItaliano.PanCompleto;Base.BunsHotdog_single] flags[InheritFoodAge],
item 1 tags[base:screwdriver] mode:keep,
}
outputs
{
item 1 CompleteItaliano.CompletoItaliano,
}
}- Old recipes don't convert themselves: you have to rewrite them. See the items and recipes guide.
- Every item from your mod needs the module in front (
MiMod.Item). If it's missing, the game won't load the save ("World loading could not proceed, there are script load errors"). - The recipe's display name goes in
Recipes.json(see section 5).
5. Translations: JSON only
B42 only reads .json files. B41's .txt files are silently ignored: the key shows up on screen instead of the text.
B41: media/lua/shared/Translate/ES/ItemName_ES.txt
ItemName_ES = {
ItemName_MiMod.Sopaipilla = "Sopaipilla",
}
B42: media/lua/shared/Translate/ES/ItemName.json
{
"MiMod.Sopaipilla": "Sopaipilla"
}- Notice that the key changes: in B42 it's
Module.Item, without theItemName_in front. - The same goes for
Tooltip,Recipes,IG_UI,Sandbox: one.jsonper type and per language (the example above is the SpanishESfolder; English lives inEN). Details in Translations.
6. Loot: nearly the same, but check the names
The system is still ProceduralDistributions with Events.OnPostDistributionMerge, so B41 loot code usually works. But many lists were changed or left empty: for example, GunStoreShelf exists but is marked as deprecated and has no items. If your item "doesn't spawn", check every name in the loot list reference.
Always use the pattern that checks the list exists, explained in Loot.
7. Lua changes that break mods
| Before | In B42 |
|---|---|
getProperties():Is(IsoFlagType.water) | getProperties():has(IsoFlagType.water), lowercase. The game doesn't use :Is( anywhere. |
getCell():getVehicles():get(i) | getVehicles() is now a Set, with no :get(i). To loop over objects, use getCell():getObjectListForLua(). |
HaloTextHelper.addText(player, texto, color) | Use addGoodText (green), addBadText (red) or addText(player, texto). |
table.insert(PrintMediaDefinitions.Fliers, ...) | That table no longer exists: fliers are now a registry (Registries.FLIER). |
BodyLocations as strings: getOrCreateLocation("Hat") | The game uses the ItemBodyLocation.HAT enum. Check media/lua/shared/NPCs/BodyLocations.lua. |
Timed actions in client/ | Put them in shared/: in B42 multiplayer the server also creates them by name. |
The typical symptom of these changes is a tried to call nil error that shows up when the save loads. The full list of B42 events is in the Lua events reference.
8. Servers: Mods= takes a backslash
If your mod gets used on servers, mention on its page that in B42 the line is Mods=\MiMod (with a \ before each ID). More in the dedicated server guide.
Checklist
- Files moved into
42/andversionMinset inmod.info. - Every
Type =changed toItemType = base:.... - Tags, BodyLocations and categories with
base:, copied from the reference. - Recipes rewritten as
craftRecipe, with your mod's items prefixed by the module. - Translations moved to
.json, with the new keys. - Loot lists checked one by one.
- No
:Is(,getVehicles():get(orPrintMediaDefinitions.Fliersleft in the Lua. - Tested with
-debugon a new save: no errors inconsole.txt. See Common errors.