Builders » Guide

Building triggers

DG triggers are scripted reactions attached to mobs, objects, or rooms. This guide covers trigedit, the three attach types, common trigger types (GREET, COMMAND, RANDOM, DEATH, etc.), variable interpolation, control flow, and worked examples.

Last updated: 2026-05-18

📥 Download as Markdown

Building triggers

A DG trigger is a small script that fires on a specific in-game event. Mob triggers handle NPC behavior; object triggers handle item interactions; world triggers handle room-level events. You write them with trigedit and attach them to entities via the S menu in medit/oedit/redit.

This guide is the builder-facing overview. For the full reference (every trigger type, every variable, every script command) see DG Scripts (staff doc, readable as a builder).

Open the editor

trigedit 8500     Create or edit trigger vnum 8500

Triggers are vnum-addressed just like mobs/objs/rooms. Pick a vnum in your zone’s range.

Trigger Editor [8500]

1) Name         : baker greet
2) Intended for : Mobiles
3) Trigger types: GREET
4) Numeric Arg  : 100
5) Arguments    : (none)
6) Commands:
   * Triggered when someone enters the room
   wait 2 sec
   say If you're going adventuring, I recommend the waybread.
   wait 10 sec
   %echo% The Baker takes a rack of fresh bread from the oven.
W) Copy Trigger
Q) Quit

Pick the attach type FIRST

2) Intended for determines the available trigger types. You can’t change it after saving — triggers are bound to mob/obj/world. To switch, delete and recreate.

Attach typeUsed forCommands available
MobilesNPCs that react/speak/movem* script commands (mecho, mload, mteleport, …)
ObjectsItems that react to use/wear/geto* script commands
RoomsRooms that react to enter/leave/castw* script commands

The trigger type bitvector

Each attach type has its own list. Pick one or more (multiple types = trigger fires on any matching event).

Common mob trigger types

TypeFires whenUseful for
GREETSomeone enters the room the mob can seeWelcoming, gating, scripted reactions to PCs
GREET_ALLAnything enters (even invisible)Trap-style mobs, hidden detection
COMMANDA character types a commandOverride commands (“buy” handled by shopkeeper script)
SPEECHA character says a phraseNPC dialogue, password-recognition
ACTAn act() message in the room contains a keywordReacting to “smiles at you” etc.
DEATHThe mob diesLoot drop, summon servants, last words
RANDOMRandom pulse (numeric arg = % per tick)Ambient flavor lines
FIGHTEach combat round while fightingCombat tactics, special attacks
HITPRCNTHP drops below N% (numeric arg = threshold)Boss “second phase” behavior
LOWHPEdge-fires once when HP crosses below 20%Distress call, flee trigger
RECEIVEGiven an objectQuest turn-in
BRIBEGiven coins (numeric arg = min amount)Bribery scripts
LOADThe mob is loaded (zone reset)Initialization, special setup
MEMORYMob sees someone in its memory listVengeance scripts
CASTMob is targeted by a spellAnti-magic responses
TIMEGame-hour matches numeric argScheduled behaviors
WEATHEREVENTWeather event starts in the mob’s zoneIn-fiction weather reactions
TELLA PC tells the mob somethingConversational NPCs

Common object trigger types

TypeFires when
GETPicked up
DROPDropped
GIVEGiven to someone
WEARWorn
REMOVERemoved
USEuse <obj>
CONSUMEEaten/drunk
CASTTargeted by a spell
LOADLoaded (zone reset)
TIMERObject’s timer expires
RANDOMRandom pulse
COMMANDOwner types a command

Common room trigger types

TypeFires when
ENTERA character enters
LEAVEA character leaves
COMMANDCommand typed in the room
SPEECHSomeone speaks
CASTSpell cast in the room
DOORDoor manipulated
RANDOMRandom pulse
RESETZone reset
LOGINA character logs in to this room

Numeric arg and arglist

These two fields are interpreted differently per trigger type:

Trigger typeNumeric argArglist
RANDOM%-chance per pulse (1-100)
COMMANDCommand keyword(s)
SPEECH1=any-of, 2=all-ofKeyword(s) to match in spoken text
HITPRCNTHP threshold %
BRIBEMinimum coin amount
TIMEGame-hour to fire
GREET%-chance per greet (1-100)
WEATHEREVENTEvent name filter
PUBSUBTopic patterns: weather.*, combat.kill, *

When in doubt, the editor labels them.

Variables

Inside command lines, %var% is substituted with the variable’s current value.

Built-in variables (most common)

  • %self% — the trigger’s owner (mob/obj/room)
  • %actor% — whoever triggered this event
  • %random.N% — random integer 1..N
  • %time.hour%, %time.day%, %time.month%
  • %argument% — for COMMAND triggers, the rest of the command line
  • %speech% — for SPEECH triggers, what was said
  • %topic%, %payload% — for PUBSUB triggers
  • %direction% — for GREET/LEAVE triggers, the direction they entered/left

