The value of the CLASS attribute may contain a list of classes separated by
spaces. This permits client output to be in the 'system' class as well as
more specific ones. That allows you to change all of these colors in one
shot if you are too lazy to change them each individually. For example, if
you define a style sheet that changes the background color, you might need to
redefine the various foreground colors like this:
In this example, the background color of the terminal will be aqua, normal
text from the server will be black, and all output from the client will be
bold and red, except echoed commands and expansion lists, which will be bold
and green. The more specific .command rule is placed after the general
.system rule so that its color takes precedence. This is how style sheets
are composed--you write general rules first followed by any exceptions.
The order in which rules are specified is one of the factors that determines
precedence of style sheet commands. The language is known as Cascading Style
Sheets because of its ability to handle several layers of stylistic rules,
intermingling the configurations of the user and the designer in an ordered
fashion.
Rules are selected by first finding all matching candidates for a given
attribute in the current HTML tag being processed. If there is more than
one, rules from a higher level style sheet take precedence over lower level
ones. That means the basic user configurable settings in DreamSeeker are
the lowest priority, followed by a style sheet in the user's
.dms script file, followed by a style sheet from the designer's
client.script setting, because that is the order in which these
are read by the style sheet manager.
Rules from the same style sheet are ordered by specificity. The selector
SPAN.chat is more specific than .chat and
.chat EM is more specific than EM. In general,
the more classes referenced by a selector, the more specific it is. When
that results in a tie, the selector with the greater number of tags takes
precedence.
If two rules about the same attribute come from the same sheet and have the
same specificity, the final one to be defined takes precedence.
In the rare event that a rule needs to break out of the normal order of
precedence, it can be flagged as important. In this case it will take
precedence over all other "unimportant" rules. However, if more than one
rule is important, the normal rules of precedence will be used to resolve
the conflict.
In the above example, only the background color is important, not the font
specification.
Style commands may also be inserted directly in an html tag to control
its appearance. This does not have the advantages of style sheets, which
separate content from presentation, but it does allow you to use the style
sheet syntax when formatting text.
tags (text)
- See also:
- entities (text)
- macros (text)
- style sheets
- text
Text tags (also known as elements by snooty HTML purists) control
how the text is formatted. HTML syntax is used, so all tags start with
< and end with >. The tags which are
currently supported by Dream Seeker, are listed below:
//anchor (hyperlink)
//acronym or abbreviation
//bold text
//one size bigger text
//body of html document
//line break
//citation reference
//program source code
//definition
//used in conjunction with style sheets
//emphasized text
//font face, color, and size
//heading level
//document head section
//html document
//italic text
//display icons
//keyboard input
//paragraph
//pre-formatted text
//overstrike text
//sample output
//one size smaller text
//used in conjunction with style sheets
//strongly emphasized text
//contains a style sheet
//document title
//typewriter style
//underline
//variable name
<XMP></XMP> //preformatted (tags ignored)
In addition to these, the <BEEP> tag, which is not
standard HTML, may be used to beep the terminal.
Some tags take additional parameters, known as attributes. The most common
ones are <FONT> and <A>.
The syntax for these is illustrated by the following two examples:
"How about this!"
"Click here!"
As many attributes may be specified as desired. The attribute value may
have quotes around it, but this is only necessary if the value contains
spaces. It is usually more convenient to use single quotes so you don't have
to escape the double quotes, but you can also embed the HTML in a text document to avoid the need for escaping quotes.
Text colors may be specified by name or RGB value. The named colors and
their corresponding RGB value are listed in the following table:
The hexadecimal colors above are written with 8 bits (two hex digits) for
each color. It is also possible to use 4 bit values by using only one hex
digit per color. The full 8 bit color is produced by repeating each digit.
For example, #F00 (red) is the same as #FF0000.
Text sizes range from 1 to 7, 1 being the smallest and 7 being the largest.
In addition to absolute sizes, relative sizes may be specified (like +1 for
one size bigger or -1 for one size smaller).
area
- See also:
- atom
- procs (area)
- rooms
- vars (area)
Areas are derived from /area. Regions on the map may be assigned to an
area by painting it onto the map. Areas off the map serve as rooms that
objects may enter and exit.
For each area type defined, one area object is created at runtime. So for
areas on the map, all squares with the same area type belong to the same
instance of the area.
Additional instances of rooms may be created from the same type by
explicitly creating them with null as the initial location. That is, the
first argument to new() should either be null or left
unspecified.
The following example defines the area prototype
/area/outside. It also defines an action to be taken when
somebody enters an area, namely to display its description.
Example:
area
Entered(O)
if(desc) O << desc
return ..()
outside
desc = "Ah! A breath of fresh air!"
animate_movement var (movable atoms)
- See also:
- Move proc (movable atom)
- pixel_step_size var (movable atoms)
- Default value:
- FORWARD_STEPS (1)
- Possible values:
- NO_STEPS (0)
- FORWARD_STEPS (1)
- SLIDE_STEPS (2)
- SYNC_STEPS (3)
Setting this to 0 causes movement between two adjacent positions to be
displayed as a single discrete jump. Otherwise, objects will be made to glide
from one position to another, using the movement animation defined in the icon
file if one is defined.
By default, movement animation avoids cutting corners, since this can look
very bad in some games. If you want objects to take the shortest (and
smoothest) visual path when moving around, use SLIDE_STEPS instead of the
default FORWARD_STEPS. This also allows the object to be facing in a
different direction than it is moving, so make sure this is what you want.
SYNC_STEPS is intended for objects that move in unison as part of a larger
"conglomerate" object. You should set the movement animation to SYNC_STEPS on
all but a single "head" object, which will serve as the leader when choosing
pixel step sizes. If you do not use SYNC_STEPS, there are cases where the
pixel offsets of objects may get out of sync during motion, causing the object
to visually break up.
screen_loc var (movable atoms)
- See also:
- HUD / screen objects
- layer var (atom)
- screen var (client)
- view var (client)
- map_format var (world)
This is a text string that controls where an object that is listed in
client.screen will appear on the user's screen. The format is:
"x,y"
"x1,y1 to x2,y2"
The bottom left corner of the map viewport (southwest) is "1,1".
If the view is 11x11, then the top-right corner (northeast) is
"11,11". (Changing world.map_format
may change the range for screen_loc.)
The edges of the map may also be referenced by using directions, such as
"3,NORTH". For convenience, the order of coordinates is arbitrary
when using directions, so one may specify y before x as
in "NORTH,WEST". In expressions such as the latter, you may also
leave out the comma.
A range of coordinates (the second format above) causes a square region to
be filled with the object at each position. The southwest and northeast
corners of the box are indicated in the screen_loc value.
Normal layering rules apply to screen objects, so to color the background
of the map (visible at least when regions of the map are blocked from view),
one could create an object with a drawing layer below all other map objects
and set its screen_loc to cover the whole map (e.g. "1,1 to 11,11").
In addition to objects inside of the map view, one may create border
objects. Borders are automatically created when screen objects are placed at
coordinates outside of the inner map view. For example, objects placed at y=0
fall on a border directly below the map and y=-1 is one layer below that.
Offsets may be applied to screen_loc coordinates. For example,
"NORTH+1,WEST" is in a border above the map.
It is also possible to specify a pixel offset. Screen objects do not use
pixel_x and pixel_y for this purpose, because it is intended that an object
could exist on the map and in the screen object list simultaneously, so
positioning must be independent.
Pixel offsets are specified after a colon line this: "1:16,1:16".
In this case the object is shifted to the northeast by 16 pixels.
You can use HUD objects in any additional map controls that might appear in
game's skin file. If you have a second map named "map2" for instance, then you
can use "map2:1,1" or something similar as a screen_loc. If the map control is
set to automatically scale to fit its contents, it will try to show every
object you put there. (NOTE: You should not use the full window.control name,
just the name of the control itself. Map controls should always have unique
names.)
New proc (atom)
- See also:
- New proc (datum)
- new proc
- Format:
- New(loc)
- (supports named arguments)
- When:
- Called when the object is created.
- Args:
- loc: The initial location.
- Default action:
- None.
By the time New() is called, the object has already been created at the
specified location and all of its variables have been initialized. You can
perform additional initialization by overriding this procedure.
Since the initial location parameter passed to new() is
applied before New() is even called, there is some special handling of the
loc variable when using named arguments in a call. Normally, if a
procedure is overridden, named arguments in a call are matched against those
in the the overridden definition. In this case, however, the loc
parameter name is hard-coded. Regardless of what you call the first argument
in your definition of New(), the initial location will be taken from the first
positional argument, or from the argument named loc if there are no
positional arguments.
The following example does some extra initialization that is not possible
in the variable definition section, because it requires a runtime evaluation.
This is a common reason to use New().
Example:
mob
var
birthdate //time stamp
New()
birthdate = world.realtime
return ..()
verb/look()
set src in view()
usr << "[src] was born on [time2text(birthdate,"DD-MMM-YYYY")]."
icon var (atom)
- See also:
- icon proc
- icon_state var (atom)
- icons
- overlays var (atom)
- underlays var (atom)
- Default value:
- null
This is the icon file that will be used to represent the object on
graphical clients.
Example:
turf/wall
icon = 'wall.dmi'
You can also assign this to an external file at run-time with an expression
such as file("wall.dmi"), but you would only want to do that when the other
method is not possible, because it requires addition of the file to the
resource cache, which can take a little time.
When this variable is assigned to any dynamically created icon object, that
object gets dumped into the world's resource cache (the .rsc file),
and a reference to that cached file is assigned to atom.icon. In other words,
don't expect comparisons such as usr.icon ==
MyDynamicallyCreatedIcon to work unless you have used fcopy_rsc() to
get a cache reference to your dynamically created icon first. This is almost
never an issue, so don't worry about it if none of that made any sense to you!
layer var (atom)
- See also:
- overlays var (atom)
- z var (atom)
- map_format var (world)
- TOPDOWN_LAYER
- Default value:
- 1 (AREA_LAYER)
- 2 (TURF_LAYER)
- 3 (OBJ_LAYER)
- 4 (MOB_LAYER)
This numerical value determines the layer in which the object is drawn on
the map. By default, the order is area, turf, obj, mob, followed by missiles
and images (in FLY_LAYER, which is 5).
Example:
turf
archway
layer = MOB_LAYER+1 //overhead
When making objects to be used as graphical overlays, you should also be
aware of the special FLOAT_LAYER value. This causes the overlay (or underlay)
to be in the same drawing layer as the base object, no matter how that layer
changes after the addition of the overlay. Otherwise, the overlay object's
own drawing layer is used.
The actual drawing order of icons may change depending on world.map_format.
An isometric map for instance has to display tiles that are "closer" to the
viewer in front of tiles that are in the back, so the layer var takes a
backseat to the needs of the map. If you use the TOPDOWN_MAP or TILED_ICON_MAP
map formats, the layer is more important.
If you are using a world.map_format that does not display topdown, such as
ISOMETRIC_MAP, then you can use a special layer for showing certain portions
of the map in topdown mode. For those parts of the map, you can add TOPDOWN_LAYER
to every atom's layer to make the atom appear in topdown mode. This is for
special cases, like for instance a battle map in an RPG, where a regular topdown
view is preferable to the special mapping used by the rest of the game. It is
recommended that you use TOPDoWN_LAYER with every atom in that portion of the map,
since topdown and isometric maps for instance don't mix. If you use TOPDOWN_LAYER,
it is best to use a square size in world.icon_size if any of these atoms will be
moving around.
overlays var (atom)
- See also:
- icon var (atom)
- layer var (atom)
- list
- underlays var (atom)
- Default value:
- empty list
This is a list of icons which are displayed on top of the object's main
icon.
The individual items in the list may not be directly accessed, since they
are stored in a special internal format. However, the list operators
+=, -=, and the procedures Add,
Remove, and Cut work normally.
Example:
turf/verb/AddOverlay(I as icon)
overlays += I
turf/verb/RemoveOverlay(I as icon)
overlays -= I
The data types that may be used as overlays are icons, icon states (text
strings), objects, and object types. When an icon state is used, the
corresponding image in the object's icon is displayed. When another object is
used as an overlay, a static "snapshot" of the object is taken at the time
when the overlay is created. Future changes to the object will not change the
appearance of the overlay.
Overlays have their own independent drawing layer. It is normally the
special value FLOAT_LAYER, which makes them float above the base object. If
the overlay is a snapshot of another object, the drawing layer of that object
is used. The important advantage of using FLOAT_LAYER is that if the layer of
the base object changes, the overlays will move with it into the new layer.
Any negative number may be used in place of FLOAT_LAYER (which happens to
be -1). They all cause the same "floating" behavior. However, the overlays
are ordered amongst themselves according to their own relative layer values
(-2 below -1 and so on). This may be useful if you have several classes of
overlays that should always appear in a certain order, because you would not
have to worry about the order in which you add them to the list.
Example:
var/const
ARMOR_LAYER = FLOAT_LAYER-1
CLOTHES_LAYER = FLOAT_LAYER-2
obj/overlay
armor
icon = 'armor.dmi'
layer = ARMOR_LAYER
clothes
icon = 'clothes.dmi'
layer = CLOTHES_LAYER
mob/verb
wear_clothes()
overlays += /obj/overlay/clothes
wear_armor()
overlays += /obj/overlay/armor
remove_clothes()
overlays -= /obj/overlay/clothes
remove_armor()
overlays -= /obj/overlay/armor
That example used object types, but you can use instances of objects as
well. Rather than using different "float" layers, you can also just make your
own list of overlays with the order you want and assign that to the actual
overlays list.
Example:
mob/var
boots
clothes
armor
mob/proc
ShowOverlays()
var/L[0]
if(boots) L += boots
if(clothes) L += clothes
if(armor) L += armor
overlays = L
text var (atom)
- Default value:
- The first letter of the object's name.
This is the character used to represent the object on text clients.
Entering several characters produces a text movie (the state of the art!).
In that case, each character is displayed for a 10th of a second.
HTML tags in the text can be used to modify the colors of the text
characters. As a convenience, the <font> tag may include a
bgcolor attribute, so you don't have to do a CSS style setting to
accomplish the same thing.
Example:
world
maxx = 10
maxy = 10
area
text = " "
turf
text = "......"
The example above produces a map with a blue background (from the area) and
turfs (depicted by ".") that flash from bright red to a shorter span of light
red.
Note that in order to see text icons, the user must switch to the text map
in Dream Seeker. If your DM code never does anything with the icon variable,
then this is the default configuration. Such applications are known as
advanced iconic text games:)
underlays var (atom)
- See also:
- icon var (atom)
- list
- overlays var (atom)
- Default value:
- empty list
This is a list of icons which are displayed underneath the object's main
icon.
The individual items in the list may not be directly accessed, since they
are stored in a special internal format. However, the list operators
+=, -=, and the procedures Add,
Remove, and Cut work normally.
Example:
turf/verb/AddUnderlay(I as icon)
underlays += I
turf/verb/RemoveUnderlay(I as icon)
underlays -= I
The data types that may be used as underlays are icons, icon states (text
strings), objects, and object types. When an icon state is used, the
corresponding image in the object's icon is displayed. When another object is
used as an underlay, a static "snapshot" of that object is taken at the time
when the underlay is created. Future changes to the object will not change
the appearance of the underlay.
Underlays have their own independent drawing layer. It is normally the
special value FLOAT_LAYER, which makes them float directly below the base
object. If the underlay is a snapshot of another object, the drawing layer of
that object is used.
See the discussion of FLOAT_LAYER for overlays, because the same applies here.
z var (atom)
- See also:
- layer var (atom)
- loc var (atom)
- Default value:
- The z coordinate of the object on the map.
The z coordinate is how objects move between maps. When you include
several maps in a project, they are placed on different z levels so that the
full map is a single 3-dimensional space. It is also possible for a single
map file to contain multiple z levels.
Do not confuse this with drawing layer. The z coordinate moves an object
between different maps. The layer variable determines the order in which an
object is drawn graphically relative to other objects at the same position on
the map.
You may assign the coordinates of movable objects (mobs and objs), but this
is not advisable. It is better to compute the new location (with
locate()) and move them to that. Then you can use the normal
Move() procedure, which enables all the normal movement behavior.
For areas that are on the map, this is the coordinate of the turf with the
lowest z, y, and x coordinate (in that order) that is contained by the area.
Command proc (client)
- Format:
- Command(command as command_text)
- When:
- Called when the player types in something that is not understood as a
valid command, or if the player is connected via telnet.
- Default action:
- None.
If this proc is used, players will be able to connect to your world via
telnet. All telnet users' commands are routed through this proc instead of
being parsed into verbs. Players who join the world through Dream Seeker
will have their commands parsed as verbs first, and those commands will end
up here only if there is no applicable verb.
Note that text received by this proc is not interpreted beforehand, so
quotes " and backslashses \ should come through unaltered.
This proc is primarily useful if you want to handle parsing yourself (like
for a MUD), or if your world is a chat server and verbs are not used much.
Export proc (client)
- See also:
- Import proc (client)
- New proc (client)
- hub var (world)
- savefile
- Format:
- client.Export(url,file)
- client.Export(file)
- Args:
- url: a Dream Seeker action url
- file: optional file to attach
The default action, when no url is specified, is to store the given file on
the user's computer in a special location unique to each registered world.hub setting. This is most useful for writing a
client-side savefile, but any type of file may be stored. The purpose of this
is to exchange information between different worlds running under the same hub
path.
When a savefile is exported to the player's computer, it replaces any
previous savefile stored by a game with the same world.hub value.
This should not be used for anything requiring high security, because any
other world could make use of the same hub path and access the savefile. It
is also possible for the user to tinker with the file, since it resides on
their computer.
To delete the client-side savefile completely, call
client.Export() with no argument at all.
The url parameter may be used to make Dream Seeker do one of various other
operations on the file. You normally do not call it directly but various
procedures and libraries use it internally. The URL has the following format:
"Address##action=ActionName"
In most cases, Address is blank, because the destination of the file is
simply the user's own computer. ActionName may be any one of the following:
- ftp
- offer to store the attached file on the user's computer (generated by ftp()
- run
- offer to run the attached file on the user's computer (generated by run)
- browse_rsc
- store the attached file for subsequent use by a browser page (generated by browse_rsc)
- browse_file
- display the attached file as a browser page (generated by browse)
- hubfile
- store the attached file at BYOND Hub (see hublib)
If no action is specified, the attached file is stored as a client-side
savefile.
Example:
mob/verb/save()
var/savefile/F = new()
F << usr //write the player's mob
usr.client.Export(F)
client/New()
var/client_file = Import()
if(client_file)
var/savefile/F = new(client_file) //open it as a savefile
F >> usr //read the player's mob
return ..()
Import proc (client)
- See also:
- Export proc (client)
- New proc (client)
- savefile
- Format:
- client.Import(Query)
- Args:
- Query: optional query parameters
When no query parameters are given, this returns the client-side file last
exported with client.Export(). This comes as an entry in the
resource cache, which can be opened as a savefile among other things. If
there is no file, null is returned. For an example, see client.Export.
When there are query parameters, these may be used to import a file from
some alternate source. Currently, that applies only to the user's hubfiles
stored at BYOND Hub. The specific query syntax is not documented here,
because those details are all taken care of by the hublib DM library.
You can use it to create a savefile shared between one or more users, useful,
for example, in turn-based games where the users can make moves whenever they
happen to log in rather than all having to play at the same time.
MouseDown proc (client)
- See also:
- Click proc (client)
- DblClick proc (client)
- MouseDown proc (atom)
- MouseDrag proc (client)
- MouseDrop proc (client)
- MouseEntered proc (client)
- MouseExited proc (client)
- MouseUp proc (client)
- mouse_opacity var (atom)
- mouse_pointer_icon var (client)
- show_popup_menus var (client)
- Format:
- MouseDown(object,location,control,params)
- Args:
- object: the object under the mouse pointer
- location: the turf, stat panel, grid cell, etc. containing the object where it was clicked
- control: the name of the skin control involved
- params: other parameters including mouse/keyboard flags, icon offsets, etc.; see mouse control
- Default action:
- Call object.MouseDown(location,control,params).
This is called when the a mouse button is pressed while pointing to the
object. Note that MouseUp() will always be called after MouseDown() is
called, even if over empty space. That means object and
location may be null.
Don't define this unless you need it, because it generates extra
communication that is otherwise avoided. Most operations can be done through
Click(), DblClick(), and MouseDrop(). The other procedures are simply
available for completeness.
Note: In BYOND 3.5 this procedure took four different arguments:
object, location, icon_x, and icon_y. Since icon_x and icon_y have been replaced,
old code will need to be modified. Games compiled before this change will still
work normally.
New proc (client)
- See also:
- Export proc (client)
- Import proc (client)
- Login proc (mob)
- New proc (datum)
- Topic proc (client)
- mob var (world)
- savefile
- Format:
- New(TopicData)
- Returns:
- The newly connected mob, client.mob, or null to disallow the connection.
- When:
- Called when the player first tries to connect to the world.
- Args:
- usr: The mob in the world with the same key as the player, if it exists.
- TopicData: If the player accessed the world with a "connection topic",
this is the topic text. Otherwise it is null.
- Default action:
- Look for an existing mob with the same key as the player. If found,
connect the player to that mob (mob.Login()). Otherwise, look for a
prototype mob with the same key as the player. If found, create a mob of
that type and connect the player to it. Otherwise, create a mob of type
world.mob, give it the same name and gender as the player's key, and
connect the player to it. If TopicData is not null, call
client.Topic(TopicData). Finally, the player's mob is returned.
This is a fairly low-level procedure that you would only want to override
if you cannot accomplish the same thing in mob/Login() or
mob/New(). One reason to override client/New() is
if player mobs are created from a savefile. In that case, you don't need a
temporary mob to be created first.
Example:
client/New()
if(usr) return ..() //reconnecting to existing mob
else
var/player_sav = "players/[ckey].sav"
if(length(file(player_sav))) //if player savefile exists
var/savefile/F = new(player_sav) //open it
F >> usr //create saved mob
return ..() //creates a new mob if necessary
mob/Logout()
var/player_sav = "players/[ckey].sav"
var/savefile/F = new(player_sav)
F << src
del src
If you want to do any user-interaction before loading the saved mob, you
will have to create a temporary mob first in order to interact with the
player. In that case, you are better off doing things in
mob/Login(), rather than client/New().
Note that for the above example to work, you must make
proper use of the tmp flag when defining new object
variables. Otherwise, this can end up sucking large portions of your world
into each player savefile, which can have all sorts of unexpected
consequences!
Topic proc (client)
- See also:
- New proc (client)
- Topic proc (datum)
- link proc
- ref text macro
- Format:
- Topic(href,href_list[],hsrc)
- When:
- Called when a player connects to a world with a "connection topic" or
when the player runs a hyperlink in the current world by clicking one
embedded in text or generated by the link() instruction.
- Args:
- href: The topic text (everything after the '?' in the full href).
- href_list: List of key/value pairs in href (produced from params2list(href)).
- hsrc: The object referenced by the "src" parameter in href or null if none.
- Default action:
- Call the hsrc object's own Topic() proc.
The following example uses a very simple href value.
Example:
mob/Login()
src << "Click here to download the source code."
return ..()
client/Topic(href)
if(href == "source")
usr << file("world.dm")
usr << file("world.rsc")
else ..()
Be sure to call the default handler unless you want to prevent rerouting
of topics to other objects. For security reasons, you might want to control
which objects a player has access to, since a player could spoof a topic
link containing any arbitrary object reference. (Never trust those sneaky
players!)
The next example demonstrates an href that gets handled by another object.
This is how you would normally want to do things. It is best not to override
client/Topic() (as in the example above) unless you need to intervene in the
low-level details of routing the request to the right object.
You specify the object that will handle the request by using a parameter
called "src".
Example:
mob/Login()
src << "Click here to start."
return ..()
mob/Topic(href,href_list[])
switch(href_list["action"])
if("startgame")
usr << "Starting game..."
else
return ..()
Although it is slightly more complex, the use of the parameter list allows
you to easily include extra data and new functionality. Just remember that
the data in the list is always stored as text, so if you are expecting a
number of an object, you must convert it yourself (with text2num(), locate(),
or whatever).
authenticate var (client)
This value may be set to 0 at compile-time to disable BYOND hub-based
authentication of users. The default value is 1, which enables
authentication. Hub authentication provides an additional level of
assurance that the user is really the owner of the BYOND key in question.
When a world requests certification, Dream Seeker generates a random
password and passes it through the hub (for certification) to the world.
The certificate is saved for faster access in the future and for protection
against possible hub outages.
Some applications do not depend on the validity of the user's identity.
In that case, it would be more efficient to turn off the extra level of
authentication. In other situations, the hub may not be available, such as
from behind a firewall or on a LAN without internet access. In those cases,
all hub access (including authentication) can be disabled by entering the
command ".configuration hub-address none" in Dream Seeker.
Connections to worlds on the same machine are not hub-authenticated to
allow for convenient offline testing.
command_text (client)
- See also:
- arguments (verb)
- Skin reference
- macros (client script)
- Default value:
- null
This text is placed onto the command line, to be followed by whatever the
user may type. It is usually the name of a verb followed by a space, such
as "say ". The user can clear this and enter a different command by hitting
backspace, escape, delete, or '/'.
(Note: In BYOND 4.0 this var is deprecated. The command
parameter for an Input control can be set to !command which does the
same thing. See the skin reference
for details.)
Example:
client
command_text = "say "
verb/say(T as text)
world << "[usr] says, '[T]'"
It is also possible to turn on macro mode, in which each keypress
executes a keyboard macro, by setting
command_text to ".alt ". That stands for the Alt key,
which can be used to execute macros in normal mode.
This variable could also be used to create a specialized command prompt.
For example, a traditional style MUD command-line could be implemented like
this:
Example:
client
command_text = "> "
verb/command(C as command_text)
set name = ">"
usr << "Your command: [C]"
This example uses the command_text input type, which accepts raw
text, with no quoting, escaping, or translating, so that you can invent
whatever syntax you want.
eye var (client)
- See also:
- lazy_eye var (client)
- mob var (client)
- perspective var (client)
- pixel_step_size var (client)
- view var (client)
- virtual_eye var (client)
- view var (world)
- Default value:
- The connected mob, client.mob.
This value determines the center of the player's map. The default value
simply means that the visible region is normally centered on the player's mob.
Effects such as setting perspective to
EDGE_PERSPECTIVE or using lazy_eye can move the map
off-center temporarily. The eye is the ideal center, not
necessarily the actual center; to find the actual center, use
virtual_eye.
Note that the visibility of objects is still computed from the point of
view of the mob rather than the eye. This allows the use of
lazy_eye or similar effects that control the panning of the map
while still having the player see only what the mob can see. To determine
visibility from the eye, you can change the value of
client.perspective.
If a player connects to a new mob M, client.eye automatically changes to M.
Example:
client
eye = locate(5,5,1)
This fixes the center of the player's map at the turf coordinate (5,5,1).
Since the eye is fixed, the map will not scroll even as the player's mob
moves out of the visible range.
lazy_eye var (client)
- See also:
- view var (client)
- view var (world)
- Default value:
- 0
This is the maximum "lag" between client.eye and client.mob. The mob can
stray up to this many tiles before the eye will move to keep it in view. The
default value of 0 means that the eye always moves as the mob moves, keeping
the mob at the center of the player's map.
Setting this value to a non-zero value automatically initializes client.eye
to client.mob.loc (or to the center of the full map if that is possible).
Thereafter, client.eye will stray from the mob as it moves about the map,
making one big jump to catch up whenever the mob gets out of range.
Example:
client
lazy_eye = 5
This setting allows client.mob to move onto the entire 11x11 visible
region without changing the value of client.eye. The moment it steps out of
this region, the entire region will shift 5 tiles in the direction of motion.
You can assign lazy_eye to any value valid as a view size, so, for example,
if you have a non-square setting for client.view, say, "17x11", you could
apply a similar setting to lazy_eye. You can even make one dimension lazy and
the other one strictly centered: "0x5".
perspective var (client)
- See also:
- eye var (client)
- mob var (client)
- Default value:
- MOB_PERSPECTIVE
- Possible values:
- MOB_PERSPECTIVE
- EYE_PERSPECTIVE
- EDGE_PERSPECTIVE
This controls the eye's apparent center and what can be seen by the client.
EYE_PERSPECTIVE determines how visibility calculations are performed when
client.eye and client.mob are different. Normally,
visibility is done from the position of the mob, rather than from the eye
(which is actually just the center of the map view). The alternative flag is
MOB_PERSPECTIVE, the default.
EDGE_PERSPECTIVE limits scrolling to the bounds of the map (1,1 to
world.maxx,world.maxy), and does not keep the mob centered if it strays near
the edge.
The above values can be used together via the | operator.
preload_rsc var (client)
- Default value:
- 1.
This variable controls whether resource files (icons and sounds) are
automatically downloaded by Dream Seeker when first connecting, or whether
they should be downloaded as needed. Resource files are cached (in
byond.rsc) for future use, so this should only affect people who have not
played the game before or who have not played it for some time.
The three possible settings are:
- 0
- do not preload any resources
- 1
- preload compiled-in resources only
- 2
- preload all resources including those uploaded by players
- URL
- preload resources from specified file
Preloading resource files will eliminate delays later on, but may cause
a very long initial delay when logging in.
Resources may also be distributed from a website to save bandwidth on the
machine hosting the game. Simply zip up the .rsc file, upload it to a web
site, and put the URL here.
Example:
client/preload_rsc = "http://dan.byond.com/mygame_rsc.zip"
Instead of putting the .rsc file in the .zip, you can also put the
individual resource files there. This would allow you to select specific
files that you would like to be preloaded. For example, you could create a
different resource package for different parts of the game world and assign
client.preload_rsc dynamically as the player moves into each different area.
Once Dream Seeker has downloaded a resource package, it caches it and will
not download it again, even if you upload a new version of the file. This
allows you to make small changes without forcing a complete refresh. Any
files which are not found in the preload package are simply downloaded from
the game server directly.
If you want to force a complete refresh, simply change the name of the
resource package. For example, you could put a version number in the name of
the file: mygame_rsc_01.zip, mygame_rsc_02.zip, and so on.
script var (client)
- See also:
- #include directive
- PASSWORD_TRIGGER (client script)
- URL (client script)
- aliases (client script)
- browser configuration
- command_text (client)
- macros (client script)
- style sheets
- style sheets (in scripts)
- Default value:
- none
Client scripts are mini-programs used to configure the client. The
language they use is called DM Script, and will undoubtedly expand in the
future. Currently, client scripts can be used to define style sheets,
command aliases, and macros. When executed directly by a player, they can
also be used to specify an initial URL to open and a password trigger (for
some ancient telnet worlds that don't suppress password echo).
For the specific syntax of DM Script, see the relevant reference sections
listed above.
The client.script variable may be assigned to script code in
a text string (double quotes) or in a file (single quotes). You can also
simply include the file in your project or explicitly use the
#include statement. Files containing DM Script should have the
extension .dms.
Example:
client/script = ""
This example selects a default monospace font for all output to the
terminal.
In addition to scripts loaded via client.script, the player
may have client-side scripts. These are either called
connection scripts or post-connection scripts depending on
whether they are used to automatically connect to a world or whether they
are executed automatically after connecting to a world. In either case, the
player's scripts are always executed before the designer's
client.script script, so style sheets from the designer have
higher precedence by default.
There are three post-connection client-side scripts for the three types
of worlds the client can connect to: byond.dms,
telnet.dms, and irc.dms. These are automatically
executed if the player connects directly to a world without using a
connection script to do so. The intention is to load any standard
configurations such as style sheets and command aliases.
browser configuration
- See also:
- URL (client script)
DM Script can be used to effectively make a hyperlink in a web document
to a BYOND world. This is done by making a DM Script file that defines the
desired URL. It need do nothing more than that. When a user clicks on the
link in a web browser, DreamSeeker will pop up, execute the script, and
connect to the specified URL.
Some browsers may need to be configured to know what to do with a DM
Script file. For example, in Netscape, you can add an entry to the list of
helper applications. You should add a MIME type called
'application/x-dms' with the description 'DM Script' and the
extension dms. Have this execute DreamSeeker with the
.dms file as an argument.
Example:
myworld.dms
/*If your browser shows you this, you either need
to install BYOND (it's free!) from www.byond.com,
or you need to configure your browser to execute
DreamSeeker with DM Script (.dms) files.
*/
#define URL "byond://myworld"
myworld.html
Welcome to My World
You can connect to my world
here.
aliases (client script)
- See also:
- macros (client script)
- script var (client)
- verbs
Command aliases have a syntax similar to verbs. They define a command
and a series of arguments which can then be used to execute a new command.
The most common use for this is in a telnet world like a MUD. By defining
aliases corresponding to the MUD commands, the player can have primitive
command expansion and help.
The syntax of an alias definition is best illustrated by the following
example:
alias/say(msg as text)
set desc = "speak your mind"
return "say [msg]"
As you can see, it is just like a verb. Alias have all the same
properties as verbs, except the src setting is always equal to
the player.
The value returned by an alias is executed as a command. In telnet mode,
the command to execute is often simply the same as the command that was
entered (since the alias was only defined to provide command expansion and
help). Since that is such a common case, the return value defaults to the
alias name followed by each of the arguments. The example above, for
instance, would have the same effect without an explicit return statement.
Note that commands executed via an alias are never interpreted as
aliases. Otherwise, examples such as the one above would result in an
infinite loop.
view var (client)
- See also:
- lazy_eye var (client)
- show_map var (client)
- view proc
- view var (world)
- Default value:
- world.view (which is 5 by default)
- Possible values:
- -1 to 34 or "WIDTHxHEIGHT"
This controls the size of the map window in Dream Seeker. Normally, you
would simply compile with world/view assigned to whatever you want, but in
some cases, you might want to customize the map size for different players,
such as admins or subscribed users.
Like all other view sizes in DM, this may either be a view depth
or an absolute size. A view depth is a single number that determines how far
from a center point the edges of a square viewable region extend. A value of
5 creates edges which are 2*5+1 = 11 tiles long.
The newer, more flexible syntax is a text string of the form
"WIDTHxHEIGHT". For example, a view depth of 5 corresponds to "11x11". Using
this syntax, you can create non-square views as well.
The maximum view size is about 5000 tiles, or roughly 70x70.
tag var (datum)
- See also:
- locate proc
- Default value:
- null
This may be assigned to a unique text string identifying a particular
object. A reference to the object can then be obtained by using locate().
One reason to use tags is when making references in the code to objects and
locations that will be created on the map. You can simply edit the object in
the map editor, set its tag, and then use that in the code relating to the
object.
The following example demonstrates how to set a tag and use it to obtain a
reference to an object.
Example:
mob/verb/test()
var/obj/O = new()
O.tag = "My Object"
var/obj/O2 = locate("My Object")
ASSERT(O == O2) //this should always be true
Setting a tag to "" or null removes it. Any object with a non-empty tag is
immune to garbage collection, since the tag is treated as an implicit
reference to that object.
icon
- See also:
- icon procs
- icons
- image objects
An /icon object is created by loading an icon file into memory for direct
access and manipulation. In order to be displayed, an /icon object always
gets converted back into an icon file; this happens automatically when you
assign atom.icon to an /icon object, since that variable may only refer to a
static icon file, rather than a dynamic memory object.
To create an /icon object, simply use new/icon(), or the short-cut icon()
instruction. The following example loads an icon file, reddens it, and then
assigns it back to the player's icon, which implicitly creates a new icon
file.
Example:
mob/verb/test()
var/icon/I = new('player.dmi')
I.Blend(rgb(40,0,0))
usr.icon = I
Note that merely displaying different icon states or directions can
generally be achieved without any icon manipulation, which is good, because it
saves quite a bit of overhead. For example, the variables atom.icon_state and
atom.dir can be used to control how atom.icon is displayed, without any need
for generating a new icon file.
Blend proc (icon)
- See also:
- icon
- icon procs
- overlays var (atom)
- rgb proc
- Format:
- Blend(icon,function=ICON_ADD,x=1,y=1)
- Args:
- icon: an icon file, /icon object, or color
- function: the blending operation to use
- x, y: the position to blend the icon
The valid blending operations are:
- ICON_ADD
- ICON_SUBTRACT
- ICON_MULTIPLY
- ICON_OVERLAY
- ICON_AND
- ICON_OR
- ICON_UNDERLAY
The result is a combination of each corresponding pixel in the two icons.
In all but ICON_OVERLAY, ICON_UNDERLAY, and ICON_OR, the transparent regions of
the two icons are ORed together. That means if either icon is transparent on a
given pixel, the result will be transparent. With ICON_OVERLAY or ICON_UNDERLAY,
on the other hand, the original icon shows through wherever the top icon is
transparent, giving the same effect as an overlay object, but resulting in only a
single icon. In ICON_OR, the transparent regions are ANDed together; solid pixels
are added together where they exist in both icons, or just pass through if the
other icon is transparent at that pixel.
In addition to blending with an icon, an rgb() value may also be specified.
This is treated identically to an icon of that same solid color, except that the
x and y arguments will be ignored. Blending with a color blends the whole icon.
By default, the icons will line up at their lower left corners. If you want
to position the second icon in a different place for blending, use the x and y
arguments to specify where its lower left corner will be. 1,1 is the default,
which is the lower left. 11,1 for instance would be 10 pixels to the right,
and 1,21 would be 20 pixels up.
Insert proc (icon)
- See also:
- icon procs
- New proc
- map_format var (world)
- Big icons
- Tiled icons
- Format:
- Insert(new_icon,icon_state,dir,frame,moving,delay)
- (supports named arguments)
- Args:
- new_icon: an icon file or /icon object to insert
- icon_state: an optional text string, specifying a single icon state to
change or add to this icon
- dir: an optional direction; the inserted icon will only be added for this
direction
- frame: an optional animation frame (starting at 1); the inserted icon will
only be added for this frame
- moving: Non-zero to insert as a movement state, 0 for a regular non-movement
state
- delay: 0 or null to leave unchanged; positive to set delay for a frame and turn
rewind off; negative to set delay and rewind
This adds additional states or images to an existing icon, allowing you to
build directional, animated, and multi-state icons on the fly. If the state
you wish to insert already exists in the file, it will be altered; otherwise
it will be added. An animation may be built a piece at a time, for example by
inserting an icon into the NORTH direction for animation frame 3.
Example:
// start with a non-animated arrow icon
var/icon/I = new('arrow.dmi')
// make a new state called "blink"
var/icon/J = new('arrow.dmi')
I.Insert(J, "blink", delay=-1) // set rewind flag
// create darker shades of the arrow
var/n = 2
for(var/light=9, light>=5, light--)
J = new('arrow.dmi')
J.SetIntensity(light/10)
I.Insert(J, "blink", frame=n++)
// congratulations, you have a pulsating arrow
icon = I
The icon resulting from this example has two states: The original arrow,
and a new state called "blink" that pulsates between full and ½
luminance. To use the blinking state after that, set the atom's icon_state to
"blink".
(Note for animations: When building an animated icon_state from scratch,
you can only add 16 new animation frames at a time; i.e., frame<=total_frames+16.
Higher values for frame will be ignored. This is a safety precaution.)
If you insert an icon of a different size, the src icon will be resized to
match the size of new_icon. (The only exception is if you are using the TILED_ICON_MAP
map_format, and new_icon is a single tile being inserted as a chunk into a larger icon.
If icon_state, such as "2,0" or "open 0,0", already exists in src as one of its smaller
pieces, then new_icon will be inserted in its place.)
When inserting an individual animation frame, you can change the delay for
just that frame only. If you don't specify a delay, the nearest frame's delay
will be used. If this is the first frame being inserted into an icon, then
the delay will default to 1 tick. Remember, if your delay is positive, it will
turn off the rewind flag for that entire icon state; negative will turn it on.
MapColors proc (icon)
- See also:
- icon
- icon procs
- rgb proc
- Format:
- MapColors(rr, rg, rb, gr, gg, gb, br, bg, bb, r0=0, g0=0, b0=0)
or
MapColors(r_rgb, g_rgb, b_rgb, rgb0=rgb(0,0,0))
or
MapColors(rr, rg, rb, ra, gr, gg, gb, ga, br, bg, bb, ba, ar, ag, ab, aa, r0=0, g0=0, b0=0, a0=0)
or
MapColors(r_rgba, g_rgba, b_rgba, a_rgba, rgba0)
- Args:
- rr: portion of old red component -> new red component
- rg: portion of old red component -> new green component
- rb: portion of old red component -> new blue component
- ra: portion of old red component -> new alpha component
- r0: new base red component
- ...
- or
- r_rgb: red component is converted to this color
- g_rgb: green component is converted to this color
- b_rgb: blue component is converted to this color
- rgb0: this color is added to the result
This is used for complex color mapping that can be used for many special
effects. For the number form, values usually range from 0 to 1, but you can
use anything you like, including negative numbers. 1 means 100% of the
original color will be used. If rg=1, for example, then the amount of red in
the original icon becomes the same amount of green in the new icon's colors.
There is also an alternate form that can use rgb() values
instead, though it is less flexible. r_rgb is the color that will be used in
place of 100% red; any darker shades of red will become a darker shade of
that color. g_rgb converts green to another color, and b_rgb converts blue to
still another color, and all of them are added together.
Either of these calls change the icon to grayscale:
icon.MapColors(0.3,0.3,0.3, 0.59,0.59,0.59, 0.11,0.11,0.11, 0,0,0)
// or...
icon.MapColors(rgb(77,77,77), rgb(150,150,150), rgb(28,28,28), rgb(0,0,0))
The calculations are as follows:
- For any red in the original icon, add 30% gray to the output.
- For any green in the original icon, add 59% gray to the output.
- For any blue in the original icon, add 11% gray to the output.
- Add an additional 0% (nothing).
Or this will make a nice moonlight effect:
icon.MapColors(0.2,0.05,0.05, 0.1,0.3,0.2, 0.1,0.1,0.4, 0,0,0)
// or...
icon.MapColors(rgb(51,13,13), rgb(26,77,51), rgb(26,26,102), rgb(0,0,0))
- For any red in the original icon, add rgb(51,12.75,12.75) (dark pink) to the output.
- For any green in the original icon, add rgb(25.5,76.5,51) (dark bluish green) to the output.
- For any blue in the original icon, add rgb(25.5,25.5,102) (dark grayish blue) to the output.
- Add an additional 0% (nothing).
Or a negative icon (invert all colors):
MapColors(-1,0,0, 0,-1,0, 0,0,-1, 1,1,1)
The longer formats of MapColors() will allow you to also change alpha colors.
New proc (icon)
- See also:
- icon
- icon procs
- image proc
- new proc
- Format:
- New(icon,icon_state,dir,frame,moving)
- (supports named arguments)
- Args:
- icon: an icon file or /icon object
- icon_state: an optional text string, specifying a single icon state to load
- dir: an optional direction to extract
- frame: an optional animation frame to extract
- moving: Non-zero to extract only movement states, 0 for non-movement states,
or null (default) for both
You generally don't call this directly but via new(). The specified icon
file is loaded into memory for direct access and manipulation.
If the icon state is not specified, all icon states are loaded. Ditto for
the direction, animation frame, or preference for movement states. Animation
frames are numbered from 1 and up, so frame=4 is the 4th frame.
(Movement states are special versions of an existing icon_state with the
same name, but appear in the Dream Maker editor with an "M" indicator. These
states are used for animation when the atom using the icon_state moves from
one tile to the next; otherwise only the normal non-moving state is displayed.)
The following contrived example, loads the EAST facing default icon state
"" from the user's icon file, rotates that a bit, and then creates a new icon
file for the user.
Example:
mob/verb/test()
var/icon/I = new(usr.icon,icon_state = "",dir = EAST)
I.Turn(90) //rotate clockwise 90 degrees
usr.icon = I
Note that merely displaying different icon states or directions can
generally be achieved without any icon manipulation, which is good, because it
saves quite a bit of overhead. For example, the variables atom.icon_state and
atom.dir can be used to control how atom.icon is displayed, without any need
for generating a new icon file.
SwapColor proc (icon)
- See also:
- icon
- icon procs
- rgb proc
- Format:
- SwapColor(old_rgb,new_rgb)
or
SwapColor(old_rgba,new_rgba)
- Args:
- old_rgba: the old rgba value to be replaced
- new_rgba: the new rgba value to use in its place
This causes a color value in the icon's palette to be changed. You can use
null in place of an RGB or RGBA value.
If the old color is a full RGBA color with an alpha value, such as
rgb(1,2,3,4) or "#01020304", then that exact color is the only one changed.
If the old color is an RGB value with no alpha specified, such as
rgb(1,2,3) or "#010203", then that color will change to the new one
regardless of its alpha value, and the original icon's alpha will be kept
intact. (If the new color is totally transparent, however, then the old color
will be replaced with full transparency.)
image objects
- See also:
- icon var (atom)
- image proc
- image vars
- images var (client)
- overlays var (atom)
The /image type contains data used to create a virtual image. Unlike other
atomic objects, this object is a purely visual effect. It always appears
attached to some other object and it behaves in every way as though it were
part of that object (e.g. if the user clicks on it, this counts as a click on
the atomic object, not the image).
One reason for creating images is player-by-player control over visibility.
Images only become visible when they are explicitly output to players:
Example:
var/image/I = image('icon.dmi',usr) //make an image attached to usr
usr << I //allow usr to see it
Images are also useful in the creation of overlays. Overlays are like
images, since they are always attached to another object, but overlays obey
the normal rules of visibility, so they are more convenient when you do not
want to hide the effect from anybody. An overlay can be created directly from
an icon file (or icon state), but when one wishes to override some additional
parameter, the image() instruction is a convenient way to do it.
Example:
usr.overlays += image('shirt.dmi',icon_state = "red")
In the above example, the icon state of an overlay was set by creating the
overlay from an image with the desired icon state. Note that after the
creation of an overlay, no link remains between the overlay and the object
that was used to create it. If you change the image after that time, it will
not change the overlay, which is simply a "snapshot" of the original image.
list
- See also:
- list associations
- list proc
- procs (list)
- vars (list)
Lists are used to represent groups of objects. Like objects, they have
vars and procs associated with them. In order to access these attributes,
list vars must be declared of type /list. These may then be assigned to
existing lists, or used to create new lists.
Example:
var/list/L // list reference
L = world.contents // assign to existing list
L = new/list() // make a new list
L = new() // make a new list (implicit type)
L.Add("futz") // L contains: "futz"
del(L) // delete L
Lists created with 'new()' have a default length of 0; this can be
overridden by specifying the size; that is, new/list(size) creates a list
with size (null) elements.
The 'list()' proc may be used to more easily initialize list data.
Example:
var/list/L
L = list("futz",3) // L contains: ("futz", 3)
Alternatively, lists may be declared by using brackets, '[]'. Empty
brackets indicate a list reference, exactly as /list does, so list/L is
equivalent to L[]. Setting an initial size within the brackets, for
instance, L[10], creates a list of that initial size.
Example:
var/L[] // same as var/list/L: list reference
var/M[10] // initially empty list of size 10
L = M // L is now an empty list of size 10
Once a list L is declared, a specific item can be accessed by putting its
index in the brackets: L[index].
Indices range from 1 to len. If the length of the list is changed,
existing elements in the list will be preserved if they are less than the
new length. New elements in the list will be given the initial value of
null.
Example:
var/L[5] // initial length of 5
var/i
for(i=1, i<=L.len, i++)
L[i] = i
// L contains: (1,2,3,4,5)
L.len = 7 // expand list
// L contains: (1,2,3,4,5,null,null)
del(L) // destroy list
Multi-dimensional lists may be created by making a list of lists.
Example:
var/grid[10][5]
grid[1][1] = 1
grid[1][2] = 2
...
Such a list may also be created by using new(). As in the previous
example, the next one creates a list of 10 lists each having 5 elements.
Example:
var/grid = new/list(10,5)
list associations
- See also:
- list
- list proc
- list2params proc
- params var (world)
- params2list proc
- vars list var (datum)
Each unique text string or object in a list may be associated with another
value. This is done by using the item as an index into the list.
Example:
var/params[0]
params["player"] = "James Byond"
params["score"] = 2000
//List now contains ("player","score")
//These are associated with ("James Byond",2000)
usr << "Looping through list items:"
var/p
for(p in params)
usr << "[p] = [params[p]]"
usr << "Looping through array indices:"
var/i
for(i=1,i<=params.len,i++)
p = params[i]
usr << "[p] = [params[p]]"
The above example illustrates the typical way in which list associations
are managed. Note that an item in the list may be added by assigning its
associated value. The example could have started by doing
params.Add("player","score"), but that would have been
redundant.
Both for loops in the example have the same effect. The
first one loops through each item in the list, and displays it along with
its associated value. The second loop achieves the same thing by looping
through the numerical indices (referred to as array indices as
opposed to associative indices).
Since numerical indices are treated differently, you may not assign an
associated value to a numerical list item. Associations must have a text
string or object reference as the index item.
Associated values default to null if none is assigned. The is also the
value returned when the supplied index item does not exist in the list. The
list defined above, for example, would return null for
params["time"].
The list() instruction may also be used to create associative
lists.
Example:
var/list/lst = list("player" = "James Byond", "score" = 2000)
When the index values happen to be text strings that satisfy all the
requirements for variable names, this may also be written in a convenient
short-hand:
var/list/lst = list(player = "James Byond", score = 2000)
In other words, this is exactly the same syntax as for named arguments.
path operators
- See also:
- . path operator
- / path operator
- : path operator
- procs
- vars
A "path" in DM is a constant value that identifies a particular definition
in the code tree (i.e. an object, procedure, or variable definition). An
example of this is the default mob type for new players /mob.
Paths are used in two contexts. One is to "get to" a particular point in
the code tree in order to modify the definition. The other is to reference a
particular definition made elsewhere in the code tree. The syntax of a path
is similar in both cases.
When you are making a definition, you simply put the path at the beginning
of a line like this:
obj/clothes/gloves
That automatically creates that path in the code tree if it does not
already exist. When starting at the beginning of the line (no indentation)
there is no need to begin the path with '/', but that is perfectly acceptable.
When making definitions, DM equates the path separator '/' with
indentation, so the above example is really just a more compact way of
writing:
obj
clothing
gloves
One generally uses indentation when you have several things to define with
a common parent path:
obj
clothing
gloves
sandals
An important element of DM is that you can get to the same path in the
code tree from multiple places in the source code. For example, given the
above definition of gloves and sandals, you could
modify a property of one of them from somewhere else using any path syntax you
like:
obj/clothing/sandals
name = "Winged Sandals"
While that was not a useful thing to do in this case, it can be a very
powerful tool when organizing source code in large projects. Also note that
the use of "/" can save your source code from getting too deeply indented,
which may sound mundane, but which is quite important!
The above examples used paths to make definitions. The other time when you
use paths is when you need to refer to a particular definition. Creation of
an object is one example:
mob/Login()
if(length(contents) == 0) //poor fellow has nothing
//create sandals in his contents list
new /obj/clothing/sandals (src)
return ..()
Another common use of paths is to declare the data type of a variable. In
DM, variable types do not affect what type of data the variable may
contain--variables that you define may contain any type of value. Instead,
the variable type affects what properties of the data you can attempt to
access.
The following example defines variables for clothing that is occupying
various positions on the body.
mob
var/clothing
feet
hands
torso
Since there were several variables of the same type, they were grouped
under var/clothing. It can be done any number of ways, depending
on the situation. The same path syntax applies to variable definitions as
it does to anything else. This example produces the same effect:
mob/var/clothing/feet
mob/var
clothing
hands
torso
Provisos
Just do not make a mistake like the following:
mob/var
/clothing/feet
Beginning a path with '/' effectively ignores whatever indentation may
precede it. That is why it is called an absolute path. The above
example would therefore be the same as the following, which is not what you
want:
mob/var //empty variable definition
clothing/feet //definition of object type /clothing/feet
On a related note, parameter definitions in procedures should not begin
with a "/".
mob/Move(atom/Dest) //correct
src << "Moving to [Dest.x],[Dest.y]."
return ..()
mob/Move(var/atom/Dest) //ok
mob/Move(/atom/Dest) //WRONG
Essentially, "var/" is prepended to each entry in the parameter list.
procs
- See also:
- arguments (proc)
- procs (area)
- procs (mob)
- procs (obj)
- procs (turf)
- vars (procs)
Procs may be derived from /proc. These procs are "global", in that they
can be called anywhere in the code.
Example:
proc/poof()
world << "POOF!"
The proc 'poof()' may now be called
anywhere in the code.
Procs may also be attached to objects
by defining them under the appropriate
object/proc subnode. Currently DM allows
procs to be defined or overridden for
/mob, /obj, /turf, /area, and /client, as
well as for data objects derived from /.
Predefined procs are discussed under the
"procs" entry for the object type.
Example:
mob/proc/poof()
world << "POOF!"
This can be called by a mob var M, using 'M.poof()'.
.. proc
- See also:
- . proc
- Format:
- ..(Args)
- Returns:
- The return value of the parent proc.
- Args:
- The arguments to pass to the parent proc. This defaults to the
arguments to the current proc.
If object O is derived from object P, P is called the parent of O. If a
proc (or verb) is defined in both O and P, O can call P's version by using
..().
Example:
mob
P
verb/history()
world << "P"
O
verb/history()
world << "O"
..() // call P.history()
Here O is derived from P. When P calls "history", his name is
displayed. When O calls "history", his name is displayed, followed by the
name of his parent, P.
..() can also be used for predefined procs.
Example:
mob/Move() // override proc
world << "moving..."
return ..() // call default
This proc will print "moving..." whenever
the mob moves.
arglist proc
- See also:
- arguments (proc)
- call proc
- list proc
- Format:
- arglist(List)
- Args:
- List: a list to be used as the arguments to a procedure
Normally, if you were to pass a list directly to a procedure, it would only
come through as a singe argument to that procedure. In some cases, you might
instead want the items in the list to become the arguments to the procedure.
That is what arglist() achieves.
If the items in the list are associations, these are treated as named arguments. Each such list item is
matched against the names of the procedure arguments and its associated value
is assigned to that parameter.
Most built-in DM instructions do not support use of
arglist(), but all user-defined procedures automatically
support it. The built-in instructions which support named arguments will also
support arglist().
The following example shows how to use arglist() with both
positional parameters and named arguments. Both of these examples could be
replaced by a much simpler direct call without need for a list to hold the
arguments; this is just to illustrate the syntax.
Example:
proc/MyProc(a,b)
usr << "MyProc([a],[b])"
mob/verb/test()
var/lst = list(1,2)
MyProc(arglist(lst)) //MyProc(1,2)
lst = list(b=2,a=1) //just to illustrate that order does not matter
MyProc(arglist(lst)) //MyProc(b=2,a=1) --> MyProc(1,2)
named arguments (proc)
- See also:
- New proc (atom)
- arglist proc
- arguments (proc)
The parameters passed to a procedure are called arguments. These may
either be passed in positional order, or they can be passed as named
arguments. Not all procedures are defined with the intention of
supporting named arguments, so consult the documentation for the procedure in
question first. (This is mainly an issue of whether the argument names might
change in the future.)
The following example shows several ways of producing the same call to a
procedure.
Example:
mob/proc/MyProc(a,b,c)
src << "MyProc([a],[b],[c])"
mob/verb/test()
MyProc(1,2,3) //positional parameters
MyProc(a=1,b=2,c=3) //named arguments
MyProc(1,b=2,c=3) //positional and named arguments
MyProc(c=3,a=1,b=2) //named arguments can come in any order
To prevent silent errors, named arguments that do not match any of the
arguments of the procedure being called will generate a runtime error. This
is somewhat different from the behavior of positional arguments in DM where it
is perfectly acceptable to pass more arguments than were explicitly defined in
the procedure.
As always, arguments that are not assigned in the call will simply be given
the value null (or whatever default value is specified in the definition).
When an object procedure is overridden, the variable names in the new
definition are the ones that get matched against named arguments in a call to
that procedure. A procedure which is intended to support named arguments
should therefore be defined with care so as to conform to the interface
expected by users of the procedure. That doesn't stop you from changing that
interface when overriding a procedure, but the normal case would be to
preserve the argument names of the base procedure when overriding it.
The following example is not useful, but it illustrates a situation where a
procedure is overridden so as to preserve the same argument names and
positions. As mentioned above, you are not required to preserve
either the names or positions, but that is usually what you want.
Example:
mob
proc/MyProc(a,b,c)
usr << "mob.MyProc([a],[b],[c])"
mob/verb/test()
MyProc(a=1,b=2,c=3)
special_mob
MyProc(a,b,c,d)
if(d) ..() //pass in same order
else ..(c,b,a) //pass in reverse order
test()
MyProc(a=1,b=2,c=3,d=0) //normal order
MyProc(a=1,b=2,c=3,d=1) //reverse the order
This example merely used positional parameters in the call to
..(), but one can use named arguments there too if it is
desirable.
The best time to use named arguments is when calling a procedure that takes
a lot of optional parameters. You can just name the ones that you want to
assign and leave the rest unspecified. Trying to do the same thing with
positional parameters can be much more awkward--especially when the arguments
you do want to assign are preceded by a number of ones that you don't care to
assign. It's easy to lose your place in the list or to forget what it does.
Since named arguments involve a slight amount of extra overhead, one should
avoid them in code that is highly cpu intensive due to being called many many
times. Otherwise, let code clarity may priority.
browse proc
- See also:
- << output operator
- browse_rsc proc
- file proc
- link proc
- run proc
- Format:
- usr << browse(Body,Options)
- Args:
- Body: html text, file, or null to close the browser.
- Options: optional parameters
This sends the html text or file to the user and optionally displays it in
the web browser. The default action is to use the embedded browser panel in the Dream
Seeker window; specifying an alternate window name (see below) causes it to appear in a
popup window. Passing in 'null' for the html text causes the browser panel or named
window to be closed.
The option parameters should either be omitted or they should be in a text
string of the following format:
"window=name;file=name;display=1;
size=300x300;border=0;can_close=1;
can_resize=1;can_minimize=1;titlebar=1"
You may use commas (,), ampersands (&), or semicolons (;) as the
delimiter. Any or all of the parameters may be specified and they may be
included in any order.
General options
These control how to handle the text or file.
- window
- This is the name used to identify the popup window. It is not visible to
the user. Multiple calls to browse() with the same window name overwrite
previous contents of the same popup window. If window is not specified, the
embedded browser panel will be used.
- file
- When this is unspecified, the client will store the generated html file in the
user's byond "cache" directory with an appropriate name. If Body is a
text string, the client will generate a unique name. If it is a file, it will use
the name of the file. You can override this by setting this parameter. This is
only useful when you need to reference the file later, typically in tandem with the
display setting below.
- display
- This controls whether the browser actually displays Body in the web browser
or not. If it is turned off (display=0), the text or file is simply sent
to the user and expected to be referenced later. This might be useful, for instance, to first send an image to a user and then display a web page that uses that image:
usr << browse('monster.png',"display=0")
usr << browse("
A scary monster appears from the mist!")
Note that this performs the same function as the browse_rsc proc (preserved for legacy reasons). It is a little more powerful because you can use
it to send html text as well as files. In that case, you'll have to also supply the file=name argument so that you can reference the html text from within a later browse().
When display=0, all of the other arguments besides file are ignored.
Popup options
These control how the popup window initially appears. Setting these parameters for
an existing popup window or the embedded browser has no effect.
- border
- This is the width of the border between the edges of the dialogue and the window
content. The default value is 0, meaning that the entire window is filled with
html content.
- size
- This is the size of the popup window in pixels. The format is
WIDTHxHEIGHT.
- can_close
- This specifies whether the window should be closable. The default value
is 1, which enables the standard "X" button for closing.
- can_resize
- This controls whether the window is resizable. The default value is 1,
enabling resizing and maximizing.
- can_minimize
- This controls whether the window is minimizable. The default value is 1,
enabling the standard minimization button.
- titlebar
- The default titlebar=1 enables the standard bar at the top of the window.
Turning it off disables can_close and can_minimize.
Note also that many display options can be controlled through the html
itself. For instance, to turn off the scrollbars, you can do:
<body scroll=no>; to add a title, you can do:
<head><title>My Title</title></head>; and so forth.
The following example displays a help page in a popup window.
Example:
var/const/help = {"
Help!
You are beyond help!
"}
client/verb/help()
usr << browse(help,"window=help")
browse_rsc proc
- See also:
- browse proc
- Format:
- usr << browse_rsc(File,FileName)
- Args:
- File: a resource file (such as an image)
- FileName: name of file (if different from source file)
This sends the specified resource file to usr (or anybody else) and
stores it in their cache directory with the specified name. In
subsequent browse() output, you can then refer to that file.
If your world is always running on the internet, you can save yourself
the trouble and simply link to the image files through a web server.
However, if it may be played offline, you can compile in the resource files
and manually send them to players with browse_rsc().
Note that no data is transmitted if it already exists in the user's
cache, so there is little overhead in calling this every time you are about
to use browse().
Example:
area
var
room_graphic = 'cozy_room.jpg'
Enter(O)
. = ..() //do default checks
if(.) //if we got clearance to enter
O << browse_rsc(room_graphic,"room.jpg")
O << browse("
[desc]")