Add Fancheng relief scenario

This commit is contained in:
2026-06-18 01:20:06 +09:00
parent 3f9f74905e
commit b64a6625d6
5 changed files with 379 additions and 4 deletions

View File

@@ -4,7 +4,7 @@ Godot 4 tactical RPG prototype inspired by classic turn-based Romance of the Thr
## Current Slice
- Forty-four campaign scenarios.
- Forty-five campaign scenarios.
- Grid movement.
- Unit selection.
- Move, attack, wait, end turn.
@@ -65,6 +65,7 @@ Godot 4 tactical RPG prototype inspired by classic turn-based Romance of the Thr
- Ruxu Advance consumes the Hanzhong Settlement branch flags and opens Ruxu bank or Sun Quan river-line follow-up choices.
- Ruxu River Line consumes the Ruxu Advance branch flags and introduces water-move enemy boats along the riverbank.
- Ruxu Crossing consumes the Ruxu River Line branch flags and turns Ruxu toward an eastern crossing base or Fancheng relief.
- Fancheng Relief consumes the Ruxu Crossing branch flags and uses a protected Fancheng messenger defense objective.
- Post-battle choices can save campaign flags that branch later briefing text, shop stock, and scenario events.
- Scenario post-battle dialogue can play before the victory result panel.
- Basic battle EXP, level-ups, and core first-tier class promotion routes.

View File

@@ -223,6 +223,11 @@
"id": "044_ruxu_crossing",
"title": "Ruxu Crossing",
"path": "res://data/scenarios/044_ruxu_crossing.json"
},
{
"id": "045_fancheng_relief",
"title": "Fancheng Relief",
"path": "res://data/scenarios/045_fancheng_relief.json"
}
]
}

View File

