docs: sync plan with shipped corrections (hold-the-line, smoke-test matchId)
This commit is contained in:
@@ -646,6 +646,8 @@ Create `public/assets/scenarios/skirmish.json`:
|
||||
|
||||
Create `public/assets/scenarios/hold-the-line.json`:
|
||||
|
||||
> **NOTE:** The original terrain (a 12-tile forest pocket containing the objective at `(4,4)`) made the objective unreachable — alpha defenders (speed 1, inside forest) cannot move out, and bravo strikers (speed 3) cannot bridge from column 9 to column 4 through forest. The validator's reachability rule is correct. The corrected fixture below places the objective in the open at `(4,4)`, gives alpha defenders speed 2 so they can step out of their cover onto the objective, gives bravo-4 the scout archetype at speed 5 placed on `(9,4)` so it can reach `(4,4)` across open ground in 5 steps, and limits forest to a small cluster around the alpha deployment zone that doesn't block bravo's path. The tactically-intended property — alpha fights from forest cover, bravo has to push across open ground to reach the objective — is preserved.
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "hold-the-line",
|
||||
@@ -654,23 +656,22 @@ Create `public/assets/scenarios/hold-the-line.json`:
|
||||
"width": 10,
|
||||
"height": 8,
|
||||
"terrain": {
|
||||
"3:2": "forest", "3:3": "forest", "3:4": "forest", "3:5": "forest",
|
||||
"4:2": "forest", "4:3": "forest", "4:4": "forest", "4:5": "forest",
|
||||
"5:2": "forest", "5:3": "forest", "5:4": "forest", "5:5": "forest"
|
||||
"2:2": "forest", "2:3": "forest", "2:4": "forest", "2:5": "forest",
|
||||
"3:2": "forest", "3:3": "forest"
|
||||
}
|
||||
},
|
||||
"units": [
|
||||
{ "id": "alpha-1", "teamId": "alpha", "position": { "x": 4, "y": 3 }, "maxHealth": 14, "health": 14, "attack": 3, "defense": 5, "speed": 1, "archetype": "defender", "abilities": [] },
|
||||
{ "id": "alpha-2", "teamId": "alpha", "position": { "x": 3, "y": 4 }, "maxHealth": 14, "health": 14, "attack": 3, "defense": 5, "speed": 1, "archetype": "defender", "abilities": [] },
|
||||
{ "id": "alpha-3", "teamId": "alpha", "position": { "x": 5, "y": 4 }, "maxHealth": 14, "health": 14, "attack": 3, "defense": 5, "speed": 1, "archetype": "defender", "abilities": [] },
|
||||
{ "id": "alpha-1", "teamId": "alpha", "position": { "x": 2, "y": 3 }, "maxHealth": 14, "health": 14, "attack": 3, "defense": 5, "speed": 2, "archetype": "defender", "abilities": [] },
|
||||
{ "id": "alpha-2", "teamId": "alpha", "position": { "x": 2, "y": 4 }, "maxHealth": 14, "health": 14, "attack": 3, "defense": 5, "speed": 2, "archetype": "defender", "abilities": [] },
|
||||
{ "id": "alpha-3", "teamId": "alpha", "position": { "x": 2, "y": 5 }, "maxHealth": 14, "health": 14, "attack": 3, "defense": 5, "speed": 2, "archetype": "defender", "abilities": [] },
|
||||
{ "id": "bravo-1", "teamId": "bravo", "position": { "x": 9, "y": 1 }, "maxHealth": 8, "health": 8, "attack": 5, "defense": 2, "speed": 3, "archetype": "striker", "abilities": ["area_damage"] },
|
||||
{ "id": "bravo-2", "teamId": "bravo", "position": { "x": 9, "y": 3 }, "maxHealth": 8, "health": 8, "attack": 5, "defense": 2, "speed": 3, "archetype": "striker", "abilities": ["area_damage"] },
|
||||
{ "id": "bravo-3", "teamId": "bravo", "position": { "x": 9, "y": 5 }, "maxHealth": 7, "health": 7, "attack": 2, "defense": 2, "speed": 3, "archetype": "support", "abilities": ["heal"] },
|
||||
{ "id": "bravo-4", "teamId": "bravo", "position": { "x": 9, "y": 7 }, "maxHealth": 6, "health": 6, "attack": 3, "defense": 1, "speed": 5, "archetype": "scout", "abilities": [] }
|
||||
{ "id": "bravo-3", "teamId": "bravo", "position": { "x": 9, "y": 7 }, "maxHealth": 7, "health": 7, "attack": 2, "defense": 2, "speed": 3, "archetype": "support", "abilities": ["heal"] },
|
||||
{ "id": "bravo-4", "teamId": "bravo", "position": { "x": 9, "y": 4 }, "maxHealth": 6, "health": 6, "attack": 3, "defense": 1, "speed": 5, "archetype": "scout", "abilities": [] }
|
||||
],
|
||||
"deploymentZones": {
|
||||
"alpha": { "teamId": "alpha", "positions": [{ "x": 4, "y": 3 }, { "x": 3, "y": 4 }, { "x": 5, "y": 4 }] },
|
||||
"bravo": { "teamId": "bravo", "positions": [{ "x": 9, "y": 1 }, { "x": 9, "y": 3 }, { "x": 9, "y": 5 }, { "x": 9, "y": 7 }] }
|
||||
"alpha": { "teamId": "alpha", "positions": [{ "x": 2, "y": 3 }, { "x": 2, "y": 4 }, { "x": 2, "y": 5 }] },
|
||||
"bravo": { "teamId": "bravo", "positions": [{ "x": 9, "y": 1 }, { "x": 9, "y": 3 }, { "x": 9, "y": 7 }, { "x": 9, "y": 4 }] }
|
||||
},
|
||||
"objectives": {
|
||||
"objective-1": { "id": "objective-1", "position": { "x": 4, "y": 4 } }
|
||||
@@ -679,7 +680,6 @@ Create `public/assets/scenarios/hold-the-line.json`:
|
||||
"holdRoundsRequired": 3
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 4: Create `last-stand.json`**
|
||||
|
||||
Create `public/assets/scenarios/last-stand.json`:
|
||||
@@ -850,7 +850,7 @@ final class GetBundledScenariosTest extends TestCase
|
||||
|
||||
private function writeFixture(string $name, string $body): void
|
||||
{
|
||||
file_put_contents($this->tmpDir . '/' . $name, $body);
|
||||
file_put_contents($this->tmpDir . '/' . $name . '.json', $body);
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -2327,10 +2327,10 @@ final class PostMatchActionTest extends TestCase
|
||||
new Battlefield(8, 8),
|
||||
[
|
||||
new UnitState('alpha-1', 'alpha', new Position(0, 0), 10, 10, 3, 3, 2, 2, false, Archetype::Defender),
|
||||
new UnitState('alpha-2', 'alpha', new Position(1, 0), 10, 10, 3, 3, 2, 2, false, Archetype::Defender),
|
||||
new UnitState('alpha-3', 'alpha', new Position(2, 0), 10, 10, 3, 3, 2, 2, false, Archetype::Support, ['heal']),
|
||||
new UnitState('alpha-2', 'alpha', new Position(0, 1), 10, 10, 3, 3, 2, 2, false, Archetype::Defender),
|
||||
new UnitState('alpha-3', 'alpha', new Position(1, 1), 10, 10, 3, 3, 2, 2, false, Archetype::Support, ['heal']),
|
||||
new UnitState('bravo-1', 'bravo', new Position(7, 7), 10, 10, 3, 3, 2, 2, false, Archetype::Striker),
|
||||
new UnitState('bravo-2', 'bravo', new Position(6, 7), 10, 10, 3, 3, 2, 2, false, Archetype::Striker),
|
||||
new UnitState('bravo-2', 'bravo', new Position(6, 6), 10, 10, 3, 3, 2, 2, false, Archetype::Striker),
|
||||
new UnitState('bravo-3', 'bravo', new Position(5, 7), 10, 10, 3, 3, 2, 2, false, Archetype::Striker),
|
||||
],
|
||||
'alpha',
|
||||
@@ -3024,6 +3024,15 @@ use PHPUnit\Framework\TestCase;
|
||||
* End-to-end smoke test. Boots a real `php -S` dev server and walks the
|
||||
* Skirmish bundled scenario to a winner. Gated by BATTLEFORGE_E2E=1 so the
|
||||
* per-commit CI does not pay its cost.
|
||||
*
|
||||
* NOTE: The original brief hard-coded a MATCH_ID constant (`0123456789abcdef`)
|
||||
* and used it in every action body. But `PostStartMatch` mints a random matchId
|
||||
* server-side via `bin2hex(random_bytes(8))`, so the action body must echo
|
||||
* back the response's matchId. The fix below captures `$matchId` from the
|
||||
* start-match response and threads it through `pickAction`'s second
|
||||
* argument. The `MATCH_ID` constant is removed; the `pickAction` method
|
||||
* signature gains `string $matchId`; the `assertSame(self::MATCH_ID, ...)`
|
||||
* check is replaced with a regex match.
|
||||
*/
|
||||
final class PostMatchActionSmokeTest extends TestCase
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user