<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://en.doc.boardgamearena.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=R3z3nd3</id>
	<title>Board Game Arena - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://en.doc.boardgamearena.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=R3z3nd3"/>
	<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/Special:Contributions/R3z3nd3"/>
	<updated>2026-09-29T02:13:40Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.39.0</generator>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Options_and_preferences:_gameoptions.json,_gamepreferences.json&amp;diff=8603</id>
		<title>Options and preferences: gameoptions.json, gamepreferences.json</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Options_and_preferences:_gameoptions.json,_gamepreferences.json&amp;diff=8603"/>
		<updated>2021-06-26T21:35:51Z</updated>

		<summary type="html">&lt;p&gt;R3z3nd3: Change &amp;quot;Game preferences&amp;quot; to &amp;quot;User preferences&amp;quot; for consistency&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Studio_Framework_Navigation}}&lt;br /&gt;
&lt;br /&gt;
In this file, you can define your game options (i.e. game variants) and user preferences.&lt;br /&gt;
   &lt;br /&gt;
Note: If your game has no variants or preferences, you don&#039;t have to modify this file.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;IMPORTANT:&#039;&#039;&#039; after you edited this file and syncronized to ftp folder you have to go to the control panel and press &amp;quot;Reload game options configuration&amp;quot; for your changes &#039;&#039;&#039;to take effect&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Make sure you understand difference bettween options and preferences:&lt;br /&gt;
* Game options - something usually in the rule book defined as &amp;quot;variant&amp;quot; (except for 2,3,X people - that is automatically handled - you can query it)&lt;br /&gt;
* User preferences - personal choices of each player only visible to that specific player - i.e. layout, either or not to prompt for action, ether or not auto-opt in in some actions, etc&lt;br /&gt;
&lt;br /&gt;
== Game Options ==&lt;br /&gt;
&lt;br /&gt;
Game options are selected by the table creator and usually correspond to game variants, for example if the game includes expansions or certain special rules.&lt;br /&gt;
&lt;br /&gt;
These variants are defined in gameoptions.inc.php as the $game_options variable:  &lt;br /&gt;
  $game_options = array(...); // exactly named that&lt;br /&gt;
&lt;br /&gt;
Each option is a pair in the format: number =&amp;gt; &#039;option description array&#039;. &lt;br /&gt;
&lt;br /&gt;
All options defined in this file should have a corresponding &amp;quot;game state label&amp;quot; with the same ID (see &amp;quot;initGameStateLabels&amp;quot; in yourgame.game.php)&lt;br /&gt;
&lt;br /&gt;
             self::initGameStateLabels ( array (&lt;br /&gt;
                        ...&lt;br /&gt;
                        &amp;quot;my_game_variant&amp;quot; =&amp;gt; 100,&lt;br /&gt;
              ) );&lt;br /&gt;
