Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 39 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ numbers: records have ids, flags have names, and what stands in a room is
written on the room. This needs PyYAML (`pip install area-reader[authoring]`).

```
area-reader build SRC [-o OUT.are] [--set DIR ...] [--show-defaults]
area-reader build SRC [-o OUT] [--format rom|json] [--set DIR ...] [--show-defaults]
area-reader unbuild AREA.are -o SRC
```

Expand Down Expand Up @@ -237,6 +237,44 @@ objects:
such as `rooms.gatehouse.exits.east.key`. `build` parses its own output with
the ROM reader and writes nothing unless the result equals what it compiled.

### Beyond ROM: `--format json`

`build --format json` writes the area as JSON in place of the `.are` file: the
same JSON `area-reader AREA.are` prints for the built area, so a program that
reads one reads the other. The JSON can also carry what a ROM area file has no
place for, for a world that is not a ROM server:

```yaml
area:
name: The Castle
vnums: {first: 12000, size: 100}
properties: {gravity: 0.9}

rooms:
landing:
name: The Upper Landing
kind: echoing # what the room is, to the world that loads it
with: {decay: 3} # the kind's parameters
properties: {ceiling: 12} # set on the room as written
exits:
north: {to: corridor, kind: guarded, with: {phrase: open sesame}}
hatch: {to: loft, keyword: hatch, kind: guarded}
```

- **`kind`, `with`, `properties`** may be written on the header, a room, a mob,
an object and an exit. `kind` is a slug; `with` needs a `kind`. They appear
under the same names on the record in the JSON. `build` does not know which
kinds a world has: any slug is accepted.
- **Named exits.** An exit whose name is not one of the six directions is any
slug. It has one side and takes `to`, `keyword`, `description` and the three
keys above, with no door or key: what stands in its way is its kind's
business. In the JSON it is one more entry of the room's `exits`, with the
name as its `door`.
- The ROM part of the area is still rendered, parsed back and compared before
anything is written. `--format rom` refuses a source that uses any of this,
naming the first place it does. `lint`, `walk` and `unbuild` read area
files, not this JSON.

`unbuild` writes any ROM area the reader parses in this form: ids slugged from
names, every vnum pinned, two-way exits collapsed, resets hung on their rooms.
For the 48 stock areas with rooms, building the unbuilt directory gives back
Expand Down
56 changes: 56 additions & 0 deletions agent-notes/feat-mongoose-json.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# feat/mongoose-json: a JSON output from `build` that carries what ROM cannot hold

## Goal

Q, 2026-10-12: the area source format gets extended beyond ROM ("we can always enhance the format we own
everything"), and the infrastructure must not be specific to one setting. This branch is the first piece: `build`
can write the reader's own JSON directly, so a source directory can say things a ROM `.are` file has no place for,
and a world that loads the JSON (Mongoose's `$area_reader` / `$mud_world`) receives them.

## State (2026-10-12)

Branch from `origin/master` `5e64b9c`, worktree `C:\Users\Q\code\area_reader-mongoose-json`.

Written in `area_reader/authoring/builder.py`:

- Source keys `kind` (a slug), `with` (a mapping; needs `kind`) and `properties` (a mapping with text keys) on
the area header, rooms, mobs, objects and exits written as mappings.
- An exit whose name is not one of the six compass words is a named exit: any slug, one side only, keys `to`,
`keyword`, `description` and the three extension keys.
- `build(..., output_format="json")` / `area-reader build --format json`: renders the ROM part, parses it back
and checks it as before, then writes `RomAreaFile.as_dict()` of the parsed area with the extension keys laid
over each record and the named exits appended to their rooms' `exits` (with `door` set to the name). Default
output name is the header's filename with `.json`.
- `--format rom` (the default) raises a `SourceError` at the first extension key or named exit.

## Decisions and why

- The JSON is the reader's JSON, not a new schema: the Mongoose loader already consumes `as_dict()` output, so a
plain source built to JSON is exactly what the server's wrapper prints for the same area's `.are`.
- The pass-through block is called `properties`, not after any one game: area_reader is a general tool.
- No version field in the JSON.
- Named exits take no door, key or reverse side: ROM's door resets address exits by direction number, and what
stands in the way of a named exit is the kind's business.
- `rom` refuses rather than drops: silently losing a kind would build an area that looks right and is not.

## Not done

- `lint`, `walk` and `atlas` read `.are` files only; they do not see the JSON or check kind names.
- No registry of kinds: any slug is accepted.
- `unbuild` does not read the JSON back.
- Text in a source file must still be Latin-1 without `~` everywhere, including inside `properties`.
- A typo in a compass name (`nroth`) is now a named exit, caught only by `--format rom`.

## Checked (2026-10-12)

- Whole suite: 1722 passed (11 new tests in `test_authoring.py`); `ruff check .` clean. `ruff format --check`
flags only code blocks in `PROJECT.md`, which this branch does not touch.
- A copy of `mongoose-areas/areas/saltworks` (30 rooms, 11 mobs, 18 objects) built with `--format json` equals,
as parsed JSON, what `area-reader saltworks.are` prints for the same source built to ROM.
- Not checked: any load of this JSON by a MOO. The Mongoose server wrapper and `$area_reader:load` take `.are`
files only today.

## Next step

In Mongoose, outside this repo: the server wrapper accepts a `.json` file; the loader reads `kind` to choose a
class and applies `properties`.
Loading
Loading