TinyMUX

Movement System

Hardcode

The movement system in TinyMUX handles how objects physically relocate between rooms, containers, and other objects. All movement logic lives in move.cpp and is built around three core routines: move_via_exit for normal exit traversal, move_via_teleport for teleportation, and move_via_generic for all other movement (entering objects, leaving containers, going home, being picked up or dropped).

The Movement Sequence

Every movement follows a consistent sequence of phases:

  1. Pre-move messages – exit @succ/@osucc/@asucc (normal movement) or @oxtport (teleportation).
  2. Leave processing@leave, @oleave, @oxenter, @aleave, and “has left” in the source room.
  3. Physical relocation – the object is removed from the source contents list, added to the destination, and shown the new room.
  4. Post-arrival messages – exit @drop/@odrop/@adrop (normal movement), or @tport/@otport/@atport (teleportation). The object’s own @move/@omove/@amove always fire.
  5. Enter processing@enter, @oenter, @oxleave, @aenter, and “has arrived” in the destination room.
  6. Post-move cleanup – divestiture of KEY objects and sticky drop-to processing on the vacated room.

Message Generation

Messages are generated by process_leave_loc and process_enter_loc, which evaluate attributes via did_it (handling the personal message, the others-see message, and the action list in one call).

Leaving triggers: @leave (to the mover), @oleave (to others in the old location), @aleave (action list on the old location), @oxenter from the new location (to others in the old location), and a “has left” notification.

Entering triggers: @enter (to the mover), @oenter (to others in the new location), @aenter (action list on the new location), @oxleave from the old location (to others in the new location), and a “has arrived” notification.

When moving through an exit, two additional attribute sets fire around the leave/enter sequence: @succ/@osucc/@asucc before leaving, and @drop/@odrop/@adrop after arrival.

The @aenter and @aleave action lists always execute, even when other messages are suppressed by darkness. This means rooms can reliably run softcode in response to arrivals and departures. The object’s own @amove also always executes.

Teleportation vs Normal Movement

Teleportation (move_via_teleport) differs from exit-based movement:

  • Lock checks: the source’s TeloutLock is checked up the containment tree to the enclosing room. The destination’s TportLock is checked if it is JUMP_OK and uncontrolled. Failure triggers @tofail/@otofail/@atofail.
  • Messages: @oxtport replaces exit @osucc before the move; @tport/@otport/@atport replace exit @drop/@odrop after.
  • Divestiture: KEY-flagged objects are always stripped after arrival.

Drop-Tos

A room can be linked to a drop-to destination with @link. When an object is dropped in such a room, and neither the object nor the room is STICKY, the object is sent through the drop-to via move_via_generic. If the room is STICKY, the drop-to is deferred: objects are only swept to the drop-to after the last connected hearer leaves the room (process_sticky_dropto). If the dropped object itself is STICKY, it is sent home instead of through the drop-to.

Home Movement

Typing home triggers a special path in do_move. The server prints “There’s no place like home…” three times, then calls move_via_generic with the HOME destination. The player is divested of KEY objects, and sticky drop-to processing runs on the vacated room. The FIXED flag prevents non-royalty players from going home.

Entering and Leaving Containers

The enter command moves a player inside a THING or PLAYER. The target must have ENTER_OK set (or be controlled), and the player must pass its EnterLock. On failure, @efail/@oefail/@aefail fire.

The leave command moves a player out of a container to the container’s location. The player must pass the LeaveLock; on failure, @lfail/@olfail/@alfail fire. The leave lock only governs the leave command—it does not block exits, teleportation, or going home.

Both commands use move_via_generic and fire the full leave/enter message sequence.

Lock Checks During Movement

The movement system consults several locks:

  • DefaultLock on exits: must pass to traverse.
  • EnterLock on things/players: must pass to enter.
  • LeaveLock on things/players: must pass to leave.
  • TportLock on destinations: must pass to teleport to a JUMP_OK room.
  • TeloutLock on locations: must pass to teleport out. Checked on every containing object up to the enclosing room.

Dark Movement and Stealth

When a moving object or its location is DARK, the leave and enter messages (@leave, @oleave, @enter, @oenter, @oxenter, @oxleave) and the “has left” / “has arrived” notifications are suppressed. The exception is when the location has Wizard privileges, which forces messages to display regardless of darkness.

A player with the dark power who sets themselves DARK moves silently: no arrival/departure messages, no exit @osucc/@odrop, and no “has arrived”/“has left” notifications. Action lists (@aleave, @aenter) still execute. The BLIND flag independently suppresses “has left” and “has arrived” notifications on either the mover or the location.

The /quiet switch on move, enter, and leave suppresses the others-see and action-list attributes on the exit or container, but only if the player controls the relevant object.