WIKI

Mods

Modding the tile cursor, range ring and radar route

These indicators now load real GLB models, just like towers. You can replace their geometry, paint and embedded PBR textures through models.json. The game places them on the floor, applies the actual tower range and animates the radar signal. This does not change tower range, valid build cells or enemy routing.

Try the example

  1. Open Options → Mods → Open Mods Folder.
  2. Copy _example_glb_markers to my_markers (remove the leading underscore).
  3. Give the copy a unique id in mod.json, enable it and restart the game.
  4. Place/hover a tower, open the factory and enable the radar path with T.

The sample has cobalt housings, embedded striped textures and extra hexagonal fasteners. Green/red/blue/yellow validity and player signals still work. Its GLBs can be imported directly into Blender. The repository also contains the vanilla source Assets/Models/Source/GroundMarkers.blend, with one collection per model (only TileCursor is visible initially; unhide the desired collection).

Model mapping

{
  "version": 1,
  "models": {
    "Markers/TileCursor": {"file": "Models/Markers/TileCursor.glb", "material": "imported"},
    "Markers/PartnerCursor": "Models/Markers/PartnerCursor.glb",
    "Markers/RangeRing": "Models/Markers/RangeRing.glb",
    "Markers/RadarChevron": "Models/Markers/RadarChevron.glb",
    "Markers/RadarGuide": "Models/Markers/RadarGuide.glb",
    "Markers/RadarStop": "Models/Markers/RadarStop.glb"
  }
}

Any entry can be omitted; it then uses its shipping GLB. TileCursor serves both the main board and factory. PartnerCursor is independent so a co-op partner can remain visually distinct. The system mouse/insect-leg pointer and screen-space building hover brackets are separate assets, not these floor markers.

KeyAuthoring dimensions in Godot coordinates
TileCursorCenter at (0,0,0); frame fits a 64×64 tile, X/Z from −32 to +32. Factory scales X/Z to its 32-unit cells; height stays unchanged.
PartnerCursorSame 64×64 reference; use a closed frame or other distinct shape.
RangeRingCenter at origin; reference radius 128 in X/Z. Keep the ring near that radius, not a filled disk. The renderer offsets each vertex radially by actual_range − 128, retaining rail/tick thickness and height.
RadarChevronPoints toward +Z. Reference footprint about X ±10, Z −8…+6. Repeats every 32 path units and travels toward the exit along the actual rounded route.
RadarGuideOptional-looking side tabs in the art, around X ±13 and Z −6…+4. Repeats every 64 path units; omit the mapping to retain vanilla tabs.
RadarStopCrossbar spanning X ±14, around Z=0. Appears only at an actual visible blockage.

Y is up, with the underside at Y=0. Keep the art shallow (vanilla is approximately 0.4–1 unit high). In Blender, Z is up and radar forward is −Y when exporting with glTF +Y Up. Preserve the origin/scale by editing an imported sample. Apply transforms deliberately; nested rigid mesh transforms are supported.

Avoid geometry close to the center of a range ring: radial remapping is designed for an annulus, not interior spokes or a central badge. The renderer does not auto-fit arbitrary bounds; the 128-unit reference determines accurate range.

Materials and signals

At least one material slot must have a name beginning with MarkerSignal. Assign it to the luminous insets or indicator geometry. MarkerSignal.001 is valid. Other materials are the housing, paint, fasteners and decoration. A model without this slot is rejected with a message; it cannot replace a working model with an invisible/incorrect validity signal.

  • imported (also the string shorthand) preserves housing base color, vertex colors, embedded albedo/metallic-roughness/emission/normal textures and PBR values. UV0 remains available for your textures. Alpha uses cutouts, not sorted glass.
  • game uses vertex paint with Torreta's metal finish. Export COLOR_0 for every surface. This is useful for reshaping the vanilla model without new textures.
  • In both modes, MarkerSignal gets the current gameplay signal color: validity/player color for cursors, amber for range and open radar, red for a blocked route. Signal emission/animation is controlled by the game; author the luminous shape rather than baking a fixed red/green color into it.
  • Vertex alpha is reserved internally as the signal mask. UV2 is reserved for path distance and movement flags. Neither is an author-controlled animation input.

RadarChevron moves as a rigid model at the source radar's speed; RadarGuide and RadarStop stay fixed. Geometry movement and the light chase pause with gameplay. A blocked route remains still and red. Arrows shrink at the entrance and end of coverage, including partial reveals; the stop marker does not appear at a partial-reveal boundary. Do not export baked animation clips, armatures, lights, cameras, collision nodes or scripts. Use indexed triangles with normals, embed all textures/buffers, and export glTF 2.0 → GLB.

Performance and distribution

The renderer caches each source GLB and batches repeated radar modules by material. A cached arc-length texture drives rigid arrow movement in the vertex shader; it does not create a node per arrow or rebuild the mesh for each animation frame. Vanilla uses one surface per displayed marker/route. Mods can add surfaces, so keep materials and texture sizes modest, especially for repeated radar parts. The whole-game 30 FPS target is not guaranteed for arbitrary mod geometry.

Ship mod.json, models.json and the raw GLBs. Players do not need Blender, Godot's editor or .import files. Restart after editing/enabling/disabling the pack. Normal mod load order, validation, multiplayer signatures and fallback rules apply. The radar building itself already uses Buildings/Radar_1.