BYOND 5.0 controls and parameters guide

Build 512

Control overview

  All Window (Main) Label Button Input Output Browser Map Info Child Tab Grid Bar
Size & position pos
  legacy-size   view-size   lock   cells
General appearance is-visible
  is-flat multi-line style
  style multi-line is-vert multi-line show-lines
Color text-color
transparent-color   link-color
User interaction is-default
can-close   is-checked
current-tab current-cell is-slider
Text & title font-family
text text   use-title text-mode allow-html
Images   icon
image   image
auto-format icon-size
Commands on-size macro
  command command   on-show
  on-tab   on-change
Panes   can-scroll

Important terms

Any item in the skin file: A macro, menu, menu item, window, control, etc.
Any piece of the interface that is part of a window (except for a menu). The window itself is also a control.
A window that will appear on the player's desktop and can be moved around.
Acts like a window, but always goes inside another window and does not move around on its own.
A collection of menu items, each with a command. A menu can be attached to a window.
A keyboard shortcut with a command. Macros belong to a set, which can be attached to a window.

Control types

A window or a pane. A window is just the standard type of freestanding window with titlebar, minimize box, etc. (all of which are optional). One window should be a default in your project; it will be the main window. Panes are meant to appear inside other windows, via the Child or Tab controls. A window/pane can be cloned if a copy is needed, e.g. for another scoring grid to put into a Tab control.
Text, a picture, or both.
A pushable button, checkbox, or radio button with text and/or a picture, which sends a verb command when pressed. The command can also be a Dream Seeker internal command like .winset or .host.
An box where commands are typed. It can be set up with a default command that serves as a prefix to anything you type in. If used, one input control should be a default in your project.
Text output, with partial HTML/CSS support. Regular game output normally goes here. If used, one output control should be a default in your project.
A built-in browser (currently IE) that can display regular HTML documents. Good for interfaces that require JavaScript or more advanced formatting than Output provides. browse() without a named window will send anything over to your default browser control. If you use the window parameter in browse(), output will be sent to 1) a browser within a window of that name, or 2) a browser with that name. If neither is available, a generic window (a popup) will be created by that name.
The game map, capable of displaying icons or character graphics. If used, the main map control should be marked as a default. You can use other map controls for secondary displays that support screen (HUD) objects only; see screen_loc in the DM Reference for details. You can also display text on the map via the atom.maptext var.
Traditional BYOND statpanels and verb panels. Partial HTML/CSS support like the Grid control's is available as an option. If used, the info control should be marked as a default. Multiple info controls are not supported, but by putting it in a pane it can be moved to different Child or Tab controls.
A control that holds panes. It can hold one pane which fills its entire space, or two panes separated by a movable splitter. The panes may be swapped in and out at runtime.
A control that holds panes. The tab control can hold multiple panes, which are accessed via the tabs. The title of each pane appears on the tab. Tabs can be changed at runtime.
A flexible grid with partial HTML/CSS support. Only one text style/color per cell is available; background may be set by changing the body element via CSS in a <style> tag. One image may be displayed via the <img> tag, or a BYOND object by sending usr << output(object,grid).
A bar that can be used to show progress, health level, magic level, etc., or used as an adjustable slider. The bar can be straight or formed into an arc. Any area not covered by the bar or slider is transparent, so you can make an arc around another control.

Parameters in detail

