← World map and portals · all tasks

Spec the world graph — areas, portals, per-area rules, and the public/private split

done priority 1 estimate L

world-map-and-portals/001 · created 2026-08-12 · updated 2026-08-18

What

Write the specification for the world at the scale of areas — the layer above ground and below “the game”. Output is a design document in land-of-lor/docs/ (agent-authored, so it goes in the shared part of the tree, not the human-owned docs/thought-specs/), not code. Kris’s intent is that this spec then feeds a full implementation plan.

Read epics/world-map-and-portals/overview.md first — it carries the source material from Kris’s 2026-08-12 voice brief and, importantly, the list of primitives that already exist in land-of-lor/game/director/ so this doesn’t get re-invented.

What the spec must settle

  1. The name. Kris is calling them rooms provisionally and explicitly asked what they should be called. Areas? Realms? Rooms? Pick one, argue it, use it consistently everywhere afterwards.
  2. What an area is as a designed object — beyond “a worlds row”. Name, description, who owns it, whether it’s public or private, and its rule set.
  3. Per-area rules as a first-class concept. Kris’s example: a battle arena won’t let you bring your whole inventory in. Define what dimensions a rule set can constrain (inventory, resources, PvP, building, persistence) and how an area declares them. This is the concept that later makes offline play a rule set rather than a fork.
  4. Portals as authored objects. They exist in the protocol today (PortalConfigSchema, SetWorldPortalsRequest, portal_transfer_*) as test-scoped configuration applied at next spawn. Specify how a portal becomes a designed, named, durable part of the world instead — including whether portals are one-way or paired, and what a player sees and does at one.
  5. The public/private split. The public commons and its onward areas (village of Lor → beginner battle arena → the Badlands, per Kris’s sketch) versus each player’s home area and portals to friends’ realms. world_members is already the whitelist mechanism. Settle what a player can see of a realm they can’t enter.
  6. Servers. There will be more than one. Define what a server is to a player, what is and isn’t shared across servers (accounts? collections? friends?), and therefore what the site’s server dropdown is actually selecting.
  7. Authored vs. derived. State plainly whether the canonical map is hand-authored content or a live projection of worlds + portal rows. Both surfaces in task 002 depend on this answer, so it cannot be left open.
  8. Offline play — as a constraint, not a feature. Do not design offline play here. Do state, for each decision above, whether it forecloses offline play, and reject any design that does. Kris’s position, verbatim in spirit: probably not possible in the current build, wanted in the final version, and announced now precisely so nothing is built that rules it out.

Definition of done

A document that answers 1–8 with decisions (not option lists), each with a short reason, and that an implementation plan can be written directly from. Where a decision genuinely belongs to Kris, state a recommendation and mark it — don’t leave a bare question.

Input Kris still owes

The paper sketch of the Lor map. Kris drew it on 2026-08-12; it is not in the repo. The initial public topology should come from that sketch, not from invention. If it still isn’t available when this task is picked up, spec everything else and leave the concrete topology as a clearly-marked placeholder rather than guessing at Kris’s world.

Assumptions


Answered, 2026-08-15

The spec exists, in two pieces Kris authored and commissioned rather than an agent inventing: land-of-lor/docs/specs/CORE_ENTITIES.md (Kris, 2026-08-15) and the three Claude Design handoffs in land-of-lor/docs/design/ClaudeDesignWorldMapBrief/. Between them the eight questions are settled, and the implementation has landed against them (tasks 003–007). The decisions, for the record:

  1. The name is Area. Not “room”, not “realm” — used consistently in the DB model, the loader, both map surfaces and the editor. The worlds table keeps its name because “worldId” is the wire protocol, the GDScript and every CLI harness; a table-only rename would split the vocabulary in two. land-of-lor/game/director/src/areas.ts is where the new vocabulary lives.
  2. An Area as a designed object: slug, name, type (shared / home / battle_arena, from a lookup table so a new type is one insert), access (public / restricted / private), owner, grid size, map position, and an optional parent for a nested room.
  3. Per-area rules are first-class — a row per rule in area_rules with a JSON params column, never a text blob, so giving a rule parameters later isn’t a migration of meaning.
  4. Portals are authored objects in their own table. One row is one portal even when it goes both ways; the return leg occupies the destination cell. One-way is a flag, not a second row. to_special = 'home_area' resolves per player at travel time.
  5. Public/private: public areas auto-member whoever walks in (this was the change that made authored travel possible at all); private and restricted still gate on world_members. A realm you can’t enter is fogged, not hidden — the map returns its position and nothing else, because hiding a ball its neighbour can see makes the graph lie.
  6. A server is a servers row; there is one, Spellgrove, and the picker reads it from data rather than hardcoding it.
  7. Authored, not derived. The canonical world is land-of-lor/game/content/spellgrove.world.json, edited by the local editor, reviewed in git, applied to a database by npm run load-world. Both map surfaces then read the database through one public endpoint.
  8. Offline is not foreclosed. Nothing above requires the network to describe the world: the authored world is a file, area rules are data, and the map surfaces are readers. What is not offline-ready remains what always was — the live shared areas.

Dropped: Portal.distance and Portal.direction. They existed only to hint map layout, and the editor now authors positions directly (Area.map_x / map_y). The one survivor of that family is nesting (parent_area_id), because “the Market Stalls are a room off the Village” says something true about the world rather than about drawing.

No longer blocked on the paper sketch. Kris’s 2026-08-12 sketch was never photographed into the repo; the design’s nine-area world supersedes it as the starting topology.

View source in repository · also available as raw markdown.