Mods
A mod is a game feature plugin in its own folder, made against a released build of your game. Players drop it into the game's mod folder; Gantry checks it, mounts it, and its experiences join the experience tree next to the game's own. The game never needs a list of mods.
What a mod can do is whatever an experience can do: add a new game mode to the game's list, change an existing mode every time it runs, add settings pages, UI, input and data.
Taking mods in your game
In Project Settings > Plugins > Gantry Experience:
| Setting | What it does |
|---|---|
| Mod Directories | Folders, next to the packaged game's .uproject, that hold mods. Mods is the usual choice. |
| Mount Mods At Startup | Mounts every mod in those folders when a game or server starts. The editor mounts on request instead. |
| Mod Rescan Interval | Seconds between looks at the folders while the game runs. Above zero, a mod copied in is mounted within a moment. |
That is all the game needs. Gantry logs every mod it mounts, refuses or replaces;
Gantry.Mods.Report prints the list at any time.
How a mod finds its place
A mod's experience cannot be listed in your game's assets, so it says where it belongs:
- A new game mode sets Attach To to the experience it goes under. In the example game, a new round attaches to the rounds' parent, so it appears in the lobby's list of rounds.
- A change to an existing mode sets Extends to that mode's tag. Whenever the mode activates, the mod's experience activates right after it. The mode never names the mod. Set Attach To as well, usually to the base experience, so the mod has a place in the tree.
- Something that needs another mod uses Optional Dependencies, or depends on that mod's
plugin in its
.uplugin, which also makes it mount after the other mod.
Mounting only makes a mod's experiences known. Nothing of it activates until an experience in the chain lists or extends it, exactly like the game's own content.
What players install
A mod is a folder in the mod directory:
Mods/
LowGravity/
LowGravity.uplugin the game feature plugin (Explicitly Loaded)
Config/ its own gameplay tags and config
Content/Paks/<Platform>/ its cooked content
Or the same folder packed into one .gantry file, which is easier to hand to players: a zip of
the .uplugin, Config/ and Content/Paks/<Platform>/, stored rather than compressed. Gantry
unpacks it into a folder beside it and mounts that. Removing the file removes the folder at the
next look or the next start. A .gantry file holds one platform's mod.
What Gantry checks
Gantry judges a mod before mounting anything of it, and refuses it, with the reason in the log, when:
- its
.upluginis not Explicitly Loaded; - its name is already taken by another plugin or content root: the game's, the engine's or another mod's;
- it carries C++ code and the game cannot load code (see below);
- it was cooked against a different build of the game: a package it uses is not in this one;
- it is incompatible: its game feature data or an experience in it needs another game version (see compatibility).
A mod refused after mounting, for example by the compatibility check, is unmounted again, so none of its content stays readable.
When mods overlap
Two mods may ship the same thing, or a mod may replace something of the game's. That is allowed,
and never silent. After each mount, the log and Gantry.Mods.Report list:
- assets provided more than once, and which copy wins: the mod mounted last, with a mod that builds on another mounting after it;
- experiences sharing a tag, a guid or an asset name. The tree keeps the first;
- config keys two mods set differently, or a mod sets differently from the game, and redirects that rename content outside the mod's own folder.
Compatibility
Every experience, and every game feature plugin whose data asset is a Gantry Game Feature
Data, carries which engine and game version it was cooked against, and which game versions it
supports (Metadata > Required Game Version). Gantry's game feature policy refuses a plugin
that does not match this build before it mounts, and an incompatible experience shows as
Incompatible in the tree, with the reason, and never activates. During development, set
bEnforceCompatibility=False to log mismatches instead of refusing them.
Getting Started has the setup.
While the game runs
With Mod Rescan Interval above zero, a mod folder or .gantry file copied in is mounted within
a moment, and its experiences join the tree at the next activation. A game that builds its list
of modes from the tree offers the new one from its next lobby. Mods already mounted stay as they
are.
Gantry.Mods.Unmount and Gantry.Mods.Remount take mods out and put them back without a
restart. A mod whose experience is running, or that another mounted mod builds on, stays, and the
log says why. In the editor, Gantry.Mods.Mount mounts the mod folders on request.
Content mods and code mods
Mods made of assets, Blueprints and data work in every build of the game, Blueprint-only projects included. A mod with C++ modules needs a game that can load code from a plugin: the editor, or a game built "modular" from a source engine. A normal packaged game is one executable, and there Gantry refuses a code mod before mounting anything of it, saying that this game takes content mods only.
Making a mod
A mod is made in a copy of the game's project and cooked as DLC against a released build, so it holds only its own content:
- Package the game with
-createreleaseversion=<release>. This records the release. - Cook the mod with the stock BuildCookRun:
-cook -stage -pak -dlcname=<path to the mod's .uplugin> -basedonreleaseversion=<release>. Gantry mounts the mod, and any mods it builds on, inside the cook so the cooker can find it. - Copy the staged
.pak,.utocand.ucasfiles into the mod'sContent/Paks/<Platform>/. - Ship the folder, or pack it as a
.gantryfile.
The mod guide walks through it, and the GantryExamples project includes three example mods: a new round, a change to an existing round, and one made for a newer game that Gantry refuses.
Mods in multiplayer
The server decides which experiences run, and every client must be able to run the same chain. A client that lacks a mod the server is running refuses, and Gantry reports why, naming both chains. Install the same mods on every machine. See Multiplayer.