Table of Contents

Script Law — Mobiles

Full mobile SpecProc onboarding. You may know Diku mobile specials or dg_scripts — Neo uses Beanshell on named SpecProcs, attached with @npc proc after the mobile prototype exists.

Hub: Script Law. Build first: Creation Law — Mobiles.

Why attach after the prototype exists

@npc proc <name> only stores a string name on the prototype. The Beanshell lives in the SpecProc table. Create the proc, write the script, verify with examine / index, then load the npc workspace, set proc, @examine, @save. Reversing that order is the top beginner mistake.

Step-by-step: first mobile script

1. Create the named proc

> @proc npc new quiet_stretch
Okay.
> @proc npc script quiet_stretch
(writer opens — paste the stub below, finish writer)
> @proc npc examine quiet_stretch
> @proc npc matrix quiet_stretch 0.0
Okay.
> index proc_npc quiet
>

Pattern: @proc npc [delete|examine|new|matrix|rename|script] <name>. Names: lowercase, alphabetic/underscore, length 3–16.

2. Minimal starter stub (periodic flavor only — safe default):

if (var.STATE == var.STATE_SCRIPT) {
  // occasional flavor only
  if (util.chance(100)) {
    var.mobile.echoRoom("You stretch.", "$n stretches.");
    return true;
  }
}
return false;

3. Attach on the mobile prototype

> @load npc 1210
Okay.
> @npc proc quiet_stretch
Okay.
> @examine npc
> @save npc
Okay.
> create npc 1210
> zone reset
>

If create is refused, fix ranges / maximum (Mobiles, Items create-vs-load notes). If the script never fires, confirm the proc name on @examine npc and that you saved.

4. Personal writer alternative

> script mobile list
Listing the mobile script for Silk:
…
> script mobile write
Writing a new mobile script for Silk.
(writer opens)
>

script (mobile|item|room) (list|write) [player] — non-implementors edit their own name only.

STATE branches you will write constantly

Need Branch
Ambient chatter / pulse var.STATE == 0 or var.STATE_SCRIPT
After give / say / social STATE_POST_INTERPRETER (-3)
During command interpret STATE_INTERPRETER (-1)
Combat tick STATE_COMBAT (-2)

Return Boolean.TRUE to block the triggering command on interpreter-style calls (see SpecProcMobile.func javadoc). Otherwise return false;.

Mobile shell APIs (illustrative)

Real mobile scripts use patterns such as:

Prefer @proc npc examine <name> on a live world proc before inventing new calls — only MobileShell / script subclass methods are legal.

CPU filter caveat (read once)

Authors historically embed the literal tokens STATE_SCRIPT, STATE_INTERPRETER, … in script text so SpecProc.script() can set CPU filter flags. In current SpecProcMobile.func that early-return filter is commented out, so mobile scripts still run for every call until the optimization is re-enabled. Keep scripts cheap, and still write correct STATE branches for when the filter returns.

Worked example: ''babybunny'' (chatter + slap)

> @proc npc examine babybunny

Pattern from the live world dump: on STATE_SCRIPT (0), roll and echoRoom; on STATE_POST_INTERPRETER (-3), react to slap. Always end with return false; unless you intend to block. Study the full text in-game — this handbook only teaches the shape.

Worked example: ''thanksgiving'' (quest give)

On pulse (STATE == 0) the hen speaks via oldScript. On post-interpret, if var.command is give and var.item.vid() matches the quest item, thank the player, purge the item, and createItem a reward into the victim's inventory. Returning true consumes the interaction.

Teaching checklist when you copy this pattern:

Worked example: ''quest_cursor'' (follow / sayto)

Branches on var.STATE_POST_INTERPRETER for sayto orders (follow, make indian, …) and on STATE_SCRIPT to teleport home or stay with the master. Uses named constants (var.STATE_POST_INTERPRETER / var.STATE_SCRIPT) rather than raw integers — prefer that style in new scripts.

Hard-coded Java specials

Not every interesting mobile is a Beanshell row. MobileSimpleScript dispatches compiled methods by VID for a large legacy set. Classes such as MobileMayor, MobileJanitor implement SpecProc* in Java. Attach those through SpecNPC on @npc_stats attrs when the special is enum-backed compiled code rather than a free-form script name (Mobiles).

Bind overview (mobile ''var'')

Editing safety

Common mistakes