feat: v0.7.0 — server-authoritative sim engine: tick-on-read clock (time-scale + pause via POST /api/sim), contract expiry + market spawn, analytic plane movement/finalization
This commit is contained in:
+57
-2
@@ -37,7 +37,7 @@ export const openApiSpec = {
|
||||
get: {
|
||||
summary: 'Game state snapshot',
|
||||
description:
|
||||
'Full current game state for client polling — account, sim clock, planes and contracts. Read-only.',
|
||||
'Full current game state for client polling — account, sim clock, planes and contracts. Tick-on-read: each call first advances the sim clock by (real time since last read) × timeScale (clamped per tick), so expiry/finalization/spawn are always applied before the snapshot is returned.',
|
||||
operationId: 'getState',
|
||||
responses: {
|
||||
200: {
|
||||
@@ -51,6 +51,40 @@ export const openApiSpec = {
|
||||
},
|
||||
},
|
||||
},
|
||||
'/api/sim': {
|
||||
post: {
|
||||
summary: 'Set sim time controls',
|
||||
description:
|
||||
'Advance the sim clock (tick-on-read) and set the time scale / pause state. The clock is advanced first, so the returned simState already reflects current game time; contract expiry, arrival finalization and market spawn run inside that tick.',
|
||||
operationId: 'setSimControls',
|
||||
requestBody: {
|
||||
required: false,
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: { $ref: '#/components/schemas/SimControlsRequest' },
|
||||
},
|
||||
},
|
||||
},
|
||||
responses: {
|
||||
200: {
|
||||
description: 'Updated sim state',
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: { $ref: '#/components/schemas/SimState' },
|
||||
},
|
||||
},
|
||||
},
|
||||
400: {
|
||||
description: 'Invalid body (not an object, unknown field, or wrong types)',
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: { $ref: '#/components/schemas/Error' },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'/api/version': {
|
||||
get: {
|
||||
summary: 'App version',
|
||||
@@ -155,6 +189,26 @@ export const openApiSpec = {
|
||||
},
|
||||
required: ['clockMs', 'timeScale', 'paused'],
|
||||
},
|
||||
SimControlsRequest: {
|
||||
type: 'object',
|
||||
description: 'Partial update — omit a field to leave it unchanged.',
|
||||
properties: {
|
||||
timeScale: {
|
||||
type: 'number',
|
||||
minimum: 1,
|
||||
maximum: 60,
|
||||
description: 'Game-time multiplier; values outside [1, 60] are clamped.',
|
||||
},
|
||||
paused: { type: 'boolean' },
|
||||
},
|
||||
},
|
||||
Error: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
error: { type: 'string' },
|
||||
},
|
||||
required: ['error'],
|
||||
},
|
||||
PlaneState: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
@@ -194,7 +248,8 @@ export const openApiSpec = {
|
||||
cargoType: { type: 'string' },
|
||||
cargoCount: { type: 'integer' },
|
||||
deadlineSimTime: { type: 'integer', description: 'Sim-clock epoch ms (game time)' },
|
||||
status: { enum: ['open', 'accepted', 'completed'] },
|
||||
// 'expired' = an open contract whose deadline passed; accepted/in-flight contracts never expire.
|
||||
status: { enum: ['open', 'accepted', 'completed', 'expired'] },
|
||||
planeId: { type: ['string', 'null'] },
|
||||
createdSimTime: { type: 'integer' },
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user