Show pageOld revisionsBacklinksBack to top You've loaded an old revision of the document! If you save it, you will create a new version with this data. Media Files ====== Script Law ====== Otherwise known as the SpecProc handbook. Where immortals learn how to attach, edit, and reason about Beanshell scripts on rooms, objects, mobiles, and items in Nilgiri. ===== What scripting is here ===== Nilgiri does not ship a separate "dg_scripts" or MUDL interpreter for builders. Live world scripts are **Beanshell** (''bsh'') stored on SpecProc rows in the world H2 database and evaluated at event time. Hard-coded Java specials under ''net.nilgiri.mud.spec'' (for example ''MobileMayor'', ''RoomPrayForItems'', ''SpellSunbeam'') remain available for behavior that belongs in compiled code rather than a DB script. * See: [[codelaw|Code Law]] — why Beanshell was chosen * See: [[creationlaw|Creation Law]] — build the room / item / npc prototype before attaching a proc Two immortal faces exist for scripts: * '''''@proc''''' — create/rename/edit/delete **named** SpecProcs for the world (item, npc, room, spell). Creator command set. * '''''script''''' — list or rewrite the SpecProc whose name matches a **player** (usually your own). Immortals edit their own; implementors may name another player as a third token. ===== Who may script ===== * ''@proc'' is in ''Command._creator'' and gated by ''Immortality.creatorCheck'' (same as building). * ''script'' is also listed under the creator set. Non-implementors may only edit the script named for themselves; implementors may pass another player name. * Scripts persist in world tables (''spec_mobile'', ''spec_room'', ''spec_item'', spell procs) and reload on boot via ''SpecProc*.init()''. Errors during eval are reported to the owning immortal when the proc name matches a player CID (see ''SpecProcMobile.func''). ===== Creating and attaching a SpecProc ===== ==== Named world procs (''@proc'') ==== <code mud> > @proc npc new thanksgiving Okay. > @proc npc script thanksgiving (writer opens — paste Beanshell, then finish) > @proc npc examine thanksgiving …script text… > @proc npc matrix thanksgiving 0.0 Okay. > @proc npc rename thanksgiving turkey_mom Okay. > @proc npc delete turkey_mom Okay. > </code> Help text from code: * ''@proc item [delete|examine|new|matrix|rename|script] <name>'' * ''@proc npc [delete|examine|new|matrix|rename|script] <name>'' * ''@proc room [delete|examine|new|matrix|rename|script] <name>'' * ''@proc spell [delete|examine|new|matrix|rename|script] <name>'' Proc names are lowercased, alphabetic/underscore, length 3–16 (''SpecProc.MIN_NAME_LEN'' / ''MAX_NAME_LEN''). List existing procs with the immortal index: <code mud> > index proc_npc thanksgiving > index proc_room > index proc_item > </code> ==== Bind the proc to a prototype ==== While a room / item / npc workspace entry is open (see [[creationlaw|Creation Law]]): <code mud> > @load npc 9314 Okay. > @npc proc thanksgiving Okay. > @save npc Okay. > @load room 1200 > @room proc my_room_proc > @save room > @load item 3100 > @item proc my_item_proc > @save item > </code> ==== Personal ''script'' writer ==== <code mud> > script mobile list Listing the mobile script for Silk: … > script mobile write Writing a new mobile script for Silk. (writer opens) > script item list > script room write > </code> Usage patterns from ''Immortal.cmdScript'': ''script (mobile|item|room) (list|write) [player]''. ===== Event triggers (STATE_*) ===== SpecProcs are invoked from room / mobile / item event paths with a ''Var'' context. The trigger kind is ''var.STATE'' (integers from ''Constant''): ^ Constant ^ Value ^ Typical meaning ^ | ''STATE_SCRIPT'' | 0 | Periodic / script pulse (mobile ''mobact'', room ''roomact'', …) | | ''STATE_INTERPRETER'' | -1 | Before / during command interpretation involving the entity | | ''STATE_COMBAT'' | -2 | Combat tick involvement | | ''STATE_POST_INTERPRETER'' | -3 | After a command (give, say, social reactions, …) | | ''STATE_ENTER'' | -4 | Entry into a room (room procs) | | ''STATE_MOVE_TO'' | -5 | Movement toward / into | | ''STATE_UPDATE'' | -6 | Periodic room update | Scripts should branch on ''var.STATE'' (or the named constants on the Var, e.g. ''var.STATE_POST_INTERPRETER''). Returning ''Boolean.TRUE'' can **block** the triggering command for interpreter-style calls (see javadoc on ''SpecProcMobile.func''). Returning ''false'' / ''null'' allows normal processing. Authors historically embed the literal tokens ''STATE_SCRIPT'', ''STATE_INTERPRETER'', … inside the 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 the STATE branches for correctness. ===== Bindings available to Beanshell ===== Each ''func'' sets: * '''''var''''' — event context (''MobileEvent.Var'', ''RoomEvent.Var'', or ''ItemEvent.Var'') * '''''util''''' — ''ScriptTool'' helpers (''roll'', ''chance'', ''limit'', ''max'', ''min'', ''getPosInt'', ''tokenizerNoFill'', …) ==== Fields on ''var'' (mobile / room family) ==== Common public fields include: * ''STATE'', ''state'' — trigger kind and a free mutable script state integer * ''mobile'' / ''room'' — the SpecProc owner shell (''MobileScript'' / ''RoomScript'') * ''victim'', ''victims'', ''item'', ''items'' * ''command'', ''args'' — command verb and argument string for interpreter hooks * Scratch aliases: ''m'', ''it'', ''rm'', ''s'', ''n'' ==== Shell APIs (illustrative, from code) ==== Scripts call methods on shells rather than inventing new verbs. Real mobile scripts in the world DB use patterns such as: * ''var.mobile.echoRoom(...)'', ''cechoRoom(...)'', ''cechonRoom(...)'', ''say(...)'', ''social(...)'', ''interpretSocial(...)'' * ''var.mobile.follow(...)'', ''teleportHome()'', ''teleportToNC(...)'', ''createItem(...)'', ''createNPC(...)'', ''purge()'', ''oldScript(String[] cmds)'' * ''var.item.purge()'', ''var.item.vid()'' * ''util.roll(n)'', ''util.chance(die)'' Room shells expose weather / door helpers (''lockNorth'', ''unlockEast'', ''echo'', …). Item shells expose type tests (''isWeapon'', ''isKey'', …), ''purge'', ''createMobile'', fill helpers, and more. Prefer reading an existing proc with ''@proc npc examine <name>'' or ''index proc_npc'' before inventing new call patterns — the shell surface is large and only what exists on ''MobileShell'' / ''RoomShell'' / ''ItemShell'' (and their script subclasses) is legal. ===== SpecProc matrix ===== ''@proc … matrix <name> <double>'' stores builder metadata on the SpecProc row. It is **not** combat power. Combat matrix scores come from ''Matrix.calculate'' / ''Mobile.matrix()''. Live procs often leave matrix at ''0.0''. ===== Worked examples from the live world dump ===== These are shortened illustrations of patterns found in ''db.world.sql'' SpecProc mobile scripts — cite the real proc names when studying full text in-game. ==== Periodic chatter + post-interpret reaction (''babybunny'') ==== <code mud> > @proc npc examine babybunny </code> Pattern: 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. ==== Quest turn-in on give (''thanksgiving'') ==== 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. ==== Follow / sayto control (''quest_cursor'') ==== 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 ''var.STATE_POST_INTERPRETER'' / ''var.STATE_SCRIPT'' named constants rather than raw integers. ==== 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'', ''RoomSkullDoor'', ''ItemExcalibur'' implement ''SpecProc*'' in Java. Attach those through the ''SpecNPC'' / ''SpecItem'' / ''SpecRoom'' attribute on stats/rooms (via ''@npc_stats attrs'' / ''@item_stats attrs'' / ''@room attrs'') when the special is an enum-backed compiled proc rather than a free-form script name. ===== Editing safety ===== * Immortal / creator only — mortals never pass ''creatorCheck''. * ''@proc … script'' and ''script … write'' open the standard multi-line writer; finishing the writer calls back into ''Immortality'' to store the text and update filter flags. * ''@proc … delete'' removes the DB row; detach prototypes that still name the proc before deleting if you rely on clean references. * Eval errors: Beanshell ''EvalError'' is caught; when the proc name matches a player, that player receives the error text. Laggy scripts (> ''Eventable.MAX_LAG_TIME'') are logged. * There is no separate "script reload" verb beyond saving the proc (''script()'' → ''update()'') and ensuring the prototype points at the name. Boot reloads everything from H2. * Shared static Beanshell ''Interpreter'' instance on ''SpecProc'' — keep scripts free of leftover globals; the runtime unsets ''var'' / ''util'' after each eval. ===== Minimal starter script ===== A cautious mobile pulse stub that does nothing harmful: <code mud> if (var.STATE == var.STATE_SCRIPT) { // occasional flavor only if (util.chance(100)) { var.mobile.echoRoom("You stretch.", "$n stretches."); return true; } } return false; </code> Attach after creating the proc: <code mud> > @proc npc new quiet_stretch Okay. > @proc npc script quiet_stretch (paste stub, finish writer) > @load npc 1210 > @npc proc quiet_stretch > @save npc > create npc 1210 > zone reset > </code> ===== Related ===== * [[creationlaw|Creation Law]] — prototypes, zones, load/create/purge * [[codelaw|Code Law]] — Beanshell among coding resources * [[gamelaw|Game Law]] — player-facing systems scripts may interact with SavePreviewCancel Edit summary Note: By editing this page you agree to license your content under the following license: CC Attribution-Share Alike 4.0 International scriptlaw.1790177060.txt.gz Last modified: 2026/09/23 15:24(external edit)