Skip to content

osrlib.crawl

The crawl framework: adventure content, the game session, and the dungeon crawl loop.

osrlib.crawl is the layer you build a dungeon crawler on. It holds the content models you author an adventure with, the GameSession that runs one, and the procedures the session dispatches to while the party explores, talks, and fights. It sits on top of the osrlib.core kernel, which has the characters, items, dice, the clock, and the rules that need no dungeon around them. The dependency runs one way: the kernel never imports from here, so you can use the core rules on their own and reach for this package when you want a running game.

The modules, in the order you meet them:

Typical usage:

from osrlib.core.abilities import AbilityScore
from osrlib.core.alignment import Alignment
from osrlib.core.character import Character
from osrlib.crawl.adventure import Adventure, TownSpec
from osrlib.crawl.commands import EnterDungeon, MoveParty
from osrlib.crawl.dungeon import Direction, DungeonSpec, Edge, EdgeKind, LevelSpec
from osrlib.crawl.party import Party
from osrlib.crawl.session import GameSession

hero = Character(
    name="Hild",
    class_id="fighter",
    race="human",
    level=1,
    xp=0,
    scores={ability: 12 for ability in AbilityScore},
    alignment=Alignment.LAWFUL,
    max_hp=8,
    current_hp=8,
)
crypt = DungeonSpec(
    id="crypt",
    name="The Old Crypt",
    levels=(LevelSpec(number=1, width=2, height=1, entrance=(0, 0), edges={"1,0:west": Edge(kind=EdgeKind.OPEN)}),),
)
adventure = Adventure(name="A First Delve", town=TownSpec(name="Threshold"), dungeons=(crypt,))

session = GameSession.new(Party(members=[hero]), adventure, seed=7)
session.execute(EnterDungeon(dungeon_id="crypt"))
result = session.execute(MoveParty(direction=Direction.EAST))

print([event.code for event in result.events])
# ['exploration.party.moved']