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.

## Contents

Changed Behaviors
Topic URLs
client/Import()
Del()
visibility
view
New Features
atom, datum, and parent_type
Named Arguments
Mouse Interaction
Screen Objects
Pixel-Level Graphics
View Size
Drawing Layer
Vision
Icon Manipulation
BYOND Hub
client.CheckPassport
Modified Types
Resource File Transmission
Index of Changes

## Changes

### URL syntax

Hyperlinks may be embedded in text so that when the user clicks on them, 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 "


The preferred syntax is now to use '?' in place of '#':

" click here"


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 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[]).

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:

"key1=value1&key2=value2&..."


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 "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]..."


Now, it may be passed anywhere in the href text, using the new key=value parameter list syntax:

"?key1=value1&...&src=\ref[Object]&..."


As before, if no 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.

It is worth mentioning that one very handy way of generating these key=value text strings is to use list2params(). It now automatically applies \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

In order to support arbitrary file types, a slight change had to be made to the old behavior in which 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())


That makes it possible to store any type of file; it used to only work with savefiles.

### Del()

The 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 ..()


## New Features

### atom, datum, and parent_type

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 /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.

This naturally lead to the creation of various "ancestors" in the type tree. The new entries are listed below:

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


All object types at the top level are implicitly derived from /datum unless parent_type is pointed to something else. In the code above, therefore, the statement atom/parent_type = /datum is actually redundant.

Of course, types at lower levels of inheritance are still derived from the type "above" them, just like they used to be, unless parent_type is applied. For example, there was no need in the above code to make the statement atom/movable/parent_type = /atom.

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 /player and /monster types:

player
parent_type = /mob
monster
parent_type = /mob


### Named Arguments

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 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

A significant amount of extra mouse control has been added. In BYOND 2.0, just 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

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.

### View Size

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:

world/view = "17x13"


### Drawing Layer

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 layer variable. This allows for nifty effects such as turfs with "arch" overlays that appear over the top of people as they walk underneath.

See layer in the DM Reference for details.

### Vision

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.

As noted already, 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).

To get the old behavior in which 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.

### BYOND Hub

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 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()

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 client.CheckPassport() to find out if a user has a subscription:

mob/var
full_access

if(client.CheckPassport("0123456789abcdef"))
full_access = 1
else
usr << "For full access, subscribe!"
return ..()


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.

### Modified Types

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}

#### Example:

mob/contents = newlist(
name = "Introduction"
desc = "The fate of Bracolia depends on you ..."
}
)


### Resource File Transmission

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.

## Index of Changes

All changes of note to the DM Reference since BYOND 2.0 are listed below:

DM
garbage
icon
mouse
pointers
__MAIN__
atom
movable
proc
var
animate_movement
pixel_step_size
screen_loc
proc
Entered
Exited
MouseDown
MouseDrag
MouseDrop
MouseEntered
MouseExited
MouseUp
var
infra_luminosity
invisibility
layer
mouse_drag_pointer
mouse_drop_pointer
mouse_drop_zone
mouse_opacity
mouse_over_pointer
pixel_x
pixel_y
client
proc
CheckPassport
Export
Import
MouseDown
MouseDrag
MouseDrop
MouseEntered
MouseExited
MouseUp
SendPage
Topic
var
CGI
authenticate
command_prompt
command_text
default_verb_category
images
lazy_eye
mouse_pointer_icon
perspective
pixel_step_size
screen
show_map
show_verb_panel
view
datum
icon
proc
Blend
Flip
IconStates
New
SetIntensity
Shift
SwapColor
Turn
image
mob
var
see_in_dark
see_infrared
see_invisible
sight
operator
>
<
proc
ASSERT
CRASH
arccos
arcsin
arglist
arguments
named
browse
browse_rsc
cos
fcopy_rsc
fexists
hearers
image
input
ispath
istype
list
pick
roll
sin
time2text
typesof
view
viewers
savefile
proc
ExportText
ImportText
Lock
Unlock
verb
arguments
set
category
invisibility
world
proc
Export
GetConfig
IsBanned
OpenPort
SetConfig
var
byond_version
cache_lifespan
executor
hub
log
status
system_type
url
view
visibility