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
0prefixes where the dialect expects them (e.g.04000c0b1is 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.