Wolf systems
Wolf Roleplay and Game Mode
Switch Game Mode on and the region’s game appears in your viewer: health, stamina and hunger, a bag, pets, weapons, an action bar and a target frame, drawn by the viewer itself with no HUD to wear. Anyone can build their own game with the wolfGame functions.
Wolf Territories only. This needs WolfViewer or WolfStorm on a Wolf Territories region. On other grids the menu items, buttons and panels are not shown at all.
Other viewers do not show the game screens. The roleplay kit's objects fall back to local chat and ordinary menus only when the game refuses a notice or menu, for example when you are not playing.
Overview

Game Mode: on or off
Game Mode is off until you switch it on. Switched on, the region’s game shows and you are joined to it automatically wherever you go; switched off, the game screens go away. Switch it with any of these:
- World > Game Mode, or the toolbar’s Game Mode button (it says On or Off).
- The paw icon in the bottom-right corner, beside the Toolbar, Car, Plane and Boat icons. With Game Mode off it switches it on; with it on it shows or hides the game bar, and the game keeps running while the bar is hidden.
- GAME: ON / OFF on the game bar, and the switch at the top of the Roleplay window.
Some regions force Game Mode on (so nobody can switch it off to avoid a fight). There the switch shows a padlock and reads LOCKED ON, and Leave this game is hidden. Your own choice comes back on the next region.
Two kinds of game
Managed games
Run by the grid. Stats regenerate and decay by themselves, health is the avatar’s own health, death respawns you at the game’s spawn point, and the game’s money, items and pets are kept by the grid, the same on every region of the game. The Wolf Territories game is one.
External games
An existing system with its own server and rules (Knightwood’s KRS, for example) that uses the viewer as its screen: its scripts set what the player sees, and nothing on the grid ticks.
Each game has its own money, separate from WT$.
Playing

The game bar
- Left: your portrait with the experience ring round it and your level, then the game’s first three stats as orbs, each with its number and name. Click either for your character.
- Centre: twelve action slots. The keys 1 to 9, 0, - and = press them, while Game Mode is on and you are not typing. Then your weapon slots: the rounds left, a sweep while reloading; click a weapon to reload it, or to open the Combat page.
- Right: the first eight things in your bag and your wallet (for the Wolf Territories game, Bones).
- Along the top: the page buttons Character, Combat, Bag, Pets, Game, Look and Help open the Roleplay window on that page (press again to close it). PANEL turns the plate behind the bar on or off; GAME: ON / OFF is the Game Mode switch.
- One panel uses the bottom of the screen at a time: the game bar steps aside for the car dashboard and the flight or sailing deck and comes back when they go. The paw icon, or switching Game Mode on, takes the bottom back.

