From d36493ffc717d60dbd81d9f040cbab15f17c59f4 Mon Sep 17 00:00:00 2001
From: Frank Weinberg 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 scoreboard will return to the timeout after the jam ends. If that happens, press End Timeout at this point. 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. 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.
-Updating the Score
Correcting Scores and Clocks
Preparing a Game
Screen Layout
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. -
+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 operate the scoreboard until +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:
It is possible to assign multiple actions to a single key. As this can have unitended consequences, -take care that you are careful how you use this feature.
+be careful how you use this feature.To assign multiple actions to a single key:
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.
Starting with Version 4.1 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.
+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.
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.
- +Note: If the team actually fielded a skater but you didn't spot who it was leave the "?".
See Penalty Box Staffing for staffing recommendations.
- +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.
Disable 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 is enabled by default in CRG 4.x and 5.x/2023.x because it has 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.)
+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).
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.
+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 should be aspect ratio 5:1 (e.g. 1600x320).
+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 should be aspect ratio 2.667:1 (e.g. 640x240).
+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
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.
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 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.For builtin rulesets there will not be an "Update" button and no fields can be edited.
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.
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:
☰ (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.
+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.
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.
@@ -2143,8 +2144,10 @@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 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:
☰ (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.
+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.
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.
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:
ant zip
instead. The archive will be placed in the folder release
.
Caution: The architecture of the frontend will significantly change in CRG 2025 and this page has not yet been updated to reflect this change.
+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 the latest CRG version installed on your computer.
-The only Javascript add-on used by CRG is jQuery. While it would certainly be possible to write a custom page without using it, because it is universally used by the existing CRG codebase, this tutorial will also employ it. (Plus, it really DOES make things easier.)
-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.
+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, at a minimum, 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. In addition, we will link to "example.js", the file which contains our own Javascript.
-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>
- <link rel="stylesheet" type="text/css" href="example.css">
<script type="text/javascript" src="/external/jquery/jquery.js" ></script>
<script type="text/javascript" src="/json/core.js"></script>
- <script type="text/javascript" src="example.js">
You will note that the template above also links to "example.css", a CSS file used to style the page. 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.
+</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 simplest model for a CRG frontend page is to have an "initialize" function, which runs each time the page is loaded or reloaded. It is VERY IMPORTANT that you design your page to be able to work properly if the page reloads. If your design assumes that the page will be open and running throughout the game and can successfully do its job only if not interrupted, that's not a good choice.
-In order to read any information from the scoreboard, or to react if a value changes, we MUST declare a "listener" for that function. Even if the listener doesn't DO anything, we will not be able to read a value without an active listener.
-This simple example declares a listener for just the value of the period clock.
-$(initialize); // This line runs the "initialize" function when this file is run.
-
-function initialize() {
- WS.Connect();
- WS.AutoRegister(); // These two lines must be present for this script to communicate with the scoreboard.
-
- WS.Register("ScoreBoard.CurrentGame.Clock(Period).Time")
-}
If you create the three files above in your "html/custom" directory, you will discover that they do absolutely nothing. This is because the HTML file has no content, and the javascript file listens for the value of the period clock, but doesn't DO anything with it.
-Let's fix both of those problems.
-First, replace "<-- PUT SOMETHING HERE -->" with something.
+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 id="clock">30:00</div>
-</body>
Now we have an area, called a "div" which we've given a unique identifier, clock
. If you are familiar with HTML, you know that "id" tags should not be repeated on a page. So if you make a second area, give it another name.
If you reload "example.html", you will find that the clock now reads 30:00! This is probably correct, since you haven't started a game yet. However, since it's static text, it will become increasingly inaccurate, by virtue of remaining unchanged. Let's do something about that!
-Right now, the period clock listener in our javascript doesn't DO anything - it just makes the value available if we want it. Let's change that, and add a function that is executed every time the value changes.
-WS.Register( "ScoreBoard.Clock(Period).Time", function(k,v) {
- $("#clock").html(v);
-})
Well - that's a bit more complicated. What does it mean?
-The WS.Register command takes two arguments. The first is the channel or channels to listen to. The second is a function to execute any time one of the registered channels changes. When the function is called, it is passed two values. k
indicates which channel has changed. Since we are only listening to one channel here, k
will always be ScoreBoard.CurrentGame.Clock(Period).Time
. (For a complete documentation of the channels available in CRG see Websocket Channels.)
v
is the value that the channel has changed to. In this case, the period clock value.
So all the code inside the curly brackets will execute any time one of the monitored channels changes. What are we DOING with this information? In this case, we are changing a value on our web page! $("#clock")
is a selector in the jQuery add-on to javascript. It means to do SOMETHING to every single element in the page with the id clock
. (There should be only one.) It can also be used to search for GROUPS of items and change them all at once, but we're not going to do that here.
The aspect of clock
we want to change is the value of the html contained within it, so we use the statement $("#clock").html(v)
to change the value of the clock to v
, which is the period time. Start your scoreboard program running, open the operator console and start the jam, then open "example.html" in your web browser. You should see a rapidly changing number that makes no sense at all!
Oh right - the scoreboard stores the clock value in milliseconds. Try this:
- $("#clock").html(_timeConversions.msToMinSec(v));
That little bit of extra code should convert the time value to something human beings can read.
-In order to use our screen to CHANGE something, we need a control of some sort. How about a button? Everyone likes buttons!
+ <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 id="clock">30:00</div></br>
-<button id="startjam">Start Jam</button>
-<button id="timeout">Timeout</Button>
-</body>
Right now, these buttons don't DO anything, because we haven't attached any code to them.
- $("#startjam").click(function() {
- WS.Set("ScoreBoard.CurrentGame.StartJam",true);
- }
This is more jQuery. It looks for the element named startjam
and sets it so that any time that element is clicked, it executes the function in the curly brackets. WS.Set
is a function that sets the channel specified first, to the value specified second. In this case, we are sending a value of true
to the channel ScoreBoard.CurrentGame.StartJam
. If you reload "example.html" and then press "start jam", the period clock should start running. (If it's already running, go back to the operator screen and stop it first.)
Another way to execute code when a button is clicked is to put it in an external function. You might want to do this if you are assigning multiple buttons to do the same task, or if you have several different tasks called sequentially by the same button. Let's set up our timeout button that way.
-$("#timeout").click(function() {
- startTimeout();
-})
-
-function startTimeout() {
- WS.Set("ScoreBoard.CurrentGame.Timeout", true);
-}
Here we assign the "Timeout" button to call the function startTimeout
whenever it is clicked. The startTimeout
function, in turn, actually tells the scoreboard to start a timeout.
This tutorial illustrates the very basics of sending data to and from the scoreboard. There are a LOT of things it doesn't cover: "What are all the channels I can read and set?" "How can I listen to multiple channels?" "How can I listen to channels with unspecified values, like skater numbers I don't know in advance?" "What is the fastest land animal in Australia?" Hopefully, documentation for these and other topics will continue to grow over time. For now, try exploring some of the basic pages in the /html/views/ directory for more examples of front end pages.
+ <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.
@@ -2542,7 +3306,7 @@{
"state": {
"ScoreBoard.Settings.Setting(ScoreBoard.Clock.Sync)": "true",
- "ScoreBoard.Settings.Setting(ScoreBoard.ClockAfterTimeout)": "Lineup",
+ "ScoreBoard.Settings.Setting(ScoreBoard.View_BoxStyle)": "box_flat_bright",
}
}
A pong is sent by the backend as reply to a ping. It looks like:
@@ -2584,21 +3348,22 @@ScoreBoard.Media.MediaFormat(*).MediaType(*)
ScoreBoard.Media.MediaFormat(*).MediaType(*).MediaFile(*)
ScoreBoard.Clients
ScoreBoard.Clients.Client(*)
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
PreparedOfficial(_id_)
Version(_type_)
ScoreBoard
UpdateInProgress
StatsbookExists
JsonExists
ClockDuringFinalScore
ExportBlockedBy
Clock(_clock_)
ScoreBoard
UpdateInProgress
StatsbookExists
JsonExists
StartBoxTrip
ClockDuringFinalScore
StartJammerBoxTrip
ExportBlockedBy
Copy
ScoreAdjustment(_id_)
AddTrip
CurrentFielding->PenaltyBox
HasUnserved
CurrentBoxSymbols
Flags
Flags
PreparedSkater->Flags
but not synced afterwardsPreparedSkater
Pronouns
Color
Jammer
and Pivot
currently have an effectPenaltyDetails
PreparedSkater->Flags
but not synced afterwardsPreparedSkater
ExtraPenaltyTime
Duration
CurrentSkater
CurrentFielding->Skater
RosterNumber
CurrentFielding->SkaterNumber
PenaltyCodes
TotalPenalties
CurrentSkater.PenaltyCount
TimingStopped
Time
Clock->Time
Shortened
PenaltyDetails
Team1PenaltyCount
Team2PenaltyCount
Team1Points
Team2Points
Jam(_number_)
PenaltyTime
CurrentBoxTrip->Time
Annotation
PreparedOfficial
Store
Overlay.Interactive.Clock
On
, Off
true
, false
On
true
Overlay.Interactive.LowerThird.Line1
Overlay.Interactive.Score
On
, Off
true
, false
On
true
Overlay.Interactive.ShowJammers
On
, Off
true
, false
On
true
Overlay.Interactive.ShowLineups
On
, Off
true
, false
On
true
Overlay.Interactive.ShowAllNames
On
, Off
Off
Overlay.Interactive.ShowNames
true
, false
false
Overlay.Interactive.ShowPenaltyClocks
true
, false
true
ScoreBoard.AutoStart
Jam
, Timeout
ScoreBoard.AutoEndJam
true
, false
true
(will change in 2025.0)false
(changed in 2025.0)ScoreBoard.AutoEndTTO
ScoreBoard.ClockAfterTimeout
Lineup
, Timeout
Lineup
false
ScoreBoard.Penalties.UsePBT
true
, false
false
ScoreBoard.Stats.InputFile
ScoreBoard.Operator_Default.StartStopButtons
true
, false
false
ScoreBoard.Operator_Default.ReplaceButton
true
, false
false
(will change in 2025.0)false
ScoreBoard.Operator_Default.ScoreAdjustments
ScoreBoard.Operator__*.StartStopButtons
true
, false
false
ScoreBoard.Operator__*.ReplaceButton
true
, false
false
(will change in 2025.0)false
ScoreBoard.Operator__*.ScoreAdjustments
false
ScoreBoard.Preview_HidePenaltyClocks
true
, false
false
ScoreBoard.Preview_SidePadding
false
ScoreBoard.View_HidePenaltyClocks
true
, false
false
ScoreBoard.View_Image
ScoreBoard.ClientsClient(_id_)
Client
no
-
+before 2025.0
ScoreBoard.Clients
-Elements in ScoreBoard.Clients.Client(*)
+Elements in ScoreBoard.Clients.Client(*)
and ScoreBoard.Clients.Device(*).Client(*)
@@ -6536,10 +7562,18 @@ Elements in ScoreBoard.Cli
+NumClients
+number
+no
+from 2025.0
+
+
+
Client(_id_)
-ClientId
+Client
no
+type changed from ClientId in 2025.0
@@ -6694,6 +7728,61 @@ Elements in ScoreBoar
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 | ++ |