@@ -0,0 +1,366 @@
{
"id": "045_fancheng_relief",
"name": "Fancheng Relief",
"objectives": {
"victory": "Reach Fancheng's outer gate with Cao Cao, then defeat Guan Yu's vanguard.",
"defeat": "Cao Cao or the Fancheng messenger is defeated, or the battle reaches Turn 18."
},
"conditions": {
"victory": { "type": "all_units_defeated", "team": "enemy", "after_event": "fancheng_gate_relieved" },
"defeat": [
{ "type": "any_officer_defeated", "team": "player", "officer_ids": ["cao_cao"] },
{ "type": "any_unit_defeated", "unit_ids": ["fancheng_messenger_ch45"] },
{ "type": "turn_reached", "turn": 18, "team": "player" }
]
},
"briefing": {
"title": "Fancheng Relief",
"location": "Fancheng, Han River, 219 CE",
"lines": [
"Ruxu's campaign has ended, but urgent word from the north says Cao Ren is locked inside Fancheng under Guan Yu's pressure.",
"Cao Cao's relief column must reach the outer gate before the Jingzhou vanguard turns the siege into a breach."
],
"conditional_lines": [
{
"campaign_flags": { "secured_ruxu_crossing": true },
"lines": [
"Securing the Ruxu crossing leaves a steadier eastern base, letting Cao Cao pull relief supplies north without abandoning the river front."
]
},
{
"campaign_flags": { "prepared_fancheng_relief": true },
"lines": [
"Preparing Fancheng relief early puts Cao Cao on the road quickly, but Guan Yu's scouts have already tightened the ring around Cao Ren."
]
}
]
},
"shop": {
"items": [
"bean",
"wine",
"iron_sword",
"training_spear",
"short_bow",
"hand_axe",
"war_axe",
"leather_armor",
"iron_armor"
],
"conditional_items": [
{
"campaign_flags": { "secured_ruxu_crossing": true },
"items": ["imperial_seal"]
},
{
"campaign_flags": { "prepared_fancheng_relief": true },
"items": ["war_drum"]
}
]
},
"roster": {
"max_units": 7,
"required_officers": ["cao_cao", "guo_jia"],
"required_units": ["fancheng_messenger_ch45"]
},
"formation": {
"cells": [[1, 3], [1, 4], [1, 5], [2, 2], [2, 3], [2, 4], [2, 5], [2, 6], [3, 2], [3, 3], [3, 4], [3, 5], [3, 6]]
},
"map": {
"width": 18,
"height": 11,
"terrain": [
"GGGGHHGGGGGGHHGGGG",
"GGFFHHGGRRGGHHFFGG",
"GGRRRRRRRRRRRRFFGG",
"GGGFGHGGGGRRGGGGGG",
"RRRRRRRRRRRRRRRRRR",
"GGGGGHHGGGRRGFFGGG",
"GGHHGFFFGGFFFGGHHG",
"GGHHGFFFGGFFFGGHHG",
"GGGGGGFFGGHHHGGGGG",
"GGFFGGGGGGHHHFFGGG",
"GGGGGGGGGGGGGGGGGG"
]
},
"deployments": [
{
"unit_id": "cao_cao_ch45",
"officer_id": "cao_cao",
"team": "player",
"pos": [1, 4]
},
{
"unit_id": "guo_jia_ch45",
"officer_id": "guo_jia",
"team": "player",
"requires_joined": true,
"pos": [2, 4]
},
{
"unit_id": "zhang_he_ch45",
"officer_id": "zhang_he",
"team": "player",
"requires_joined": true,
"pos": [2, 3]
},
{
"unit_id": "xiahou_dun_ch45",
"officer_id": "xiahou_dun",
"team": "player",
"pos": [1, 5]
},
{
"unit_id": "dian_wei_ch45",
"officer_id": "dian_wei",
"team": "player",
"requires_joined": true,
"pos": [2, 5]
},
{
"unit_id": "xiahou_yuan_ch45",
"officer_id": "xiahou_yuan",
"team": "player",
"requires_joined": true,
"pos": [3, 3]
},
{
"unit_id": "fancheng_messenger_ch45",
"name": "Fancheng Messenger",
"class_id": "infantry",
"team": "player",
"level": 32,
"controllable": false,
"persist_progression": false,
"ai_target_priority": 8,
"pos": [3, 4],
"base": { "hp": 118, "mp": 4, "atk": 18, "def": 28, "int": 18, "agi": 18 }
},
{
"unit_id": "guan_yu_vanguard_commander",
"name": "Guan Yu Vanguard Commander",
"class_id": "commander",
"team": "enemy",
"level": 42,
"pos": [14, 4],
"base": { "hp": 140, "mp": 62, "atk": 43, "def": 35, "int": 35, "agi": 23 }
},
{
"unit_id": "jingzhou_siege_captain",
"name": "Jingzhou Siege Captain",
"class_id": "guard_captain",
"team": "enemy",
"level": 42,
"pos": [12, 4],
"base": { "hp": 116, "atk": 43, "def": 36 }
},
{
"unit_id": "han_river_champion",
"name": "Han River Champion",
"class_id": "champion",
"team": "enemy",
"level": 42,
"pos": [15, 3],
"base": { "hp": 144, "mp": 12, "atk": 45, "def": 32, "int": 13, "agi": 28 }
},
{
"unit_id": "jingzhou_flood_advisor",
"name": "Jingzhou Flood Advisor",
"class_id": "military_advisor",
"team": "enemy",
"level": 42,
"pos": [13, 5],
"skills": ["blaze", "great_mend"],
"base": { "hp": 104, "mp": 88, "atk": 8, "def": 23, "int": 45, "agi": 21 }
},
{
"unit_id": "fancheng_siege_spear_north",
"name": "Fancheng Siege Spear",
"class_id": "infantry",
"team": "enemy",
"level": 42,
"pos": [12, 3],
"base": { "hp": 106, "atk": 43, "def": 33 }
},
{
"unit_id": "fancheng_siege_spear_south",
"name": "Fancheng Siege Spear",
"class_id": "infantry",
"team": "enemy",
"level": 42,
"pos": [12, 5],
"base": { "hp": 106, "atk": 43, "def": 33 }
},
{
"unit_id": "jingzhou_gate_marksman",
"name": "Jingzhou Gate Marksman",
"class_id": "marksman",
"team": "enemy",
"level": 42,
"pos": [13, 2],
"base": { "hp": 98, "atk": 44, "def": 19, "agi": 31 }
}
],
"events": [
{
"id": "opening",
"once": true,
"when": { "type": "battle_start" },
"actions": [
{ "type": "log", "text": "Cao Ren holds Fancheng's outer gate while Guan Yu's vanguard presses the siege line." }
]
},
{
"id": "opening_dialogue",
"once": true,
"when": { "type": "battle_begin" },
"actions": [
{
"type": "dialogue",
"lines": [
{ "speaker": "Cao Ren", "text": "Fancheng still stands, but every drum outside the gate is louder than the last." },
{ "speaker": "Guo Jia", "text": "A gate under siege is a clock. We must break the hand before it reaches the hour." },
{ "speaker": "Cao Cao", "text": "Protect the messenger and relieve the gate. Cao Ren does not fall while I still command the road." }
]
}
]
},
{
"id": "secured_ruxu_supports_relief",
"once": true,
"when": { "type": "turn_start", "team": "player", "turn": 2, "campaign_flags": { "secured_ruxu_crossing": true } },
"actions": [
{
"type": "dialogue",
"lines": [
{ "speaker": "Xiahou Yuan", "text": "Ruxu's secured crossing sent grain north behind us. The relief column will not starve before the gate." },
{ "speaker": "Cao Cao", "text": "Then Fancheng receives both food and steel." }
]
}
]
},
{
"id": "prepared_relief_tightens_siege",
"once": true,
"when": { "type": "turn_start", "team": "enemy", "turn": 2, "campaign_flags": { "prepared_fancheng_relief": true } },
"actions": [
{
"type": "dialogue",
"lines": [
{ "speaker": "Guan Yu Vanguard Commander", "text": "Cao Cao came north quickly. Tighten the ring before his column reaches Cao Ren." },
{ "speaker": "Zhang He", "text": "They saw our haste and answered with pressure. Good. The road will choose the stronger answer." }
]
},
{
"type": "spawn_deployment",
"deployment": {
"unit_id": "jingzhou_ring_riders",
"name": "Jingzhou Ring Riders",
"class_id": "cavalry",
"team": "enemy",
"level": 42,
"pos": [16, 3],
"base": { "hp": 96, "atk": 39, "def": 23, "agi": 29 }
}
}
]
},
{
"id": "turn_4_gate_pressure",
"once": true,
"when": { "type": "turn_start", "team": "enemy", "turn": 4 },
"actions": [
{
"type": "dialogue",
"lines": [
{ "speaker": "Jingzhou Flood Advisor", "text": "Keep Cao Ren behind the gate and make the relief column fight uphill through fear." },
{ "speaker": "Cao Ren", "text": "Fancheng has not opened its gate to fear yet." }
]
}
]
},
{
"id": "fancheng_gate_relieved",
"once": true,
"when": { "type": "unit_reaches_tile", "team": "player", "officer_ids": ["cao_cao"], "pos": [9, 4] },
"actions": [
{
"type": "set_objective",
"victory": "Fancheng's outer gate is relieved. Defeat Guan Yu's vanguard.",
"defeat": "Cao Cao or the Fancheng messenger is defeated, or the battle reaches Turn 18."
},
{
"type": "dialogue",
"lines": [
{ "speaker": "Cao Cao", "text": "Cao Ren, open only enough for my banner. The siege line breaks here." },
{ "speaker": "Guan Yu Vanguard Commander", "text": "Then break his banner before the gate breathes." }
]
},
{
"type": "spawn_deployments",
"deployments": [
{
"unit_id": "guan_yu_inner_spear",
"name": "Guan Yu Inner Spear",
"class_id": "guard_captain",
"team": "enemy",
"level": 42,
"pos": [16, 4],
"base": { "hp": 114, "atk": 43, "def": 36 }
},
{
"unit_id": "han_river_arrow_screen",
"name": "Han River Arrow Screen",
"class_id": "archer",
"team": "enemy",
"level": 42,
"pos": [16, 5],
"base": { "hp": 90, "atk": 42, "def": 16, "agi": 30 }
}
]
}
]
},
{
"id": "turn_9_relief_arrives",
"once": true,
"when": { "type": "turn_start", "team": "player", "turn": 9 },
"actions": [
{
"type": "dialogue",
"lines": [
{ "speaker": "Xiahou Dun", "text": "The siege line is splitting. Cao Ren's gate is still ours." },
{ "speaker": "Cao Cao", "text": "Then make the enemy remember which side of the gate survived." }
]
}
]
}
],
"rewards": {
"gold": 8800,
"items": ["bean", "wine", "war_drum"]
},
"post_battle_dialogue": [
{ "speaker": "Cao Ren", "text": "Fancheng stands. Another day inside those walls and the gate would have begun speaking for the enemy." },
{ "speaker": "Guo Jia", "text": "The siege is broken, but Guan Yu's supply road still feeds his courage." },
{ "speaker": "Cao Cao", "text": "Then choose whether Fancheng becomes a wall we strengthen or a blade we push toward Jingzhou." }
],
"post_battle_choices": [
{
"id": "reinforce_fancheng",
"label": "Reinforce Fancheng",
"description": "Cao Cao reinforces Fancheng so the northern gate can withstand another siege.",
"set_flags": { "reinforced_fancheng": true, "struck_jingzhou_supply": false },
"gold": 1500,
"items": ["imperial_seal"]
},
{
"id": "strike_jingzhou_supply",
"label": "Strike Supply",
"description": "Cao Cao strikes Guan Yu's Jingzhou supply road before the siege army can reform.",
"set_flags": { "reinforced_fancheng": false, "struck_jingzhou_supply": true },
"gold": 1300,
"items": ["war_drum"]
}
]
}

View File

@@ -55,6 +55,7 @@ data/scenarios/041_hanzhong_settlement.json
data/scenarios/042_ruxu_advance.json
data/scenarios/043_ruxu_river_line.json
data/scenarios/044_ruxu_crossing.json
data/scenarios/045_fancheng_relief.json
```
## Campaign
@@ -111,7 +112,8 @@ The campaign file defines scenario order, resource paths, and officers who are a
{ "id": "041_hanzhong_settlement", "title": "Hanzhong Settlement", "path": "res://data/scenarios/041_hanzhong_settlement.json" },
{ "id": "042_ruxu_advance", "title": "Ruxu Advance", "path": "res://data/scenarios/042_ruxu_advance.json" },
{ "id": "043_ruxu_river_line", "title": "Ruxu River Line", "path": "res://data/scenarios/043_ruxu_river_line.json" },
{ "id": "044_ruxu_crossing", "title": "Ruxu Crossing", "path": "res://data/scenarios/044_ruxu_crossing.json" }
{ "id": "044_ruxu_crossing", "title": "Ruxu Crossing", "path": "res://data/scenarios/044_ruxu_crossing.json" },
{ "id": "045_fancheng_relief", "title": "Fancheng Relief", "path": "res://data/scenarios/045_fancheng_relief.json" }
]
}
```

