====== Script Law — Items ======
Item-shell scripting detail for new creators. This page assumes you can already create and attach an item SpecProc ([[immortal:scriptlaw:objects|Script objects]]) and that the object prototype exists ([[immortal:creationlaw:objects|Objects]]).
If you only remember one teaching point: **many "item quests" are really mobile scripts** that inspect ''var.item''. Put behavior on the entity whose event actually fires. This page documents what you can do when the **item** proc runs, and the item-side primitives mobile scripts call.
Hub: [[immortal:scriptlaw|Script Law]].
===== Attach reminder (then come back here) =====
> @proc item new my_sword_proc
Okay.
> @proc item script my_sword_proc
(paste Beanshell that branches on var.STATE; end with return false;)
> @load item 3100
> @item proc my_sword_proc
> @examine item
> @save item
> create item 3100
>
Full attach pedagogy: [[immortal:scriptlaw:objects|Script objects]].
===== What ''var'' looks like for items =====
Item procs receive an ''ItemEvent.Var''. Fields you will read or branch on:
* ''STATE'', ''state'' — trigger kind and a free mutable script state integer
* ''item'' — the SpecProc owner shell (''ItemScript'' / item shell)
* ''mobile'', ''room'', ''victim'', ''victims'', ''items'' — context when the event provides them
* ''command'', ''args'' — when interpreter / post-interpreter hooks fire
* Scratch aliases such as ''m'', ''it'', ''rm'', ''s'', ''n'' where the Var exposes them
Always branch on ''var.STATE'' (or named constants like ''var.STATE_POST_INTERPRETER''). Return ''false'' unless you mean to block the triggering command.
Why branching matters: the same script text can be invoked for different STATEs. A stub that only chatters on ''STATE_SCRIPT'' will look "broken" if you were testing a give/drop path that never hits that STATE.
===== Item shell APIs (proven patterns) =====
Scripts call methods on shells rather than inventing verbs. From code and live world usage, item shells expose (illustrative — **not** an exhaustive javadoc dump):
* Type tests: ''isWeapon'', ''isKey'', and related ''is…'' helpers present on ''ItemShell''
* ''purge()'' — remove this item instance
* ''vid()'' — prototype / instance identity checks in quest scripts
* ''createMobile'' / fill helpers — where the shell provides them
* Other echo / container helpers that appear on the script subclass in real procs
Every eval also binds ''util'': ''roll'', ''chance'', ''limit'', ''max'', ''min'', ''getPosInt'', ''tokenizerNoFill'', …
**Rule for new creators:** before you invent a call, run ''@proc item examine '' or ''index proc_item'' and copy a pattern that already works. Only methods on ''ItemShell'' / script subclasses are legal. Fabricating ''var.item.doSomethingCool()'' will fail at eval time.
===== Pattern: type guard =====
Use when ambient item logic should only run for weapons (or keys, …):
if (var.STATE == var.STATE_SCRIPT) {
if (var.item.isWeapon()) {
// weapon-only flavor — keep it cheap
}
}
return false;
If an ''is…'' method is missing at eval time, you invented it — examine a live proc or shell source; do not guess.
===== Pattern: identity + purge (usually from a **mobile** proc) =====
Quest turn-ins typically live on the mobile (see ''thanksgiving'' on [[immortal:scriptlaw:mobiles|Script mobiles]]). The item-side primitives those scripts rely on:
* ''var.item.vid()'' — compare to the quest prototype VID you built in Creation
* ''var.item.purge()'' — consume the turned-in instance
* mobile ''createItem'' (or equivalent shell helper) — grant the reward
Teaching checklist when something "eats the give" wrong:
- [ ] You are testing the VID you think you are (''stat item'', Creation notes)
- [ ] The **mobile** has the proc attached, not only the item
- [ ] You return ''true'' only when you intend to consume/block the give
- [ ] Between tests you ''purge'' leftover rewards and re-''create'' the quest item
===== Pattern: when to put logic on the item vs the mobile =====
* **Mobile proc** — reactions to ''give'', ''say'', ''sayto'', socials, combat involving the NPC
* **Item proc** — behavior that must run because **this object** is pulsing / interpreting, independent of a particular NPC
* If you attached only ''@item proc'' and expected a shopkeeper to thank you for a give, move the quest logic to ''@npc proc''
===== Editing and re-test loop =====
> @proc item script my_sword_proc
(revise Beanshell, finish writer)
> purge sword
> create item 3100
(exercise the trigger again)
>
If a zone loads the object, ''@save'' the script then ''zone reset'' so you are not staring at an old mental model of "stale instances." Script text lives on the SpecProc row; the prototype must still ''@item proc'' that name.
===== Safety =====
* Immortal / creator only
* Eval errors: Beanshell ''EvalError'' caught; when the proc name matches a player, that player may receive the error text
* Laggy scripts (> ''Eventable.MAX_LAG_TIME'') are logged
* Shared static Interpreter on ''SpecProc'' — leave no leftover globals; runtime unsets ''var'' / ''util'' after each eval
* ''@proc item delete'' only after prototypes stop naming the proc
===== Common mistakes =====
* Inventing shell methods
* Expecting item procs to see every ''give'' (that is usually the mobile)
* Forgetting ''return false;''
* Editing script text but testing an old instance without purge/reset
* Attaching a proc name that ''index proc_item'' cannot find
===== Related =====
* [[immortal:scriptlaw:objects|Script objects]] — attach workflow
* [[immortal:creationlaw:items|Creation items]] — types/flags/spawn
* [[immortal:scriptlaw:mobiles|Script mobiles]] — give/quest patterns that read items
* [[immortal:scriptlaw|Script Law]] — hub