Edit Mode provides the ability to directly edit the JSON defining all the game elements in a live visual environment. You can add, remove, or edit widgets, execute game elements, and examine debug information that can help you diagnose problems. The images on this page show a mix of light mode and dark mode screen shots.
- Overview
- Top Toolbar
- Menu (Right Sidebar)
- JSON Editor
- Selecting widgets
- Widget Toolbar
- Editing widgets
- Debug
Overview
From the game screens, pressing either Edit Mode or Ctrl-J will enter the Edit Mode. (Another Ctrl-J will return you to normal game mode as will pressing the X in the blue toolbar at the top.) You will be presented with a screen similar to this (note that the content in red in this graphic is a guide to the sections below describing the different areas, and does not appear in the actual editor):
The room with the Game Area takes up the left-hand portion of the screen. Above it is the Top Toolbar with a blue background and white icons. To its right is the Text Display Area, which is currently empty. Following that is a column of icons and clickable buttons with blue and white text called the Widget Buttons area. This is only displayed when showing JSON. On the far right is the Menu. Each of these areas is described below.
Top Toolbar
Across the top of the screen are icons that perform a variety of functions. If an icon is greyed out, it is currently not available (most likely due to the widgets you have selected or not selected). The functions of the icons are described below in icon order from left to right.
Start with a new blank room. This will instantly delete everything in the room and create a new blank room. You can undo this by using the History menu (discussed below), but only if you use the History menu before you leave the room or refresh the browser.
Save changes to the currently loaded game. This feature will open a submenu with several options that allow you to make changes to the game without leaving Edit Mode and going to the Game Shelf:
- Save to Active Variant. This immediately saves the game to the current variant. If a game has not yet been saved, this option is not available. This option is also not available for Public Library games.
- Save as New Variant (of ...). The button name displays the name of the game you are currently working on. This immediately creates a new variant in that game. If a game has not yet been saved, this option is not available. This option is also not available for Public Library games.
- Save as New Game. This button prompts you for the name of the new game and then saves it to the Game Shelf.
- Quick Download. This button will download the JSON, and only the JSON and not the assets, of the current variant. This is NOT the method you should use for saving offline versions of games. This is a simple function for limited purposes.
- Quick Save. This button will create (if it does not already exist) a saved version called "Quicksave". The variant name will be the date and time (UTC) of the save. Each additional press of the button will create a new variant with the new date and time.
- Auto-save every 5 minutes. If checked, this button does the same thing the Quick Save button does, but does so automatically every 5 minutes while you are in the room AND whenever you close out of the editor. This can create many, many Quicksave variants.
Toggle between light and dark mode in the editor. As the description suggests, toggles the background color of the JSON editor portion of the room (on the right) from light to dark.
Toggle fullscreen mode. Does exactly what it says.
Toggles grid lines on and off. When on, you are prompted to choose a pixel size (default is 25px), a color (default is gray), and whether to show thicker lines that divide the room into quarters, thirds, or fifths (default is quarters). When on, the grid lines are also displayed when not in edit mode. All lines are only visible to the user that turned them on and not other players. Grid lines are not visible over a background or other solid widgets. While editing, you can change the opacity of the background/widget to allow the lines to show through or set the layer to -11 or lower.
Close the editor and return to playing the game. Does exactly what it says. Pressing Ctrl-J does the same thing.
Undo the last change. Works in conjunction with the History menu to go back one change for each press of the button (or the hotkey z). It undoes virtually everything, including dragging widgets manually and the routine operations of buttons. The only way to redo something you just undid, however, is to use the History menu.
Toggle between drag to move and drag to select. When you first enter Edit Mode, the primary mouse button (usually the left), continues to operate in "game" mode. This means that you use the primary mouse button to click on buttons in the Game Area to interact with those widgets as if you were not in Edit Mode. The secondary mouse button (usually the right), is how you select and interact with the widgets in Edit Mode. This icon toggles that behavior so the primary and secondary mouse buttons swap roles. If there is a third mouse button/clickable scroll button, clicking it always acts in game mode.
Toggle between the normal view and a zoomed out view that allows you to see widgets that are hidden off screen. In many rooms, some widgets are maintained offscreen and out of the view of the players. This button zooms out to display an expanded area outside of the regular playing surface. By setting sufficiently large or small values of x/y in individual widgets, they can be located even outside of the area visible using the zoomed out view.
Add a new widget. Opens a pop-up screen to allow you to add a new widget (same as pressing the hotkey a).
Delete the selected widgets. All currently selected widgets will be deleted (same as pressing the hotkey Delete).
Align the selected widgets to the left. All selected widgets will be aligned to the lowest x value of the widgets (same as pressing the hotkey ArrowLeft).
Align the selected widgets to the center. All selected widgets will be aligned to the average x value of the widgets.
Align the selected widgets to the right. All selected widgets will be aligned to the highest x value of the widgets (same as pressing the hotkey ArrowRight).
Align the selected widgets to the top. All selected widgets will be aligned to the lowest y value of the widgets (same as pressing the hotkey ArrowUp).
Align the selected widgets to the center. All selected widgets will be aligned to the average y value of the widgets.
Align the selected widgets to the top. All selected widgets will be aligned to the highest y value of the widgets (same as pressing the hotkey ArrowDown).
Equalize the spacing between the selected widgets horizontally (same as pressing the hotkey h). Use this to create an even horizontal distribution across the selected widgets. This uses the far left and the far right widgets as anchor points that will not be moved.
Equalize the spacing between the selected widgets vertically (same as pressing the hotkey v). Use this to create an even vertical distribution across the selected widgets. This uses the topmost and the bottommost widgets as anchor points that will not be moved.
Change the layering of the selected widgets so that the bottom and right most widgets are on top. You can optionally use this when duplicating widgets. (Depending on the direction of the duplication, widgets may otherwise be hidden because of the widget layering. This changes the z-value so the bottom and right most widgets are on top.)
Group the selected widgets by inserting an invisible parent widget. Each of the selected widgets will become the child (in the same relative position) of a newly created parent widget.
Menu (Right Sidebar)
When clicking on a Menu button in the Right Sidebar, the Text Area will be filled with information based on which button you press. If you Ctrl-Shift-click (on PC; Mac not tested), the menu item you select will display on top of and cover the game area. This is a good way to view very detailed JSON or debug information. Also, if you click and hold and drag the menu label to the left, you will see dotted red lines dividing the Text Area into 4 separate areas. You can drop the menu label being dragged into one of those areas and customize your workspace. For example, in the image below, the JSON (including the blue and white buttons that are part of the JSON Editor) are in the top left, debug output in the top right, widget tree in the bottom left, and history in the bottom right. Finally, the size of the Text Area in relation to the Game Area can be changed by placing the mouse over the right edge of the visible room Game Area until the cursor changes to a double-ended arrow. Then drag that dividing line to resize the Game Area.
-
When no widgets are selected. Select one of the radio button options to either generate a custom deck of cards by choosing suits and properties or by uploading individual images, groups of images, or tiles of images. After following the prompts, the deck will be added to the room (but not placed into a holder). You can also select the number of each type of card to immediately add to the room.
-
When a widget is selected.
a. If the widget selected is anything but a card or a deck, the Text Area will display key attributes in table form about each selected widget. You can directly change those attributes by changing the text displayed for each attribute.
b. If the widget selected is a card, you see the card properties, which can be changed directly. It also shows information about the card type. There you can immediately add or remove the count of that type of card in the room or click on the edit button below the card to make additional changes to the details from the card's faceTemplate.
c. If the widget selected is a deck, you see all of the card types. There are buttons to add or remove one of every card type of each button press. Or you can individually add or remove cards or edit data from the cards' faceTemplate. The deck view also shows how each individual layer from the faceTemplate looks for each card face. Finally, you can also view and edit the cardDefaults from this deck view as well.
(Note: Some changes in the deck manager are instant and some require you to push the apply changes button. Instant: adding or removing cards using +/- buttons; card default properties, and card properties if viewing a single card and not the whole deck. Button approval: card layers and edits to cardTypes properties on individual cards.
-
The Text Area displays the history of the changes made in the room (through Edit Mode and regular game play). The list is not infinite, but should be sufficiently long to fix most issues. Click on any numbered row (that when possible, includes which player made the change and what widget was changed) to return the room to the state after the described action. You can click on a higher numbered row to return to a later state, but only up until a new change is made after returning to a past state. WARNING: the history operation may occasionally glitch. It is a best practice to make regular backups or saved states of your room.
-
Displays the JSON for the selected widget. More details on viewing and editing JSON are in several of the following sections.
-
This is a method for adding widgets to the room and for saving to local storage widgets and groups of widgets that are frequently used. More on this at the bottom of this section in Widgets Menu Item.
-
Displays a list of widgets in the room. The tree is displayed alphabetically, but widgets that are children of other widgets are listed under the parent. A filter bar is displayed at the top of the tree. Typing text there will limit the displayed widgets to those matching the typed text. The filter uses the widget id and widget type, so typing "button" will display any widgets of the
typebutton or that have "button" anywhere in theirid. Also, you can filter by properties. For example, type "text:small" will filter to only those widgets with a text property containing the word small. The tree displays the widget id in yellow and in parenthesis after that, the type in green and the x,y coordinates in purple. A widget with children will have a white arrow next to it. Click on the arrow to expand (or collapse) the list of child widgets. -
Displays the debug information for recently activated routines. See the Debug section below.
-
Allows you to download all assets (images) from the game to a zip file. Also allows you to easily compress most assets into smaller file size. After compression, remember to save your variant for the changes to become permanent.
- The first allows you to save the currently selected widget(s) and all of the child widgets to a buffer to transfer them to a different room. To use, go to the room with the widgets you want and select them in the Editor. Then click on the Toolbox menu button. On the following pop-up screen, click on the Save Widgets to Buffer button. Then go to the room you want (using the same browser, but it can be in a different tab), then click the Put Widgets into the Game button. If you click it more than once, the widgets will not be duplicated.
- The second allows you to search and replace text on all widgets in the room. Use this to change the name of a property or its value every place it appears in the room. Match case and Match whole word are checked by default. Use caution making changes without those buttons checked as you could inadvertently make changes in places you did not intend. You should usually be able to use the history Menu button to undo the changes.
- The third allows you to align a group of selected widgets in a circle.
- If Legacy Mode is active for the current game, a Legacy Mode section will be displayed. The yellow circle notification next to the gear icon shows how many legacy modes are currently active.
- UI settings allows you to change how other players' cursor indicators appear for the game variant. The same setting is used for all players.
- Global Room CSS allows custom CSS to be applied throughout the game variant. This uses traditional CSS syntax rather than the syntax needed for JSON. You can see samples of this at Useful Global CSS Snippets.
Widgets Menu Item
When you click on you get a system for adding and managing widgets that looks like the following:
At the top, you get a legend explaining the orange lightning bolt and the red star. The red star is just a visual reminder that normally there will only be one of those kinds of widgets in a room. The orange lightening bolt means that a routine will be triggered when the widget is added to the room. For example, game pieces trigger a routine to choose a color. Also at the top is a "Filter" search bar. Typing in that bar will limit the results displayed. The filter works on both the name of the widget and the type of widget. Finally, next to the search bar are 4 icons. The first one displays the widgets in a list, as in the image above. The second icon displays the widgets in a grid, as in the following:
The third icon in the top area will save whatever widget or widgets are currently selected. The last icon in the top area
allows editing of widget information as well as uploading and downloading of widgets. When clicked, the display changes to something like this:
Below the top area are two large blue bars: "On The Server" and "In Local Storage". The widgets on the server are the same ones that can be added from the Add Widget overlay. You cannot edit or change these in any way. If you have clicked the pen edit icon, you can download them using the download button to the right of the widget.
Widgets that you have saved or uploaded from saved files are in the "In Local Storage" area. At the right edge of that blue bar are sort buttons that allow you to sort widgets by time, name, or type in ascending or descending order. You can also create a group of widgets that will be arranged and maintained within their own group. To create a group, drag and drop a widget from the list onto the "+ New Group" label and give the group a name. To add more widgets to that group, drag and drop them from the list onto the group name. Groups will be indicated with dark gray bars. A double line separates the last group from the individual widgets. Once a widget is in a group, it can be dragged to another group but cannot be put back into the list of individual widgets. When sorting, groups are sorted in the same way with the buttons, but will always be listed at the top before individual widgets. Note that these groups are for organizing how the widgets are displayed, like a folder. The widgets still must be individually added to a room. If you want several widgets actually combined into a single widget for purposes of adding to a room, select multiple widgets in the editor before pressing the save icon. They will be listed as a single widget (you should consider changing the name to reflect this), but all of them get added to the room together.
When the pen edit icon is pressed, for widgets in local storage you get several options. You can change the name of a group or widget by typing a new name. You can check the box as a reminder that the widget is "Unique" (and give it a red star in the display). You can delete the widget from the saved widgets (but not the room!) by clicking on the trash can icon. You can download an individual widget to a .json file by clicking on the download arrow icon to the right of the widget. You can download all of the widgets in local storage to a single .json file by clicking on the download arrow icon at the right of the blue bar for "In Local Storage". You can upload a .json file by clicking on the upload arrow icon.
To add a widget to the room, you can click on the plus icon to the right of the widget. This will place the widget in the room at pre-defined coordinates; for custom widgets, this is the x/y values when the widget was saved. You can also drag and drop a widget to any location you want. Widgets get an id based on the id of the widget as it was saved. If more than one widget of the same type is added, then subsequent widgets get a 1, 2, 3, etc. added to the end of their id. If you want to create a widget that triggers a routine when it is added to the room in edit mode, put a editorAddToRoomRoutine on the widget before you save it. It will appear in orange in the JSON unlike other routines. It will be saved with the widget in local storage, but editorAddToRoomRoutine will trigger and then erased from the widget when it is put into the room. This routine type is only for edit mode and not for play mode.
JSON Editor
When JSON is one of the selected Menu items, then a few icons along with text buttons will be displayed in the Text Area. If no widget is selected, then the blue and white button text allows you to instantly add a widget of the listed type (as shown in the image below). When a widget is selected, the buttons change and become context sensitive. See the Editing widgets section below.
Across the top of the Text Area where the JSON has been opened are icons that perform a variety of functions. If an icon is greyed out, it is currently not available (most likely due to the widgets you have selected or not selected). The functions of the icons are described below in icon order from left to right.
Copy state from another room/server. Clicking this button prompts you to enter the full URL to another VTT room. After pressing Go, the current state of that room will be downloaded into the current room and replace all the contents of the current room. If the URL does not specify a valid VTT room, the command silently has no effect.
Macro. This button brings up a JavaScript code snippet in the editing area:
As noted in the comment in the screen, any macro defined here will be executed for each widget in the room. This allows you to code an arbitrarily complex set of actions to take on various widgets. Pressing the macro button again (which now appears as ▶) will execute the macro. [NOTE: Macro execution will proceed without a request for confirmation. It is very easy to completely mess up your room. We strongly suggest that you back up your VTT file before executing a macro. It should be obvious that some knowledge of JavaScript and the code base would be useful if you want to use this feature.]
Show this widget below. This button shows an uncolorized copy of the current widget's JSON at the bottom of the context-specific panel (below the blue and white buttons). This can be useful if you want to navigate to another widget but want to be able to simultaneously view the current widget.
Reverse order of F-key shortcuts. When the mouse is moving over the Game Area, the context-sensitive blue and white buttons are covered with an area that displays F-keys with the
type and id of the widget(s) the mouse is over. Initially, when the mouse is over a point containing multiple widgets, the widgets are assigned F-keys with the topmost widget getting F1. Clicking this button will reverse the ordering so that the bottom-most widget will instead get F1. Note that regardless of this setting, cards are always sorted below (assigned higher F-key numbers) than other widgets, and that widgets owned by a different player are always sorted below cards.
Duplicate widget. Pressing this button will allow you to make one or more duplicates of the selected widget (or widgets, if more than one is selected).
The advantage to using this button over the grid (see the Widget Toolbar section below) is more granular control over the resulting JSON as well as adding an inheritFrom property (discussed on the Widget page in the Global properties for every widget table at Global properties for every widget.
- Increment IDs controls how the widget
idfor created widgets is determined. The default is Numbers. With this setting, the last set of numbers in the source widget will be incremented for successive duplicates. For example,v1x8will have successive duplicates namedv1x9,v1x10, andv1x11. If the source widget has no numbers in it, the first duplicate will have a1appended. Thusvaxbduplicates tovaxb1,vaxb2, and so forth. If you select Letters, the last set of capital letters in the source widget will be lexically incremented. Thus for examplePlayerAis duplicated toPlayerB,PlayerC, and so forth. If the last set of capital letters consists of allZs, the next value will be determined in "Excel style". Thus for example the widgets afterPlayerZZarePlayerAAA,PlayerAAB, andPlayerAAC. If the widget has no capital letters, the first duplicate will have anAappended, similarly to the Numbers case. If you select None, widget copies will be given randomids. - Increment In defaults to
dropTarget, hand, index, inheritFrom, linkedToSeat, onlyVisibleForSeat, text. You can remove any of the default properties from the list or add other standard or custom properties. This setting is ignored if Increment IDs is None. Otherwise, for each of those properties, if theidcontains a number (if Numbers is selected) or a letter (if Letters is selected) and if the the value of that property contains the same number or last capital letter as in theid, then those properties will also be incremented in exactly the same way theidis. For example, if"id":"widget1"and"linkedToSeat":"seat1", then the next copy will have"id":"widget2"and"linkedToSeat":"seat2". - Copy using inheritFrom is not initially selected. Selecting it means that all copied widgets will have the
inheritFromproperty applied rather than duplicating all of the source widget's properties. You can learn more about that at Global properties for every widget. - Inherit properties is ignored if Copy using inheritFrom is unchecked. Otherwise, this allows you to select the individual properties that will be inherited from the specified widget. If the box is empty, all heritable properties will be inherited.
- Recursive is initially selected. Leaving it selected means that all child widgets of the widget(s) being duplicated will also be duplicated and their parent properties will automatically be updated.
- X offset and Y offset each default to
0. Change this (to a positive or negative number) to make the copied widgets appear in a different location on the screen. For example, if the x value is set to 25 and you are making 3 copies of a widget at x coordinate 100, the first copy will be at 125, the second at 150, and the third at 175. - # Copies X and # Copies Y: X defaults to 1 and Y defaults to 0. Use this to set the number of copies across (x) or up/down (y). If you set a value in both x and y, a grid of copies will be made.
Open parent. This button selects the parent of the selected widget. It is disabled if the selected widget has no parent, or if more than one widget is selected.
Toggle wide editor. This button does not work. Its function has been replaced by the magnifying glass button on the Top Toolbar.
Toggle widget highlighting. This button, initially on (yellow), controls whether selected widgets are highlighted in the room. If clicked, the button turns off (white) and the selected widgets will still be highlighted in the Tree display (if used at the same time as the JSON display), but there will be no yellow highlight around the widgets in the room.
Show colors in SVG image. When a basic widget with an SVG image is selected, this button becomes active. Note, it will not work with decks or other situations where the
image property is inside an array or object and is not directly on the widget. Click it to open a display listing the colors in the SVG widget that can be modified by svgReplaces. Click on a color to create a placeholder within the svgReplaces property.
Below that group of buttons and before the long list of wide rectangular buttons is an area that says "Press or hold Tab to search." If the cursor is in the JSON edit text area, then pressing or holding the tab button on the keyboard or clicking that visual indication of the tab button will bring up a filter. Typing when tab is activated will search for other widget ids in the room, will search the currently active widget for JSON text, and will filter the list of available buttons.
Selecting widgets
There are several ways to select a widget for editing:
-
If no widgets are currently selected, a Ctrl-click in the room will select the topmost widget at that location. Remember, the mouse button you use to interact with widgets in Edit Mode and in game mode are set using the Top Toolbar and defaults to the secondary mouse button. By default, in most cases the selected widget will also be outlined in yellow in the room, so that you can tell which widget in the room you have actually selected. (There are cases, mostly involving widgets with CSS masks, in which the yellow outline will not be displayed). You can turn off the highlighting by clicking on the yellow flashlight.
-
If one or more widgets is currently selected, a Ctrl-Shift-click (for PC) or Ctrl-click (for Mac) will add the selected widget to the set of selected widgets. See more on multi-select editing below.
-
To deselect a widget when only one widget is selected, just click another widget. Or using the multi-select, you can Ctrl-Shift-click (for PC) or move the cursor over the desired widget and press Shift-F1 to deselect a widget.
-
If you hover over a point in the room, the widgets at that point will be displayed in a list in a pop-up box that covers the JSON Editor buttons. If the widget you want is not on "top" (listed under F1), then you can press a function key to select that widget. You cannot multi-select widgets using the F-keys; you must use another method. And if multiple widgets are already selected, selecting a widget by using the F-keys will automatically unselect the other widgets.
-
If you click on a widget in the tree (or a sub-set of the tree list created using the filter), that widget will be selected. To select multiple widgets using the tree, use Shift-click (PC and Mac).
-
If you are examining a widget's JSON in the editing area, you can highlight the id of a referenced widget (for example, its parent); at that point, a button labeled "open widget by ID" will appear in the context commands panel. Clicking that button will select the referenced widget and display it in the editing area instead of the current widget.
-
Use the
tabmode mentioned above to type the name of a widget and it will appear as a button that may be selected.
Once a widget is selected, the JSON for that widget will be displayed in the editing area if it is the only widget selected. Additionally, the selected widget will be highlighted in the tree, if the tree is being displayed.
If multiple widgets have been selected, the editing area will show their widget ids together with their x, y, width, height, parent, z, and layer properties. Additional properties can be added to the list by clicking on the "add property" button that appears in the context-specific area when multiple widgets are selected. Then enter the name of the property in the white typing area and press the Go button. Then scroll to the bottom of the widget and enter the new property value after the property name. It will be applied to all selected widgets. In any event, the displayed JSON can be edited in place. You can also use this view to align widgets. In the widget code area, put the cursor on either the x or y value that you want to modify. You will then see blue buttons with options to align, center in parent or distribute. Once you select the desired option, additional menu options will be presented to determine which coordinates to apply (center, top left, or bottom right), and which widget value to use as the baseline. Press the Go button to implement the change.
Widget Toolbar
Once you have selected a widget, the Widget Toolbar will appear, usually directly below the widget. If you have multiple widgets selected, the toolbar is for the most recently selected widget.
The buttons on this toolbar perform the following functions:
Drag to move this toolbar without doing anything because it is in the way.
Drag to clone the selected widgets into a grid. Once the desired widget(s) is/are selected, click and hold this button while dragging in the direction you want the grid. Release the button when the grid is the desired size.
Drag to adjust spacing between selected widgets. This button is only available when at least 2 widgets are selected. Click and hold this button while dragging in the direction that you want the spacing modified. Release the button when the desired spacing is attained.
Drag to rotate the selected widgets. Once the desired widget(s) is/are selected, click and hold this button while dragging left/right (or up/down) to rotate the widgets left and right. Release the button when the desired rotation angle is attained.
Drag to resize the selected widget(s).
Drage to resize the selected widget(s) and the aspect ratio will be maintained
Drag to move the selected widgets. Once the desired widget(s) is/are selected, click and hold this button while dragging to move the widgets. Release the button when the widgets are in the desired location. While dragging, a pop up will show how far the widget has changed from its previous x/y coordinates. Note, these are not the current widget coordinates, but the change since you started dragging. The pop up also shows the distance from the play area boundaries.
Editing widgets
Widget JSON displayed in the editing area is color-coded to make it easier for the user to interpret. Further, commands are made available in the context-specific area that correspond to the place in the JSON where the cursor is. Note that syntax highlighting and command context detection work best when the JSON is formatted like the editor does when loading a widget. If you are having issues in this regard, try reselecting the widget.
The coloring conventions used are as follows; you can compare these with the screenshot below to see how the various elements appear:
- Gray: used to indicate a default property and value, or the
varkeyword. - Yellow: used for properties and other keys.
- Orange: used for custom properties or keys added by the game room designer and unique to certain widget(s) in that room. This includes the names of custom variables.
- Teal: used for variable references (items enclosed in
${}). - Red: used for
cardTypeandcardDefault. Also used in the context commands panel to indicate an error in the JSON. - Green: used for strings contained within quotation marks.
- Purple: used for numbers (treated as numbers, rather than strings)
- Blue: used for
true,false, andnull. - White: Once you type or paste something in the editing area, it will automatically be colorized in most situations. If it is invalid JSON, it will remain white, and an error indication will appear in the context panel (see below for more information). There are also cases where the JSON is valid but cannot be interpreted properly by the colorization code, and it will remain white. In this case, reselecting the widget should solve the problem.
When you place the cursor at some point in the JSON, a set of commands will appear in the context commands panel. In the screenshot below, the "K" key was selected, either by Ctrl-clicking on it or by clicking "letterK" in the tree display. Then, the cursor was placed in the highlighted area in the fist function where it says "clickable". (Note: you do not need to highlight information to use the context-dependent menus. All you need do is to have the cursor on the line or in the function where you want to edit. The screenshot highlighted this area to make it easier to describe where the cursor was.)
The actions you are likely to want to take are divided into several sections, with the most local (deeply nested) section first. The first section, then, presents several likely replacements for the value of the property key. The second section gives additional properties you might wish to add to the SET function, and the third gives additional functions that you might want to add to the thenRoutine. There are additional sections further down, reachable by scrolling, that contain information for outer contexts.
Clicking on any of the blue buttons in this section will take the appropriate action. For the buttons in the first group, it will replace the existing property value clickable with the chosen item; for buttons in the other two groups, a new key or function will be added.
In general, the code tries to figure out where the most likely desired location is for a new function. But it is always worth checking to make sure that the software correctly interpreted your intentions.
Note that changes you make take effect immediately, but you can use the History button in the Menu to undo any unwanted changes.
If your edits produce syntactically invalid JSON, the changes will not take effect, and the context area will be replaced by information similar to the screenshot below:
When this happens, entering Ctrl-space will move the cursor to the most likely location of the error. Generally this is a nesting error, or an extra or missing comma or quote mark.
Debug
If you want to follow along with this portion of the documentation in a live room, load up the Hangman game from the Public Library. Click on Edit Mode. Then make sure the Debug button on the Menu is active. Uncheck the box in the top right that says "Clear after each interaction." Start a game by pressing the "1 player button" (using the mouse button that you have set to interact in game mode), then press the "J" button. You should see the screen below (this may vary slightly depending on what other Menu buttons you have active, but in the screenshot below, only the Debug button is active):
The first line indicates that what follows is the clickRoutine for the 1Pbtn widget. Each line after that is a single function in that routine; by comparing with the text at the right, you can see that this is the case. The information on each line tells you what was done, and what the results were.
After the lines of that clickRoutine, you can see the clickRoutine for the letter J widget. Since you activated 2 clickRoutines for this example, the Debug shows the output of both of them. Take a look at the letter J entry. The first line inverts the clickable property for the widgets in thisButton (which contains only letter J), while the second line puts the widget mainCheck into the DEFAULT collection. At the end of the line, in grey, is the time in milliseconds that it took to complete the operation. If you notice lag time in your room during routine execution, you can look at these times to get an idea of where the slowdown is taking place.
You can get more detail on any of these operations by clicking on a line with a triangle on it. For example, clicking on the final line in the letter J debug information produces:
Here you can see what happened when the letter J routine caused a click on each button in the DEFAULT collection (in this case, the mainCheck button). The purpose of this routine is to check if the guessed letter is in fact in the word, and to fill the appropriate blanks with the letter if it matches.
Next, note that the CLICK function in the letter J clickRoutine has no explicit parameters. To see how this function was interpreted, click on the line labeled "Original and applied operation". This shows you the function as it appears in the JSON together with the fully expanded version:
If the original function invocation had had a variable expansion, for example
{
"func": "CLICK",
"count": "${number}"
}
then the applied operation would show you what value had been substituted for ${number}.
If you also click on the final line in the CLICK function invocation, labeled "Variables and collections afterwards", you will see all the variables and collections that are defined at the end of that function invocation:
Finally, suppose that your JSON contained some error. For example, if you change the relation in the SET function of the letter J clickRoutine to "no such relation" and click the button, the debug information, after a little bit of expansion, looks like this:
From this, you can find, from the red text, the offending statement, together with an explanation of what is wrong. If the erroneous statement is nested within some routines or other nested construct, the expandable arrows for the ancestors of that statement will be red as well. This allows you to quickly locate any erroneous statements.
Below the routine execution area there is a game validation table. The table checks for a variety of possible errors that may not show up when playing a game or when examining routine debug statements. In this game, there are multiple reports of "unrecognized and seemingly unused) property. This means that there are properties on the identified widgets that are not used by any routine. That is not necessarily a problem, but it would be a good practice to remove those unnecessary properties. Many games that were implemented before 2026, like Hangman in this example, will have validation issues like this that do not impact the operation of the game.
The messages in the table will indicate various types of problems that may exist. For example: there could be an undefined collection or variable, there may be cards in the deck that have not been added to the room, widgets that are mentioned in routines but are missing, properties in deck "faceTemplates" that are both directly set and in the "dynamicProperties", and other problems. Also, if you have both the debug and the JSON menu buttons selected and are looking at both at the same time, then clicking on a widget in the table will take you to that widget and to the line with the problem.
The validation table is updated as changes are made in the room. However, if the validation code starts to slow things down it will detect that and you will see a button like the one below instead. Press it to run the validation code and update the table.
Finally, if there are no validation errors being reported, you get this message:
Quick Links
Home
1. Basics
2. Developer Documentation
- Widgets
- Functions, automation, and routines
- Dynamic Expressions and using variables
- Math, string, array, color, JSON functions
- Cards and Decks
- Editing JSON
- Using CSS
- Fonts and Symbols
3. Available Resources
- Publicly available games
- Tutorials
- Demonstration Features
- Useful Code Snippets
- Useful Global CSS Snippets
4. Usage Guidelines and Copyrights
5. Other Technical Information
- Download Repository
- Using GitHub and creating Pull Requests
- Internals Overview
- Testing with TestCafé
- URL-addressing rooms
- Using Docker containers
- Config.json file