Remove stray runtime API draft from deploy
This commit is contained in:
parent
d899e902a0
commit
ca054581a4
1 changed files with 0 additions and 312 deletions
|
|
@ -1,312 +0,0 @@
|
|||
# Worldshaper Runtime API Proposal
|
||||
|
||||
## Goal
|
||||
|
||||
Provide a stable HTTP API that a game engine can call to load Worldshaper-authored data without depending directly on editor-only JSON structure.
|
||||
|
||||
This is different from the current editor API.
|
||||
|
||||
The editor API is optimized for:
|
||||
|
||||
- editing
|
||||
- saving
|
||||
- validation
|
||||
- editor UI state
|
||||
- internal content storage
|
||||
|
||||
The runtime API should be optimized for:
|
||||
|
||||
- loading the world into a game engine
|
||||
- streaming chunks as the player moves
|
||||
- fetching only the catalog data the engine actually needs
|
||||
- staying stable even if the editor changes internally
|
||||
|
||||
## Current State
|
||||
|
||||
Worldshaper already exposes useful HTTP routes in [server.js](/D:/Programming/Worldshaper/server.js:2004), including:
|
||||
|
||||
- `GET /api/world-default`
|
||||
- `GET /api/world/:worldId`
|
||||
- `GET /api/world/:worldId/chunks`
|
||||
- `GET /api/content/tiles`
|
||||
- `GET /api/content/sprites`
|
||||
- `GET /api/content/dialogues`
|
||||
- `GET /api/content/npc_templates`
|
||||
- `GET /api/images/:filename`
|
||||
|
||||
That means the project already has the foundations for a runtime API.
|
||||
|
||||
## Why Not Use The Editor API Directly
|
||||
|
||||
Some current payloads include editor concerns that a game engine should not be forced to understand.
|
||||
|
||||
Examples:
|
||||
|
||||
- world definitions contain `editorUi`
|
||||
- images are stored in editor-authored form in `images.json`
|
||||
- some content files may not always exist locally
|
||||
- route naming and response shape are editor-first, not engine-first
|
||||
|
||||
Using those routes directly would tightly couple the engine to the editor's internal storage format.
|
||||
|
||||
## Recommendation
|
||||
|
||||
Add a separate runtime-facing API namespace:
|
||||
|
||||
- `GET /api/runtime/worlds`
|
||||
- `GET /api/runtime/worlds/:worldId`
|
||||
- `GET /api/runtime/worlds/:worldId/chunks`
|
||||
- `GET /api/runtime/catalog/tiles`
|
||||
- `GET /api/runtime/catalog/sprites`
|
||||
- `GET /api/runtime/catalog/npc-templates`
|
||||
- `GET /api/runtime/catalog/dialogues`
|
||||
- `GET /api/runtime/bundle/:worldId`
|
||||
|
||||
This lets Worldshaper keep evolving internally while the engine targets a cleaner contract.
|
||||
|
||||
## Recommended V1
|
||||
|
||||
V1 should be small and practical.
|
||||
|
||||
### Startup Flow
|
||||
|
||||
The engine should be able to:
|
||||
|
||||
1. fetch the default or selected world
|
||||
2. fetch shared runtime catalogs once
|
||||
3. fetch chunks on demand as the player moves
|
||||
|
||||
### Best First Endpoints
|
||||
|
||||
#### `GET /api/runtime/worlds`
|
||||
|
||||
Returns a lightweight world list.
|
||||
|
||||
Example:
|
||||
|
||||
```json
|
||||
{
|
||||
"worlds": [
|
||||
{
|
||||
"id": "overworld",
|
||||
"name": "Overworld Mock"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### `GET /api/runtime/worlds/:worldId`
|
||||
|
||||
Returns runtime-safe world metadata only.
|
||||
|
||||
Example:
|
||||
|
||||
```json
|
||||
{
|
||||
"world": {
|
||||
"id": "overworld",
|
||||
"name": "Overworld Mock",
|
||||
"chunkWidth": 32,
|
||||
"chunkHeight": 32,
|
||||
"tileSize": 32,
|
||||
"backgroundColor": "#060A14",
|
||||
"defaultBackgroundTileId": "tile_5b6206b849",
|
||||
"spawn": { "x": 80, "y": 80 }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Do not include:
|
||||
|
||||
- `editorUi`
|
||||
- editor layout metadata
|
||||
- editor-only presentation settings unless the engine truly uses them
|
||||
|
||||
#### `GET /api/runtime/worlds/:worldId/chunks?chunkX=0&chunkY=0&radius=1`
|
||||
|
||||
Returns chunk payloads around a center point.
|
||||
|
||||
Example:
|
||||
|
||||
```json
|
||||
{
|
||||
"worldId": "overworld",
|
||||
"center": { "chunkX": 0, "chunkY": 0 },
|
||||
"radius": 1,
|
||||
"chunks": [
|
||||
{
|
||||
"chunkX": 0,
|
||||
"chunkY": 0,
|
||||
"width": 32,
|
||||
"height": 32,
|
||||
"backgroundTileId": "tile_5b6206b849",
|
||||
"roomLayers": [
|
||||
{ "layer": 0, "rows": ["................................"] },
|
||||
{ "layer": 1, "rows": [" "] }
|
||||
],
|
||||
"heightLayers": [],
|
||||
"instances": []
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
This is the most important runtime route.
|
||||
|
||||
#### `GET /api/runtime/catalog/tiles`
|
||||
|
||||
Returns tile definitions needed for world rendering.
|
||||
|
||||
Example:
|
||||
|
||||
```json
|
||||
{
|
||||
"tiles": [
|
||||
{
|
||||
"id": "tile_5b6206b849",
|
||||
"symbol": ".",
|
||||
"name": "Grass",
|
||||
"width": 16,
|
||||
"height": 16,
|
||||
"pixelScale": 2,
|
||||
"rows": ["................"]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### `GET /api/runtime/catalog/sprites`
|
||||
|
||||
Returns sprite definitions needed for entity rendering.
|
||||
|
||||
Example:
|
||||
|
||||
```json
|
||||
{
|
||||
"sprites": [
|
||||
{
|
||||
"id": "npc_human_style_01",
|
||||
"name": "Human Style 01 - Wide Hat Coat",
|
||||
"width": 16,
|
||||
"height": 16,
|
||||
"pixelScale": 2,
|
||||
"rows": ["................"]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### `GET /api/runtime/catalog/npc-templates`
|
||||
|
||||
Returns entity templates the engine can use to resolve placed instances.
|
||||
|
||||
Example:
|
||||
|
||||
```json
|
||||
{
|
||||
"npcTemplates": [
|
||||
{
|
||||
"id": "npc_gatekeeper_bubbles",
|
||||
"name": "Bubbles",
|
||||
"faction": "dangerous_gatekeeper",
|
||||
"spriteId": "npc_human_style_13",
|
||||
"defaultDialogueId": "dlg_npc_gatekeeper_bubbles"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### `GET /api/runtime/catalog/dialogues`
|
||||
|
||||
Returns runtime dialogue definitions.
|
||||
|
||||
This may be enough for V1 if the engine can interpret the current dialogue node structure.
|
||||
|
||||
If not, Worldshaper should add a runtime dialogue normalization step later.
|
||||
|
||||
#### `GET /api/runtime/bundle/:worldId`
|
||||
|
||||
Optional convenience endpoint.
|
||||
|
||||
Returns:
|
||||
|
||||
- runtime world metadata
|
||||
- tiles
|
||||
- sprites
|
||||
- npc templates
|
||||
- factions
|
||||
- dialogues
|
||||
|
||||
This is useful for prototypes and early engine work.
|
||||
|
||||
It may be too large for long-term world streaming, but it is a very good first integration endpoint.
|
||||
|
||||
## Suggested Runtime Data Rules
|
||||
|
||||
The runtime API should follow these rules:
|
||||
|
||||
- never expose editor layout/state unless the engine truly needs it
|
||||
- prefer explicit IDs over editor-specific structures
|
||||
- keep references stable: `tileId`, `spriteId`, `dialogueId`, `templateId`
|
||||
- return only what the engine needs to simulate and render
|
||||
- keep route names descriptive and runtime-oriented
|
||||
|
||||
## What The Engine Likely Needs
|
||||
|
||||
Minimum likely needs:
|
||||
|
||||
- world metadata
|
||||
- chunk geometry and layer rows
|
||||
- tile catalog
|
||||
- sprite catalog
|
||||
- instance template catalog
|
||||
- placed instances per chunk
|
||||
- dialogue definitions
|
||||
- factions or other lookup catalogs used by templates
|
||||
|
||||
Maybe later:
|
||||
|
||||
- items
|
||||
- abilities
|
||||
- monsters
|
||||
- loot tables
|
||||
- triggers
|
||||
- transitions
|
||||
- quest hooks
|
||||
|
||||
## Open Questions For The Engine Developer
|
||||
|
||||
These should be answered before implementation:
|
||||
|
||||
1. Does the engine want raw JSON data from Worldshaper, or a normalized runtime contract?
|
||||
2. Should the engine load the full world at startup, or stream chunks around the player?
|
||||
3. Does the engine want graphics as row-based pixel data, or should Worldshaper also expose rendered asset URLs or atlas data?
|
||||
4. Will the engine consume dialogues in the current node format, or does it need a simpler compiled dialogue format?
|
||||
5. Does the engine need polling or version info so it can hot-reload changed data?
|
||||
|
||||
## Recommended Answer
|
||||
|
||||
Unless the engine developer strongly objects, the best answer is:
|
||||
|
||||
- normalized runtime contract
|
||||
- chunk streaming
|
||||
- row-based tile/sprite data first
|
||||
- existing dialogue format first
|
||||
- optional bundle endpoint for fast early integration
|
||||
|
||||
## Practical Next Step
|
||||
|
||||
Before implementation, send your friend this exact question:
|
||||
|
||||
> I can expose Worldshaper as a runtime API. Do you want a clean engine-facing contract with world metadata, chunk streaming, tiles, sprites, NPC templates, and dialogues, or do you want direct access to the raw editor JSON?
|
||||
|
||||
If he says "clean engine-facing contract", V1 should target:
|
||||
|
||||
- `GET /api/runtime/worlds/:worldId`
|
||||
- `GET /api/runtime/worlds/:worldId/chunks`
|
||||
- `GET /api/runtime/catalog/tiles`
|
||||
- `GET /api/runtime/catalog/sprites`
|
||||
- `GET /api/runtime/catalog/npc-templates`
|
||||
- `GET /api/runtime/catalog/dialogues`
|
||||
- optional `GET /api/runtime/bundle/:worldId`
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue