No man's land: TurnResult.unowned + release/re-claim in applyTurnResult + distinct grey map rendering (#16 P3)
- shared/protocol.ts: TurnResult.unowned (keys released this turn) + the map presentation contract (regionFillStyle / unownedTooltipLabel, hue-less grey) - shared/types.ts: required GameState.unowned (cumulative mid-game releases; [] at init, distinct from preset-unassigned regions) - server/engine.ts: applyTurnResult applies releases first (sole-owner only, never fabricating no man's land from unassigned keys), then claims against the post-release snapshot (gain on an ownerless key = re-claim); lone release is isMeaningful; prompts + user payload carry the unowned field - server/stub.ts: unchanged behavior (never releases; e2e stays stable) - server/db.ts: legacy rows load with unowned defaulted to [] - server/index.ts: create-game sets []; jump reference table includes released keys so the model can name them for re-claim - WorldMap/App: unowned prop -> visible grey + 'No man's land' tooltip - unit tests: 105 -> 127 (release/re-claim suites, presentation contract, legacy-row normalization)
This commit is contained in:
@@ -24,6 +24,13 @@ export interface StubPayload {
|
||||
* reads the frontier from the prompt instead.
|
||||
*/
|
||||
frontier?: string[];
|
||||
/**
|
||||
* (v0.22, #16 P3) Region keys currently in no man's land (`state.unowned`),
|
||||
* emitted by the engine's user prompt. The stub ignores this field — it
|
||||
* never releases a region (see deterministicTurn), so no-man's-land behavior
|
||||
* is covered by unit tests against applyTurnResult, not by the stub.
|
||||
*/
|
||||
unowned?: string[];
|
||||
}
|
||||
|
||||
function truncate(s: string, n: number): string {
|
||||
@@ -45,6 +52,11 @@ function truncate(s: string, n: number): string {
|
||||
* content in one round), so the frontier comes from the prompt payload, not
|
||||
* from a getNeighbours call. With an empty frontier (no controllable border)
|
||||
* no territory change is emitted, keeping every existing assertion stable.
|
||||
*
|
||||
* (v0.22, #16 P3) The stub NEVER releases a region to no man's land (it
|
||||
* always returns `unowned: []`) — e2e assertions rely on its fully-deterministic
|
||||
* one-conquest behavior, so the release/re-claim path is exercised by unit
|
||||
* tests only (see server/engine.test.ts).
|
||||
*/
|
||||
export function deterministicTurn(p: StubPayload): TurnResult {
|
||||
const state = p.state;
|
||||
@@ -108,6 +120,7 @@ export function deterministicTurn(p: StubPayload): TurnResult {
|
||||
stateChanges: [{ nation: pid, stat: 'military', op: 'set', value: mil }],
|
||||
relations: otherId ? [{ a: pid, b: otherId, set: 'ally' }] : [],
|
||||
territoryChanges,
|
||||
unowned: [], // the stub never creates no man's land (see doc comment)
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user