Argo Programmer Guide
3.1 Argo Programming Overview
Argo is meant to be an extensible system. Staff utilities
such as +define go a long way toward allowing staff members
to add things to the system to tailor it to their worlds. However,
inevitably, people will think of worthwhile additions that require
modification or extension of the MUF programs supporting
the system. Argo grew, over a period of several years, in the
process acquiring what might be called a coral-reef architecture... As a
result, adding to or modifying the system isn't trivial, but it is
definitely allowed. If you would like to change or extend Argo,
you are welcome too.
This page provides an overview of how the system hangs together (to
whatever extent it really does hang together)... subsequent pages deal
with more specific issues that you will face as you work with the
code.
What can feasibly be included here is included... But there is no
substitute for diving into the code itself. These pages are meant as an
overview and jumpstart, but adding reliable programs to the system will
also require reading the code of existing Argo program. (Adding
and modifying Argo programs is probably not the place to start
if you are new to MUF programming... spend some time with
the tutorial on MUF in The MUCK
Manual first.)
Programs:
Argo consists of a libary of shared code, lib-argo. Lib-argo
is also the link point of the +install and
+uninstall commands, used to add and remove system
components. These components are for the most part the `asys-' programs:
MUF programs handling either a single Argo command
(asys-sheet, handling the +sheet command, would be an
example), a group of closely related commands (such as the monetary
commands handled by asys-money or the rumor and influence commands
handled by asys-rumors), or a set of `coded effects', which are not
called directly by a command, but are instead invoked by the events
manager (asys-eventmgr), which calls other programs as needed to handle
events in combat, spell casting, and other uses of abilites that trigger
coded effects. These programs called by the event manager are usually
not called directly by any commands: asys-stdspells, which handles
spells cast with the +cast command, would be an example.
Subsequent pages detail the function calls available from lib-argo, and
provide skeleton programs for new commands and coded abilities, along
with discussion of issues related to each.
Data Storage:
All stateful data used by Argo is stored in the
@a/ propdir, either on the room parenting an Argo
realm (if there is only one realm on the MUCK , this will
always be room #0), or on a specific, Argo-enabled object, such
as a player or weapon. System components (installed programs, command
actions) are stored as dbrefs. Within the event system, target objects are
also stored as dbrefs. Elsewhere, objects are stored as reflist strings.
Process IDs, system times and amounts of time that must pass before an
event completes (such as the effects of a spell wearing off or
completion of making an object) are stored as integers. All other data
is stored as strings.
Below is a brief tour of the Argo data propdirs on the
different types of objects. Very few MUCKs will have all
these propdirs... some are created when database entries of a new type
are made for the first time, and some are not applicable to certain
MUCKs (a CyberPunk MUCK probably won't have a
propdir for spells, for example).
Realm Parent Rooms
Room #0 is used as the parent room in all examples.
The name of each property or propdir is
followed by an indicator of its scope: data with a
MUCK -wide scope is stored on room #0, and is the same for
all realms; data with a realm-wide scope is stored on the parent room
for a realm, and only applies within that realm (room #0 can be the
parent of a realm on a MUCK that has multiple subrealms...
in other words, #0 will often hold both MUCK -wide and
realm-wide data).
@a/banks/ (Scope: Realm)
This propdir holds information about banks and accounts within them,
organized by bank name. If no banks have been set up, this propdir will
not exist. If rooms numbers #420 and #1191 had been configured as
locations of BankOne, typing ex
#0=@a/banks/bankone/branches would show:
str /@a/banks/BankOne/branches:#420 #1191
This propdir also holds account information for players, organized by
bank name: if player #123 had deposited 1 large coin and 20 small coins
at BankOne in the global realm, examining the propdir would show the
following:
str /@a/banks/BankOne/123/large_coins:1
str /@a/banks/BankOne/123/smallcoins:20
Argo modifies the branch information with the
+banks command, and the account information with the
+deposit and +withdraw commands. Added
programs can do likewise.
@a/calls/ (Scope: MUCK )
The @a/calls/ propdir is used to store the dbrefs of
programs that should be called in order to handle various events. As
such, it is most often referenced by asys-eventmgr. An example: if the
asys-thieves command, which handles the Lockpicking skill, has dbref
#321, typing ex #0=@a/calls/uselockpicking will display:
ref
/@a/calls/uselockpicking/asys-thieves:asys-thieves(#321FWM3)
The `use' prefix tells Argo that this is for skill
named `lockpicking', rather than an ability of another type; the dbref
indicates the program to call when players invoke the skill with
+use lockpicking . Working with these program calls is
discussed in more detail in later sections of the Programmer Guide.
@a/cat_list/ (Scope: MUCK )
This propdir holds the display names of databse categories, such as
@a/cat_list/npcs:NPC . It is referenced when showing the
categories available for viewing, with commands such as
+list , or modified with commands such as
+define .
The category list is stored on all realm parent rooms... so, while it
may be referenced as though it exists at a realm-wide scope, categories
should be the same throughout the MUCK .
@a/cg_locs (Scope: MUCK )
This property (not propdir) holds a reflist of all configured character
generation rooms.
@a/comm_list/ (Scope: MUCK )
The @a/comm_list/ propdir holds the dbrefs of Argo
command actions, organized by command name. If the command has been
renamed with the +rename command, the value of the original
command name will be not the dbref of the command action, but a `go to'
string providing a cross reference to the current property holding the
command dbref. For example, if the +vote command had been
renamed to vote , but the +will command had not
been renamed, the @a/comm_list/ propdir would contain the
following:
@a/comm_list/+vote:go to vote
@a/comm_list/+will:+will(#343E)
@a/comm_list/vote:vote:(#409E)
The command list directory is used to display command names with
commands such as +list , and to help ensure that
no-longer-needed Argo commands are recycled when a program is
uninstalled. New Argo command programs will need to add
themselves to this list when they are installed, and remove themselves
when uninstalled; the skeleton programs discussed later in the Guide
include functions for doing this.
@a/creatures/ (Scope: Realm)
This propdir holds the abilities and levels for all creatures defined in
the realm's database. Each creature type's entry is organized much like
an individual player's @a/ propdir, as discussed below.
@a/dataobj (Scope: Realm)
This property (not propdir) servers two purposes. Its existence on a
room indicates that this is the parent room object holding the data for
a realm. The value of the property is the name of the realm:
@a/dataobj:Global
So, this property, on room #0, indicates that #0 is the parent of a
realm named `Global'.
@a/dis-ad/ (Scope: Realm)
The @a/dis-ad/ propdir holds information about all defined
advantages and disadvantages. The value of an advantage will be a
positive integer; the value of a disadvantage will be a negative
integer. Triggered effects are stored in a list, named `trigs', under
the named dis-ad. For example, if the Anemic disadvantage had a value of
1 point, and a triggered effect of reducing the Constitution stat by
one, the propdir would contain the following:
str @a/dis-ad/Anemic/:-1
str @a/dis-ad/Anemic/trigs#/:1
str @a/dis-ad/Anemic/trigs#/1:stats,con,-1
This format for storing an ability modification or requirement,
stats,con,-1 or
<category>/<instance>/<level> is used in
a number of places in the database.
@a/docs/ (Scope: MUCK )
This propdir holds all documents in the online manual, organized as
lists named for the document topic. Directly modifying
the contents of this propdir is not recommended: use +man
#edit to change the manual's contents.
@a/dtemp (Scope: MUCK )
This propdir holds temporary data used when defining objects. New
Argo programs will seldom need to access or modify its contents
directly.
@a/groups/ (Scope: Realm)
The groups propdir simply holds an integer string indicating the minimum
status level required to belong to a group. The status level is used
when players try to join a group by using the +skills
command to acquire the relevant Influence skill... A more common use of
the directory is to loop through its properties to obtain a list of all
currently defined groups.
@a/jobs (Scope: Realm)
This propdir holds the data defining a job... for example, `Blacksmith':
str @a/jobs/Blacksmith/hmod:0
str @a/jobs/Blacksmith/injchance:2
str @a/jobs/Blacksmith/injdam:1d6
str @a/jobs/Blacksmith/preqs#/1:skills,smith,1
str @a/jobs/Blacksmith/preqs#/:1
str @a/jobs/Blacksmith/salary:10
The hmod property is the hiring modifier.
Injchance and injdam are the chance for
on-the-job injury and the amount of damage taken when injured,
respectively. The preqs list contains ability sets, in the
standard format (<category>/<instance>/<level>),
defining the qualifications for the job. The salary
property is the job's salary, in small coins.
@a/objects/ (Scope: Realm)
This propdir contains the definition data for all objects. Conceivably,
new Argo programs will need to modify this data directly. More
commonly, the directory will be referenced to determine the qualities of
an object (very few Argo properties are stored on the objects
themselves: whenever possible, the property is not copied to
the object... instead, the realm's @a/objects/ propdir is
accessed, using the object's @a/name property as a key. This
allows modifications of object definitions to retroactively apply to
existing instances of an object, and saves a bit of database space).
Object definitions are one of the more complicated structures. For
example, the standard Broadsword:
str @a/objects/Broadsword/class/melee weapons:1
str @a/objects/Broadsword/class/swords:1
str @a/objects/Broadsword/class/weapons:1
str @a/objects/Broadsword/combat/bable:1
str @a/objects/Broadsword/combat/dable:1
str @a/objects/Broadsword/combat/dam:2d6
str @a/objects/Broadsword/combat/hands:1
str @a/objects/Broadsword/combat/minstr:12
str @a/objects/Broadsword/combat/pable:1
str @a/objects/Broadsword/combat/parry:1
str @a/objects/Broadsword/combat/skills/swords:1
str @a/objects/Broadsword/combat/type:conventional
str @a/objects/Broadsword/cost:80
str @a/objects/Broadsword/create/materials/steel:6
str @a/objects/Broadsword/create/prereqs/skills/armorer:1
str @a/objects/Broadsword/create/prereqs/skills/swords:1
str @a/objects/Broadsword/create/rolls/skills/armorer:0
int @a/objects/Broadsword/create/time:172800
str @a/objects/Broadsword/create/tools/forge tools:1
str @a/objects/Broadsword/desc#/1:A straight-bladed....
str @a/objects/Broadsword/desc#/:1
str @a/objects/Broadsword/name:Broadsword
str @a/objects/Broadsword/repair/skills/armorer:1
int @a/objects/Broadsword/repair/time:7200
str @a/objects/Broadsword/repair/tools/forge tools:1
The subdirectories directly beneath the object name (`Broadsword' in
this case) contain data pertaining to a specific use of the object: the
class subdirectory holds the object classes instantiated by the object;
the combat directory holds values refrenced by the combat system; the
create and repair directories hold information needed by the
+make and +repair commands.
Some notes about properties in the combat directory: a true value for
bable indicates that the weapon can be blocked,
dable indicates that it can be dodged, and
pable indicates that it can be parried. The true value
stored in the parry property indicates that this weapon can
be used to parry. The dam property is a dice string
indicating the amount of damage done with a successfaul attack. The
skills propdir includes skills that can be invoked to use
the weapon. Minstr is the minimum Strength required to use
the weapon. The value of hands will be 1 or 2, indicating
how many hands are required when using it. The type
property holds the weapon's damage type, which will be `conventional'
for all ordinary weapons.
Note that ability levels specified in the create/ and
repair/ directories are stored in a form that differs from
the `standard' format for recording ability levels mentioned elsewhere
on this page. The reasons for this difference are, um, lost in the mists
of time. One hypothesis: this way works better, but wasn't hit upon
until relatively late in Argo's development, and other programs
that record or read ability levels have not been rewritten to take
advantage of it.
@a/prog_list/ (Scope: MUCK )
This propdir lists installed Argo programs, organized by name
and stored by dbref:
ref /@a/prog_list/asys-active:asys-active(#286FWM3)
ref /@a/prog_list/asys-approve:asys-approve(#289FWM3)
ref /@a/prog_list/asys-approved:asys-approved(#290FWM3)
ref /@a/prog_list/asys-award:asys-award(#291FWM3)
ref /@a/prog_list/asys-background:asys-background(#292FWM3)
(etc.)
Your programs can loop through this directory to obtain a list of all
currently installed Argo programs. It may also be used as a
reliable way to find a particular program: the property will always be
named for the `official' Argo name of the program, even if the
program object itself has been renamed.
@a/psiabs/ (Scope: Realm)
This directory holds the definitions for psionic abilities. For
example...
str /@a/psiabs/Obscure/def:@a/stats/pre
str /@a/psiabs/Obscure/fat:16
str /@a/psiabs/Obscure/preqs#/1:dis-ad,Psionic Aptitude,1
str /@a/psiabs/Obscure/preqs#/2:skills,Mental Discipline,6
str /@a/psiabs/Obscure/preqs#/:2
str /@a/psiabs/Obscure/:int,13,0
The top-level property of this propdir
(@a/psiabls/Obscure ) holds the basic ability definition:
the base stat for the Obscure psionic ability is Intelligence; its
intelligence rating is 13, it doesn't cost any money to learn the
ability. The def property indicates the ability used as a
defence against the psionic ability; the fat property
indicates its fatigue cost. The preqs list holds
definitions for prerequisites required to learn the psiab, in the
standard format.
Note that the ability definition data stored here has nothing to do
with the Obscure ability's coded effects. The data here is created when
the ability is defined, and referenced when the ability is learned and
used. If the ability is used with the generic RP commands
(+prove and +roll ), success or failure will be
displayed, but nothing further will happen. If it is used as part of the
psionics system, with the +focus command, then the psionics
system (asys-psionics) will verify that the user has the ability, the
target is valid, etc., and then call the events manager (asys-eventmgr)
to handle actual execution of the ability. On the user's turn to act,
the event manager will confirm that the ability can be used (target is
still valid, user has enough fatigue, etc.), and will then see if any
other programs have been set up to handle the use of this ability. If
not, control will be returned to asys-psionics, which will treat it as a
`null ability', making any necessary rolls, displaying the results, and
recording the expenditure of 16 points of fatigue. And that's all that
will happen... no changes to the database indicating that the target
object is obscured will be applied.
In order for coded effects to be applied, some program must be
installed, in a way that lets the event manager recognize that it should
be called when this ability is used. In the case of Obscure, there
is such a program... asys-stdpsiabs:
str @a/calls/focusobscure:asys-stdpsiabs(#636FWLM3)
The events manager checks the global @a/calls/ propdir
to determine if another program should be called to handle any
particular event. The property focusobscure indicates that
when the focus command is used with the Obscure
ability, asys-stdpsiabs should be called to handle the event. This
called program may apply any coded effects as needed. Programming Psiabs discusses how to set up
these program calls in more detail.
@a/realms (Scope: MUCK )
This property (not propdir) is a reflist of all realm parent rooms.
@a/recycle (Scope: MUCK )
This property (not propdir) is a reflist of items that should be checked
for recycle times. This and a number of related properties store dbrefs
for items that are due for `high priority checks'... Determinations that
need to be made on a turn-by-turn basis:
@a/stop_listen
@a/relock
@a/reveal
@a/uncontrol
@a/return
@a/recycle
@a/uncontrol
The @a/stop_listen prop records a reflist of objects
which are currently set with a _listen prop, because of
something like the Clairsentience psiab. The @a/relock prop
is a reflist of objects that have their _/lk lock property
reset by Argo, and will need to be returned to their original
lock values. Objects in the @a/reveal reflist are currently
set `hidden' or `invisible'... They need to be checked for when this
effect expires. The @a/recycle reflist holds objects that
will need to be recycled at some point in the near future.
@a/uncontrol holds a reflist of objects usually
puppets which someone can control via the +control
command.
The `rules' for recording these objects along with supporting data
are rather involved and piecemeal... you'll need to grep
through the Argo programs to find examples of how they are used
and study the code in order to duplicate the functionality.
@a/rumors/ (Scope: Realm)
This propdir holds data for existing rumors, organized by group.
str @a/rumors/Underworld/1/instig:#217
str @a/rumors/Underworld/1/status:whispered
str @a/rumors/Underworld/1/:
That guy Hammer's got a soft spot
Rico, the skinny kid who lives over the dry
goods store on
Front street... You wanna put pressure on
Hammer? Squeeze Rico.
str @a/rumors/Underworld/:Word on the street is...
The instig prop is the dbref of the player who started
the roomer; status is the rumor's status (whispered,
muttered, widespread, etc.).
@a/scanner (Scope: MUCK )
This property is the process ID of the system scanner. If
ISPID? returns true for this int, the scanner is running.
@a/skills/Lockpicking/nodef:yes
@a/skills/Lockpicking/tools/lockpicks:1
@a/skills/Lockpicking/:dex,8,0
This is a fairly typical entry for a skill with coded effects. The
top-level prop (@a/skills/Lockpicking:dex,8,0 ) indicates
that the base stat for the skill is Dexterity, that its intelligence
rating is 8, and that it costs no money to learn. It has a true value
for the nodef prop, indicating that it it cannot be rolled
at default values: a player must explicitly know the skill in order to
use it. The value of 1 for tools/lockpicks indicates that
the player must have one intance of an object with the class `lockpicks'
as well.
@a/staff/ (Scope: MUCK )
The @a/staff/ propdir holds information for displaying a
list of the Argo staff:
@a/staff/header#/1:___The Dark Star Rising
Staff_______________________________
@a/staff/header#/:1
@a/staff/members:#2 #517
@a/staff/trailer#/1:____________________________________________________________
@a/staff/trailer#/:1
The header and trailer lists are
information to be shown befor and after the listing of staff members,
respectively, set with the +staff #format command. The
members property is a reflist of staff members, set when
players are added to or removed from the staff roster with +staff
#add and +staff #remove . Note that this reflist is
used only for getting a list of players to show when the
+staff command is used... Argo determines whether
a player has staff privileges by checking for a true value for the
@a/staff property on the player object.
@a/stats/ (Scope: MUCK )
This propdir simply holds the display name of the various stats:
@a/stats/con:Constitution
@a/stats/cra:Craft Skill
@a/stats/dex:Dexterity
@a/stats/int:Intelligence
@a/stats/phy:Physical Skill
@a/stats/pre:Presence
@a/stats/str:Strength
@a/sysparms/ (Scope: Realm)
The @a/sysparms/ propdir holds the system parameters for
the realm, as discussed in Setting System
Parameters.
@a/temp/ (Scope: MUCK )
This propdir hold temporary data, organized by player dbref (for
example, temp data for player #123 would be stored in #0's
@a/temp/123 propdir). Individual player propdirs in
@a/temp/ are routinely written to by Argo
programs, and deleted by the initialization routine called by most
Argo commands. Newly added programs should probably follow this
method. If there's a chance that a player could enter another
Argo command while the data is still needed, use #0's
@a/dtemp/ propdir, and then explicitly delete the data when
you're sure it is no longer needed.
@a/version (Scope: MUCK )
This property holds the version number of the currently installed
Argo system. Numerous programs use the presense of an
@a/version property to verify that an object is
Argo-enabled, and future versions of the system will use this
prop to coordinate sanity checks... So, don't fool around with the
version prop.
@a/vote/ (Scope: MUCK )
This propdir holds data for the player voting system:
int @a/vote/start:966816720
str @a/vote/voted/293:1
str a/vote/votes/517:1
The start property holds the systime when the current
voting period started. The voted/293 property above
indicates that player #293 has voted one time this interval. The
votes/517 property indicates that plyaer #517 has received
one vote this interval.
prev |
toc |
top |
next
|