ParameterFormatSupported byDefaultMisc. info
aligncenter or left or right or top or bottom or top-left or top-right or bottom-left or bottom-rightLabelcenterDefault alignment of text/image, both horizontal and vertical. A BYOND direction flag like WEST may be assigned to this parameter, or 0 for center alignment.
allow-htmltrue or falseInfofalseAllow HTML tags to be used in stat() info. The same limitations apply as to the Grid control.
alpha0 to 255Main255Opacity; 255=opaque, 0=invisible.
anchor1[x%],[y%] or noneAllnoneAnchors the control within the window/pane. 0,0 is the upper left, 100,100 the lower right. Use one anchor to manage the control's position only, or two to stretch it.
anchor2[x%],[y%] or noneAllnone
angle1[angle]Bar0The angle where the bar's arc starts, if dir is clockwise or counterclockwise. 0 is due north, 90 is east, etc.
angle2[angle]Bar180The angle where the bar's arc ends, if dir is clockwise or counterclockwise. 0 is due north, 90 is east, etc.
auto-formattrue or falseBrowsertrueAdds formatting to the HTML header so Internet Explorer can properly display PNG files with transparency. IE7 does not require this.
background-color#RRGGBB or #RGB or noneAll#fffAffects background color. May not work the same in all controls.
bar-color#RRGGBB or #RGB or noneBarnoneThe color of the bar or slider.
bordernone or line or sunkenAllnoneBorder type around the control or window. May not work the same in all controls.
button-typepushbutton or pushbox or checkbox or radioButtonpushbuttonChanges the type of button. A pushbox is a regular button that can be pushed in (used as a checkbox or radio control). A value of checkbox or radio will make it look like a simple checkbox or radio button.
can-checktrue or falseMenufalseToggle the check on a menu item automatically (or treat it as a radio button, if group is specified) when it is clicked.
can-closetrue or falseMaintrueAllow the window to be closed.
can-minimizetrue or falseMaintrueAllow the window to be minimized.
can-resizetrue or falseMaintrueAllow the window to be resized or maximized.
can-scrollnone or horizontal or vertical or bothMainnoneIf the window is a pane, it will retain its horizontal and/or vertical size and show scrollbars if necessary, instead of shrinking to fit the container.
command"[verb]"Button, Input, Menu, Macro""Command executed when the button, menu item, or macro is activated; or the default command for an Input control. If used for Input, this command is followed by whatever the user types in. For input controls, if your command starts with an exclamation point (!), everything after the ! is shown as a default prompt that may be cleared by the user.
cell-span[columns]x[rows]Grid1x1The span of the current grid cell; it can be merged with cells to the right and down. If is-list is true, this setting is ignored. This setting is only available at runtime.
cells[columns]x[rows]Grid0x0The number of columns and rows in the grid. If is-list is true, this sets the maximum number of items in the list; it can be set to just a single value [items]. Setting the number of rows or columns to -1 means that value will not change.
current-cell[column],[row]Grid0x0The active cell. Any output sent to the grid will go into this cell. If is-list is true, this can be set to 1,[item] or just the item number.
current-tab"[name]"Tab""The name the active/default tab. If set to a tab that is not currently available, the pane by that name will be added as another tab.
dirnorth or south or east or west or clockwise or counterclockwiseBareastThe direction of the bar; as the value increases the bar will move further in this direction. The clockwise and counterclockwise directions will let you make an arc from angle1 to angle2. You can use cw and ccw as shorthand for clockwise or counterclockwise.
drop-zonetrue or falseAllvariesTrue if dragged objects may be dropped here. Default is true for Map, Info, and Grid controls, false for others.
enable-http-imagestrue or falseOutput, GridfalseAllows images to be pulled from the Web when using the <img> tag; otherwise only locally stored images can be shown.
flash[times] or -1All0Set to a value above 0 to make the control flash, 0 to stop flashing, or -1 to flash indefinitely. Currently this is only implemented for window controls even though the param exists for all controls.
focustrue or falseAllfalseTrue if this control has focus; set to true to give it focus.
font-family"[font name]"All""Leave blank to use the default font. This can be used for CSS-style fallback fonts, e.g. "Arial,Helvetica".
font-size[point size]All0Leave 0 to use the default font size.
font-style"bold" or "italic" or "underline" or "strike" or any combinationAll""Sets the font style. Values can be combined if separated by spaces or commas.
group"[name]" or ""Button, Menu""If the button or menu item should be treated as part of a radio button group, this is the name of the group; otherwise group should be blank. Buttons in different windows, or menu items in another menu or submenu, are always treated as a different group.
highlight-color#RRGGBB or #RGBGrid, Info#0f0The color used to highlight moused-over statpanel items or verbs. In grids, this color is used when hovering over objects or links.
icon'[file]'Main""Custom icon used for the window. If this is a pane, its icon will appear on the tab if the pane is inside a tab control. (The Windows .ico format is not used. Only image formats BYOND can already use are supported.)
icon-size0 or [size]Map0Size, in pixels, of icons on map. 0 stretches to fit available space; 32 is the BYOND standard icon size. Use zoom if you'd rather go by a ratio instead of pixels.
id"[name]"Allno defaultThe name of this control. If this is a Main control, (a window or pane) the name should be unique. Other controls can be referenced by [windowname].[controlname] at runtime. Read-only.
image'[file]'Main, Label, Button, Output""Image shown in label/button, or background image for window/pane or output. (Output control: See notes.)
image-modecenter or stretch or tileMain, LabelstretchIf using a background image, this decides how the image will fit the window/pane or label.
index[N] or 0Menu1000Moves the menu item to the Nth position among its siblings. 0 or less is no change.
is-checkedtrue or falseButton, MenufalseTrue if the button or menu item is currently checked. (Set button-type to use this with buttons, or can-check for menus.) Menu items allow manual checking even if can-check is false.
is-defaulttrue or falseAllfalseSpecifies a default control. This should be set to true for your main window, map, info, and main output, input, and browser controls.
is-disabledtrue or falseAll, Menu, MacrofalseDisables the control, menu item, or macro.
is-flattrue or falseButtonfalseDo not give this button a 3D appearance.
is-listtrue or falseGridfalseTrue if the grid is used for a list of items; the number of columns and rows may change to fit them.
is-minimizedtrue or falseMainfalseMinimize the window.
is-maximizedtrue or falseMainfalseMaximize the window.
is-panetrue or falseMainfalseMake this a pane that will be used in Child or Tab controls, not a regular window. Read-only.
is-passwordtrue or falseInputfalseHide text with asterisks. Copy to clipboard is not available in this mode, but the text parameter can still read the control's contents.
is-slidertrue or falseBarfalseThe bar is an adjustable slider instead of a progress bar.
is-transparenttrue or falseAllfalseMay not work for all controls. (See notes.)
is-verttrue or falseChildfalseThe splitter, if it appears, is vertical.
is-visibletrue or falseAlltrueThe main window should usually be made visible.
keep-aspecttrue or falseMain, LabelfalseIf stretching an image, preserve its aspect ratio.
left"[pane name]" or noneChildnoneThe name of the pane that will appear on the left/top side of this Child. If none, the right/bottom side fills the whole space.
legacy-sizetrue or falseOutputtrueWhen true, font sizes are scaled slightly larger for readability, which is legacy (and default) BYOND behavior. Set to false for exact font sizing.
letterboxtrue or falseMaptrueIf map auto-scales its icons, make sure the entire map fits, and fill excess space with blackness. If letterbox is not enabled, zoom to fill the entire available space; any excess will be cut off.
line-color#RRGGBB or #RGBGrid#c0c0c0The color of grid lines.
link-color#RRGGBB or #RGBOutput, Grid#00fAffects unvisited links.
locknone or left or rightChildnoneAllows one pane to "lock" the splitter so if the Child control is resized, the splitter will stay put on that side.
macro"[name]"Main""Macro set to use, if any. Use the name of a macro set defined in the skin file. Not valid for panes.
map-to"[name]"Macro""The macro name of a key combo, Dpad, mouse button, etc. this macro maps to. See macros for more details.
max-lines[lines] or 0Output1000Maximum number of lines before the control drops old text to make room for more. (Extra lines may be allowed to prevent flickering between trims.) 0 is no limit.
menu"[name]"Main""Menu to use, if any. Use the name of a menu defined in the skin file. Not valid for panes.
multi-linetrue or falseInput, Info, TabvariesInfo and Tab: Show tabs in multiple rows if there are too many to fit in a single row; true by default. Input: Create a multi-line input control; false by default. Changing this at runtime will not affect an input control.
name"[label]" or "[key]" or ""Menu, Macrono defaultFor menus, this is the enu item label. A tab character can be used between the name and a keyboard shortcut, like "Help\tF1". (Keyboard shortcuts must be made as macros in order to work.) A blank name shows just a separator. For macros, the name is the key combination such as R+REP or CTRL+Northwest.
no-commandtrue or falseInputfalseIf true, this input control is for typing only; hitting Enter will not run a command.
on-close"[verb]"Main""Command executed when the window is closed. Not valid for panes.
on-change"[verb]"Bar""Command executed when the value of the bar/slider is changed. If you drag the slider around, the command will not run until you let go. In the command, [[*]] is replaced by the new value.
on-hide"[verb]"Map, Browser, Info""Command executed when the default map, browser, or info control is hidden by the game. Usually a .winset command. (Not editable in Dream Maker.)
on-show"[verb]"Map, Browser, Info""Command executed when the default map, browser, or info control is shown by the game. Usually a .winset command. (Not editable in Dream Maker.)
on-size"[verb]"All""Command executed when the control is resized. If you are dragging a window edge or splitter, the command won't run until you finish. No command will be sent in response to size or splitter changes made by winset(). In the command, [[*]] is replaced by the new size.
on-tab"[verb]"Info, Tab""Command executed when the current tab is changed. In the command, [[*]] is replaced by the new tab.
pos[x],[y] or noneAll0,0Position of upper left corner.
prefix-color#RRGGBB or #RGB or noneInfononeThe color used in the prefix/header column, to the left of atoms in the statpanel. If no color is specified, the normal text-color is used.
right"[pane name]" or noneChildnoneThe name of the pane that will appear on the right/bottom side of this Child. If none, the left/top side fills the whole space.
right-clicktrue or falseAllfalseTrue if this control should allow right-clicks to behave like any other click instead of opening up popup menus or similar special behavior.
saved-paramsparameter namesAllvariesA semicolon-separated list of parameters that get saved with this control. This is often used for things a user might set, like zoom level for a map.
size[width]x[height]All0x0Setting 0 for width or height uses up any available space right/downward. If the control is a window, this refers to its interior size, not counting borders, titlebar, menu, or statusbar.
show-historytrue or falseBrowserfalseShow forward/back navigation buttons.
show-linesnone or horizontal or vertical or bothGridbothWhich grid lines are shown.
show-namestrue or falseGridtrueIf atoms are output to the grid, show the atom's name next to the icon. If the atom has no icon and show-names is false, the grid cell will be blank.
show-splittertrue or falseChildtrueShow a splitter if both the left and right panes are in use. If shown the splitter allows the user to resize the two panes.
show-urltrue or falseBrowserfalseShow URL address bar.
small-iconstrue or falseGridfalseWhen output(object,grid) is sent, show smaller icons (16×16) in this control instead of larger ones (32×32).
splitter0 to 100Child50Percent distance of the splitter, if it appears, from the left/top of the Child control. 50% is an equal split.
suffix-color#RRGGBB or #RGB or noneInfononeThe color used in the suffix column, to the right of atoms in the statpanel that have a suffix. If no color is specified, the normal text-color is used.
statusbartrue or falseMainfalseShow a statusbar (unless this is a pane).
stretchtrue or falseLabelfalseStretch the image for this label. (Deprecated. Use image-mode instead.)
style"[css]"Output, Map, Grid""Custom stylesheet used for the control. For maps, this affects any maptext drawn. In a grid, changing this will not immediately affect the existing cells, which will need to be updated.
tab-background-color#RRGGBB or #RGB or noneInfononeAffects background color for tabs.
tab-font-family"[font name]"Info""Same as font-family, but for tabs.
tab-font-size[point size]Info0Same as font-size, but for tabs.
tab-font-style"bold" or "italic" or "underline" or "strike" or any combinationTab""Same as font-style, but for tabs.
tab-text-color#RRGGBB or #RGB or noneInfononeAffects foreground text for tabs.
tabs"[tab names, comma-separated]" or "+[new tab name]" or "-[tab to remove]"Tab""The names of the panes that will appear as tabs, in order, separated by commas. Precede with "+" to add tabs to the current list without removing any, or "-" to remove only the tabs you specify.
text"[label]"Label, Button, Input""Text shown in label/button/input. For input controls this setting is only available at runtime.
text-color#RRGGBB or #RGB or noneAll#000Affects foreground text.
text-modetrue or falseMapfalseShow text mode even if icons are available. Text mode will be used if no icons are present, regardless of this setting.
text-wraptrue or falseLabelfalseWrap text within the label.
title"[title]"Main""The title that would be shown in a titlebar, or in a tab if this is a pane.
titlebartrue or falseMaintrueShow a titlebar (unless this is a pane).
transparent-color#RRGGBB or #RGB or noneMainnoneColor in background image to make transparent; this will affect all controls.
type[TYPE]Allno defaultThe type of control. Read-only.
use-titletrue or falseBrowserfalseUse the browser's title to override the title of the window/pane holding it.
value0 to 100Bar0The "fullness" of the bar or slider, as a percentage.
view-size[size]Map0Size, in pixels, the area the map is using (or trying to use) for display, not including any of the "letterboxing". If icon-size is not 0, this value may be bigger than the control's actual size. Read-only.
visited-color#RRGGBB or #RGBOutput, Grid#f0fAffects visited links.
width[width]Bar10Width, in pixels, of the bar or slider. 0 uses all available width.
zoom0 or [size]Map0Zoom factor for icons on map. 0 stretches to fit available space; 1 will show the icons at their normal size, 2 at double size, 0.5 at half size, and so on. This is a companion to icon-size, which does the same thing but uses an exact pixel size instead of a ratio.
zoom-modenormal or distort or blurMapnormalControls the way a map is scaled up. The normal setting tries to keep the look of individual pixels, but will adjust to non-integer zooms (like 1.1x) by blending neighboring pixels; this produces best results on most games. The distort option will add duplicate rows/columns of pixels, or drop them, as needed to fit the requested zoom size. (At integer zoom sizes, normal and distort are identical.) The blur option uses bilinear sampling. When the map is downscaled, bilinear sampling is always used.

