Mod API reference
The reference for mod makers: what a mod folder holds, the data files, and the code API. New to modding? Start with Making mods.
The reference for mod makers: what a mod folder holds, the data files, and the code API. New to modding? Start with Making mods.
Players install mods from the website (Install opens the game), from Mods ▸ Browse in the main menu, or by putting folders in the Mods folder, and switch them on and off in main menu ▸ Mods. In multiplayer everyone plays with the host's mods: a joining player gets the mods they're missing from the host (after saying yes), keeps their own client-side mods, and goes back to their own mods when they leave.
Where mods go
| Folder | What |
|---|---|
<persistent data>/Mods/<any name>/ | The player's mods (%USERPROFILE%\AppData\LocalLow\DefaultCompany\Seeds & Circuits\Mods on Windows). Open Folder in the Mods screen opens it |
<game folder>/Mods/<any name>/ | Mods shipped next to the executable (in the editor: Mods next to Assets) |
<persistent data>/Mods/.downloaded/<id>-<hash>/ | Mods downloaded from hosts |
<persistent data>/Mods/mods.json | Which mods the player turned on or off |
The player's own mods start on; downloaded ones start off (they're used in that host's games only, unless the
player turns them on). Start the game with -nomods to load no mods at all.
What a mod is
A folder with a mod.json:
{
"id": "someone.coppertools",
"name": "Copper Tools",
"version": "1.0",
"author": "Someone",
"side": "both",
"description": "Copper axe, pickaxe and shovel.",
"dependencies": ["someone.coremod", "someone.library >= 1.2 < 2.0"]
}
id (letters, digits, . _ -; the folder name if left out) must be unique: two mods with one id can't both be on.
Mods load after their dependencies; a mod whose dependency is missing, or there in a version it can't use, stays
off and the Mods screen says why ("Needs Core Mod 1.2 or newer (1.0 is installed)"). A dependency is an id, optionally
followed by version rules (>=, >, <=, <, =), compared part by part as numbers (1.10 is newer than 1.9).
gameVersion (written by the Mod Kit) is the game version a code mod was built for: the Mods screen notes "made for
game version X" when that isn't this game's version (its code may not work; data mods don't care).
side says where the mod runs in multiplayer (default both):
| Side | Runs on | In multiplayer | For |
|---|---|---|---|
both | Host and every player | Everyone must have it: joiners download it from the host | Items, recipes, shared gameplay (Waypoint Map) |
client | Wherever the player has it | Works on any host. A host's client-side mods are offered to joiners (ticked by default, they can untick) | HUD, UI, compass, cosmetics (Trader Compass) |
server | Only on the host | Never sent to or required from players; a joiner's own server mods are off while joined | Admin tools, rules (Ban Hammer) |
Everything else in the folder is optional, and any mix works:
| File | What it does |
|---|---|
items.json | Adds items or changes the game's items (below) |
recipes.json | Adds crafting recipes (below) |
*.dll | Code (below) |
| images, AssetBundles, anything | Used by the above (icons, models) |
Files and folders starting with . are ignored. The mod's hash (SHA-256 of every file's path and bytes) tells
whether two machines have the same mod. A mod may be up to 512 MB. A mod never writes into its own folder (that
would change its hash): code mods keep their saved data in Mod.DataFolder.
Items (items.json)
{
"items": [
// New item, starting from cooked pork (a food), with the clay pot's model and icon.
{ "id": "berry_jam", "copy": "cooked_pork", "name": "Berry Jam", "food": 30, "spoilDays": 0,
"stackSize": 10, "model": "clay_pot" },
// Same id as a game item: only the fields named here change.
{ "id": "rope", "stackSize": 50 }
]
}
// comments and trailing commas are allowed.
| Field | |
|---|---|
id | Item id. A game item's id changes that item |
copy | Start from this item (any id, also another mod's) |
model | Use this item's held, drop and place prefabs (and icon, unless icon is given) |
name, description | Shown in the UI |
type | Tool, Block, Building, Resource, Station, Parts, Clothing |
stackSize | 1, 5, 10, 20, 50, 100 or 500 (the game's sizes) |
icon | icons/jam.png (PNG/JPG in the mod), item:<id> (a game item's icon) or bundle/path:Asset |
heldPrefab, dropPrefab, placePrefab | bundle/path:Asset Name, from an AssetBundle in the mod |
food, poison, keepOnDeath, spoilDays, durability | As the Items table |
fuel, burnTemperature, burnsInto, burnYield | Campfire fuel |
cooksInto, cookTime, byproduct, smeltsInto, smeltTime, smeltTemperature | Cooking and smelting |
equipSlot (Hat, Top, Bottom, Boots, Backpack), bagSlots, armor, warmth | Clothing |
blockType (normal, roof, glass, mesh: decides the shapes), blockHealth, blockMaterial (bundle/path:Material) | Blocks |
The game's Items table loads with the world, after the mods. Mod items are rebuilt and put back every time the item
list changes, so copy, model and changes to game items work in the world even though those items don't exist in the
main menu yet. Turning a mod off puts the game's own item back.
AssetBundles must be built with this game's Unity version (6000.6). Prefabs used as item models are only looks (networked objects: see Network prefabs).
Recipes (recipes.json)
{
"recipes": [
{ "result": "berry_jam", "count": 1, "category": "Food", "craftTime": 3,
"ingredients": [ { "item": "blueberry", "count": 5 }, { "item": "clay_pot", "count": 1 } ] }
]
}
id (default: the result), result, count, category (a Recipe Book tab: Tools, Materials, Building, Weapons,
Equipment, Food, Other), station (e.g. Workbench; empty = by hand), stationTier, craftTime, requiresBlueprint,
ingredients. A recipe with a game recipe's id replaces it.
Data files (no code)
Besides items.json and recipes.json, a mod without code can bring these (all optional, // comments allowed). Each
entry can start from a game one (copy) and change only what it names. Everything goes when the mod is turned off.
| File | Lists | Fields |
|---|---|---|
effects.json | effects | id, copy, name, description, icon (PNG, item:<id>, bundle ref), buff, seconds, maxSeconds, stacking (refresh / extend), healthPerSecond, regenMultiplier, stopsRegen, hungerDrainMultiplier |
food | item, effect, seconds: eating the item gives the effect | |
crops.json | crops | id, copy (a game crop: its growth models), name, seed, produce, growMinutes, yield / seeds ([min, max]), regrows, seasons (["Spring", "Summer"]), stages (bundle prefab refs) |
trades.json | trades | npc (otto, margit, viggo, rosa, gunnar, ylva, pell, sabine), item, price, stock, buys (the NPC buys it instead) |
dialogue.json | lines | npc (empty = every NPC), text: another "Tell me more." line |
options | npc, text (the player), answer (the NPC) | |
worldtypes.json | worldTypes | id, name, startsFrom (Island, Archipelago, Highlands, Lakelands), flat, hills, mountains, erosion, lakeSize, caves (times the shape's), mountainShare, land (0..1), rivers, lakes |
assets.json | From the mod's AssetBundle ("Bundles/content:Assets/.../X.asset"): materials, biomes, scatter ([{ "set": ref, "biome": "Pine Forest" }]), animals (their stage prefabs are registered as network prefabs), birds, fish, npcTypes, npcs, music, sounds ([{ "set": "Tools/Axe/Chop", "clips": [refs] }]) |
// trades.json
{ "trades": [ { "npc": "viggo", "item": "sulfur", "price": 6, "stock": 20 } ] }
Mod creator (Mods ▸ Create)
Data mods can be made inside the game: Mods ▸ Create. Pick New mod (or one of your mods without code) and a
section: General (name, id, version, author, description), Items, Recipes, Effects, Food effects, Crops, Trades,
Dialogue lines, Dialogue choices, World types. List sections show their entries on the left (Add / Remove) and the
chosen one's fields on the right; fields left empty aren't written. Item, effect, NPC and crop fields have a picker
(with the game's items and icons, and the mod's own). Save writes the mod's JSON files into the Mods folder (a new
mod gets a folder named after it); turn it on in the Mods list to try it. Open Folder shows the files (to add PNG
icons, which icon fields name). Leaving with unsaved changes asks first.
Worlds and mods
A world's save remembers the mods it was played with (id, name and version; players' own client mods left out). Loading it from Play when one of them is off or another version asks first: their items, blocks and other things may be lost when the world is saved.
Code (*.dll)
The easiest way to make code mods is the Mod Kit: a Unity package with the game's API, so mods are made in Unity with prefabs, models and networked components, and built with one button.
The game uses Mono, so mods can be C# assemblies. Every .dll in the folder is loaded; each non-abstract class
deriving from SeedsAndCircuits.Mods.Mod is created once (parameterless constructor) and gets:
| Method | When |
|---|---|
OnLoad() | The mod is turned on: at start, in the Mods screen, or when joining a host that has it |
OnWorldLoaded() | The world is running (host and players) |
OnUpdate() | Every frame while the mod is on |
OnGUI() | Unity's immediate-mode GUI (GUI.*): simple screens and overlays (the Waypoint Map draws its map here) |
OnWorldUnloaded() | Leaving the world |
OnUnload() | The mod is turned off (or the game quits): undo everything OnLoad did |
OnPlayerConnecting(ModConnection) | Host: someone asks to join (ClientId, PlayerId, PlayerName). Return a reason to turn them away |
OnPlayerJoined(clientId) / OnPlayerLeft(clientId) | Host: a player is in (the host itself too) / left |
OnSavingWorld() | Host: the world is about to be saved; put the latest state in WorldData |
Helpers on Mod:
Info, Folder | mod.json (id, side, hash...) and the mod's folder |
DataFolder | <persistent data>/ModData/<id>/ for the mod's own saved files |
IsServer, IsClient, IsHost, LocalClientId | Where this copy runs in the current game |
WorldName | The save this machine hosts (null on players) |
WorldData | Host: the mod's data in the world save (below) |
AddKey(name, keyboard, gamepad) | A rebindable key (below) |
AddToggle / AddSlider / AddChoice | Settings on Settings ▸ Mods (below) |
OnMessage(name, handler) | Receive messages this mod sends from other machines (msg.Sender, msg.Data, msg.Text) |
SendToServer(name, data) | To the host (works on the host too) |
SendToClients(name, data) / SendToClient(id, name, data) | Host: to every player (the host included) / one player |
RegisterNetworkPrefab(name, gameObject), SpawnNetworkPrefab(name, pos, rot) | Networked objects (below) |
Log, LogWarning, LogError, GetPath, ReadText, LoadTexture, LoadAssetBundle, LoadAsset<T> | Logging and the mod's files (textures and bundles are freed with the mod) |
Json.ToJson(obj, pretty), Json.FromJson<T>(text) | Save/send your own classes as JSON (static, in SeedsAndCircuits.Mods) |
Use Json, not Unity's JsonUtility, for classes in a mod: JsonUtility only knows types from assemblies Unity
compiled, so a mod's classes silently come out as {}.
Json works by reflection: public and [SerializeField] fields, strings, numbers, bools, enums, lists, arrays,
string-keyed dictionaries, nested classes, Vector2/3/4, Quaternion, Color.
Messages take byte[] or a string; names are per mod (two mods can both use "sync"). They're reliable and ordered.
Mods may use any public game API (SeedsAndCircuits.*.dll, e.g. ItemCatalog, RecipeCatalog, PlayerSpawn,
TownNpc, Compass.CollectMarkers), Unity and Netcode. Static [ConsoleCommand] methods become console commands
while the mod is on (outside the console's namespace write [ConsoleCommandAttribute(...)]); commands without
Local = true run on the host (for the host, and for players it gave the console with op).
- Assemblies are loaded from bytes (the files stay unlocked, and two versions of a mod can be loaded in one run). They can't be unloaded: a mod turned off stops getting calls, but its code stays in memory until the game quits.
- An exception in a mod is logged and shown on its row in the Mods screen; it doesn't stop the game.
OnUpdateandOnGUIerrors are logged once per mod. - Several assemblies in one mod (or a mod depending on another mod's assembly) find each other by name.
- Prefer the
Modcalls over your own MonoBehaviours: classes from DLLs loaded at run time can't always be added as components.
World data (saved with the world)
WorldData is the mod's part of the host's world save: text or any object (as JSON) by key. It's loaded with the
world (read it in OnWorldLoaded), saved with it (OnSavingWorld runs just before), and moves, copies and gets
deleted with the world. A new world starts empty. Only the host has it: send players what they need.
public override void OnWorldLoaded() { if (IsServer) _stats = WorldData.Get("stats", new Stats()); }
public override void OnSavingWorld() => WorldData.Set("stats", _stats);
Data of mods that are off stays in the save. Things a player keeps for themselves (their own waypoints) go in
DataFolder instead.
Game events
SeedsAndCircuits.GameEvents (static events, assembly SeedsAndCircuits.GameEvents) tells mods what happens in the
world. All fire on the host only, once per thing:
| Event | Arguments |
|---|---|
PlayerDied / PlayerRespawned | player GameObject, cause (Damage, Hunger, ...) |
FoodEaten | player, item id |
ItemCrafted | player (null: a station on its own), station id (null: by hand), item id, count |
ItemPickedUp | player, item id, count |
BlocksPlaced / BlocksBroken | item id, block-grid cells |
PropPlaced | item id, position, player (or null) |
TreeFelled | tree kind, position |
AnimalKilled | animal, species, killer (player or null) |
DayStarted | day number (also when sleeping past midnight) |
SeasonChanged | Spring / Summer / Autumn / Winter |
Subscribe in OnLoad, unsubscribe in OnUnload. A handler that throws is logged and doesn't stop the others.
Keys
AddKey("Open Map", "<Keyboard>/m") (optional gamepad binding) returns an InputAction: check
WasPressedThisFrame(). Each mod's keys are listed on Settings ▸ Controls as "Waypoint Map: Open Map" and rebound
like the game's keys (a player's bindings are kept while the mod is off). They're only on while the game's own Player keys are and the
mouse is captured, so not in menus, the inventory or other item windows, the console or while loading.
Screens
A mod that shows its own screen over the game (a map, a menu) sets ScreenOpen = true while it's up: the cursor
is freed and the game's controls are off like in its own screens (moving, looking, tools, hotbar keys and mouse wheel,
interacting, opening the inventory). Escape calls OnCloseScreen() instead of opening the pause menu; ScreenOpen goes
back to false then, and when the mod turns off.
World map
TerrainWorld.Instance.MapArea(center) is the world's rectangle (or a square around center in a flat world) and
RenderMap(area, size, pixels, firstRow, rowCount) draws a top-down map of it into a Color32[] (ground colours,
water, hill shading) from the terrain data, so it works for unloaded land and on clients. Burst job: a 512² map is
~20 ms; draw some rows per frame for big maps (the Waypoint Map does 128 rows of 1024 a frame).
Settings
AddToggle(key, label, default), AddSlider(key, label, min, max, default, step) and AddChoice(key, label, options, default) put rows on Settings ▸ Mods (a header per mod), in both the main menu and the pause menu. Read
.Value (.Index for a choice) and listen to .Changed. Values are stored per player with the game settings, so
they follow the settings screen: changes show at once, Apply keeps them, Back undoes them.
Network prefabs
RegisterNetworkPrefab("beacon", go) in OnLoad (on every machine, so only in both mods) makes a prefab Netcode can
spawn; the host calls SpawnNetworkPrefab("beacon", position, rotation) and every player sees it. A GameObject built
in code becomes a hidden template (it gets a NetworkObject); an AssetBundle prefab needs a NetworkObject already.
The prefab id comes from the mod id and the name, so it's the same everywhere.
Netcode's own components (NetworkTransform, NetworkRigidbody...) work on them. NetworkBehaviours of your own
(RPCs and NetworkVariables) need Unity's code generation: they work in mods built with the Mod Kit, not in mods built
with dotnet build. Without the kit, sync your own state with messages.
Adding content from code
Everything a Mod adds with these is taken out again by itself when the mod turns off (WhenTurnedOff(action) does
the same for your own registrations). Assets (species, biomes, clips, prefabs) come from the mod's AssetBundle
(LoadContent<T>) or are made in code. Content everyone has to agree on (items, species, crops, world generation,
music) belongs in a both mod, added in OnLoad, so the host and every player have it.
| Call | Adds | Game side |
|---|---|---|
AddItem(ItemDefinition), AddRecipe(CraftingRecipe) | Items and recipes from code (items.json / recipes.json are simpler and can change game items) | ItemCatalog, RecipeCatalog |
AddResearch(ResearchDefinition) | A blueprint researchable at the research table | ResearchCatalog |
AddStatusEffect(StatusEffectDefinition), AddFoodEffect(item, effect, seconds) | Buffs and sicknesses; food that gives them | StatusEffectBook.AddEffect/AddFoodEffect |
AddCrop(CropDefinition) | A farm crop (its seed item plants it) | FarmingSettings.AddCrop |
AddTool(ToolStats), AddArrow(ArrowStats) | Make an item a tool or weapon of a kind the game has (axe, pickaxe, spear, bow, rod...) | ToolSwing.AddTool/AddArrow |
AddAnimal(AnimalSpecies), AddBird(BirdSpecies), AddFish(FishSpecies) | Wildlife (register its prefabs with RegisterNetworkPrefab first) | Wildlife/Birds/Fishes.AddSpecies |
AddNpcType(NpcType), AddNpc(NpcDefinition), AddTrade(character, item, price, stock, sells) | Town roles, characters, trade lines (after the character's own, so saved stock still matches) | Town.AddType/AddCharacter/AddTrade |
AddSounds(set, clips), AddMusic(clip) | A new sound set or one of the game's replaced (Resources/Sfx folder names); music tracks | Sfx.AddClips, Music.AddTrack |
AddBiome, AddScatter, AddWorldType, AddTerrainMaterial | World generation (below) | TerrainModding |
AddNpcJob, OnNpcSpawned, AddDialogueOption/Opening/Line, AddAnimalBehaviour | Behaviour of NPCs and animals (below) | Town, Dialogue, AnimalAgent |
Anything else is plain Unity code: a mod's MonoBehaviours, its own prefabs (also as placeable items: placePrefab
with a component implementing IInteractable / IAttackUse is interacted with like the game's objects), messages,
world data and game events make whole new systems.
World generation
Generated worlds are worked out on every machine from the seed, so a mod can change them as long as it does the same
everywhere (a both mod) and takes its randomness only from world.seed. In order, while a world starts:
| Hook | When | Change |
|---|---|---|
OnConfigureWorld(world, ref landscape) | Before the map is made (also for previews) | ProceduralWorldParams: hill/mountain heights, mountain and land share, erosion, rivers, lakes, lake sizes |
OnMapGenerated(world, map) | The map is made, nothing has read it yet | ProceduralMap: Heights (640 × 640, index x + z * 640, cell x, z at map.Origin + (x, z) * map.Cell, metres), Moisture (0..1), Kinds (Land, Sea, LakeCell, RiverCell), Lakes, Sites. Edit in place; the map's hash (desync check) is redone after |
OnBiomesGenerated(world, biomes) | Climate biomes are placed | TerrainBiomePainter: SetCell(x, z, biome) / Paint(center, radius, biome) over 4 m cells, GetCell |
OnConfigureGround(world, ref ground) | Every world's ground (play mode) | TestGeneratorParams: caves (CavesEnabled, CaveDensity, CaveCellSize...), strata, ores, surface noise |
AddWorldType(id, name, startsFrom, flat)adds a choice to New World ▸ World. The world savesworld.type = id; the mod checks it in the hooks. A world of a type whose mod is gone loads as the type's starting shape.AddBiome(TerrainBiomeDefinition)adds a biome after the game's (climate biomes grow where their moisture/height/slope ranges hold; natural ones by noise; any can be painted).AddScatter(TerrainScatterSet, biomeName)adds trees, plants, rocks, pickups and grass to a biome (null: every biome).TerrainModding.FindBiome(name)finds the game's.AddTerrainMaterial(TerrainMaterialDefinition)adds ground a biome, strata layer or ore can be made of: textures of any size (top, and optional sides; albedo, normal, height), tint, tiling, smoothness, hardness, tool tier, drops. When a world starts, the game makes a play-time copy of its material database with the mods' materials after its own, and texture arrays with a slice for each (the game's slices copied on the GPU, the mods' scaled in). Ids follow the game's in mod order, so host and players need the same mods, and digging/building saved with a mod material keeps its id (without the mod it shows as another material).- Generated worlds also have outer islands:
OnMapGenerated/OnBiomesGeneratedrun once for each, when it's made (also during play), with that island's seed and size. Its map starts atmap.Params.Offset(zero for the start island; the painter's cell (0, 0) is the island's corner). - Set things up before the world starts (
OnLoad); a running world keeps what it was made with. - Code that isn't a mod can use
SeedsAndCircuits.Terrain.TerrainModding(the same events and lists) directly.
NPC and animal behaviour
Behaviour runs on the host; everyone sees the result.
- NPC jobs.
AddNpcJob(roleId, npc => new MyJob())gives every town NPC of a role ("citizen","shopkeeper"...; null = all) anINpcJob:WantsToWork(npc)is asked every frame, and while it's trueWork(npc, deltaTime)runs instead of the NPC's own day (bedtime still sends it home to bed). Return null from the maker to leave an NPC to the game (shopkeepers keep their shop). NPCs already in the world get the job at once.OnNpcSpawned(npc => ...)runs for each NPC as it comes into the world;Town.Agentslists them. - What NPCs can do (
TownNpc, host):WalkTo(point),StandAt(spot, yaw),Say(text, seconds)(a speech bubble everyone sees),PlayAction(state, seconds, speed)(a state of the character animator's Actions layer:Tool_Chop,Punch_R,Punch_L...),LookAt(point)/StopLooking(),Hold(itemId)(the item's held model in its right hand; null = nothing),SetWorking(bool),HoldForTalk(playerPosition). - Dialogue (each player's machine):
AddDialogueOption(text, npc => answer, npc => shows)adds a choice to the talk window (the answer replaces the NPC's text; send a message to the host to change the world),AddDialogueOpening(npc => line or null)what NPCs say first,AddDialogueLine(characterId, line)more "Tell me more." lines (null = every NPC). - Animals.
AddAnimalBehaviour(speciesId, animal => new MyBehaviour())(null = every species): itsThink(animal, now)runs five times a second before the animal thinks itself; return true to decide for it this time (GoTo(point, run),Stop(),LieDown(sleep),FaceTowards(point)), false to let it be. Its own state (Species,IsDead,IsMoving, herd and taming) stays as it is.
Examples
| Mod | Side | Shows |
|---|---|---|
| Berry Jam | both (data) | items.json (new item copying another, changing a game item), recipes.json |
| Hello Mod | both | Lifecycle, console commands, OnPlayerJoined greeting, ping/pong messages, a network prefab (hello.beacon), game events counted into world data (hello.stats) |
| Waypoint Map | both | M (rebindable) opens a map of the whole world, drawn from the terrain data (TerrainWorld.RenderMap) right after the world loads, centred on you (arrow = where you look). Drag: pan. Scroll: zoom. Click: private waypoint (saved on your machine per world). Shift+click: shared waypoint (kept in the world save, WorldData, and sent to everyone). Right-click: remove. Waypoints show on the compass. Settings: waypoints on the compass, map size. Console waypoint.add <name> [shared], waypoint.remove, waypoint.list |
| Trader Compass | client | Wandering traders show on the compass as gold diamonds (range on Settings ▸ Mods, default 300 m). Console traders |
| Volcano Island | both | World generation: a world type (New World ▸ World ▸ Volcano Island) whose island gets a volcano with a crater lake (OnMapGenerated), ash fields (a biome and a terrain material made in code, AddBiome, AddTerrainMaterial, OnBiomesGenerated), lower hills elsewhere (OnConfigureWorld) and more caves (OnConfigureGround); Viggo sells sulfur (AddTrade) |
| Town Life | both | Behaviour: NPCs carry a lantern about in the evening (AddNpcJob, Say, Hold), tell you about animals nearby (AddDialogueOption) and a line of gossip (AddDialogueLine); pigs follow anyone holding a carrot (AddAnimalBehaviour) |
| Ban Hammer | server | ban <player name or clientId> [reason] kicks and keeps a player out (OnPlayerConnecting), unban <name or id>, bans. Bans are per host machine, by player id (a GUID the player's game keeps: it says who they are, it doesn't prove it) |
Each one is on the website's Mods page (tagged example) to install, and its source is on the wiki (Example mods).
Mods screen
Main menu ▸ Mods: every installed mod with name, version, author, side and description; a switch to turn it on or
off (at once, no restart) and Delete (click twice). Problems (bad mod.json, missing dependency, duplicate id, load
errors) show in red under the mod. Browse lists the mods on the website with Install / Update. Open Folder
opens the Mods folder. Create opens the mod creator. The list is read again each time
the screen opens.
Multiplayer
When a player joins a host:
- They must run the same
bothmods as the host (same files). Missing ones are offered for download from the host, and a mod's code is marked so players know it runs code. - The host's
clientmods are offered too, ticked by default; the player can untick them. - The host's
servermods are never sent or compared, and the player's ownclientmods always stay on. - A different build of the game can't join ("You have a different version of the game than the host.").
- Any running mod on the host can turn a player away with a reason (
OnPlayerConnecting); the player sees the reason. - Leaving the game brings back the player's own mods.
Console
| Command | |
|---|---|
mods | Installed mods: on/off, version, hash, code/downloaded, problems |
mods.active | The mods running now, in load order |
mods.declined [clear] | Hosts' client-side mods you turned down; clear has hosts offer them again |