Skip to content

Docstrings: crawl authoring - #97

Merged
mmacy merged 2 commits into
mainfrom
docs/api-ref-crawl-authoring
Sep 14, 2026
Merged

mmacy merged 2 commits into
mainfrom
docs/api-ref-crawl-authoring

Conversation

@mmacy

@mmacy mmacy commented Sep 14, 2026

Copy link
Copy Markdown
Owner

A reader who has never opened the source can now assemble an adventure from the reference alone. The crawl subpackage front page says what the framework is and lists its modules in the order you meet them, with what goes into each and what comes out. The party, the adventure and its town, the dungeon geometry and its state overlay, content packs, and stocking all say what each member is for, what you need before you call it, what to call next, and where its limits are. Every pydantic field has its own prose, so the field rows are no longer bare names. Adventure, DungeonSpec, and LevelSpec carry runnable examples built on the package quickstart's two-cell corridor, and validate_adventure shows the error you get from an unknown monster id. Where a guide already covers the long form, the docstring links it by URL instead of repeating it.

I corrected four docstrings because the code says something else.

Party.ranks (party.py:71 before this change) said the width is 3 in a keyed area and 2 in a corridor. Battle measures the party's frontage and divides by FIGHTER_FRONTAGE_FEET, so the docstring now says the width comes from the space the party is standing in.

DropPile (dungeon.py:704 before) said coins thrown down to distract a pursuer land in the pile. _apply_drop scatters pursuit bait with to_pile=False and Evade empties each purse outright, so nothing reaches a pile. The docstring now names the three things that do land there and says the bait is gone.

KeyedMonster.count_dice had no stream named and I first wrote the encounter stream. A keyed encounter's count rolls on WANDERING_STREAM in _spawn_keyed_encounter, and the result is held at 1 or more, so the field says that.

DungeonSpec.levels had no order statement and I first wrote that the order does not matter. EnterDungeon lands the party on the first level in the tuple that has an entrance, so the field says the order decides that.

One thing worth knowing about rendering: osrlib/crawl/__init__.py gets no page on the site, because tools/docs/gen_api_reference.py only emits pages for modules with a non-empty __all__. The subpackage front page is written and correct, and it reaches anyone reading help(osrlib.crawl) or an IDE tooltip, but it is not on the published reference today.

DungeonState.discovered_features is documented as unwritten, because nothing in the package reads or writes it. Secret doors record discovery on DoorState.discovered, and found features go to found_traps and found_tricks. I left the field alone; removing it is a schema decision.

Every example runs under the docs harness, so none are no-run. The gate passes: ruff format --check, ruff check, pyright with 0 errors, 2283 tests passed and 73 skipped, and mkdocs build --strict.

https://claude.ai/code/session_01GL26QnA6dCrvUc3WmhzFSa

Rewrite the reference prose for the models an author builds before a
session starts: the crawl subpackage front page, the party, the adventure
with its town, the dungeon geometry and its state overlay, content packs,
and stocking. Every public member and every pydantic field now says what it
is for, what you need first, what to call next, and what its limits are,
and Adventure, DungeonSpec, and LevelSpec carry runnable examples.

Four claims corrected against the code: Party.ranks no longer says the
width is 3 in a room and 2 in a corridor, DropPile no longer says pursuit
bait lands in a pile, KeyedMonster.count_dice now names the wandering
stream, and DungeonSpec.levels now says the tuple's order decides which
entrance EnterDungeon uses.

Claude-Session: https://claude.ai/code/session_01GL26QnA6dCrvUc3WmhzFSa
Show `wall` and `open` in the edge examples, since EdgeKind is a StrEnum
and print emits the value. Say that EnterDungeon lands the party facing
north, on both DungeonSpec.levels and LevelSpec.entrance, and that
TravelToTown refuses to leave from anywhere but the entrance cell. Put
validate_adventure's check list in the order the body runs it, with the
town-travel and dungeon-entrance checks before the per-level loop. Add the
dice-expression ValueError to TrapEffect's Raises.

Claude-Session: https://claude.ai/code/session_01GL26QnA6dCrvUc3WmhzFSa
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant