Files
galaxy-game/game/openapi.yaml
Ilia Denisov 969c0480ba ui/phase-27: battle viewer (radial scene, playback, map markers)
Engine wire change: Report.battle switched from []uuid.UUID to
[]BattleSummary{id, planet, shots} so the map can place battle
markers without N extra fetches. FBS schema + generated Go/TS
regenerated; transcoder + report controller updated; openapi
adds the BattleSummary schema with a freeze test.

Backend gateway forwards engine GET /api/v1/battle/:turn/:uuid as
/api/v1/user/games/{game_id}/battles/{turn}/{battle_id} (handler
plus engineclient.FetchBattle, contract test stub, openapi spec).

UI:
- BattleViewer (lib/battle-player/) is a logically isolated SVG
  radial scene that consumes a BattleReport prop. Planet at the
  centre, races on the outer ring at equal angular spacing, race
  clusters by (race, className) with <class>:<numLeft> labels;
  observer groups (inBattle: false) are not drawn; eliminated
  races drop out and survivors re-distribute on the next frame.
- Shot line per frame: red on destroyed, green otherwise; erased
  on the next frame. Playback controls: play/pause + step ± +
  rewind + 1x/2x/4x speed (400/200/100 ms per frame).
- Page wrapper (lib/active-view/battle.svelte) loads BattleReport
  via api/battle-fetch.ts; synthetic-gameId prefix routes to a
  fixture loader, otherwise REST through the gateway. Always-
  visible <ol> text protocol satisfies the accessibility ask.
- section-battles.svelte links every battle UUID into the viewer.
- map/battle-markers.ts: yellow X cross of 2 LinePrim through the
  corners of the planet's circumscribed square (stroke width
  clamps from 1 px at 1 shot to 5 px at 100+ shots); bombing
  marker is a stroke-only ring (yellow when damaged, red when
  wiped). Wired into state-binding.ts; click handler dispatches
  battle clicks to the viewer and bombing clicks to the matching
  Reports row.
- i18n keys for the viewer in en + ru.

Docs: ui/docs/battle-viewer-ux.md, FUNCTIONAL.md §6.5 + ru
mirror, ui/PLAN.md Phase 27 decisions + deferred TODOs (push
event, richer class visuals, animated re-distribution).

Tests: Vitest unit (radial layout + timeline frame builder +
marker stroke formula + marker primitives), Playwright e2e for
the viewer (Reports link → viewer, playback step, not-found),
backend engineclient FetchBattle (200 / 404 / bad input), engine
openapi freezes (BattleReport, BattleReportGroup,
BattleActionReport, BattleSummary, Report.battle items).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 12:24:20 +02:00

