Skip to content

Mod files and folders

A mod is a folder (or a zip of that folder). The game looks for mods in your local Mods folder, in Steam Workshop installs, and in packages you staged for upload.

Zip one pack at a time. Startup and Load Now accept modinfo.json and the pack files at the archive root, or inside one enclosed pack folder. The archive filename does not have to match that folder. Archives with several unrelated pack roots are ambiguous and should be split into separate zips.

Required identity

A supported mod needs a modinfo.json at the folder root. Older packs with modinfo.lua must move their identity fields into modinfo.json before they can be loaded or prepared for publishing. A Lua file cannot serve as the mod's identity.

Field Purpose
UniqueModName Stable prefix for all ids (modname.thing). Never use sol.
DisplayName Name in the Mods list and on Workshop
Description Listing text

Typical layout

MyMod/
  modinfo.json
  item_my_sword.json
  structure_my_box.json
  creature_my_critter.json
  Spawning/spawnrule_my_critter.json  # optional encounters in existing worlds
  worldprofile_my_world.json   # optional extra Sandbox world type
  WorldGenerator/…             # optional terrain files for that world
  Spawning/SPWN_*.json          # optional base spawn lists for a custom world
  Parallax/…                   # optional sky for that world
  recipes.xml                  # optional crafting recipes
  Config/playerConfig.json     # optional startup player overrides
  Config/worldConfig.json      # optional startup world overrides
  preview.png                  # optional Workshop preview (Mod Prep)

JSON files the game should load as content need a known filename prefix:

item_, structure_, flora_, floratype_, projectile_, creature_, fluid_, status_, spfx_, worldprofile_, or spawnrule_.

Other .json files are ignored as content. Spriter's atlas.json next to a .scml file is a normal exception.

A structure_ file needs a Structure object with a nonempty Name. Structure names must be distinct within the pack, including when their UniqueIdentifier or DisplayName differs. The lookup is case-sensitive.

Start with Mod Prep's one-item project. Copy patterns from Example Mod when you need weapons, armor, creatures, recipes, or custom worlds.

Sprites and art

Point inventory pictures at PNG files inside the mod, relative to the mod folder. Keep those files in the folder you ship. Older mods that still use a sprite sheet plus a frame name continue to work.

Recipes

Optional root files recipes.xml and grindRecipes.xml are checked by Mod Prep. Put smelting, cooking, and chemistry recipes in recipes.xml with processType="smelt" (or cook / chemistry). grindRecipes.xml is for mill and process jobs only (wheat to flour, nuts to butter). Break down world items with GrinderDrops / GrinderDropQuantity on the item JSON. Do not ship smeltingrecipes.xml — the game does not load it.

Gameplay configuration

Optional gameplay overrides belong at Config/playerConfig.json and Config/worldConfig.json inside your pack. Match the folder and filename spelling exactly. Files with these names at the pack root are ignored by the game; Mod Prep reports the misplaced files as errors.

These overrides apply when the game starts. Load Now skips gameplay configuration, so restart the game to test changes to either file.

Lua

You do not need Lua for a simple item. When you do, set LuaScriptPath on content that actually runs scripts: held items, melee weapons, throwables, consumables, armor, structures, plants, projectiles, status effects, and creatures. Other item types ignore that field; Mod Prep reports it as an error.

Keep Lua helpers inside the pack. require("helpers") first looks for helpers.lua in the folder containing modinfo.json, then beside the importing script. require("Tools.helpers") looks for Tools/helpers.lua in the same order. Existing namespace folders still work; helper names do not need a mod-specific prefix. Return a helper table and store the import in a local variable, such as local helpers = require("helpers"). See Lua modules for caching and shared-state limits.

See the Lua programming reference and Lua safety and limits.

Locale packs

A language pack is also a mod: modinfo.json plus overlay JSON under Config/. You do not need Mod Prep or Lua to contribute translations. See Community translations.

Custom worlds

To add wildlife encounters to existing worlds, use Ambient wildlife spawns. A spawnrule_*.json contributes a targeted group without changing the world's base spawn table.

Mods can add extra Sandbox world types with worldprofile_*.json plus files under WorldGenerator/, Spawning/, and optionally Parallax/. See Custom worlds and Detailed world building.

Publishing

  1. Validate in Mod Prep.
  2. Stage for in-game. That writes a folder under Documents/My Games/Signs of Life/WorkshopUpload/.
  3. In the game, open Mods → Staged Mods and Upload New Mod or Update Existing Mod. Mod Prep does not talk to Steam itself.

After Steam creates the item, the source project remembers it in .solmodproject.json next to modinfo.json. Keep that file with the project: it is not included in the downloadable mod, and it prevents a cleaned staging folder from becoming a second Workshop item on the next publish.

Load Now and Disable

  • Load Now adds a Pending local or newly downloaded mod to a running single-player session when it can. It cannot reload an already Loaded pack.
  • After editing a Loaded pack, validate and refresh the test copy if needed, then restart the game. Install / Refresh Test Copy updates files on disk only.
  • A newly subscribed, enabled Workshop mod does the same after Steam finishes installing it.
  • Disable turns a mod off for the next launch. Turning one off while you are in a world reloads game content.
  • Multiplayer does not offer Load Now.

Removing and reinstalling a mod

When a save loads without a content pack, its inventory items become inert Missing mod item placeholders. Missing equipped items move to inventory. Placed structures, plants, and creatures whose definitions are missing remain in the save but are not simulated. Saving preserves their recorded state and the placeholders' original content identities.

Reinstall and enable the pack with the same UniqueModName and UniqueIdentifier values, then reload the save to restore those objects. Recovered equipment stays in inventory until you equip it again. Deleting a placeholder discards that item; changing its content identity creates a new type instead of restoring the old one. Projectiles and active status effects are transient and do not survive a save reload.

A custom world's profile is still required to load that world. Disabling a pack stops future ambient spawns from its rules. On the next save load, existing creatures follow the normal missing-content behavior if their creature definition is also unavailable.

Example Mod

The installed game includes a complete sample in its top-level ExampleMod/ directory. Copy that folder into Documents/My Games/Signs of Life/Mods/ before loading it; the shipped copy does not enable itself.

Example Mod is a cookbook for established projects: weapons, Lua, animations, sounds, armor, clothing, recipes, a creature with an ambient spawn rule, and sandbox world types. Start with Mod Prep's one-item project first, then copy individual pieces from Example Mod as you need them.