Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/TaylorZaneKirk/MMO-Project/llms.txt

Use this file to discover all available pages before exploring further.

After a character is authenticated, EnterWorldService reads the character’s last saved map position and makes it the authoritative live presence. A world_snapshot message then hydrates the full game state for the client — tiles, skills, inventory, equipment, NPCs, remote players, and visible ground items — before any gameplay messages flow. The snapshot is the client’s single source of truth at session start and after any resync request.

Enter world

EnterWorldService.EnterWorldAsync orchestrates the transition from authenticated identity to live map presence.
1

Load character world entry

Reads map_id, tile_x, and tile_y from the characters table for the given character_id.
2

Normalize position

WorldPositionNormalizationService.NormalizeCharacterWorldEntryAsync checks that the saved coordinates fall within a valid chunk. Out-of-range coordinates are snapped to the nearest valid tile.
3

Ensure map loaded

Calls WorldPositionNormalizationService.EnsureMapAsync to confirm the resolved map_id has chunk data loaded in WorldChunkCatalog.
4

Upsert map presence

Calls MapPresenceRepository.UpsertPresenceAsync with the normalized map_id, tile_x, and tile_y. This row drives reconnect, movement validation, and snapshot assembly from this point forward.
5

Return enter_world_response

Returns EnterWorldResult with map_id, tile_x, tile_y, facing: south, and presence_source: character_save.
public sealed record EnterWorldResult(
    Guid SessionId,
    string CharacterId,
    string MapId,
    int TileX,
    int TileY,
    string Facing,
    string PresenceSource);

World snapshot

WorldSnapshotService.BuildSnapshotAsync assembles the complete world_snapshot payload by querying every relevant repository before constructing the result. The snapshot carries both a character_revision and a map_revision so delta clients can detect any gap since the previous message. The snapshot is organized around six data regions:
RegionContents
Local playerTile position, facing, status bars (health, concentration, special — current and max), full skill list with base/equipment/temporary/effective values, 28-slot inventory with skill_requirements, skill_modifiers, and context_actions per item, full equipment slots
NPCsnpc_id, display_name, texture_path, tile_x, tile_y, facing, current_state for every NPC on the same map
Remote playerscharacter_id, character_name, tile position, facing, and equipment snapshot for every other character present on the map
Ground itemsAll ground_items on the map that are currently visible to this character (ground_item_id, owner_character_id, position, item_name, icon_texture_path, stack_count)
Private ground itemsItems dropped by this character that are still within the private visibility window — visible only to the owner
Revisionscharacter_revision and map_revision for delta stream tracking
public sealed record WorldSnapshotResult(
    Guid SessionId,
    string CharacterId,
    string MapId,
    long CharacterRevision,
    long MapRevision,
    int TileX,
    int TileY,
    string Facing,
    WorldSnapshotPlayerStatusResult Status,
    WorldSnapshotPlayerSkillsResult Skills,
    WorldSnapshotPlayerInventoryResult Inventory,
    WorldSnapshotPlayerEquipmentResult Equipment,
    IReadOnlyList<WorldSnapshotGroundItemResult> PrivateGroundItems,
    IReadOnlyList<WorldSnapshotNpcResult> Npcs,
    IReadOnlyList<WorldSnapshotGroundItemResult> GroundItems,
    IReadOnlyList<WorldSnapshotPlayerResult> Players);
Inventory items include server-owned context_actions (e.g. equip, eat, use, drop) so the client can build right-click menus without duplicating item rules locally. These are menu affordances — not permission to apply mutations client-side.

WorldChunkCatalog

The prototype world is a flat, contiguous grid of chunks. WorldChunkCatalog loads and indexes all chunk definitions from prototype/shared/maps/ at startup.
PropertyValue
Grid dimensions20 × 20 chunks
Chunk tile size17 × 9 tiles per chunk
Total world tiles340 × 180 world-space tiles
Named origin chunkx1000y992 at chunk position (10, 10)
Default chunk templategrass_17x9_v1
Named chunks have explicit map_id values and dedicated JSON files under chunks/. Unnamed chunks receive a generated map_id in the format chunk_{x}_{y} and render using the default grass template. WorldChunkCatalog exposes three coordinate conversion methods used by every movement and snapshot path:
  • ToWorldTile(mapId, localTileX, localTileY) — converts a chunk-local coordinate to an absolute world-tile position.
  • ResolveWorldTile(worldTileX, worldTileY) — converts an absolute world-tile coordinate back to a (mapId, localTileX, localTileY) triple, including the resolved chunkX/chunkY.
  • ClampWorldTile(worldTileX, worldTileY) — clamps a world coordinate to the valid grid boundary before pathfinding.

Zone simulation

ZoneSimulationService.TickAsync is called every 600 ms by ZoneSimulationWorker. Each tick performs two phases:
  1. Character movement — calls MovementService.AdvanceActiveMovementsAsync to dequeue one step for every character with an active path. Each resolved step is persisted and broadcast as movement_applied to the moving character. Other characters on the same map receive a player_state_update with the mover’s new tile and walking/idle animation state.
  2. NPC advancement — calls NpcRuntimeService.AdvanceNpcStates(600) to tick every NPC’s state machine. NPCs with changed state are grouped by map. For each affected map, a new map_revision is allocated and a single npc_state_update message is broadcast to all connected clients on that map.
// npc_state_update message shape
{
  "name": "npc_state_update",
  "payload": {
    "map_id": "x1000y992",
    "map_revision": 142,
    "npcs": [
      {
        "npc_id": "orc_01",
        "display_name": "Orc",
        "texture_path": "res://sprites/orc.png",
        "tile_x": 8,
        "tile_y": 4,
        "facing": "south",
        "current_state": "patrol"
      }
    ]
  }
}

Position normalization

WorldPositionNormalizationService snaps out-of-range chunk-local coordinates to the nearest valid tile and persists or updates the corrected position when a change is detected. It is called consistently across all three position-critical paths:
  • Enter world — normalizes the saved characters position before inserting map_presence.
  • World snapshot — re-normalizes map_presence before assembling the snapshot (updatePresence: true), keeping presence and snapshot coordinates in sync.
  • Movement — normalizes current presence before computing the A* path origin and after resolving each step.

Map revisions

world_snapshot carries both character_revision and map_revision. Delta-protocol clients track these values; if a subsequent message arrives with a revision that is non-contiguous, the client sends world_resync_request. The server responds with a fresh world_snapshot, which is the only recovery path for stale delta streams in the current prototype phase.
The 3×3 chunk area around the active player is rendered in the Godot client. The server serves all chunk data from shared JSON fixtures during the prototype phase.

Build docs developers (and LLMs) love