Field access

%actor.name%, %actor.level%, %actor.class%, %actor.hp%, %actor.is_pc%, %actor.vnum% (for mobs).

Chain for nested fields: %actor.room.vnum%.

Sub-fields with arguments: %actor.eq(wield).name% (the weapon’s short desc), %actor.skill(magic missile)% (skill level).

Control flow

Inside the command body:

* This is a comment

if <condition>
  <commands>
elseif <condition>
  <commands>
else
  <commands>
end

while <condition>
  <commands>
done

switch <value>
  case <val1>
    <commands>
  break
  default
    <commands>
  break
done

set <varname> <value>
eval <varname> <expression>

wait <N>            * wait N seconds
wait <N> tick
wait until <hour>

halt                * abort execution
return <0|1>        * 1 = command consumed (for COMMAND triggers)

Worked examples

Greeter

Name:          Baker greeter
Intended for:  Mobiles
Trigger types: GREET
Numeric arg:   100
Arguments:     (none)
Commands:
  wait 1 sec
  msend %actor% The Baker waves at you.
  mecho The Baker waves at %actor.name%.

Attach to the Baker via medit … S.

Conditional door guard

Name:          Guard north
Intended for:  Mobiles
Trigger types: COMMAND
Numeric arg:
Arguments:     north
Commands:
  if %actor.level% < 10
    msend %actor% The guard blocks your way! "You are not yet ready."
    return 1
  end
  msend %actor% The guard nods and lets you pass.

Attach to the guard. return 1 consumes the command so the player doesn’t actually walk north.

Quest item turn-in

Name:          Collect dragon scales
Intended for:  Mobiles
Trigger types: RECEIVE
Numeric arg:
Arguments:
Commands:
  if %object.vnum% != 3000
    msend %actor% %self% looks confused. "I have no use for that."
    mforce %actor% take %object% from %self%
    halt
  end
  msend %actor% %self% bows deeply. "Thank you, brave one!"
  mload obj 3001
  give scroll %actor%
  if %actor.questvar(scales_quest)% != complete
    set scales_quest complete
    msend %actor% Quest "Dragon Scales" complete!
  end

Ambient random mob action

Name:          Tavern crowd noise
Intended for:  Rooms
Trigger types: RANDOM
Numeric arg:   3
Arguments:
Commands:
  switch %random.4%
    case 1
      wecho A merchant slams his mug on the table, laughing.
    break
    case 2
      wecho A dwarf at the bar mutters something about deep tunnels.
    break
    case 3
      wecho A traveler at a corner table glances around nervously.
    break
    default
      wecho The fire crackles in the hearth.
    break
  done

Attach to the tavern room. With numeric_arg=3, fires roughly 3% of pulses — about every 30 seconds on average.

Boss second phase

Name:          Dragon enrage
Intended for:  Mobiles
Trigger types: HITPRCNT
Numeric arg:   50
Arguments:
Commands:
  mecho %self% roars in fury, eyes blazing with rage!
  set rage_active 1
  mforce %self% breathe fire

Once per fight when HP drops below 50%, the dragon enrages and uses a special attack.

Periodic shopkeeper restock

Name:          Restock bakery
Intended for:  Mobiles
Trigger types: TIME
Numeric arg:   6
Arguments:
Commands:
  * 6am every game-day
  mecho %self% takes a fresh batch of bread from the oven.
  mload obj 3010
  mload obj 3011
  mload obj 3012

Attaching triggers to entities

After saving the trigger:

  • Mob: medit <vnum>S → add trigger vnum.
  • Object: oedit <vnum>S → add trigger vnum.
  • Room: redit <vnum>S → add trigger vnum.

A trigger can be attached to multiple entities. Each instance gets its own running state.

You can also use the T zone reset command to attach a trigger only when the entity is loaded in a specific room.

Debugging

  • mlog / olog / wlog — write to the script log. Use freely.
  • Add comment lines (* …) liberally.
  • For variable issues, use mecho debug: var=%myvar% to confirm interpolation.
  • tstat <vnum> and vstat trig <vnum> show the trigger’s loaded state in-game.
  • DG runtime errors log to script.log AND to show script-errors (GOD).
  • show script-errors recent shows the latest failures.

Common pitfalls

SymptomCause
Trigger doesn’t fire at allNot attached, or the trigger type bitvector doesn’t include the event
if runs unconditionallyForgot == (used = which is assignment — set is the right keyword)
%var% prints literallyVariable not set; check spelling and case
Trigger fires once then never againHit a halt somewhere, or a COMMAND trigger consumed with return 1
Loop runs foreverwhile without an exit; engine caps with GET_TRIG_LOOPS after N iterations

See also