Modding: Work In Progress
Decorate vanilla maps through the server config, or build entirely new maps in the Holdfast SDK.
This page collects the current map making pipeline from several years of notes in the modding channels, SDK release notes, the Server Configuration reference, and Server Configuration Enums. It supersedes the older Map Editing page, which was written around the now-removed flat CustomMap. Content is still being checked against the live SDK. Sections marked Verify need confirmation.
EngineUnity 2022.3.62f1 (SDK v2.31)
Scale1 Unity unit = 1 metre
Water LevelY = 0
DistributionSteam Workshop

How Map Making Works

"Map making" in Holdfast covers two very different workflows. Pick the right one before you start:

Route 1: Config-Based Map Editing

Customise vanilla maps through the server configuration file: spawn props and weapon racks with objects_override, move spawns and capture points, change class limits, weapons, and weather until the map plays like something new. No tools beyond a text editor are needed, and changes apply per map rotation.

Route 2: SDK Map Building

Build entirely new maps in the Unity-based Holdfast SDK — your own terrain, water, props, spawns, and game modes — and ship them through the Steam Workshop. Servers then load them with mods_installed + load_mod and map_name modmap (see Loading a Workshop Map).

Cross-play changes the trade-off. Loading a map (or script) mod flips a server to Steam-only — console players cannot join. Config-based objects_override editing is the only "map modding" that works on cross-play servers, which is why it has seen renewed interest since mid-2025. See Mods and Consoles.
The flat starter maps are gone. Older guides (including the previous Map Editing page) are built around map_name CustomMap and CustomMapNaval — two flat, empty maps. Naval CustomMap was retired around January 2024 (Open Waters does practically the same thing) and the flat land CustomMap was removed later. Neither appears in the current map name enums. Build on an existing vanilla map, or subscribe to one of the community-published flat-plane Workshop maps instead.

Loading a Workshop Map

The single most-asked question in five years of modding chat. Loading a custom map from the Steam Workshop takes three config entries:

# Global section (top of config, NOT inside a rotation).
# The comment after # is ignored — use it to label your mods.
mods_installed 2101070095   #My Map Name

# Inside the rotation:
!map_rotation start
map_name modmap
map_name_override Swamp Town
game_mode ArmyBattlefield
# ... your usual rotation settings ...
load_mod 2101070095
!map_rotation end
  • mods_installed <workshopid> installs the mod on the server. The ID is the long number in the mod's Steam Workshop URL. One mods_installed line per mod — putting two IDs on a single line breaks the server.
  • map_name modmap tells the rotation to use whatever modded map is loaded instead of a vanilla map. For non-map mods (uniforms, sounds, scripts) use the same mods_installed + load_mod pattern but do not change map_name.
  • load_mod <workshopid> loads the mod for that rotation. Convention is to put it just above !map_rotation end. You can stack multiple load_mod lines — one map mod but any number of skin/uniform mods per rotation.
  • map_name_override <name> gives the map a proper display name in the map list, RC map menu, and admin panel instead of a generic "modded map" label. It works on vanilla rotations too.
  • Restart the server after editing the config or updating the Workshop item — or hot-reload while iterating, see Iterating Without Restarts.
  • The spelling is load_mod. A circulating example config uses mod_loaded, which does not work.
There is no CommanderBattle game mode enum. For the popular Commander Battles mod, use game_mode ArmyAssault in the rotation. Game mode enums are listed on Server Configuration Enums.

See Server Configuration for mods_installed_server_only, load_mod_client_only, load_mod_server_only, and mod variables.

Rotation Setup & Base Maps

When editing a map through config you'll spend a long time placing objects, so set up a dedicated sandbox rotation with an unlimited timer and open spawns:

!map_rotation start
map_name SpanishFarm          # any vanilla map enum — see Server Configuration Enums
game_mode ArmyBattlefield
round_time_minutes -1
reinforcements_per_faction 9000
wave_spawn_time_seconds 1
max_player_respawns -1
faction_balancing false
allow_midround_spawning true
allow_faction_switching true
allow_spectating true
minimum_players -1
maximum_players 150
time_hour 8
time_dynamic false
friendly_fire true
weather_preset calm
weather_dynamic false
game_type hardcore
!map_rotation end

