Wire thing templates and inventory into server startup

Loads thing templates from content/things/ at startup. Registers
get/drop/inventory commands via things module import. Reconstructs
player inventory from saved template names on login, with graceful
fallback for unknown templates.
This commit is contained in:
Jared Miller 2026-02-11 20:03:57 -05:00
parent 6081c90ad1
commit 8acfa5ea22
Signed by: shmup
GPG key ID: 22B5C6D66A38B06C

View file

@ -22,6 +22,7 @@ import mudlib.commands.play
import mudlib.commands.quit import mudlib.commands.quit
import mudlib.commands.reload import mudlib.commands.reload
import mudlib.commands.spawn import mudlib.commands.spawn
import mudlib.commands.things
from mudlib.caps import parse_mtts from mudlib.caps import parse_mtts
from mudlib.combat.commands import register_combat_commands from mudlib.combat.commands import register_combat_commands
from mudlib.combat.engine import process_combat from mudlib.combat.engine import process_combat
@ -30,6 +31,8 @@ from mudlib.effects import clear_expired
from mudlib.if_session import broadcast_to_spectators from mudlib.if_session import broadcast_to_spectators
from mudlib.mob_ai import process_mobs from mudlib.mob_ai import process_mobs
from mudlib.mobs import load_mob_templates, mob_templates from mudlib.mobs import load_mob_templates, mob_templates
from mudlib.thing import Thing
from mudlib.things import load_thing_templates, spawn_thing, thing_templates
from mudlib.player import Player, players from mudlib.player import Player, players
from mudlib.resting import process_resting from mudlib.resting import process_resting
from mudlib.store import ( from mudlib.store import (
@ -264,6 +267,7 @@ async def shell(
"max_stamina": 100.0, "max_stamina": 100.0,
"flying": False, "flying": False,
"zone_name": "overworld", "zone_name": "overworld",
"inventory": [],
} }
# Resolve zone from zone_name (currently only overworld exists) # Resolve zone from zone_name (currently only overworld exists)
@ -302,6 +306,20 @@ async def shell(
reader=_reader, reader=_reader,
) )
# Reconstruct inventory from saved data
for item_name in player_data.get("inventory", []):
template = thing_templates.get(item_name)
if template:
spawn_thing(template, player)
else:
# Template not found — create a bare Thing so it's not lost
log.warning(
"unknown thing template '%s' for player '%s'",
item_name,
player_name,
)
Thing(name=item_name, location=player)
# Parse and store client capabilities from MTTS # Parse and store client capabilities from MTTS
ttype3 = _writer.get_extra_info("ttype3") ttype3 = _writer.get_extra_info("ttype3")
player.caps = parse_mtts(ttype3) player.caps = parse_mtts(ttype3)
@ -465,6 +483,13 @@ async def run_server() -> None:
mob_templates.update(loaded) mob_templates.update(loaded)
log.info("loaded %d mob templates from %s", len(loaded), mobs_dir) log.info("loaded %d mob templates from %s", len(loaded), mobs_dir)
# Load thing templates
things_dir = pathlib.Path(__file__).resolve().parents[2] / "content" / "things"
if things_dir.exists():
loaded_things = load_thing_templates(things_dir)
thing_templates.update(loaded_things)
log.info("loaded %d thing templates from %s", len(loaded_things), things_dir)
# connect_maxwait: how long to wait for telnet option negotiation (CHARSET # connect_maxwait: how long to wait for telnet option negotiation (CHARSET
# etc) before starting the shell. default is 4.0s which is painful. # etc) before starting the shell. default is 4.0s which is painful.
# MUD clients like tintin++ reject CHARSET immediately via MTTS, but # MUD clients like tintin++ reject CHARSET immediately via MTTS, but