Skip to content

osrlib.messages

Turn an event into a line of English.

osrlib never puts prose in an event. A GameSession responds to a command with typed events made of structured facts, like who attacked, what they rolled, and how much damage landed, and your front end decides what a player reads. This module is the default formatter that comes with osrlib. format_message takes an event and returns a plain English sentence, so you can print a session's output before you've written any rendering of your own.

The event's code determines the line you get. It's a dotted name like combat.attack.hit that identifies the outcome the event records, and this module has one template per code. Every event class declares the codes it can use in allowed_codes, and ALL_EVENT_CLASSES lists every event class, so {code for cls in ALL_EVENT_CLASSES for code in cls.allowed_codes} is every code osrlib defines. The message-code reference lists the same codes with the event class behind each one, its default visibility, and its template. Read it when you're deciding which codes your front end handles differently.

Use this formatter for a log, a transcript, a debugging view, or the first working version of a game. Replace it when you want your own wording, and you replace the whole of it: read the event's fields and write your own line, or hand the event to a narrator. There's nothing here to configure, no way to register a template, and no translation, because a front end that cares about wording already has the structured fields it needs to write any wording it likes. Entity ids come out as ids, since only your game has a name for orc-1. The quest and objective events are the exception, and include a display name the adventure's author wrote.

Formatting is string work. It reads no files, makes no calls, and changes nothing, so it's safe on any event from any source.

Typical usage:

from osrlib.core.events import DamageDealtEvent
from osrlib.messages import format_message

event = DamageDealtEvent(target_id="orc-1", attacker_id="hild", amount=5)
print(format_message(event))
# orc-1 takes 5 damage from hild.

format_message

format_message(event: Event) -> str

Format an event as a line of default English.

Call it on each event in a CommandResult's events, or on each event in a session's event_log, to get a transcript a person can read. If you're showing the result to a player, first keep only the events whose visibility is Visibility.PLAYER, so referee-only events stay hidden.

A session's event_log can also contain plain dicts. After load_game, an entry whose event type this osrlib doesn't recognize stays the dict it was in the save. Skip those, or print their code key, before you filter on visibility. A dict has no visibility attribute, and this function takes an event object, not a dict.

On an event osrlib built, it doesn't raise and it doesn't return an empty string. An event whose code has no template comes back as the code itself, so a log written by a newer osrlib than the one reading it still prints, one plain line per event, instead of failing part way through. An event you assemble by hand can still raise AttributeError, because a template reads the fields its event class declares: give an event a code from another class and the field that template needs isn't there. When you build an event by hand, use the class that declares its code.

Some events include a narrative, the sentence an adventure's author wrote for that moment. When one is there it's appended to the templated line, word for word, because the wording of authored text belongs to the author.

Write your own formatter as soon as you want control of the wording. This one prints entity ids as ids, writes only English, and has no hook for changing a template. Every fact it uses is a typed field on the event, so your version reads the same fields and uses the names your game gives things.

Parameters:

Name Type Description Default
event Event

Any event, from a command result, a session's event log, or a save you loaded.

required

Returns:

Type Description
str

One line, with no trailing newline: the template for the event's code, followed by the event's narrative when it has one, or the bare code when no template matches.

Examples:

from osrlib.core.events import DamageDealtEvent, Event, Visibility
from osrlib.messages import format_message

event = DamageDealtEvent(target_id="orc-1", attacker_id="hild", amount=5)
print(format_message(event))
# orc-1 takes 5 damage from hild.

unknown = Event(code="future.thing.happened", visibility=Visibility.PLAYER)
print(format_message(unknown))
# future.thing.happened