Choosing a Base Map

  • With the flat CustomMap removed, start from a relatively open vanilla map (see the map name list) or subscribe to a community flat-plane map on the Workshop and load it as a mod map.
  • Editing vanilla maps by spawning props via config needs no SDK at all, though it is wonkier and more limited than building the map properly in the SDK.
  • Config prop placement and Workshop mod maps stack: you can objects_override on top of a loaded mod map too.

Positioning

Before placing a prop, decide where it goes and which way it faces. Stand where you want it in-game, open the console with F1 and type get. This prints your position and rotation:

playerPosition => (15.3, 16.8, 146.9)
playerRotation => (0.0, 218.0, 0.0)
  • Position is (X, Y, Z). Positive X is North, positive Y is up, positive Z is West.
  • Rotation is degrees around (X, Y, Z). You'll use Y most to turn objects; X and Z tilt.
  • To face the opposite direction of the example above, use (0.0, 38.0, 0.0) (218 - 180).
  • get playerPosition and get details copy the values to your clipboard for pasting straight into the config.

Placing Props

Props range from simple decor (position and rotation only) to interactables with extra parameters. All objects_override lines go between !map_rotation start and !map_rotation end.

Decorative Props

objects_override <prop> <pX> <pY> <pZ> <rX> <rY> <rZ>
  • <prop> — Enum from the Spawnable Props list
  • <pX> <pY> <pZ> — Position (use get playerPosition)
  • <rX> <rY> <rZ> — Rotation (use get playerRotation)

Example — a target dummy:

objects_override TargetDummy 15.3 16.8 146.9 0.0 218.0 0.0
Only props on the Spawnable Props list can be placed via config or the F1 console. The list has been accused of being out of date, but spot checks (e.g. TargetDummy after the Frontlines update) pass; treat individual entries with mild suspicion rather than distrusting the whole page. Expanding the list (and a mod-map-to-config exporter) has been floated by AGS but not committed to.

Weapon Racks

Players hold E to take weapons from a rack (limited supply).

objects_override WeaponRack <pX> <pY> <pZ> <rX> <rY> <rZ> <Weapon> <Count 0-255>
  • <Weapon> — Enum from Weapon. Racks accept melee weapons too, not just firearms.
objects_override WeaponRack 1 2 3 7 8 9 Rifle_Pattern1800Infantry 4
objects_override WeaponRack 286.81 17.98 469.46 0.00 161.02 0.00 Axe2H_Variation1 255

Firearm Ammoboxes

Customisable ammo boxes for roleplay and events. Players replenish ammo on use.

objects_override firearmammobox <pX> <pY> <pZ> <rX> <rY> <rZ> <Firearm> <Max Uses> <Ammo Given> <Max Uses Per Player>
  • <Firearm> — Enum from Firearm
  • The three counts are each 0-255: total interactions until depletion, rounds given per use, and the per-player cap.
objects_override firearmammobox 1 2 3 7 8 9 Rifle_Pattern1800Infantry 20 2 1
Ammo boxes are firearm-specific while class weapon overrides are category-based, so you cannot force a whole faction onto one particular musket through this system.

Spawns, Capture Points & Ships (Config)

Dynamic Capture Point

A round-ending capture flag can be spawned from config on any map, including naval ones — this is how the community built a "Sea Race" mode:

dynamic_capture_point_enabled true
dynamic_capture_point_position <X> <Y> <Z>
dynamic_capture_point_auto_active_time 1190
dynamic_capture_point_capture_duration 360
dynamic_capture_point_max_capture_player_count 1
  • auto_active_time counts from round end, not round start. On a 20-minute (1200 s) round, a value of 1190 makes the flag appear 10 seconds after the round starts; a value of 10 makes it appear 10 seconds before the round ends.
  • dynamic_capture_point_capture_duration reportedly has no effect (the capture timer stays around 40 s), and capture_point_override with objective letters didn't change it either. Verify
  • Manual alternative: an admin types rc set triggerDynamicCapturePoint. An rc delay entry in the rotation can automate the trigger.

Custom Ship Spawn Positions

A working recipe for placing ship spawns at exact positions (used for a naval training map):

objects_override shipspawnsection 374.48 0.30 333.60 0.00 156.12 0.00
ships_spawn schooner2gun 1 french 0
ships_spawn Schooner2gun 1 British 1
  • The map's spawn section must be set up for Naval Battlefield in the SDK; grab the coordinates in-game with get playerPosition.
  • Known limitation: only one custom-positioned ship spawn works at a time. Functional (sailable) ships cannot otherwise be spawned at an exact position.
  • See Server Configuration for ships_spawn, ships_spawn_detail_override, and ships_health_detail_override.

Spawn Timing Tricks

  • One-life-style custom spawn waves: rc delayed <seconds> set characterRespawnTime 9999999 inside the rotation.
Starting-weapon overrides leak between rotations. Changing class weapons on one map can carry over to other maps in the rotation. Workaround: explicitly (re-)set the weapon override — even back to the defaults — on every map in the rotation.

Iterating Without Restarts

While building, you'll change the config constantly. Reload it without a full server restart:

rc fileReloader serverConfigFile
rc mapRotation 1
  • Substitute the correct rotation index. rc mapRotation re-enters the rotation immediately — don't wait for the round to end.
  • rc set endRound then advancing naturally works better for some cases (e.g. testing round-end behaviour).
  • If the rotation loads a Workshop mod, the mod re-downloads each time you switch to it after changing the Workshop upload.
  • When the Workshop mod itself is updated, restart the server rather than relying on the hot reload.

See Remote Console Commands for the full RC reference.

SDK Setup & Unity Versions

Basic Unity familiarity helps, but map building requires no programming.

  • The SDK currently targets Unity 2022.3.62f1 (SDK v2.31); 2022.3.53f1 also works since the May 2025 compatibility fix. Using any other version is the most common source of broken projects — check the SDK Version History if you are upgrading an old map.
  • Install the SDK and set up your first mod following SDK Tutorial #1 – Getting Started and #2 – Creating A New Mod. The official SDK documentation covers the level editor end to end; the SDK User Guide lists all 22 video tutorials.
  • Up-to-date Unity download links are maintained in the #become-a-modder Discord channel.
  • Scale is 1:1: one Unity unit is one metre. Drop the default 1 m³ cube into the scene to gauge distances.
  • Vanilla map terrains and heightmaps ship with the SDK — you can study or reuse their terrain data, but full map scenes cannot be opened.
A large SDK asset drop is tied to the upcoming naval update (not the 2025 Scottish-themed update), alongside talk of exposing mod-bundle props to the config spawn system. Expect the props library to grow.

Hierarchy, Layers & Colliders

Scene Hierarchy

Follow SDK Tutorial #3 – Map Scene Hierarchy. The rules that answer 90% of support questions:

  • Gameplay props and buildings go under the Level parent.
  • Objects without colliders (visual-only) belong under Client — the server never needs them.
  • Small decorative items (cutlery, birds, clutter) go under Clutter so low-end clients can skip them.
  • Remove Rigidbody components from imported static props, or they'll behave as physics objects.

Layers (the most repeated SDK advice)

  • Terrain goes on the Terrain layer.
  • Props players collide with go on Layer 13: Static Environment.
  • The Default layer is a trap: players can stand on the object, but crouching, jumping, aiming, and weapon switching break — the game treats them as floating in mid-air.

Custom Walkable Props

For imported models players should walk on, use this pattern: an empty parent holding (a) the model child on Static Environment with no colliders, and (b) a separate empty on the Terrain/walkable layer holding primitive box colliders that approximate the shape.

  • For a simple house mesh, a non-convex mesh collider is acceptable; for most props prefer primitive boxes or a LOD mesh as the collider.
  • Don't tick Convex on a mesh collider if players must enter the interior — convex hulls seal it shut.