View File

@@ -21,7 +21,7 @@
- Destination victory conditions and objective map markers exist.
- Turn-limit conditions and HUD turn-limit display exist.
- Victory reward summary is visible.
- Next-battle flow exists across the current forty-four-scenario campaign.
- Next-battle flow exists across the current forty-five-scenario campaign.
- Campaign completion and new-campaign reset exist.
- Reward inventory can be brought into the next battle.
@@ -52,7 +52,7 @@
- Party roster persistence has a first save-file skeleton.
- Level, experience, and equipment persistence.
- Chapter selection and save/load.
- Linear forty-four-scenario campaign order exists.
- Linear forty-five-scenario campaign order exists.
- Save reset exists.
- Victory rewards, consumable counts, equipment stock, and equipped gear persist.
- A basic pre-battle shop with scenario-specific stock exists. Sell-back and richer item management are still planned.
@@ -104,6 +104,7 @@
- Forty-second-scenario content exists with Ruxu riverbank pressure, Wu vanguard resistance, Hanzhong garrison or Ruxu pivot branch reactions, and Ruxu bank or Sun Quan river-line follow-up flags.
- Forty-third-scenario content exists with Ruxu river-line pressure, water-move enemy boats, Ruxu bank or Sun Quan line branch reactions, and Ruxu camp or crossing follow-up flags.
- Forty-fourth-scenario content exists with Ruxu crossing pressure, water-move counterboats, camp or forced-crossing branch reactions, and Ruxu base or Fancheng relief follow-up flags.
- Forty-fifth-scenario content exists with Fancheng relief pressure, protected Fancheng messenger defense, Ruxu crossing or Fancheng relief branch reactions, and Fancheng reinforcement or Jingzhou supply follow-up flags.
## Milestone 5: Presentation