Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,22 @@ dotnet run --project src/Sts2Headless/Sts2Headless.csproj
{"cmd": "action", "action": "end_turn"}
{"cmd": "action", "action": "select_map_node", "args": {"col": 3, "row": 1}}
{"cmd": "action", "action": "skip_card_reward"}
{"cmd": "get_cards"}
{"cmd": "get_powers"}
{"cmd": "get_monsters"}
{"cmd": "quit"}
```

Each command returns a JSON decision point (`map_select` / `combat_play` / `card_reward` / `rest_site` / `event_choice` / `shop` / `game_over`). All names are in English.

`combat_play` responses also include a flat `choices` array of valid actions for the current combat state, so a client can choose directly from engine-approved moves instead of rebuilding legality from the board state.

`get_cards` returns the full runtime card catalog from the DLL in the same summary style used elsewhere in the CLI: `id`, `name`, `cost`, `type`, `rarity`, `target_type`, `stats`, `description`, `keywords`, and `after_upgrade`.

`get_powers` returns the runtime power catalog the bridge can discover from the DLL, with `id`, `name`, `description`, `stats`, and the underlying runtime type name.

`get_monsters` returns the runtime monster catalog the bridge can discover from the DLL, with `id`, `name`, `title`, `min_hp`, `max_hp`, and the underlying runtime type name.

## Game Logs

Every run is automatically logged to `logs/` as a JSONL file (one JSON per line), recording each game state and action with timestamps. Logs older than 7 days are cleaned up automatically.
Expand Down
Binary file removed docs/demo_en.gif
Binary file not shown.
Binary file removed docs/demo_zh.gif
Binary file not shown.
36 changes: 35 additions & 1 deletion src/Sts2Headless/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,8 @@ static void Main(string[] args)
cmd.TryGetProperty("character", out var ch) ? ch.GetString() ?? "Ironclad" : "Ironclad",
cmd.TryGetProperty("ascension", out var asc) ? asc.GetInt32() : 0,
cmd.TryGetProperty("seed", out var s) ? s.GetString() : null,
cmd.TryGetProperty("lang", out var lang) ? lang.GetString() ?? "en" : "en"
cmd.TryGetProperty("lang", out var lang) ? lang.GetString() ?? "en" : "en",
cmd.TryGetProperty("neow", out var neow) ? neow.GetBoolean() : true
);

case "action":
Expand Down Expand Up @@ -161,6 +162,15 @@ static void Main(string[] args)
case "get_map":
return sim.GetFullMap();

case "get_cards":
return sim.GetCards();

case "get_powers":
return sim.GetPowers();

case "get_monsters":
return sim.GetMonsters();

case "set_player":
{
var args = new Dictionary<string, JsonElement>();
Expand All @@ -177,6 +187,30 @@ static void Main(string[] args)
return sim.EnterRoom(roomType, encounter, eventId);
}

case "setup_combat":
{
var scCharacter = cmd.TryGetProperty("character", out var scCh) ? scCh.GetString() ?? "Ironclad" : "Ironclad";
var scEncounter = cmd.TryGetProperty("encounter", out var scEnc) ? scEnc.GetString() ?? "SHRINKER_BEETLE_WEAK" : "SHRINKER_BEETLE_WEAK";
var scAscension = cmd.TryGetProperty("ascension", out var scAsc) ? scAsc.GetInt32() : 10;
var scSeed = cmd.TryGetProperty("seed", out var scSd) ? scSd.GetString() : null;
var scHp = cmd.TryGetProperty("hp", out var scHpEl) ? scHpEl.GetInt32() : 80;
var scMaxHp = cmd.TryGetProperty("max_hp", out var scMhpEl) ? scMhpEl.GetInt32() : 80;
var scGold = cmd.TryGetProperty("gold", out var scGEl) ? scGEl.GetInt32() : 99;
var scLang = cmd.TryGetProperty("lang", out var scLa) ? scLa.GetString() ?? "en" : "en";

var scRelics = new List<string>();
if (cmd.TryGetProperty("relics", out var scRelicsArr))
foreach (var r in scRelicsArr.EnumerateArray())
scRelics.Add(r.GetString() ?? "");

var scDeck = new List<string>();
if (cmd.TryGetProperty("deck", out var scDeckArr))
foreach (var d in scDeckArr.EnumerateArray())
scDeck.Add(d.GetString() ?? "");

return sim.SetupCombat(scCharacter, scEncounter, scAscension, scSeed, scHp, scMaxHp, scGold, scRelics, scDeck, scLang);
}

case "set_draw_order":
{
var cards = new List<string>();
Expand Down
Loading