8.4 KiB
Tutorial Battle System
This document describes the current opening tutorial battle. It is based on the live implementation in TutorialGameCreation.scala, TutorialBattleController.cpp, ShardokGamesManager.cpp, ResolveBattleAction.scala, and the Unity dialogue scripts.
For the Unity tutorial UI/dialogue architecture, see TUTORIAL_SYSTEM.md. For copy and content notes, see TUTORIAL_CONTENT.md.
Current Flow
When a player creates a tutorial game at the default OpeningBattle phase:
TutorialGameCreation.createTutorialGame()creates aGameType.Tutorial(TutorialPhase.OpeningBattle)game starting inRoundPhase.BattleRequest.- Province 14, Onmaa, belongs to Sadar Rakon's faction and already has a defending army.
- Bregos Fyar's faction has a hostile attacking army, led by Ikhaan Tarn, already moving from province 31 to Onmaa.
RequestBattlesActionimmediately creates the Shardok battle and tags tutorial reinforcement hero IDs100and101.GamesManagerstores the generatedTutorialBattleConfigfor this game and passes it to Shardok when the battle starts.- Shardok creates the battle with the configured timed reinforcement events.
- Unity plays the active dialogue scripts from
tutorial_strategic.jsonandtutorial_battle.json.
There is also a tutorial phase-start path. Starting after OpeningBattle applies precomputed tutorial setup results from TutorialPhaseResultsLoader; this is why the Unity post-battle trigger logic handles a "battle was never observed" auto-resolve path.
Battle Setup
Defender: Sadar Rakon's Faction
Configured in src/main/resources/net/eagle0/eagle/tutorial_parameters.json:
- Faction ID: 3
- Province: 14, Onmaa
- Starting support: 23
- Starting resources: 50 gold, 4000 food
- Heroes: Sadar Rakon, Old Marek the Learned, Agamemnon
- Battalions:
- Rakon's Loyalists: Light Infantry, 529 size, 80 training, 75 armament
- Onmaa Defenders: Light Infantry, 311 size, 80 training, 60 armament
- Hunters of the Steppe: Longbowmen, 478 size, 80 training, 60 armament
Attacker: Bregos Fyar's Faction
The opening attacking army is configured under Bregos Fyar's attackingArmies:
- Faction ID: 2
- Origin province: 31
- Destination province: 14, Onmaa
- Heroes: Ikhaan Tarn, Tall Edgtheow, Waylaid Julius, Luke the Prank-tricker
- Battalions:
- Doomriders: Heavy Cavalry, 592 size, 80 training, 80 armament
- The Shardok's Guard: Heavy Infantry, 507 size, 80 training, 80 armament
- Bowmen of Nikemi: Longbowmen, 291 size, 80 training, 80 armament
- Swift Sabres: Light Cavalry, 450 size, 80 training, 80 armament
Tarn's unit is made visible to the defender from the start through TutorialBattleConfig.initial_visibilities.
Reinforcements
The current tutorial config has two timed reinforcement events. It does not currently configure a scripted Tarn flee event.
| Event ID | Trigger | Hero ID | Hero | Battalion |
|---|---|---|---|---|
elena_reinforcement_round_5 |
End of round 5 or later | 101 | Elena Fyar | Fyar's Vanguard, Heavy Infantry, 535 size, 75 training, 75 armament |
ranil_reinforcement_round_7 |
End of round 7 or later | 100 | John Ranil | Ranil's Riders, Heavy Cavalry, 458 size, 80 training, 80 armament |
Shardok creates reinforcement units at battle creation time with PENDING_REINFORCEMENT status. TutorialBattleController activates them when their event triggers and returns a TUTORIAL_REINFORCEMENTS_ARRIVED action result. Unity maps that action to profession-specific dialogue triggers:
tutorial_reinforcement_paladinfor Elena Fyartutorial_reinforcement_engineerfor John Ranil
The reinforcement action includes an attacker_starting_position_index; Shardok resolves that to currently open map positions and starts a reinforcement placement phase.
Scripted Event Controller
TutorialBattleController is a generic event-driven controller, even though the current tutorial battle only uses timed reinforcements.
Supported trigger types:
after_roundunits_lostdamage_takenunit_killed
Supported action types:
fleereinforcements
Events are checked at the end of each round, evaluated in config order, and each event_id fires at most once.
Battle Resolution
RequestBattlesAction marks tutorial opening battles with reinforcementHeroIds = Set(100, 101). ResolveBattleAction uses that metadata so reinforcement heroes are accepted when battle results return, even though they were not part of the original defending army.
After the opening battle resolves, ResolveBattleAction applies TutorialTarnDisappearsAction for GameType.Tutorial(TutorialPhase.OpeningBattle). Tarn is removed from captured/unaffiliated province state and from his faction's leaders list, matching the post-battle dialogue that he has vanished.
TutorialBattleAutoResolve provides a synthetic defender victory for tutorial setup paths that skip past the opening battle. In that synthetic result:
- The defender wins.
- Reinforcement heroes 100 and 101 survive.
- Tarn is marked outlawed/escaped.
- Other attacker heroes are captured.
- Defender battalions take about 30% casualties.
- Attacker battalions are destroyed.
Unity Dialogue Hooks
Strategic tutorial dialogue:
game_started: opening Onmaa monologue, ending withFightButtonhighlighted.tutorial_battle_ended: post-battle aftermath.tutorial_rebuild_support: support rebuilding guidance after captured-hero handling is done.
Battle tutorial dialogue:
shardok_placement_started: placement and unit overview.shardok_battle_running: first player turn guidance.- Ability/terrain triggers such as
archery_available,melee_available,ability_charge_available,start_fire_available,thunderstorm,duel_available,hide_available, andengineer_near_enemy. - Reinforcement triggers
tutorial_reinforcement_paladinandtutorial_reinforcement_engineer. - Capture triggers
enemy_hero_capturedandfriendly_hero_captured. shardok_battle_reset: replay dialogue after a battle reset.
Files To Check First
| File | Purpose |
|---|---|
src/main/resources/net/eagle0/eagle/tutorial_parameters.json |
Tutorial map, factions, starting provinces, armies |
src/main/scala/net/eagle0/eagle/service/new_game_creation/TutorialGameCreation.scala |
Opening battle setup and TutorialBattleConfig creation |
src/main/protobuf/net/eagle0/common/tutorial_battle_config.proto |
Scripted event config schema |
src/main/cpp/net/eagle0/shardok/server/ShardokGamesManager.cpp |
Adds pending reinforcement units and applies initial visibility |
src/main/cpp/net/eagle0/shardok/library/tutorial/TutorialBattleController.cpp |
Evaluates scripted events and creates Shardok action results |
src/main/scala/net/eagle0/eagle/library/actions/impl/action/RequestBattlesAction.scala |
Creates the opening battle and tags reinforcement hero IDs |
src/main/scala/net/eagle0/eagle/library/actions/impl/action/ResolveBattleAction.scala |
Resolves reinforcements and applies Tarn disappearance |
src/main/scala/net/eagle0/eagle/service/tutorial/TutorialBattleAutoResolve.scala |
Synthetic result for phase-start paths after the opening battle |
src/main/csharp/net/eagle0/clients/unity/eagle0/Assets/Tutorial/Triggers/TutorialTriggerRegistry.cs |
Converts strategic and tactical events into dialogue triggers |
src/main/csharp/net/eagle0/clients/unity/eagle0/Assets/Resources/Dialogues/tutorial_battle.json |
Active battle dialogue content |
Testing Checklist
- Tutorial game starts in BattleRequest and creates an Onmaa battle immediately.
- Opening strategic dialogue highlights the Fight button.
- Tarn's unit is visible to the defender from battle start.
- Placement dialogue fires during setup.
- First-turn battle-running dialogue fires on the player's first active turn.
- Elena Fyar arrives from the configured round-5 event.
- John Ranil arrives from the configured round-7 event.
- Reinforcement arrival dialogues fire once per hero.
- Battle reset clears battle dialogue completion for replay.
- Post-battle aftermath fires after the battle leaves
RunningShardokGameModels. - Rebuild-support dialogue waits until captured-hero handling and visible notifications are done.
- Starting a tutorial at a later phase uses precomputed setup and still reaches coherent strategic dialogue state.