Further details


Each window, pane, or control has an ID. This is used for winset(), winget(), winclone(), winshow(), winexists(), and output().

The ID needs to be unique for a window or pane, but other controls don't have this restriction. If a control ID is unique, you can interact with it by just using that ID; otherwise, you'll need to use "[window_id].[control_id]" to reference it.


For regular input/output, when a control isn't named specifically, BYOND will use whatever controls you specify as defaults.

If two controls of the same type are marked as defaults, the first one in the skin is considered the true default.

It is generally not a good idea to change is-default at runtime. Instead, default controls can be more easily placed in a pane that can be moved around. If you want swappable window layouts for the main window, the easiest way to handle that is to use panes as well, and just put a Child control in the main window.


By using one anchor, you can hold your control in the same relative position in the window/pane as it resizes. Using two anchors, you can stretch it.

The control will stay positioned in the same place relative to the bottom center of the window. This is a good place for an OK button.
anchor1=0,0 and anchor2=100,0
0,0 is the top left and 100,0 is the top right. The control will stretch left and right, but its height will not change.
anchor1=0,0 and anchor2=100,100
0,0 is the top left and 100,100 is the bottom right. The control will stretch with the window in any direction.
anchor1=0,0 and anchor2=50,100
0,0 is the top left and 50,100 is the bottom center. The control will stretch with the window height-wise, but width-wise it will stretch only half as much.