&lt;br /&gt;
Numbers have to be exactly from 100 to 199 (there can be gaps).&lt;br /&gt;
&lt;br /&gt;
That is how you access them during runtime:&lt;br /&gt;
&lt;br /&gt;
    public function isSecondVariant() {&lt;br /&gt;
        return $this-&amp;gt;getGameStateValue(&#039;my_game_variant&#039;) == 2;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
Or this&lt;br /&gt;
    $this-&amp;gt;gamestate-&amp;gt;table_globals[100]&lt;br /&gt;
&lt;br /&gt;
The following are the parameters of option description array:&lt;br /&gt;
* &#039;&#039;&#039;name&#039;&#039;&#039; - &#039;&#039;&#039;mandatory&#039;&#039;&#039;. The name of the option visible for table creator. Value must be wrapped in totranslate function.&lt;br /&gt;
* &#039;&#039;&#039;values&#039;&#039;&#039; - &#039;&#039;&#039;mandatory&#039;&#039;&#039;. The array (map) of values with additional parameters per value.&lt;br /&gt;
** &#039;&#039;&#039;name&#039;&#039;&#039; - &#039;&#039;&#039;mandatory&#039;&#039;&#039;. String representation of the numeric value visible to table creator. Value must be wrapped in totranslate function.&lt;br /&gt;
** &#039;&#039;&#039;description&#039;&#039;&#039; - String description of this value to use when the name of the option is not self-explanatory. Displayed at the table under the option when this value is selected.&lt;br /&gt;
** &#039;&#039;&#039;tmdisplay&#039;&#039;&#039; - String representation of the option visible in the table description, usually if variant &amp;quot;names&amp;quot; are On and Off, but the description would be same as option name when On, and nothing when Off. (&#039;&#039;&#039;Warning&#039;&#039;&#039;: due to some caching, a change in tmdisplay may not be effective immediately in the studio, even after forcing a reload of gameoptions.inc.php.)&lt;br /&gt;
** &#039;&#039;&#039;nobeginner&#039;&#039;&#039; - Set to true if not recommended for begginers&lt;br /&gt;
** &#039;&#039;&#039;firstgameonly&#039;&#039;&#039; - Set to true if this option is recommended only for the first game (discovery option)&lt;br /&gt;
** &#039;&#039;&#039;beta&#039;&#039;&#039; - Option in beta stage on development&lt;br /&gt;
** &#039;&#039;&#039;premium&#039;&#039;&#039; - Option can be only used by premium members&lt;br /&gt;
* &#039;&#039;&#039;default&#039;&#039;&#039; - indicates the default value to use for this option (optional, if not present the first value listed is the default)&lt;br /&gt;
* &#039;&#039;&#039;displaycondition&#039;&#039;&#039; - checks the conditions before displaying the option for selection. All conditions must be true for the option to display. Supported condition types:&lt;br /&gt;
** &#039;&#039;minplayers&#039;&#039; condition ensures at least this many players&lt;br /&gt;
** &#039;&#039;maxplayers&#039;&#039; conditions ensure at most this many players&lt;br /&gt;
** &#039;&#039;otheroption&#039;&#039; condition ensures another option is set to this given values. &lt;br /&gt;
** &#039;&#039;otheroptionisnot&#039;&#039; conditions ensure another option is NOT set to this given values&lt;br /&gt;
* &#039;&#039;&#039;displayconditionoperand&#039;&#039;&#039; - can be &#039;and&#039; (this is the default) or &#039;or&#039;. Allows to change the behaviour to display the option if one of the conditions is true instead of all of them.&lt;br /&gt;
* &#039;&#039;&#039;startcondition&#039;&#039;&#039; - checks the conditions (on options VALUES) before starting the game. All conditions must be true for the game to start, otherwise players will get a red error message when attempting to begin the game. Supported condition types:&lt;br /&gt;
** &#039;&#039;minplayers&#039;&#039; condition ensures at least this many players&lt;br /&gt;
** &#039;&#039;maxplayers&#039;&#039; conditions ensure at most this many players&lt;br /&gt;
** &#039;&#039;otheroption&#039;&#039; conditions ensure another option is set to this given values. That works the same as in &#039;&#039;&#039;displaycondition&#039;&#039;&#039;.&lt;br /&gt;
** &#039;&#039;otheroptionisnot&#039;&#039; conditions ensure another option is NOT set to this given value.  That works the same as in &#039;&#039;&#039;displaycondition&#039;&#039;&#039;.&lt;br /&gt;
* &#039;&#039;&#039;notdisplayedmessage&#039;&#039;&#039; - if option is not suppose to be visible because of displaycondition but this is set, the text will be visible instead of combo drop down&lt;br /&gt;
&lt;br /&gt;
Common options for all tables (reserved range 200-299):&lt;br /&gt;
*201 (const GAMESTATE_RATING_MODE) - ELO OFF (aka Training mode), &lt;br /&gt;
*200 (const GAMESTATE_CLOCK_MODE) - game speed profile, array(0,1,2) - realtime, values 11-21 - turn based&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 $game_options = array(&lt;br /&gt;
     100 =&amp;gt; array(&lt;br /&gt;
         &#039;name&#039; =&amp;gt; totranslate(&#039;my game option&#039;),&lt;br /&gt;
         &#039;values&#039; =&amp;gt; array(&lt;br /&gt;
             // A simple value for this option:&lt;br /&gt;
             1 =&amp;gt; array(&lt;br /&gt;
                 &#039;name&#039; =&amp;gt; totranslate(&#039;option 1&#039;)&lt;br /&gt;
             ),&lt;br /&gt;
&lt;br /&gt;
             // A simple value for this option.&lt;br /&gt;
             // If this value is chosen, the value of &amp;quot;tmdisplay&amp;quot; is displayed in the game lobby&lt;br /&gt;
             2 =&amp;gt; array(&lt;br /&gt;
                 &#039;name&#039; =&amp;gt; totranslate(&#039;option 2&#039;),&lt;br /&gt;
                 &#039;tmdisplay&#039; =&amp;gt; totranslate(&#039;option 2&#039;)&lt;br /&gt;
             ),&lt;br /&gt;
&lt;br /&gt;
             // Another value, with other options:&lt;br /&gt;
             //  beta=true =&amp;gt; this option is in beta version right now.&lt;br /&gt;
             //  nobeginner=true  =&amp;gt;  this option is not recommended for beginners&lt;br /&gt;
             3 =&amp;gt; array(&lt;br /&gt;
                 &#039;name&#039; =&amp;gt; totranslate(&#039;option 3&#039;),&lt;br /&gt;
                 &#039;beta&#039; =&amp;gt; true,&lt;br /&gt;
                 &#039;nobeginner&#039; =&amp;gt; true&lt;br /&gt;
             ),&lt;br /&gt;
         ),&lt;br /&gt;
         &#039;default&#039; =&amp;gt; 1&lt;br /&gt;
     ),&lt;br /&gt;
     &lt;br /&gt;
     101 =&amp;gt; array(&lt;br /&gt;
         &#039;name&#039; =&amp;gt; totranslate(&#039;Draft variant&#039;),&lt;br /&gt;
         &#039;values&#039; =&amp;gt; array(&lt;br /&gt;
             1 =&amp;gt; array(&lt;br /&gt;
                 &#039;name&#039; =&amp;gt; totranslate(&#039;No draft&#039;)&lt;br /&gt;
             ),&lt;br /&gt;
             2 =&amp;gt; array(&lt;br /&gt;
                 &#039;name&#039; =&amp;gt; totranslate(&#039;Draft&#039;),&lt;br /&gt;
                 &#039;tmdisplay&#039; =&amp;gt; totranslate(&#039;Draft&#039;),&lt;br /&gt;
                 &#039;premium&#039; =&amp;gt; true,&lt;br /&gt;
                 &#039;nobeginner&#039; =&amp;gt; true&lt;br /&gt;
             ),&lt;br /&gt;
         ),&lt;br /&gt;
         &#039;displaycondition&#039; =&amp;gt; array( &lt;br /&gt;
             // Note: do not display this option unless these conditions are met&lt;br /&gt;
             array(&lt;br /&gt;
                 &#039;type&#039; =&amp;gt; &#039;otheroption&#039;,&lt;br /&gt;
                 &#039;id&#039; =&amp;gt; 100, // Game specific option defined in the same array above&lt;br /&gt;
                 &#039;value&#039; =&amp;gt; array(2, 3, 4)&lt;br /&gt;
             ),&lt;br /&gt;
             // Note: do not display this option unless these conditions are met&lt;br /&gt;
            array( &#039;type&#039; =&amp;gt; &#039;otheroption&#039;, &lt;br /&gt;
                 &#039;id&#039; =&amp;gt; 201, // ELO OFF hardcoded framework option&lt;br /&gt;
                 &#039;value&#039; =&amp;gt; 1 // 1 if OFF&lt;br /&gt;
            )&lt;br /&gt;
         ),&lt;br /&gt;
&lt;br /&gt;
         &#039;startcondition&#039; =&amp;gt; array(&lt;br /&gt;
             1 =&amp;gt; array(),&lt;br /&gt;
             2 =&amp;gt; array(&lt;br /&gt;
                 array(&lt;br /&gt;
                     &#039;type&#039; =&amp;gt; &#039;maxplayers&#039;,&lt;br /&gt;
                     &#039;value&#039; =&amp;gt; 3,&lt;br /&gt;
                     &#039;message&#039; =&amp;gt; totranslate(&#039;Draft option is available for 3 players maximum.&#039;)&lt;br /&gt;
                 )&lt;br /&gt;
             ),&lt;br /&gt;
         ),&lt;br /&gt;
     ),&lt;br /&gt;
     &lt;br /&gt;
     102 =&amp;gt; array(&lt;br /&gt;
         &#039;name&#039; =&amp;gt; totranslate(&#039;Takeovers&#039;),&lt;br /&gt;
         &#039;values&#039; =&amp;gt; array(&lt;br /&gt;
             2 =&amp;gt; array(&lt;br /&gt;
                 &#039;name&#039; =&amp;gt; totranslate(&#039;No takeover&#039;)&lt;br /&gt;
             ),&lt;br /&gt;
             1 =&amp;gt; array(&lt;br /&gt;
                 &#039;name&#039; =&amp;gt; totranslate(&#039;Allow takeovers&#039;),&lt;br /&gt;
                 &#039;tmdisplay&#039; =&amp;gt; totranslate(&#039;Takeovers&#039;),&lt;br /&gt;
                 &#039;premium&#039; =&amp;gt; true,&lt;br /&gt;
                 &#039;nobeginner&#039; =&amp;gt; true&lt;br /&gt;
             ),&lt;br /&gt;
         ),&lt;br /&gt;
         &#039;displaycondition&#039; =&amp;gt; array( // Note: do not display this option unless these conditions are met&lt;br /&gt;
             array(&lt;br /&gt;
                 &#039;type&#039; =&amp;gt; &#039;otheroption&#039;,&lt;br /&gt;
                 &#039;id&#039; =&amp;gt; 100,&lt;br /&gt;
                 &#039;value&#039; =&amp;gt; array(3, 4)&lt;br /&gt;
             )&lt;br /&gt;
         ),&lt;br /&gt;
         &#039;startcondition&#039; =&amp;gt; array(&lt;br /&gt;
             2 =&amp;gt; array(),&lt;br /&gt;
             1 =&amp;gt; array(&lt;br /&gt;
                 array(&lt;br /&gt;
                     &#039;type&#039; =&amp;gt; &#039;maxplayers&#039;,&lt;br /&gt;
                     &#039;value&#039; =&amp;gt; 2,&lt;br /&gt;
                     &#039;message&#039; =&amp;gt; totranslate(&#039;Rebel vs Imperium Takeover Scenario is available for 2 players only.&#039;)&lt;br /&gt;
                 )&lt;br /&gt;
             ),&lt;br /&gt;
         ),&lt;br /&gt;
     )&lt;br /&gt;
 );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example of option that condition on ELO off&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$game_options = array(&lt;br /&gt;
&lt;br /&gt;
        100 =&amp;gt; array(&lt;br /&gt;
                &#039;name&#039; =&amp;gt; totranslate(&#039;Learning Game (No Research)&#039;),&lt;br /&gt;
                &#039;values&#039; =&amp;gt; array(&lt;br /&gt;
                        &lt;br /&gt;
                        1 =&amp;gt; array( &#039;name&#039; =&amp;gt; totranslate(&#039;Off&#039;), &#039;tmdisplay&#039; =&amp;gt; totranslate(&#039;&#039;) ),&lt;br /&gt;
                        2 =&amp;gt; array( &#039;name&#039; =&amp;gt; totranslate(&#039;On&#039;), &#039;tmdisplay&#039; =&amp;gt; totranslate(&#039;Learning Game&#039;) ),&lt;br /&gt;
                        &lt;br /&gt;
                ),&lt;br /&gt;
                &#039;displaycondition&#039; =&amp;gt; array(&lt;br /&gt;
                        // Note: do not display this option unless these conditions are met&lt;br /&gt;
                        array( &#039;type&#039; =&amp;gt; &#039;otheroption&#039;,&lt;br /&gt;
                                &#039;id&#039; =&amp;gt; 201, // ELO OFF hardcoded framework option&lt;br /&gt;
                                &#039;value&#039; =&amp;gt; 1, // 1 if OFF&lt;br /&gt;
&lt;br /&gt;
                        )&lt;br /&gt;
                ),&lt;br /&gt;
                &#039;notdisplayedmessage&#039; =&amp;gt; totranslate(&#039;Learning variant available only with ELO off&#039;)&lt;br /&gt;
                ),&lt;br /&gt;
&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example of condition that is only available for REALTIME game mode&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&#039;displaycondition&#039; =&amp;gt; array(&lt;br /&gt;
    // Note: do not display this option until these conditions are met - game speed is selected as realtime&lt;br /&gt;
    array( &#039;type&#039; =&amp;gt; &#039;otheroption&#039;, &#039;id&#039; =&amp;gt; GAMESTATE_CLOCK_MODE, &#039;value&#039; =&amp;gt; array(0,1,2) )&lt;br /&gt;
),&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example of using condition on your own option&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        102 =&amp;gt; array(&lt;br /&gt;
                &#039;name&#039; =&amp;gt; totranslate(&#039;Scenarios&#039;),&lt;br /&gt;
                &#039;values&#039; =&amp;gt; array(&lt;br /&gt;
                        1 =&amp;gt; array( &#039;name&#039; =&amp;gt; totranslate(&#039;Off&#039;),&lt;br /&gt;
                                &#039;nobeginner&#039; =&amp;gt; false  ),&lt;br /&gt;
                        2 =&amp;gt; array( &#039;name&#039; =&amp;gt; totranslate(&#039;On&#039;), &#039;tmdisplay&#039; =&amp;gt; totranslate(&#039;Scenarios&#039;),&lt;br /&gt;
                                &#039;nobeginner&#039; =&amp;gt; true  ),&lt;br /&gt;
                        &lt;br /&gt;
                ),&lt;br /&gt;
                &#039;displaycondition&#039; =&amp;gt; array(&lt;br /&gt;
                        // Note: do not display this option unless these conditions are met&lt;br /&gt;
                        array( &#039;type&#039; =&amp;gt; &#039;otheroptionisnot&#039;,&lt;br /&gt;
                                &#039;id&#039; =&amp;gt; 100, // learning variant&lt;br /&gt;
                                &#039;value&#039; =&amp;gt; 2, // 1 if OFF,2 is ON&lt;br /&gt;
                                &lt;br /&gt;
                        )&lt;br /&gt;
                ),&lt;br /&gt;
                &#039;notdisplayedmessage&#039; =&amp;gt; totranslate(&#039;Scenarios variant is not available if Learning variant is chosen&#039;)&lt;br /&gt;
        ),&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== User Preferences ==&lt;br /&gt;
&lt;br /&gt;
User preferences is something cosmetic about the game interface which however can create user wars, so you can satisfy all users&lt;br /&gt;
by giving them individual preferences. You should use this only if it significantly improves the interface for a large proportion of users.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$game_preferences = array(&lt;br /&gt;
    100 =&amp;gt; array(&lt;br /&gt;
        &#039;name&#039; =&amp;gt; totranslate(&#039;Notation style&#039;),&lt;br /&gt;
        &#039;needReload&#039; =&amp;gt; true, // after user changes this preference game interface would auto-reload&lt;br /&gt;
        &#039;values&#039; =&amp;gt; array(&lt;br /&gt;
            1 =&amp;gt; array( &#039;name&#039; =&amp;gt; totranslate( &#039;Classic&#039; ), &#039;cssPref&#039; =&amp;gt; &#039;notation_classic&#039; ),&lt;br /&gt;
            2 =&amp;gt; array( &#039;name&#039; =&amp;gt; totranslate( &#039;Tournament&#039; ), &#039;cssPref&#039; =&amp;gt; &#039;notation_tournament&#039; )&lt;br /&gt;
        ),&lt;br /&gt;
        &#039;default&#039; =&amp;gt; 2&lt;br /&gt;
    )&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There is two ways to check/apply this. In java Script&lt;br /&gt;
&lt;br /&gt;
  if (this.prefs[100].value == 2) ...&lt;br /&gt;
&lt;br /&gt;
This checks if preferences 100 has selected value 2.&lt;br /&gt;
&lt;br /&gt;
Second, if cssPref specified it will be applied to the &#039;&#039;&#039;&amp;lt;html&amp;gt;&#039;&#039;&#039; tag. So you can use different css styling for the preference. Note: it seems needed to set needReload to true for that class change to be effective.&lt;br /&gt;
&lt;br /&gt;
As user you have to select them from the Gear menu when game is started. On studio only user0 will have it actually working (bug?).&lt;br /&gt;
&lt;br /&gt;
The following are the parameters of preferences description array:&lt;br /&gt;
* &#039;&#039;&#039;name&#039;&#039;&#039; - &#039;&#039;&#039;mandatory&#039;&#039;&#039;. The name of the preference. Value will be automatically wrapped in totranslate if you don&#039;t.&lt;br /&gt;
* &#039;&#039;&#039;needReload&#039;&#039;&#039; - If set to true, the game interface will auto-reload after a change of the preference.&lt;br /&gt;
* &#039;&#039;&#039;values&#039;&#039;&#039; - &#039;&#039;&#039;mandatory&#039;&#039;&#039;. The array (map) of values with additional parameters per value.&lt;br /&gt;
** &#039;&#039;&#039;name&#039;&#039;&#039; - &#039;&#039;&#039;mandatory&#039;&#039;&#039;. String representation of the numeric value. Value will be automatically wrapped in totranslate if you don&#039;t.&lt;br /&gt;
** &#039;&#039;&#039;cssPref&#039;&#039;&#039; - CSS class to add to the &#039;&#039;&#039;&amp;lt;html&amp;gt;&#039;&#039;&#039; tag. Currently it is added or removed only after a reload (see needReload).&lt;br /&gt;
* &#039;&#039;&#039;default&#039;&#039;&#039; - Indicates the default value to use for this preference (optional, if not present the first value listed is the default).&lt;br /&gt;
&lt;br /&gt;
=== Listening for preference changes ===&lt;br /&gt;
&lt;br /&gt;
The BGA framework lacks any callback to notify your game when a user preference is changed (see [https://studio.boardgamearena.com/bug?id=36 proposal #36]), but you can create your own if you need to run some UI code in response to a preference change.&lt;br /&gt;
&lt;br /&gt;
; In ggg.js&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    setup: function (gamedatas) {&lt;br /&gt;
      ... // your setup code here&lt;br /&gt;
      this.setupPreference();&lt;br /&gt;
    },&lt;br /&gt;
    &lt;br /&gt;
    setupPreference: function () {&lt;br /&gt;
      // Extract the ID and value from the UI control&lt;br /&gt;
      var _this = this;&lt;br /&gt;
      function onchange(e) {&lt;br /&gt;
        var match = e.target.id.match(/^preference_[cf]ontrol_(\d+)$/);&lt;br /&gt;
        if (!match) {&lt;br /&gt;
          return;&lt;br /&gt;
        }&lt;br /&gt;
        var prefId = +match[1];&lt;br /&gt;
        var prefValue = +e.target.value;&lt;br /&gt;
        _this.prefs[prefId].value = prefValue;&lt;br /&gt;
        _this.onPreferenceChange(prefId, prefValue);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      // Call onPreferenceChange() when any value changes&lt;br /&gt;
      dojo.query(&amp;quot;.preference_control&amp;quot;).connect(&amp;quot;onchange&amp;quot;, onchange);&lt;br /&gt;
      &lt;br /&gt;
      // Call onPreferenceChange() now&lt;br /&gt;
      dojo.forEach(&lt;br /&gt;
        dojo.query(&amp;quot;#ingame_menu_content .preference_control&amp;quot;),&lt;br /&gt;
        function (el) {&lt;br /&gt;
          onchange({ target: el });&lt;br /&gt;
        }&lt;br /&gt;
      );&lt;br /&gt;
    },&lt;br /&gt;
    &lt;br /&gt;
    onPreferenceChange: function (prefId, prefValue) {&lt;br /&gt;
      console.log(&amp;quot;Preference changed&amp;quot;, prefId, prefValue);&lt;br /&gt;
      ... // your code here to handle the change&lt;br /&gt;
    },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Updating preference from code ===&lt;br /&gt;
The BGA framework lacks any method to update a user preference from the code (see [https://studio.boardgamearena.com/bug?id=36 proposal #36]), but you can create your own if you need to.&lt;br /&gt;
&lt;br /&gt;
; In ggg.js&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    updatePreference: function(prefId, newValue) {&lt;br /&gt;
        // Select preference value in control:&lt;br /&gt;
        dojo.query(&#039;#preference_control_&#039; + prefId + &#039; &amp;gt; option[value=&amp;quot;&#039; + newValue&lt;br /&gt;
        // Also select fontrol to fix a BGA framework bug:&lt;br /&gt;
            + &#039;&amp;quot;], #preference_fontrol_&#039; + prefId + &#039; &amp;gt; option[value=&amp;quot;&#039; + newValue&lt;br /&gt;
            + &#039;&amp;quot;]&#039;).forEach((value) =&amp;gt; dojo.attr(value, &#039;selected&#039;, true));&lt;br /&gt;
        // Generate change event on control to trigger callbacks:&lt;br /&gt;
        const newEvt = document.createEvent(&#039;HTMLEvents&#039;);&lt;br /&gt;
        newEvt.initEvent(&#039;change&#039;, false, true);&lt;br /&gt;
        $(&#039;preference_control_&#039; + prefId).dispatchEvent(newEvt);&lt;br /&gt;
    },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>R3z3nd3</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Options_and_preferences:_gameoptions.json,_gamepreferences.json&amp;diff=8602</id>
		<title>Options and preferences: gameoptions.json, gamepreferences.json</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Options_and_preferences:_gameoptions.json,_gamepreferences.json&amp;diff=8602"/>
		<updated>2021-06-26T21:33:20Z</updated>

		<summary type="html">&lt;p&gt;R3z3nd3: /* Game Options */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Studio_Framework_Navigation}}&lt;br /&gt;
&lt;br /&gt;
In this file, you can define your game options (i.e. game variants) and user preferences.&lt;br /&gt;
   &lt;br /&gt;
Note: If your game has no variants or preferences, you don&#039;t have to modify this file.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;IMPORTANT:&#039;&#039;&#039; after you edited this file and syncronized to ftp folder you have to go to the control panel and press &amp;quot;Reload game options configuration&amp;quot; for your changes &#039;&#039;&#039;to take effect&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Make sure you understand difference bettween options and preferences:&lt;br /&gt;
* Game options - something usually in the rule book defined as &amp;quot;variant&amp;quot; (except for 2,3,X people - that is automatically handled - you can query it)&lt;br /&gt;
* Game preferences - personal choice of player only visible to this specific player - i.e. layout, either or not prompt for action, ether or not auto-opt in in some actions, etc&lt;br /&gt;
&lt;br /&gt;
== Game Options ==&lt;br /&gt;
&lt;br /&gt;
Game options are selected by the table creator and usually correspond to game variants, for example if the game includes expansions or certain special rules.&lt;br /&gt;
&lt;br /&gt;
These variants are defined in gameoptions.inc.php as the $game_options variable:  &lt;br /&gt;
  $game_options = array(...); // exactly named that&lt;br /&gt;
&lt;br /&gt;
Each option is a pair in the format: number =&amp;gt; &#039;option description array&#039;. &lt;br /&gt;
&lt;br /&gt;
All options defined in this file should have a corresponding &amp;quot;game state label&amp;quot; with the same ID (see &amp;quot;initGameStateLabels&amp;quot; in yourgame.game.php)&lt;br /&gt;
&lt;br /&gt;
             self::initGameStateLabels ( array (&lt;br /&gt;
                        ...&lt;br /&gt;
                        &amp;quot;my_game_variant&amp;quot; =&amp;gt; 100,&lt;br /&gt;
              ) );&lt;br /&gt;
&lt;br /&gt;
Numbers have to be exactly from 100 to 199 (there can be gaps).&lt;br /&gt;
&lt;br /&gt;
That is how you access them during runtime:&lt;br /&gt;
&lt;br /&gt;
    public function isSecondVariant() {&lt;br /&gt;
        return $this-&amp;gt;getGameStateValue(&#039;my_game_variant&#039;) == 2;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
Or this&lt;br /&gt;
    $this-&amp;gt;gamestate-&amp;gt;table_globals[100]&lt;br /&gt;
&lt;br /&gt;
The following are the parameters of option description array:&lt;br /&gt;
* &#039;&#039;&#039;name&#039;&#039;&#039; - &#039;&#039;&#039;mandatory&#039;&#039;&#039;. The name of the option visible for table creator. Value must be wrapped in totranslate function.&lt;br /&gt;
* &#039;&#039;&#039;values&#039;&#039;&#039; - &#039;&#039;&#039;mandatory&#039;&#039;&#039;. The array (map) of values with additional parameters per value.&lt;br /&gt;
** &#039;&#039;&#039;name&#039;&#039;&#039; - &#039;&#039;&#039;mandatory&#039;&#039;&#039;. String representation of the numeric value visible to table creator. Value must be wrapped in totranslate function.&lt;br /&gt;
** &#039;&#039;&#039;description&#039;&#039;&#039; - String description of this value to use when the name of the option is not self-explanatory. Displayed at the table under the option when this value is selected.&lt;br /&gt;
** &#039;&#039;&#039;tmdisplay&#039;&#039;&#039; - String representation of the option visible in the table description, usually if variant &amp;quot;names&amp;quot; are On and Off, but the description would be same as option name when On, and nothing when Off. (&#039;&#039;&#039;Warning&#039;&#039;&#039;: due to some caching, a change in tmdisplay may not be effective immediately in the studio, even after forcing a reload of gameoptions.inc.php.)&lt;br /&gt;
** &#039;&#039;&#039;nobeginner&#039;&#039;&#039; - Set to true if not recommended for begginers&lt;br /&gt;
** &#039;&#039;&#039;firstgameonly&#039;&#039;&#039; - Set to true if this option is recommended only for the first game (discovery option)&lt;br /&gt;
** &#039;&#039;&#039;beta&#039;&#039;&#039; - Option in beta stage on development&lt;br /&gt;
** &#039;&#039;&#039;premium&#039;&#039;&#039; - Option can be only used by premium members&lt;br /&gt;
* &#039;&#039;&#039;default&#039;&#039;&#039; - indicates the default value to use for this option (optional, if not present the first value listed is the default)&lt;br /&gt;
* &#039;&#039;&#039;displaycondition&#039;&#039;&#039; - checks the conditions before displaying the option for selection. All conditions must be true for the option to display. Supported condition types:&lt;br /&gt;
** &#039;&#039;minplayers&#039;&#039; condition ensures at least this many players&lt;br /&gt;
** &#039;&#039;maxplayers&#039;&#039; conditions ensure at most this many players&lt;br /&gt;
** &#039;&#039;otheroption&#039;&#039; condition ensures another option is set to this given values. &lt;br /&gt;
** &#039;&#039;otheroptionisnot&#039;&#039; conditions ensure another option is NOT set to this given values&lt;br /&gt;
* &#039;&#039;&#039;displayconditionoperand&#039;&#039;&#039; - can be &#039;and&#039; (this is the default) or &#039;or&#039;. Allows to change the behaviour to display the option if one of the conditions is true instead of all of them.&lt;br /&gt;
* &#039;&#039;&#039;startcondition&#039;&#039;&#039; - checks the conditions (on options VALUES) before starting the game. All conditions must be true for the game to start, otherwise players will get a red error message when attempting to begin the game. Supported condition types:&lt;br /&gt;
** &#039;&#039;minplayers&#039;&#039; condition ensures at least this many players&lt;br /&gt;
** &#039;&#039;maxplayers&#039;&#039; conditions ensure at most this many players&lt;br /&gt;
** &#039;&#039;otheroption&#039;&#039; conditions ensure another option is set to this given values. That works the same as in &#039;&#039;&#039;displaycondition&#039;&#039;&#039;.&lt;br /&gt;
** &#039;&#039;otheroptionisnot&#039;&#039; conditions ensure another option is NOT set to this given value.  That works the same as in &#039;&#039;&#039;displaycondition&#039;&#039;&#039;.&lt;br /&gt;
* &#039;&#039;&#039;notdisplayedmessage&#039;&#039;&#039; - if option is not suppose to be visible because of displaycondition but this is set, the text will be visible instead of combo drop down&lt;br /&gt;
&lt;br /&gt;
Common options for all tables (reserved range 200-299):&lt;br /&gt;
*201 (const GAMESTATE_RATING_MODE) - ELO OFF (aka Training mode), &lt;br /&gt;
*200 (const GAMESTATE_CLOCK_MODE) - game speed profile, array(0,1,2) - realtime, values 11-21 - turn based&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 $game_options = array(&lt;br /&gt;
     100 =&amp;gt; array(&lt;br /&gt;
         &#039;name&#039; =&amp;gt; totranslate(&#039;my game option&#039;),&lt;br /&gt;
         &#039;values&#039; =&amp;gt; array(&lt;br /&gt;
             // A simple value for this option:&lt;br /&gt;
             1 =&amp;gt; array(&lt;br /&gt;
                 &#039;name&#039; =&amp;gt; totranslate(&#039;option 1&#039;)&lt;br /&gt;
             ),&lt;br /&gt;
&lt;br /&gt;
             // A simple value for this option.&lt;br /&gt;
             // If this value is chosen, the value of &amp;quot;tmdisplay&amp;quot; is displayed in the game lobby&lt;br /&gt;
             2 =&amp;gt; array(&lt;br /&gt;
                 &#039;name&#039; =&amp;gt; totranslate(&#039;option 2&#039;),&lt;br /&gt;
                 &#039;tmdisplay&#039; =&amp;gt; totranslate(&#039;option 2&#039;)&lt;br /&gt;
             ),&lt;br /&gt;
&lt;br /&gt;
             // Another value, with other options:&lt;br /&gt;
             //  beta=true =&amp;gt; this option is in beta version right now.&lt;br /&gt;
             //  nobeginner=true  =&amp;gt;  this option is not recommended for beginners&lt;br /&gt;
             3 =&amp;gt; array(&lt;br /&gt;
                 &#039;name&#039; =&amp;gt; totranslate(&#039;option 3&#039;),&lt;br /&gt;
                 &#039;beta&#039; =&amp;gt; true,&lt;br /&gt;
                 &#039;nobeginner&#039; =&amp;gt; true&lt;br /&gt;
             ),&lt;br /&gt;
         ),&lt;br /&gt;
         &#039;default&#039; =&amp;gt; 1&lt;br /&gt;
     ),&lt;br /&gt;
     &lt;br /&gt;
     101 =&amp;gt; array(&lt;br /&gt;
         &#039;name&#039; =&amp;gt; totranslate(&#039;Draft variant&#039;),&lt;br /&gt;
         &#039;values&#039; =&amp;gt; array(&lt;br /&gt;
             1 =&amp;gt; array(&lt;br /&gt;
                 &#039;name&#039; =&amp;gt; totranslate(&#039;No draft&#039;)&lt;br /&gt;
             ),&lt;br /&gt;
             2 =&amp;gt; array(&lt;br /&gt;
                 &#039;name&#039; =&amp;gt; totranslate(&#039;Draft&#039;),&lt;br /&gt;
                 &#039;tmdisplay&#039; =&amp;gt; totranslate(&#039;Draft&#039;),&lt;br /&gt;
                 &#039;premium&#039; =&amp;gt; true,&lt;br /&gt;
                 &#039;nobeginner&#039; =&amp;gt; true&lt;br /&gt;
             ),&lt;br /&gt;
         ),&lt;br /&gt;
         &#039;displaycondition&#039; =&amp;gt; array( &lt;br /&gt;
             // Note: do not display this option unless these conditions are met&lt;br /&gt;
             array(&lt;br /&gt;
                 &#039;type&#039; =&amp;gt; &#039;otheroption&#039;,&lt;br /&gt;
                 &#039;id&#039; =&amp;gt; 100, // Game specific option defined in the same array above&lt;br /&gt;
                 &#039;value&#039; =&amp;gt; array(2, 3, 4)&lt;br /&gt;
             ),&lt;br /&gt;
             // Note: do not display this option unless these conditions are met&lt;br /&gt;
            array( &#039;type&#039; =&amp;gt; &#039;otheroption&#039;, &lt;br /&gt;
                 &#039;id&#039; =&amp;gt; 201, // ELO OFF hardcoded framework option&lt;br /&gt;
                 &#039;value&#039; =&amp;gt; 1 // 1 if OFF&lt;br /&gt;
            )&lt;br /&gt;
         ),&lt;br /&gt;
&lt;br /&gt;
         &#039;startcondition&#039; =&amp;gt; array(&lt;br /&gt;
             1 =&amp;gt; array(),&lt;br /&gt;
             2 =&amp;gt; array(&lt;br /&gt;
                 array(&lt;br /&gt;
                     &#039;type&#039; =&amp;gt; &#039;maxplayers&#039;,&lt;br /&gt;
                     &#039;value&#039; =&amp;gt; 3,&lt;br /&gt;
                     &#039;message&#039; =&amp;gt; totranslate(&#039;Draft option is available for 3 players maximum.&#039;)&lt;br /&gt;
                 )&lt;br /&gt;
             ),&lt;br /&gt;
         ),&lt;br /&gt;
     ),&lt;br /&gt;
     &lt;br /&gt;
     102 =&amp;gt; array(&lt;br /&gt;
         &#039;name&#039; =&amp;gt; totranslate(&#039;Takeovers&#039;),&lt;br /&gt;
         &#039;values&#039; =&amp;gt; array(&lt;br /&gt;
             2 =&amp;gt; array(&lt;br /&gt;
                 &#039;name&#039; =&amp;gt; totranslate(&#039;No takeover&#039;)&lt;br /&gt;
             ),&lt;br /&gt;
             1 =&amp;gt; array(&lt;br /&gt;
                 &#039;name&#039; =&amp;gt; totranslate(&#039;Allow takeovers&#039;),&lt;br /&gt;
                 &#039;tmdisplay&#039; =&amp;gt; totranslate(&#039;Takeovers&#039;),&lt;br /&gt;
                 &#039;premium&#039; =&amp;gt; true,&lt;br /&gt;
                 &#039;nobeginner&#039; =&amp;gt; true&lt;br /&gt;
             ),&lt;br /&gt;
         ),&lt;br /&gt;
         &#039;displaycondition&#039; =&amp;gt; array( // Note: do not display this option unless these conditions are met&lt;br /&gt;
             array(&lt;br /&gt;
                 &#039;type&#039; =&amp;gt; &#039;otheroption&#039;,&lt;br /&gt;
                 &#039;id&#039; =&amp;gt; 100,&lt;br /&gt;
                 &#039;value&#039; =&amp;gt; array(3, 4)&lt;br /&gt;
             )&lt;br /&gt;
         ),&lt;br /&gt;
         &#039;startcondition&#039; =&amp;gt; array(&lt;br /&gt;
             2 =&amp;gt; array(),&lt;br /&gt;
             1 =&amp;gt; array(&lt;br /&gt;
                 array(&lt;br /&gt;
                     &#039;type&#039; =&amp;gt; &#039;maxplayers&#039;,&lt;br /&gt;
                     &#039;value&#039; =&amp;gt; 2,&lt;br /&gt;
                     &#039;message&#039; =&amp;gt; totranslate(&#039;Rebel vs Imperium Takeover Scenario is available for 2 players only.&#039;)&lt;br /&gt;
                 )&lt;br /&gt;
             ),&lt;br /&gt;
         ),&lt;br /&gt;
     )&lt;br /&gt;
 );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example of option that condition on ELO off&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$game_options = array(&lt;br /&gt;
&lt;br /&gt;
        100 =&amp;gt; array(&lt;br /&gt;
                &#039;name&#039; =&amp;gt; totranslate(&#039;Learning Game (No Research)&#039;),&lt;br /&gt;
                &#039;values&#039; =&amp;gt; array(&lt;br /&gt;
                        &lt;br /&gt;
                        1 =&amp;gt; array( &#039;name&#039; =&amp;gt; totranslate(&#039;Off&#039;), &#039;tmdisplay&#039; =&amp;gt; totranslate(&#039;&#039;) ),&lt;br /&gt;
                        2 =&amp;gt; array( &#039;name&#039; =&amp;gt; totranslate(&#039;On&#039;), &#039;tmdisplay&#039; =&amp;gt; totranslate(&#039;Learning Game&#039;) ),&lt;br /&gt;
                        &lt;br /&gt;
                ),&lt;br /&gt;
                &#039;displaycondition&#039; =&amp;gt; array(&lt;br /&gt;
                        // Note: do not display this option unless these conditions are met&lt;br /&gt;
                        array( &#039;type&#039; =&amp;gt; &#039;otheroption&#039;,&lt;br /&gt;
                                &#039;id&#039; =&amp;gt; 201, // ELO OFF hardcoded framework option&lt;br /&gt;
                                &#039;value&#039; =&amp;gt; 1, // 1 if OFF&lt;br /&gt;
&lt;br /&gt;
                        )&lt;br /&gt;
                ),&lt;br /&gt;
                &#039;notdisplayedmessage&#039; =&amp;gt; totranslate(&#039;Learning variant available only with ELO off&#039;)&lt;br /&gt;
                ),&lt;br /&gt;
&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example of condition that is only available for REALTIME game mode&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&#039;displaycondition&#039; =&amp;gt; array(&lt;br /&gt;
    // Note: do not display this option until these conditions are met - game speed is selected as realtime&lt;br /&gt;
    array( &#039;type&#039; =&amp;gt; &#039;otheroption&#039;, &#039;id&#039; =&amp;gt; GAMESTATE_CLOCK_MODE, &#039;value&#039; =&amp;gt; array(0,1,2) )&lt;br /&gt;
),&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example of using condition on your own option&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        102 =&amp;gt; array(&lt;br /&gt;
                &#039;name&#039; =&amp;gt; totranslate(&#039;Scenarios&#039;),&lt;br /&gt;
                &#039;values&#039; =&amp;gt; array(&lt;br /&gt;
                        1 =&amp;gt; array( &#039;name&#039; =&amp;gt; totranslate(&#039;Off&#039;),&lt;br /&gt;
                                &#039;nobeginner&#039; =&amp;gt; false  ),&lt;br /&gt;
                        2 =&amp;gt; array( &#039;name&#039; =&amp;gt; totranslate(&#039;On&#039;), &#039;tmdisplay&#039; =&amp;gt; totranslate(&#039;Scenarios&#039;),&lt;br /&gt;
                                &#039;nobeginner&#039; =&amp;gt; true  ),&lt;br /&gt;
                        &lt;br /&gt;
                ),&lt;br /&gt;
                &#039;displaycondition&#039; =&amp;gt; array(&lt;br /&gt;
                        // Note: do not display this option unless these conditions are met&lt;br /&gt;
                        array( &#039;type&#039; =&amp;gt; &#039;otheroptionisnot&#039;,&lt;br /&gt;
                                &#039;id&#039; =&amp;gt; 100, // learning variant&lt;br /&gt;
                                &#039;value&#039; =&amp;gt; 2, // 1 if OFF,2 is ON&lt;br /&gt;
                                &lt;br /&gt;
                        )&lt;br /&gt;
                ),&lt;br /&gt;
                &#039;notdisplayedmessage&#039; =&amp;gt; totranslate(&#039;Scenarios variant is not available if Learning variant is chosen&#039;)&lt;br /&gt;
        ),&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== User Preferences ==&lt;br /&gt;
&lt;br /&gt;
User preferences is something cosmetic about the game interface which however can create user wars, so you can satisfy all users&lt;br /&gt;
by giving them individual preferences. You should use this only if it significantly improves the interface for a large proportion of users.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$game_preferences = array(&lt;br /&gt;
    100 =&amp;gt; array(&lt;br /&gt;
        &#039;name&#039; =&amp;gt; totranslate(&#039;Notation style&#039;),&lt;br /&gt;
        &#039;needReload&#039; =&amp;gt; true, // after user changes this preference game interface would auto-reload&lt;br /&gt;
        &#039;values&#039; =&amp;gt; array(&lt;br /&gt;
            1 =&amp;gt; array( &#039;name&#039; =&amp;gt; totranslate( &#039;Classic&#039; ), &#039;cssPref&#039; =&amp;gt; &#039;notation_classic&#039; ),&lt;br /&gt;
            2 =&amp;gt; array( &#039;name&#039; =&amp;gt; totranslate( &#039;Tournament&#039; ), &#039;cssPref&#039; =&amp;gt; &#039;notation_tournament&#039; )&lt;br /&gt;
        ),&lt;br /&gt;
        &#039;default&#039; =&amp;gt; 2&lt;br /&gt;
    )&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There is two ways to check/apply this. In java Script&lt;br /&gt;
&lt;br /&gt;
  if (this.prefs[100].value == 2) ...&lt;br /&gt;
&lt;br /&gt;
This checks if preferences 100 has selected value 2.&lt;br /&gt;
&lt;br /&gt;
Second, if cssPref specified it will be applied to the &#039;&#039;&#039;&amp;lt;html&amp;gt;&#039;&#039;&#039; tag. So you can use different css styling for the preference. Note: it seems needed to set needReload to true for that class change to be effective.&lt;br /&gt;
&lt;br /&gt;
As user you have to select them from the Gear menu when game is started. On studio only user0 will have it actually working (bug?).&lt;br /&gt;
&lt;br /&gt;
The following are the parameters of preferences description array:&lt;br /&gt;
* &#039;&#039;&#039;name&#039;&#039;&#039; - &#039;&#039;&#039;mandatory&#039;&#039;&#039;. The name of the preference. Value will be automatically wrapped in totranslate if you don&#039;t.&lt;br /&gt;
* &#039;&#039;&#039;needReload&#039;&#039;&#039; - If set to true, the game interface will auto-reload after a change of the preference.&lt;br /&gt;
* &#039;&#039;&#039;values&#039;&#039;&#039; - &#039;&#039;&#039;mandatory&#039;&#039;&#039;. The array (map) of values with additional parameters per value.&lt;br /&gt;
** &#039;&#039;&#039;name&#039;&#039;&#039; - &#039;&#039;&#039;mandatory&#039;&#039;&#039;. String representation of the numeric value. Value will be automatically wrapped in totranslate if you don&#039;t.&lt;br /&gt;
** &#039;&#039;&#039;cssPref&#039;&#039;&#039; - CSS class to add to the &#039;&#039;&#039;&amp;lt;html&amp;gt;&#039;&#039;&#039; tag. Currently it is added or removed only after a reload (see needReload).&lt;br /&gt;
* &#039;&#039;&#039;default&#039;&#039;&#039; - Indicates the default value to use for this preference (optional, if not present the first value listed is the default).&lt;br /&gt;
&lt;br /&gt;
=== Listening for preference changes ===&lt;br /&gt;
&lt;br /&gt;
The BGA framework lacks any callback to notify your game when a user preference is changed (see [https://studio.boardgamearena.com/bug?id=36 proposal #36]), but you can create your own if you need to run some UI code in response to a preference change.&lt;br /&gt;
&lt;br /&gt;
; In ggg.js&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    setup: function (gamedatas) {&lt;br /&gt;
      ... // your setup code here&lt;br /&gt;
      this.setupPreference();&lt;br /&gt;
    },&lt;br /&gt;
    &lt;br /&gt;
    setupPreference: function () {&lt;br /&gt;
      // Extract the ID and value from the UI control&lt;br /&gt;
      var _this = this;&lt;br /&gt;
      function onchange(e) {&lt;br /&gt;
        var match = e.target.id.match(/^preference_[cf]ontrol_(\d+)$/);&lt;br /&gt;
        if (!match) {&lt;br /&gt;
          return;&lt;br /&gt;
        }&lt;br /&gt;
        var prefId = +match[1];&lt;br /&gt;
        var prefValue = +e.target.value;&lt;br /&gt;
        _this.prefs[prefId].value = prefValue;&lt;br /&gt;
        _this.onPreferenceChange(prefId, prefValue);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      // Call onPreferenceChange() when any value changes&lt;br /&gt;
      dojo.query(&amp;quot;.preference_control&amp;quot;).connect(&amp;quot;onchange&amp;quot;, onchange);&lt;br /&gt;
      &lt;br /&gt;
      // Call onPreferenceChange() now&lt;br /&gt;
      dojo.forEach(&lt;br /&gt;
        dojo.query(&amp;quot;#ingame_menu_content .preference_control&amp;quot;),&lt;br /&gt;
        function (el) {&lt;br /&gt;
          onchange({ target: el });&lt;br /&gt;
        }&lt;br /&gt;
      );&lt;br /&gt;
    },&lt;br /&gt;
    &lt;br /&gt;
    onPreferenceChange: function (prefId, prefValue) {&lt;br /&gt;
      console.log(&amp;quot;Preference changed&amp;quot;, prefId, prefValue);&lt;br /&gt;
      ... // your code here to handle the change&lt;br /&gt;
    },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Updating preference from code ===&lt;br /&gt;
The BGA framework lacks any method to update a user preference from the code (see [https://studio.boardgamearena.com/bug?id=36 proposal #36]), but you can create your own if you need to.&lt;br /&gt;
&lt;br /&gt;
; In ggg.js&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    updatePreference: function(prefId, newValue) {&lt;br /&gt;
        // Select preference value in control:&lt;br /&gt;
        dojo.query(&#039;#preference_control_&#039; + prefId + &#039; &amp;gt; option[value=&amp;quot;&#039; + newValue&lt;br /&gt;
        // Also select fontrol to fix a BGA framework bug:&lt;br /&gt;
            + &#039;&amp;quot;], #preference_fontrol_&#039; + prefId + &#039; &amp;gt; option[value=&amp;quot;&#039; + newValue&lt;br /&gt;
            + &#039;&amp;quot;]&#039;).forEach((value) =&amp;gt; dojo.attr(value, &#039;selected&#039;, true));&lt;br /&gt;
        // Generate change event on control to trigger callbacks:&lt;br /&gt;
        const newEvt = document.createEvent(&#039;HTMLEvents&#039;);&lt;br /&gt;
        newEvt.initEvent(&#039;change&#039;, false, true);&lt;br /&gt;
        $(&#039;preference_control_&#039; + prefId).dispatchEvent(newEvt);&lt;br /&gt;
    },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>R3z3nd3</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Options_and_preferences:_gameoptions.json,_gamepreferences.json&amp;diff=8601</id>
		<title>Options and preferences: gameoptions.json, gamepreferences.json</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Options_and_preferences:_gameoptions.json,_gamepreferences.json&amp;diff=8601"/>
		<updated>2021-06-26T21:33:02Z</updated>

		<summary type="html">&lt;p&gt;R3z3nd3: Included missing &amp;quot;in&amp;quot; word&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Studio_Framework_Navigation}}&lt;br /&gt;
&lt;br /&gt;
In this file, you can define your game options (i.e. game variants) and user preferences.&lt;br /&gt;
   &lt;br /&gt;
Note: If your game has no variants or preferences, you don&#039;t have to modify this file.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;IMPORTANT:&#039;&#039;&#039; after you edited this file and syncronized to ftp folder you have to go to the control panel and press &amp;quot;Reload game options configuration&amp;quot; for your changes &#039;&#039;&#039;to take effect&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Make sure you understand difference bettween options and preferences:&lt;br /&gt;
* Game options - something usually in the rule book defined as &amp;quot;variant&amp;quot; (except for 2,3,X people - that is automatically handled - you can query it)&lt;br /&gt;
* Game preferences - personal choice of player only visible to this specific player - i.e. layout, either or not prompt for action, ether or not auto-opt in in some actions, etc&lt;br /&gt;
&lt;br /&gt;
== Game Options ==&lt;br /&gt;
&lt;br /&gt;
Game options are selected by the table creator and usually correspond to game variants, for example if the game includes expansions or certain special rules.&lt;br /&gt;
&lt;br /&gt;
These variants are defined in gameoptions.inc.php as the $game_options variable:  &lt;br /&gt;
  $game_options = array(...); // exactly named that&lt;br /&gt;
&lt;br /&gt;
Each option is a pair int the format: number =&amp;gt; &#039;option description array&#039;. &lt;br /&gt;
&lt;br /&gt;
All options defined in this file should have a corresponding &amp;quot;game state label&amp;quot; with the same ID (see &amp;quot;initGameStateLabels&amp;quot; in yourgame.game.php)&lt;br /&gt;
&lt;br /&gt;
             self::initGameStateLabels ( array (&lt;br /&gt;
                        ...&lt;br /&gt;
                        &amp;quot;my_game_variant&amp;quot; =&amp;gt; 100,&lt;br /&gt;
              ) );&lt;br /&gt;
&lt;br /&gt;
Numbers have to be exactly from 100 to 199 (there can be gaps).&lt;br /&gt;
&lt;br /&gt;
That is how you access them during runtime:&lt;br /&gt;
&lt;br /&gt;
    public function isSecondVariant() {&lt;br /&gt;
        return $this-&amp;gt;getGameStateValue(&#039;my_game_variant&#039;) == 2;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
Or this&lt;br /&gt;
    $this-&amp;gt;gamestate-&amp;gt;table_globals[100]&lt;br /&gt;
&lt;br /&gt;
The following are the parameters of option description array:&lt;br /&gt;
* &#039;&#039;&#039;name&#039;&#039;&#039; - &#039;&#039;&#039;mandatory&#039;&#039;&#039;. The name of the option visible for table creator. Value must be wrapped in totranslate function.&lt;br /&gt;
* &#039;&#039;&#039;values&#039;&#039;&#039; - &#039;&#039;&#039;mandatory&#039;&#039;&#039;. The array (map) of values with additional parameters per value.&lt;br /&gt;
** &#039;&#039;&#039;name&#039;&#039;&#039; - &#039;&#039;&#039;mandatory&#039;&#039;&#039;. String representation of the numeric value visible to table creator. Value must be wrapped in totranslate function.&lt;br /&gt;
** &#039;&#039;&#039;description&#039;&#039;&#039; - String description of this value to use when the name of the option is not self-explanatory. Displayed at the table under the option when this value is selected.&lt;br /&gt;
** &#039;&#039;&#039;tmdisplay&#039;&#039;&#039; - String representation of the option visible in the table description, usually if variant &amp;quot;names&amp;quot; are On and Off, but the description would be same as option name when On, and nothing when Off. (&#039;&#039;&#039;Warning&#039;&#039;&#039;: due to some caching, a change in tmdisplay may not be effective immediately in the studio, even after forcing a reload of gameoptions.inc.php.)&lt;br /&gt;
** &#039;&#039;&#039;nobeginner&#039;&#039;&#039; - Set to true if not recommended for begginers&lt;br /&gt;
** &#039;&#039;&#039;firstgameonly&#039;&#039;&#039; - Set to true if this option is recommended only for the first game (discovery option)&lt;br /&gt;
** &#039;&#039;&#039;beta&#039;&#039;&#039; - Option in beta stage on development&lt;br /&gt;
** &#039;&#039;&#039;premium&#039;&#039;&#039; - Option can be only used by premium members&lt;br /&gt;
* &#039;&#039;&#039;default&#039;&#039;&#039; - indicates the default value to use for this option (optional, if not present the first value listed is the default)&lt;br /&gt;
* &#039;&#039;&#039;displaycondition&#039;&#039;&#039; - checks the conditions before displaying the option for selection. All conditions must be true for the option to display. Supported condition types:&lt;br /&gt;
** &#039;&#039;minplayers&#039;&#039; condition ensures at least this many players&lt;br /&gt;
** &#039;&#039;maxplayers&#039;&#039; conditions ensure at most this many players&lt;br /&gt;
** &#039;&#039;otheroption&#039;&#039; condition ensures another option is set to this given values. &lt;br /&gt;
** &#039;&#039;otheroptionisnot&#039;&#039; conditions ensure another option is NOT set to this given values&lt;br /&gt;
* &#039;&#039;&#039;displayconditionoperand&#039;&#039;&#039; - can be &#039;and&#039; (this is the default) or &#039;or&#039;. Allows to change the behaviour to display the option if one of the conditions is true instead of all of them.&lt;br /&gt;
* &#039;&#039;&#039;startcondition&#039;&#039;&#039; - checks the conditions (on options VALUES) before starting the game. All conditions must be true for the game to start, otherwise players will get a red error message when attempting to begin the game. Supported condition types:&lt;br /&gt;
** &#039;&#039;minplayers&#039;&#039; condition ensures at least this many players&lt;br /&gt;
** &#039;&#039;maxplayers&#039;&#039; conditions ensure at most this many players&lt;br /&gt;
** &#039;&#039;otheroption&#039;&#039; conditions ensure another option is set to this given values. That works the same as in &#039;&#039;&#039;displaycondition&#039;&#039;&#039;.&lt;br /&gt;
** &#039;&#039;otheroptionisnot&#039;&#039; conditions ensure another option is NOT set to this given value.  That works the same as in &#039;&#039;&#039;displaycondition&#039;&#039;&#039;.&lt;br /&gt;
* &#039;&#039;&#039;notdisplayedmessage&#039;&#039;&#039; - if option is not suppose to be visible because of displaycondition but this is set, the text will be visible instead of combo drop down&lt;br /&gt;
&lt;br /&gt;
Common options for all tables (reserved range 200-299):&lt;br /&gt;
*201 (const GAMESTATE_RATING_MODE) - ELO OFF (aka Training mode), &lt;br /&gt;
*200 (const GAMESTATE_CLOCK_MODE) - game speed profile, array(0,1,2) - realtime, values 11-21 - turn based&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 $game_options = array(&lt;br /&gt;
     100 =&amp;gt; array(&lt;br /&gt;
         &#039;name&#039; =&amp;gt; totranslate(&#039;my game option&#039;),&lt;br /&gt;
         &#039;values&#039; =&amp;gt; array(&lt;br /&gt;
             // A simple value for this option:&lt;br /&gt;
             1 =&amp;gt; array(&lt;br /&gt;
                 &#039;name&#039; =&amp;gt; totranslate(&#039;option 1&#039;)&lt;br /&gt;
             ),&lt;br /&gt;
&lt;br /&gt;
             // A simple value for this option.&lt;br /&gt;
             // If this value is chosen, the value of &amp;quot;tmdisplay&amp;quot; is displayed in the game lobby&lt;br /&gt;
             2 =&amp;gt; array(&lt;br /&gt;
                 &#039;name&#039; =&amp;gt; totranslate(&#039;option 2&#039;),&lt;br /&gt;
                 &#039;tmdisplay&#039; =&amp;gt; totranslate(&#039;option 2&#039;)&lt;br /&gt;
             ),&lt;br /&gt;
&lt;br /&gt;
             // Another value, with other options:&lt;br /&gt;
             //  beta=true =&amp;gt; this option is in beta version right now.&lt;br /&gt;
             //  nobeginner=true  =&amp;gt;  this option is not recommended for beginners&lt;br /&gt;
             3 =&amp;gt; array(&lt;br /&gt;
                 &#039;name&#039; =&amp;gt; totranslate(&#039;option 3&#039;),&lt;br /&gt;
                 &#039;beta&#039; =&amp;gt; true,&lt;br /&gt;
                 &#039;nobeginner&#039; =&amp;gt; true&lt;br /&gt;
             ),&lt;br /&gt;
         ),&lt;br /&gt;
         &#039;default&#039; =&amp;gt; 1&lt;br /&gt;
     ),&lt;br /&gt;
     &lt;br /&gt;
     101 =&amp;gt; array(&lt;br /&gt;
         &#039;name&#039; =&amp;gt; totranslate(&#039;Draft variant&#039;),&lt;br /&gt;
         &#039;values&#039; =&amp;gt; array(&lt;br /&gt;
             1 =&amp;gt; array(&lt;br /&gt;
                 &#039;name&#039; =&amp;gt; totranslate(&#039;No draft&#039;)&lt;br /&gt;
             ),&lt;br /&gt;
             2 =&amp;gt; array(&lt;br /&gt;
                 &#039;name&#039; =&amp;gt; totranslate(&#039;Draft&#039;),&lt;br /&gt;
                 &#039;tmdisplay&#039; =&amp;gt; totranslate(&#039;Draft&#039;),&lt;br /&gt;
                 &#039;premium&#039; =&amp;gt; true,&lt;br /&gt;
                 &#039;nobeginner&#039; =&amp;gt; true&lt;br /&gt;
             ),&lt;br /&gt;
         ),&lt;br /&gt;
         &#039;displaycondition&#039; =&amp;gt; array( &lt;br /&gt;
             // Note: do not display this option unless these conditions are met&lt;br /&gt;
             array(&lt;br /&gt;
                 &#039;type&#039; =&amp;gt; &#039;otheroption&#039;,&lt;br /&gt;
                 &#039;id&#039; =&amp;gt; 100, // Game specific option defined in the same array above&lt;br /&gt;
                 &#039;value&#039; =&amp;gt; array(2, 3, 4)&lt;br /&gt;
             ),&lt;br /&gt;
             // Note: do not display this option unless these conditions are met&lt;br /&gt;
            array( &#039;type&#039; =&amp;gt; &#039;otheroption&#039;, &lt;br /&gt;
                 &#039;id&#039; =&amp;gt; 201, // ELO OFF hardcoded framework option&lt;br /&gt;
                 &#039;value&#039; =&amp;gt; 1 // 1 if OFF&lt;br /&gt;
            )&lt;br /&gt;
         ),&lt;br /&gt;
&lt;br /&gt;
         &#039;startcondition&#039; =&amp;gt; array(&lt;br /&gt;
             1 =&amp;gt; array(),&lt;br /&gt;
             2 =&amp;gt; array(&lt;br /&gt;
                 array(&lt;br /&gt;
                     &#039;type&#039; =&amp;gt; &#039;maxplayers&#039;,&lt;br /&gt;
                     &#039;value&#039; =&amp;gt; 3,&lt;br /&gt;
                     &#039;message&#039; =&amp;gt; totranslate(&#039;Draft option is available for 3 players maximum.&#039;)&lt;br /&gt;
                 )&lt;br /&gt;
             ),&lt;br /&gt;
         ),&lt;br /&gt;
     ),&lt;br /&gt;
     &lt;br /&gt;
     102 =&amp;gt; array(&lt;br /&gt;
         &#039;name&#039; =&amp;gt; totranslate(&#039;Takeovers&#039;),&lt;br /&gt;
         &#039;values&#039; =&amp;gt; array(&lt;br /&gt;
             2 =&amp;gt; array(&lt;br /&gt;
                 &#039;name&#039; =&amp;gt; totranslate(&#039;No takeover&#039;)&lt;br /&gt;
             ),&lt;br /&gt;
             1 =&amp;gt; array(&lt;br /&gt;
                 &#039;name&#039; =&amp;gt; totranslate(&#039;Allow takeovers&#039;),&lt;br /&gt;
                 &#039;tmdisplay&#039; =&amp;gt; totranslate(&#039;Takeovers&#039;),&lt;br /&gt;
                 &#039;premium&#039; =&amp;gt; true,&lt;br /&gt;
                 &#039;nobeginner&#039; =&amp;gt; true&lt;br /&gt;
             ),&lt;br /&gt;
         ),&lt;br /&gt;
         &#039;displaycondition&#039; =&amp;gt; array( // Note: do not display this option unless these conditions are met&lt;br /&gt;
             array(&lt;br /&gt;
                 &#039;type&#039; =&amp;gt; &#039;otheroption&#039;,&lt;br /&gt;
                 &#039;id&#039; =&amp;gt; 100,&lt;br /&gt;
                 &#039;value&#039; =&amp;gt; array(3, 4)&lt;br /&gt;
             )&lt;br /&gt;
         ),&lt;br /&gt;
         &#039;startcondition&#039; =&amp;gt; array(&lt;br /&gt;
             2 =&amp;gt; array(),&lt;br /&gt;
             1 =&amp;gt; array(&lt;br /&gt;
                 array(&lt;br /&gt;
                     &#039;type&#039; =&amp;gt; &#039;maxplayers&#039;,&lt;br /&gt;
                     &#039;value&#039; =&amp;gt; 2,&lt;br /&gt;
                     &#039;message&#039; =&amp;gt; totranslate(&#039;Rebel vs Imperium Takeover Scenario is available for 2 players only.&#039;)&lt;br /&gt;
                 )&lt;br /&gt;
             ),&lt;br /&gt;
         ),&lt;br /&gt;
     )&lt;br /&gt;
 );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example of option that condition on ELO off&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$game_options = array(&lt;br /&gt;
&lt;br /&gt;
        100 =&amp;gt; array(&lt;br /&gt;
                &#039;name&#039; =&amp;gt; totranslate(&#039;Learning Game (No Research)&#039;),&lt;br /&gt;
                &#039;values&#039; =&amp;gt; array(&lt;br /&gt;
                        &lt;br /&gt;
                        1 =&amp;gt; array( &#039;name&#039; =&amp;gt; totranslate(&#039;Off&#039;), &#039;tmdisplay&#039; =&amp;gt; totranslate(&#039;&#039;) ),&lt;br /&gt;
                        2 =&amp;gt; array( &#039;name&#039; =&amp;gt; totranslate(&#039;On&#039;), &#039;tmdisplay&#039; =&amp;gt; totranslate(&#039;Learning Game&#039;) ),&lt;br /&gt;
                        &lt;br /&gt;
                ),&lt;br /&gt;
                &#039;displaycondition&#039; =&amp;gt; array(&lt;br /&gt;
                        // Note: do not display this option unless these conditions are met&lt;br /&gt;
                        array( &#039;type&#039; =&amp;gt; &#039;otheroption&#039;,&lt;br /&gt;
                                &#039;id&#039; =&amp;gt; 201, // ELO OFF hardcoded framework option&lt;br /&gt;
                                &#039;value&#039; =&amp;gt; 1, // 1 if OFF&lt;br /&gt;
&lt;br /&gt;
                        )&lt;br /&gt;
                ),&lt;br /&gt;
                &#039;notdisplayedmessage&#039; =&amp;gt; totranslate(&#039;Learning variant available only with ELO off&#039;)&lt;br /&gt;
                ),&lt;br /&gt;
&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example of condition that is only available for REALTIME game mode&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&#039;displaycondition&#039; =&amp;gt; array(&lt;br /&gt;
    // Note: do not display this option until these conditions are met - game speed is selected as realtime&lt;br /&gt;
    array( &#039;type&#039; =&amp;gt; &#039;otheroption&#039;, &#039;id&#039; =&amp;gt; GAMESTATE_CLOCK_MODE, &#039;value&#039; =&amp;gt; array(0,1,2) )&lt;br /&gt;
),&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example of using condition on your own option&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        102 =&amp;gt; array(&lt;br /&gt;
                &#039;name&#039; =&amp;gt; totranslate(&#039;Scenarios&#039;),&lt;br /&gt;
                &#039;values&#039; =&amp;gt; array(&lt;br /&gt;
                        1 =&amp;gt; array( &#039;name&#039; =&amp;gt; totranslate(&#039;Off&#039;),&lt;br /&gt;
                                &#039;nobeginner&#039; =&amp;gt; false  ),&lt;br /&gt;
                        2 =&amp;gt; array( &#039;name&#039; =&amp;gt; totranslate(&#039;On&#039;), &#039;tmdisplay&#039; =&amp;gt; totranslate(&#039;Scenarios&#039;),&lt;br /&gt;
                                &#039;nobeginner&#039; =&amp;gt; true  ),&lt;br /&gt;
                        &lt;br /&gt;
                ),&lt;br /&gt;
                &#039;displaycondition&#039; =&amp;gt; array(&lt;br /&gt;
                        // Note: do not display this option unless these conditions are met&lt;br /&gt;
                        array( &#039;type&#039; =&amp;gt; &#039;otheroptionisnot&#039;,&lt;br /&gt;
                                &#039;id&#039; =&amp;gt; 100, // learning variant&lt;br /&gt;
                                &#039;value&#039; =&amp;gt; 2, // 1 if OFF,2 is ON&lt;br /&gt;
                                &lt;br /&gt;
                        )&lt;br /&gt;
                ),&lt;br /&gt;
                &#039;notdisplayedmessage&#039; =&amp;gt; totranslate(&#039;Scenarios variant is not available if Learning variant is chosen&#039;)&lt;br /&gt;
        ),&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== User Preferences ==&lt;br /&gt;
&lt;br /&gt;
User preferences is something cosmetic about the game interface which however can create user wars, so you can satisfy all users&lt;br /&gt;
by giving them individual preferences. You should use this only if it significantly improves the interface for a large proportion of users.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$game_preferences = array(&lt;br /&gt;
    100 =&amp;gt; array(&lt;br /&gt;
        &#039;name&#039; =&amp;gt; totranslate(&#039;Notation style&#039;),&lt;br /&gt;
        &#039;needReload&#039; =&amp;gt; true, // after user changes this preference game interface would auto-reload&lt;br /&gt;
        &#039;values&#039; =&amp;gt; array(&lt;br /&gt;
            1 =&amp;gt; array( &#039;name&#039; =&amp;gt; totranslate( &#039;Classic&#039; ), &#039;cssPref&#039; =&amp;gt; &#039;notation_classic&#039; ),&lt;br /&gt;
            2 =&amp;gt; array( &#039;name&#039; =&amp;gt; totranslate( &#039;Tournament&#039; ), &#039;cssPref&#039; =&amp;gt; &#039;notation_tournament&#039; )&lt;br /&gt;
        ),&lt;br /&gt;
        &#039;default&#039; =&amp;gt; 2&lt;br /&gt;
    )&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There is two ways to check/apply this. In java Script&lt;br /&gt;
&lt;br /&gt;
  if (this.prefs[100].value == 2) ...&lt;br /&gt;
&lt;br /&gt;
This checks if preferences 100 has selected value 2.&lt;br /&gt;
&lt;br /&gt;
Second, if cssPref specified it will be applied to the &#039;&#039;&#039;&amp;lt;html&amp;gt;&#039;&#039;&#039; tag. So you can use different css styling for the preference. Note: it seems needed to set needReload to true for that class change to be effective.&lt;br /&gt;
&lt;br /&gt;
As user you have to select them from the Gear menu when game is started. On studio only user0 will have it actually working (bug?).&lt;br /&gt;
&lt;br /&gt;
The following are the parameters of preferences description array:&lt;br /&gt;
* &#039;&#039;&#039;name&#039;&#039;&#039; - &#039;&#039;&#039;mandatory&#039;&#039;&#039;. The name of the preference. Value will be automatically wrapped in totranslate if you don&#039;t.&lt;br /&gt;
* &#039;&#039;&#039;needReload&#039;&#039;&#039; - If set to true, the game interface will auto-reload after a change of the preference.&lt;br /&gt;
* &#039;&#039;&#039;values&#039;&#039;&#039; - &#039;&#039;&#039;mandatory&#039;&#039;&#039;. The array (map) of values with additional parameters per value.&lt;br /&gt;
** &#039;&#039;&#039;name&#039;&#039;&#039; - &#039;&#039;&#039;mandatory&#039;&#039;&#039;. String representation of the numeric value. Value will be automatically wrapped in totranslate if you don&#039;t.&lt;br /&gt;
** &#039;&#039;&#039;cssPref&#039;&#039;&#039; - CSS class to add to the &#039;&#039;&#039;&amp;lt;html&amp;gt;&#039;&#039;&#039; tag. Currently it is added or removed only after a reload (see needReload).&lt;br /&gt;
* &#039;&#039;&#039;default&#039;&#039;&#039; - Indicates the default value to use for this preference (optional, if not present the first value listed is the default).&lt;br /&gt;
&lt;br /&gt;
=== Listening for preference changes ===&lt;br /&gt;
&lt;br /&gt;
The BGA framework lacks any callback to notify your game when a user preference is changed (see [https://studio.boardgamearena.com/bug?id=36 proposal #36]), but you can create your own if you need to run some UI code in response to a preference change.&lt;br /&gt;
&lt;br /&gt;
; In ggg.js&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    setup: function (gamedatas) {&lt;br /&gt;
      ... // your setup code here&lt;br /&gt;
      this.setupPreference();&lt;br /&gt;
    },&lt;br /&gt;
    &lt;br /&gt;
    setupPreference: function () {&lt;br /&gt;
      // Extract the ID and value from the UI control&lt;br /&gt;
      var _this = this;&lt;br /&gt;
      function onchange(e) {&lt;br /&gt;
        var match = e.target.id.match(/^preference_[cf]ontrol_(\d+)$/);&lt;br /&gt;
        if (!match) {&lt;br /&gt;
          return;&lt;br /&gt;
        }&lt;br /&gt;
        var prefId = +match[1];&lt;br /&gt;
        var prefValue = +e.target.value;&lt;br /&gt;
        _this.prefs[prefId].value = prefValue;&lt;br /&gt;
        _this.onPreferenceChange(prefId, prefValue);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      // Call onPreferenceChange() when any value changes&lt;br /&gt;
      dojo.query(&amp;quot;.preference_control&amp;quot;).connect(&amp;quot;onchange&amp;quot;, onchange);&lt;br /&gt;
      &lt;br /&gt;
      // Call onPreferenceChange() now&lt;br /&gt;
      dojo.forEach(&lt;br /&gt;
        dojo.query(&amp;quot;#ingame_menu_content .preference_control&amp;quot;),&lt;br /&gt;
        function (el) {&lt;br /&gt;
          onchange({ target: el });&lt;br /&gt;
        }&lt;br /&gt;
      );&lt;br /&gt;
    },&lt;br /&gt;
    &lt;br /&gt;
    onPreferenceChange: function (prefId, prefValue) {&lt;br /&gt;
      console.log(&amp;quot;Preference changed&amp;quot;, prefId, prefValue);&lt;br /&gt;
      ... // your code here to handle the change&lt;br /&gt;
    },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Updating preference from code ===&lt;br /&gt;
The BGA framework lacks any method to update a user preference from the code (see [https://studio.boardgamearena.com/bug?id=36 proposal #36]), but you can create your own if you need to.&lt;br /&gt;
&lt;br /&gt;
; In ggg.js&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    updatePreference: function(prefId, newValue) {&lt;br /&gt;
        // Select preference value in control:&lt;br /&gt;
        dojo.query(&#039;#preference_control_&#039; + prefId + &#039; &amp;gt; option[value=&amp;quot;&#039; + newValue&lt;br /&gt;
        // Also select fontrol to fix a BGA framework bug:&lt;br /&gt;
            + &#039;&amp;quot;], #preference_fontrol_&#039; + prefId + &#039; &amp;gt; option[value=&amp;quot;&#039; + newValue&lt;br /&gt;
            + &#039;&amp;quot;]&#039;).forEach((value) =&amp;gt; dojo.attr(value, &#039;selected&#039;, true));&lt;br /&gt;
        // Generate change event on control to trigger callbacks:&lt;br /&gt;
        const newEvt = document.createEvent(&#039;HTMLEvents&#039;);&lt;br /&gt;
        newEvt.initEvent(&#039;change&#039;, false, true);&lt;br /&gt;
        $(&#039;preference_control_&#039; + prefId).dispatchEvent(newEvt);&lt;br /&gt;
    },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>R3z3nd3</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Options_and_preferences:_gameoptions.json,_gamepreferences.json&amp;diff=8600</id>
		<title>Options and preferences: gameoptions.json, gamepreferences.json</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Options_and_preferences:_gameoptions.json,_gamepreferences.json&amp;diff=8600"/>
		<updated>2021-06-26T21:32:25Z</updated>

		<summary type="html">&lt;p&gt;R3z3nd3: /* Game Options */ -- Improving grammar&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Studio_Framework_Navigation}}&lt;br /&gt;
&lt;br /&gt;
In this file, you can define your game options (i.e. game variants) and user preferences.&lt;br /&gt;
   &lt;br /&gt;
Note: If your game has no variants or preferences, you don&#039;t have to modify this file.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;IMPORTANT:&#039;&#039;&#039; after you edited this file and syncronized to ftp folder you have to go to the control panel and press &amp;quot;Reload game options configuration&amp;quot; for your changes &#039;&#039;&#039;to take effect&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Make sure you understand difference bettween options and preferences:&lt;br /&gt;
* Game options - something usually in the rule book defined as &amp;quot;variant&amp;quot; (except for 2,3,X people - that is automatically handled - you can query it)&lt;br /&gt;
* Game preferences - personal choice of player only visible to this specific player - i.e. layout, either or not prompt for action, ether or not auto-opt in in some actions, etc&lt;br /&gt;
&lt;br /&gt;
== Game Options ==&lt;br /&gt;
&lt;br /&gt;
Game options are selected by the table creator and usually correspond to game variants, for example if the game includes expansions or certain special rules.&lt;br /&gt;
&lt;br /&gt;
These variants are defined in gameoptions.inc.php as the $game_options variable:  &lt;br /&gt;
  $game_options = array(...); // exactly named that&lt;br /&gt;
&lt;br /&gt;
Each option is a pair the format: number =&amp;gt; &#039;option description array&#039;. &lt;br /&gt;
&lt;br /&gt;
All options defined in this file should have a corresponding &amp;quot;game state label&amp;quot; with the same ID (see &amp;quot;initGameStateLabels&amp;quot; in yourgame.game.php)&lt;br /&gt;
&lt;br /&gt;
             self::initGameStateLabels ( array (&lt;br /&gt;
                        ...&lt;br /&gt;
                        &amp;quot;my_game_variant&amp;quot; =&amp;gt; 100,&lt;br /&gt;
              ) );&lt;br /&gt;
&lt;br /&gt;
Numbers have to be exactly from 100 to 199 (there can be gaps).&lt;br /&gt;
&lt;br /&gt;
That is how you access them during runtime:&lt;br /&gt;
&lt;br /&gt;
    public function isSecondVariant() {&lt;br /&gt;
        return $this-&amp;gt;getGameStateValue(&#039;my_game_variant&#039;) == 2;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
Or this&lt;br /&gt;
    $this-&amp;gt;gamestate-&amp;gt;table_globals[100]&lt;br /&gt;
&lt;br /&gt;
The following are the parameters of option description array:&lt;br /&gt;
* &#039;&#039;&#039;name&#039;&#039;&#039; - &#039;&#039;&#039;mandatory&#039;&#039;&#039;. The name of the option visible for table creator. Value must be wrapped in totranslate function.&lt;br /&gt;
* &#039;&#039;&#039;values&#039;&#039;&#039; - &#039;&#039;&#039;mandatory&#039;&#039;&#039;. The array (map) of values with additional parameters per value.&lt;br /&gt;
** &#039;&#039;&#039;name&#039;&#039;&#039; - &#039;&#039;&#039;mandatory&#039;&#039;&#039;. String representation of the numeric value visible to table creator. Value must be wrapped in totranslate function.&lt;br /&gt;
** &#039;&#039;&#039;description&#039;&#039;&#039; - String description of this value to use when the name of the option is not self-explanatory. Displayed at the table under the option when this value is selected.&lt;br /&gt;
** &#039;&#039;&#039;tmdisplay&#039;&#039;&#039; - String representation of the option visible in the table description, usually if variant &amp;quot;names&amp;quot; are On and Off, but the description would be same as option name when On, and nothing when Off. (&#039;&#039;&#039;Warning&#039;&#039;&#039;: due to some caching, a change in tmdisplay may not be effective immediately in the studio, even after forcing a reload of gameoptions.inc.php.)&lt;br /&gt;
** &#039;&#039;&#039;nobeginner&#039;&#039;&#039; - Set to true if not recommended for begginers&lt;br /&gt;
** &#039;&#039;&#039;firstgameonly&#039;&#039;&#039; - Set to true if this option is recommended only for the first game (discovery option)&lt;br /&gt;
** &#039;&#039;&#039;beta&#039;&#039;&#039; - Option in beta stage on development&lt;br /&gt;
** &#039;&#039;&#039;premium&#039;&#039;&#039; - Option can be only used by premium members&lt;br /&gt;
* &#039;&#039;&#039;default&#039;&#039;&#039; - indicates the default value to use for this option (optional, if not present the first value listed is the default)&lt;br /&gt;
* &#039;&#039;&#039;displaycondition&#039;&#039;&#039; - checks the conditions before displaying the option for selection. All conditions must be true for the option to display. Supported condition types:&lt;br /&gt;
** &#039;&#039;minplayers&#039;&#039; condition ensures at least this many players&lt;br /&gt;
** &#039;&#039;maxplayers&#039;&#039; conditions ensure at most this many players&lt;br /&gt;
** &#039;&#039;otheroption&#039;&#039; condition ensures another option is set to this given values. &lt;br /&gt;
** &#039;&#039;otheroptionisnot&#039;&#039; conditions ensure another option is NOT set to this given values&lt;br /&gt;
* &#039;&#039;&#039;displayconditionoperand&#039;&#039;&#039; - can be &#039;and&#039; (this is the default) or &#039;or&#039;. Allows to change the behaviour to display the option if one of the conditions is true instead of all of them.&lt;br /&gt;
* &#039;&#039;&#039;startcondition&#039;&#039;&#039; - checks the conditions (on options VALUES) before starting the game. All conditions must be true for the game to start, otherwise players will get a red error message when attempting to begin the game. Supported condition types:&lt;br /&gt;
** &#039;&#039;minplayers&#039;&#039; condition ensures at least this many players&lt;br /&gt;
** &#039;&#039;maxplayers&#039;&#039; conditions ensure at most this many players&lt;br /&gt;
** &#039;&#039;otheroption&#039;&#039; conditions ensure another option is set to this given values. That works the same as in &#039;&#039;&#039;displaycondition&#039;&#039;&#039;.&lt;br /&gt;
** &#039;&#039;otheroptionisnot&#039;&#039; conditions ensure another option is NOT set to this given value.  That works the same as in &#039;&#039;&#039;displaycondition&#039;&#039;&#039;.&lt;br /&gt;
* &#039;&#039;&#039;notdisplayedmessage&#039;&#039;&#039; - if option is not suppose to be visible because of displaycondition but this is set, the text will be visible instead of combo drop down&lt;br /&gt;
&lt;br /&gt;
Common options for all tables (reserved range 200-299):&lt;br /&gt;
*201 (const GAMESTATE_RATING_MODE) - ELO OFF (aka Training mode), &lt;br /&gt;
*200 (const GAMESTATE_CLOCK_MODE) - game speed profile, array(0,1,2) - realtime, values 11-21 - turn based&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 $game_options = array(&lt;br /&gt;
     100 =&amp;gt; array(&lt;br /&gt;
         &#039;name&#039; =&amp;gt; totranslate(&#039;my game option&#039;),&lt;br /&gt;
         &#039;values&#039; =&amp;gt; array(&lt;br /&gt;
             // A simple value for this option:&lt;br /&gt;
             1 =&amp;gt; array(&lt;br /&gt;
                 &#039;name&#039; =&amp;gt; totranslate(&#039;option 1&#039;)&lt;br /&gt;
             ),&lt;br /&gt;
&lt;br /&gt;
             // A simple value for this option.&lt;br /&gt;
             // If this value is chosen, the value of &amp;quot;tmdisplay&amp;quot; is displayed in the game lobby&lt;br /&gt;
             2 =&amp;gt; array(&lt;br /&gt;
                 &#039;name&#039; =&amp;gt; totranslate(&#039;option 2&#039;),&lt;br /&gt;
                 &#039;tmdisplay&#039; =&amp;gt; totranslate(&#039;option 2&#039;)&lt;br /&gt;
             ),&lt;br /&gt;
&lt;br /&gt;
             // Another value, with other options:&lt;br /&gt;
             //  beta=true =&amp;gt; this option is in beta version right now.&lt;br /&gt;
             //  nobeginner=true  =&amp;gt;  this option is not recommended for beginners&lt;br /&gt;
             3 =&amp;gt; array(&lt;br /&gt;
                 &#039;name&#039; =&amp;gt; totranslate(&#039;option 3&#039;),&lt;br /&gt;
                 &#039;beta&#039; =&amp;gt; true,&lt;br /&gt;
                 &#039;nobeginner&#039; =&amp;gt; true&lt;br /&gt;
             ),&lt;br /&gt;
         ),&lt;br /&gt;
         &#039;default&#039; =&amp;gt; 1&lt;br /&gt;
     ),&lt;br /&gt;
     &lt;br /&gt;
     101 =&amp;gt; array(&lt;br /&gt;
         &#039;name&#039; =&amp;gt; totranslate(&#039;Draft variant&#039;),&lt;br /&gt;
         &#039;values&#039; =&amp;gt; array(&lt;br /&gt;
             1 =&amp;gt; array(&lt;br /&gt;
                 &#039;name&#039; =&amp;gt; totranslate(&#039;No draft&#039;)&lt;br /&gt;
             ),&lt;br /&gt;
             2 =&amp;gt; array(&lt;br /&gt;
                 &#039;name&#039; =&amp;gt; totranslate(&#039;Draft&#039;),&lt;br /&gt;
                 &#039;tmdisplay&#039; =&amp;gt; totranslate(&#039;Draft&#039;),&lt;br /&gt;
                 &#039;premium&#039; =&amp;gt; true,&lt;br /&gt;
                 &#039;nobeginner&#039; =&amp;gt; true&lt;br /&gt;
             ),&lt;br /&gt;
         ),&lt;br /&gt;
         &#039;displaycondition&#039; =&amp;gt; array( &lt;br /&gt;
             // Note: do not display this option unless these conditions are met&lt;br /&gt;
             array(&lt;br /&gt;
                 &#039;type&#039; =&amp;gt; &#039;otheroption&#039;,&lt;br /&gt;
                 &#039;id&#039; =&amp;gt; 100, // Game specific option defined in the same array above&lt;br /&gt;
                 &#039;value&#039; =&amp;gt; array(2, 3, 4)&lt;br /&gt;
             ),&lt;br /&gt;
             // Note: do not display this option unless these conditions are met&lt;br /&gt;
            array( &#039;type&#039; =&amp;gt; &#039;otheroption&#039;, &lt;br /&gt;
                 &#039;id&#039; =&amp;gt; 201, // ELO OFF hardcoded framework option&lt;br /&gt;
                 &#039;value&#039; =&amp;gt; 1 // 1 if OFF&lt;br /&gt;
            )&lt;br /&gt;
         ),&lt;br /&gt;
&lt;br /&gt;
         &#039;startcondition&#039; =&amp;gt; array(&lt;br /&gt;
             1 =&amp;gt; array(),&lt;br /&gt;
             2 =&amp;gt; array(&lt;br /&gt;
                 array(&lt;br /&gt;
                     &#039;type&#039; =&amp;gt; &#039;maxplayers&#039;,&lt;br /&gt;
                     &#039;value&#039; =&amp;gt; 3,&lt;br /&gt;
                     &#039;message&#039; =&amp;gt; totranslate(&#039;Draft option is available for 3 players maximum.&#039;)&lt;br /&gt;
                 )&lt;br /&gt;
             ),&lt;br /&gt;
         ),&lt;br /&gt;
     ),&lt;br /&gt;
     &lt;br /&gt;
     102 =&amp;gt; array(&lt;br /&gt;
         &#039;name&#039; =&amp;gt; totranslate(&#039;Takeovers&#039;),&lt;br /&gt;
         &#039;values&#039; =&amp;gt; array(&lt;br /&gt;
             2 =&amp;gt; array(&lt;br /&gt;
                 &#039;name&#039; =&amp;gt; totranslate(&#039;No takeover&#039;)&lt;br /&gt;
             ),&lt;br /&gt;
             1 =&amp;gt; array(&lt;br /&gt;
                 &#039;name&#039; =&amp;gt; totranslate(&#039;Allow takeovers&#039;),&lt;br /&gt;
                 &#039;tmdisplay&#039; =&amp;gt; totranslate(&#039;Takeovers&#039;),&lt;br /&gt;
                 &#039;premium&#039; =&amp;gt; true,&lt;br /&gt;
                 &#039;nobeginner&#039; =&amp;gt; true&lt;br /&gt;
             ),&lt;br /&gt;
         ),&lt;br /&gt;
         &#039;displaycondition&#039; =&amp;gt; array( // Note: do not display this option unless these conditions are met&lt;br /&gt;
             array(&lt;br /&gt;
                 &#039;type&#039; =&amp;gt; &#039;otheroption&#039;,&lt;br /&gt;
                 &#039;id&#039; =&amp;gt; 100,&lt;br /&gt;
                 &#039;value&#039; =&amp;gt; array(3, 4)&lt;br /&gt;
             )&lt;br /&gt;
         ),&lt;br /&gt;
         &#039;startcondition&#039; =&amp;gt; array(&lt;br /&gt;
             2 =&amp;gt; array(),&lt;br /&gt;
             1 =&amp;gt; array(&lt;br /&gt;
                 array(&lt;br /&gt;
                     &#039;type&#039; =&amp;gt; &#039;maxplayers&#039;,&lt;br /&gt;
                     &#039;value&#039; =&amp;gt; 2,&lt;br /&gt;
                     &#039;message&#039; =&amp;gt; totranslate(&#039;Rebel vs Imperium Takeover Scenario is available for 2 players only.&#039;)&lt;br /&gt;
                 )&lt;br /&gt;
             ),&lt;br /&gt;
         ),&lt;br /&gt;
     )&lt;br /&gt;
 );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example of option that condition on ELO off&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$game_options = array(&lt;br /&gt;
&lt;br /&gt;
        100 =&amp;gt; array(&lt;br /&gt;
                &#039;name&#039; =&amp;gt; totranslate(&#039;Learning Game (No Research)&#039;),&lt;br /&gt;
                &#039;values&#039; =&amp;gt; array(&lt;br /&gt;
                        &lt;br /&gt;
                        1 =&amp;gt; array( &#039;name&#039; =&amp;gt; totranslate(&#039;Off&#039;), &#039;tmdisplay&#039; =&amp;gt; totranslate(&#039;&#039;) ),&lt;br /&gt;
                        2 =&amp;gt; array( &#039;name&#039; =&amp;gt; totranslate(&#039;On&#039;), &#039;tmdisplay&#039; =&amp;gt; totranslate(&#039;Learning Game&#039;) ),&lt;br /&gt;
                        &lt;br /&gt;
                ),&lt;br /&gt;
                &#039;displaycondition&#039; =&amp;gt; array(&lt;br /&gt;
                        // Note: do not display this option unless these conditions are met&lt;br /&gt;
                        array( &#039;type&#039; =&amp;gt; &#039;otheroption&#039;,&lt;br /&gt;
                                &#039;id&#039; =&amp;gt; 201, // ELO OFF hardcoded framework option&lt;br /&gt;
                                &#039;value&#039; =&amp;gt; 1, // 1 if OFF&lt;br /&gt;
&lt;br /&gt;
                        )&lt;br /&gt;
                ),&lt;br /&gt;
                &#039;notdisplayedmessage&#039; =&amp;gt; totranslate(&#039;Learning variant available only with ELO off&#039;)&lt;br /&gt;
                ),&lt;br /&gt;
&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example of condition that is only available for REALTIME game mode&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&#039;displaycondition&#039; =&amp;gt; array(&lt;br /&gt;
    // Note: do not display this option until these conditions are met - game speed is selected as realtime&lt;br /&gt;
    array( &#039;type&#039; =&amp;gt; &#039;otheroption&#039;, &#039;id&#039; =&amp;gt; GAMESTATE_CLOCK_MODE, &#039;value&#039; =&amp;gt; array(0,1,2) )&lt;br /&gt;
),&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example of using condition on your own option&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        102 =&amp;gt; array(&lt;br /&gt;
                &#039;name&#039; =&amp;gt; totranslate(&#039;Scenarios&#039;),&lt;br /&gt;
                &#039;values&#039; =&amp;gt; array(&lt;br /&gt;
                        1 =&amp;gt; array( &#039;name&#039; =&amp;gt; totranslate(&#039;Off&#039;),&lt;br /&gt;
                                &#039;nobeginner&#039; =&amp;gt; false  ),&lt;br /&gt;
                        2 =&amp;gt; array( &#039;name&#039; =&amp;gt; totranslate(&#039;On&#039;), &#039;tmdisplay&#039; =&amp;gt; totranslate(&#039;Scenarios&#039;),&lt;br /&gt;
                                &#039;nobeginner&#039; =&amp;gt; true  ),&lt;br /&gt;
                        &lt;br /&gt;
                ),&lt;br /&gt;
                &#039;displaycondition&#039; =&amp;gt; array(&lt;br /&gt;
                        // Note: do not display this option unless these conditions are met&lt;br /&gt;
                        array( &#039;type&#039; =&amp;gt; &#039;otheroptionisnot&#039;,&lt;br /&gt;
                                &#039;id&#039; =&amp;gt; 100, // learning variant&lt;br /&gt;
                                &#039;value&#039; =&amp;gt; 2, // 1 if OFF,2 is ON&lt;br /&gt;
                                &lt;br /&gt;
                        )&lt;br /&gt;
                ),&lt;br /&gt;
                &#039;notdisplayedmessage&#039; =&amp;gt; totranslate(&#039;Scenarios variant is not available if Learning variant is chosen&#039;)&lt;br /&gt;
        ),&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== User Preferences ==&lt;br /&gt;
&lt;br /&gt;
User preferences is something cosmetic about the game interface which however can create user wars, so you can satisfy all users&lt;br /&gt;
by giving them individual preferences. You should use this only if it significantly improves the interface for a large proportion of users.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$game_preferences = array(&lt;br /&gt;
    100 =&amp;gt; array(&lt;br /&gt;
        &#039;name&#039; =&amp;gt; totranslate(&#039;Notation style&#039;),&lt;br /&gt;
        &#039;needReload&#039; =&amp;gt; true, // after user changes this preference game interface would auto-reload&lt;br /&gt;
        &#039;values&#039; =&amp;gt; array(&lt;br /&gt;
            1 =&amp;gt; array( &#039;name&#039; =&amp;gt; totranslate( &#039;Classic&#039; ), &#039;cssPref&#039; =&amp;gt; &#039;notation_classic&#039; ),&lt;br /&gt;
            2 =&amp;gt; array( &#039;name&#039; =&amp;gt; totranslate( &#039;Tournament&#039; ), &#039;cssPref&#039; =&amp;gt; &#039;notation_tournament&#039; )&lt;br /&gt;
        ),&lt;br /&gt;
        &#039;default&#039; =&amp;gt; 2&lt;br /&gt;
    )&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There is two ways to check/apply this. In java Script&lt;br /&gt;
&lt;br /&gt;
  if (this.prefs[100].value == 2) ...&lt;br /&gt;
&lt;br /&gt;
This checks if preferences 100 has selected value 2.&lt;br /&gt;
&lt;br /&gt;
Second, if cssPref specified it will be applied to the &#039;&#039;&#039;&amp;lt;html&amp;gt;&#039;&#039;&#039; tag. So you can use different css styling for the preference. Note: it seems needed to set needReload to true for that class change to be effective.&lt;br /&gt;
&lt;br /&gt;
As user you have to select them from the Gear menu when game is started. On studio only user0 will have it actually working (bug?).&lt;br /&gt;
&lt;br /&gt;
The following are the parameters of preferences description array:&lt;br /&gt;
* &#039;&#039;&#039;name&#039;&#039;&#039; - &#039;&#039;&#039;mandatory&#039;&#039;&#039;. The name of the preference. Value will be automatically wrapped in totranslate if you don&#039;t.&lt;br /&gt;
* &#039;&#039;&#039;needReload&#039;&#039;&#039; - If set to true, the game interface will auto-reload after a change of the preference.&lt;br /&gt;
* &#039;&#039;&#039;values&#039;&#039;&#039; - &#039;&#039;&#039;mandatory&#039;&#039;&#039;. The array (map) of values with additional parameters per value.&lt;br /&gt;
** &#039;&#039;&#039;name&#039;&#039;&#039; - &#039;&#039;&#039;mandatory&#039;&#039;&#039;. String representation of the numeric value. Value will be automatically wrapped in totranslate if you don&#039;t.&lt;br /&gt;
** &#039;&#039;&#039;cssPref&#039;&#039;&#039; - CSS class to add to the &#039;&#039;&#039;&amp;lt;html&amp;gt;&#039;&#039;&#039; tag. Currently it is added or removed only after a reload (see needReload).&lt;br /&gt;
* &#039;&#039;&#039;default&#039;&#039;&#039; - Indicates the default value to use for this preference (optional, if not present the first value listed is the default).&lt;br /&gt;
&lt;br /&gt;
=== Listening for preference changes ===&lt;br /&gt;
&lt;br /&gt;
The BGA framework lacks any callback to notify your game when a user preference is changed (see [https://studio.boardgamearena.com/bug?id=36 proposal #36]), but you can create your own if you need to run some UI code in response to a preference change.&lt;br /&gt;
&lt;br /&gt;
; In ggg.js&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    setup: function (gamedatas) {&lt;br /&gt;
      ... // your setup code here&lt;br /&gt;
      this.setupPreference();&lt;br /&gt;
    },&lt;br /&gt;
    &lt;br /&gt;
    setupPreference: function () {&lt;br /&gt;
      // Extract the ID and value from the UI control&lt;br /&gt;
      var _this = this;&lt;br /&gt;
      function onchange(e) {&lt;br /&gt;
        var match = e.target.id.match(/^preference_[cf]ontrol_(\d+)$/);&lt;br /&gt;
        if (!match) {&lt;br /&gt;
          return;&lt;br /&gt;
        }&lt;br /&gt;
        var prefId = +match[1];&lt;br /&gt;
        var prefValue = +e.target.value;&lt;br /&gt;
        _this.prefs[prefId].value = prefValue;&lt;br /&gt;
        _this.onPreferenceChange(prefId, prefValue);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      // Call onPreferenceChange() when any value changes&lt;br /&gt;
      dojo.query(&amp;quot;.preference_control&amp;quot;).connect(&amp;quot;onchange&amp;quot;, onchange);&lt;br /&gt;
      &lt;br /&gt;
      // Call onPreferenceChange() now&lt;br /&gt;
      dojo.forEach(&lt;br /&gt;
        dojo.query(&amp;quot;#ingame_menu_content .preference_control&amp;quot;),&lt;br /&gt;
        function (el) {&lt;br /&gt;
          onchange({ target: el });&lt;br /&gt;
        }&lt;br /&gt;
      );&lt;br /&gt;
    },&lt;br /&gt;
    &lt;br /&gt;
    onPreferenceChange: function (prefId, prefValue) {&lt;br /&gt;
      console.log(&amp;quot;Preference changed&amp;quot;, prefId, prefValue);&lt;br /&gt;
      ... // your code here to handle the change&lt;br /&gt;
    },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Updating preference from code ===&lt;br /&gt;
The BGA framework lacks any method to update a user preference from the code (see [https://studio.boardgamearena.com/bug?id=36 proposal #36]), but you can create your own if you need to.&lt;br /&gt;
&lt;br /&gt;
; In ggg.js&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    updatePreference: function(prefId, newValue) {&lt;br /&gt;
        // Select preference value in control:&lt;br /&gt;
        dojo.query(&#039;#preference_control_&#039; + prefId + &#039; &amp;gt; option[value=&amp;quot;&#039; + newValue&lt;br /&gt;
        // Also select fontrol to fix a BGA framework bug:&lt;br /&gt;
            + &#039;&amp;quot;], #preference_fontrol_&#039; + prefId + &#039; &amp;gt; option[value=&amp;quot;&#039; + newValue&lt;br /&gt;
            + &#039;&amp;quot;]&#039;).forEach((value) =&amp;gt; dojo.attr(value, &#039;selected&#039;, true));&lt;br /&gt;
        // Generate change event on control to trigger callbacks:&lt;br /&gt;
        const newEvt = document.createEvent(&#039;HTMLEvents&#039;);&lt;br /&gt;
        newEvt.initEvent(&#039;change&#039;, false, true);&lt;br /&gt;
        $(&#039;preference_control_&#039; + prefId).dispatchEvent(newEvt);&lt;br /&gt;
    },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>R3z3nd3</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Options_and_preferences:_gameoptions.json,_gamepreferences.json&amp;diff=8543</id>
		<title>Options and preferences: gameoptions.json, gamepreferences.json</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Options_and_preferences:_gameoptions.json,_gamepreferences.json&amp;diff=8543"/>
		<updated>2021-06-19T17:57:47Z</updated>

		<summary type="html">&lt;p&gt;R3z3nd3: Improving grammar&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Studio_Framework_Navigation}}&lt;br /&gt;
&lt;br /&gt;
In this file, you can define your game options (i.e. game variants) and user preferences.&lt;br /&gt;
   &lt;br /&gt;
Note: If your game has no variants or preferences, you don&#039;t have to modify this file.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;IMPORTANT:&#039;&#039;&#039; after you edited this file and syncronized to ftp folder you have to go to the control panel and press &amp;quot;Reload game options configuration&amp;quot; for your changes &#039;&#039;&#039;to take effect&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Make sure you understand difference bettween options and preferences:&lt;br /&gt;
* Game options - something usually in the rule book defined as &amp;quot;variant&amp;quot; (except for 2,3,X people - that is automatically handled - you can query it)&lt;br /&gt;
* Game preferences - personal choice of player only visible to this specific player - i.e. layout, either or not prompt for action, ether or not auto-opt in in some actions, etc&lt;br /&gt;
&lt;br /&gt;
== Game Options ==&lt;br /&gt;
&lt;br /&gt;
Game options is something selected by table creator and usually correspond to game variant, for example if game includes expansion or certain special rule.&lt;br /&gt;
&lt;br /&gt;
These variants defined in gameoptions.inc.php as variable  &lt;br /&gt;
  $game_options = array(...); // exactly named that&lt;br /&gt;
&lt;br /&gt;
Each option is pair number =&amp;gt; &#039;option description array&#039;. &lt;br /&gt;
&lt;br /&gt;
All options defined in this file should have a corresponding &amp;quot;game state label&amp;quot; with the same ID (see &amp;quot;initGameStateLabels&amp;quot; in yourgame.game.php)&lt;br /&gt;
&lt;br /&gt;
             self::initGameStateLabels ( array (&lt;br /&gt;
                        ...&lt;br /&gt;
                        &amp;quot;my_game_variant&amp;quot; =&amp;gt; 100,&lt;br /&gt;
              ) );&lt;br /&gt;
&lt;br /&gt;
Number have to be exactly from 100 to 199 (there can be gaps).&lt;br /&gt;
&lt;br /&gt;
That is how you access them during runtime:&lt;br /&gt;
&lt;br /&gt;
    public function isSecondVariant() {&lt;br /&gt;
        return $this-&amp;gt;getGameStateValue(&#039;my_game_variant&#039;) == 2;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
Or this&lt;br /&gt;
    $this-&amp;gt;gamestate-&amp;gt;table_globals[100]&lt;br /&gt;
&lt;br /&gt;
The following are the parameters of option description array:&lt;br /&gt;
* &#039;&#039;&#039;name&#039;&#039;&#039; - &#039;&#039;&#039;mandatory&#039;&#039;&#039;. The name of the option visible for table creator. Value must be wrapped in totranslate function.&lt;br /&gt;
* &#039;&#039;&#039;values&#039;&#039;&#039; - &#039;&#039;&#039;mandatory&#039;&#039;&#039;. The array (map) of values with additional parameters per value.&lt;br /&gt;
** &#039;&#039;&#039;name&#039;&#039;&#039; - &#039;&#039;&#039;mandatory&#039;&#039;&#039;. String representation of the numeric value visible to table creator. Value must be wrapped in totranslate function.&lt;br /&gt;
** &#039;&#039;&#039;description&#039;&#039;&#039; - String description of this value to use when the name of the option is not self-explanatory. Displayed at the table under the option when this value is selected.&lt;br /&gt;
** &#039;&#039;&#039;tmdisplay&#039;&#039;&#039; - String representation of the option visible in the table description, usually if variant &amp;quot;names&amp;quot; are On and Off, but the description would be same as option name when On, and nothing when Off. (&#039;&#039;&#039;Warning&#039;&#039;&#039;: due to some caching, a change in tmdisplay may not be effective immediately in the studio, even after forcing a reload of gameoptions.inc.php.)&lt;br /&gt;
** &#039;&#039;&#039;nobeginner&#039;&#039;&#039; - Set to true if not recommended for begginers&lt;br /&gt;
** &#039;&#039;&#039;firstgameonly&#039;&#039;&#039; - Set to true if this option is recommended only for the first game (discovery option)&lt;br /&gt;
** &#039;&#039;&#039;beta&#039;&#039;&#039; - Option in beta stage on development&lt;br /&gt;
** &#039;&#039;&#039;premium&#039;&#039;&#039; - Option can be only used by premium members&lt;br /&gt;
* &#039;&#039;&#039;default&#039;&#039;&#039; - indicates the default value to use for this option (optional, if not present the first value listed is the default)&lt;br /&gt;
* &#039;&#039;&#039;displaycondition&#039;&#039;&#039; - checks the conditions before displaying the option for selection. All conditions must be true for the option to display. Supported condition types:&lt;br /&gt;
** &#039;&#039;minplayers&#039;&#039; condition ensures at least this many players&lt;br /&gt;
** &#039;&#039;maxplayers&#039;&#039; conditions ensure at most this many players&lt;br /&gt;
** &#039;&#039;otheroption&#039;&#039; condition ensures another option is set to this given values. &lt;br /&gt;
** &#039;&#039;otheroptionisnot&#039;&#039; conditions ensure another option is NOT set to this given values&lt;br /&gt;
* &#039;&#039;&#039;displayconditionoperand&#039;&#039;&#039; - can be &#039;and&#039; (this is the default) or &#039;or&#039;. Allows to change the behaviour to display the option if one of the conditions is true instead of all of them.&lt;br /&gt;
* &#039;&#039;&#039;startcondition&#039;&#039;&#039; - checks the conditions (on options VALUES) before starting the game. All conditions must be true for the game to start, otherwise players will get a red error message when attempting to begin the game. Supported condition types:&lt;br /&gt;
** &#039;&#039;minplayers&#039;&#039; condition ensures at least this many players&lt;br /&gt;
** &#039;&#039;maxplayers&#039;&#039; conditions ensure at most this many players&lt;br /&gt;
** &#039;&#039;otheroption&#039;&#039; conditions ensure another option is set to this given values. That works the same as in &#039;&#039;&#039;displaycondition&#039;&#039;&#039;.&lt;br /&gt;
** &#039;&#039;otheroptionisnot&#039;&#039; conditions ensure another option is NOT set to this given value.  That works the same as in &#039;&#039;&#039;displaycondition&#039;&#039;&#039;.&lt;br /&gt;
* &#039;&#039;&#039;notdisplayedmessage&#039;&#039;&#039; - if option is not suppose to be visible because of displaycondition but this is set, the text will be visible instead of combo drop down&lt;br /&gt;
&lt;br /&gt;
Common options for all tables (reserved range 200-299):&lt;br /&gt;
*201 (const GAMESTATE_RATING_MODE) - ELO OFF (aka Training mode), &lt;br /&gt;
*200 (const GAMESTATE_CLOCK_MODE) - game speed profile, array(0,1,2) - realtime, values 11-21 - turn based&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 $game_options = array(&lt;br /&gt;
     100 =&amp;gt; array(&lt;br /&gt;
         &#039;name&#039; =&amp;gt; totranslate(&#039;my game option&#039;),&lt;br /&gt;
         &#039;values&#039; =&amp;gt; array(&lt;br /&gt;
             // A simple value for this option:&lt;br /&gt;
             1 =&amp;gt; array(&lt;br /&gt;
                 &#039;name&#039; =&amp;gt; totranslate(&#039;option 1&#039;)&lt;br /&gt;
             ),&lt;br /&gt;
&lt;br /&gt;
             // A simple value for this option.&lt;br /&gt;
             // If this value is chosen, the value of &amp;quot;tmdisplay&amp;quot; is displayed in the game lobby&lt;br /&gt;
             2 =&amp;gt; array(&lt;br /&gt;
                 &#039;name&#039; =&amp;gt; totranslate(&#039;option 2&#039;),&lt;br /&gt;
                 &#039;tmdisplay&#039; =&amp;gt; totranslate(&#039;option 2&#039;)&lt;br /&gt;
             ),&lt;br /&gt;
&lt;br /&gt;
             // Another value, with other options:&lt;br /&gt;
             //  beta=true =&amp;gt; this option is in beta version right now.&lt;br /&gt;
             //  nobeginner=true  =&amp;gt;  this option is not recommended for beginners&lt;br /&gt;
             3 =&amp;gt; array(&lt;br /&gt;
                 &#039;name&#039; =&amp;gt; totranslate(&#039;option 3&#039;),&lt;br /&gt;
                 &#039;beta&#039; =&amp;gt; true,&lt;br /&gt;
                 &#039;nobeginner&#039; =&amp;gt; true&lt;br /&gt;
             ),&lt;br /&gt;
         ),&lt;br /&gt;
         &#039;default&#039; =&amp;gt; 1&lt;br /&gt;
     ),&lt;br /&gt;
     &lt;br /&gt;
     101 =&amp;gt; array(&lt;br /&gt;
         &#039;name&#039; =&amp;gt; totranslate(&#039;Draft variant&#039;),&lt;br /&gt;
         &#039;values&#039; =&amp;gt; array(&lt;br /&gt;
             1 =&amp;gt; array(&lt;br /&gt;
                 &#039;name&#039; =&amp;gt; totranslate(&#039;No draft&#039;)&lt;br /&gt;
             ),&lt;br /&gt;
             2 =&amp;gt; array(&lt;br /&gt;
                 &#039;name&#039; =&amp;gt; totranslate(&#039;Draft&#039;),&lt;br /&gt;
                 &#039;tmdisplay&#039; =&amp;gt; totranslate(&#039;Draft&#039;),&lt;br /&gt;
                 &#039;premium&#039; =&amp;gt; true,&lt;br /&gt;
                 &#039;nobeginner&#039; =&amp;gt; true&lt;br /&gt;
             ),&lt;br /&gt;
         ),&lt;br /&gt;
         &#039;displaycondition&#039; =&amp;gt; array( &lt;br /&gt;
             // Note: do not display this option unless these conditions are met&lt;br /&gt;
             array(&lt;br /&gt;
                 &#039;type&#039; =&amp;gt; &#039;otheroption&#039;,&lt;br /&gt;
                 &#039;id&#039; =&amp;gt; 100, // Game specific option defined in the same array above&lt;br /&gt;
                 &#039;value&#039; =&amp;gt; array(2, 3, 4)&lt;br /&gt;
             ),&lt;br /&gt;
             // Note: do not display this option unless these conditions are met&lt;br /&gt;
            array( &#039;type&#039; =&amp;gt; &#039;otheroption&#039;, &lt;br /&gt;
                 &#039;id&#039; =&amp;gt; 201, // ELO OFF hardcoded framework option&lt;br /&gt;
                 &#039;value&#039; =&amp;gt; 1 // 1 if OFF&lt;br /&gt;
            )&lt;br /&gt;
         ),&lt;br /&gt;
&lt;br /&gt;
         &#039;startcondition&#039; =&amp;gt; array(&lt;br /&gt;
             1 =&amp;gt; array(),&lt;br /&gt;
             2 =&amp;gt; array(&lt;br /&gt;
                 array(&lt;br /&gt;
                     &#039;type&#039; =&amp;gt; &#039;maxplayers&#039;,&lt;br /&gt;
                     &#039;value&#039; =&amp;gt; 3,&lt;br /&gt;
                     &#039;message&#039; =&amp;gt; totranslate(&#039;Draft option is available for 3 players maximum.&#039;)&lt;br /&gt;
                 )&lt;br /&gt;
             ),&lt;br /&gt;
         ),&lt;br /&gt;
     ),&lt;br /&gt;
     &lt;br /&gt;
     102 =&amp;gt; array(&lt;br /&gt;
         &#039;name&#039; =&amp;gt; totranslate(&#039;Takeovers&#039;),&lt;br /&gt;
         &#039;values&#039; =&amp;gt; array(&lt;br /&gt;
             2 =&amp;gt; array(&lt;br /&gt;
                 &#039;name&#039; =&amp;gt; totranslate(&#039;No takeover&#039;)&lt;br /&gt;
             ),&lt;br /&gt;
             1 =&amp;gt; array(&lt;br /&gt;
                 &#039;name&#039; =&amp;gt; totranslate(&#039;Allow takeovers&#039;),&lt;br /&gt;
                 &#039;tmdisplay&#039; =&amp;gt; totranslate(&#039;Takeovers&#039;),&lt;br /&gt;
                 &#039;premium&#039; =&amp;gt; true,&lt;br /&gt;
                 &#039;nobeginner&#039; =&amp;gt; true&lt;br /&gt;
             ),&lt;br /&gt;
         ),&lt;br /&gt;
         &#039;displaycondition&#039; =&amp;gt; array( // Note: do not display this option unless these conditions are met&lt;br /&gt;
             array(&lt;br /&gt;
                 &#039;type&#039; =&amp;gt; &#039;otheroption&#039;,&lt;br /&gt;
                 &#039;id&#039; =&amp;gt; 100,&lt;br /&gt;
                 &#039;value&#039; =&amp;gt; array(3, 4)&lt;br /&gt;
             )&lt;br /&gt;
         ),&lt;br /&gt;
         &#039;startcondition&#039; =&amp;gt; array(&lt;br /&gt;
             2 =&amp;gt; array(),&lt;br /&gt;
             1 =&amp;gt; array(&lt;br /&gt;
                 array(&lt;br /&gt;
                     &#039;type&#039; =&amp;gt; &#039;maxplayers&#039;,&lt;br /&gt;
                     &#039;value&#039; =&amp;gt; 2,&lt;br /&gt;
                     &#039;message&#039; =&amp;gt; totranslate(&#039;Rebel vs Imperium Takeover Scenario is available for 2 players only.&#039;)&lt;br /&gt;
                 )&lt;br /&gt;
             ),&lt;br /&gt;
         ),&lt;br /&gt;
     )&lt;br /&gt;
 );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example of option that condition on ELO off&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$game_options = array(&lt;br /&gt;
&lt;br /&gt;
        100 =&amp;gt; array(&lt;br /&gt;
                &#039;name&#039; =&amp;gt; totranslate(&#039;Learning Game (No Research)&#039;),&lt;br /&gt;
                &#039;values&#039; =&amp;gt; array(&lt;br /&gt;
                        &lt;br /&gt;
                        1 =&amp;gt; array( &#039;name&#039; =&amp;gt; totranslate(&#039;Off&#039;), &#039;tmdisplay&#039; =&amp;gt; totranslate(&#039;&#039;) ),&lt;br /&gt;
                        2 =&amp;gt; array( &#039;name&#039; =&amp;gt; totranslate(&#039;On&#039;), &#039;tmdisplay&#039; =&amp;gt; totranslate(&#039;Learning Game&#039;) ),&lt;br /&gt;
                        &lt;br /&gt;
                ),&lt;br /&gt;
                &#039;displaycondition&#039; =&amp;gt; array(&lt;br /&gt;
                        // Note: do not display this option unless these conditions are met&lt;br /&gt;
                        array( &#039;type&#039; =&amp;gt; &#039;otheroption&#039;,&lt;br /&gt;
                                &#039;id&#039; =&amp;gt; 201, // ELO OFF hardcoded framework option&lt;br /&gt;
                                &#039;value&#039; =&amp;gt; 1, // 1 if OFF&lt;br /&gt;
&lt;br /&gt;
                        )&lt;br /&gt;
                ),&lt;br /&gt;
                &#039;notdisplayedmessage&#039; =&amp;gt; totranslate(&#039;Learning variant available only with ELO off&#039;)&lt;br /&gt;
                ),&lt;br /&gt;
&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example of condition that is only available for REALTIME game mode&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&#039;displaycondition&#039; =&amp;gt; array(&lt;br /&gt;
    // Note: do not display this option until these conditions are met - game speed is selected as realtime&lt;br /&gt;
    array( &#039;type&#039; =&amp;gt; &#039;otheroption&#039;, &#039;id&#039; =&amp;gt; GAMESTATE_CLOCK_MODE, &#039;value&#039; =&amp;gt; array(0,1,2) )&lt;br /&gt;
),&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example of using condition on your own option&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        102 =&amp;gt; array(&lt;br /&gt;
                &#039;name&#039; =&amp;gt; totranslate(&#039;Scenarios&#039;),&lt;br /&gt;
                &#039;values&#039; =&amp;gt; array(&lt;br /&gt;
                        1 =&amp;gt; array( &#039;name&#039; =&amp;gt; totranslate(&#039;Off&#039;),&lt;br /&gt;
                                &#039;nobeginner&#039; =&amp;gt; false  ),&lt;br /&gt;
                        2 =&amp;gt; array( &#039;name&#039; =&amp;gt; totranslate(&#039;On&#039;), &#039;tmdisplay&#039; =&amp;gt; totranslate(&#039;Scenarios&#039;),&lt;br /&gt;
                                &#039;nobeginner&#039; =&amp;gt; true  ),&lt;br /&gt;
                        &lt;br /&gt;
                ),&lt;br /&gt;
                &#039;displaycondition&#039; =&amp;gt; array(&lt;br /&gt;
                        // Note: do not display this option unless these conditions are met&lt;br /&gt;
                        array( &#039;type&#039; =&amp;gt; &#039;otheroptionisnot&#039;,&lt;br /&gt;
                                &#039;id&#039; =&amp;gt; 100, // learning variant&lt;br /&gt;
                                &#039;value&#039; =&amp;gt; 2, // 1 if OFF,2 is ON&lt;br /&gt;
                                &lt;br /&gt;
                        )&lt;br /&gt;
                ),&lt;br /&gt;
                &#039;notdisplayedmessage&#039; =&amp;gt; totranslate(&#039;Scenarios variant is not available if Learning variant is chosen&#039;)&lt;br /&gt;
        ),&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== User Preferences ==&lt;br /&gt;
&lt;br /&gt;
User preferences is something cosmetic about the game interface which however can create user wars, so you can satisfy all users&lt;br /&gt;
by giving them individual preferences. You should use this only if it significantly improves the interface for a large proportion of users.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$game_preferences = array(&lt;br /&gt;
    100 =&amp;gt; array(&lt;br /&gt;
        &#039;name&#039; =&amp;gt; totranslate(&#039;Notation style&#039;),&lt;br /&gt;
        &#039;needReload&#039; =&amp;gt; true, // after user changes this preference game interface would auto-reload&lt;br /&gt;
        &#039;values&#039; =&amp;gt; array(&lt;br /&gt;
            1 =&amp;gt; array( &#039;name&#039; =&amp;gt; totranslate( &#039;Classic&#039; ), &#039;cssPref&#039; =&amp;gt; &#039;notation_classic&#039; ),&lt;br /&gt;
            2 =&amp;gt; array( &#039;name&#039; =&amp;gt; totranslate( &#039;Tournament&#039; ), &#039;cssPref&#039; =&amp;gt; &#039;notation_tournament&#039; )&lt;br /&gt;
        ),&lt;br /&gt;
        &#039;default&#039; =&amp;gt; 2&lt;br /&gt;
    )&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There is two ways to check/apply this. In java Script&lt;br /&gt;
&lt;br /&gt;
  if (this.prefs[100].value == 2) ...&lt;br /&gt;
&lt;br /&gt;
This checks if preferences 100 has selected value 2.&lt;br /&gt;
&lt;br /&gt;
Second, if cssPref specified it will be applied to the &#039;&#039;&#039;&amp;lt;html&amp;gt;&#039;&#039;&#039; tag. So you can use different css styling for the preference. Note: it seems needed to set needReload to true for that class change to be effective.&lt;br /&gt;
&lt;br /&gt;
As user you have to select them from the Gear menu when game is started. On studio only user0 will have it actually working (bug?).&lt;br /&gt;
&lt;br /&gt;
The following are the parameters of preferences description array:&lt;br /&gt;
* &#039;&#039;&#039;name&#039;&#039;&#039; - &#039;&#039;&#039;mandatory&#039;&#039;&#039;. The name of the preference. Value will be automatically wrapped in totranslate if you don&#039;t.&lt;br /&gt;
* &#039;&#039;&#039;needReload&#039;&#039;&#039; - If set to true, the game interface will auto-reload after a change of the preference.&lt;br /&gt;
* &#039;&#039;&#039;values&#039;&#039;&#039; - &#039;&#039;&#039;mandatory&#039;&#039;&#039;. The array (map) of values with additional parameters per value.&lt;br /&gt;
** &#039;&#039;&#039;name&#039;&#039;&#039; - &#039;&#039;&#039;mandatory&#039;&#039;&#039;. String representation of the numeric value. Value will be automatically wrapped in totranslate if you don&#039;t.&lt;br /&gt;
** &#039;&#039;&#039;cssPref&#039;&#039;&#039; - CSS class to add to the &#039;&#039;&#039;&amp;lt;html&amp;gt;&#039;&#039;&#039; tag. Currently it is added or removed only after a reload (see needReload).&lt;br /&gt;
* &#039;&#039;&#039;default&#039;&#039;&#039; - Indicates the default value to use for this preference (optional, if not present the first value listed is the default).&lt;br /&gt;
&lt;br /&gt;
=== Listening for preference changes ===&lt;br /&gt;
&lt;br /&gt;
The BGA framework lacks any callback to notify your game when a user preference is changed (see [https://studio.boardgamearena.com/bug?id=36 proposal #36]), but you can create your own if you need to run some UI code in response to a preference change.&lt;br /&gt;
&lt;br /&gt;
; In ggg.js&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    setup: function (gamedatas) {&lt;br /&gt;
      ... // your setup code here&lt;br /&gt;
      this.setupPreference();&lt;br /&gt;
    },&lt;br /&gt;
    &lt;br /&gt;
    setupPreference: function () {&lt;br /&gt;
      // Extract the ID and value from the UI control&lt;br /&gt;
      var _this = this;&lt;br /&gt;
      function onchange(e) {&lt;br /&gt;
        var match = e.target.id.match(/^preference_[cf]ontrol_(\d+)$/);&lt;br /&gt;
        if (!match) {&lt;br /&gt;
          return;&lt;br /&gt;
        }&lt;br /&gt;
        var prefId = +match[1];&lt;br /&gt;
        var prefValue = +e.target.value;&lt;br /&gt;
        _this.prefs[prefId].value = prefValue;&lt;br /&gt;
        _this.onPreferenceChange(prefId, prefValue);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      // Call onPreferenceChange() when any value changes&lt;br /&gt;
      dojo.query(&amp;quot;.preference_control&amp;quot;).connect(&amp;quot;onchange&amp;quot;, onchange);&lt;br /&gt;
      &lt;br /&gt;
      // Call onPreferenceChange() now&lt;br /&gt;
      dojo.forEach(&lt;br /&gt;
        dojo.query(&amp;quot;#ingame_menu_content .preference_control&amp;quot;),&lt;br /&gt;
        function (el) {&lt;br /&gt;
          onchange({ target: el });&lt;br /&gt;
        }&lt;br /&gt;
      );&lt;br /&gt;
    },&lt;br /&gt;
    &lt;br /&gt;
    onPreferenceChange: function (prefId, prefValue) {&lt;br /&gt;
      console.log(&amp;quot;Preference changed&amp;quot;, prefId, prefValue);&lt;br /&gt;
      ... // your code here to handle the change&lt;br /&gt;
    },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Updating preference from code ===&lt;br /&gt;
The BGA framework lacks any method to update a user preference from the code (see [https://studio.boardgamearena.com/bug?id=36 proposal #36]), but you can create your own if you need to.&lt;br /&gt;
&lt;br /&gt;
; In ggg.js&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    updatePreference: function(prefId, newValue) {&lt;br /&gt;
        // Select preference value in control:&lt;br /&gt;
        dojo.query(&#039;#preference_control_&#039; + prefId + &#039; &amp;gt; option[value=&amp;quot;&#039; + newValue&lt;br /&gt;
        // Also select fontrol to fix a BGA framework bug:&lt;br /&gt;
            + &#039;&amp;quot;], #preference_fontrol_&#039; + prefId + &#039; &amp;gt; option[value=&amp;quot;&#039; + newValue&lt;br /&gt;
            + &#039;&amp;quot;]&#039;).forEach((value) =&amp;gt; dojo.attr(value, &#039;selected&#039;, true));&lt;br /&gt;
        // Generate change event on control to trigger callbacks:&lt;br /&gt;
        const newEvt = document.createEvent(&#039;HTMLEvents&#039;);&lt;br /&gt;
        newEvt.initEvent(&#039;change&#039;, false, true);&lt;br /&gt;
        $(&#039;preference_control_&#039; + prefId).dispatchEvent(newEvt);&lt;br /&gt;
    },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>R3z3nd3</name></author>
	</entry>
</feed>