UOUndeathCodex

Hand-maintained page (not auto-generated). Edit it directly; the reference generator leaves it alone.

SphereServer Reference

UOUndeath runs on SphereServer 0.56 — a scripted Ultima Online server. There is no compile step: the world is defined by .scp text files that the engine loads at startup and reloads on .resync. This page is a refresher for anyone who hasn't touched Sphere scripting in a while. For staff commands, see the Game Master Guide.

This shard uses the original 2012 spheresvr binary, not the modern SphereServer — the classic content depends on it. Script syntax below is the 0.56 dialect.

How the scripts fit together

Everything the server loads is listed, in order, in server/scripts/spheretables.scp under [RESOURCES]. A new .scp file isn't live until it's listed there — or dropped into a directory that's already included (like server/scripts/UOUD/). Order matters: a DEFNAME must be defined before anything references it.

spheretables.scp     ← entrypoint: [RESOURCES] lists every file, in load order
sphere_defs.scp      ← base DEFNAMEs / constants (loaded early)
sphere_*.scp         ← stock Sphere systems (spells, skills, menus, triggers…)
UOD/                  ← this shard's custom content

To disable a script, this shard renames it to .tmp under UOD/Inactive/ (Sphere only loads *.scp) rather than deleting it.

Anatomy of a script

A .scp file is a list of sections. Each section header is [TYPE name_or_id], and its body is KEY=value lines plus trigger blocks.

[ITEMDEF i_magic_sword]
NAME=magic sword
ID=i_sword
WEIGHT=8.0
DAM=15,25

ON=@Equip
  SRC.SYSMESSAGE You feel a surge of power.

Common section types you'll meet:

Section Defines
[ITEMDEF …] An item type — id, name, weight, damage, behavior
[CHARDEF c_…] A creature / NPC — stats, sounds, AI, loot
[FUNCTION name] A reusable command/subroutine, callable as .name or object.name
[TYPEDEF t_…] Custom double-click / trigger behavior shared by many items
[DIALOG d_…] A gump window (layout + a BUTTON handler section)
[SPAWN …] A group of creatures/items used to populate the world
[TEMPLATE …] A reusable bundle of properties / loot
[SKILLMENU …] A crafting / skill menu tree
[EVENTS e_…] A block of triggers you attach to chars/items with EVENTS +e_…
[DEFNAME group] Named constants: mydef 042 → use as <def.mydef>

Every one of the shard's custom definitions is catalogued under Reference (auto-generated from server/scripts/UOUD/).

The object model

The world is characters and items, each with a unique UID (serial). Scripts act on objects through reference keywords that point at "who's involved" in the current trigger:

Reference Points at
(bare) The object the trigger is running on
SRC The source — usually the player who caused the action
ACT The actor — the object last acted upon
OBJ A general-purpose pointer you set yourself (OBJ=<uid>)
NEW The object just created by NEWITEM / NEWNPC
TOPOBJ The top-level container of an item (the ground or a pack owner)
SERV The server itself — for global commands (SERV.NEWITEM, SERV.ALLCLIENTS)
I.<defname> / C.<defname> Look up an item / char definition by name

You chain a reference to a property or command with a dot: <src.name>, src.go britain, <act.topobj.uid>.

Reading & writing properties

Wrap a property in angle brackets to read its value; write it with =.

<src.name>            // read the source's name
src.str=100           // set the source's strength
<eval <hits> + 10>    // EVAL forces integer math
  • <...> — evaluate/substitute. Nest them: <serv.chardef.<obj.id>.icon>.
  • <eval ...> — evaluate as an integer expression.
  • <def.NAME> / <def0.NAME> — read a named constant.
  • Numbers default to hex unless prefixed; write decimals as needed and use 0 prefixes where the dialect expects them (e.g. 04000c0b1 is a UID).

TAGs and VARs — your storage

You rarely have real variables; you attach data to objects and the server instead.

Storage Scope Example
TAG.<name> Persists on an object, saved with the world src.tag.quest_stage=2
TAG0.<name> Same, but a "0" default-read that returns 0 if unset <obj.tag0.p>
VAR.<name> Global server variable <var.event_active>
LOCAL.<name> Temporary, only within the current trigger/function call local.count=0
ARGV[n] / ARGS Arguments passed into a FUNCTION <argv[0]>, <args>

Triggers (@events)

Behavior hangs off triggers — blocks that fire on an event. Inside a section, a trigger starts with ON=@Name:

[TYPEDEF t_newshrink]
ON=@DClick
  IF !(<topobj.uid>==<src.uid>)
    src.syserror The shrink has to be on you to be used.
    RETURN 1        // stop the default double-click behavior
  ENDIF

RETURN 1 from a trigger usually means "I handled it — cancel the default action." RETURN 0 (or falling off the end) lets the engine continue.

A few triggers you'll see constantly:

Trigger Fires when
@Create The object is first created
@DClick A character double-clicks the item/NPC
@Click A character single-clicks (the name label)
@Step Something steps onto the item's tile
@Equip / @UnEquip Item is worn / removed
@Timer The object's TIMER countdown reaches 0
@Death / @GetHit / @Attack Combat events on a character
@Login / @Logout A player connects / disconnects

TIMER=<seconds> on an object schedules its @Timer trigger — the standard way to do delayed or repeating work (set TIMER again at the end to loop).

Reusable trigger blocks live in [EVENTS e_name] and are attached with EVENTS +e_name (on a char/item) or globally; a player being "in" one is tested with <isevent.e_name>.

Flow control

IF (<src.account.plevel> > 1)
  src.sysinfo You are staff.
ELSEIF (<src.hits> < 10)
  src.sysinfo You are badly hurt.
ELSE
  src.sysinfo Carry on.
ENDIF

FOR 1 5
  serv.log Iteration <local._for>
ENDFOR
  • IF / ELSEIF / ELSE / ENDIF, FOR … ENDFOR, WHILE … ENDWHILE.
  • String compare with STRMATCH(<args>,SET); math/logic with &&, ||, ==, >, !.
  • RETURN <n> exits the current trigger/function with a value.

Talking to the player

Command Shows
SRC.SYSMESSAGE <text> A line in the lower-left system log
SRC.SYSINFO <text> Info-styled system message
SRC.SYSERROR <text> Error-styled (used for "you can't do that")
MINFO / MSPECIAL Overhead / special messages used by this shard
SRC.DIALOG d_name Open a gump; SRC.DIALOGCLOSE d_name closes it
SERV.B <text> Broadcast to everyone
Prefix @<hue> / @<font,hue> Colour a message, e.g. @0<...>

Making things

SERV.NEWITEM i_gold          // create an item, becomes NEW
NEW.AMOUNT=500
SRC.BOUNCE <new.uid>         // put it in the source's hands/pack

SERV.NEWNPC c_orc            // create a creature, becomes NEW
NEW.P=<src.p>                // place it at the source's position

P is a position (x,y,z,map); <src.p> reads where the source is standing. REMOVE deletes the current object; BOUNCE / EQUIP / MOVE relocate items.

Where to look next

  • Game Master Guide — the staff command toolkit and plevels.
  • Reference — auto-generated catalogs of every custom item, NPC, function, dialog, template and more in this shard.
  • Systems — worked examples of these building blocks in the shard's own scripts.
  • Official docs live at the SphereServer wiki, but this page plus the catalogs should cover day-to-day work here.