anchor1 is meant to be the top left anchor, and anchor2 is the bottom right. If you set up anchors in the wrong order, weird things can happen.

Client-side commands

Several commands can be executed at runtime that are not verbs, but raw instructions for Dream Seeker.


You can change the default font of almost any control by changing the following parameters:

The font-family paremeter can be a list of fonts separated by commas, like "Tahoma,Arial,sans-serif", and you can put double or single quotes around a font name if it includes a space, such as: "\"Tempus Sans ITC\",\"Comic Sans MS\",sans-serif".

The list of fonts is done in "first-choice" order just like in CSS, so that if the user does not have the first font on the list installed, the next one will be tried, and then the next, and so on. There are some generic fonts that will always be accepted: sans-serif (a friendly, basic font), serif (like what you see in most books), and monospace (a fixed-width, typewriter-like font).

If you include any .ttf font files in your resources by putting them in single quotes in your source code, they will be temporarily installed on the user's system so they are available to your interface. It is a good idea not to do this with common fonts that most people have, because font files can be large. Also you should be sure the font is OK to distribute. Many freeware fonts can be found online.

var/list/extra_resources = list(\

Use font-size to specify a point size for the font. 0 is the default value, which will just use whatever size the control would normally use.

The font-style parameter can change some of the font's attributes to alter the way it looks. You can choose from bold, italic, underline, and strike as styles. To use more than one, combine them with spaces or commas like "bold,italic". This parameter isn't very picky, so it can accept things like "italics" and "strikeout" and still understand what you mean. It isn't case-sensitive either, so caps are OK.

Some controls have special behavior regarding fonts:

Using winset()

Normally winset() is used to modify one control at a time. The list of parameters to change is in the same format used by list2params():

winset(usr, "tinypane.output", "text-color=#000000;background-color=#ffffff")

Calling the winset() proc with a blank or null control ID lets you modify more than one control at once, just like the .winset command does. To use this feature, each parameter should be listed with its full control_id.parameter name.

winset(usr, null, "tinypane.output.text-color=#000000;tinypane.input.text-color=#000000")

Special .winset commands

You can use the .winset command or the winset() proc to execute a verb, like so:

.winset "command=\"jump\""
winset(usr, null, "command=\"jump\"")

No window or control name is supplied, only the command parameter. Some commands cannot be executed this way, but can only be typed manually or run from Dream Seeker's Options & Messages box.

Another option you have is resetting the skin:

.winset "reset=true"
winset(usr, null, "reset=true")

When resetting the skin, any saved settings (like window position and size) are still kept, as determined by saved-params for each control. Controls created at runtime, including windows made via winclone(), are destroyed. The reset option is provided so that you can reset a user's skin when they reconnect or when they are brought in via link() from another server. Normally the skin will not reset.

Conditonals are also supported, but only for the .winset command used in DS or in skins. The winset() proc in DM does not technically support them. The format is like so:


The condition is the same as any other parameter you might use in .winset, but instead of setting the parameter, it checks to see if it's true. If so, then the parameters in choice1 will be set. Otherwise, the parameters in choice2 are set. This example makes the window background red if bigbutton is checked.

.winset " ? window.background-color=#ff0000 : window.background-color=none"

If you want to look for values that don't match instead of values that do, use != instead of = in the condition.

.winset "!=false ? window.background-color=#ff0000 : window.background-color=none"

The choice2 item is optional.

.winset " ? window.background-color=#ff0000"

Because it's often useful to do more than one thing at a time, choice1 and choice2 don't have to be just one parameter. You can use multiple parameters, but separate them with a space instead of a semicolon.

.winset " ? window.text-color=#ffffff window.background-color=#ff0000 : window.text-color=none window.background-color=none"

Special winget() calls

Calling the winget() proc with a blank or null control ID can return some values that belong to the whole program.

To retrieve more than one parameter at a time, separate them with semicolons:

var/buttons = winget(player, "mainwindow", "pos;size")

The result looks like this:


...and can be decoded using params2list(). That will give you an associative list where list["pos"] is "0,0" and list["size"] is "500x500".

To retrieve the parameters of more than one control at a time, separate the control IDs with semicolons:

var/buttons = winget(player, "button1;button2", "is-checked")

Again the result can be decoded using params2list(). The name of each parameter in the result would be and If you mix two types of controls where one has a parameter that the other doesn't, only the parameters that are available are included in the result. For instance, if you have a window with an Input and two Buttons:

var/form = winget(player, "age;male;female", "text;is-checked")

Your result might look like so:


You can use a wildcard after a window name in winget() to retrieve info about all the controls in a window (including the window itself). winget(player, "mainwindow.*", "image") will return the image parameter (where available) for mainwindow and any controls that are a part of mainwindow. The result would look something like this:


More than one parameter can be used at a time, so if you use winget(player, "mainwindow.*", "size;image"), you will also receive size info about all the controls.

This wildcard format also works with menus and macros. For a macro, it will retrieve info on every individual macro in the set that has an ID associated (so it can be disabled, changed at runtime, etc.). For a menu, it will retrieve info on any menu item with an ID, and also anything in sub-menus.

(Note: The wildcard format is not recursive, except with menus. If you use winget() on all the controls in a window and that window includes a Child control, the Child's panes are not included in the result.)

A wildcard is also allowed for the parameters. If used, it will retrieve all parameters belonging to a control. To conserve bandwidth, this should be avoided; it is mostly intended for special occasions or for working with JavaScript (below)

Winset and Winget via JavaScript

Some games use browser interfaces and want them to interact with the rest of the skin. In the past the only way to do this was by making the JavaScript call a byond: URL and interpreting it in client/Topic(), which made it work like a verb. To read any parameter values, the server had to call winget() which would then have to wait for a reply from the client, all to do things that JavaScript could have done locally if it had a way to communicate directly.

To improve on this and allow better access to the skin via JavaScript, two new URL formats have been added. If window.location is set to these from JavaScript in a browser control, they can be used to interact directly.

Winset URL: byond://winset?id=[element ID]&[property]=[value]&...

This works like an ordinary winset() call from the server, where the id field is the ID of the element to change, and all of the other properties listed in the URL are items to change.

Any text you use other than letters, numbers, hyphens, commas, and periods should be encoded via the encodeURIComponent() function in JavaScript.

As with normal winset(), you can leave the ID blank and specify each property fully, such as

Winget URL: byond://winget?callback=[callback function]&id=[element ID/list]&property=[property/list]

In this winget, the IDs and properties you want can be separated by commas if you want to retrieve more than one.

The winget operation works via a callback function you must define in JavaScript. The callback is given just one argument, a JavaScript object with all of the properties you requested. For example, this URL:


...might send this to the callback function wgcb:

  'is-checked': true,
  'size': {
    x: 60,
    y: 20
  'background-color': {
    value: 'none',
    isDefault: true,
    red: 236,
    green: 233,
    blue: 216,
    alpha: 255,
    css: '#ece9d8'

The property names will be in the same format you would expect from winget(), so when you're looking at multiple elements' properties, you'll get the full names in format. The values are always sent back in a convenient form for JavaScript to work with; in the case of size, position, and color these will always be objects.

An optional "control" parameter for the winget call can be used if you want to send data to a callback in a different browser control.

winexists() results

When you use winexists() to check on whether a control exists, it will return one of the following values as text:

Windows and panes

At this time, a Main control is either a window or a pane, and stays that way for life. Panes do not have most of the options a window does; those settings, such as statusbar, are irrelevant for the pane. Only panes can be selected into Child or Tab controls.

Windows or panes may be copied via the winclone() proc, and windows can be shown or hidden via winshow().

Any window or pane in your skin file is loaded immediately, even if it is invisible and not used yet.


Menus can be changed at runtime just like controls. They support a more limited set of parameters. To alter a menu item or add items under it, it needs to have an ID. These are the parameters that can be changed using winset():

A new item can be added to a menu at runtime by including a parent parameter, which points to the ID of a menu or one of the items in it. If you have a menu with an ID of "mainmenu", for instance, this will add a Players menu beneath it:

winset(usr, "playersmenu", "parent=mainmenu;name=Players")
  var/itemname = "playermenu_[C.ckey]"
  var/command = "view [C.ckey]"
  winset(usr, itemname,\

Menu items that were added this way can also be deleted again by setting their parent to a blank value.

A menu can also be cloned with winclone. To use the menu, use winset() to assign it to a window.


Macros are used to convert keyboard and gamepad events into actions. There are two ways this works: A macro can run a command, or in some cases (such as gamepad controls) it can be used to remap one control to another.

Macros can be changed at runtime. If a macro does not have an ID, you can refer to it by its key combination. If you have a macro set named macro1 and have a Ctrl+E macro for instance, you could use winset() with "macro1.Ctrl+E". These are the parameters that can be changed using winset():

The name is actually the full key combination as it would appear in the macro editor, like CTRL+E, Space+REP, or Alt+Shift+F1. This is not case-specific and it doesn't matter where you put modifiers like CTRL+, SHIFT+, etc.

A new macro can be added to a macro set at runtime by including a parent parameter, which points to the ID of an existing macro set. Using the example above, Ctrl+E could be added as a macro at runtime like so:

winset(usr, "myCtrlEmacro", "parent=macro1;name=Ctrl+E;command=exit")

Macros that were added this way can also be deleted again by setting their parent to a blank value.

winset(usr, "macro1.myCtrlEmacro", "parent=")

A macro set can also be cloned with winclone. To use the macros, use winset() to assign the macro set to a window.

The map-to parameter is used by mappings, which are like macros but are used to convert gamepad inputs easily and quickly to keyboard inputs. E.g., GamepadLeft can map to West which is the left arrow key. A set of default mappings will be added automatically at runtime if you don't include any gamepad mapping in your project (see the Any macro note below for more info).

Available macros

Macro modifiers are part of the macro name, and control the conditions in which the macro will fire.
SHIFT+This macro only counts if either Shift key is pressed.
CTRL+This macro only counts if either Ctrl key is pressed.
ALT+This macro only counts if either Alt key is pressed.
+REPIf a key/button is held down, this macro repeats.
+UPThis macro fires when the key/button is released.
Keyboard keys are the garden-variety macros. (This list is abridged to exclude keys probably no one has.)
A - ZLetter key
0 - 9Number key
Numpad0 - Numpad9Numpad numbers
NorthUp arrow
SouthDown arrow
EastRight arrow
WestLeft arrow
NorthwestHome key
SouthwestEnd key
NortheastPage Up key
SoutheastPage Down key
CenterCenter key (numpad)
ReturnEnter / Return key
EscapeEsc key
TabTab key
SpaceSpace bar
BackBackspace key
InsertIns key
DeleteDel key
PausePause key
SnapshotSnapshot / Print Screen key
LWinLeft Windows key
RWinRight Windows key
AppsApps key
MultiplyMultiply key
AddAdd key
SubtractSubtract key
DivideDivide / Slash key
SeparatorSeparator / Backslash key
ShiftShift key (when not used as a modifier)
CtrlCtrl key (when not used as a modifier)
AltAlt key (when not used as a modifier)
Special macros
AnyA special macro that can run a command on press/release of any key or gamepad button. UP is the only modifier allowed. In the command, [[*]] is replaced with the key/button name.
GamepadRawCaptures raw input from a gamepad, without regard to the adjustments done by the Gamepad Setup dialog. In the command, [[id]] is replaced by the name of the button or axis changed ("Button0" through "Button15" and "Axis0" through "Axis11"), [[value]] is replaced with the value of the button or axis, and [[*]] is equivalent to "[[id]] [[value]]" without quotes.

Special notes:

If no gamepad mappings are included in a game's interface, the default mappings are used instead, which will map the Dpad buttons to the arrow keys. This will cause the Any macro to register both a gamepad directional button and the mapped key on the same press. If you plan on using macros to capture gamepad input, you may wish instead to map any one of the directional buttons to "None", which will override the default gamepad mappings completely.

Gamepad buttons can use another gamepad button as a modifier (but not CTRL, SHIFT, ALT), and can be mapped to one or two keyboard keys or mouse buttons.
GamepadFace1A (Xbox), X (PS), bottom of diamond
GamepadFace2B (Xbox), Circle (PS), right of diamond
GamepadFace3X (Xbox), Square (PS), left of diamond
GamepadFace4Y (Xbox), Triangle (PS), top of diamond
GamepadL1Left top shoulder
GamepadR1Right top shoulder
GamepadL2Left bottom shoulder
GamepadR2Right bottom shoulder
GamepadSelectSelect / Back
GamepadStartStart / Forward
GamepadL3Left analog click
GamepadR3Right analog click
Directional buttons: only one can pressed at a time, and the diagonal buttons are virtual.
GamepadUpUp button
GamepadDownDown button
GamepadLeftLeft button
GamepadRightRight button
GamepadUpLeftUp+left virtual button
GamepadUpRightUp+right virtual button
GamepadDownLeftDown+left virtual button
GamepadDownRightDown+right virtual button
Gamepad analog sticks can have commands and/or map to GamepadDir, GamepadDir4, or Mouse. They can use a gamepad button as a modifier. In a command, [[x]] and [[y]] are replaced by coordinates, and [[*]] is replaced by both with a comma for separation.
GamepadLeftAnalogLeft analog stick
GamepadRightAnalogLeft analog stick
Gamepad Dpads†‡ can have commands or are used as mapping targets for analog sticks. A gamepad button can be used as a modifier. In a command, [[*]] is replaced by a direction number, which can be 0.
GamepadDirDpad, converted to one of the eight standard directions.
GamepadDir4Dpad, converted to a cardinal direction.
Mouse "macros" can only be used as mapping targets for another macro.
MouseThe mouse cursor, mappable by a gamepad analog stick.
MouseLeftButtonLeft button, mappable by a gamepad button.
MouseRightButtonRight button, mappable by a gamepad button.
MouseMiddleButtonMiddle button, mappable by a gamepad button.

Special notes:

All of the gamepad macros defined above apply to the first gamepad. BYOND can now support up to four gamepads, and you can replace Gamepad in the names above with Gamepad2, Gamepad3, or Gamepad4 to access them. Each gamepad also has its own raw macro (i.e., Gamepad2Raw).

If you use a Dpad macro like GamepadDir as a map-to target, you don't have to specify gamepad 2-4 in map-to; the mapping will automatically know that when Gamepad2LeftAnalog is mapped to GamepadDir, it means Gamepad2Dir.

Using winclone()

The winclone() proc can copy a window, pane, menu, or macro set from the skin file. It takes three arguments: The user, the name of the skin element to copy, and the name of the new clone.

winclone(player, "helpwindow", "helpwindow_howtoplay")

When you copy an item that exists in the skin file, any items that belong to it are also copied. If the helpwindow element in this example had a browser control called helpwindow.browser, then the new window would have a control called helpwindow_howtoplay.browser just like it. This would be useful if you had several different kinds of help topics the user might want to look at at the same time.

You can also use winclone() to create a brand new element. If the name of the original is "window", "pane", "menu", or "macro" and an element by that name does not already exist in the skin file, an element of that type is created. So for instance, you can create a brand new menu:

winclone(usr, "menu", "newmenu")
winset(usr, "newmenu_file", "parent=newmenu;name=File")
winset(usr, "newmenu_quit", "parent=newmenu_file;name=Quit;command=.quit")

You can also create a new window or pane this way.

// Create the pane
winclone(usr, "pane", "newpane")
// Give it a size so we can figure out where to put controls
winset(usr, "newpane", "size=100x100")
// Add controls
winset(usr, "newpane_label", \
// Put the pane in a child control where it can be seen
winset(usr, "a_child", "left=newpane")
usr << output("newpane_label", "New label")

After you have cloned something or created a control at runtime, you can delete it like so:

winset(usr, "clonedwindow1", "parent=none")

Grids and Info

The grid and info controls support limited formatting using HTML and CSS. Specifically, those limits are:

You can send output to a particular grid cell without having to use winset() first to change the current-cell. Instead of just using the grid's ID in output(), use "[id]:[column],[row]" instead. Or if the grid is using is-list, "[id]:[item]" will do.

usr << output("This is cell 3,2", "mygrid:3,2")

Very important: If you send an atom to a grid like you would with a statpanel, keep that object in a list or make sure it actually exists somewhere in the world. Do not use a temporary object that will be deleted when the proc ends, or it can disappear/change in the grid when a new object is created. Statpanels don't have this problem because of the way they update, but it's a good idea even there not to use temporary atoms.

Mouse actions and drop-zone

Any atom that you have made draggable can be dragged from wherever it appears: the map, the info control, or a grid. Those same controls are set up as drop zones by default, meaning you can drop the atom there and get MouseDrag() and MouseDrop() messages.

When drag or drop involves the map, src_location or over_location will be a turf, or null.

When drag or drop involves the info control, src_location or over_location will be the name of that statpanel.

When drag or drop involves the grid, src_location or over_location will be "[column],[row]", or just a blank "" string if no cell is involved. If the grid has is-list turned on, then "[item]" is the location instead.

Clicking or double-clicking an object will also send the same kind of information.

The new mouse commands are formatted like so:

(Note: In BYOND 3.5, MouseDown() and MouseUp() included icon_x and icon_y arguments. These now belong to params. Old game files will still run as expected, but if you recompile an old project that uses these, you will need to make changes.)

The params argument is a text string which can be decoded using params2list(). Mouse parameters may include:

Creating or deleting controls at runtime

Controls in a window or pane can be added or deleted at runtime. (Only controls you add at runtime can be deleted.) To create a control, you need to supply a parent parameter with the ID of the window or pane that will hold the control, and type which is one of the available control types.

var/list/params = new
params["parent"] = "mywindow"
params["type"] = "button"
params["text"] = "New button"
params["command"] = "say \"This is a new button.\""
params["pos"] = "10,10"
params["size"] = "80x20"
params["anchor1"] = "0,0"

winset(usr, "newbutton", list2params(params))

The ID of this button will be newbutton, which in full form is mywindow.newbutton.

Note: At the present time, adding a control will not work through the .winset command that can be used in macros or menus, or typed in an input box. Only using the winset() proc inside the program's code will work.

Controls that were added this way can also be deleted again by setting their parent to a blank value.

Special control/parameter notes


Anchors currently can't be changed at runtime.

Changing is-default at runtime may cause unpredictable results.

The is-transparent setting has very limited support. At present, only the label control supports this, and it will not repaint properly if placed on top of another control except for bar controls or another transparent label.

If transparent-color is in use for the window housing this label and that color is the label's background (or foreground), ClearType font rendering in Windows will cause drawing artifacts.


The default window's title is not used; the current value is used instead.

can-close should be left on for the default window, even if you don't use a titlebar, to allow easy access to Options & Messages from the taskbar and allow the window to close. It will not make a close box appear if titlebar is false.

Non-default values for transparent-color or alpha trigger drawing bugs when the map is drawn with hardware rendering turned on. Because this setting only works on one color and affects all controls, it may cause other unexpected display issues.

Transparent or translucent windows over a map may cause flickering with hardware rendering on.

If can-scroll is used in a pane, the size parameter refers to the full scrollable area, not the size seen on the screen. If a 2000x2000 pane is scrunched into a 400x400 space and can-scroll is set to both so vertical and horizontal scrollbars appear, size still reports 2000x2000.

If a window does not set icon, the Dream Seeker icon is used by default. However if the default window has an icon set, that will be used as the default icon for all windows.


Built-in verbs like .click, and local commands like .winset, are not accepted when typed in by the user. This kind of command can still be entered through the Client menu in the Options & Messages window.


An overflow of 5% of max-lines is allowed, to reduce flicker.

If a background image is used, it will not show up beneath any images that appear in your text output; instead, the background color will be shown there.


background-color affects the splitter color only.

top and bottom can substitute for left and right.