tbamud/lib/scripts/README.md

5.2 KiB

Scripts In lib/scripts

This directory contains Python and DSL-style scripts used by the game. Scripts are attached to rooms, npc's, and objects via builder commands (e.g. rset add script, mset add script, oset add script). The script file itself is the data format.

Two Script Styles

  1. DSL (no function definitions)

    • If the file does NOT contain def on_trigger, it is treated as the DSL.
    • The DSL supports Python-style if/elif/else, for, and while blocks.
    • Actions are written as simple verbs or function-style calls:
      • move("n") or move("north")
      • move(1200) (room vnum path step, no closed doors)
      • emote("looks around warily")
      • sleep(3)
      • log("text with {npc.vnum}")
      • do("say hello")
    • Command-style is also supported:
      • move "n"
      • sleep 3
      • log "hello {npc.vnum}"
    • NOTE: The DSL does not support custom variable assignments yet. Use the full Python style if you need variables.
  2. Full Python (with def on_trigger(event):)

    • If the file contains def on_trigger, it runs as normal Python.
    • Use mud.sleep(seconds) to pause and resume later.
    • You can use local variables, helpers, and full Python expressions.

Event Context (Full Python)

on_trigger(event) receives a dict with:

  • event["self"]: the entity this trigger is attached to (mob/object/room)
  • event["trigger"]: info about the trigger (vnum, name, type, narg, etc.)
  • event["vars"]: trigger variables (if any)

Entity Data Model (DSL and Python)

Every entity has these common properties:

  • entity.kind -> kind id (mob/obj/room)
  • entity.uid -> unique runtime id
  • entity.vnum -> vnum (mob/obj/room)
  • entity.name -> name/short for display

Mob (NPC or PC) properties:

  • npc.health / npc.max_health
  • npc.mana / npc.max_mana
  • npc.stamina / npc.max_stamina
  • npc.move / npc.max_move (alias for stamina)
  • npc.class / npc.class_id
  • npc.species / npc.species_id
  • npc.is_pc / npc.is_npc
  • npc.keyword (NPC keywords; for PCs, name)
  • npc.room -> room entity where the mob is located
    • npc.room.vnum -> room vnum
    • npc.room.name -> room name/short

Object properties:

  • object.keyword -> object keywords
  • object.oval -> list of object values (oval[0] .. oval[NUM_OBJ_VAL_POSITIONS-1])
  • object.room -> room entity where the object is located
    • object.room.vnum -> room vnum
    • object.room.name -> room name/short

Room properties:

  • room.contents -> list of objects in the room
  • room.people -> list of characters in the room
  • room.vnum -> room vnum
  • room.name -> room name/short

Entity comparisons:

  • entity == "rat" checks keyword match for mobs/objects.
  • entity == 123456 checks entity uid.
  • entity_a == entity_b matches if kind+uid are equal.

Available Methods

These are available in both DSL and Python (via the mud module).

Core methods:

  • mud.do(command, actor=None) Execute a game command. If actor is a mob, it runs as that mob. If actor is a room, it runs in that room context.
  • mud.emote(message, actor=None) Emote as a mob (actor is optional if the trigger is on a mob).
  • mud.move(direction, actor=None) Move a mob in a direction (e.g. "n", "south", "ne"). You can also pass a room vnum to step toward a destination, but if it is blocked (eg. with a door), this will not work.
  • mud.sleep(seconds) Pause the script and resume later.
  • mud.roll("1d6") Roll dice. Supported: d4/d6/d8/d10/d12/d20/d100.
  • mud.log(message) Write to log/script.log.
  • mud.echo_room(room, message) Echo a message to a specific room.
  • mud.send_char(character, message) Send a message to a character.
  • mud.call_later(seconds, func, *args, **kwargs) Call a function later (Python scripts only).

Convenience names in full Python scripts:

  • log("...") is available as a shortcut for mud.log(...).
  • Direction strings are available as mud.n, mud.s, mud.e, mud.w, etc.

Formatting / Expressions

DSL supports Python-style blocks:

while True:
    if npc.stamina < 20:
        rest
    else:
        stand

DSL logging supports f-string style with braces:

log "rat {npc.vnum} in room {npc.room.vnum}"

In full Python scripts, use normal f-strings:

log(f"rat {event['self'].vnum} in room {event['self'].room.vnum}")

Variables (Full Python)

Use normal Python variables:

def on_trigger(event):
    room = event["self"]
    count = 0
    while True:
        count += 1
        mud.echo_room(room, f"tick {count}")
        mud.sleep(30)

The DSL currently does not support custom variable assignment. If you need variables, use full Python with def on_trigger(event):.

Best Practices

  • Keep scripts small and focused.
  • Use log(...) during development and remove or reduce noise later.
  • Avoid infinite tight loops without sleep.
  • Use comments generously (# ...).
  • Prefer readable direction strings: "north", "west", etc.

Sample: Room Echo Script

See sample_echo.py in this directory for a ready-to-attach room script.