12. Free Tactics (Live)
In short: Free Tactics is a turn-based battle mode that is fought right on the exploration map, with free movement in meters instead of grid tiles. There is no loading screen and no battle map: enemies notice the party, the camera lifts into a tactical view, and everyone fights from where they stand. Use it for modern party-tactics fights: cover, height, surfaces, doors, summons and a battlefield you can break.
12.1 Basics
12.1.1 What the player sees
- Being noticed. Enemies have a vision cone and hearing. A bar fills above their heads while they see or hear the party. When it is full, a ! appears and the battle starts. The bar empties again if the party gets out of sight. Sneaking makes the party harder to see and hear. Tall grass and shadows hide it even better.
- How the battle opens. There are three openings:
- They noticed you: normal initiative.
- You reached them unseen (from behind, sneaking): a surprise round. The party acts first and the enemies lose their first turn.
- They were waiting in ambush: the enemies act first and the party loses its first turn.
- A turn. The active character sees a soft outline on the ground that shows how far it can walk. Pointing at the ground shows the path and its length. Pointing at a target shows the damage, the chance to hit and the chance of a critical hit, with cover, height and flanking already counted. Walking and acting happen in any order until the turn's budget is spent or the player picks End Turn. Commands that cannot be used right now are dimmed and say why.
- Others join. Groups standing close to the fight join from the start. Enemies that walk past and notice the battle join at the start of the next round. Party members near the leader fight from where they stand.
- Running away. Flee works when no enemy that can see the character is within the escape radius. Fled units keep their HP. When everyone still standing has fled, the battle ends as an escape.
- The end. On victory, a banner lists experience, money and items, and the player keeps exploring from where they stand. On defeat, the Game Over screen offers Retry battle, which puts everything back as it was just before the fight.
12.1.2 Make a group fight in Free Tactics
- Select an Encounter Spawner in your level.
- In the Details panel, under Free Tactics, tick Free Tactics.
- Optional: tick Ambush so the group attacks first when it notices the party.
Or open an Encounter asset and set its Battle Mode to Free Tactics. Every spawner that uses it, and every trigger that starts it, then fights in Free Tactics. See Battle fundamentals for encounters and the battle mode override. A camp that should stand guard instead of wandering needs a Roaming Behavior whose Idle is Stand; Detection Speed on the behavior makes a group notice faster or slower.
12.1.3 Try it in two minutes
Open /RPGSagaEngine/Examples/Maps/L_RSE_StarterExample, press Play, open the console and type:
RSE.FreeTactics.Setup 16
A camp with walls, crates and tall grass appears 16 m in front of you. Walk toward it, or sneak around and strike from behind for a surprise round. RSE.FreeTactics.Setup 16 ambush makes the camp lie in ambush instead. These test commands are not in shipping builds. The map /RPGSagaEngine/Examples/Maps/L_RSE_FreeTacticsInterior is a two-floor house with stairs, a balcony, ladders, doors, windows and a basement. See Appendix C for every console command.
12.1.4 Hide a spot in tall grass or shadow
Place a volume over the grass and add the actor tag RSE.TallGrass (or RSE.Shadow). How much each tag hides is set in Project Settings → RPG Saga Engine → Stealth → Concealment Tags. You can add your own tags there.
12.1.5 Keep something out of the battle area
The battle area is measured from your level when the fight starts: walls, rocks and crates become cover. Any actor tagged RSE.FreeTacticsIgnore is left out (foliage, decorations, effects). The combat roles you give your assets decide what counts as full cover, half cover, rough ground or nothing at all (see Enemy AI and adaptive difficulty for the Combat Role Configurator).
12.2 How it works
Exploration (enemy notices party, or a trigger / dialog starts an encounter)
-> URSEFreeTacticsSubsystem gathers who takes part (the group, the called-for-help enemies, nearby party members)
-> ARSEFreeTacticsDirector captures the area into a navigation snapshot (meters, floors, cover, doors)
-> URSEFreeTacticsBattle (RSECore) runs the rules: turn order, budgets, commands, surfaces, objects, AI
-> the director shows the battle's events (camera, overlay, HUD, effects) and turns input into commands
-> victory / defeat / escape -> back to exploration, no transition
The rules run without a world. URSEFreeTacticsBattle is plain data and logic in RSECore, so the same battle runs in the headless battle simulator and in automated tests. The director in RSE only captures the area, presents the events and turns the player's input into commands.
Every decision is a command. A move, an ability, a flee, a door, a jump and End Turn are each one FRSEFreeTacticsCommand. The battle validates a command (ExecuteCommand) and either applies it or refuses it with an ERSEFreeCommandResult (not your turn, cannot reach, action rejected, cannot flee, cannot use door, cannot jump). Commands are plain serializable data, which is why the same battle can be saved, replayed and driven over the network.
Who decides is a Free Tactics Controller (URSEFreeTacticsController): the local player (a queued controller that waits for input), the companion AI or the enemy AI. You can swap controllers per team or per unit at any time.
Turn order is individual Charge Time by default (fast units act more often), with an optional team-based round mode. Turn budget is either one shared Action Point pool, or three separate budgets: movement in meters, an action and a bonus action (the default).
Determinism. Every random roll (a slip, a status) uses the battle's seed, so the same commands give the same battle.
12.2.1 Battle feel
A live battle should feel like a fight, not like a menu. The classic modes are not changed by any of it, and every piece can be turned off.
- The start. A ring spreads on the ground from the point where the party and the enemies met, time slows down for a moment, the enemies that noticed you turn toward the party and shout a short line, the HUD fades in and the music crossfades to the battle music. Nobody is teleported: a unit that stands where it cannot is nudged a few centimeters (Max Start Nudge).
- Every action at its pace. Each action plays in phases: wind-up (a spell charges with a magic circle and its area is marked on the ground), the action itself (a spell or shot flies to its target and the hit waits for it), impact (a flash, a few frames of hit-stop, the target flinches) and recovery. Defaults per kind of action (melee, ranged, spell, support, item) live in Battle Feel → Pacing, and a presentation asset or an ability can override them.
- Juice. Weapon trails, damage numbers tinted by element, looping effects while a status lasts, an optional impact shake and a camera that glides to the active character without close-ups.
- What the enemy is about to do. On an enemy's turn a small icon (attack, spell, heal, buff, debuff, item, summon, move, flee) shows over it for a moment before it acts, sometimes with a short line. The icons, colors and lines are in Battle Feel → Intent.
12.3 Key classes and assets
| Class / asset | Module | Role |
|---|---|---|
URSEFreeTacticsBattle | RSECore | The rules and state of one battle: units, turns, budgets, surfaces, objects, doors, overwatch, flee |
FRSEFreeTacticsCommand | RSECore | One decision (Move, UseAction, EndTurn, Flee, Door, Jump) as plain data |
URSEFreeTacticsController | RSECore | Abstract, Blueprintable: decides commands for a unit or team (ProvideCommand) |
URSEFreeTacticsQueuedController | RSECore | A controller fed from outside; the local player and remote players use it |
URSEFreeTacticsAIController | RSECore | The enemy and companion AI (see Enemy AI and adaptive difficulty) |
URSECoverProvider | RSECore | Decides what cover a blocker gives; subclass to change the rules |
URSEFreeTacticsSettings | RSECore | Rules (Project Settings → Free Tactics), a rules-profile section |
URSEFreeTacticsFieldSettings | RSECore | Battlefield rules: surfaces, objects, pushes, jumps, falls |
URSESurfaceData | RSECore | Data asset: one ground surface (fire, water, oil...) |
URSEFieldObjectData | RSECore | Data asset: what a breakable or explosive object does when it breaks |
FRSEAbilityFreeTacticsRules | RSECore | Per-ability meters-based rules (range, area, cost, Overwatch) |
URSEFreeTacticsSubsystem | RSE | World subsystem that starts battles and gathers participants |
ARSEFreeTacticsDirector | RSE | The map director: captures the area, presents events, turns input into commands |
ARSESurfaceSpot | RSE | Placed actor that lays a surface when a battle starts |
ARSEDoor, ARSELadder, ARSEInteriorVolume | RSE | Doors, ladders and interior camera/battle-area volumes |
URSEPartyFieldSubsystem | RSE | The visible party: leader switching, formation, party orders |
URSEPartyCommandData | RSECore | Data asset: one party order |
URSEFollowerProfile | RSECore | Data asset: formation values and idle behaviors of followers |
URSEExplorationCameraSubsystem | RSE | The tactical exploration camera shared with battles |
12.4 Settings
Everything is in Project Settings → RPG Saga Engine. The groups that matter for Free Tactics:
| Group | What you tune |
|---|---|
| Free Tactics | Space (meters per tile, unit radius, start nudge), navigation (snapshot cell size, step limits, any-angle paths), turns (action model, movement meters, actions and bonus actions, turn order), combat (arcs, height bonus), cover, opportunity attacks, openings, joining, fleeing, summons, doors, the AI's weights. A rules-profile section, so zones and bosses may override it. |
| Free Tactics (Presentation) | Slow motion at the start, battle area size and growth, camera, ground overlay style, pace, victory banner, fallen enemies, texts. |
| Free Tactics Field | Surfaces, the reaction table, breakable objects, pushes, the fall damage curve, jumping, how much the AI cares about surfaces and barrels. A rules-profile section. |
| Free Tactics Field (Presentation) | How surfaces, explosions, cover shields, forecasts, lines of fire and cutaways look. |
| Free Tactics (Co-op) | Who commands unassigned units, turn timeout, guest pacing, pulling far players in. |
| Battle Feel | The entry, per-action pacing, juice, status visuals, intent icons and lines. |
| Stealth | Detection bar speeds, sneaking, hearing, concealment tags. |
| Party Field | Formation, follow distances, party orders. |
| Exploration | Camera style, tactical camera limits, camera input actions. |
| Camera Occlusion | What fades or hides in front of the party. |
Defaults worth knowing (all in Free Tactics):
| Setting | Default |
|---|---|
| Action Model | Movement + action + bonus action |
| Movement Meters (Fixed source) | 9 m per turn, 1 action, 1 bonus action |
| Turn Order | Individual (Charge Time) |
| Meters Per Tile | 1.5 m |
| Opportunity Attacks | Off. Reactions then come from Overwatch abilities. |
| Surprise Rounds | On |
| Call For Help Radius | 12 m |
| Party Join Radius | 20 m |
| Escape Radius / Escape Hidden Radius | 8 m / 3 m |
| Pursuit Leash Radius | 20 m |
| Summon Placement Range | 6 m |
| Doors in battle | On, a door costs a bonus action |
Every value is checked when you save (IsDataValid). For example the editor warns when the overlay material does not match the overlay style, or when the tactical camera's zoom limits are the wrong way round. See Appendix B for the full list.
12.5 Blueprint usage
12.5.1 Start a battle from a trigger or a dialog
- Event (Box Trigger overlap, or a dialog effect) → Get RSE Free Tactics Subsystem (a world subsystem node).
- Start Encounter Battle (Encounter =
DA_Encounter_Camp, Opening = Normal, Enemy Actors = the enemies standing in your level, Source = Self). - Branch on the returned Boolean: false means a battle cannot start now.
Start Group Battle does the same for a visible group of an Encounter Spawner (Spawner, Group Index, Opening). The opening is ERSEFreeOpening: Normal, Player Surprise or Enemy Surprise.
12.5.2 Ask what is going on
- Is Battle Active and Get Active Director on the subsystem.
- On the director: Get Battle, Is Awaiting Player, Get Input Mode, Get Unit Actor, Get Unit Id Of, Get Unit Name, Is Entry Playing.
- On the battle: Get Round, Is Surprised, Can Flee Battle, Check Flee, Has Escaped, Get Door Count, Is Door Open.
12.5.3 Write your own controller
- Create a Blueprint class from Free Tactics Controller.
- Override Provide Command (Battle, Unit Id → Out Command, return value). Fill the command (for example Make Move style: Type = Move, Unit Id, Point) and return true, or return false to wait.
- Optional: override On Command Rejected to react when the battle refuses a command.
- On the battle, call Set Team Controller (a team tag) or Set Unit Controller (a unit id).
12.5.4 Change the battlefield from a script
- Create Surface Circle (Creator Id, Data =
DA_Surface_Oil, Center, Radius, Duration Override) and Remove Surface. - Spawn Object, Damage Object (a barrel taking damage can explode).
- Check Jump and Preview From Destination for custom UI.
- Toggle Door and, on an RSE Door actor, Set Locked and Set Open.
12.5.5 Presentation events
The director exposes On Event Presented, On Callout (a bark or an intent over a unit), On Notice and On Custom Menu Command. Bind them in a HUD Blueprint. See Appendix A for every node.
12.6 C++ usage
Drive a battle from code, for example from a custom controller:
UCLASS()
class UMyHoldPositionController : public URSEFreeTacticsController
{
GENERATED_BODY()
protected:
virtual bool ProvideCommand_Implementation(URSEFreeTacticsBattle* Battle, int32 UnitId,
FRSEFreeTacticsCommand& OutCommand) override
{
// Never move: end the turn facing north.
OutCommand = FRSEFreeTacticsCommand::MakeEndTurn(UnitId, 0.f);
return true;
}
};
// Somewhere that owns the battle:
Battle->SetUnitController(UnitId, NewObject<UMyHoldPositionController>(Battle));
const ERSEFreeCommandResult Result = Battle->ExecuteCommand(
FRSEFreeTacticsCommand::MakeMove(UnitId, FVector(4.f, 0.f, 0.f)));
Start a battle from C++:
if (URSEFreeTacticsSubsystem* Free = URSEFreeTacticsSubsystem::Get(this))
{
Free->StartEncounterBattle(Encounter, ERSEFreeOpening::PlayerSurprise, EnemyActors, this);
}
Extension points:
URSEFreeTacticsController(C++ or Blueprint) for any decision logic.URSECoverProvider: subclass and set it in Free Tactics → Cover → Cover Provider. Or callSetCoverProvideron a battle.- Command-bus integration:
FRSEFreeTacticsCommandderives fromFRSECommand, so it travels through the same bus as the rest of the plugin (see Co-op and online). - Try the rules headless in the battle simulator: ``
UnrealEditor-Cmd.exe YourProject.uproject -run=RSEBattleSim "-Scenario=Plugins/RPGSagaEngine/Config/BattleSim/FreeTacticsSkirmish.json"``
12.7 Advanced
12.7.1 The battlefield
The ground itself takes part in the fight.
Surfaces. Fire, water, electrified water, ice, oil, poison, blood and steam lie on the ground as areas measured in meters and drawn on the real terrain. When two surfaces meet, or an attack of an element hits one, they react: fire on oil makes a bigger fire, lightning on water electrifies it, cold freezes water, fire melts ice, water puts fire out. Reactions can chain (burning oil reaches a barrel, the barrel explodes). The AI avoids harmful surfaces and likes to ignite oil or electrify the water its enemies stand in.
To make your own surface:
- Create an RSE Surface Data asset (or duplicate one of
/RPGSagaEngine/Data/Field/DA_Surface_*). - Give it a Zone Tag (for example
Zone.Tar), a name, a color and a Look (Liquid, Fire, Frozen, Oil, Toxic, Electric, Vapor). - Fill in what it does: Effects On Enter, Effects On Turn Start, Duration Turns, Move Cost Multiplier, Slip Chance, Slip Status and the Visual.
- Add its reactions in Project Settings → Free Tactics Field → Interactions: one row per pair (this surface + this element, surface or weather = that surface, or nothing to remove it).
- Let an ability make it with a Create Zone effect.
Surfaces already lying in the level. Place an RSE Surface Spot actor over a ford, a puddle of oil or a marsh and set its Surface. Scale its box to the area (or tick Circle). When a battle starts, every spot inside the battle area lays its surface. Duration Rounds 0 keeps it for the whole battle, -1 uses the surface's own duration. Outside battles the spot does nothing and is not drawn.
Breakable and explosive objects. Give a mesh the combat role Destructible or Explosive. The role sets the hit points, and its Break Object (a Field Object Data asset) sets the explosion's damage and radius, the surface it leaves and the effects it plays. Examples: DA_Object_ExplosiveBarrel, DA_Object_Crate. A broken object stops being cover.
Pushes, jumps and falls. Shove and every Knockback effect push a unit back in meters: into a wall it takes collision damage, off a ledge it falls and takes damage by height (the Fall Damage curve). Jump is a command next to Move that crosses gaps and climbs low ledges; it costs movement or the bonus action, as you set in Free Tactics Field → Jumping. Leap, Dash, Teleport and Swap work in meters too.
Reading the battlefield. Pointing at a spot you can walk to shows cover shields on the side of each enemy it covers from, plus the hit and critical chance each enemy would have against you there. A line of fire shows green when clear, yellow through cover and red where a wall blocks it. Roofs, upper floors and tree canopies tagged with the combat role Overhead (or an actor tag from Cutaway Tags) are cut away while the camera looks under them.
12.7.2 Abilities in meters and Overwatch
An ability without its own Free Tactics rules is converted from its Tactics rules (1 tile = Meters Per Tile). To tune it, open the ability and turn on Free Tactics Rules → Override: Action Cost, Action Point Cost, Min and Max Range, vertical tolerance, line of sight and trajectory (direct or arc), area shape (single, circle, cone, line), radius, falloff, uses per turn and whether it ends the turn.
Overwatch (a stance) is set in the same struct. Tick Overwatch → Enabled on an ability: using it puts the unit on watch until its next turn. The first enemy that enters, or moves within, its watch Range is answered at once with the Response ability at Damage Factor (0.7 by default). By default it spends the rest of the turn and ends it. Overwatch is how reactions come into the live mode while Opportunity Attacks stays off.
If you turn Opportunity Attacks on, a unit that walks out of an enemy's melee reach provokes a strike. The traits Trait.Reaction.OpportunityAttack and Trait.Reaction.NoOpportunityAttack (on a class, character, equipment or status) decide for their unit whatever the setting says.
12.7.3 Summons
Summons appear where the summoner points. The ground shows every legal spot (within Summon Placement Range, standable, with room for the creature, not on anybody, in the summoner's sight). A refused spot says why. A big creature takes more room: set Summon Footprint Radius on the Pact, or Footprint Radius on the Summon Units effect.
12.7.4 Inside buildings
The battle map is measured with every floor of every spot, so units can fight on a balcony over the yard, a bridge, a basement.
- Stairs made of separate steps: tag each step
RSE.Floor. Ramps and wide stairs need no tag. - Ladders: place an RSE Ladder, move its Bottom Point and Top Point widgets onto the two floors it joins.
- Doors: place an RSE Door. In exploration the player opens it with the interact button. In battle a unit next to it opens or closes it (Open Door / Close Door). A closed door blocks the way and line of sight; a locked one does not open. Enemies open a door when it is the only way to the party.
- Windows: a gap in a wall that units can see and shoot through but not walk through. A glass pane that should block the way but not the view takes the tag
RSE.Window. - Interior Volumes: place an RSE Interior Volume over each building, cave or room. Inside it the exploration camera moves closer (or, with Fixed Angle, keeps a fixed rotation for a classic pre-rendered room look). A battle that starts inside measures only the volume (plus Battle Area Margin) and uses the volume's Battle Camera. The highest Priority wins where volumes overlap.
Each floor needs its own collision (one slab per actor or per component): one mesh holding several floors is read as its top floor only.
12.7.5 The visible party
Outside battle the party walks behind the leader in formation. Switch Leader and Party Command are input actions in Project Settings → Exploration. Party Command opens a radial menu of orders (Search here, Open / unlock, Guard here, Come to me, Stay, Scout ahead). Each order is a Party Command Data asset (requirements, chance of success with a bonus for preferred classes, effects on success and on failure, the noise of a failure, texts), added in Project Settings → Party Field → Commands. Members keep a loose place that drifts, close up in corridors, stroll and play idle animations when the leader stands still. That comes from a Follower Profile asset (formation values and a weighted list of idle behaviors with cooldowns). Add a behavior by adding an entry, or by subclassing RSE Idle Behavior (URSEIdleBehavior) in Blueprint. RSE Idle Spot actors give them benches and walls to use.
In Blueprint, the party field subsystem offers Cycle Leader, Set Leader, Follow, Stay, Refresh Followers and Toggle Command Menu.
12.7.6 The exploration camera
Outside battle the party is seen from above at a tactical angle, and the same camera runs the battles, so a fight starts with the camera simply taking over. Zoom, tilt, turn and pan are all player-controlled (and rebindable in Options). Walls and trees fade only where they hide a character:
- materials with the fade function show a soft dithered circle around the hidden character;
- any other mesh turns into a ghost (
M_RSE_CameraOcclusionGhost) while it covers enough of a character; - hiding is the last resort.
To add the exact fade to your own materials, select them in the Content Browser, then right click → RPG Saga: Add Camera Occlusion Fade (and RPG Saga: Remove Camera Occlusion Fade to undo). The tool changes only materials under Camera Occlusion → Opt In Content Roots (/Game/ by default) and keeps backups in Saved/RSE/CameraOcclusionBackups/. Tag an actor RSE.NoFade to keep it from ever fading, and RSE.Ground for ground meshes. Place an RSE Exploration Camera (Level) actor to give one level its own camera style or limits (a town can keep the classic close third-person camera while the rest of the game uses the tactical one). In Blueprint, Get Camera Style, Set Camera Style and Clear Camera Style on the exploration camera subsystem switch it live. See Camera and battle presentation.
12.7.7 Co-op
Free Tactics is host-authoritative. The host's battle owns the rules; guests present the host's events and send commands for the units they play. Settings in Project Settings → Free Tactics (Co-op):
- Companion Units: party units that no player plays are commanded by the AI (default) or by the host.
- Turn Timeout Seconds (45 s) and Turn Timeout Action: when a guest does not answer in time, the host takes over (default), the AI plays the turn, or the battle waits.
- Guest Playback Wait Max, Catch Up Backlog, Catch Up Playback Rate: the host waits for guests to show the events so far, but never longer than the limit; a guest that falls behind plays the backlog faster.
- Pull In Far Players: players farther than Party Join Radius are brought next to the leader with a short fade.
- Reconnect Retakes Unit At Once: a player who reconnects gets their unit back immediately, or watches until the battle ends.
Single-player games read none of this. See Co-op and online.
12.7.8 Performance notes
The navigation snapshot cell size (Snapshot Cell Size, 0.25 m) trades path detail against memory and capture time; raise it for large battle areas. Max Search Cells guards path searches. The AI samples AI Candidate Positions per decision, so lower it on weak hardware. Nothing in the mode needs Tick outside an active battle.
12.8 Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
| The group never starts a Free Tactics battle | The encounter's Battle Mode is not Free Tactics, or the spawner's Free Tactics box is off | Set the Battle Mode on the Encounter, or tick Free Tactics on the spawner |
| Units stand inside a wall at the start | The wall was captured as walkable, or has no collision | Give it collision and a combat role (Full cover or Obstacle) |
| Foliage or a decoration blocks movement | It was captured as an obstacle | Tag the actor RSE.FreeTacticsIgnore, or give it the Neutral decoration role |
| Units on different floors block each other, or the upper floor is not walkable | One mesh holds several floors | Split the floors into separate slabs, one per actor or component |
| Stairs cannot be climbed | Steps are separate narrow meshes | Tag each step RSE.Floor, or raise Max Step Up a little |
| Flee is dimmed ("Enemy near") | A seeing enemy is within Escape Radius | Walk away first, or use Escape Rounds for a delayed escape |
| Flee does nothing for a boss | The encounter's Can Flee is off | Turn it on, or keep the boss unfleeable on purpose |
| No opportunity attacks | Opportunity Attacks is off by default | Turn it on in Free Tactics, or give abilities an Overwatch stance |
| A surface does not react | No row in Free Tactics Field → Interactions for that pair | Add the row |
| A wall hides the party instead of fading | The mesh is translucent or not a mesh | Add the fade to its material, or tag it for a ghost; see the camera tool above |
| A battle in a house shows the wrong camera | Two volumes overlap with equal priority | Raise the Priority of the one that should win |
12.9 See also
- Battle fundamentals for encounters, rewards and the simulator.
- Grid Tactics for the grid mode that shares abilities and Action Points.
- Enemy AI and adaptive difficulty for how enemies choose.
- Exploration for stealth, encounters on the map and reinforcements.
- Co-op and online for the network model.
- Product pages in
docs/product/:free-tactics.md,combat-roles.md,coop.md.