Since the time of its publication, the DM language has been under active development. Fortunately, the core syntax of the language is unchanged. A few aspects of DM have been extended and generalized, and new features have been added for ease of use and in order to accomplish things that were not possible before.
This addendum covers the most noteworthy changes and additions that have been made since the first edition of the Guide, which comprehensively covers BYOND 2.0--still the fundamental core of the DM language.
A few minor syntax changes had to be made in order to improve the language.
In most cases, the old syntax is still accepted, but in a few cases, the
compiler will issue a warning and recommend the use of the new preferred
syntax. These changes are discussed in the following sections.
Hyperlinks may be embedded in text so that when the user clicks on them,
The preferred syntax is now to use '?' in place of '#':
This has proven to be a better standard now that DM can be used to create
pure web applications (see BYOND web programming).
In addition to that minor change, better support has been added for
multi-valued href parameters. Previously, it was up to the programmer to
parse the href text in In order to take advantage of that, all you have to do is use the standard
form for "query" URLs. The portion after the '?' (the "href" portion) has
the following "key=value" form:
In DM, the '&' may be used interchangeably with ';' as the delimiter,
since this is also the new recommended standard on the web.
The final change to preferred URL syntax is in how the " Now, it may be passed anywhere in the href text, using the new key=value
parameter list syntax:
As before, if no It is worth mentioning that one very handy way of generating these
key=value text strings is to use list2params(). It now automatically applies
The procedures In order to support arbitrary file types, a slight change had to be made to
the old behavior in which That makes it possible to store any type of file; it used to only work with
savefiles.
The The The A number of important features have been added to the DM language. The
intention was to freeze development for a while after BYOND 2.0 came out, but
nothing could be further from what actually took place!
From the standpoint of elegance, the most important development has been
the addition of object types that bring together all of the built-in DM
objects.
Since the atomic objects This naturally lead to the creation of various "ancestors" in the type
tree. The new entries are listed below:
All object types at the top level are implicitly derived from
Of course, types at lower levels of inheritance are still derived from the
type "above" them, just like they used to be, unless The upshot of all this is that you can add properties to all objects, all
atomic objects, or all movable objects by simply defining new procedures or
variables in the ancestor object types. Previously, one sometimes had to
resort to defining the same procedure once per atomic object type, which was
silly.
It also allows you to create new atomic objects that behave as "siblings"
of the built-in ones. For example, you might want to have separate
In general, this allows you to choose between the hierarchical type tree
and a more flattened out approach with more top-level or near top-level types.
Another important advance in DM syntax since BYOND 2.0 is the addition of
named arguments. The normal method of passing arguments to a procedure is to
use positional arguments. However, procedures with many independent
optional arguments can become rather awkward to use.
The solution is to pass the arguments by name rather than by position. In
general, you may pass any number of positional arguments first (typically the
required ones) followed by any number of named arguments.
A good example of this is the As you can see, the named arguments are passed by simply assigning the name
of the parameter to the value you wish to pass. They may be passed in any
order, since the name rather than the position is used to identify the
argument.
A significant amount of extra mouse control has been added. In BYOND 2.0,
just The reference contains a good overview of all of the mouse-related features.
One of the best developments since BYOND 2.0 allows for much greater
freedom in the graphical interface. You can create objects that appear in and
around the map display in Dream Seeker, such as toolbar objects, graphical
stats, and fancy frames. See
screen.
In addition, a couple variables have been added to allow you to turn off
aspects of Dream Seeker's interface that you do not want visible. See
show_verb_panel and
show_map.
BYOND now allows objects to have pixel offsets. This means that they need
not be confined to a single-tile, as in previous versions. This is strictly a
visual effect, but it can greatly improved the graphics. See pixel_x and
pixel_y.
The map view size may now be set on a player-by-player basis and it is no
longer restricted to being square. For example, the following sets the
default view size to 17x13:
See
client.view and world.view
for more information.
The layer in which an object's icon is drawn used to be fixed by the type
of object, but it is now configurable via the See
layer in the DM Reference for details.
A number of extra controls have been added to the vision system, including
a full range of invisibility levels, infravision, night vision, independent
verb visibility, and a choice between "mob" and "eye" perspectives in the
player's view.
More information:
As noted already, To get the old behavior in which A new DM contains built-in features that allow you to easily link up to a
centralized database known as BYOND Hub. It is by no means a requirement that
this be used, but it has turned out to be an enormously important capability.
You must register your world with BYOND Hub to take
advantage of the hub features. Your game is then identified by a "hub path"
of the form YourKey.GameTitle. This text string is case insensitive,
and all punctuation and spaces except for "." are also not significant.
By assigning The hub also provides a subscription database. You can configure your hub
entry to support
BYOND Passport, in which case, users who subscribe (or who you invite),
can be identified in a game by doing a passport check.
When you enable BYOND Passport, a master passport ID is assigned to you.
You simply pass that to This is a very versatile mechanism, since you can choose to do whatever you
want in response to a subscription. It's also possible to distribute software
directly through the hub and, of course, that gives you the additional option
of limiting who may download the game based on subscription, a more
traditional approach to paid software usage.
Another generalization of DM syntax is the addition of modified
types. Anywhere that you can use a type value in DM (shuch as in new()
or newlist()), you can make simple initializations of variables using the
following syntax:
path {var1 = val1; var2 = val2}
This syntax is the same as that used in Another major area of development since BYOND 2.0 has been an improvement
in the resource file transmission system. Icon and sound files can be
downloaded by Dream Seeker on demand, all at once, or some combination of the
two. It is also possible to create resource packs that are distributed from a
web server, rather than from the game server itself, saving bandwidth on the
machine hosting the game.
All of this is accomplished through a variable called
client.preload_rsc, which you can read about in the DM Reference.
All changes of note to the DM Reference since BYOND 2.0 are listed below:
URL syntax
Topic(href)
gets called (page 78 section 7.6). Previously, the
"href" text that got submitted back to client/Topic()
was
specified in the hyperlink using '#' as the delimiter like this:
" click here "
" click here"
Topic()
and extract multiple values that
might be packed together there. Now the href text is automatically passed
through params2list()
and the result is provided as an additional
argument to Topic(href,href_list[])
.
"key1=value1&key2=value2&..."
src
"
of Topic()
is encoded in the href text. Previously, the object
intended to handle the Topic()
call was embedded directly at the
beginning of the href text like this (page 78 section 7.6):
"#\ref[Object]..."
"?key1=value1&...&src=\ref[Object]&..."
src
is specified, client/Topic()
is expected to handle it. Otherwise, the default behavior of
client/Topic()
is to call the specified object's
Topic()
procedure.
\ref
to object values, so things such as the following are
possible:
mob/verb/test()
var/href[0]
var/url
href["src"] = src //call my Topic()
href["data"] = ...
url = "byond://?[ list2params(href) ]"
usr << "Click here to win!"
client-side savefiles
client.Import()
and
client.Export()
may be used to store data on the player's
computer for possible shared use by different worlds (page 139 section 12.5).
These procedures have been generalized to handle other things, including files
stored centrally in BYOND hub for shared use by multiple people (see hublib).
Import()
returned an open savefile. It
now simply returns a reference to the file data, which can then be opened as a
savefile like this:
var/savefile/F = new(client.Import())
Del()
Del()
procedure (page 73 section 7.2.2) has changed in the
way it treats the contents of the object being deleted. Previously, it dumped
these objects to the location of the container object. It now simply deletes
these objects. It is a simple matter to achieve the old behavior if that is
indeed desired:
mob/Del()
var/O
for(O in contents) O:Move(loc)
return ..()
visibility
visibility
variable (a true/false value) has been replaced
by one called invisibility
, which has a range of 0 to 100. Old
code continues to work, but conversion is recommended. See vision for more details.
view
view()
instruction used to ignore any special visual
capabilities (or incapacities) of the mob, and it ignored invisibility of
objects altogether. It now takes these into account. To get the old
behavior, simply do view(usr.loc)
instead of
view(usr)
. See vision
for more information.
New Features
atom, datum, and parent_type
/area
, /turf
,
/obj
, and /mob
are all defined at the "top" of the
inheritance tree, a new construct had to be invented to allow all of these to
share a common ancestor. This is a variable named parent_type
.
It allows an object type to be derived from some other point in the type tree.
datum //ancestor of all objects
atom //ancestor of all atomic objects
parent_type = /datum
atom/movable //ancestor of movable objects
area
parent_type = /atom
turf
parent_type = /atom
obj
parent_type = /atom/movable
mob
parent_type = /atom/movable
/datum
unless parent_type
is pointed to something
else. In the code above, therefore, the statement
atom/parent_type = /datum
parent_type
is applied. For example, there was no need in the above code to make the
statement atom/movable/parent_type = /atom
/player
and /monster
types:
player
parent_type = /mob
monster
parent_type = /mob
Named Arguments
image()
procedure. It used to
just take an icon and a location for the purpose of displaying a particular
icon to selected users. It now takes additional arguments, allowing you to
override the default icon state, drawing layer, and direction.
mob/var
image/shield_image
mob/verb/shields_up()
shield_image = image('shield.dmi',loc = usr,icon_state = "high power")
usr << shield_image
mob/verb/shield_off()
del shield_image
Mouse Interaction
Click()
and DblClick()
were defined. Now there
is support for drag-and-drop, custom mouse cursors, pixel-level clicking,
mouse-over detection, and extra mouse "opacity" control.
Screen Objects
Pixel-Level Graphics
View Size
world/view = "17x13"
Drawing Layer
layer
variable.
This allows for nifty effects such as turfs with "arch" overlays that appear
over the top of people as they walk underneath.
Vision
view()
has been modified to take mob visual
capabilities into account, which is consistent with how it works in the player
interface. If client.eye is not the same as client.mob (often true when using
client.lazy_eye), this still might result in a different list of objects than
what are truly visible to the player. You can take client.eye and other
client-specific settings into account by doing view(usr.client)
rather than just view(usr)
.
view()
ignored visual
capabilities of the mob, simply do view(usr.loc)
instead of
view(usr)
, however, in most situations like that, you would
probably want to use the new procedures viewers()
or
hearers()
, which take into account the ability of other
mobs to perceive the center mob, rather than the ability of the center mob
to perceive the others.
Icon Manipulation
/icon
object type has been added. This may be used to
load icon data into memory for direct access and manipulation. This makes it
possible to dynamically modify colors for multi-player games and a host of
other effects. See
/icon in the DM Reference.
BYOND Hub
world.hub
to the hub path of your game, you make
it possible for players to easily broadcast announcements of live games to
other viewers of the hub. A system of channels exists in the hub, allowing a
game to be published to different audiences, and the default channel(s) in
which live games are broadcast automatically conforms to the publication
settings and, of course, the user's membership in the channel itself.
client.CheckPassport()
client.CheckPassport()
to find out if a
user has a subscription:
mob/var
full_access
mob/Login()
if(client.CheckPassport("0123456789abcdef"))
full_access = 1
else
usr << "For full access, subscribe!"
return ..()
Modified Types
Example:
mob/contents = newlist(
/obj/scroll/readme {
name = "Introduction"
desc = "The fate of Bracolia depends on you ..."
}
)
.dmm
files for object
instances that are edited in the map editor. As stated, these initializations
must be "simple" expressions, but, in general, DM's definition of a "simple"
initialization has expanded quite a bit since BYOND 2.0. For example, it now
supports initialization to a new object or list.
Resource File Transmission
Index of Changes