← World map and portals · all tasks
Spec the world graph — areas, portals, per-area rules, and the public/private split
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
- 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.
- What an area is as a designed object — beyond “a
worldsrow”. Name, description, who owns it, whether it’s public or private, and its rule set. - 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.
- 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. - 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_membersis already the whitelist mechanism. Settle what a player can see of a realm they can’t enter. - 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.
- 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. - 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
- The output belongs in
land-of-lor/docs/as agent-authored design material. If Kris wants it in the workspace instead, it moves — the location isn’t load-bearing. - Spec-only, no code, matching how
world-traversal-and-ground/001was scoped.
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:
- The name is Area. Not “room”, not “realm” — used consistently in the DB model, the
loader, both map surfaces and the editor. The
worldstable 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.tsis where the new vocabulary lives. - 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. - Per-area rules are first-class — a row per rule in
area_ruleswith a JSONparamscolumn, never a text blob, so giving a rule parameters later isn’t a migration of meaning. - 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. - 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. - A server is a
serversrow; there is one, Spellgrove, and the picker reads it from data rather than hardcoding it. - 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 bynpm run load-world. Both map surfaces then read the database through one public endpoint. - 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.