The Roleplay window
Open it from World > Roleplay, the toolbar’s Roleplay button, or the game bar. The top shows your portrait, name and game, the Game Mode switch and your wallet.
| Tab | What is on it |
|---|---|
| Stats | Every stat as a ring with its number, your level, the game's information panel, and markers on other regions (Show on map, Teleport: both ask first). |
| Combat | Your weapon cards and the armour slots round a paper doll, each with Unequip; your abilities; the buffs and debuffs on you. |
| Bag | A grid of slots: what you hold, with its count, and everything else the game has at 0. Items with a slot have an Equip button. |
| Pets | A card for each pet: its picture, name, type, age and stats. "Died" shows as a word. |
| Game | The game's logo, name, who runs it, whether you are playing, its description, rules and website. |
| Look | The window's background picture: the theme's own, a texture dragged from your inventory, or a picture file from your computer, with its strength and a tint (Natural, Amber, Moonlight, Blood, Forest or Dusk). |
| Help | How to play, and the photograph and font credits. |
At the foot: Leave this game leaves only this game (it asks first; your stats are kept, and Game Mode stays on), and Clear screen effects clears any flash, blur or blackout and puts the downed overlay away. The window closes with its X or Escape, and every control can be reached with Tab.
What else you will see
Notices
Top right, at most four. Information and success notices stay 6 seconds, warnings 10; a danger notice stays until you close it.
Dialogs and buttons
Questions from the game, top right like ordinary script menus, and the game's own buttons in the Roleplay window.
Targets
With Game Mode on, click an avatar or object to target it: its frame shows top centre with its health, level, and a coloured rim with the word Hostile, Neutral or Friendly. Escape or the frame's X clears it.
Down and dead
A downed player is held still under a dark overlay that may count down; you can still chat for help. At zero health you die and the game respawns you.
Screen effects
A flash when hit, a pulse at low health, blur, blackout, greyscale or a shake. Escape or Clear screen effects always clears them, and they are toned down if your system asks for reduced motion.
Markers and tags
Markers on your screen, minimap and world map; game tags, a line under an avatar's name drawn as a game tag so it cannot pass for a group title.
Unverified
Anything that does not come from the game's own registered scripts (a worn HUD, or an object named like the game) is marked Unverified, with an icon and the word, and drawn plain. A web page from an unverified script asks before it opens.
The Wolf Territories game
The grid’s own game, in the wolves theme. It runs on every Wolf Territories region that has no game of its own: switch Game Mode on and you are playing.
Stats
| Stat | How it works |
|---|---|
| Health | You die at 0 and respawn. It comes back by 1 a minute. |
| Stamina | Comes back by 10 a minute. At 0 you slow down. Hunting and fishing cost stamina. |
| Hunger | How full you are. It falls by 1 a minute; at 0 you slow down. Eat to fill it. |
Bones, items and pets
- Bones are the money. You start with 100, and a new player gets 3 Meat, 2 Fresh Water and 2 Berries.
- The most of each item you can carry: Meat 50, Fish 50, Berries 50, Healing Herbs 20, Fresh Water 20, Antler 99, Pelt 99, Raven Feather 99.
- Pets: the Wolf Pup and the Raven, at most 3 of each. Each has Fed and Happiness (0 to 100); both fall by 1 a minute, even while you are away, so feed your pets and play with them.
The kit
The Wolf Territories Roleplay Kit, from the Wolf Games account. Every object and script in it is full permission: rez them, take them apart and read the scripts. Gathering objects keep their waiting time on you, not on the object, so ten bushes do not give ten times the berries.
| Object | What it does |
|---|---|
| Berry Bush | 2-4 Berries, once every 5 minutes. |
| Fishing Jetty | Cast a line (5 stamina): 7 casts in 10 catch 1-2 Fish. Stay within 20 m. Once every 2 minutes. |
| Fresh Water Spring | 3 Fresh Water, once every 3 minutes. |
| Herb Patch | 1-2 Healing Herbs, once every 10 minutes. |
| Deer (Hunting Ground) | Hunt it (15 stamina): 6 in 10 succeed, 2-3 Meat and sometimes a Pelt and an Antler. A miss can end with a kick (8 damage). Once every 5 minutes. |
| Raven Perch | Usually a Raven Feather, sometimes two, sometimes nothing. Once every 4 minutes. |
| Campfire | Cook and eat: Meat gives back 30 hunger, Fish 25, Berries 8. |
| Drinking Pool | 1 Fresh Water for 40 stamina. |
| Healer's Stone | 1 Healing Herbs for 25 health (not while you are down). |
| Pack Trader | Buys Pelts (12 Bones), Antlers (8) and Raven Feathers (3); sells Meat (6), Fish (5), 3 Berries (4), 2 Fresh Water (3) and Healing Herbs (10). Every trade happens completely or not at all. |
| Pet Den | Adopt a Wolf Pup (60 Bones) or a Raven (40 Bones): name it, pay, and get the pet's object. |
| Wolf Pup and Raven | Rez one and touch it: Feed meat or fish, Play (+20 Happiness, once a minute), Rename, Change pet. The pet itself is kept by the game, so every copy of the object can show it. |
Why the kit’s objects may change your game
Only a game’s own scripts may move its items, money and pets, or change a player’s stats. Every script in the kit is registered for the Wolf Territories game. The registration belongs to the script’s exact contents: copying an object keeps it working, but if you edit a kit script and save it, it becomes a new script the game refuses (“only the game’s own scripts may ...”). Otherwise anyone could change a berry bush to hand out a thousand berries.
Make your own game
- On a region you hold, create the game with
wolfGameCreate: a name, a currency and how death works. The region then runs it. - Add its stats with
wolfGameDefineStat, and its items and pets withwolfGameDefineItem,wolfGameDefinePetandwolfGameDefinePetStat. - Build its objects. Register each script that may move money, items and pets with
wolfGameTrustScript(register it again after every edit). - To run the same game on your other regions, read its key with
wolfGameKey()on the first region, then callwolfGameRegister(key)on each of the others.
Every call returns TRUE when it worked; when it is refused, wolfGetLastError() says why (an unknown key, a value out of range, or a rights rule).
Creating a game
// From the Sandbox test box: a managed game with Test Coins, health tied to the
// avatar's own, stamina that slows you at zero, and hunger that drains health.
wolfGameCreate(["name", "Sandbox Test", "kind", "managed",
"description", "Wolf Roleplay test game", "currency", "Test Coins", "symbol", "TC",
"start", 50, "playerpay", 1, "death", "spawn", "respawn", 5]);
wolfGameDefineStat("health", ["label", "Health", "max", 100, "start", 100,
"rate", 1, "health", 1, "colour", "#ef4444", "order", 0]);
wolfGameDefineStat("stamina", ["label", "Stamina", "max", 100, "start", 100,
"rate", 10, "zero", "slow", "colour", "#eab308", "order", 1]);
wolfGameDefineStat("hunger", ["label", "Hunger", "max", 100, "start", 100,
"rate", -30, "zero", "drain", "target", "health", "amount", 60, "colour", "#84cc16", "order", 2]);wolfGameCreate and wolfGameSet rules
| Key | Value |
|---|---|
| name | The game's name, unique, up to 64 characters. Required to create. |
| kind | "managed" (the default) or "external". |
| theme | "wolves" or "plain" (the default). |
| description / rules | Text up to 500 / 2000 characters, shown on the Game tab. |
| website | An https:// address. |
| logo | A texture key: the portrait and the Game tab's logo. |
| currency / symbol | The money's name (up to 24 characters) and symbol (up to 8). |
| currencyicon | The money's picture, a texture key. |
| start | The money a new player starts with (0 to start with). |
| playerpay | 1 lets players pay each other with their own objects. |
| death | "spawn" (the default), "home" or "stay". |
| respawn | Seconds before a dead player comes back, 0 to 600 (10 to start with). |
| spawn | A vector: where players respawn, on this region (defaults to the object). |
| starter | What a player's first join gives, e.g. "meat=3,water=2". |
| webhook / webhooksecret | An https:// address the grid tells about game events, and a 16 to 64 character secret that signs them. |
Stats: wolfGameDefineStat rules
At most 16 stats. The first three (by order) are the orbs on the game bar.
| Key | Value |
|---|---|
| label | The name shown, up to 32 characters. |
| min / max / start | Whole numbers; max must be more than min, and start between them (0, 100 and 100 to start with). |
| rate | Per minute: positive regenerates, negative decays. |
| zero | What happens at the minimum: "none", "die", "slow" or "drain". |
| target / amount | For "drain": the stat to drain, and how much a minute. |
| colour | #rrggbb. |
| icon | A texture key, or a short text glyph (up to 16 characters). |
| visible / order | 0 or 1; the sort order. |
| health | 1 ties the stat to the avatar's own health. |
| keep | 1 keeps it through a respawn (experience, gold). |
Items and pets
wolfGameDefineItem(name, rules): label, icon, max (per player, 0 = no limit), order; and for combat a kind and slot (see Combat). At most 200 items.- Give and take with
wolfGameItemAdd/wolfGameItemTake. For any trade usewolfGameExchange(avatar, take, give, reason): one step, all or nothing, with"$"standing for the game’s money. wolfGameDefinePet(type, rules): label, icon, max per player, order.wolfGameDefinePetStat(type, stat, rules): label, min, max, start, rate (per minute, and it keeps running while the pet is in inventory), zero ("none" or "die"), colour, icon, order.wolfGamePetCreate(owner, type, name, data)returns the new pet’s key; keep it in the pet object. The pet lives on the grid, aged by real time.
Defining items and a pet type (farm_setup.lsl, 32 lines: show or hide)
// Wolf Roleplay example - FARM + PETS SETUP (run once by the game's owner on a region running
// their game). Defines the items the farm and the pet shop use, and the wolf pup pet type.
// Everything here can also be done from the control panel's Roleplay section.
say(string what, integer ok)
{
if (ok) llOwnerSay(what + ": OK");
else llOwnerSay(what + ": REFUSED - " + wolfGetLastError());
}
default
{
touch_start(integer n)
{
if (llDetectedKey(0) != llGetOwner()) return;
if (wolfGameKey() == "") { llOwnerSay("This region runs no game - wolfGameCreate first."); return; }
// Items: what players hold, on the grid, the same on every region of the game.
say("item seed", wolfGameDefineItem("seed", ["label", "Wheat seed", "max", 500, "order", 1]));
say("item wheat", wolfGameDefineItem("wheat", ["label", "Wheat", "max", 9999, "order", 2]));
say("item pet_food", wolfGameDefineItem("pet_food", ["label", "Pet food", "max", 200, "order", 3]));
// A pet type and its stats. Rates are per MINUTE and keep running while the pet is in
// inventory or its owner is offline - a pup left a week without food will be gone.
say("pet wolf_pup", wolfGameDefinePet("wolf_pup", ["label", "Wolf pup", "max", 3]));
say("pup hunger", wolfGameDefinePetStat("wolf_pup", "hunger",
["label", "Food", "max", 100, "start", 80, "rate", -1, "zero", "die", "colour", "#84cc16", "order", 0]));
say("pup happiness", wolfGameDefinePetStat("wolf_pup", "happiness",
["label", "Happy", "max", 100, "start", 80, "rate", -2, "zero", "none", "colour", "#eab308", "order", 1]));
}
}
A market stall: every trade one wolfGameExchange (market_stall.lsl, 52 lines: show or hide)
// Wolf Roleplay example - MARKET STALL. Owned by the game's owner (or a no-modify copy made by
// them). Every trade is ONE wolfGameExchange: the goods and the money move together or not at
// all, so a player can never pay and not get the seeds, or sell wheat and not get paid.
list TRADES = [
// button, take, give
"Sell 10 wheat", "wheat|10", "$|25",
"Buy 5 seeds", "$|10", "seed|5",
"Buy pet food", "$|8", "pet_food|5"
];
integer MENU_CH;
integer gMenu;
list parse(string s)
{
list p = llParseString2List(s, ["|"], []);
return [llList2String(p, 0), (integer)llList2String(p, 1)];
}
default
{
state_entry()
{
MENU_CH = -3000000 - (integer)llFrand(1000000);
llSetText("Market stall\nTouch to trade", <1, 1, 1>, 1.0);
}
touch_start(integer n)
{
key av = llDetectedKey(0);
if (!wolfGameIsPlaying(av)) { llRegionSayTo(av, 0, "Join the game first."); return; }
list buttons = llList2ListStrided(TRADES, 0, -1, 3);
llListenRemove(gMenu);
gMenu = llListen(MENU_CH, "", av, "");
// The player's own Wolf viewer shows the dialog; the answer comes back here as chat.
if (!wolfGameDialog(av, "Market stall", "You have " + (string)wolfGameItemCount(av, "wheat")
+ " wheat and " + (string)wolfGameBalance(av) + " coins.", buttons, MENU_CH))
llDialog(av, "Market stall", buttons, MENU_CH); // not a Wolf viewer, or refused
}
listen(integer ch, string name, key av, string msg)
{
integer i = llListFindList(TRADES, [msg]);
if (i == -1 || i % 3 != 0) return;
if (wolfGameExchange(av, parse(llList2String(TRADES, i + 1)), parse(llList2String(TRADES, i + 2)), msg))
wolfGameNotify(av, "Market", msg + " - done.", "success");
else
wolfGameNotify(av, "Market", "Not done: " + wolfGetLastError(), "warning");
}
}
A farm plot that grows wheat (farm_plot.lsl, 123 lines: show or hide)
// Wolf Roleplay example - FARM PLOT. One prim of soil. Owned by the game's owner (or a no-modify
// copy made by them), so it may move the game's items (wolfGameExchange).
//
// touch an empty plot -> plant: takes 1 seed
// touch a growing plot -> water it (rain on the region waters it for you)
// touch a ripe plot -> harvest: 3-5 wheat and 1-2 seeds back
//
// The crop survives a region restart: its state is kept in linkset data, and growth is worked
// out from the time it was planted, not counted by a timer. Left dry for longer than DRY_SECONDS
// it withers and the seed is lost.
integer GROW_SECONDS = 1800; // each of the two growing stages
integer DRY_SECONDS = 2700; // how long it can go without water
vector SOIL = <0.36, 0.25, 0.16>;
vector SPROUT = <0.45, 0.70, 0.25>;
vector RIPE = <0.85, 0.72, 0.30>;
vector DEAD = <0.40, 0.38, 0.30>;
integer gMenu;
integer MENU_CH;
string lsd(string k) { return llLinksetDataRead(k); }
put(string k, string v) { llLinksetDataWrite(k, v); }
// 0 empty, 1 seedling, 2 growing, 3 ripe, 4 withered
integer stage()
{
integer planted = (integer)lsd("planted");
if (planted == 0) return 0;
if ((integer)lsd("withered")) return 4;
integer now = llGetUnixTime();
if (now - (integer)lsd("watered") > DRY_SECONDS && now - planted < 2 * GROW_SECONDS)
{
put("withered", "1");
return 4;
}
if (now - planted >= 2 * GROW_SECONDS) return 3;
if (now - planted >= GROW_SECONDS) return 2;
return 1;
}
show()
{
integer s = stage();
vector c = SOIL; string t = "Empty plot\nTouch to plant (1 seed)";
if (s == 1) { c = SPROUT; t = "Seedling\nTouch to water"; }
else if (s == 2) { c = SPROUT; t = "Growing\nTouch to water"; }
else if (s == 3) { c = RIPE; t = "Ripe wheat\nTouch to harvest"; }
else if (s == 4) { c = DEAD; t = "Withered - nobody watered it\nTouch to clear"; }
llSetColor(c, ALL_SIDES);
llSetText(t, <1, 1, 1>, 1.0);
}
// Rain on the region waters every plot on it.
checkRain()
{
list w = wolfGetRegionWeather();
integer i = llListFindList(w, ["kind"]);
if (i != -1 && llList2String(w, i + 1) == "rain" && (integer)lsd("planted") && !(integer)lsd("withered"))
put("watered", (string)llGetUnixTime());
}
default
{
state_entry()
{
MENU_CH = -2000000 - (integer)llFrand(1000000);
show();
llSetTimerEvent(60.0);
}
on_rez(integer p) { llResetScript(); }
timer() { checkRain(); show(); }
touch_start(integer n)
{
key av = llDetectedKey(0);
if (!wolfGameIsPlaying(av))
{
llRegionSayTo(av, 0, "Join the game first (Roleplay floater > Join).");
return;
}
integer s = stage();
if (s == 0)
{
// Planting costs one seed - taken in the same step the plot is claimed.
if (!wolfGameExchange(av, ["seed", 1], [], "planted wheat"))
{
llRegionSayTo(av, 0, "You need a wheat seed to plant here (" + wolfGetLastError() + ").");
return;
}
put("planted", (string)llGetUnixTime());
put("watered", (string)llGetUnixTime());
put("farmer", (string)av);
put("withered", "0");
}
else if (s == 1 || s == 2)
{
put("watered", (string)llGetUnixTime());
llRegionSayTo(av, 0, "Watered.");
}
else if (s == 3)
{
integer wheat = 3 + (integer)llFrand(3.0);
integer seeds = 1 + (integer)llFrand(2.0);
if (!wolfGameExchange(av, [], ["wheat", wheat, "seed", seeds], "harvest"))
{
llRegionSayTo(av, 0, "Could not harvest: " + wolfGetLastError());
return;
}
wolfGameNotify(av, "Harvest", "You harvested " + (string)wheat + " wheat and " + (string)seeds + " seeds.", "success");
llLinksetDataReset();
}
else if (s == 4)
{
llLinksetDataReset();
llRegionSayTo(av, 0, "Cleared. Plant again with a seed.");
}
show();
}
}
A pet shop (pet_shop.lsl, 57 lines: show or hide)
// Wolf Roleplay example - PET SHOP. Owned by the game's owner. Put a no-modify copy of the pet
// object ("Wolf pup", with pet.lsl inside, made by the game's owner) in this prim's inventory.
//
// Buying: 100 coins, then a pet record on the grid (wolfGamePetCreate) and the pet object. The
// object finds its own record the first time it is rezzed (pet.lsl), so the pet's name, age and
// hunger stay with the pet - not with one copy of the object.
integer PRICE = 100;
string PET_OBJECT = "Wolf pup";
integer MENU_CH;
integer gMenu;
key gBuyer;
default
{
state_entry()
{
MENU_CH = -4000000 - (integer)llFrand(1000000);
llSetText("Pet shop\nWolf pup - " + (string)PRICE + " coins\nTouch to buy", <1, 1, 1>, 1.0);
}
touch_start(integer n)
{
key av = llDetectedKey(0);
if (!wolfGameIsPlaying(av)) { llRegionSayTo(av, 0, "Join the game first."); return; }
gBuyer = av;
llListenRemove(gMenu);
gMenu = llListen(MENU_CH, "", av, "");
llTextBox(av, "Name your wolf pup (" + (string)PRICE + " coins):", MENU_CH);
}
listen(integer ch, string name, key av, string msg)
{
if (av != gBuyer) return;
llListenRemove(gMenu);
string petName = llStringTrim(msg, STRING_TRIM);
if (petName == "") petName = "Pup";
// Pay first; if the pet cannot be made, the money goes back.
if (!wolfGameExchange(av, ["$", PRICE], [], "bought a wolf pup"))
{
wolfGameNotify(av, "Pet shop", "Not bought: " + wolfGetLastError(), "warning");
return;
}
string pet = wolfGamePetCreate(av, "wolf_pup", petName, ["colour", "grey"]);
if (pet == "")
{
string why = wolfGetLastError();
wolfGameExchange(av, [], ["$", PRICE], "refund - pet not made");
wolfGameNotify(av, "Pet shop", "Refunded: " + why, "warning");
return;
}
llGiveInventory(av, PET_OBJECT);
wolfGameNotify(av, "Pet shop", petName + " is yours. Rez the Wolf pup from your inventory.", "success");
}
}
The pet object (pet.lsl, 107 lines: show or hide)
// Wolf Roleplay example - THE PET OBJECT ("Wolf pup"). Made by the game's owner, given no-modify,
// so this script may change its own owner's pet (it counts as the game's own item).
//
// The pet itself lives on the grid; this object only shows it. The first time it is rezzed it
// takes the owner's newest pet of this type that no object has claimed yet, and keeps that pet
// key in linkset data, so the same pet comes back every time it is rezzed.
//
// touch: Feed (1 pet food), Play, Rename, Status
string TYPE = "wolf_pup";
integer MENU_CH;
integer gMenu;
integer gRename;
string pet() { return llLinksetDataRead("pet"); }
// The owner's pets of this type that are alive: the newest one this object can take.
claim()
{
list pets = wolfGamePets(llGetOwner()); // [key, type, name, alive, ...]
integer i;
string chosen = "";
for (i = 0; i < llGetListLength(pets); i += 4)
if (llList2String(pets, i + 1) == TYPE && llList2Integer(pets, i + 3))
chosen = llList2String(pets, i); // the list is oldest first; keep the newest
if (chosen != "") llLinksetDataWrite("pet", chosen);
}
show()
{
if (pet() == "") { llSetText("No pet - buy one at the pet shop", <1, 0.6, 0.6>, 1.0); return; }
list p = wolfGamePetGet(pet()); // [type, name, owner, alive, age, stat, v, m, ...]
if (p == [])
{
llSetText("(" + wolfGetLastError() + ")", <1, 0.6, 0.6>, 1.0);
return;
}
if (llList2String(p, 2) != (string)llGetOwner())
{
// Given or sold to someone else since: this copy no longer shows that pet.
llLinksetDataDelete("pet");
llSetText("This pet belongs to someone else now", <1, 0.6, 0.6>, 1.0);
return;
}
string t = llList2String(p, 1);
if (!llList2Integer(p, 3)) t += " (died)";
else
{
integer days = llList2Integer(p, 4) / 86400;
t += " - " + (string)days + " day" + llList2String(["s", ""], days == 1);
integer i;
for (i = 5; i < llGetListLength(p); i += 3)
t += "\n" + llList2String(p, i) + " " + (string)llList2Integer(p, i + 1) + "/" + (string)llList2Integer(p, i + 2);
}
llSetText(t, <1, 1, 1>, 1.0);
}
default
{
state_entry()
{
MENU_CH = -5000000 - (integer)llFrand(1000000);
if (pet() == "") claim();
show();
llSetTimerEvent(120.0);
}
on_rez(integer p) { llResetScript(); }
changed(integer c) { if (c & CHANGED_OWNER) { llLinksetDataReset(); llResetScript(); } }
timer() { show(); }
touch_start(integer n)
{
key av = llDetectedKey(0);
if (av != llGetOwner()) return;
llListenRemove(gMenu);
gMenu = llListen(MENU_CH, "", av, "");
llDialog(av, "Your wolf pup", ["Feed", "Play", "Rename", "Status"], MENU_CH);
}
listen(integer ch, string name, key av, string msg)
{
if (ch == MENU_CH + 1)
{
llListenRemove(gRename);
if (!wolfGamePetRename(pet(), llStringTrim(msg, STRING_TRIM))) llOwnerSay(wolfGetLastError());
}
else if (msg == "Feed")
{
// One pet food, taken from the owner's game items, then +30 food for the pup.
if (!wolfGameExchange(av, ["pet_food", 1], [], "fed the pup")) llOwnerSay("No pet food: " + wolfGetLastError());
else if (!wolfGamePetAddStat(pet(), "hunger", 30)) llOwnerSay(wolfGetLastError());
}
else if (msg == "Play")
{
if (!wolfGamePetAddStat(pet(), "happiness", 20)) llOwnerSay(wolfGetLastError());
else llSetTimerEvent(120.0);
}
else if (msg == "Rename")
{
gRename = llListen(MENU_CH + 1, "", av, "");
llTextBox(av, "New name:", MENU_CH + 1);
}
show();
}
}
Some example comments mention a Roleplay section in the control panel. It is not on the website yet; everything it would do can be done from these scripts.
Events: wolfGameListen
wolfGameListen(channel) sends the game’s events to your script as chat on that channel, from the game’s name and key (0 stops them). A game script hears every player, so check the avatar in each message; a worn object hears only its wearer’s.
| Message | When |
|---|---|
| join|av | A player joins. |
| arrive|av | A player is now playing on this region: set up their action bar. |
| leave|av | A player leaves. |
| death|av|killer|cause | A player dies. |
| respawn|av | A player comes back. |
| zero|av|stat | A stat reached its minimum. |
| pay|from|to|amount | One player paid another. |
| item|av|item|+n | A player's item count changed. |
| equip|av|slot|item and unequip|av|slot|item | Equipment changed. |
| target|av|key | A player picked a target. |
| buffend|av|id | A buff or debuff ran out. |
Webhooks. With a webhook set, the grid also posts each event (except target changes) to your server as JSON: event, game, region, regionName, agent, extra and time. With a webhooksecret the post carries X-Wolf-Game-Time (unix seconds) and X-Wolf-Game-Sig, the hex HMAC-SHA256 of the time, a newline and the body, so your server can tell it came from the grid.
Who may do what
- A worn script may drive its own wearer’s screen, and may join its wearer to the game.
- A script whose owner holds the region may run the region’s game and drive the screen of anyone playing it there.
- The game’s own scripts (its owner’s, and those registered with
wolfGameTrustScript) may act on anyone playing it; money, items and pets move only for them. wolfGameForceMode(TRUE)keeps Game Mode on for everyone on the region (the region’s holder, or a grid god). It never changes anyone’s own saved choice.
Combat
Fighting, spells and guns. The region checks every press of an action button (its cooldown, cast time, ammunition and cost) before your script hears it, so a modified viewer cannot fire faster or for free.
Weapons and armour
- Slots: weapons in
main,offandranged; armour inhead,body,hands,legs,feet,neck,ring(andofffor a shield). - Define them as items with a
kind("weapon", "armour", "spell", "consumable", "material") and aslot. Weapons can showdamage,range,firemode,magazineand theirammoitem, and betwohandinmain; armour showsdefence. These are for display: your scripts decide the real numbers. - Players equip from the Bag tab; scripts with
wolfGameEquip/wolfGameUnequip, and read it withwolfGameLoadout.
The action bar
wolfGameSetAbility(avatar, id, rules) puts a button on the player’s bar (at most 12): label, icon, cooldown, cast, cost and amount, key, enabled, group (a shared cooldown), weapon and ammo, target (1 = needs one), order and channel. A press comes back on the channel from the avatar’s key under the name #wolfgame, which no viewer can chat under:
Hearing the presses
llListen(channel, "#wolfgame", avatar, "");
// then: "cast|id|target", "use|id|target", "interrupted|id"| Function | What it shows or does |
|---|---|
| wolfGameCooldown / wolfGameInterrupt | Start (or end) a cooldown; stop a cast in progress. |
| wolfGameSetGear / wolfGameSetAmmo / wolfGameReload / wolfGameGetAmmo | What a weapon slot shows, its magazine and reserve, a reload bar. |
| wolfGameSetTarget / wolfGameGetTarget / wolfGameTargetHealth | The target frame: name, health, level, hostility (hostile, neutral, friendly), icon, subtitle. |
| wolfGameAddBuff / wolfGameRemoveBuff | Buffs and debuffs with an icon, time, stacks and text (at most 20). |
| wolfGameCombatText | A floating number over the target or the player: hit, crit, heal, miss, dodge, block, immune or absorb. |
| wolfGameDamage / wolfGameHeal / wolfGameKill / wolfGameRespawn | Health, death and coming back. |
| wolfGameEffect | flash, pulse, blur, blackout, desaturate, shake or clear. |
Combat setup: mana, a sword, a rifle and its rounds, armour, trusted scripts (combat_setup.lsl, 54 lines: show or hide)
// Wolf Roleplay example - COMBAT SETUP (run once by the game's owner on a region running their
// game). Defines the mana stat, the weapons and armour the two combat examples use, and registers
// those two scripts as the game's OWN (wolfGameTrustScript) - only the game's own scripts may hurt
// players, take mana, and move ammunition.
//
// Put copies of "combat_sword_and_spell" and "combat_gun" in THIS object's inventory first: a
// script is trusted by its asset, and a copy has the same asset as long as nobody edits it.
// Everything here can also be done from the control panel's Roleplay section.
// TRUE makes this region an arena: Game Mode stays on for everyone here, so nobody can switch it
// off to avoid a fight (their own saved choice is untouched; it applies again when they leave).
// FALSE leaves the region as it is - it never turns off forcing set from the control panel;
// wolfGameForceMode(FALSE) does that.
integer FORCE_GAME_MODE = FALSE;
say(string what, integer ok)
{
if (ok) llOwnerSay(what + ": OK");
else llOwnerSay(what + ": REFUSED - " + wolfGetLastError());
}
default
{
touch_start(integer n)
{
if (llDetectedKey(0) != llGetOwner()) return;
if (wolfGameKey() == "") { llOwnerSay("This region runs no game - wolfGameCreate first."); return; }
// Mana: spells cost it, it comes back 6 a minute. The region TAKES the cost of an
// ability set by the game's own script, so the spell script never counts mana itself.
say("stat mana", wolfGameDefineStat("mana",
["label", "Mana", "min", 0, "max", 100, "start", 100, "rate", 6, "colour", "#3b82f6", "order", 3]));
// Weapons and armour. The damage/range/firemode/defence are what the weapons panel SHOWS;
// the scripts decide the real numbers.
say("item sword", wolfGameDefineItem("sword",
["label", "Iron sword", "kind", "weapon", "slot", "main", "damage", "12-18", "range", "3 m",
"firemode", "melee", "max", 1, "order", 10]));
say("item rifle_ammo", wolfGameDefineItem("rifle_ammo",
["label", "Rifle rounds", "kind", "consumable", "max", 600, "order", 12]));
say("item rifle", wolfGameDefineItem("rifle",
["label", "Hunting rifle", "kind", "weapon", "slot", "ranged", "damage", "8-12", "range", "100 m",
"firemode", "semi-auto", "magazine", 30, "ammo", "rifle_ammo", "max", 1, "order", 11]));
say("item leather", wolfGameDefineItem("leather",
["label", "Leather jerkin", "kind", "armour", "slot", "body", "defence", "5", "max", 1, "order", 13]));
// The two worn weapon scripts are the game's own.
say("trust combat_sword_and_spell", wolfGameTrustScript("combat_sword_and_spell"));
say("trust combat_gun", wolfGameTrustScript("combat_gun"));
if (FORCE_GAME_MODE) say("force Game Mode", wolfGameForceMode(TRUE));
}
}
A sword and two spells, with cooldowns, a cast bar, damage numbers and buffs (combat_sword_and_spell.lsl, 180 lines: show or hide)
Download combat_sword_and_spell.lsl
// Wolf Roleplay example - SWORD AND SPELLS. Worn (a sword attachment, or a HUD). Registered as
// one of the game's own scripts by combat_setup, so the region lets it hurt players and takes the
// mana its spells cost.
//
// What the player sees, in their Wolf viewer:
// - an action bar: 1 Slash (melee, needs the sword equipped), 2 Fireball (1.5 s cast, 20 mana,
// leaves a Burning debuff), 3 Mend (2 s cast, 30 mana, heals and gives a Mended buff);
// - real cooldown sweeps, a cast bar, floating damage numbers and a hit marker;
// - the target frame (they pick a target by selecting an avatar).
// The REGION checks every press - cooldown, cast, mana - and takes the mana; this script is told
// on its channel from the wearer's key under the name "#wolfgame": "cast|id|target", "use|id|target", "interrupted|id".
// Slash and Fireball need a target: without one the region says "No target" and takes nothing.
string ICON_SLASH = ""; // texture keys for the buttons ("" shows the label's letters)
string ICON_FIREBALL = "";
string ICON_MEND = "";
string ICON_BURNING = "";
string ICON_MENDED = "";
float SWORD_RANGE = 3.5;
float SPELL_RANGE = 40.0;
integer gChannel; // ability uses come back here
integer gEvents; // the game's events about the wearer (wolfGameListen)
integer gUseListen;
integer gEventListen;
key gWearer;
list gBurning; // [target, seconds left, ...] - Fireball's damage over time
setup()
{
gWearer = llGetOwner();
llListenRemove(gUseListen);
llListenRemove(gEventListen);
gUseListen = llListen(gChannel, "#wolfgame", gWearer, ""); // "#wolfgame": only the region, never a viewer, sends under that name
gEventListen = llListen(gEvents, "", NULL_KEY, "");
// A worn object hears its own wearer's game events: equip/unequip, arrive, death.
wolfGameListen(gEvents);
showBar();
}
integer armed()
{
return llListFindList(wolfGameLoadout(gWearer), ["main", "sword"]) != -1;
}
showBar()
{
// A screen is per region: this runs on attach, on every region change and on "arrive".
wolfGameSetAbility(gWearer, "slash", ["label", "Slash", "icon", ICON_SLASH, "cooldown", 1.5,
"key", "1", "enabled", armed(), "target", 1, "channel", gChannel, "order", 1]);
wolfGameSetAbility(gWearer, "fireball", ["label", "Fireball", "icon", ICON_FIREBALL, "cooldown", 6.0,
"cast", 1.5, "cost", "mana", "amount", 20, "key", "2", "target", 1, "channel", gChannel, "order", 2]);
wolfGameSetAbility(gWearer, "mend", ["label", "Mend", "icon", ICON_MEND, "cooldown", 15.0,
"cast", 2.0, "cost", "mana", "amount", 30, "key", "3", "group", "heals", "channel", gChannel, "order", 3]);
}
clearBar()
{
wolfGameRemoveAbility(gWearer, "slash");
wolfGameRemoveAbility(gWearer, "fireball");
wolfGameRemoveAbility(gWearer, "mend");
}
// Hurt `target` (a player of the game here, within `range`) by lo..hi, 1 in 10 a critical hit.
// Both screens get it: a number over the target and a hit marker for the attacker, a number
// over themselves and a red flash for the target.
integer strike(key target, integer lo, integer hi, float range, string cause, string colour)
{
if (target == NULL_KEY) return FALSE; // the region refuses "No target" before this
list d = llGetObjectDetails(target, [OBJECT_POS]);
if (d == [] || llVecDist(llList2Vector(d, 0), llGetPos()) > range)
{
wolfGameCombatText(gWearer, target, 0, "miss", "");
return FALSE;
}
if (!wolfGameIsPlaying(target))
{
wolfGameCombatText(gWearer, target, 0, "immune", "");
return FALSE;
}
integer dmg = lo + (integer)llFrand(hi - lo + 1);
string kind = "hit";
if (llFrand(1.0) < 0.1) { dmg *= 2; kind = "crit"; }
if (!wolfGameDamage(target, dmg, cause)) { llOwnerSay(cause + ": " + wolfGetLastError()); return FALSE; }
wolfGameCombatText(gWearer, target, dmg, kind, colour);
wolfGameCombatText(target, target, dmg, kind, colour);
wolfGameEffect(target, "flash", 35, 0.4);
return TRUE;
}
default
{
state_entry()
{
gChannel = -7000000 - (integer)llFrand(1000000);
gEvents = gChannel - 1;
if (llGetAttached()) setup();
}
attach(key id)
{
if (id != NULL_KEY) llResetScript();
else clearBar();
}
changed(integer c)
{
if (c & CHANGED_REGION) setup();
if (c & CHANGED_OWNER) llResetScript();
}
listen(integer ch, string name, key id, string msg)
{
list p = llParseStringKeepNulls(msg, ["|"], []);
string what = llList2String(p, 0);
if (ch == gEvents)
{
// From the game: "equip|av|slot|item", "unequip|av|slot|item", "arrive|av", ...
// A game script hears EVERY player's events: only the wearer's are this sword's.
if ((key)llList2String(p, 1) != gWearer) return;
if (what == "arrive") showBar();
else if ((what == "equip" || what == "unequip") && llList2String(p, 3) == "sword")
wolfGameSetAbility(gWearer, "slash", ["enabled", what == "equip"]);
return;
}
// From the region, as the wearer: the ability presses it has already checked.
string ability = llList2String(p, 1);
key target = (key)llList2String(p, 2);
if (what == "use")
{
if (ability == "slash")
strike(target, 12, 18, SWORD_RANGE, "sword", "");
else if (ability == "fireball")
{
if (strike(target, 25, 35, SPELL_RANGE, "fireball", "#ff7a1a"))
{
// Burning: 3 damage a second for 6 s, shown on the target's buff bar.
wolfGameAddBuff(target, "burning", ["label", "Burning", "icon", ICON_BURNING, "seconds", 6,
"type", "debuff", "text", "Takes 3 fire damage a second."]);
integer i = llListFindList(gBurning, [target]);
if (i == -1) gBurning += [target, 6];
else gBurning = llListReplaceList(gBurning, [6], i + 1, i + 1);
llSetTimerEvent(1.0);
}
}
else if (ability == "mend")
{
if (wolfGameHeal(gWearer, 30))
{
wolfGameCombatText(gWearer, gWearer, 30, "heal", "");
wolfGameAddBuff(gWearer, "mended", ["label", "Mended", "icon", ICON_MENDED, "seconds", 10,
"type", "buff", "text", "Recently healed."]);
}
}
}
// "cast|id|target" (a cast began) and "interrupted|id" (it was stopped) also arrive here:
// the place to start and stop a casting animation, which this example does not have.
}
timer()
{
list keep;
integer i;
for (i = 0; i < llGetListLength(gBurning); i += 2)
{
key t = llList2Key(gBurning, i);
integer left = llList2Integer(gBurning, i + 1) - 1;
if (wolfGameIsPlaying(t) && wolfGameDamage(t, 3, "burning"))
{
wolfGameCombatText(gWearer, t, 3, "hit", "#ff7a1a");
wolfGameCombatText(t, t, 3, "hit", "#ff7a1a");
}
if (left > 0) keep += [t, left];
}
gBurning = keep;
if (gBurning == []) llSetTimerEvent(0.0);
}
}
A rifle with a magazine, reserve and reload (combat_gun.lsl, 189 lines: show or hide)
// Wolf Roleplay example - A GUN WITH AMMO AND RELOAD. Worn (the rifle attachment). Registered as
// one of the game's own scripts by combat_setup, so the region lets it hurt players and move the
// rifle_ammo item.
//
// What the player sees, in their Wolf viewer:
// - the rifle on their weapons panel (from the equipped "rifle" item: name, damage, range,
// fire mode) with its magazine "24 / 30" and reserve, and a reload bar;
// - action bar: 4 Fire (one round), 5 Aimed shot (1.2 s cast, three rounds, always critical);
// - R (or the Reload button) reloads; firing on an empty magazine asks for a reload by itself.
//
// WHO COUNTS WHAT. The magazine is on the player's screen and the REGION takes the rounds each shot
// uses, refusing "Out of ammo - reload" when there are too few. The reserve is the player's
// "rifle_ammo" item on the grid: a reload takes rounds from it with wolfGameItemTake, so ammunition
// bought, looted or traded is the same everywhere.
integer MAGAZINE = 30;
float RELOAD_SECONDS = 2.5;
float RANGE = 100.0;
string ICON_FIRE = ""; // texture keys for the buttons ("" shows the label's letters)
string ICON_AIMED = "";
integer gChannel;
integer gEvents;
integer gUseListen;
integer gEventListen;
key gWearer;
integer gMag; // rounds in the magazine, as this script last set or read them
integer gReloading;
integer equipped()
{
return llListFindList(wolfGameLoadout(gWearer), ["ranged", "rifle"]) != -1;
}
integer reserve()
{
return wolfGameItemCount(gWearer, "rifle_ammo");
}
setup()
{
gWearer = llGetOwner();
llListenRemove(gUseListen);
llListenRemove(gEventListen);
gUseListen = llListen(gChannel, "#wolfgame", gWearer, ""); // "#wolfgame": only the region, never a viewer, sends under that name
gEventListen = llListen(gEvents, "", NULL_KEY, "");
wolfGameListen(gEvents);
if (equipped()) arm();
else disarm();
}
arm()
{
// A screen is per region, so the magazine is set again on every arrival from this script's count.
wolfGameSetGear(gWearer, "ranged", ["channel", gChannel, "magazine", MAGAZINE]);
wolfGameSetAmmo(gWearer, "ranged", gMag, reserve());
wolfGameSetAbility(gWearer, "fire", ["label", "Fire", "icon", ICON_FIRE, "cooldown", 0.2,
"weapon", "ranged", "ammo", 1, "key", "4", "channel", gChannel, "order", 4]);
wolfGameSetAbility(gWearer, "aimed", ["label", "Aimed shot", "icon", ICON_AIMED, "cooldown", 5.0,
"cast", 1.2, "weapon", "ranged", "ammo", 3, "key", "5", "target", 1, "channel", gChannel, "order", 5]);
}
disarm()
{
wolfGameRemoveAbility(gWearer, "fire");
wolfGameRemoveAbility(gWearer, "aimed");
wolfGameSetGear(gWearer, "ranged", []);
}
// The magazine as the region has it now (it takes the rounds of every shot).
readMagazine()
{
list a = wolfGameGetAmmo(gWearer, "ranged");
if (a != [] && llList2Integer(a, 0) >= 0) gMag = llList2Integer(a, 0);
}
startReload()
{
if (gReloading) return;
readMagazine();
if (gMag >= MAGAZINE) return;
if (reserve() <= 0)
{
wolfGameNotify(gWearer, "Rifle", "No rifle rounds left.", "warning");
return;
}
gReloading = TRUE;
wolfGameReload(gWearer, "ranged", RELOAD_SECONDS); // the bar, and no firing meanwhile
llSetTimerEvent(RELOAD_SECONDS);
}
// One shot: at the target when there is one (and it is in the line of fire), else straight ahead.
shoot(key target, integer lo, integer hi, integer crit)
{
vector from = llGetPos() + <0.0, 0.0, 0.6>;
vector dir = llRot2Fwd(llGetRootRotation());
if (target != NULL_KEY)
{
list d = llGetObjectDetails(target, [OBJECT_POS]);
if (d != []) dir = llVecNorm(llList2Vector(d, 0) - from);
}
list hit = llCastRay(from + dir * 0.6, from + dir * RANGE, [RC_REJECT_TYPES, RC_REJECT_LAND, RC_MAX_HITS, 1]);
key victim = llList2Key(hit, 0);
if (llList2Integer(hit, -1) < 1 || victim == gWearer || !wolfGameIsPlaying(victim))
{
if (target != NULL_KEY) wolfGameCombatText(gWearer, target, 0, "miss", "");
return;
}
integer dmg = lo + (integer)llFrand(hi - lo + 1);
string kind = "hit";
if (crit) { dmg *= 2; kind = "crit"; }
if (!wolfGameDamage(victim, dmg, "rifle")) { llOwnerSay("rifle: " + wolfGetLastError()); return; }
wolfGameCombatText(gWearer, victim, dmg, kind, "");
wolfGameCombatText(victim, victim, dmg, kind, "");
wolfGameEffect(victim, "flash", 30, 0.3);
}
default
{
state_entry()
{
gChannel = -8000000 - (integer)llFrand(1000000);
gEvents = gChannel - 1;
gMag = MAGAZINE; // a new rifle comes loaded
if (llGetAttached()) setup();
}
attach(key id)
{
if (id != NULL_KEY) setup();
else disarm();
}
changed(integer c)
{
if (c & CHANGED_REGION) setup();
if (c & CHANGED_OWNER) llResetScript();
}
listen(integer ch, string name, key id, string msg)
{
list p = llParseStringKeepNulls(msg, ["|"], []);
string what = llList2String(p, 0);
if (ch == gEvents)
{
// A game script hears EVERY player's events: only the wearer's are this rifle's.
if ((key)llList2String(p, 1) != gWearer) return;
if (what == "arrive") setup();
else if (llList2String(p, 3) == "rifle" && llList2String(p, 2) == "ranged")
{
if (what == "equip") arm();
else if (what == "unequip") disarm();
}
// Rounds bought, looted or traded show at once as the reserve.
else if (what == "item" && llList2String(p, 2) == "rifle_ammo" && equipped() && !gReloading)
{
readMagazine();
wolfGameSetAmmo(gWearer, "ranged", gMag, reserve());
}
return;
}
if (what == "reload" && llList2String(p, 1) == "ranged") { startReload(); return; }
if (what != "use") return;
string ability = llList2String(p, 1);
key target = (key)llList2String(p, 2);
if (ability == "fire") shoot(target, 8, 12, FALSE);
else if (ability == "aimed") shoot(target, 10, 14, TRUE);
readMagazine();
}
timer()
{
llSetTimerEvent(0.0);
if (!gReloading) return;
gReloading = FALSE;
readMagazine();
integer have = reserve();
integer take = MAGAZINE - gMag;
if (take > have) take = have;
if (take > 0 && wolfGameItemTake(gWearer, "rifle_ammo", take, "reload"))
{
gMag += take;
have -= take;
}
else if (take > 0) wolfGameNotify(gWearer, "Rifle", "Could not reload: " + wolfGetLastError(), "warning");
wolfGameSetAmmo(gWearer, "ranged", gMag, have); // also ends the reload bar
}
}
Players reload by clicking the weapon on the game bar, or with Reload on the Combat tab. The R key is not used for it: viewers already use R for other things, and the viewer’s own key wins.
External games
A system that already keeps its own stats, money and rules on its own server, such as Knightwood’s KRS, can still use the viewer as its screen. Its worn HUD drives its wearer’s screen; scripts whose owner holds the region drive the screen of anyone playing there. Nothing is kept or ticked by the grid for these:
| To show | Use |
|---|---|
| Bars for your own stats | wolfGameShowStat / wolfGameHideStat |
| Your own money | wolfGameSetCurrencyDisplay(avatar, "KR$", 1500) |
| A level and experience bar | wolfGameSetLevel |
| Notices, dialogs and buttons | wolfGameNotify, wolfGameDialog, wolfGameSetButtons, wolfGameSetPanel |
| Downed, speed, screen effects | wolfGameSetDowned, wolfGameSetSpeed, wolfGameEffect |
| Your own web page in the viewer | wolfGameShowWeb (https only: a panel, an overlay or a window) / wolfGameCloseWeb |
| A sound only that player hears | wolfGameSound |
| Markers, across your regions | wolfGameMarker / wolfGameClearMarker |
| A line under a name tag | wolfGameSetTag |
| Weapons, abilities, targets, buffs, combat text | wolfGameSetGear, wolfGameSetAmmo, wolfGameReload, wolfGameSetAbility (a cost that is not a game stat is shown, never taken), wolfGameSetTarget, wolfGameTargetHealth, wolfGameAddBuff, wolfGameCombatText |
Each player’s screen accepts about 10 messages a second, and anything not from the region’s own game is marked Unverified to the player.
All functions
Every wolfGame function the grid runs, read from the region software. Each links to its page in the LSL Guide.
Roleplay: the game
Make a Wolf Roleplay game for this region, owned by the script's owner, who must hold the region. Rules: name (unique), kind (managed|external), theme (wolves|plain), description, website, rules, logo, currency, symbol, currencyicon (the currency's picture, a texture key), start, playerpay, death (spawn|home|stay), respawn (seconds), spawn (vector - defaults to this object), webhook, webhooksecret, starter (items a player's first join gives, e.g. "meat=3,water=2"). Register the game's own scripts with wolfGameTrustScript. TRUE when created.
Change this region's game (same rules as wolfGameCreate). Only the game's owner.
This region's game as key/value pairs, or an empty list. Includes "forced" (1 when the region forces Game Mode on).
Add or change a stat: label, min, max, start, rate (per minute, + regenerates, - decays), zero (none|die|slow|drain), target and amount (for drain), colour, icon (a texture key; or a short text glyph), visible, order, health (1 = tied to the avatar's health), keep (1 = kept through a respawn: xp, gold). At most 16 stats.
Remove a stat from this region's game.
The names of this region's game stats.
Run an existing game (one you own, or the Wolf Territories default game) on this region.
Stop running a game on this region.
This region's game key, or "" when it runs none.
Where this game's players respawn, on this region.
Receive game events on this channel as chat (from the game's name and key; check the av field - a game script hears every player): join|av, arrive|av (playing on this region now - set up their action bar), leave|av, death|av|killer|cause, respawn|av, zero|av|stat, pay|from|to|amount, item|av|item|+n, equip|av|slot|item, unequip|av|slot|item, target|av|key, buffend|av|id. 0 stops. The region's holder and the game's own scripts hear everyone; a WORN object hears only its own wearer's events.
Roleplay: players, stats and money
Join an avatar to this region's game. The region's holder, the avatar's own worn object, or a game-made item the avatar owns. On a forced region an avatar whose own switch is off is read in as on arrival (playing a moment later) - never re-joined to a game they left.
Take an avatar out of this region's game (their wallet stays).
TRUE when the avatar plays this region's game and is here.
The keys of everyone playing this region's game here.
Every stat back to its start value.
One stat's value. 0 and wolfGetLastError() set when it cannot be read.
Set a stat (held to its min and max). Reaching the minimum runs the stat's zero action.
Add to a stat (negative takes away) - eating, drinking, a stamina drink.
This player's own maximum for a stat - a skill that raises max stamina.
[name, value, max, ...] for every stat.
Take health away. At 0 the player dies and the game respawns them.
Give health back (not to the dead - wolfGameRespawn does that).
Kill the player now.
Bring a dead player back now instead of after the game's respawn time.
The avatar's balance of this game's currency.
Give game currency to a player.
Take game currency from a player; refused when they have too little.
Move game currency from one player to another. The payer's own object, when the game allows players to pay; or the region's holder.
Store a value for this player in this game (class, race, quest step...). "" removes it.
A value stored with wolfGameSetData, or "".
Roleplay: the player's screen
Show a bar on the player's Wolf viewer: name, value, max, colour (#rrggbb), icon (a texture key; or a short text glyph). For games that keep their own stats.
Remove a bar shown with wolfGameShowStat.
Show a balance from your own system on the player's screen ("KR$", 1500). "" hides it.
Show a level and XP bar on the player's screen.
A notice on the player's screen. Type: info, success, warning or danger.
A dialog on the player's Wolf viewer. The button pressed comes back on the channel as chat from the avatar, like llDialog.
Buttons in the player's Roleplay panel: [id, label, id, label...]. A press comes back on the channel as chat from the avatar: the id.
A screen effect: flash, pulse, blur, blackout, desaturate, shake or clear. Strength 0-100, seconds 0-600.
Down (TRUE) or up (FALSE): an overlay on the player's screen, and the region holds them still.
Walking/running speed, 0.1 to 2.0 (1.0 is normal). The region enforces it.
Your own https:// page in the player's viewer: mode panel, overlay or window; width and height 0 for automatic.
Close the page opened by wolfGameShowWeb.
Play a sound that only this player hears (name in this object, or a sound key). Volume 0.0-1.0.
A marker on the player's screen, minimap and world map: id, region ("" = this one), position, label, colour, seconds (0 = until cleared).
Remove a marker ("" removes them all).
A line under the avatar's name tag, seen by everyone using a Wolf viewer. "" removes it.
An information panel in the player's Roleplay floater: title, [label, value, ...].
Roleplay: items and pets
Define a game item (seeds, wheat, bread, lockpicks, a sword): label, icon (a texture key; or a short text glyph), max (per player, 0 = no limit), order; kind ("" | weapon | armour | spell | consumable | material); for weapons and armour a slot (weapons: main, off, ranged; armour: off, head, body, hands, legs, feet, neck, ring) and display stats - damage, range, firemode, magazine, ammo (its ammunition item), twohand (main only), defence. Only the game's owner.
Remove an item's definition (players keep what they hold).
Give a player some of an item. The game's owner or the game's own no-modify items only.
Take some of an item from a player; refused when they have too few.
How many of an item the player holds.
[item, quantity, ...] for everything the player holds.
One atomic swap: take [name, qty, ...] and give [name, qty, ...] - "$" is the game's money. Selling 10 wheat for 50 coins, planting a seed. All or nothing.
Define a pet type (wolf_pup, pony): label, icon (a texture key; or a short text glyph), max (per player, 0 = no limit), order. Only the game's owner.
Remove a pet type no pet still has.
A pet type's stat: label, min, max, start, rate (per minute, keeps running while the pet is in inventory), zero (none|die), colour, icon (a texture key; or a short text glyph), order.
Remove a stat from a pet type.
A new pet for a player (a pet shop, a hatchery, breeding): owner, type, name, [data key, value, ...]. Returns the pet's key - keep it in the pet object (linkset data). "" when refused.
[type, name, owner, alive, age seconds, stat, value, max, ...] - stats as they are NOW, aged by real time.
A value stored with the pet (genes, colour, tricks), or "".
Set a pet stat. The pet owner's own game items, or the game's own items on the game's land.
Add to a pet stat - feeding, playing, grooming.
Store a value with the pet. "" removes it.
Rename a pet.
Give or sell the pet to another player of the game.
Let the pet go: its record is deleted.
[pet key, type, name, alive, ...] for an avatar's pets in this game.
Roleplay: trusted scripts and forced Game Mode
Register a script in this object as one of the game's OWN scripts (by its asset - an edited copy is not). Only the game's owner. The game's own scripts are the only ones that may change players, money, items and pets.
Take a script in this object off the game's own list.
TRUE keeps Game Mode ON for everyone on this region (they cannot switch it off or leave the game here - "so people dont turn it off to avoid getting killed"); FALSE gives them their own choice back. Never changes anyone's own saved switch. The region's holder or a grid god.
Roleplay: combat
Put an item the player holds into its slot (a weapon or armour item - see wolfGameDefineItem). Kept per player per game. The game's own scripts; players equip from their viewer.
Empty an equipment slot: main, off, ranged, head, body, hands, legs, feet, neck or ring.
[slot, item, ...] - what the player has equipped.
Add or change a button on the player's action bar: label, icon, cooldown (s), cast (s), cost (a stat) and amount, key (hint), enabled, group (shared cooldown), weapon (a slot whose ammo it uses), ammo (rounds per use), target (1 = refused with "No target" when the player has none), order, channel. A press is checked by the region (cooldown, cast, ammo; the cost is TAKEN when the game's own script set it and it is a stat of the game - never down to the minimum of a stat whose emptiness does something, such as health) and comes back on the channel from the avatar's key under the name "#wolfgame" (listen with llListen(channel, "#wolfgame", avatar, "") - no viewer can chat under that name): cast|id|target, use|id|target, interrupted|id. At most 12.
Remove an action-bar button ("" removes them all).
Start an ability's cooldown for this many seconds (0 ends it).
Stop the player's cast in progress (a stun, a hit). Its script hears interrupted|id.
What an equipment slot shows on the player's weapons panel (for games that keep their own weapons): label, icon, damage, range, firemode, defence, ammoname, magazine, ammo, reserve, channel (reload requests come back as reload|slot, from the avatar under the name "#wolfgame"). [] clears it.
A slot's ammo: rounds in the magazine and in reserve (-1 = not shown). Ends a reload. The region takes the rounds an ability uses by itself.
Show a reload on a weapon slot for this many seconds (0 stops it); its abilities cannot fire meanwhile. Call wolfGameSetAmmo when it is done.
[ammo, magazine, reserve, reloading] for a slot.
The player's target frame: target key ("" clears), then name, health, max, level, hostility (hostile|neutral|friendly), icon, text (subtitle), dead. With no health, a player of this game shows their live health.
The player's current target, or NULL_KEY. Players pick targets in their viewer; you hear target|av|key.
Update the health bar on the target frame of everyone targeting this key (a monster taking hits).
A buff or debuff on the player's screen: label, icon, seconds (0 = until removed; given again it restarts), stacks, type (buff|debuff), text. At most 20. You hear buffend|av|id when it runs out.
Remove a buff or debuff ("" removes them all).
A floating combat number: over the target `at` (damage dealt, with a hit marker) or over the player (at = the player or "": damage taken). Kind: hit, crit, heal, miss, dodge, block, immune, absorb. Colour #rrggbb or "".