Questlight Studio
Docs / Grid Tactics

10. Grid Tactics

In short: Grid Tactics is turn-based combat on a square grid laid over your live level. Tiles have height and terrain, units face a direction, and position matters: flanking, high ground, cover, line of sight. Turn order follows a per-unit charge counter (CT), and each turn is paid with Action Points (AP) that you spend on moving and acting in any order. Use it for story battles, bosses and any fight where where you stand matters.

10.1 Basics

10.1.1 The words

WordMeaning
Tactics zoneThe actor (ARSETacticsZone) that marks where the battle happens. Its grid is measured from your level geometry.
Bake GridMeasuring the level under the zone: which tiles are walkable, how high each one is. You do it once in the editor.
TileOne square of the grid (100 cm by default). It has a height (in steps), a terrain and a walkable flag.
Height stepThe unit of height (50 cm by default). Climbing and dropping are measured in steps.
CT (charge time)Each unit fills a counter at its own speed. At 100 the unit takes a turn. Fast units act more often.
AP (Action Points)The budget of one turn (the unit's Stat.ActionPoints). Moving and acting both spend it.
FacingThe direction a unit looks: North, East, South or West. Attacks from the side or the back hit harder and more often.
Deployment tilesThe tiles where the player places units before the battle starts.
DirectorThe actor (ARSETacticsBattleDirector) that runs one grid battle: deployment, turns, AI and presentation.

10.1.2 Set up your first grid battle

The fast way:

  1. Open a level with open, mostly flat ground.
  2. Choose RPG Saga Engine → Advanced tools → Make Battle Zone Here... (or right-click in the viewport → RPG Saga → Make Battle Zone Here). Pick an encounter. The tool traces the grid, picks deployment tiles, places the enemies, and adds a zone, a director and a trigger. Press Apply.
  3. Play. Walk into the trigger. The world turns into a grid, you place your units on the blue tiles and start the battle.

The manual way (to learn what the tool does):

  1. Place an RSE Tactics Zone (search "Tactics Zone" in Place Actors). Its origin is the corner of tile (0,0). The grid follows the actor's location and yaw.
  2. Set Grid Width and Grid Depth (12 by 12 by default) and press Bake Grid in Details. Tiles that are too steep, or have no clearance above them, become unwalkable.
  3. Place an RSE Tactics Battle Director. Set Zone to your zone and Encounter to an encounter asset. (Or leave the director to be found by a trigger or a battle site.)
  4. Lay out the enemies and the deployment tiles with the Encounter Layout mode (see Battle fundamentals).
  5. Add an RSE Encounter Trigger that points at the director. Play.

Fix a wrong tile with Tile Overrides on the zone (height, terrain, walkable), then Bake Grid again. Mark scenery the bake should ignore with the actor tag RSE.GridIgnore.

10.1.3 How a battle plays

  1. Deployment. The player sees the deployment tiles, places the roster characters (click a blue tile or use the buttons Place, Withdraw, Auto Deploy) and presses Start Battle. Required characters must be placed. With free slots the game asks for confirmation. The encounter's Max Deployed Units (4 by default) limits how many.
  2. Turns. The unit whose CT reaches the threshold takes a turn. It gets AP equal to its ActionPoints stat.
  3. Move and act. Blue tiles show where the unit can walk. Hovering a tile draws the real path with its AP cost ("5 AP (3 left)"). Choose an ability and the range, the area and who it hits are previewed, with the hit chance, damage range and a KO marker. Moving and acting mix freely: move, attack, move again, as long as AP last.
  4. End turn. The player picks the unit's facing. A turn that used no AP costs 60 CT, one that used them all costs 100, and partial use is in between, so a unit that does less comes back sooner.
  5. Victory or defeat by the encounter's objectives. Then the results flow starts.

A fallen unit stays on the grid for KO Countdown Turns (3) of its own turns. Revive it in time or it leaves the battle.

A danger zone key toggles an overlay of every tile the enemies can hit on their next turn.

10.2 How it works

10.2.1 Data to rules to presentation

Level geometry ──Bake──► ARSETacticsZone.Grid (FRSETacticalGrid, saved in the level)
                                   │
URSEEncounterData ─► ARSETacticsBattleDirector ─► URSETacticsBattle (RSECore, headless)
                         (deployment, AI turns,        grid, CT, AP, movement, targeting,
                          presentation, input)         positional damage, zones, objects
                                   ▲                                │
                                   └────── battle events ◄──────────┘

URSETacticsBattle holds all the rules and runs without a world. The grid stays inside the battle, and at runtime nothing scans the level. An unbaked zone is baked once at the start of play with a warning (Bake If Empty At Runtime), but the right fix is to press Bake Grid in the editor and save the level.

10.2.2 Movement

  • Four directions (North is +X, East is +Y). Heights are whole steps.
  • A step is allowed when the target tile is walkable, its terrain is not impassable, the height difference fits the unit's jump (Stat.Jump up, jump plus Jump Down Bonus down) and no enemy stands there.
  • The cost of a step is the terrain's Move Cost plus a height cost: Climb Cost Per Step (default 1) for each step up and Descend Cost Per Step (default 0) for each step down. Stairs (Terrain.Stairs) cancel the height cost.
  • Units can pass through allies but not stop on them. Enemies block fully.
  • Pathfinding is A* over the real costs. The AI uses the same queries.

Terrains are gameplay tags with rules in Project Settings → RPG Saga Engine → Grid → Terrain Rules: move cost, impassable, water, no climb cost, an Evasion Bonus and a Defense Bonus Percent for the unit standing there, and a display name. The starter terrains are Ground, Grass, Sand (cost 2), Swamp (3), Stairs, Shallow Water (2) and Deep Water (impassable).

Movement traits are tags a unit gets from its class, equipment, a Pact or a status:

TagEffect
Trait.Move.IgnoreTerrainCostEvery walkable tile costs 1.
Trait.Move.LevitateNo height limits or costs. Crosses water. Walls still block.
Trait.Move.WaterWalkWater costs 1 and deep water is open.

10.2.3 Turn order and Action Points

CT fills every tick with the unit's Speed. At CT Threshold (100) the unit acts. After the turn it pays between Turn CT Cost Idle (60) and Turn CT Cost Full (100). The HUD shows the predicted order (PredictTurnOrder in the code). Statuses with Status.Block.Turn skip the turn, Status.Block.Move and Status.Block.Act stop one half. Turn manipulation effects change CT, and the Action Points effect adds or removes AP now or next turn (limited by Max Bonus Action Points).

10.2.4 Position and damage

Tactics adds three things to the shared damage rules:

  • Facing. A hit from the side deals 1.25 times the damage (Side Damage Multiplier) with +10 hit chance (Side Hit Bonus). From behind it is 1.5 times with +25 (Back Damage Multiplier, Back Hit Bonus).
  • Height. Damage changes by 10% per height step the attacker stands above the target (Height Damage Per Step), clamped between 0.7 and 1.5.
  • Terrain. The target's tile gives it its evasion bonus and defense bonus.

All of this is in one breakdown (FRSETacticsPositionalBreakdown) used by the real hit, the AI's estimate and the forecast the player sees, so they always agree. The values are in Battle → Tactics → Positioning.

10.2.5 Targeting, shapes and line of sight

An ability's Tactics Rules decide what can be targeted: Min Range and Max Range (Manhattan distance in tiles), Vertical Tolerance (height difference), and Requires Line Of Sight. Line of sight is traced from an eye height above the tile surface (Line Of Sight Eye Height, 2 steps). Walls and tall objects block it. A Direct trajectory is a straight shot. An Arc (with Arc Height) flies over lower obstacles. Height Steps Per Range Bonus gives extra range from high ground.

The area is one of Single, Diamond, Cross, Line, Cone, Ring, Rectangle or Mask. A Mask is a hand-drawn pattern of rows separated by / or |, where X or # is a hit tile, O the center and @ a hit center. Area Centered On Caster makes the shape start at the user (a blast around you, a cone in front). Falloff lowers power with distance from the center.

10.2.6 Zones and field objects

Grid battles add two kinds of field content, both data assets:

  • Tile zones (URSETileZoneData): an area effect that lasts a number of turns. It has Effects On Enter and Effects On Turn Start, a Trigger Filter, Extra Move Cost (the pathfinder pays it), Slippery (units slide), Trap (triggers once, optionally Hidden From Enemies) and Removes Zones (fire melts ice). Examples in /RPGSagaEngine/Data/Field/: DA_Zone_FireGround, DA_Zone_HealingSpring, DA_Zone_SpikeTrap.
  • Field objects (URSEFieldObjectData): walls, barriers, crates, explosive barrels. They have HP, can block movement and line of sight, expire after a number of turns, and can explode, chaining to neighbors (up to Max Chain Explosions). Examples: DA_Object_StoneWall, DA_Object_ExplosiveBarrel.

Abilities create them with Create Zone and Spawn Object effects. Encounters can place objects from the start (Field Objects). Movement is evaluated tile by tile, so traps, zones, overwatch and sliding trigger on each tile.

10.2.7 Deployment

FRSEDeployment (RSECore, no world) holds the roster, the deployment tiles and the placements. CheckStart answers Ready, Not Full, Missing Required or No Units. AutoDeploy places required characters first, then the rest, putting short-range units on tiles closest to the enemy and long-range units behind. Units already placed never move.

10.3 Key classes and assets

Class / assetModuleRole
URSETacticsBattleRSECoreThe headless grid battle: CT, AP, movement, targeting, positional combat, zones.
FRSETacticalGrid, FRSEGridCoordRSECoreThe grid and tile coordinates.
URSEGridSettingsRSECoreTile size, height step, terrain rules, cost rules.
RSEGridPathfinding, RSEGridQueriesRSECoreReachable tiles, A* paths, ranges, shapes, line of sight (pure functions).
FRSEDeploymentRSECoreDeployment rules.
URSETileZoneData, URSEFieldObjectDataRSECoreZone and object data assets.
ARSETacticsZoneRSEThe zone actor: bake, overrides, drawing.
ARSETacticsBattleDirectorRSERuns the battle and presents it.
ARSEGridUnitRSEThe unit actor on the grid (placeholder body, or the character's look).
ARSETacticsPlayerController, ARSETacticsCameraPawnRSEInput and the battle camera.
ARSEPathPreview, ARSETargetPreviewRSEThe path line and the target preview.

10.4 Settings

Project Settings → RPG Saga Engine:

GroupWhat it holds
GridTile Size (100 cm), Height Step Size (50 cm), Default Terrain, Terrain Rules, Cost Rules (climb, descend, levitate). Tile size, height step and default terrain are global only, because levels are built for them. A rules-profile section.
BattleCT and AP rules, KO Countdown Turns (3), Jump Down Bonus (1), the positioning rules (side, back, height, line-of-sight eye height).
Tactics ZoneBake trace settings (Bake Trace Channel, Required Clearance, Min Walkable Normal Z, Bake Min Surface Size, Bake Ignore Tag), the grid look (Grid Visual Mode: Projected or Tiles), highlight colors, unit placeholder look and movement speed.
Tactics CameraPitch (-50), initial yaw (45), field of view (35), distance limits, zoom and pan speeds, rotation step (90 degrees).
Tactics Path PreviewThe look of the path line.
Target PreviewThe targeting preview: Default Style (Classic or Modern), colors, labels, what to mark. Players can pick their own in the options.
InputThe input actions, including Danger Zone Action.

See Appendix B for every property.

10.5 Blueprint usage

Start a grid battle from a button:

  1. Event (a menu button) → Find Tactics Director (Encounter = DA_Encounter_Starter_Z1_Skirmish).
  2. Branch on Is Valid. True: Set Encounter, then Begin Encounter. If you want to skip deployment, tick Auto Deploy on the director and call Start Battle.
  3. Bind On Event Presented on the director to show your own numbers, or use the shipped HUD.

Useful director nodes: Begin Encounter, Start Battle, Restart Encounter, End Encounter, Get Phase (Idle, Deployment, Battle, Finished), Get Battle, Get Battle Outcome, Is Awaiting Command, Is Playback Idle, Get Unit Actor, Get Last Rewards.

Rebake from a tool: the zone's Bake Grid and Clear Grid are callable in the editor, and RSE.Tactics.BakeZones rebakes every zone in the level in development builds.

The full node list is in Appendix A.

10.6 C++ usage

Move and attack in a headless grid battle (a test, a tool, an AI):

URSETacticsBattle* Battle = NewObject<URSETacticsBattle>();
Battle->Initialize(Grid, Spawns, /*Seed*/ 7);
Battle->StartBattle();

TArray<FRSEGridReachableTile> Reach;
Battle->GetActiveUnitReachableTilesWithCost(Reach);

if (Battle->MoveActiveUnit(Goal))
{
    const ERSEAbilityUseResult Result = Battle->UseAbility(Ability, Target);
    if (Result == ERSEAbilityUseResult::Ok)
    {
        Battle->EndTurn(ERSEGridDirection::South);
    }
}

ERSEAbilityUseResult explains refusals: Not Active Unit, Blocked, Unknown Ability, Not Enough Action Points, Not Enough Resources, Uses Per Turn Reached, Invalid Target, Item Unavailable, Requirement Not Met. For the player's UI use ForecastAbilityAt, GetTargetingTilesFrom and GetAreaPreviewFrom. They use the same path as the real resolution and never change the battle.

From a director, the same commands are CommandMove, CommandAbility, CommandItem, CommandEndTurn, DeployPlace and DeployWithdraw.

Extension points:

  • A new effect that works on the grid: a subclass of URSEAbilityEffect that overrides PreviewDisplacement (to preview movement) and uses the battle's grid functions (ComputePush, ApplyPush, IsTileStandable).
  • A new terrain: a gameplay tag under Terrain.* plus a row in Grid → Terrain Rules.
  • A new objective: a URSEBattleCondition subclass.
  • Your own unit actor: set the director's Unit Actor Class to a subclass of ARSEGridUnit.

10.7 Advanced

10.7.1 Terrain from the world

The bake traces straight down for every tile. A tile is walkable when the surface is flat enough and has clear space above. Surfaces that do not block pawns, pawns, objects narrower than Bake Min Surface Size and anything tagged RSE.GridIgnore are skipped. Combat roles on level actors (cover, obstacle, difficult terrain, high ground) can change tiles during the bake (see World building). The bake keeps the exact surface under each tile, so units, the path line and the highlights sit on the real ground even on slopes.

10.7.2 Grid visuals

Grid Visual Mode is Projected by default: one decal over the zone drawn from a small texture, which looks right on uneven ground and costs one draw call. Tiles draws instanced meshes. Projected needs a grid decal material. Without it the mode falls back to Tiles. You can show the grid only in battle (Show Grid Only In Battle) and play a reveal animation when the battle starts.

10.7.3 Rules profiles for tactics

Tile size and height step are global because levels are built for them. Everything else (costs, positioning, CT, KO countdown) can change per encounter through a rules profile. A boss can use a profile with no side bonus, a swamp level a profile with cheaper water.

10.7.4 AI

The AI plans on the same reachable tiles and costs. It scores flanks, height, line-of-sight blocking and danger tiles according to its intelligence value (see Enemy AI and adaptive difficulty). The director's AI Think Delay and Event Pause set the presentation pace.

10.7.5 Networking

The host runs the grid battle and guests send commands (FRSECmd family). The battle is deterministic, so every machine can mirror it (Co-op and online).

10.7.6 Performance

  • The grid is data in the level. Nothing is scanned at runtime.
  • The director has no per-frame cost beyond its presentation.
  • The danger zone and the previews recompute only when the battle changes.
  • Use Projected for live-map battles and keep the Combat Area free of clutter.

10.7.7 Development commands

In development builds: RSE.Tactics.ShowReach [Unit], RSE.Tactics.MoveUnit X Y [Unit], RSE.Tactics.BakeZones, RSE.Tactics.Demo approach|use|wait, RSE.Tactics.Deploy [start], RSE.Tactics.Preview style Classic|Modern|Default and RSE.Battle.AutoPlay 1. See Appendix C.

10.8 Troubleshooting

SymptomCause and fix
No grid appears, or "zone without a baked grid"Press Bake Grid on the zone and save the level.
Many tiles are unwalkableThe surface is too steep (Min Walkable Normal Z) or something is within Required Clearance above it. Use Tile Overrides, or tag props RSE.GridIgnore.
The grid floats above or sinks into the groundThe zone's origin is too high or low, or Bake Trace Height Above misses the ground. Move the zone and rebake.
A unit cannot reach a tile that looks closeHeight difference above its jump, a costly terrain, or an enemy blocks the path. Hover the tile to read the path cost.
An ability shows no valid targetsMin Range, Max Range, Vertical Tolerance or line of sight. Use Test ability in Grid mode to read the step-by-step reasons.
Units start on invalid tilesA start tile is off the grid or blocked. The game moves them to the nearest free tile. Fix the layout in Encounter Layout.
The grid looks wrong in the Projected modeThe grid decal material is not set or the surface is too steep for Projected Min Normal Z. Switch to Tiles.
The enemy never moves closeThe AI's intelligence, or the encounter's profile. Check the AI chapter.
The player cannot start the battleA required character is not placed, or nobody is placed. The message names the character.

10.9 See also