1290 lines
40 KiB
YAML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
openapi: 3.0.3
info:
title: Galaxy Game Service REST API
version: v1
description: |
This specification documents the REST contract of `galaxy/game`.
The service hosts a single game instance and exposes endpoints for game
initialization, turn advancement, game-state queries, player reports, and
batched player command execution.
Transport rules:
- request bodies are JSON
- `PUT /api/v1/command` is rate-limited to one concurrent execution;
requests that cannot acquire the execution slot within 100 ms receive
`504 Gateway Timeout`
- `501 Not Implemented` is returned without a body when the game has not
been initialized
- validation errors return `400` with `{"error": "message"}`
- game-engine errors return `500` with `{"generic_error": "message", "code": integer}`
- other internal errors return `500` with `{"error": "message"}`
servers:
- url: http://localhost:8080
description: Default local listener for Game Service.
tags:
- name: GameLifecycle
description: Game initialization, state retrieval, and turn advancement.
- name: PlayerActions
description: Player command execution, order validation, and turn-report retrieval.
- name: Health
description: Technical liveness probes used by Runtime Manager and operator tooling.
paths:
/api/v1/admin/status:
get:
tags:
- GameLifecycle
operationId: adminGetGameStatus
summary: Get the current game state
description: |
Returns the current game state including turn number, stage, and a
summary of all players. Returns `501` if the game has not yet been
initialized. Routed only from the trusted network segment that
connects `Game Master` to the engine container.
responses:
"200":
description: Current game state.
content:
application/json:
schema:
$ref: "#/components/schemas/StateResponse"
"501":
description: Game has not been initialized yet.
"500":
$ref: "#/components/responses/InternalError"
/api/v1/admin/init:
post:
tags:
- GameLifecycle
operationId: adminInitGame
summary: Initialize a new game
description: |
Generates a new game instance with the supplied list of races.
Requires at least 10 race entries. Routed only from the trusted
network segment that connects `Game Master` to the engine
container.
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/InitRequest"
responses:
"201":
description: Game initialized successfully.
content:
application/json:
schema:
$ref: "#/components/schemas/StateResponse"
"400":
$ref: "#/components/responses/ValidationError"
"500":
$ref: "#/components/responses/InternalError"
/api/v1/admin/race/banish:
post:
tags:
- GameLifecycle
operationId: adminBanishRace
summary: Deactivate a race after a permanent platform-level removal
description: |
Deactivates the named race in the running engine. Called by `Game
Master` after a Lobby-driven permanent membership removal. Routed
only from the trusted network segment that connects `Game Master`
to the engine container.
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/BanishRequest"
responses:
"204":
description: Race deactivated; no response body.
"400":
$ref: "#/components/responses/ValidationError"
"500":
$ref: "#/components/responses/InternalError"
/api/v1/report:
get:
tags:
- PlayerActions
operationId: getReport
summary: Get a player turn report
description: |
Returns the full game report for the specified player and turn.
`player` must be a non-blank race name. `turn` defaults to `0`.
parameters:
- $ref: "#/components/parameters/PlayerParam"
- $ref: "#/components/parameters/TurnParam"
responses:
"200":
description: Player turn report.
content:
application/json:
schema:
$ref: "#/components/schemas/Report"
"400":
$ref: "#/components/responses/ValidationError"
"500":
$ref: "#/components/responses/InternalError"
/api/v1/command:
put:
tags:
- PlayerActions
operationId: executeCommands
summary: Execute a batch of player commands
description: |
Applies one or more game commands for the specified actor. Serialized
to one concurrent execution; requests that cannot acquire the execution
slot within 100 ms return `504 Gateway Timeout`. Returns `202 Accepted`
with no body on success. Reserved for future use; player order
submissions go through `/api/v1/order`.
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/CommandRequest"
responses:
"202":
description: All commands accepted.
"400":
$ref: "#/components/responses/ValidationError"
"504":
description: Command execution slot not acquired within 100 ms.
"500":
$ref: "#/components/responses/InternalError"
/api/v1/order:
put:
tags:
- PlayerActions
operationId: validateOrder
summary: Validate and store a player order without executing it
description: |
Validates and stores the game commands structurally without executing them.
On success returns `202 Accepted` with the stored order, including the
engine-assigned `updatedAt` timestamp used by clients to detect stale
submissions.
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/CommandRequest"
responses:
"202":
description: Order is structurally valid and stored.
content:
application/json:
schema:
$ref: "#/components/schemas/UserGamesOrder"
"400":
$ref: "#/components/responses/ValidationError"
"500":
$ref: "#/components/responses/InternalError"
get:
tags:
- PlayerActions
operationId: getOrder
summary: Fetch the stored order for a player and turn
description: |
Returns the order previously stored by `PUT /api/v1/order` for the
specified player and turn. Responds `204 No Content` when no order
has been stored for that turn.
parameters:
- $ref: "#/components/parameters/PlayerParam"
- $ref: "#/components/parameters/TurnParam"
responses:
"200":
description: Stored player order for the requested turn.
content:
application/json:
schema:
$ref: "#/components/schemas/UserGamesOrder"
"204":
description: No order has been stored for this player on this turn.
"400":
$ref: "#/components/responses/ValidationError"
"500":
$ref: "#/components/responses/InternalError"
/api/v1/battle/{turn}/{uuid}:
get:
tags:
- PlayerActions
operationId: getBattle
summary: Fetch a single battle report
description: |
Returns the full `BattleReport` for the supplied `turn` and battle
identifier. The `turn` segment must be a non-negative integer; the
`uuid` segment must be a valid RFC 4122 UUID. Responds with
`404 Not Found` when no battle is stored for the supplied pair.
parameters:
- $ref: "#/components/parameters/BattleTurnParam"
- $ref: "#/components/parameters/BattleIDParam"
responses:
"200":
description: Battle report for the supplied turn and identifier.
content:
application/json:
schema:
$ref: "#/components/schemas/BattleReport"
"400":
$ref: "#/components/responses/ValidationError"
"404":
description: No battle exists for the supplied turn and identifier.
"500":
$ref: "#/components/responses/InternalError"
/api/v1/admin/turn:
put:
tags:
- GameLifecycle
operationId: adminGenerateTurn
summary: Advance the game to the next turn
description: |
Processes the current turn and generates the next one. Returns the
updated game state. Routed only from the trusted network segment
that connects `Game Master` to the engine container.
responses:
"200":
description: Updated game state after turn generation.
content:
application/json:
schema:
$ref: "#/components/schemas/StateResponse"
"500":
$ref: "#/components/responses/InternalError"
/healthz:
get:
tags:
- Health
operationId: healthz
summary: Engine liveness probe
description: |
Returns `{"status":"ok"}` with HTTP `200` whenever the HTTP server
is serving requests, regardless of whether the engine has been
initialised through `POST /api/v1/admin/init`. Used by `Runtime
Manager` to probe a freshly started container before `init` runs.
Carries no game-state semantics; use `GET /api/v1/admin/status`
for game-state inspection.
responses:
"200":
description: Engine HTTP server is up.
content:
application/json:
schema:
$ref: "#/components/schemas/HealthzResponse"
components:
parameters:
PlayerParam:
name: player
in: query
required: true
description: Race name of the player requesting the report. Must be non-blank.
schema:
type: string
minLength: 1
TurnParam:
name: turn
in: query
required: false
description: Turn number to load the report for. Defaults to 0.
schema:
type: integer
minimum: 0
default: 0
BattleTurnParam:
name: turn
in: path
required: true
description: Turn number the battle was generated on.
schema:
type: integer
minimum: 0
BattleIDParam:
name: uuid
in: path
required: true
description: Battle identifier (RFC 4122 UUID).
schema:
type: string
format: uuid
schemas:
HealthzResponse:
type: object
description: Engine liveness probe response payload.
required:
- status
properties:
status:
type: string
description: Always "ok" while the engine HTTP server is serving requests.
enum:
- ok
StateResponse:
type: object
description: Summary game state returned after initialization and at each turn boundary.
required:
- id
- turn
- stage
- player
- finished
properties:
id:
type: string
format: uuid
description: Unique identifier of this game instance.
turn:
type: integer
minimum: 0
description: Current turn number.
stage:
type: integer
minimum: 0
description: Current stage within the turn for games that support state modification.
player:
type: array
description: Summary state for each player participating in the game.
items:
$ref: "#/components/schemas/PlayerState"
finished:
type: boolean
description: |
True exactly once on the turn-generation response that ends the
game; otherwise false. Server default: false. `Game Master`
uses this flag as the sole signal to run the platform finish
flow. The conditional logic that flips it to true lives in
the engine's domain code and is owned by the engine
maintainers.
PlayerState:
type: object
description: Brief player state returned as part of the game state response.
required:
- id
- raceName
- planets
- population
- extinct
properties:
id:
type: string
format: uuid
description: Unique player identifier within this game.
raceName:
type: string
description: Name of the player's race.
planets:
type: integer
minimum: 0
description: Number of planets currently owned by the player.
population:
type: number
description: Total population summed across all player planets.
extinct:
type: boolean
description: True when the race has been eliminated or voluntarily quit.
InitRequest:
type: object
description: Initialization request specifying the race list for a new game.
required:
- races
properties:
races:
type: array
description: List of participating races. Minimum 10 entries required.
minItems: 10
items:
$ref: "#/components/schemas/InitRace"
InitRace:
type: object
description: A single race entry in an initialization request.
required:
- raceName
properties:
raceName:
type: string
description: Name of the race. Must be non-blank and satisfy the entity-name format.
minLength: 1
BanishRequest:
type: object
description: |
Request body for the admin banish endpoint. `race_name` must
identify an existing race in the engine roster.
required:
- race_name
properties:
race_name:
type: string
description: Name of the race to banish. Must be non-blank.
minLength: 1
CommandRequest:
type: object
description: |
Batch command payload. `actor` identifies the race submitting the commands.
Each element of `cmd` is a polymorphic command object discriminated by the
`@type` field. At least one command is required.
required:
- actor
- cmd
properties:
actor:
type: string
description: Race name of the actor submitting the commands. Must be non-blank.
minLength: 1
cmd:
type: array
description: One or more commands to execute in order.
minItems: 1
items:
$ref: "#/components/schemas/Command"
UserGamesOrder:
type: object
description: |
Stored player order. Returned by `PUT /api/v1/order` after successful
validation and by `GET /api/v1/order` when fetching a previously stored
batch. `cmd` mirrors the command list submitted by the player; entries
carry per-command result fields (`cmdApplied`, `cmdErrorCode`) once the
order has been processed during turn generation.
required:
- game_id
- updatedAt
- cmd
properties:
game_id:
type: string
format: uuid
description: Identifier of the game this order belongs to.
updatedAt:
type: integer
format: int64
description: Engine-assigned UTC millisecond timestamp of the last write.
cmd:
type: array
description: Commands stored as part of this order, in submission order.
items:
$ref: "#/components/schemas/Command"
Command:
type: object
description: |
Polymorphic game command. The `@type` field identifies the variant.
Each variant extends the base fields with additional type-specific
parameters documented in `pkg/model/order/order.go`.
required:
- "@type"
- cmdId
properties:
"@type":
$ref: "#/components/schemas/CommandType"
cmdId:
type: string
format: uuid
description: Unique command identifier (RFC 4122 UUID).
cmdApplied:
type: boolean
description: Set in command-result responses; true when the command was applied.
cmdErrorCode:
type: integer
description: Set in command-result responses; non-zero when the command was rejected.
CommandType:
type: string
description: Discriminator identifying the game command variant carried in a `cmd` element.
enum:
- raceQuit
- raceVote
- raceRelation
- shipClassCreate
- shipClassMerge
- shipClassRemove
- shipGroupBreak
- shipGroupLoad
- shipGroupUnload
- shipGroupSend
- shipGroupUpgrade
- shipGroupMerge
- shipGroupDismantle
- shipGroupTransfer
- shipGroupJoinFleet
- fleetMerge
- fleetSend
- scienceCreate
- scienceRemove
- planetRename
- planetProduce
- planetRouteSet
- planetRouteRemove
Report:
type: object
description: |
Full game report for one player at one turn boundary. Optional array
fields are omitted when empty.
required:
- version
- turn
- mapWidth
- mapHeight
- mapPlanets
- race
- votes
- voteFor
- player
properties:
version:
type: integer
minimum: 0
description: Report format version.
turn:
type: integer
minimum: 0
description: Turn number this report covers.
mapWidth:
type: integer
minimum: 0
description: Width of the star map.
mapHeight:
type: integer
minimum: 0
description: Height of the star map.
mapPlanets:
type: integer
minimum: 0
description: Total number of planets on the map.
race:
type: string
description: Race name of the report recipient.
votes:
type: number
description: Fraction of alliance votes held by this race.
voteFor:
type: string
description: Race name this player is currently voting for.
player:
type: array
description: Diplomatic and aggregate statistics for each known player.
items:
$ref: "#/components/schemas/ReportPlayer"
localScience:
type: array
description: Science projects owned by this race.
items:
$ref: "#/components/schemas/Science"
otherScience:
type: array
description: Science projects owned by other known races.
items:
$ref: "#/components/schemas/OtherScience"
localShipClass:
type: array
description: Ship classes designed by this race.
items:
$ref: "#/components/schemas/ShipClass"
otherShipClass:
type: array
description: Ship classes belonging to other known races.
items:
$ref: "#/components/schemas/OtherShipClass"
battle:
type: array
description: Battle summaries relevant to this turn.
items:
$ref: "#/components/schemas/BattleSummary"
bombing:
type: array
description: Bombing events that occurred during this turn.
items:
$ref: "#/components/schemas/Bombing"
incomingGroup:
type: array
description: Identified ship groups inbound toward this race's planets.
items:
$ref: "#/components/schemas/IncomingGroup"
localPlanet:
type: array
description: Full state of planets owned by this race.
items:
$ref: "#/components/schemas/LocalPlanet"
shipProduction:
type: array
description: Active ship construction status on this race's planets.
items:
$ref: "#/components/schemas/ShipProduction"
route:
type: array
description: Cargo route configuration per planet.
items:
$ref: "#/components/schemas/Route"
otherPlanet:
type: array
description: Partial state of planets owned by other known races.
items:
$ref: "#/components/schemas/OtherPlanet"
uninhabitedPlanet:
type: array
description: Uninhabited planets within sensor range.
items:
$ref: "#/components/schemas/UninhabitedPlanet"
unidentifiedPlanet:
type: array
description: Unidentified planet positions within sensor range.
items:
$ref: "#/components/schemas/UnidentifiedPlanet"
localFleet:
type: array
description: Named fleets belonging to this race.
items:
$ref: "#/components/schemas/LocalFleet"
localGroup:
type: array
description: Ship groups belonging to this race.
items:
$ref: "#/components/schemas/LocalGroup"
otherGroup:
type: array
description: Ship groups belonging to other known races.
items:
$ref: "#/components/schemas/OtherGroup"
unidentifiedGroup:
type: array
description: Unidentified ship group positions within sensor range.
items:
$ref: "#/components/schemas/UnidentifiedGroup"
ReportPlayer:
type: object
description: Diplomatic and aggregate statistics for one player as seen in a report.
required:
- name
- drive
- weapons
- shields
- cargo
- population
- industry
- planets
- relation
- votes
- extinct
properties:
name:
type: string
description: Race name.
drive:
type: number
description: Current drive technology level.
weapons:
type: number
description: Current weapons technology level.
shields:
type: number
description: Current shields technology level.
cargo:
type: number
description: Current cargo technology level.
population:
type: number
description: Total population across all planets.
industry:
type: number
description: Total industrial output.
planets:
type: integer
minimum: 0
description: Number of planets owned.
relation:
type: string
description: Current diplomatic relation toward this race.
votes:
type: number
description: Fraction of alliance votes held.
extinct:
type: boolean
description: True when the race has been eliminated or quit.
Science:
type: object
description: A science project describing technology investment ratios.
required:
- name
- drive
- weapons
- shields
- cargo
properties:
name:
type: string
description: Science project name.
drive:
type: number
description: Investment ratio for drive technology (01).
weapons:
type: number
description: Investment ratio for weapons technology (01).
shields:
type: number
description: Investment ratio for shields technology (01).
cargo:
type: number
description: Investment ratio for cargo technology (01).
OtherScience:
allOf:
- $ref: "#/components/schemas/Science"
- type: object
required:
- race
properties:
race:
type: string
description: Race that owns this science project.
ShipClass:
type: object
description: Design parameters for one ship class.
required:
- name
- drive
- armament
- weapons
- shields
- cargo
- mass
properties:
name:
type: string
description: Ship class name.
drive:
type: number
description: Drive technology level.
armament:
type: integer
minimum: 0
description: Number of weapon mounts (ammo units).
weapons:
type: number
description: Weapons technology multiplier.
shields:
type: number
description: Shields technology multiplier.
cargo:
type: number
description: Cargo technology multiplier.
mass:
type: number
description: Computed ship mass.
OtherShipClass:
allOf:
- $ref: "#/components/schemas/ShipClass"
- type: object
required:
- race
properties:
race:
type: string
description: Race that owns this ship class.
Bombing:
type: object
description: Record of a bombing event that occurred during turn processing.
required:
- planet
- planetName
- owner
- attacker
- production
- industry
- population
- colonists
- capital
- material
- attack
- wiped
properties:
planet:
type: integer
minimum: 0
description: Global planet number.
planetName:
type: string
description: Planet name.
owner:
type: string
description: Race name of the planet owner.
attacker:
type: string
description: Race name of the attacker.
production:
type: string
description: Production type active on the planet at the time of bombing.
industry:
type: number
description: Industrial capacity remaining after the bombing.
population:
type: number
description: Population remaining after the bombing.
colonists:
type: number
description: Colonist units remaining after the bombing.
capital:
type: number
description: Capital reserves remaining after the bombing.
material:
type: number
description: Material reserves remaining after the bombing.
attack:
type: number
description: Aggregate attack power applied during the bombing.
wiped:
type: boolean
description: True when all population was eliminated by the bombing.
BattleSummary:
type: object
description: |
Identifies one battle relevant to the report recipient. Used by
clients to render a battle marker on the map without fetching
the full BattleReport. `planet` locates the marker; `shots`
scales the marker stroke with the battle length.
required:
- id
- planet
- shots
properties:
id:
type: string
format: uuid
description: Battle identifier; fetch the full report via `/api/v1/battle/{turn}/{uuid}`.
planet:
type: integer
minimum: 0
description: Planet number the battle took place on.
shots:
type: integer
minimum: 0
description: Number of shots exchanged during the battle.
BattleReport:
type: object
description: |
Full battle report. `races` and `ships` are JSON objects whose
keys are stringified integers used to cross-reference entries
from `protocol`: a `BattleActionReport` carries integer indices
into both maps. The serialised key is a string because JSON
object keys are always strings.
required:
- id
- planet
- planetName
- races
- ships
- protocol
properties:
id:
type: string
format: uuid
description: Battle identifier.
planet:
type: integer
minimum: 0
description: Planet number the battle took place on.
planetName:
type: string
description: Planet name at battle start.
races:
type: object
description: |
Participating races keyed by the integer index used in
`protocol.a` / `protocol.d`. Values are race identifiers.
additionalProperties:
type: string
format: uuid
ships:
type: object
description: |
Participating ship groups keyed by the integer index used
in `protocol.sa` / `protocol.sd`.
additionalProperties:
$ref: "#/components/schemas/BattleReportGroup"
protocol:
type: array
description: Ordered list of shots exchanged during the battle.
items:
$ref: "#/components/schemas/BattleActionReport"
BattleReportGroup:
type: object
description: One ship group participating in the battle.
required:
- race
- className
- tech
- num
- numLeft
- loadType
- loadQuantity
- inBattle
properties:
race:
type: string
description: Race name of the group owner.
className:
type: string
description: Ship class name; resolvable through `LocalShipClass` or `OtherShipClass`.
tech:
type: object
description: Technology levels keyed by tech type name.
additionalProperties:
type: number
num:
type: integer
minimum: 0
description: Initial number of ships in this group.
numLeft:
type: integer
minimum: 0
description: Number of ships remaining at the end of the battle.
loadType:
type: string
description: Type of cargo loaded.
loadQuantity:
type: number
description: Quantity of cargo loaded.
inBattle:
type: boolean
description: |
True when the group actually fights. False groups observe
the battle in peace state and never fire or take damage.
BattleActionReport:
type: object
description: |
One shot in the battle. Attacker and defender indices reference
`BattleReport.races`; ship-class indices reference
`BattleReport.ships`.
required:
- a
- sa
- d
- sd
- x
properties:
a:
type: integer
description: Index into `BattleReport.races` for the attacker.
sa:
type: integer
description: Index into `BattleReport.ships` for the attacker's group.
d:
type: integer
description: Index into `BattleReport.races` for the defender.
sd:
type: integer
description: Index into `BattleReport.ships` for the defender's group.
x:
type: boolean
description: True when the defender ship was destroyed by this shot.
IncomingGroup:
type: object
description: An identified ship group inbound toward a planet of this race.
required:
- origin
- destination
- distance
- speed
- mass
properties:
origin:
type: integer
minimum: 0
description: Planet number where this group originated.
destination:
type: integer
minimum: 0
description: Planet number this group is heading toward.
distance:
type: number
description: Remaining travel distance.
speed:
type: number
description: Travel speed.
mass:
type: number
description: Total mass of the group.
UnidentifiedPlanet:
type: object
description: Minimal sensor reading for an unidentified planet.
required:
- x
- "y"
- number
properties:
x:
type: number
description: Horizontal map coordinate.
"y":
type: number
description: Vertical map coordinate.
number:
type: integer
minimum: 0
description: Global planet number.
UninhabitedPlanet:
allOf:
- $ref: "#/components/schemas/UnidentifiedPlanet"
- type: object
description: An uninhabited planet within sensor range.
required:
- size
- name
- resources
- capital
- material
properties:
size:
type: number
description: Planet size.
name:
type: string
description: Planet name.
resources:
type: number
description: Natural resource yield (R).
capital:
type: number
description: Capital reserves stored on the planet (CAP).
material:
type: number
description: Material reserves stored on the planet (MAT).
LocalPlanet:
allOf:
- $ref: "#/components/schemas/UninhabitedPlanet"
- type: object
description: Full state for a planet owned by this race.
required:
- industry
- population
- colonists
- production
- freeIndustry
properties:
industry:
type: number
description: Industrial capacity of the planet (I).
population:
type: number
description: Population of the planet (P).
colonists:
type: number
description: Number of colonists on the planet (COL).
production:
type: string
description: Current production assignment.
freeIndustry:
type: number
description: Unused industrial capacity available for new production (L).
OtherPlanet:
allOf:
- $ref: "#/components/schemas/LocalPlanet"
- type: object
description: Partial planet state for a planet owned by another race.
required:
- owner
properties:
owner:
type: string
description: Race name of the planet owner.
Route:
type: object
description: Cargo route configuration originating from one planet.
required:
- planet
- route
properties:
planet:
type: integer
minimum: 0
description: Source planet number.
route:
type: object
description: |
Mapping from destination planet number (as a string key) to the
cargo load type being routed (MAT, CAP, COL, EMP).
additionalProperties:
type: string
ShipProduction:
type: object
description: Active ship construction progress on one planet.
required:
- planet
- class
- cost
- prodUsed
- percent
- free
properties:
planet:
type: integer
minimum: 0
description: Planet number where construction is taking place.
class:
type: string
description: Name of the ship class being built.
cost:
type: number
description: Total production cost for one unit of this class.
prodUsed:
type: number
description: Production units already spent on this build.
percent:
type: number
description: Completion percentage of the current build.
free:
type: number
description: Remaining free industrial capacity on this planet.
LocalFleet:
type: object
description: A named fleet belonging to this race.
required:
- name
- groups
- destination
- speed
- state
properties:
name:
type: string
description: Fleet name.
groups:
type: integer
minimum: 0
description: Number of ship groups in this fleet.
destination:
type: integer
minimum: 0
description: Destination planet number.
origin:
type: integer
minimum: 0
description: Origin planet number when the fleet is in transit.
range:
type: number
description: Remaining travel range when the fleet is in transit.
speed:
type: number
description: Travel speed.
state:
type: string
description: Fleet operational state.
OtherGroup:
type: object
description: A ship group visible to this race belonging to another race.
required:
- number
- class
- tech
- cargo
- load
- destination
- speed
- mass
properties:
number:
type: integer
minimum: 0
description: Group identifier number.
class:
type: string
description: Ship class name.
tech:
type: object
description: Technology levels of this group keyed by tech type name.
additionalProperties:
type: number
cargo:
type: string
description: Type of cargo carried by this group.
load:
type: number
description: Current cargo load quantity.
destination:
type: integer
minimum: 0
description: Destination planet number.
origin:
type: integer
minimum: 0
description: Origin planet number when the group is in transit.
range:
type: number
description: Remaining travel range when the group is in transit.
speed:
type: number
description: Travel speed.
mass:
type: number
description: Total mass of the group.
LocalGroup:
allOf:
- $ref: "#/components/schemas/OtherGroup"
- type: object
description: A ship group belonging to this race with full ownership detail.
required:
- id
- state
properties:
id:
type: string
format: uuid
description: Unique group identifier.
state:
type: string
description: Group operational state.
fleet:
type: string
nullable: true
description: Name of the fleet this group belongs to, or null if ungrouped.
UnidentifiedGroup:
type: object
description: Positional reading for an unidentified ship group.
required:
- x
- "y"
properties:
x:
type: number
description: Horizontal map coordinate.
"y":
type: number
description: Vertical map coordinate.
ValidationErrorResponse:
type: object
description: Validation error returned for malformed requests.
required:
- error
properties:
error:
type: string
description: Human-readable validation error message from the binding layer.
InternalErrorResponse:
type: object
description: |
Internal server error. The shape depends on the error source:
- `{"error": "message"}` for generic runtime errors
- `{"generic_error": "message", "code": integer}` for game-engine errors
properties:
error:
type: string
description: Generic runtime error message.
generic_error:
type: string
description: Game-engine error message.
code:
type: integer
description: Game-engine error code.
responses:
ValidationError:
description: Request body or query parameters are invalid.
content:
application/json:
schema:
$ref: "#/components/schemas/ValidationErrorResponse"
examples:
validationError:
value:
error: "Key: 'InitRequest.Races' Error:Field validation for 'Races' failed on the 'gte' tag"
InternalError:
description: Internal Game Service error.
content:
application/json:
schema:
$ref: "#/components/schemas/InternalErrorResponse"