Useful Asset Names

  • Cavalry spikes: Chevaux de Frise.
  • Destructible artillery: GameAsset_Artillery_*_Destructible (e.g. GameAsset_Artillery_FieldGun_9PDR_Destructible, GameAsset_Artillery_Mortar_Naval_Destructible).
  • Decorative ship hulls: search "Brig" and similar in the props panel. Sailable ships cannot be placed as map props.
  • Spawn menu podium: place a normal SpawnMenuCharacterScreen, rotate it, then copy its rotation to the SpawnMenuCharacterScreenEmpty variant (the Empty variant's pivot is misleading). Its map-name sign is set up manually with TextMeshPro using the OptimusPrinceps font.
  • Loading-screen/ambient music: an Audio Source under Client → Ambient Sounds, set to 2D, no loop.

Tricks

  • Custom spawn flags: dismantle the vanilla British spawn-flag prop and swap the flag part's texture. Faction flag props can't be rescaled — the flag cloth is loaded per-faction at runtime.
  • Weather blocking underground areas: the SDK's own weather blockers don't work; an upside-down desert-gate asset scaled hugely on Y extrudes its built-in weather blocker over the area.
  • Fake destructible terrain: cover a pit with the SDK's dirt-pile props and mark the prop destructible.

Terrain, Water & Grass

Terrain

  • Start with SDK Tutorial #4 – Editing The Terrain.
  • Duplicating a terrain without losing textures/grass: duplicate the mapname_terrain.asset file under Terrain Collider → Terrain Data (Ctrl+D), rename it, and drag it into the scene.
  • Swapping terrain textures: use the SDK's Terrain Texture Replacer tool (Holdfast SDK Options → SDK Tools) — SDK Tutorial #18.
  • Import trees as props, not as Unity terrain trees (official AGS recommendation). Easy Scatter or a prefab brush speeds up placement.

Water & Naval Maps

  • The game's water level is Y = 0. While building, add a lake/sea water prop at Y = 0 as a visual guide — but delete it before uploading, or the game's own generated ocean overlaps it and you get two water layers.
  • The partial ocean system (ocean on one side, land elsewhere — Port Nile / Glacier / Mansion style) is exposed on the HoldfastMapModOverload root object.
  • The Limited Ocean area is roughly 7500 × 7500.
  • Rowboat spawners require the ocean — lake props are not enough. Their spawn obstruction check rejects any obstruction, not just ship colliders.
  • Newer water workflow (post early 2024): use the WaterSystem game asset, set Seabed Depth and tick Generate Seabed.

Grass & Vegetation (TVE)

  • Grass is now part of the base SDK — no extra download. Drag grass prefabs into the Grass script list on your terrain.
  • Floating or clipping grass: raise the terrain heightmap resolution, align the TVE/grass area box to the same coordinates as the terrain, and use the TVE Height Offset setting.
  • If grass breaks entirely, the reliable fix is deleting and redoing the grass + TVE elements, including the default grass area.
  • Not every plant asset works as painted terrain detail — only those on the "blanket shader" (which snaps to terrain). Incompatible ones glitch across the screen; place those with a prefab brush instead.
  • Multi-terrain maps have known, unresolved grass problems. Verify

Spawns, Capture Points & Game Modes (SDK)

Set up game modes with SDK Tutorial #6 – Setting Up Gamemodes.

2026 breakage — spawn points unselectable on modded maps. Since the mid-2026 update, older modded maps' spawn points can't be clicked in the spawn menu. Fix: move the map's Default Camera Position up into the sky so all spawn points are visible from it, then rebuild (SDK Tutorial #20 – Scene Camera Views covers the camera object). This currently affects every map built before the update.

Spawns

  • Spawn menu ordering: spawn points with larger capacity appear higher in the list.
  • Prefer spawn nodes over area colliders where placement matters — area spawns on sloped ground (e.g. Siege defenders) pick bad spots like the highest point.
  • Area/collider spawns place players on top of whatever is above the collider, so you cannot spawn players inside buildings or underground with them.
  • Players will spawn inside tent props unless you hand-place many small exact spawn positions around them.
  • Battle Royale mod compatibility: add a game object named Dynamic Spawn Positions containing 100+ empty children spread across the map.

Capture Points

  • The old GameAsset_Capture Mode Flag no longer exists. Use the functional_captureModeFlag asset placed under the capture point hierarchy, then map spawn sections to capture points and set capture requirements in the game mode section.
  • Duplicate objective letters (three points all showing "B") is a known setup pitfall — recheck the capture point indices.
  • The server error Spawn section tied with capture point -1 is null means a spawn section is linked to a capture point that no longer exists.

Game Modes

  • A map now requires the game mode's spawn objects to be enabled for the map to load in that mode. Disabling a mode's objects makes any rotation using that mode unloadable.

Performance & Optimisation

Watch the Batch Count

Batches are the number to watch, not triangle count. Above roughly 3,000 batches performance degrades noticeably; the Stats button in play mode shows it. Foliage overuse is the easiest way to blow it up (a bamboo grove alone has produced 8k batches).

Since the URP switch, many copies of the same mesh + material are cheap; the batcher suffers when many complex meshes use different materials. Small props should still be culled at distance — quad overdraw can cost more than batch overhead. Shadows remain the single biggest FPS cost.

Custom LOD Objects (Group Culling)

Distance-based group culling, added in the September 2022 SDK hotfix — see SDK Tutorial #16 – Custom LODs:

  • Put the script on the parent of a prop group; range is measured from that object's pivot.
  • First value = normal cull distance; second = spyglass cull distance (slightly higher).
  • Typical values are 50–75 for props inside buildings. Also excellent for culling point lights.
  • It culls groups; it does not override an asset's built-in LODs.

Fog Distance

Official guideline: measure from the centre of the playable zone to the centre of the first hill line, then double it (Island Plains: 550 m → fog 1100). Keep at least 900–1100 even on very small maps; naval maps use 4000–6000. Max fog distance is set on HoldfastMapModOverload.

Sizing Datapoints

  • A 4096×4096 single-terrain naval map works but lags at 120+ players; the same size split into four 2048 terrains performs slightly better. Naval public servers cap around 80 players for performance.
  • 300+ props is nothing to worry about — Rio Grande has roughly double that.
  • Terrain rendering (MicroSplat) is mostly GPU-side, and terrain instancing is enabled on terrains using the MicroSplat replacement material.
  • Occlusion culling is not available to modders and wouldn't help much on open maps.

Building & Uploading

Follow SDK Tutorial #7 – Play Testing and #8 – Uploading Mods. Steam must be running and logged in, with the Workshop terms accepted.

Rules & Workflow

  • Scripts must live in the same folder as the built scene; textures and models can be anywhere in the project.
  • Recommended loop: open Unity → edit → save → build → upload → close Unity before re-editing. If a "Steam Workshop Upload Scene" appears on reopen, that is not your project — use File → Open Recent Scene.
  • Give the map a proper thumbnail with SDK Tutorial #9 – Custom Map Images.

Common Failures

  • Upload failures are usually a too-big preview image, a too-big upload folder, or a deleted upload .xml.
  • Lost your export profile after an SDK update? Create a new profile and manually create a matching folder in the LocalLow mod-build directory.
  • Building creates a backup folder alongside your mod files. If a project is lost, partial recovery from the built mod is possible — terrain heightmap and asset positions can be pulled back out.

After Game Updates

  • [UMod...] references a mod that is not loaded server errors after a game update mean the map must be rebuilt on the current SDK.
  • The UISceneTransitionLoaderPanel.SetCustomMapDetails NullReferenceException when loading a map points at the map's CustomMapDetails component or an outdated SDK build — rebuild.

Map Design Guidance

Community consensus distilled from years of linebattle and naval hosting:

Linebattle Maps

  • Artillery should punish but not dominate. Hill height and steepness define whether a position is a hold or a push.
  • Give players at least one big landmark for orientation.
  • Too many trees hurt third-person line play and admin spectating.
  • Rocks and trees are meaningful cannonball cover — their hitboxes actually block shots.
  • Study loved maps against disliked ones: Grassy Plains 4's west side works because of its two natural hold points; large open sweeping-hill maps play poorly.

Naval Maps

  • Go easy on assets; LODs are your friends.
  • Make walls destructible only where you want the action focused.
  • One or two secondary capture points make Coastal Siege interesting.

General

  • Don't be a perfectionist about tiny mesh overlaps; do fix glaring issues like floating props.

Troubleshooting

Recurring problems and fixes. Check the server log or press F2 during loading to see the underlying error.

Symptom Cause & Fix
Spawn points can't be selected on a modded map (post mid-2026) Move the Default Camera Position into the sky so all spawn points are visible from it, rebuild. See Spawns (SDK).
Server breaks after adding a mod Two Workshop IDs on one mods_installed line. One line per mod.
Mod downloads but the modded map never loads map_name modmap missing from the rotation, or load_mod missing/typo'd (mod_loaded is wrong).
[UMod...] references a mod that is not loaded after a game update Rebuild the map on the current SDK.
SetCustomMapDetails NullReferenceException on load Outdated SDK build / broken CustomMapDetails component. Rebuild.
Two overlapping water surfaces in-game The guide water prop was left in the scene. Delete it — the game generates the ocean itself. See Water.
Rowboat spawners don't work They require the ocean enabled; lake props aren't enough. Their obstruction check rejects any obstruction.
Grass floats above or clips into terrain Raise heightmap resolution, align the TVE area box to the terrain, use TVE Height Offset. If broken, redo the grass + TVE elements.
Plants glitch and streak across the screen The asset isn't on the blanket shader, so it can't be painted as terrain detail. Place it with a prefab brush instead.
Players can't crouch/jump/aim on a prop Prop is on the Default layer. Move it to Layer 13: Static Environment (colliders on Terrain/walkable). See Layers.
Players spawn on rooftops or the highest point Area-collider spawns place players on top of anything above the collider. Use spawn nodes.
Players spawn inside tents Hand-place many small exact spawn positions around tent props.
Multiple capture points show the same letter Capture point indices duplicated in the setup. Recheck them.
Spawn section tied with capture point -1 is null A spawn section links to a capture point that no longer exists. Relink or remove it.
Map won't load in a game mode it used to support That mode's spawn objects are disabled in the scene. Modes now require their spawn objects enabled.
Round-start weapons wrong on later rotations Starting-weapon overrides leak between rotations. Re-set the override on every map. See Spawns (Config).

SDK Version History (Map-Relevant)

Release notes that changed how maps are made. Full upgrade steps live on the SDK Upgrade Guide; full game changelogs on Game Release History.

Version Unity What Changed for Map Makers
v2.31 (current) 2022.3.62f1 Unity bumped to the last LTS release of Unity 2022. 2022.3.53f1 also remains compatible.
Mid-2026 game update n/a Broke spawn point selection on older modded maps (Default Camera Position fix, see Spawns).
~2024-01 2022.3.11f1 New water workflow (WaterSystem asset, seabed generation); grass moved into the base SDK; Naval CustomMap removed in favour of Open Waters. Flat land CustomMap removed later.
v2.15 2022.3.11f1 Built-in Render Pipeline to URP. Old materials and shaders removed; batching characteristics changed (same mesh + material now cheap). Pre-2024 material/shader advice is historical.
2022-09-09 hotfix n/a Added Custom LOD Objects (group culling) and the partial ocean system on HoldfastMapModOverload; official fog distance guidance published.
Game 2.5 n/a Holdfast SDK 5.0: 1500+ new assets in the level, uniform, and flag editors.
Game 1.3 n/a Holdfast SDK V1 released: the first map, uniform, and flag editor.

Tools & Resources

Official

Community Guides & Tools

Example Configs

The Server Config Templates page contains hundreds of working rotations, including map_name modmap + map_name_override examples for every game mode.

Known Limitations & Open Questions

Things the community has hit the edges of. If you solve one of these, share it in #mod-support and update this page.

  • Howitzer spawnable prop name: howitzers were added to community maps in 2023 but no spawnable enum for them has been found. Is one on the Spawnable Props list at all?
  • Carryable flag props: the pick-uppable flag (like lanterns) has no known objects_override enum.
  • dynamic_capture_point_capture_duration: appears to do nothing — capture timer stays around 40 s regardless.
  • Rowboat spawn obstruction check: unclear what it raycasts against; blocks rowboat use on land maps.
  • Only one custom shipspawnsection position works per rotation; no known workaround.
  • Multi-terrain maps + grass/TVE: reported broken with no fix or acknowledgement.
  • Spawning players under terrain or inside buildings with area spawns: not possible; nodes are the only partial answer.
  • Spawnable Props audit: which enums were renamed or broken across the Frontlines/URP/crossplay updates has never been fully mapped out.
  • Expanded spawnable props / mod-map-to-config exporter: floated by AGS in mid-2025 for cross-play events; no commitment yet.

Support

Got a question that's not covered in this documentation?

We will gladly give you a helping hand should you require, so don't shy away from asking any questions. You will also find members within the community familiar with the toolset willing to do so.

Join the Official Discord, then head to the #become-a-modder channel and click the button to get the Modder role. This will unlock all channels concerning the discussion of modifications and scripting, including #mod-support.

Discord: Holdfast Workshop