These are instructions for getting the software installed and running on a standalone computer to provide a functioning scoreboard. If you have already done this, see Setting up the Scoreboard below.
Updating works the same as a new install. If you extract the new version into the same parent folder as the older one (and the old one is at least version 4), CRG will automatically import all data from the old version into the new one. (Note that blank statsbooks are only copied over if they are placed in the base folder of the installation.)
Most Apple or Windows computers that have been manufactured in the last ten years should be able to handle the scoreboard well on a standalone setup. In general, a machine with at least a dual-core 64-bit processor and 2 gigabytes of RAM should be sufficient. Using the scoreboard to provide video overlays or in a networked setup that includes penalty or lineup tracking typically requires more computing power.
Chromebooks that have been modified to run Linux distributions have been used to host the scoreboard but hardware limitations (lack of a suitable display output or low-powered CPUs) may cause issues.
The scoreboard should be unzipped into a folder on the local machine. The user running the software requires write access to this folder. Do not put the scoreboard in a folder that requires administrator privileges to write to unless you intend to run the software as an administrator.
Google Chrome and Microsoft Edge (as well as their open-source parent Chromium or other browsers derived from it) are recommended for running the software. Some known issues may occur when using Mozilla Firefox or Apple Safari. Microsoft Internet Explorer is not recommended.
Java is required for providing a Java Runtime Environment (JRE) version 8.0 or newer. Installing the latest version is recommended.
Windows and Apple users can install the Java SE Development Kit that is available from Oracle’s Java site.
Linux users likely already have a JDK or JRE from the OpenJDK project installed or available from their distribution. If not, OpenJDK can be obtained from their repositories.
The project is currently hosted on GitHub, and ZIP files can be downloaded from the GitHub Releases Page. It is recommended that you use the version labeled "Latest release" (green box). The "Pre-release" (orange box) versions are currently in development and testing, and are not recommended for sanctioned games or tournaments.
After downloading, you have to extract the archive. Attempting to run from the zip file will not work.
Once everything is installed, use your file manager to navigate to the scoreboard folder and run the scoreboard background script by double-clicking on it.
Windows users: Run scoreboard-Windows.exe to start the script.
Apple users: Run scoreboard.sh to start the script. (If clicking doesn't work, try pressing command+i (or right click on the file and select "Get info"). In the new info dialog in section "open with" select Terminal.app. (If it's not listed, choose other and navigate to /Applications/Utilities/Terminal.app.)
Linux users: Run scoreboard.sh to start the script. If you are unable to start it, you may have to allow script files to be executable as programs (Right-click on the file > Properties > "Allow run as program").
Once it starts successfully, the scoreboard script will open a new window and display a series of status messages. You must keep this script running in order for the scoreboard to function, so do not close the window. You may minimize the window without effect. If there are errors during scoreboard operation, this window may contain output that can be useful for diagnosing tthe problem. So it's worth taking a snapshot.
In your file manager, open start.html with the recommended browser. You may need to right-click on the file and choose the Open With option. The browser will open to localhost:8000 where several options are presented.
Assuming that your scoreboard computer is set up with a monitor/laptop screen as a primary display for the operator, and a separate projector as a second display, right-click on the second link for Main Scoreboard and choose Open link in new window. Drag the new window with the main scoreboard onto the second display, click inside the window, and press the F11 key to make the window full screen. In the first browser window that you opened on the primary display, click on Main Operator Control Panel.
When the control panel displays, it will ask you for an operator name. Enter your name and click Login. This operator name is used to store your personalized settings such as key controls.
These instructions are intended to get you up and running as fast as possible with operating a scoreboard computer that is in the following state:
For instructions on how to accomplish this, see Installing the Scoreboard Software.
After logging in, you will be viewing the Controls tab. Click the Start New Game button. If your game is present in the dropdown under Start a prepared game, select it and click the Start Game button below it. You can then continue with the next section.
If your game has not been prepared, select both teams (or Black and White if your teams are not present) and optionally enter the start time. Click the Start Game button below these settings. If you entered a start time the Time To Derby clock will display on the scoreboard and begin counting down.
Next, if your Teams were not present in the selection and you don't want them to be displayed as Black and White, you have to set the team names. In order to do this switch to the Teams panel and fill the League and/or Team fields for each team. (If you also enter a Uniform Color the operator interface will show that while the public display shows the name). Afterwards switch back to the Controls tab.
Simply click the Start Jam button when the first whistle blows. This will start the jam and period clocks. (Don't worry if Time to Derby hasn't run down, it will automatically be cancelled.)
The scoreboard operator has two essential jobs during the game: controlling the clock and updating the score.
Controlling the clock should always be done using the Start Jam, Stop Jam / End Timeout, and Timeout buttons at the top of the page. (Note that the text on these buttons changes depending on the game state. The text above is what they will show at the time you may want to press them.)
To raise or lower the score for a team, click the Score +1 or Score -1 button under the appropriate team.
Score +1 should always work as described above. If you can't decrease the score with Score -1, go to the SK sheet at the bottom of the screen, click on a cell with a sufficiently large number and in the popup decrease that number. Then close the popup again with the corresponding button.
If you need to adjust the value of a clock, use the +1 and -1 buttons on either side of the clock. This should only be necessary when the jam timer signals you to adjust the period clock during a timeout.
If you forgot to press End Timeout at the rolling whistle, you can still start a jam, even though the button does not say Start Jam. But the timeout will continue running in the background. If that happens, press End Timeout after the end of the next jam.
That's all you need for a basic game. For the full workflow including stats generation, see Scoreboard Operation.
There are two ways to prepare a game: You can either import a WFTDA statsbook prepared for the game or prepare the data in CRG. You can also combine these methods by starting with a partially prepared statsbook and completing the data in CRG.
For both methods you start in the Data Management (a.k.a. Games / Teams / Rulesets) screen.
The "Controls" tab of the main operator control panel is used for scoreboard control during the game. The other tabs can be used for data entry or other changes to the appearance or function of the scoreboard, but when derby is going on, this screen is where the scoreboard operator spends their time.
The Controls tab is split into several sections. Top to bottom these are:
The navigation section which is used to navigate to other tabs or screens.
The options section where you can configure operator settings and trigger functions for start/end of a game.
The clock controls that are used to enter what's currently happening in terms of clocks.
The team controls that are used to enter what's currently happening in terms of points and timeouts.
The clock details that display the state of the various clocks and can be used to correct clock values and data on jams, periods, and timeouts.
The Score sheets that display the recorded points data and allow you to edit it.
(optional) If you want to display the lineup clock for the initial lineup, press the "Lineup" button at the rolling whistle.
This is not tracked by the software. Just make a mental note to not advance the trip the next time the jammer emerges from the pack.
(only possible if the Jam.InjuryContinuation rule is enabled)
If the Jam.SuddenScoring rule is enabled, this is handled automatically. The detection is done when the halftime clock has run down or period two has started. During period two there is a button in the options section that indicates the status and allows overriding it.
If you have not clicked any clock controls since the erroneous "Start Jam" (and the jam has also not been stopped by AutoEnd):
otherwise:
Afterwards you can enter a reason for the premature end on the IGRF tab.
(e.g. if your primary scoreboard computer broke down and you need to bring in a spare mid-game)
Notes:
CRG Scoreboard allows to you assign keys to commands in the main operator screen. For example, you can assign the "g" key to start the jam, or "f" to add one point to the team on the left. Any button visible on the main operator screen can be assigned a hotkey.
Jammer and Pivot selection buttons can also be assigned hotkeys. These will be remembered, if the same stored team is assigned to the same side of the scoreboard later on.
Each operator can set their own hotkeys, which will be retained on the local computer only. Setting hotkeys on one server does NOT configure them on another, and a hard reset of the scoreboard will delete saved configurations. You can however import/export operator profiles (see Data-Management).
To begin assigning hotkeys, click the "Edit Key Controls" button near the top of the screen.
Important: When you are done assigning hotkeys, do not forget to press the "Edit Key Controls" button again to exit the configuration mode. You will not be able to use hotkeys until you do this. More than one scoreboard operator has been bitten at the start of a game because they forgot this step! (Not literally bitten, you understand. At least, not as far as I know.)
For each key you wish to assign:
To assign a different key to an action:
To change what action is assigned to a key:
It is possible to assign multiple actions to a single key. As this can have unitended consequences, be careful how you use this feature.
To assign multiple actions to a single key:
To change configurations for a different operator:
Keys that don't produce a character (Shift, Control, Alt, Arrows, Function Keys, ...) can not be used as hotkeys.
Hotkeys are case sensitive - "a" and "A" are different hotkeys and may be assigned to different actions. One common use for this feature is to assign lower case keys (key pressed alone) to "Points +1" and "Add Trip" and the corresponding upper case keys (Shift + key) to the inverse actions "Points -1" and "Remove Trip".
In a situation with multiple operators using the same computer, always log out and log back in as a different user before changing hotkeys. It is impolite and confusing to redefine the hotkeys for another operator.
When the scoreboard background script is launched on a machine, that machine serves up a website. If it is served up on a network, this website can be accessed by other computers, tablets, or mobile phones on that network to do the following:
Ideally, if you are using the scoreboard to do any the above, using your own router to serve up a private network (as opposed to using the venue's network) tends to improve performance due to reduced network congestion. Using Ethernet connections instead of wireless ones can also help reduce delays. Make sure that the network is password-protected so that fans/skaters/etc. aren't able to connect to the network and tamper with the scoreboard.
Not that connecting multiple devices increases the hardware requirements. If you are running the CRG server on an older/weaker machine, it is recommended that you test your setup before game day.
It is important that you connect the computer/scoreboard to the network FIRST, then launch the scoreboard software. Failing to do this in the right order, means CRG cannot link itself to the network and it will not be visible.
Once the scoreboard background script has been launched and start.html is open in the browser (see the Setting up the Scoreboard section in Installing the Scoreboard Software), the IP address for the scoreboard website will be displayed on the start page in a box on the right labeled INFO in the format http://x.x.x.x:8000/
.
On the device you wish to connect to the scoreboard server, connect to the network that the server is on. Open a browser and navigate to the IP address on the server's start page (http://x.x.x.x:8000/
). A copy of the start page will be displayed. From there, select the function that you want to perform.
CRG supports basic access control. Each device can be switched between read/write and read only mode and the default mode for newly added devices can be set. By default new devices will be in read/write mode, which is the same behaviour as prior versions without access control.
Devices in read only mode can still access any screen but if they attempt to change any values or upload any files, this will generate an error message. This can be useful in order to give benches access to the scoreboard data without worrying about them accidentally modifying game data. It can in principle also be used to give access to the audience but due to every extra device increasing the load on both the scorebaord server and the network this is generally not recommended.
From the start screen go to Devices in the Utilities & Settings category. This leads to a screen that shows an overview of the devices the scoreboard knows about:
The buttons at the top allow you to filter the list of devices.
The selections are cumulative, e.g. in the screenshot all devices that either have a comment or have written are shown. Selecting Active and Inactive together will always show all devices known to the scoreboard.
Right above the table you can toggle if new devices should be given write access and if clients running on the same computer as the CRG backend should always have write access.
The columns in the table have the following meaning:
Devices are identified via browser cookies. That means if the browser is configured to discard cookies on close or cookies are deleted manually, closing and reopening the browser will cause the scoreboard to treat the device as a new one. The same happens when a different browser on the same physical device is used. (The old entry will however still be listed as an inactive device, as the software has no way of knowing that the cookie has been deleted.) This can cause unwanted changes in the access state for physical devices:
Any device will be removed from the scoreboard's list of devices after it has been inactive for 15 days.
When the scoreboard does not know about any device with write access (e.g. after it hasn't been used for more than 15 days) write access for new devices will automatically be enabled at startup. If this situation arises while the scoreboard is running, stopping and restarting the scoreboard server will fix the situation.
When there are devices with write access listed but you either don't have access to them or the corresponding browser cookie has been deleted, there are two ways to recover.
Method 1:
Method 2: Stop the server and use a text editor to modify the entry in config/autosave/scorebaord-0-secs-ago.json for "ScoreBoard.Clients.NewDeviceWrite" from false to true. Restart the server. (You may also have to delete the CRG cookie or use a different browser in order for your device to be recognized as a new device.)
For penalty tracking tablets with about 10" screen diagonal and a 1080 resolution generally work quite well.
For lineup tracking tablets with about 10" screen diagonal and a 1080 resolution generally work quite well.
Once the scoreboard operator marks the jam end, the column next to the "Box" buttons will turn orange with the text "Go To Next Jam"
Note: If CRG is used to time penalties, the PBT can enter substitutions as well.
Note that simply tapping the "Box" field again would start a new box trip which is not correct.
When a skater has to sit out after an injury calloff or substitution
Note: If the team actually fielded a skater but you didn't spot who it was leave the "?".
Note: The CRG PBT/PBM interfaces are NOT intended as a one-to-one replacement of stopwatches and paperwork with each timer tracking blockers of one team and the PBM tracking jammers. See Penalty Box Staffing for the intended setup.
This variant is preferrable when multiple skaters are approaching at once or you don't know which skater is approaching.
This variant is preferrable when a single skater approaches and you know who it is.
Note: You can still use the Blocker Sat Down and Jammer Sat Down buttons while the popup is open in case another skater suddenly approaches. You can also still use the Has Left buttons if another skater is released while the incoming skater is on their way.
No inputs are needed to stop/restart penalty clcoks at end/start of a jam.
Note: You can undo an erroneous "Left Early" press by pressing "Unend" in the respective row. (If there are other penalty clocks running, the row will have been moved below them.)
Note: You can also use this procedure to add penalties issued outside of the box if the PT did not enter them. It is however recommended to leave these to the PT in order to avoid entering the same penalty twice.
Note: This should normally be done by the PT. And if both you and the PT attempt to remove a penalty, you may accidentally remove two penalties.
Note: This should normally be done by the PT.
Note: When entering blockers on the LT and PBT interfaces in parallel, inputs may overwrite each other. Use this functionality with care.
Use Hotkeys at least for clock controls as you want your clocks to be as accurate as possible. Pressing a key is almost always faster then clicking with the mouse. Especially if your finger is already resting on the key.
Enable Replace on Undo. Without Replace pressing the wrong one of the clock controls is a huge pressure situation as every second you don't fix it the clocks run further away and you will have to fix them manually, if that is possible at all. Plus you may have messed up other data, e.g created another jam, which will take more effort to clean up. With Replace you have the time to first think for a moment what just happened and what you can do to fix it and then fix it completely with two clicks/button presses.
Don't enable Auto-End Jam. Simply reacting to the jam ending whistles when they happen takes less effort than checking the jam duration first. And if Jams are not called off on time (Jam Timers are human), your lineups will still last 30s from the end of the jam instead of being shortened (or requiring the jam timer to ignore the publicly visible lineup clock). When using CRG to time penalties, in case of a late call-off Auto-End Jam would also cause penalty clocks to stop early and thus skaters being released too late. (The setting was enabled by default in CRG 4.x and 5.x/2023.x because it had been this way for a very long time and there are a substantial number of people out there that have trained themselves to explicitly rely on it. The default changed in CRG 2025.)
Delete old games from time to time. Each game will increase the size of the internal data notably which will eventually lead to performance impacts if the data grows too large. Note that deleting a game from the internal list does not delete any exported statsbooks or data files from the game (and there is no need to clean up those).
When using a projector, consider not using Team Logos and instead have larger team names. Contrast on projectors is often not that great which can lead to neither logo nor name being very recognizable.
Clearing browsing data is strongly recommended if you are upgrading from version 3.x to version 4.x or higher. It shouldn't be needed when switching between different releases of 4.x and above.
If you are using a Windows system, leave it connected to the internet a day or two beforehand and manually run Windows Update to ensure that patches won't be automatically applied during the game. (Or alternatively, ensure you disable the device's ability to communicate with the outside world so it can't capture updates.)
Note: For best compatibility use PNG or JPG images.
Full-screen images should be the same resolution as the projector for best quality. Other sizes will be scaled according to your settings.
They are stored in:
html\images\fullscreen
Ad images will be displayed with the same width and a quarter of the height of your projector's resolution. Other sizes will be scaled (and distorted if the aspect ratio doesn't match).
They are stored in:
html\images\sponsor_banner
Team Logo images will be scaled to fit into the avilable space without distorting them. The actual dimensions used depend on your projector's resolution and if you display a name along with the logo.
They are stored in:
html\images\teamlogo
The following pages and videos are not maintained by the CRG development team, and are not guaranteed to be accurate, complete, or even still in existence, but they may provide some help. If a version is given, that's the CRG version they were (or appeared to be) based on the last time the respective entry was updated.
(Version 2023) The visual indicator of dots on the current trip is from the Dot System originally developed by Nine Inch Wheels. Here is a link to a google drive share with information on how it works.
(Version 4.0) Here is a playlist with video tutorials by Brain of Terror on the Dublin Roller Derby youtube channel.
(Version 3.2.3) The Downunder Derby channel on YouTube has several helpful how-to videos put together by Flat Track Protocol of Downunder Derby TV.
(Version 3.9) The Carolina Scoreboard Help Sheet is a guide to getting started as a scoreboard operator, written by Cyber Spice from Spa Town Roller Derby.
(Version 3.0) A quick start Google Document including screenshots is available courtesy of Paulie Walnuts.
An overview of running CRG Scoreboard on the Raspberry Pi 3 was written by Sebastian Vollnhals.
This is a description of all the elements on the main operator panel, moving from top to bottom, and left to right.
These buttons change their text based on the current function. When they are inactive the text will be "---"
Each team has a set of controls and displays for that team. They are identical except for being mirror images.
There are five individual clocks - Period, Jam, Lineup, Timeout, and Intermission. In most circumstances, you will not manually adjust the controls for any of these clocks. The one exception is the period clock during timeouts, which you will adjust as directed by the jam timer. As the controls are the same for each clock, they will be described here once only, from top to bottom.
-1 / <clock> /+1 - The -/+ keys decrement and increment the time on the clock. Note that in most cases, clocks should not be adjusted while they are running unless specifically envisioned in the procedures for your game or tournament. Clicking the clock will bring up a sub window:
Periods & Jams Popup Displays a list of all periods/jams on record with some information on them.
Timeouts Popup Displays a list of all timeouts recorded.
This section is only visible if enabled in the options at the top. It is intended to give the ability to record score adjustments for earlier scoring trips with hotkeys to be applied to a the scoring trip when the operator is comfortable taking their eyes off the track. (Usually at the end of the jam.)
Below are all the stashed adjustments that have not been applied yet. For each of them you can select a trip to apply them to or discard them.
The SK sheets use the same layout as the corresponding sheets from the WFTDA statsbook except that the rows are reversed so the most recent jam is at the top and older jams scroll out of view and there are extra rows for timeouts inserted at the corresponding points.
You can toggle/edit most elements by clicking on them. The columns are from left to right:
Scoring Trips - Clicking on them opens a popup that allows editing the corresponding trip
In order to display jammer names or team logos on the scoreboard, or use the stats tracking functionality, each team must be entered ahead of time. This also allows for the storage of team data, such as colors and alternate names, for easy retrieval later.
CRG distinguishes between stored teams and per game teams. There can be any number of stored teams and there will always be two per game teams for each game. These can be either linked to a stored team or custom. The editor for stored teams will always be a screen with a single team while the editor for per game teams will be a tab with both of the game's teams side by side.
The header of the team editor varies depending on team type and game state.
Custom Team before game start:
Custom Team after game start:
Linked Team before game start:
Linked Team after game start:
Stored Team:
This section contains information pertaining to the team as a whole.
The uniform color again has multiple variations depending on team type. Above is for a custom team. Linked team:
Stored Team:
html/images/teamlogo
for the team.In addition to the league name, team name, uniform color, and alternate names that you can set explicitly in the team editor there are a number of names that are derived from these:
The various places in the scoreboard will then use the following names (when multiple names are given the first nonempty one is used):
scoreboard
alternate name, display nameoverlay
alternate name, display namescoreboard
alternate name, uniform color, display namewhiteboard
alternate name, uniform color, display nameoperator
alternate name, uniform color, display nameFor builtin rulesets there will not be an "Update" button and no fields can be edited.
to be written
This tab allows you to edit all the data found on the IGRF (except for teams) and generate/download game data and statsbook files.
The buttons allow generating and downloading the game data JSON and statsbook files.
This section contains the event/venue information from the top of the IGRF.
This section displays the info that has to be put into the summary section of the physical IGRF copy before signing.
If the game had any expulsions they will be listed here, allowing you to enter a brief reason and mark if a suspension was recommended.
This section allows you to enter/manage the officials roster for the game.
This is a description of all the elements on the main operator panel, moving from top to bottom, and left to right.
These buttons change their text based on the current function. When they are inactive the text will be "---"
Each team has a set of controls and displays for that team. They are identical except for being mirror images.
There are five individual clocks - Period, Jam, Lineup, Timeout, and Intermission. In most circumstances, you will not manually adjust the controls for any of these clocks. The one exception is the period clock during timeouts, which you will adjust as directed by the jam timer. As the controls are the same for each clock, they will be described here once only, from top to bottom.
-1 / <clock> /+1 - The -/+ keys decrement and increment the time on the clock. Note that in most cases, clocks should not be adjusted while they are running unless specifically envisioned in the procedures for your game or tournament. Clicking the clock will bring up a sub window:
Periods & Jams Popup Displays a list of all periods/jams on record with some information on them.
Timeouts Popup Displays a list of all timeouts recorded.
This section is only visible if enabled in the options at the top. It is intended to give the ability to record score adjustments for earlier scoring trips with hotkeys to be applied to a the scoring trip when the operator is comfortable taking their eyes off the track. (Usually at the end of the jam.)
Below are all the stashed adjustments that have not been applied yet. For each of them you can select a trip to apply them to or discard them.
The SK sheets use the same layout as the corresponding sheets from the WFTDA statsbook except that the rows are reversed so the most recent jam is at the top and older jams scroll out of view and there are extra rows for timeouts inserted at the corresponding points.
You can toggle/edit most elements by clicking on them. The columns are from left to right:
Scoring Trips - Clicking on them opens a popup that allows editing the corresponding trip
The screen follows the penalty tracking sheet from the WFTDA statsbook with the two teams side by side. Each row represents a skater. The columns have the following functions:
From top to bottom the elements are:
The screen is divided into two parts:
Skater rows
☰ (only for skaters currently fielded) - Opens a popup
when a skater has not been to the box this jam.
when a skater is currently in the box.
when a skater was in the box earlier in this jam.
Penalty count - Indicates the number of penalties for the skater. Will highlight in yellow/orange/red when the skater has 5/6/7 penalties. Will also highlight in red after an expulsion.
The paperwork is designed like the lineup tracker paperwork from the WFTDA statsbook. The only exceptions are that the three box trip cells corresponding to a fielding are merged into a single box and that the order of the rows is reversed.
The controls on this page are set up to allow you to preview changes to the scoreboard before you actually display them to the world. When the page first loads, click both Show Preview buttons at the bottom of the page. The left side of the page will now display what's currently visible on the scoreboard, and the right side will display a preview of what will be displayed next.
If you want to live dangerously and apply changes directly to the scoreboard, you can switch the Edit dropdown to read "Live ScoreBoard". Now any changes you make will be instantly visible to the entire venue.
When you edit the preview the usual work flow is as follows:
Details on customizing each type of screen are below.
This option allows you to select a static image. CRG comes preloaded with a test image, but you can add whatever images you like to the list. To add images, either use the Files screen or start from the directory where you launched the scoreboard, and navigate to html/images/fullscreen/
. In the same directory with the test image, drop whatever other images you would like to display.
Once you have your image in the correct directory, select the file from the "Image View" dropdown.
This option allows you to select a video, which will be automatically looped. CRG comes preloaded with a test video. To add videos, either use the Files screen or start from the directory where you launched the scoreboard, and navigate to html/images/fullscreen/
. Be sure to test whether your video displays properly well ahead of time.
Once you have your video in the correct directory, select the file from the "Video View" dropdown.
You may write your own custom HTML pages for display on the scoreboard. For a starter on on how to do so see Custom Screen Creation Tutorial. Starting from the directory where you launched the scoreboard, they should be placed in html/custom/view/
.
Once you have your page in the correct directory, select the file from the "Custom Page" dropdown.
The screen follows the penalty tracking sheet from the WFTDA statsbook with the two teams side by side. Each row represents a skater. The columns have the following functions:
From top to bottom the elements are:
The screen is divided into two parts:
Skater rows
☰ (only for skaters currently fielded) - Opens a popup
when a skater has not been to the box this jam.
when a skater is currently in the box.
when a skater was in the box earlier in this jam.
Penalty count - Indicates the number of penalties for the skater. Will highlight in yellow/orange/red when the skater has 5/6/7 penalties. Will also highlight in red after an expulsion.
The paperwork is designed like the lineup tracker paperwork from the WFTDA statsbook. The only exceptions are that the three box trip cells corresponding to a fielding are merged into a single box and that the order of the rows is reversed.
These list all known elements of the respective type along with buttons to select them for download/deletion, delete/download them indvidually, edit them (except operators), or create new ones.
The Files screen allows you to upload and download files used in the scoreboard.
The (sub)tabs contain files of the respective types, seperated by use case. If you want to copy or delete them in bulk you will find them in subfolders of the "html" folder in your CRG install. (The names of the subfolders correspond to the headers on the screen.)
See Graphics for info on resultions etc.
The scoreboard features a video overlay that can be used during event livestreams, for example on Twitch or YouTube.
This section outlines the procedure for connecting a broadcaster to the Derby Scoreboard software in order to display the scoreboard overlay on the stream. This is known to work in OBS Studio and vMix.
Example: "https://192.168.1.73:8000/views/overlay/"
You can use the video overlay in OBS Studio by adding a browser source.
You can use the video overlay in vMix by adding a webpage source.
This page is a draft.
This page provides suggestions and notes for scoreboard developers. First, familiarize yourself with our contribution guidelines. (link will not work until we publish the draft)
(recommended environment)
(alternatives)
The Custom Screen Creation Tutorial provides a good introduction to how the scoreboard frontend works in version 2025.x and after.
Packages you will need installed (on a Debian/Ubuntu system - there are probably similar names for other platforms) are:
Clone or download the sourcecode and change into the directory containing the source. To build CRG simply run ant
. This will also run the bundled tests; if you want to skip those you can run ant compile
instead.
If you want to create a zip archive that you can install on other computers, run ant zip
instead. The archive will be placed in the folder release
.
Note on existing custom screens: This page describes how to devolop custom screens in CRG 2025, which differs significantly from how this was done in earler versions of CRG. Most custom screens developed for these earlier versions should still work, though you may have to copy (parts of) some js files from CRG 2023 to your custom screen, if you use functions from those. The most likely candidates being javascript/utils.js
or json/WSutils.js
.
Screens that use the sbModify
HTML attribute will probably not work in CRG 2025 without adaptation. This will primarily affect custom modifications of the main display screen or broadcast overlay. Appending the contents of each sbModify
to the corresponding sbDisplay
separated by a colon should fix the screens. But depending on the amount of customization it might be worthwile to migrate the customization to the new version of the CRG screen instead of adjusting the modified screen in order to also include the new functionality from those screens.
All CRG frontend screens are web pages. This tutorial constructs a simple example screen as an illustration of how to construct CRG frontend pages. It assumes you already have CRG v2025 or newer installed on your computer.
While you can create the files for this tutorial anywhere on your computer, best practice would be the subdirectory of the /html/custom/
directory of your scoreboard installation that fits the purpose of the screen.
In addition to basic HTML boilerplate, such as <html>
and <head>
, your HTML page must link to two scripts. One is /json/core.js
, which provides the basic scoreboard functionality, and the other is /external/jquery/jquery.js
, which provides a link to the version of jQuery bundled with CRG. For the screen to work, jquery.js
has to be loaded first. Note that for a page named example.html
Javascript from example.js
and css from example.css
in the same folder will be automatically loaded (if present).
example.html:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Strict//EN">
<html>
<head>
<title>CRG Sample Page</title>
<script type="text/javascript" src="/external/jquery/jquery.js" ></script>
<script type="text/javascript" src="/json/core.js"></script>
</head>
<body>
<!-- Put stuff here -->
</body>
</html>
This tutorial won't talk much about CSS, because there's not much CSS unique to the scoreboard. Any good online tutorial should be able to do a better job explaining the basics than we will here.
That said, if you are constructing a web page intended to be used as a broadcast overlay, there is one critical aspect to consider - the background color. Some video systems prefer the background to be a solid color (often green). Others prefer a transparent background. Put one of these two lines in your CSS file to specify a background value in that case.
example.css:
body { background-color: rgba(0,255,0,1); } /* Solid Green Background */
body { background-color: rgba(0,0,0,0); } /* Transparent Background */
The CRG javascript library is set up so that screens can be written primarily in HTML with only the occasional small helper function being needed in JS. Thus for the initial template you don't need a js file. If your sceen gets more complex and you need some helper functions, e.g. to convert values, you can just add them to example.js
.
If you create the file above in your html/custom
directory, you will discover that it does absolutely nothing. This is because the HTML file has no content.
Let's fix that problem by replacing <!-- Put stuff here -->
with actual stuff.
Specifically, let's make a spot to display the period clock. As we go forward, don't erase the whole file! Just change the bits shown.
example.html:
<body>
<div sbDisplay="ScoreBoard.CurrentGame.Clock(Period).Time"></div>
</body>
Now we have an area called a div
with an attribute named sbDisplay
. sbDisplay
is a CRG specific attribute that under the hood causes the screen to register for any updates to the Websocket Channel given and display it's current value in the HTML element to which it is attached.
If you reload example.html
, you will probably find that your screen displays some seemingly random large number. If the period clock in your scoreboard is running, this number will be changing quickly, indicating that there is a connection. But presumably this is not quite what you aimed for.
The reason is that the scoreboard stores clock values in milliseconds and we thus have to convert the value to a more convenient format. Try this:
example.html:
<body>
<div sbDisplay="ScoreBoard.CurrentGame.Clock(Period).Time: sbToTime"></div>
</body>
This adds a second argument to the sbDisplay
attribute. For all the CRG specific attributes, multiple arguments are separated by a colon. In the case of sbDisplay
the second argument (if present) is treated as the name of a Javascript function that is used to convert the value for display. sbToTime
is a conversion function provided by CRG that converts a time in the internal milliseconds format to the minutes:seconds format you are used to seeing on CRG displays.
In order to use our screen to change something, we need a control of some sort. How about a button? Everyone likes buttons!
Let's add a button that will start a new jam, and another one which will call a timeout. That way, we'll be able to see the effect on the period clock.
example.html:
<body>
<div sbDisplay="ScoreBoard.CurrentGame.Clock(Period).Time: sbToTime"></div>
<button sbSet="ScoreBoard.CurrentGame.StartJam">Start Jam</button>
<button sbSet="ScoreBoard.CurrentGame.Timeout">Timeout</Button>
</body>
If you reload the screen you should see the two buttons and they should do what their label claims.
sbSet
is another of the CRG specific HTML attributes. When called with a command Websocket Channel as argument, it will cause the command to be executed.
Now we can start and stop our period clock, but what about correcting the value if we made a mistake? Let's add some more buttons.
example.html:
<body>
<div>
<button sbSet="ScoreBoard.CurrentGame.Clock(Period).Time: -1000: change">-1</button>
<span sbDisplay="ScoreBoard.CurrentGame.Clock(Period).Time: sbToTime"></span>
<button sbSet="ScoreBoard.CurrentGame.Clock(Period).Time: +1000: change">+1</button>
</div>
<button sbSet="ScoreBoard.CurrentGame.StartJam">Start Jam</button>
<button sbSet="ScoreBoard.CurrentGame.Timeout">Timeout</Button>
</body>
These buttons makes use of the optional second and third argument of sbSet
that are useful when the first argument is a value channel instead of a command channel. The second argument can be either a function or a value. If it is a function, the function is evaluated and the cahnnel is set to the result, if it is a value the channel is set to that value. The third argument sets additional flags that are supported by some channels. The change
flag is supported by all channels with numeric values and indicates that the value is to be changed by the given amount instead of set to that number.
The values are -1000
and +1000
because we are directly working on the internal millisecond values and 1000ms are 1s.
If we have to make a bigger change, clicking +1 or -1 repeatedly can quickly get tedious. Isn't there a way to make this more efficient? There is.
example.html:
<body>
<div>
<button sbSet="ScoreBoard.CurrentGame.Clock(Period).Time: -1000: change">-1</button>
<input type="text" sbControl="ScoreBoard.CurrentGame.Clock(Period).Time: sbToLongTime: sbFromTime"></input>
<button sbSet="ScoreBoard.CurrentGame.Clock(Period).Time: +1000: change">+1</button>
</div>
<button sbSet="ScoreBoard.CurrentGame.StartJam">Start Jam</button>
<button sbSet="ScoreBoard.CurrentGame.Timeout">Timeout</Button>
</body>
sbControl
is the next of the CRG specific attributes. It can be used with input
and select
elements. Again, the first argument is a channel that is connected to the element. In this case the connection is both ways: If the value in the channel changes, the screen is updated and if the user changes the element on the screen, the channel is updated. The (optional) second argument is a conversion function from channel to screen and the (also optional) third argument is a conversion function from screen to channel. sbToLongTime
is similar to sbToTime
but it will always display a minutes part, even if it is zero, whereas the latter will display only seconds for times below a minute. sbFromTime
is the inverse conversion from the human readable minutes:secoonds to the internal milliseconds. (It can deal with both the long and the short format.)
If you look at the HTML we have so far, you might notice that we are repeating a lot of common prefixes for those channel names. This does happen commonly, as parts of a screen will often deal with channels related to each other. CRG provides a way to avoid this repetition:
example.html:
<body sbContext="ScoreBoard.CurrentGame">
<div sbContext="Clock(Period)">
<button sbSet="Time: -1000: change">-1</button>
<input type="text" sbControl="Time: sbToLongTime: sbFromTime"></input>
<button sbSet="Time: +1000: change">+1</button>
</div>
<button sbSet="StartJam">Start Jam</button>
<button sbSet="Timeout">Timeout</Button>
</body>
sbContext
will store a prefix that is used for all channels accessed in the element it is placed in and any elements enclosed by it. As you can see in the example, multiple nested instances of sbContext
are chained together. If necessary, the prefix can be ignored for an individual channel or an inner sbContext
by prefacing it with a slash, e.g. /ScoreBoard.Settings.Setting(ScoreBoard.View_SwapTeams)
.
Now we have a screen that can access the period clock. But there are more clocks in the scoreboard. Obviously we can copy and paste this in order to add other clocks. But then if we later change the code, we have to make this change multiple times over. Wouldn't it be nice if we only had to maintain one copy and could tell CRG to repeat it for each clock it knows about?
example.html:
<div sbForeach="Clock">
<span sbDisplay="Name"></span>:
<button sbSet="Time: -1000: change">-1</button>
<input type="text" sbControl="Time: sbToLongTime: sbFromTime"></input>
<button sbSet="Time: +1000: change">+1</button>
</div>
And that's it. If clocks were added or removed, this code would autmatically add/remove them from the screen. (Though in CRG the set of available clocks is fixed, so you won't be able to see this here. But if you repeat screen elements for Periods or Jams, this is very useful.) Note that sbForeach
will implicitly insert an sbContext
for the respective instance.
Now, what if you don't want to display all of the clocks and want to control the sorting of the ones that are displayed?
example.html:
<div sbForeach="Clock: Jam, Period, Timeout: only">
<span sbDisplay="Name"></span>:
<button sbSet="Time: -1000: change">-1</button>
<input type="text" sbControl="Time: sbToLongTime: sbFromTime"></input>
<button sbSet="Time: +1000: change">+1</button>
</div>
As with other attributes, there are optional arguments that can help us. The second argument here is a list of ids (the part in parentheses in the channel name) and the elements corresponding to the channels with these ids will be displayed first and in the given order. By default, all other elements would then be appended afterwards, but giving only
as the third argument suppresses them.
Now this works fine for clocks, where we know all the possible ids ahead of time. But what if we don't have this luxury?
example.html:
<div sbForeach="Clock: -Intermission, -Lineup: name" sbAttr="name: Name">
<span sbDisplay="Name"></span>:
<button sbSet="Time: -1000: change">-1</button>
<input type="text" sbControl="Time: sbToLongTime: sbFromTime"></input>
<button sbSet="Time: +1000: change">+1</button>
</div>
Here the ids in the second argument are prefaced by -
which tells CRG to exclude the elements with these ids. (You can mix this with the former approach of listing ids to place at the front.) And the third argument now gives the name of an attribute that is to be used as a sorting key. sbAttr
is used to set this attribute - the first argument gives the name of the attribute, the second is the channel from which it is set and the optional third argument is a conversion function as we know it from other CRG attributes.
Notes: If you append ,num
to the attribute in the third argument of sbForeach
, sorting is done numerically instead of alphabetically. And instead of giving an attribute to sort by, you can also give a JS function that takes two HTML elements as arguments and returns true if the second argument should be placed before the first one.
Often you'll want to affect how screen elemnts look based on values in channels, not just their text. In our example screen we could highlight, which clocks are currently running.
example.html:
<div sbForeach="Clock: -Intermission, -Lineup: name" sbAttr="name: Name">
<span sbDisplay="Name" sbClass="sbActive: Running"></span>:
<button sbSet="Time: -1000: change">-1</button>
<input type="text" sbControl="Time: sbToLongTime: sbFromTime"></input>
<button sbSet="Time: +1000: change">+1</button>
</div>
sbClass
works very similar to sbAttr
. The first argument is the css class that will be toggled. The second argument is the channel that controls it and the optional third one is a conversion function. If it is omitted, CRG will check if the channel is either the boolean true
or the string "true"
. There are some special values for the conversion function as well: !
will negate the result of the default conversion. And any value that is neither that nor the name of a function will be treated as js code that CRG will append to return v
and evaluate. You can use this for simple comparisons like < 3
.
To round things off, let's add a simple popup window to our example screen:
example.html:
<body sbContext="ScoreBoard.CurrentGame">
<div sbForeach="Clock: -Intermission, -Lineup: name" sbAttr="name: Name">
<span sbDisplay="Name" sbClass="sbActive: Running"></span>:
<button sbSet="Time: -1000: change">-1</button>
<input type="text" sbControl="Time: sbToLongTime: sbFromTime"></input>
<button sbSet="Time: +1000: change">+1</button>
<button sbCall="openPopup">Popup</button>
</div>
<button sbSet="StartJam">Start Jam</button>
<button sbSet="Timeout">Timeout</Button>
<div class="sbTemplates">
<div id="ClockDialog" sbContext="Clock(*)">
The current clock value is <span sbDisplay="Time: sbToTime"></span>.
</div>
</div>
</body>
example.js:
function openPopup(k, v, elem, event) {
WS.SetupDialog($('#ClockDialog'), k, {
title: WS.state[k + '.Name'] + ' Clock',
width: 400,
buttons: {
Close: function () {
$(this).dialog('close');
},
},
});
}
The HTML for the popup is placed in a div
with class="sbTemplates"
. This lets CRG know to prepare it accordingly when setting up the screen. The popup itself is then given a unique id
and an sbContext
that has a wildcard (*
) in it to indicate that the clock id that will appear there will vary. The contents are then just normal CRG HTML.
In order to open the popup we use another CRG attribute: sbCall
. This will call the given javascript function.
In the javascript file we then define the function that opens the popup. For the sake of consistency sbCall
will call functions with the same set of parameters as are used for converter functions, even though not all of them will have a useful value:
k
: In converter functions this is the (enriched) name of the channel that the value is coming from or that will be changed. Since sbCall
does not invoke a specific channel it will instead pass the current sbContext
.v
: Usually the value to be converted. For sbCall
it's always undefined
.elem
: The HTML element we are changing/which has been changed/clicked. In this case the button.event
: The JS event that triggered this function call. In this case the click event on the button.Our function only makes a single call to the helper function WS.SetupDialog
. Its first argument is a jquery object containing the contents of the dialog template. The second argument is the sbcontext
to set for the dialog. This should match the context set in the HTML with any wildcards replaced by specific values. The final argument is a set of options for a jQuery UI Dialog Widget.
In order to set the dialog title, we retrieve the value of a channel by passing its name to WS.state[]
(in square brackets). In order to do this the channel must be registered by the screen. In this case this is done because we are displaying the value in the HTML. If we have to retrieve values in javascript functions that are not registered by the HTML, we can do so by calling WS.Register('<channel>')
outside of any function in the JS file.
The channel names passed to the conversion functions are enriched with some convenience funtionality. In the following we'll use ScoreBoard.CurrentGame.Team(1).Skater(abcdef).Penalty(3).Code
as example.
k.field
is the part following the last period. Code
in the example..<type>(<id>)
, k.<type>
will give '<id>'
. In the example k.Team
is '1'
, k.Skater
is'abcdef'
, and k.Penalty
is '3'
.k.upTo('field')
will give the part of k up to and including field
and any id pertaining to field
. In the example, k.upTo('Skater')
is 'ScoreBoard.CurrentGame.Team(1).Skater(abcdef)'
, k.upTo('Game')
is 'ScoreBoard.CurrentGame'
.Let's close this tutorial by looking at some functionality that didn't fit onto the example screen but is still used relative often.
As you write a screen you may want to add multiple conditional css classes, multiple attributes, or multiple function calls to the same HTML element. But HTML doesn't allow multiple sbClass
, sbAttr
, or sbCall
attributes. Thus there is a syntax to add multiple instances to a single attribute: separate the instances by |
, e.g.
<span sbDisplay="Name" sbClass="sbActive: Running | noMoreJam: ^NoMoreJam"></span>
sbActive
is a CSS class styled by CRG. The default theme will add a green background to the element.
The ^
preceding the Channel is another convenience functionality: It tells CRG to discard the last part of the prefix set by sbContext
, specifically the last period and anything after it. You can use multiple ^
s to discard more elements of the context.
Sometimes you may want to base a displayed value on the values of multiple channels. In this case you can list all channels separated by commas, as in
<button sbClass="sbClickMe: InJam, Clock(Jam).Running: sbJamTooLong" sbSet="StopJam">Stop Jam</button>
In this case the element will be updated whenever one of the values changes. You will usually need a custom conversion function in order to handle such elements. Note that the conversion function will not necessarily be called with the value that's changed but with the first value that's set among the list of channels. This is often used when displaying a team name with the option to override it with an alternate name, as in
<span sbDisplay="AlternateName(operator), UniformColor, Name"></span>
When the alternate name is set, it is used. Else uniform colcor is checked and as final option we'll use the team name.
If this tutorial served it's purpose, you should now understand how create screens for CRG. But of course it doesn't cover all the details and at some point you'll need information that is not covered here. These are places where you might find further help:
html
folder of your CRG installation that do things similar to what you want to achieve might also help.question
.Throughout this section we will use the following words for parts of a channel name:
.
..
.Each element has a channel context
. This will be inherited from the parent element and can be modified with the sbContext
attribute.
Whereever a channel name is expected, it will be processed as follows:
[*]
is replaced by the current channel context.[name]
will look for the closest HTML attribute name
walking up the DOM tree and use its value.name
if it exists.sbPrefix
in the element or one of its ancestors, the character is replaced by that prefix and processing ends./
the /
is discarded and processing ends.^
at the start of the channel name one component from the end of the current channel context is discarded along with the ^
..
.When multiple channels are given, they are all processed separately.
|
. When an instance takes multiple arguments, they are always separated by :
. If an argument accepts multiple values, they are always separated by ,
.|
, :
, or ,
in any argument values.|
, :
, or ,
is trimmed on parsing, so you can use it freely to format your HTML for readability.key=value
, whitespace around =
is also trimmed.k
- The enriched name of the channel from which the current value is coming or to which it will be going. If no such channel exists, the channel context of the element on which the function was triggered.v
- For functions that convert from channels the value of the first given channel with a nonempty value. If none has a value the last channel will be used. For other attributes on input or select elements the value of the element. Otherwise true
.elem
- A jQuery set containing (only) the element on which the function was triggered.event
- The JS event that triggered the function call (if any).return
and that will be used as function.return v
will be used.return v
and that will be used as function.v
is either the boolean true or the string true
is returned.!
is replaced by the negation of the above function.Sets HTML attributes of an element based on a channel value.
pos | what | semantics | remarks |
---|---|---|---|
1 | attribute | the HTML attribute to set | |
2 | channels | the channel(s) to be listened to | |
3 | function | a function that converts the value from the channel |
Sets channels for which AutoFit on the element will be triggered when their value changes.
This attribute does not support multiple instances. (But it does support multiple channels on the single instance.)
pos | what | semantics | remarks |
---|---|---|---|
1 | channels | the channel(s) to be listened to |
Notes:
sbAutoFit
.sbDisplay
will also trigger AutoFit, so there is no need to add sbAutoFitOn
for those. Instead this attribute is intended for situations where a channel's value can affect the element's size but not its content.Calls a JS function when an element is clicked/changed.
pos | what | semantics | remarks |
---|---|---|---|
1 | function | the function to be called |
Toggles a CSS class based on a channel value.
pos | what | semantics | remarks |
---|---|---|---|
1 | channels | the channel(s) to be listened to | only the first channel given will be set |
2 | class | the CSS class to toggle | |
3 | function | a function that evaluates the value from the channel |
Modifies the channel context of the current element.
This attribute does not support multiple instances.
pos | what | semantics | remarks |
---|---|---|---|
1 | channel | channel name to be used as prefix on all attributes | |
2 | channel | channel name to be used as prefix on all attributes except sbForeach |
On an HTML element with sbForeach
, sbForeach
is always processed first, taking only the first argument into account. On the elements inserted by sbForeach
, sbContext
will then be set to the first argument of the original sbContext
, followed by the component created by sbForeach
and then the second argument of the original sbContext
, all separated by .
.
If both arguments are given on an element without sbForeach
, they will simply be joined by a .
.
Synchronizes element and channel values.
pos | what | semantics | remarks |
---|---|---|---|
1 | channels | the channel(s) to be listened to and set | only the first channel given will be set |
2 | function | a function that converts the value from the channel for display | |
3 | function | a function that converts the value from the element for the channel |
Sets CSS properties of an element based on a channel value.
pos | what | semantics | remarks |
---|---|---|---|
1 | property | the CSS property to set | |
2 | channels | the channel(s) to be listened to | |
3 | function | a function that converts the value from the channel |
Sets the contents of an element based on a channel value.
Arguments:
pos | what | semantics | remarks |
---|---|---|---|
1 | channels | the channel(s) to be listened to | |
2 | function | a function that converts the value from the channel for display | |
3 | options | The keyword html if the result of the conversion is HTML code instead of text. |
Inserted HTML code will be parsed for CRG attributes. |
Repeats an HTML element (and its contents) for multiple ids on the same field.
field(id)
will be appended to the channel context unless the noContext
option is specified.sbContext
for how the two attributes interact.Arguments:
pos | what | semantics | remarks |
---|---|---|---|
1 | field | the field for which the element should be repeated on each/multiple ids | |
2 | fixed keys | list of ids that should appear first (in the order given) | |
AND/OR ids prefixed by - that should be skipped |
|||
3 | sort function | comparator function that takes two HTML elements and returns true iff the second argument is to be displayed first | |
OR name of an attribute that should be compared to determine sort order | append ,num to sort numerically |
||
OR the keyword only to indicate that only fixed keys should be displayed |
|||
4 | options | onInsert= followed by a js function that is to be called on an inserted element |
|
AND/OR onRemove= followed by a js function that is called on an element before it is removed |
same parameters as onInsert | ||
AND/OR resort= followed by a channel. The element will be resorted when the value of that channel changes |
onInsert will be called again when a resort is triggered on an element | ||
AND/OR part= followed by a number. Only that many components of the id will be considered, starting at the front |
|||
AND/OR filter= follwed by a string. Only ids starting with the string are considered. |
filter=^ will use the string [<field>] would yield in a path |
||
AND/OR the keyword noId indicating that field(id).Id is not a valid channel |
|||
AND/OR the keyword noContext |
Adds event triggers.
Arguments:
pos | what | semantics | remarks |
---|---|---|---|
1 | event | the event to listen for | can be any event accepted by the jQuery on() function |
2 | function | the function to be called |
Defines prefixes to be used on channel names.
Arguments:
pos | what | semantics | remarks |
---|---|---|---|
1 | selector | character that is to be replaced | |
2 | prefix | prefix the character is to be replaced with | |
3 | suffix | suffix that is to be apended to the channel when the prefix is inserted |
In order to avoid surprising behaviour, characters that have a special meaning in CRG HTML attributes or at the start of channel names (|
, :
,,
,/
,^
, "
) must not be used as selector.
Due to components in CRG channel names starting with capital letters, those should also be avoided in order to avoid surprises.
If there are multiple definitions for the same prefix in the current element and its ancestors, the definition closest to the current element will be used.
Sets HTML properties of an element based on a channel value.
pos | what | semantics | remarks |
---|---|---|---|
1 | property | the HTML property to set | |
2 | channels | the channel(s) to be listened to | |
3 | function | a function that converts the value from the channel |
Sets the value of a channel.
Arguments:
pos | what | semantics | remarks |
---|---|---|---|
1 | channel | the channel to be changed | |
2 | function | a function that converts the element value for the channel. | |
3 | flag | change on numeric channels to indicate the value is an offset instead of absolute |
|
OR reset on ...Clock(*).Time to reset the time to the start |
either maximum or minimum time depending on clock direction |
Sets a CSS class based on a channel and toggles it on click.
pos | what | semantics | remarks |
---|---|---|---|
1 | channels | the channel(s) to be listened to and set | only the first channel given will be set |
2 | class | the class to be toggled | default: sbActive |
In order to achieve a consistent look & feel, CRG uses a set of CSS classes across screens that are then given a consistent styling. The actual layout of many of these classes can be modified by themes.
Maximize the font size of the element while making sure the contents still fit. Note: This works best with elements that are a fixed percentage of screen width/height.
The gray boxes with rounded corners in the default theme.
On an sbSegment: Make the segment fill the enclosing container
Group of sbSegments to be arranged side by side.
Group of elements within an sbSegment. Contents are arranged as a left-to-right flexbox by default. In the default theme, multiple consecutive groups are separated by a dashed white line.
Displays the contents of the element as a top-to-bottom flexbox.
sbGroup or table row that serves as header. Has a reddish color in the default theme.
sbGroup or table row that serves as a subheader. Has a brownish color in the default theme.
Element that contains paperwork to be displayed as in the WFTDA statsbook.
Within a sheet of paperwork indicates that the cell has an annotation by displaying a red box in the corner.
Indicates that the element is active. Green background in the default theme.
Indicates an element that the user likely wants to use in the current state. Orange background in the default theme.
Indicates a skater that has an unserved penalty. Light blue background in the default theme.
Indicates a skater curently in the box. Red background in the defaultt theme.
Indicates an element or group of elements that is less important. Lighter background and smaller font in the default theme.
Indicates an important elment. Larger font size in the default theme.
Indicates a very important elment. Even larger font size than sbImportant in the default theme.
Indicates a very very important element. Even larger font size than sbVeryImportant in the default theme.
Displays a spinning circle, indicating an opration is in progress.
Turns the curser over an element into a pointer.
Makes an element invisible (but still taking up space).
Completely removes an element.
Indicates that the element contains dialog templates.
Indicates that the element can be assigned a hotkey.
Indicates that the element should only be shown on some types of sheets. The type of sheet is determined by the closest sbSheetStyle
attribute found in the element's ancestors. Which sheet types the elment is shown on is defined by additional sbShowOn*
classes as follows:
sbSheetStyle | classes shown |
---|---|
pbt | sbShowOnPbt |
boxview | sbShowOnBoxView |
sk | sbShowOnSk |
pt | sbShowOnPt, sbShowOnPurePt |
lt | sbShowOnLt, sbShowOnPureLt |
plt | sbShowOnPlt, sbShowOnPt, sbShowOnLt |
sheet | sbShowOnSheet, sbShowOnPt |
operator | sbShowOnSk, sbShowOnOperator |
whiteboard | sbShowOnWhiteboard, sbShowOnPt |
CRG comes with a bundled library to allow frontend screens to set or retrieve information in the backend state via the Websocket protocol. This page will document the basic syntax of the commands used for this purpose.
If you can't use this library, e.g. because you are using a different programming language, see the section on the low level Websocket commands below.
In order to use the library, the following scripts must be loaded. This will usually be via a <script>
command in the HTML file.
For a list of available channels see WebSocket Channels.
/external/jquery/jquery.js /json/core.js
Note that as JavaScript commands, all of the WS.*
commands are case sensitive. WS.Register()
will work, ws.register()
will not.
To initialize a connection with the server, the script must contain the following two lines. No parameters are required. If these two commands are NOT called, any attempt to query the state will return "undefined".
WS.Connect(); WS.AutoRegister();
The WS.Register()
command is used to establish a listener for a given channel or set of channels. In order to access a value within the backend state, a corresponding Register
command must be executed first.
Simply registers the channel for listening.
WS.Register( "ScoreBoard.CurrentGame.Clock(Period).Time");
Registers a group of channels.
WS.Register( ["ScoreBoard.CurrentGame.Clock(Period).Time",
"ScoreBoard.CurrentGame.Clock(Jam).Time"
]);
Registers a channel for listening and sets a callback function which is executed every time the value of the channel changes. For example, this could be used to update a scoreboard display every time a score value changes:
WS.Register( "ScoreBoard.CurrentGame.Period(1).Jam(13).TeamJam(2).Score", function(k, v) {
updateScore(k,v);
})
This example would call the updateScore
function each time team 1's score changed. The first variable, usually called k
or key
, passes the name of the channel that was updated. The second variable, usually called v
or value
, passes the value the channel was changed to. The key and value will be passed into the function using whatever names are declared in the "function" definition.
In this example, if Team 2's jam score in Period 1 Jam 13 changed to 3, the following command would be executed:
updateScore( "ScoreBoard.CurrentGame.Period(1).Jam(13).TeamJam(2).Score", 3);
Registers a listener to execute the same callback function if ANY of the channels in the list change.
WS.Register([ "ScoreBoard.CurrentGame.Clock(Period).Running",
"ScoreBoard.CurrentGame.Clock(Jam).Running",
"ScoreBoard.CurrentGame.Clock(Intermission).Running"
], function(k,v) {
manageClocks(k,v);
});
The k
or key
parameter is used here to allow the callback function to determine which channel changed to trigger execution of the function.
Any properties which are children of a registered channel can also be accessed without a further registration. For example,
WS.Register( "ScoreBoard.CurrentGame.Team(1)");
will allow the script to access the property ScoreBoard.CurrentGame.Team(1).Score
.
An asterisk may be used as a wildcard for values in parentheses.
WS.Register( "ScoreBoard.CurrentGame.Team(*).Name");
will allow the script to acces either ScoreBoard.CurrentGame.Team(1).Name
or ScoreBoard.CurrentGame.Team(2).Name
.
If you register multiple keys, keys with wildcards or keys with child properties to a callback function, you will commonly have to access parts of the key in your callback funtion. In order to do so without lots of string parsing, you can access these parts via the key variable as shown:
WS.Register( "ScoreBoard.CurrentGame.Team(*).Skater(*)", function(k,v) {
updateSkater(k,v);
});
function updateSkater(k,v){
var team = k.Team;
var skater = k.Skater;
var penalty = k.Penalty;
}
The variable team
now contains the value of the first wildcard, the variable skater
contains the value of the second wildcard. If the update concerns a penalty, penalty
will contain the id of the penalty otherwise it will be undefined.
k.field
will contain the part of the key after the last period and k.parts
will contain an array of all the parts separated by periods without the parentheses and their content. So parts[0]
will be ScoreBoard
, part[1]
will be CurrentGame
, part[2]
will be 'Team'
, part[3]
will be 'Skater'
and part[4]
, and following will vary between updates.
As an example, for the key ScoreBoard.CurrentGame.Team(1).Skater(abcdefg).Penalty(2).Code
the values accessible through the enriched key k
would be:
k.ScoreBoard
: ''
k.CurrentGame
: ''
k.Team
: '1'
k.Skater
: 'abcdefg'
k.Penalty
: '2'
k.Code
: ''
k.field
: Code
k.parts
: ['ScoreBoard', 'CurrentGame', 'Team', 'Skater', 'Penalty', 'Code']
Note that the ids will always be returned as strings, even if they represent a numeric value.
And remember that javascript is case sensitive! k.team
would not have worked in this case nor would k.Field
have.
Once a channel is registered, its value can be retrieved. This includes from functions that are NOT callback functions for the channel. This is accompished via the WS.state
command.
WS.state[ _channel_ ]
This returns the value of a registered channel. It returns undefined
for unregistered channels. It also returns undefined
if the WS.Connect()
and WS.AutoRegister()
commands have not been issued. Note the capitalization and use of square brackets rather than parentheses.
Example:
WS.Register( "ScoreBoard.CurrentGame.Team(1).Score");
manageScore(k, v) {
var score = WS.state["ScoreBoard.CurrentGame.Team(1).Score"];
}
Values in the state can be set using the WS.Set()
command.
WS.Set( _channel_, _value_ );
Channels do NOT need to be registered in advance to use the WS.Set()
command.
Example:
WS.Set("ScoreBoard.CurrentGame.Team(1).TripScore", 4);
This will set the score for team 1's current scoring trip to 4 (and update all dependent values like the team's jam score and total score).
Note that you can only set one channel at a time and have to give the full channel name. Wildcards will NOT work.
For channels with numeric values you can also use WS.Set()
to change the value by some amount instead of setting it directly.
Example:
WS.Set("ScoreBoard.CurrentGame.Team(1).TripScore", -1, 'change');
This will reduce the score of team 1's current scoring trip by 1 (and also update all dependent values).
There are also some channels that do not have values but are used to issue commands. These commands are executed by setting their value to true. For example:
WS.Set('ScoreBoard.CurrentGame.StartJam', true);
CRG exposes a WebSocket endpoint at ws://localhost:8000/WS/
, which is used to gain access to and change CRG state. This section documents it.
Actions are sent by the browser, and look like {"action": "Action Name", ...}
.
The register action specifies state that the client is interested in knowing and getting updates on. These are provided as paths, which represent subtrees of events. For example:
{
"action": "Register",
"paths": [
"ScoreBoard.CurrentGame.Team(*).Skater",
"ScoreBoard.CurrentGame.Clock(Jam).Number"
]
}
would register the skaters on both teams and the jam number.
Registrations are cumulative - adding a new path does not cancel prior registrations. On registration each registered channel will get an initaial update and further updates will be provided as the state of the channel changes.
Set allows the browser to store state. For example:
{
"action": "Set",
"key": "ScoreBoard.CurrentGame.Team(1).TripScore",
"value": -1,
"flag": "change"
}
The key
must be the full name of a channel, and values must be valid for the given channel or the literal null
which will clear/delete the given element. If the backend doesn't know the channel or the value is invalid for the given channel, an error will be recorded on the backend's output.
Valid flag
s are change
and reset
. change
can be used for any numerical value and will cause the element to be changed by the given value instead of set to it. reset
currently only has an effect for the time on a clock which will be reset it to its initial value.
If the value changes and a WS client (including the one sending the request) is registered for ScoreBoard.CurrentGame.Team(1).Score
, it will be informed about the new value. If the command does not result in a changed value for any reason no notifications will be sent out.
This action is used to start a new ad-hoc game. It looks like:
{
"action": "StartNewGame",
"data": {
"Team1": _PreparedTeamId_,
"Team2": _PreparedTeamId_,
"Ruleset": _RulesetId_,
"IntermissionClock": _number_,
"Advance": true|false,
"TO1": _number_,
"TO2": _number_,
"OR1": _number_,
"OR2": _number_,
"Points1": _number_,
"Points2": _number_,
"Period": _number_,
"Jam": _number_,
"PeriodClock": _number_
}
}
The fields after Advance
are only evaluated if the latter is set to true
. In that case they are used to fast forward the game to a given state.
The ping action returns a pong response. This is intended as a heartbeat/keepalive to prevent quiet connections getting closed. Clients are recommended to use this every 30s. It usually looks like:
{ "action": "Ping" }
State is sent by the backend and will contain a set of channel-value pairs informing the frontend about changed values. For example:
{
"state": {
"ScoreBoard.Settings.Setting(ScoreBoard.Clock.Sync)": "true",
"ScoreBoard.Settings.Setting(ScoreBoard.View_BoxStyle)": "box_flat_bright",
}
}
A pong is sent by the backend as reply to a ping. It looks like:
{ "Pong": "" }
An error is sent by the backend if a command contained a wrong action. It looks like:
{ "error": _errorMessage_ }
This gives an overview of all the channels/keys used in the WS communication between backend and frontend and in exported JSON files. For documentation on how to use them see WebSocket Commands.
ScoreBoard
ScoreBoard.Game(*)
and ScoreBoard.CurrentGame
ScoreBoard.Clock(*)
, ScoreBoard.Game(*).Clock(*)
, and ScoreBoard.CurrentGame.Clock(*)
ScoreBoard.Team(*)
, ScoreBoard.Game(*).Team(*)
, and ScoreBoard.CurrentGame.Team(*)
ScoreBoard.Game(*).Team(*).ScoreAdjustment(*)
and ScoreBoard.CurrentGame.Team(*).ScoreAdjustment(*)
ScoreBoard.Team(*).Skater(*)
, ScoreBoard.Game(*).Team(*).Skater(*)
, and ScoreBoard.CurrentGame.Team(*).Skater(*)
ScoreBoard.Team(*).Skater(*).Penalty(*)
, ScoreBoard.Game(*).Team(*).Skater(*).Penalty(*)
, and ScoreBoard.CurrentGame.Team(*).Skater(*).Penalty(*)
ScoreBoard.Team(*).Position(*)
, ScoreBoard.Game(*).Team(*).Position(*)
, and ScoreBoard.CurrentGame.Team(*).Position(*)
ScoreBoard.Team(*).BoxTrip(*)
, and ScoreBoard.Game(*).Team(*).BoxTrip(*)
, and ScoreBoard.CurrentGame.Team(*).BoxTrip(*)
ScoreBoard.Period(*)
, ScoreBoard.Game(*).Period(*)
, and ScoreBoard.CurrentGame.Period(*)
ScoreBoard.Jam(*)
, ScoreBoard.Period(*).Jam(*)
, ScoreBoard.Game(*).Jam(*)
, ScoreBoard.Game(*).Period(*).Jam(*)
, ScoreBoard.CurrentGame.Jam(*)
, and ScoreBoard.CurrentGame.Period(*).Jam(*)
ScoreBoard.Period(*).Jam(*).TeamJam(*)
, ScoreBoard.Game(*).Period(*).Jam(*).TeamJam(*)
, and ScoreBoard.CurrentGame.Period(*).Jam(*).TeamJam(*)
ScoreBoard.Period(*).Jam(*).TeamJam(*).Fielding(*)
, ScoreBoard.Game(*).Period(*).Jam(*).TeamJam(*).Fielding(*)
, and ScoreBoard.CurrentGame.Period(*).Jam(*).TeamJam(*).Fielding(*)
ScoreBoard.Period(*).Jam(*).TeamJam(*).ScoringTrip(*)
, ScoreBoard.Game(*).Period(*).Jam(*).TeamJam(*).ScoringTrip(*)
, and ScoreBoard.CurrentGame.Period(*).Jam(*).TeamJam(*).ScoringTrip(*)
ScoreBoard.Period(*).Timeout(*)
, ScoreBoard.Game(*).Period(*).Timeout(*)
, and ScoreBoard.CurrentGame.Period(*).Timeout(*)
ScoreBoard.Game(*).Nso(*)
, ScoreBoard.Game(*).Ref(*)
, ScoreBoard.CurrentGame.Nso(*)
, and ScoreBoard.CurrentGame.Ref(*)
ScoreBoard.Game(*).Expulsion(*)
, and ScoreBoard.CurrentGame.Expulsion(*)
ScoreBoard.PenaltyCodes
ScoreBoard.Rulesets
ScoreBoard.Rulesets.RuleDefinition(*)
ScoreBoard.Rulesets.Ruleset(*)
ScoreBoard.Settings
ScoreBoard.Twitter
ScoreBoard.Twitter.ConditionalTweet(*)
ScoreBoard.Twitter.FormatSpecifier(*)
ScoreBoard.Media
ScoreBoard.Media.MediaFormat(*)
ScoreBoard.Media.MediaFormat(*).MediaType(*)
ScoreBoard.Media.MediaFormat(*).MediaType(*).MediaFile(*)
ScoreBoard.Clients
ScoreBoard.Clients.Client(*)
and ScoreBoard.Clients.Device(*).Client(*)
ScoreBoard.Clients.Device(*)
ScoreBoard.PreparedTeam(*)
ScoreBoard.PreparedTeam(*).Skater(*)
ScoreBaoad.PreparedOfficial(*)
Notes:
true
on order to ecxcute the command.Id
of an element of the corresponding type._position_
are Jammer
, Pivot
, Blocker1
, Blocker2
, Blocker3
. (As in the regular paperwork, the Pivot position is used for the 4th Blocker if there is no Pivot.)_clock_
are Period
, Jam
, Lineup
, Timeout
, and Intermission
."1"
for Team 1, "2"
for Team 2, "O"
(the letter) for Official timeout, or ""
for an untyped timeout."<gameId>_1"
and for Team 2 it's "<gameId>_2"
. "o"
and ""
are unchanged.ScoreBoard
Name | Value Type | Writable | Versions | Notes |
---|---|---|---|---|
Id |
string | no | from 4.1.1 | always empty string |
Readonly |
bool | no | from 4.1.1 | |
CurrentPeriodNumber |
number | no | before 5.0 | copy of CurrentPeriod->Number |
CurrentPeriod |
PeriodId | no | before 5.0 | |
InPeriod |
bool | no | before 5.0 | copy of CurrentPeriod->Running |
UpcomingJam |
JamId | no | before 5.0 | |
UpcomingJamNumber |
number | no | before 5.0 | copy of UpcomingJam->Number |
InJam |
bool | no | before 5.0 | |
InOvertime |
bool | no | before 5.0 | |
CurrentTimeout |
TimeoutId | no | before 5.0 | |
TimeoutOwner |
TimeoutOwner | during timeout | before 5.0 | copy of CurrentTimeout->Owner |
OfficialReview |
bool | during timeout | before 5.0 | copy of CurrentTimeout->Review |
NoMoreJam |
bool | no | before 5.0 | |
OfficialScore |
bool | yes | before 5.0 | |
Clock(_clock_) |
Clock | no | before 5.0 | |
Team(_number_) |
Team | no | before 5.0 | |
Period(_number_) |
Period | no | before 5.0 | There is a Period(0) for technical reasons. Just ignore it. |
Jam(_number_) |
Jam | no | before 5.0 | Should only hold one element at a time pointed to by UpcomingJam . |
PenaltyCodes |
no | PenaltyCodes | before 5.0 | |
Game(_id_) |
Game | yes | from 5.0 | |
CurrentGame |
CurrentGame | no | from 5.0 | change ScoreBoard.CurrentGame.Game to set the current game |
Rulesets |
Rulesets | no | ||
Settings |
Settings | no | ||
Twitter |
no | before 5.0.10 | ||
Media |
Media | no | ||
Clients |
Clients | no | from 4.1.1 | |
PreparedTeam(_id_) |
PreparedTeam | yes | ||
PreparedOfficial(_id_) |
PreparedOfficial | yes | from 2025.0 | |
Version(_type_) |
string | no | Version(release) is the version number of the running server |
|
Reset |
- | - | before 5.0 | |
StartJam |
- | - | before 5.0 | |
StopJam |
- | - | before 5.0 | Also used to stop timeouts. |
Timeout |
- | - | before 5.0 | |
ClockUndo |
- | - | before 5.0 | |
ClockReplace |
- | - | before 5.0 | |
StartOvertime |
- | - | before 5.0 | |
OfficialTimeout |
- | - | before 5.0 | |
BlankStatsbookFound |
string | yes | from 5.0.6 | bool before 2023.4. Possible values: none , checking , broken , true |
ImportsInProgress |
number | yes | from 5.0.10 |
ScoreBoard.Game(*)
and ScoreBoard.CurrentGame
All values under ScoreBoard.CurrentGame
are copies of the corresponding values of the game pointed to by ScoreBoard.CurrentGame.Game
.
Name | Value Type | Writable | Versions | Notes |
---|---|---|---|---|
Id |
string | no | ||
Readonly |
bool | no | ||
Game |
GameId | yes | only in CurrentGame |
|
Name |
string | no | was not previously in ScoreBoard ; overwrite NameFormat with a fixed string to set |
|
NameFormat |
string | yes | was not previously in ScoreBoard |
|
State |
State | no | was not previously in ScoreBoard . Possible values: Prepared , Running , Finished |
|
CurrentPeriodNumber |
number | no | copy of CurrentPeriod->Running |
|
CurrentPeriod |
PeriodId | no | ||
InPeriod |
bool | no | copy of CurrentPeriod->Running |
|
UpcomingJam |
JamId | no | ||
UpcomingJamNumber |
number | no | copy of UpcomingJam->Number |
|
InJam |
bool | no | ||
InOvertime |
bool | no | ||
InSuddenScoring |
bool | no | from 5.0.10 | copy of CurrentPeriod->SuddenScoring |
InjuryContinuationUpcoming |
bool | no | from 5.0.10 | copy of UpcomingJam->InjuryContinuation |
CurrentTimeout |
TimeoutId | no | ||
TimeoutOwner |
TimeoutOwner | during timeout | copy of CurrentTimeout->Owner |
|
OfficialReview |
bool | during timeout | copy of CurrentTimeout->Review |
|
NoMoreJam |
bool | yes | ||
OfficialScore |
bool | yes | ||
AbortReason |
string | yes | was not previously in ScoreBoard |
|
Ruleset |
RulesetId | yes | was not previously in ScoreBoard |
|
RulesetName |
string | no | was not previously in ScoreBoard ; copy of Ruleset->Name |
|
HeadNso |
OfficialId | yes | was not previously in ScoreBoard |
|
HeadRef |
OfficialId | yes | was not previously in ScoreBoard |
|
SuspensionsServed |
string | yes | was not previously in ScoreBoard |
|
UpdateInProgress |
bool | no | from 5.0.10 | |
StatsbookExists |
bool | yes | from 5.0.6 | |
JsonExists |
bool | yes | from 5.0.6 | |
ClockDuringFinalScore |
bool | yes | from 5.0.10 | |
ExportBlockedBy |
string | no | from 2023.0 | |
Clock(_clock_) |
Clock | no | ||
Team(_number_) |
Team | no | ||
Period(_number_) |
Period | no | There is a Period(0) for technical reasons. Just ignore it. |
|
Jam(_number_) |
Jam | no | Should only hold one element at a time pointed to by UpcomingJam . |
|
Rule(_id_) |
string | yes | was previously in ScoreBoard.Rulesets.CurrentRule(_id_) |
|
PenaltyCode(_code_) |
string | yes | list of verbal cues; was previously in ScoreBoard.PenaltyCodes.Code(_code_) |
|
Label(_id_) |
string | yes | was not previously in ScoreBoard |
|
EventInfo(_id_) |
string | yes | was not previously in ScoreBoard |
|
Nso(_id_) |
Official | yes | was not previously in ScoreBoard |
|
Ref(_id_) |
Official | yes | was not previously in ScoreBoard |
|
Expulsion(_id_) |
Expulsion | yes | was not previously in ScoreBoard |
|
StartJam |
- | - | ||
StopJam |
- | - | Also used to stop timeouts. | |
Timeout |
- | - | ||
ClockUndo |
- | - | ||
ClockReplace |
- | - | ||
StartOvertime |
- | - | ||
OfficialTimeout |
- | - | ||
Export |
- | - | was not previously in ScoreBoard |
|
StartBoxTrip |
- | - | from 2025.0 | |
StartJammerBoxTrip |
- | - | from 2025.0 | |
Copy |
- | - | from 2025.0 |
ScoreBoard.Clock(*)
, ScoreBoard.Game(*).Clock(*)
, and ScoreBoard.CurrentGame.Clock(*)
Name | Value Type | Writable | Versions | Notes |
---|---|---|---|---|
Id |
string | no | ||
Readonly |
bool | no | from 4.1.1 | |
Name |
string | yes | ||
Number |
number | for timeout & lineup clock | ||
Time |
number | yes | ||
InvertedTime |
number | no | ||
MinimumTime |
number | yes | before 4.0.1 | |
MaximumTime |
number | yes | ||
Direction |
bool | yes | true indicates countdown |
|
Running |
bool | yes | ||
Start |
- | - | ||
Stop |
- | - | ||
ResetTime |
- | - |
ScoreBoard.Team(*)
, ScoreBoard.Game(*).Team(*)
, and ScoreBoard.CurrentGame.Team(*)
Name | Value Type | Writable | Versions | Notes |
---|---|---|---|---|
Id |
string | no | ||
Readonly |
bool | no | from 4.1.1 | |
Name |
string | before 5.0 | ||
FullName |
string | no | from 5.0 | |
LeagueName |
string | yes | from 5.0 | copy of PreparedTeam->LeagueName when PreparedTeamConnected is true |
TeamName |
string | yes | from 5.0 | copy of PreparedTeam->TeamName when PreparedTeamConnected is true |
Initials |
string | no | from 5.0 | |
UniformColor |
string | yes | from 5.0 | |
FileName |
string | no | from 5.0 | |
Logo |
file name | yes | without path - will be taken from images/teamlogo/ ; copy of PreparedTeam->Logo when PreparedTeamConnected is true |
|
Score |
number | no | copy of RunningOrEndedTeamJam->TotalScore |
|
JamScore |
number | no | copy of RunningOrEndedTeamJam->JamScore |
|
TripScore |
number | yes | copy of CurrentTrip->Score |
|
LastScore |
number | no | copy of RunningOrEndedTeamJam->LastScore |
|
Lost |
bool | yes | copy of RunningOrEndedTeamJam->Lost |
|
Lead |
bool | yes | copy of RunningOrEndedTeamJam->Lead |
|
Calloff |
bool | yes | copy of RunningOrEndedTeamJam->Calloff |
|
Injury |
bool | yes | copy of RunningOrEndedTeamJam->Injury |
|
NoInitial |
bool | during initial & first scoring trip if JamScore is 0 |
copy of RunningOrEndedTeamJam->NoInitial |
|
DisplayLead |
bool | no | copy of RunningOrEndedTeamJam->DisplayLead |
|
StarPass |
bool | yes | copy of RunningOrEndedTeamJam->StarPass |
|
StarPassTrip |
ScoringTripId | no | copy of RunningOrEndedTeamJam->StarPassTrip |
|
CurrentTrip |
ScoringTripId | no | ||
Timeouts |
number | no | ||
OfficialReviews |
number | no | ||
LastReview |
TimeoutId | no | ||
InTimeout |
bool | no | ||
InOfficialReview |
bool | no | ||
RetainedOfficialReview |
bool | after team has taken a review | copy of LastReview->RetainedReview |
|
NoPivot |
bool | yes | ||
RunningOrUpcomingTeamJam |
TeamJamId | no | ||
RunningOrEndedTeamJam |
TeamJamId | no | ||
LastEndedTeamJam |
TeamJamId | no | before 4.0.1 | |
FieldingAdvancePending |
bool | no | ||
PreparedTeam |
PreparedTeamId | yes | from 5.0 | |
PreparedTeamConnected |
bool | yes | from 5.0 | |
Captain |
SkaterId | no | from 5.0 | set/unset the Captain flag on the skater instead |
ActiveScoreAdjustment |
ScoreAdjustment | yes | from 2023.0 | clear to stash active score adjustment |
ActiveScoreAdjustmentAmount |
number | yes | from 2023.0 | |
TotalPenalties |
number | no | from 2023.1 | |
AllBlockersSet |
bool | no | from 2025.0 | |
Skater(_id_) |
Skater | yes | ||
Position(_position_) |
Position | no | ||
TimeOut(_id_) |
TimeoutId | no | Capital O | |
BoxTrip(_id_) |
BoxTrip | no | ||
AlternateName(_type_) |
string | yes | ||
Color(_type_) |
string | yes | ||
ScoreAdjustment(_id_) |
ScoreAdjustment | yes | from 2023.0 | |
AddTrip |
- | - | ||
RemoveTrip |
- | - | ||
AdvanceFieldings |
- | - | ||
Timeout |
- | - | small o | |
OfficialReview |
- | - | ||
ClearSkaters |
- | - | from 2025.0 |
ScoreBoard.Game(*).Team(*).ScoreAdjustment(*)
and ScoreBoard.CurrentGame.Team(*).ScoreAdjustment(*)
Name | Value Type | Writable | Versions | Notes |
---|---|---|---|---|
Id |
string | no | ||
Readonly |
bool | no | ||
Amount |
number | no | ||
JamRecorded |
Jam | no | ||
PeriodNumberRecorded |
number | no | copy of JamRecorded->PeriodNumber |
|
JamNumberRecorded |
number | no | copy of JamRecorded->Number |
|
RecordedDuringJam |
bool | no | ||
LastTwoMinutes |
bool | no | ||
Open |
bool | no | ||
AppliedTo |
bool | yes | write in order to assign the adjustment | |
Discard |
- | - |
ScoreBoard.Team(*).Skater(*)
, ScoreBoard.Game(*).Team(*).Skater(*)
, and ScoreBoard.CurrentGame.Team(*).Skater(*)
Name | Value Type | Writable | Versions | Notes |
---|---|---|---|---|
Id |
string | no | ||
Readonly |
bool | no | from 4.1.1 | |
Name |
string | yes | copy of PreparedSkater->Name if PreparedTeamConnected is true in the parent element |
|
Number |
string | yes | before 4.1.1 | |
RosterNumber |
string | yes | from 4.1.1 | copy of PreparedSkater->RosterNumber if PreparedTeamConnected is true in the parent element |
PenaltyBox |
bool | if currently fielded | copy of CurrentFielding->PenaltyBox |
|
HasUnserved |
bool | no | from 2025.0 | |
CurrentBoxSymbols |
string | no | copy of CurrentFielding->CurrentBoxSymbols |
|
CurrentPenalties |
string | no | from 5.0 | |
PenaltyCount |
number | no | from 2025.0 | |
Position |
PositionId | no | copy of CurrentFielding->Position |
|
CurrentFielding |
FieldingId | no | set Role to field the skater |
|
Role |
string | yes | ||
BaseRole |
string | no | ||
Flags |
string | yes | initially copied from PreparedSkater->Flags but not synced afterwards |
|
PreparedSkater |
PreparedSkaterId | no | from 5.0 | |
Pronouns |
string | yes | from 2023.0 | |
Color |
string | yes | from 2023.0 | only Jammer and Pivot currently have an effect |
PenaltyDetails |
string | no | from 2025.0 | |
ExtraPenaltyTime |
number | yes | from 2025.0 | |
Fielding(_id_) |
FieldingId | no | ||
Penalty(_number_) |
Penalty | yes | Penalty(0) is foul out or expulsion. |
|
Pronouns |
string | yes | from 2023.0 | |
Color |
string | yes | from 2023.0 | only Jammer and Pivot currently have an effect |
ScoreBoard.Team(*).Skater(*).Penalty(*)
, ScoreBoard.Game(*).Team(*).Skater(*).Penalty(*)
, and ScoreBoard.CurrentGame.Team(*).Skater(*).Penalty(*)
Name | Value Type | Writable | Versions | Notes |
---|---|---|---|---|
Id |
string | no | ||
Readonly |
bool | no | from 4.1.1 | |
Number |
number | no | ||
Previous |
PenaltyId | no | ||
Next |
PenaltyId | no | ||
Code |
string | yes | ||
Jam |
JamId | yes | ||
PeriodNumber |
number | no | copy of Jam->PeriodNumber |
|
JamNumber |
number | no | copy of Jam->Number |
|
Serving |
bool | no | copy of BoxTrip->IsCurrent |
|
Served |
bool | no | ||
ForceServed |
bool | yes | ||
BoxTrip |
BoxTripId | yes | ||
Time |
number | no | Walltime when the penalty was entered | |
Remove |
- | - |
ScoreBoard.Team(*).Position(*)
, ScoreBoard.Game(*).Team(*).Position(*)
, and ScoreBoard.CurrentGame.Team(*).Position(*)
Name | Value Type | Writable | Versions | Notes |
---|---|---|---|---|
Id |
string | no | will be teamid_position |
|
Readonly |
bool | no | from 4.1.1 | |
Skater |
SkaterId | yes | copy of CurrentFielding->Skater |
|
Name |
string | no | copy of Skater->Name |
|
Number |
string | no | before 4.1.1 | copy of Skater->Number |
RosterNumber |
string | no | from 4.1.1 | copy of Skater->RosterNumber |
Flags |
string | no | copy of Skater->Flags |
|
CurrentFielding |
FieldingId | no | ||
PenaltyBox |
bool | yes | copy of CurrentFielding->PenaltyBox |
|
CurrentBoxSymbols |
string | no | copy of CurrentFielding->CurrentBoxSymbols |
|
CurrentPenalties |
string | no | from 5.0 | copy of Skater->CurrentPenalties |
Annotation |
string | no | copy of CurrentFielding->Annotation |
|
HasUnserved |
bool | no | from 2025.0 | copy of Skater->HasUnserved |
PenaltyTime |
number | no | from 2025.0 | copy of CurrentFielding->PenaltyTime |
PenaltyCount |
number | no | from 2025.0 | copy of Skater->PenaltyCount |
PenaltyDetails |
string | no | from 2025.0 | copy of Skater->PenaltyDetails |
ExtraPenaltyTime |
number | no | from 2025.0 | copy of Skater->ExtraPenaltyTime |
Clear |
- | - | ||
UnendBoxTrip |
- | - | from 2025.0 | |
StartBoxClock |
- | - | from 2025.0 |
ScoreBoard.Team(*).BoxTrip(*)
, and ScoreBoard.Game(*).Team(*).BoxTrip(*)
, and ScoreBoard.CurrentGame.Team(*).BoxTrip(*)
Name | Value Type | Writable | Versions | Notes |
---|---|---|---|---|
Id |
string | no | ||
Readonly |
bool | no | from 4.1.1 | |
IsCurrent |
bool | no | ||
CurrentFielding |
FieldingId | no | ||
StartFielding |
FieldingId | no | ||
StartJamNumber |
number | no | copy of StartFielding->Number |
|
StartBetweenJams |
bool | yes | ||
StartAfterSP |
bool | yes | ||
EndFielding |
FieldingId | no | ||
EndJamNumber |
number | no | copy of EndFielding->Number |
|
EndBetweenJams |
bool | yes | ||
EndAfterSP |
bool | yes | ||
WalltimeStart |
number | yes | ||
WalltimeEnd |
number | yes | ||
JamClockStart |
number | yes | ||
JamClockEnd |
number | yes | ||
CurrentSkater |
SkaterId | no | from 2025.0 | copy of CurrentFielding->Skater |
RosterNumber |
string | no | from 2025.0 | copy of CurrentFielding->SkaterNumber |
PenaltyCodes |
string | no | from 2025.0 | |
TotalPenalties |
number | no | from 2025.0 | copy of CurrentSkater.PenaltyCount |
TimingStopped |
bool | yes | from 2025.0 | |
Time |
number | no | from 2025.0 | copy of Clock->Time |
Shortened |
number | no | from 2025.0 | |
PenaltyDetails |
string | no | from 2025.0 | |
Fielding(_id_) |
FieldingId | yes | ||
Penalty(_id_) |
PenaltyId | yes | ||
Clock |
Clock | yes | from 2025.0 | |
StartEarlier |
- | - | ||
StartLater |
- | - | ||
EndEarlier |
- | - | ||
EndLater |
- | - | ||
Delete |
- | - |
ScoreBoard.Period(*)
, ScoreBoard.Game(*).Period(*)
, and ScoreBoard.CurrentGame.Period(*)
Name | Value Type | Writable | Versions | Notes |
---|---|---|---|---|
Id |
string | no | ||
Readonly |
bool | no | from 4.1.1 | |
Number |
number | no | ||
Previous |
PeriodId | no | ||
Next |
PeriodId | no | ||
CurrentJam |
JamId | no | ||
CurrentJamNumber |
number | no | copy of CurrentJam->Number |
|
FirstJam |
JamId | no | ||
FirstJamNumber |
number | no | copy of FirstJam->Number |
|
SuddenScoring |
bool | no | from 5.0.10 | |
Running |
bool | no | ||
Duration |
number | no | ||
WalltimeStart |
number | yes | ||
WalltimeEnd |
number | yes | ||
LocalTimeStart |
string | yes | from 4.1.1 | |
Team1PenaltyCount |
number | no | from 2023.1 | |
Team2PenaltyCount |
number | no | from 2023.1 | |
Team1Points |
number | no | from 2023.1 | |
Team2Points |
number | no | from 2023.1 | |
Jam(_number_) |
Jam | no | ||
Timeout(_id_) |
Timeout | yes | ||
Delete |
- | - | ||
InsertBefore |
- | - | ||
InsertTimeout |
- | - | ||
AddInitialJam |
- | - | from 2025.0 |
ScoreBoard.Jam(*)
, ScoreBoard.Period(*).Jam(*)
, ScoreBoard.Game(*).Jam(*)
, ScoreBoard.Game(*).Period(*).Jam(*)
, ScoreBoard.CurrentGame.Jam(*)
, and ScoreBoard.CurrentGame.Period(*).Jam(*)
Name | Value Type | Writable | Versions | Notes |
---|---|---|---|---|
Id |
string | no | ||
Readonly |
bool | no | from 4.1.1 | |
Number |
number | no | ||
Previous |
JamId | no | ||
Next |
JamId | no | ||
PeriodNumber |
number | no | copy of Number from the parent |
|
StarPass |
bool | no | ||
Overtime |
bool | yes | ||
InjuryContinuation |
bool | yes | from 5.0.10 | |
Duration |
number | no | ||
PeriodClockElapsedStart |
number | yes | ||
PeriodClockElapsedEnd |
number | yes | ||
PeriodClockDisplayEnd |
number | yes | ||
WalltimeStart |
number | yes | ||
WalltimeEnd |
number | yes | ||
TeamJam(_number_) |
TeamJam | no | ||
Penalty(_id_) |
PenaltyId | no | add/remove penalties to/from the skater | |
TimeoutsAfter(_id_) |
TimeoutId | no | ||
Delete |
- | - | ||
InsertBefore |
- | - | ||
InsertTimeoutAfter |
- | - | from 2023.0 |
ScoreBoard.Period(*).Jam(*).TeamJam(*)
, ScoreBoard.Game(*).Period(*).Jam(*).TeamJam(*)
, and ScoreBoard.CurrentGame.Period(*).Jam(*).TeamJam(*)
Name | Value Type | Writable | Versions | Notes |
---|---|---|---|---|
Id |
string | no | will be jamId_teamnumber |
|
Readonly |
bool | no | from 4.1.1 | |
Number |
number | no | jam number | |
Previous |
TeamJamId | no | ||
Next |
TeamJamId | no | ||
LastScore |
number | no | copy of Previous->TotalScore |
|
JamScore |
number | no | ||
AfterSPScore |
number | no | ||
TotalScore |
number | no | ||
OsOffset |
number | yes | ||
OsOffsetReason |
string | yes | from 5.0 | |
Lost |
bool | yes | ||
Lead |
bool | yes | ||
Calloff |
bool | yes | ||
Injury |
bool | yes | linked with Injury on the other team's TeamJam |
|
NoInitial |
bool | no | ||
DisplayLead |
bool | no | ||
CurrentTrip |
ScoringTripId | no | ||
CurrentTripNumber |
number | no | copy of CurrentTrip->Number |
|
StarPass |
bool | yes | ||
StarPassTrip |
ScoringTripId | yes | ||
NoPivot |
bool | yes | ||
Fielding(_position_) |
Fielding | no | ||
ScoringTrip(_number_) |
ScoringTrip | no | ||
CopyLineupToCurrent |
- | - | from 5.0 |
ScoreBoard.Period(*).Jam(*).TeamJam(*).Fielding(*)
, ScoreBoard.Game(*).Period(*).Jam(*).TeamJam(*).Fielding(*)
, and ScoreBoard.CurrentGame.Period(*).Jam(*).TeamJam(*).Fielding(*)
Name | Value Type | Writable | Versions | Notes |
---|---|---|---|---|
Id |
string | no | will be jamId_teamnumber_position |
|
Readonly |
bool | no | from 4.1.1 | |
Number |
number | no | jam number | |
Previous |
FieldingId | no | ||
Next |
FieldingId | no | ||
Position |
PositionId | no | ||
Skater |
SkaterId | yes | ||
SkaterNumber |
string | no | copy of Skater->RosterNumber , ? or n/a |
|
NotFielded |
bool | yes | ||
SitFor3 |
bool | yes | ||
PenaltyBox |
bool | yes | ||
CurrentBoxTrip |
BoxTripId | no | ||
BoxTripSymbols |
string | no | ||
BoxTripSymbolsBeforeSP |
string | no | ||
BoxTripSymbolsAfterSP |
string | no | ||
PenaltyTime |
number | no | from 2025.0 | copy of CurrentBoxTrip->Time |
Annotation |
string | yes | ||
BoxTrip(_id_) |
BoxTripId | no | ||
AddBoxTrip |
- | - | ||
UnendBoxTrip |
- | - |
ScoreBoard.Period(*).Jam(*).TeamJam(*).ScoringTrip(*)
, ScoreBoard.Game(*).Period(*).Jam(*).TeamJam(*).ScoringTrip(*)
, and ScoreBoard.CurrentGame.Period(*).Jam(*).TeamJam(*).ScoringTrip(*)
Name | Value Type | Writable | Versions | Notes |
---|---|---|---|---|
Id |
string | no | ||
Readonly |
bool | no | from 4.1.1 | |
Number |
number | no | ||
Previous |
ScoringTripId | no | ||
Next |
ScoringTripId | no | ||
Score |
number | yes | ||
AfterSP |
bool | yes | ||
Current |
bool | no | ||
Annotation |
string | yes | from 4.1.1 | |
Duration |
number | no | ||
JamClockStart |
number | no | copy of Previous->JamClockEnd or 0 |
|
JamClockEnd |
number | yes | ||
InsertBefore |
- | - | ||
Remove |
- | - |
ScoreBoard.Period(*).Timeout(*)
, ScoreBoard.Game(*).Period(*).Timeout(*)
, and ScoreBoard.CurrentGame.Period(*).Timeout(*)
Name | Value Type | Writable | Versions | Notes |
---|---|---|---|---|
Id |
string | no | ||
Readonly |
bool | no | from 4.1.1 | |
Owner |
TimeoutOwner | yes | ||
Review |
bool | yes | ||
RetainedReview |
bool | yes | ||
OrRequest |
string | yes | from 2025.0 | |
OrResult |
string | yes | from 2025.0 | |
Running |
bool | yes | ||
PrecedingJam |
JamId | yes | ||
PrecedingJamNumber |
number | no | copy of PrecedingJam->Number |
|
Duration |
number | no | ||
PeriodClockElapsedStart |
number | yes | ||
PeriodClockElapsedEnd |
number | yes | ||
PeriodClockEnd |
number | yes | ||
WalltimeStart |
number | yes | ||
WalltimeEnd |
number | yes | ||
Delete |
- | - | ||
InsertAfter |
- | - | from 2023.0 |
ScoreBoard.Game(*).Nso(*)
, ScoreBoard.Game(*).Ref(*)
, ScoreBoard.CurrentGame.Nso(*)
, and ScoreBoard.CurrentGame.Ref(*)
Name | Value Type | Writable | Versions | Notes |
---|---|---|---|---|
Id |
string | no | ||
Readonly |
bool | no | ||
Role |
string | yes | ||
Name |
string | yes | ||
League |
string | yes | ||
Cert |
string | yes | ||
P1Team |
TeamId | yes | ||
Swap |
bool | yes | ||
PreparedOfficial |
PreparedOfficial | yes | from 2025.0 | |
Store |
- | - | from 2025.0 |
ScoreBoard.Game(*).Expulsion(*)
, and ScoreBoard.CurrentGame.Expulsion(*)
Name | Value Type | Writable | Versions | Notes |
---|---|---|---|---|
Id |
string | no | ||
Readonly |
bool | no | ||
Info |
string | yes | ||
ExtraInfo |
string | yes | ||
Suspension |
bool | yes |
ScoreBoard.PenaltyCodes
Name | Value Type | Writable | Versions | Notes |
---|---|---|---|---|
Id |
string | no | from 4.1.1 | |
Readonly |
bool | no | from 4.1.1 | |
Code(_id_) |
string | no | not in 4.1.1 | value is comma-separated list of verbal cues |
PenaltyCode(_id_) |
string | no | only in 4.1.1 | value is comma-separated list of verbal cues |
ScoreBoard.Rulesets
Name | Value Type | Writable | Versions | Notes |
---|---|---|---|---|
Id |
string | no | from 4.1.1 | always empty string |
Readonly |
bool | no | from 4.1.1 | |
CurrentRuleset |
RulesetId | yes | before 5.0 | |
CurrentRulesetId |
string | no | before 5.0 | copied from CurrentRuleset->Id |
CurrentRulesetName |
string | no | before 5.0 | copied from CurrentRuleset->Name |
CurrentRule(_id_) |
string | no | before 5.0 | copied from CurrentRuleset->Rule |
RuleDefinition(_id_) |
RuleDefinition | no | ||
Ruleset(_id_) |
Ruleset | yes |
ScoreBoard.Rulesets.RuleDefinition(*)
Name | Value Type | Writable | Versions | Notes |
---|---|---|---|---|
Id |
string | no | ||
Readonly |
bool | no | from 4.1.1 | |
Name |
string | no | ||
Type |
RuleType | no | can be Boolean , Integer , Long , String , or Time |
|
DefaultValue |
string | no | ||
Description |
string | no | ||
Index |
number | no | ||
TrueValue |
string | no | only when Type is Boolean |
|
FalseValue |
string | no | only when Type is Boolean |
ScoreBoard.Rulesets.Ruleset(*)
Name | Value Type | Writable | Versions | Notes |
---|---|---|---|---|
Id |
string | no | ||
Readonly |
bool | no | from 4.1.1 | |
ParentId |
string | yes | before 5.0 | |
Parent |
ParentId | yes | from 5.0 | |
Name |
string | yes | ||
Rule(_id_) |
string | yes | might be number, time, or boolean encoded as string |
ScoreBoard.Settings
Name | Value Type | Writable | Versions | Notes |
---|---|---|---|---|
Id |
string | no | from 4.1.1 | always empty string |
Readonly |
bool | no | from 4.1.1 | |
Setting(_id_) |
string | yes |
Id | Values | Versions | Notes |
---|---|---|---|
Overlay.Interactive.BackgroundColor |
color name or color value | default: transparent |
|
Overlay.Interactive.Clock |
true , false |
values changed in 2025.0; default: true |
|
Overlay.Interactive.LowerThird.Line1 |
text | default: empty | |
Overlay.Interactive.LowerThird.Line2 |
text | default: empty | |
Overlay.Interactive.LowerThird.Style |
ColourDefault , ColourTeam1 , ColourTeam2 |
default: ColourDefault |
|
Overlay.Interactive.Panel |
empty, PPJBox , RosterTeam1 , RosterTeam2 , PenaltyTeam1 , PenaltyTeam2 , LowerThird , Upcoming |
default: empty | |
Overlay.Interactive.Score |
true , false |
values changed in 2025.0; default: true |
|
Overlay.Interactive.ShowJammers |
true , false |
values changed in 2025.0; default: true |
|
Overlay.Interactive.ShowLineups |
true , false |
from 5.0 | values changed in 2025.0; default: true |
Overlay.Interactive.ShowAllNames |
On , Off |
from 5.0; before 2025.0 | default: Off |
Overlay.Interactive.ShowNames |
true , false |
from 2025.0 | default: false |
Overlay.Interactive.ShowPenaltyClocks |
true , false |
from 2025.0 | default: true |
ScoreBoard.AutoStart |
empty, Jam , Timeout |
from 5.0 | default: empty |
ScoreBoard.AutoStartBuffer |
time | from 5.0 | default: 0:02 |
ScoreBoard.AutoEndJam |
true , false |
from 5.0 | default: false (changed in 2025.0) |
ScoreBoard.AutoEndTTO |
true , false |
from 5.0 | default: false |
ScoreBoard.ClockAfterTimeout |
Lineup , Timeout |
before 2025.0 | default: Lineup |
ScoreBoard.Clock.Sync |
true , false |
default: true |
|
ScoreBoard.Game.DefaultNameFormat |
format string | from 5.0 | default: %G %d %1 vs. %2 (%s: %S) |
ScoreBoard.Intermission.PreGame |
text | default: Time To Derby |
|
ScoreBoard.Intermission.Intermission |
text | default: Intermission |
|
ScoreBoard.Intermission.Unofficial |
text | default: Unofficial Score |
|
ScoreBoard.Intermission.Official |
text | default: Final Score |
|
ScoreBoard.Intermission.OfficialWithClock |
text | from 5.0.10 | default: Final Score |
ScoreBoard.Penalties.ForceServed |
true , false |
before 4.1.1 | default: false |
ScoreBoard.Penalties.UseLT |
true , false |
from 4.1.1 | default: false |
ScoreBoard.Penalties.UsePBT |
true , false |
from 2025.0 | default: false |
ScoreBoard.Stats.InputFile |
path | from 5.0 | default: empty |
ScoreBoard.Operator_Default.StartStopButtons |
true , false |
before 2025.0 | default: false |
ScoreBoard.Operator_Default.TabBar |
true , false |
default: true |
|
ScoreBoard.Operator_Default.ReplaceButton |
true , false |
default: false |
|
ScoreBoard.Operator_Default.ScoreAdjustments |
true , false |
default: false |
|
ScoreBoard.Operator__*.StartStopButtons |
true , false |
before 2025.0 | default: false |
ScoreBoard.Operator__*.TabBar |
true , false |
default: true |
|
ScoreBoard.Operator__*.ReplaceButton |
true , false |
default: false |
|
ScoreBoard.Operator__*.ScoreAdjustments |
true , false |
default: false |
|
ScoreBoard.Preview_BoxStyle |
empty, box_flat , box_flat_bright |
default: box_flat_bright |
|
ScoreBoard.Preview_CurrentView |
scoreboard , whiteboard , image , video , html |
default: scoreboard |
|
ScoreBoard.Preview_CustomHtml |
path | default: /customhtml/fullscreen/example.html |
|
ScoreBoard.Preview_Image |
path | default: /images/fullscreen/test-image.png (changed in 5.0) |
|
ScoreBoard.Preview_HideLogos |
true , false |
default: false |
|
ScoreBoard.Preview_HidePenaltyClocks |
true , false |
from 2025.0 | default: false |
ScoreBoard.Preview_SidePadding |
empty or number (in %) | default: empty | |
ScoreBoard.Preview_SwapTeams |
true , false |
default: false |
|
ScoreBoard.Preview_Video |
path | default: /videos/fullscreen/test-video.webm (changed in 5.0) |
|
ScoreBoard.View_BoxStyle |
empty, box_flat , box_flat_bright |
default: box_flat_bright |
|
ScoreBoard.View_CurrentView |
scoreboard , whiteboard , image , video , html |
default: scoreboard |
|
ScoreBoard.View_CustomHtml |
path | default: /customhtml/fullscreen/example.html |
|
ScoreBoard.View_HideLogos |
true , false |
default: false |
|
ScoreBoard.View_HidePenaltyClocks |
true , false |
from 2025.0 | default: false |
ScoreBoard.View_Image |
path | default: /images/fullscreen/test-image.png (changed in 5.0) |
|
ScoreBoard.View_SidePadding |
empty or number (in %) | default: empty | |
ScoreBoard.View_SwapTeams |
true , false |
default: false |
|
ScoreBoard.View_Video |
path | default: /videos/fullscreen/test-video.webm (changed in 5.0) |
ScoreBoard.Twitter
Name | Value Type | Writable | Versions | Notes |
---|---|---|---|---|
Id |
string | no | from 4.1.1 | |
Readonly |
bool | no | from 4.1.1 | |
AuthUrl |
string | yes | ||
CallbackUrl |
string | yes | ||
OauthVerifier |
string | yes | ||
AccessToken |
string | yes | ||
ManualTweet |
string | yes | ||
Status |
string | yes | ||
Logged_In |
bool | yes | ||
Error |
string | yes | ||
ScreenName |
string | yes | ||
TestMode |
bool | yes | ||
ConditionalTweet(_id_) |
ConditionalTweet | yes | ||
FormatSpecifier(_id_) |
FormatSpecifier | no | ||
Login |
- | - | ||
Logout |
- | - |
ScoreBoard.Twitter.ConditionalTweet(*)
Name | Value Type | Writable | Versions | Notes |
---|---|---|---|---|
Id |
string | no | ||
Readonly |
bool | no | from 4.1.1 | |
Condition |
string | yes | ||
Tweet |
string | yes |
ScoreBoard.Twitter.FormatSpecifier(*)
Name | Value Type | Writable | Versions | Notes |
---|---|---|---|---|
Id |
string | no | ||
Readonly |
bool | no | from 4.1.1 | |
Key |
string | no | ||
Description |
string | no | ||
Current_Value |
string | no |
ScoreBoard.Media
Name | Value Type | Writable | Versions | Notes |
---|---|---|---|---|
Id |
string | no | from 4.1.1 | |
Readonly |
bool | no | from 4.1.1 | |
Format(_id_) |
MediaFormat | yes |
ScoreBoard.Media.MediaFormat(*)
Name | Value Type | Writable | Versions | Notes |
---|---|---|---|---|
Id |
string | no | from 4.1.1 | |
Readonly |
bool | no | from 4.1.1 | |
Type(_id_) |
MediaType | yes |
ScoreBoard.Media.MediaFormat(*).MediaType(*)
Name | Value Type | Writable | Versions | Notes |
---|---|---|---|---|
Id |
string | no | from 4.1.1 | |
Readonly |
bool | no | from 4.1.1 | |
File(_id_) |
MediaFile | yes |
ScoreBoard.Media.MediaFormat(*).MediaType(*).MediaFile(*)
Name | Value Type | Writable | Versions | Notes |
---|---|---|---|---|
Id |
string | no | ||
Readonly |
bool | no | from 4.1.1 | |
Src |
string | no | ||
Name |
string | yes |
ScoreBoard.Clients
Name | Value Type | Writable | Versions | Notes |
---|---|---|---|---|
Id |
string | no | ||
Readonly |
bool | no | ||
NewDeviceWrite |
bool | yes | ||
AllLocalDevicesWrite |
bool | yes | from 4.1.3 | |
Client(_id_) |
Client | no | before 2025.0 | |
Device(_id_) |
Device | no |
ScoreBoard.Clients.Client(*)
and ScoreBoard.Clients.Device(*).Client(*)
Name | Value Type | Writable | Versions | Notes |
---|---|---|---|---|
Id |
string | no | ||
Readonly |
bool | no | ||
Device |
DeviceId | no | ||
RemoteAddr |
string | no | ||
Platform |
string | no | ||
Source |
string | no | ||
Created |
number | no | walltime | |
Wrote |
number | no | walltime |
ScoreBoard.Clients.Device(*)
Name | Value Type | Writable | Versions | Notes |
---|---|---|---|---|
Id |
string | no | ||
Readonly |
bool | no | ||
Name |
string | no | ||
RemoteAddr |
string | no | ||
Platform |
string | no | ||
Comment |
string | yes | ||
Created |
number | no | walltime | |
Wrote |
number | no | walltime | |
Accessed |
number | no | walltime | |
MayWrite |
bool | yes | ||
NumClients |
number | no | from 2025.0 | |
Client(_id_) |
Client | no | type changed from ClientId in 2025.0 |
ScoreBoard.PreparedTeam(*)
Name | Value Type | Writable | Versions | Notes |
---|---|---|---|---|
Id |
string | no | ||
Readonly |
bool | no | from 4.1.1 | |
Name |
string | no | before 5.0 | |
FullName |
string | no | from 5.0 | |
LeagueName |
string | yes | from 5.0 | |
TeamName |
string | yes | from 5.0 | |
UniformColor(_id_) |
string | yes | from 5.0 | |
Logo |
string | yes | ||
Skater(_id_) |
PreparedSkater | yes | ||
AlternateName(_id_) |
string | yes | ||
Color(_id_) |
string | yes |
ScoreBoard.PreparedTeam(*).Skater(*)
Name | Value Type | Writable | Versions | Notes |
---|---|---|---|---|
Id |
string | no | ||
Readonly |
bool | no | from 4.1.1 | |
Name |
string | yes | ||
Number |
string | yes | before 5.0 | |
RosterNumber |
string | yes | from 4.1.1 | |
Flags |
string | yes | ||
Pronouns |
string | yes | from 2023.0 |
ScoreBaoad.PreparedOfficial(*)
Name | Value Type | Writable | Versions | Notes |
---|---|---|---|---|
Id |
string | no | ||
Readonly |
bool | no | ||
Name |
string | yes | ||
League |
string | yes | ||
Cert |
string | yes | ||
FullInfo |
string | no |