<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="sr">
	<id>https://sr.doc.boardgamearena.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Een</id>
	<title>Board Game Arena - Кориснички доприноси [sr]</title>
	<link rel="self" type="application/atom+xml" href="https://sr.doc.boardgamearena.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Een"/>
	<link rel="alternate" type="text/html" href="https://sr.doc.boardgamearena.com/%D0%9F%D0%BE%D1%81%D0%B5%D0%B1%D0%BD%D0%BE:%D0%94%D0%BE%D0%BF%D1%80%D0%B8%D0%BD%D0%BE%D1%81%D0%B8/Een"/>
	<updated>2026-10-21T19:54:45Z</updated>
	<subtitle>Кориснички доприноси</subtitle>
	<generator>MediaWiki 1.39.0</generator>
	<entry>
		<id>https://sr.doc.boardgamearena.com/index.php?title=Game_options_and_preferences:_gameoptions.inc.php&amp;diff=3198</id>
		<title>Game options and preferences: gameoptions.inc.php</title>
		<link rel="alternate" type="text/html" href="https://sr.doc.boardgamearena.com/index.php?title=Game_options_and_preferences:_gameoptions.inc.php&amp;diff=3198"/>
		<updated>2018-09-24T08:41:22Z</updated>

		<summary type="html">&lt;p&gt;Een: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
In this file, you can define your game options (= 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 in your SFTP folder you have to go to the control panel and press &amp;quot;Reload game options configuration&amp;quot; for your changes to take effect.&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_first_game_variant&amp;quot; =&amp;gt; 100,&lt;br /&gt;
              ) );&lt;br /&gt;
&lt;br /&gt;
That is how you access them during runtime:&lt;br /&gt;
&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;mandartory&#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;mandartory&#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;mandartory&#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;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.&lt;br /&gt;
** &#039;&#039;&#039;nobeginner&#039;&#039;&#039; - Set to true if not recommended for begginers&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;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;otheroption&#039;&#039; condition ensures another option is set to this given value. Framework options - 201 - ELO OFF.&lt;br /&gt;
* &#039;&#039;&#039;startcondition&#039;&#039;&#039; - checks the conditions 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 value. 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&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;
&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;
     ),&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;
         &#039;disable&#039; =&amp;gt; true&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;
         &#039;disable&#039; =&amp;gt; true&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 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;
	)&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 body tag. So you can use different css styling for the preference.&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;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://sr.doc.boardgamearena.com/index.php?title=Game_options_and_preferences:_gameoptions.inc.php&amp;diff=3197</id>
		<title>Game options and preferences: gameoptions.inc.php</title>
		<link rel="alternate" type="text/html" href="https://sr.doc.boardgamearena.com/index.php?title=Game_options_and_preferences:_gameoptions.inc.php&amp;diff=3197"/>
		<updated>2018-09-24T08:39:49Z</updated>

		<summary type="html">&lt;p&gt;Een: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
In this file, you can define your game options (= 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;
IMPORTANT: After you edited and deployed this file you have to go to control panel and press &amp;quot;Reload game options configuration&amp;quot;&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_first_game_variant&amp;quot; =&amp;gt; 100,&lt;br /&gt;
              ) );&lt;br /&gt;
&lt;br /&gt;
That is how you access them during runtime:&lt;br /&gt;
&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;mandartory&#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;mandartory&#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;mandartory&#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;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.&lt;br /&gt;
** &#039;&#039;&#039;nobeginner&#039;&#039;&#039; - Set to true if not recommended for begginers&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;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;otheroption&#039;&#039; condition ensures another option is set to this given value. Framework options - 201 - ELO OFF.&lt;br /&gt;
* &#039;&#039;&#039;startcondition&#039;&#039;&#039; - checks the conditions 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 value. 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&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;
&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;
     ),&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;
         &#039;disable&#039; =&amp;gt; true&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;
         &#039;disable&#039; =&amp;gt; true&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 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;
	)&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 body tag. So you can use different css styling for the preference.&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;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://sr.doc.boardgamearena.com/index.php?title=Game_options_and_preferences:_gameoptions.inc.php&amp;diff=3196</id>
		<title>Game options and preferences: gameoptions.inc.php</title>
		<link rel="alternate" type="text/html" href="https://sr.doc.boardgamearena.com/index.php?title=Game_options_and_preferences:_gameoptions.inc.php&amp;diff=3196"/>
		<updated>2018-09-24T08:39:33Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Game Options */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
In this file, you can define your game options (= 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;
== 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_first_game_variant&amp;quot; =&amp;gt; 100,&lt;br /&gt;
              ) );&lt;br /&gt;
&lt;br /&gt;
That is how you access them during runtime:&lt;br /&gt;
&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;mandartory&#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;mandartory&#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;mandartory&#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;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.&lt;br /&gt;
** &#039;&#039;&#039;nobeginner&#039;&#039;&#039; - Set to true if not recommended for begginers&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;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;otheroption&#039;&#039; condition ensures another option is set to this given value. Framework options - 201 - ELO OFF.&lt;br /&gt;
* &#039;&#039;&#039;startcondition&#039;&#039;&#039; - checks the conditions 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 value. 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&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;
&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;
     ),&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;
         &#039;disable&#039; =&amp;gt; true&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;
         &#039;disable&#039; =&amp;gt; true&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 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;
	)&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 body tag. So you can use different css styling for the preference.&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;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://sr.doc.boardgamearena.com/index.php?title=Game_options_and_preferences:_gameoptions.inc.php&amp;diff=3195</id>
		<title>Game options and preferences: gameoptions.inc.php</title>
		<link rel="alternate" type="text/html" href="https://sr.doc.boardgamearena.com/index.php?title=Game_options_and_preferences:_gameoptions.inc.php&amp;diff=3195"/>
		<updated>2018-09-24T08:37:36Z</updated>

		<summary type="html">&lt;p&gt;Een: /* User Preferences */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
In this file, you can define your game options (= 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;
== 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_first_game_variant&amp;quot; =&amp;gt; 100,&lt;br /&gt;
              ) );&lt;br /&gt;
&lt;br /&gt;
That is how you access them during runtime:&lt;br /&gt;
&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;mandartory&#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;mandartory&#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;mandartory&#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;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.&lt;br /&gt;
** &#039;&#039;&#039;nobeginner&#039;&#039;&#039; - Set to true if not recommended for begginers&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;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;otheroption&#039;&#039; condition ensures another option is set to this given value. Framework options - 201 - ELO OFF.&lt;br /&gt;
* &#039;&#039;&#039;startcondition&#039;&#039;&#039; - checks the conditions 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 value. 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&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;
&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;
     ),&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;
         &#039;disable&#039; =&amp;gt; true&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;
         &#039;disable&#039; =&amp;gt; true&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 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;
IMPORTANT: After you edited and deployed this file you have to go to control panel and press &amp;quot;Reload game options configuration&amp;quot;&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;
	)&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 body tag. So you can use different css styling for the preference.&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;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://sr.doc.boardgamearena.com/index.php?title=Practical_debugging&amp;diff=3120</id>
		<title>Practical debugging</title>
		<link rel="alternate" type="text/html" href="https://sr.doc.boardgamearena.com/index.php?title=Practical_debugging&amp;diff=3120"/>
		<updated>2018-08-02T15:28:05Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Get the database matching a bug report */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This page gives you practical tips to debug your game during the development. Don&#039;t hesitate to share with us your difficulties in order we can improve this section.&lt;br /&gt;
&lt;br /&gt;
== Tools ==&lt;br /&gt;
&lt;br /&gt;
To work on BGA Studio, we recommend you to use [http://www.google.com/chrome Google Chrome] as it&#039;s the current fastest browser for BGA platform, and it&#039;s available in all OS.&lt;br /&gt;
&lt;br /&gt;
Another reason to use Chrome is that it embed all tools you need to work on BGA Studio. You can see them by pressing &amp;quot;F12&amp;quot; or from the menu (&amp;quot;Tools &amp;gt; Development tools&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
A good practice is to use a second browser to develop the game, in order to check that your game is working fine on this browser too.&lt;br /&gt;
&lt;br /&gt;
To debug with Firefox browser, we advise you to use these 2 extensions:&lt;br /&gt;
* [https://addons.mozilla.org/firefox/addon/firebug/ Firebug]&lt;br /&gt;
* [https://addons.mozilla.org/firefox/addon/web-developer/ Web developper]&lt;br /&gt;
&lt;br /&gt;
To debug with other browsers (IE, Edge, Opera), we advise you to use one of the most recent versions. Latest versions of the browser will likely have better development tools than the previous ones...&lt;br /&gt;
&lt;br /&gt;
== General tip for debugging ==&lt;br /&gt;
&lt;br /&gt;
In general for debugging, think of using the &#039;[[Tools_and_tips_of_BGA_Studio#Save_.26_restore_state|save &amp;amp; restore]] state&#039; functionality. It enables you to save the state of your game just before the issue you are investigating, then come back to that point with one click as many times as needed to understand what is going wrong.&lt;br /&gt;
&lt;br /&gt;
You can save up to 3 different states.&lt;br /&gt;
&lt;br /&gt;
== Debugging my game when it cannot start ==&lt;br /&gt;
&lt;br /&gt;
If your game don&#039;t start because of an error, you are probably in one of these situations:&lt;br /&gt;
* There is a SQL error in your dbmodel.sql file.&lt;br /&gt;
* You have a syntax error in your PHP file.&lt;br /&gt;
* Your PHP &amp;quot;setup&amp;quot; - or any method used during the game initial states - generates an exception.&lt;br /&gt;
&lt;br /&gt;
If the error is not explicitly displayed when you click on &amp;quot;Express start&amp;quot;, you should check the &amp;quot;Gameserver error log&amp;quot; as per [[Studio logs]].&lt;br /&gt;
More cases of why game can&#039;t start described in [[Troubleshooting]] page.&lt;br /&gt;
&lt;br /&gt;
== Debugging my PHP game logic (or my view) ==&lt;br /&gt;
&lt;br /&gt;
Most of the time, debugging PHP is quite easy. Here&#039;s what I do when I want to develop/debug some game logic that is triggered by some game action:&lt;br /&gt;
&lt;br /&gt;
* At first, I make sure that I can reproduce the needed game situation in one click. To do this, I use the &amp;quot;[[Tools_and_tips_of_BGA_Studio#Save_.26_restore_state|save &amp;amp; restore]]&amp;quot; function.&lt;br /&gt;
* Another possibility for this is to place a &#039;&#039;&#039;die(&#039;ok&#039;);&#039;&#039;&#039; PHP statement right after the PHP I am developing/debugging. This way, I make sure that every request will fail and then nothing will be commited to the database, anyway.&lt;br /&gt;
* Then, I use &#039;&#039;&#039;var_dump&#039;&#039;&#039; function to dump PHP variables and check what&#039;s wrong, until it works.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// (...my code to debug)&lt;br /&gt;
&lt;br /&gt;
var_dump( $my_variable );&lt;br /&gt;
die(&#039;ok&#039;);&lt;br /&gt;
&lt;br /&gt;
// (...my code to debug)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Add traces to your code ===&lt;br /&gt;
&lt;br /&gt;
You can use the following functions in your game to add server side logging:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;self::dump( &#039;name_of_variable&#039;, $variable );&#039;&#039;&#039;  // dump variable, like var_dump but in the log debug level logging, goes to [[Studio_logs|BGA request&amp;amp;SQL logs]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;self::debug( $message );&#039;&#039;&#039;  // debug level logging, goes to [[Studio_logs|BGA request&amp;amp;SQL logs]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;self::trace( $message );&#039;&#039;&#039;  // info level logging, goes to [[Studio_logs|BGA request&amp;amp;SQL logs]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;self::warn( $message );&#039;&#039;&#039;   // warning level logging, goes to [[Studio_logs#BGA_unexpected_exceptions_logs|BGA unexpected exceptions log]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;self::error( $message );&#039;&#039;&#039;  // error level logging, goes to [[Studio_logs#BGA_unexpected_exceptions_logs|BGA unexpected exceptions log]]&lt;br /&gt;
&lt;br /&gt;
Check [[Studio logs]] for more details on how to access your logs.&lt;br /&gt;
&lt;br /&gt;
This can be useful when you need to follow the flow of your code and not just stop it to see how it goes at some point.&lt;br /&gt;
&lt;br /&gt;
Only the error log level will appear in production. This level should be used only for critical problems. &lt;br /&gt;
Other levels will show only in the development environment and can be used as you see fit.&lt;br /&gt;
&lt;br /&gt;
== Debugging my HTML/CSS layout ==&lt;br /&gt;
&lt;br /&gt;
Situation examples:&lt;br /&gt;
* why my game element doesn&#039;t show up in the interface?&lt;br /&gt;
* why my CSS property hasn&#039;t been applied to this element?&lt;br /&gt;
* why this game element is displayed at this position?&lt;br /&gt;
&lt;br /&gt;
A first useful tip when an element does not show up in the interface is to give it a red background:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#my_element {&lt;br /&gt;
  ... some CSS definitions ...&lt;br /&gt;
  background-color: red;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This way, you know if the element is not visible because of some of its CSS property or because of anything else.&lt;br /&gt;
&lt;br /&gt;
Another tip: sometimes, you change a CSS property with no visible effect on your interface. In that case, add a &amp;quot;display:none&amp;quot; property. If your element does not disappear, the bug probably comes from your CSS selector and not from your CSS property.&lt;br /&gt;
&lt;br /&gt;
Using Chrome &amp;quot;Elements&amp;quot; tab (thre first one), you can:&lt;br /&gt;
* See the CURRENT HTML of your page. Remember that the classical &amp;quot;show page source&amp;quot; is inefficient with BGA as you are modifying the page source with your Javascript code.&lt;br /&gt;
* Using the &amp;quot;magnifying glass&amp;quot;, you can click on any part of your game interface and check it&#039;s HTML code and associated CSS styles.&lt;br /&gt;
* You can even modify directly some CSS property and see if how it looks immediately on the game interface.&lt;br /&gt;
&lt;br /&gt;
== Debugging my Javascript game interface logic ==&lt;br /&gt;
&lt;br /&gt;
Compare to PHP debugging, Javascript debugging can sometimes be painful.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s are some tips to make your life easier while developing and debugging Javascript:&lt;br /&gt;
&lt;br /&gt;
=== Do complex things on PHP side ===&lt;br /&gt;
&lt;br /&gt;
The most frequent case is the following: you want to compute possible moves in a game situation. Doing it in Javascript is a nightmare. Then, do it on PHP, and transfer the result to your client interface using the &amp;quot;args&amp;quot; game state property.&lt;br /&gt;
&lt;br /&gt;
Note: check Reversi example for this.&lt;br /&gt;
&lt;br /&gt;
=== Add traces in your code ===&lt;br /&gt;
&lt;br /&gt;
You can use the following:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;console.log( variable_to_inspect )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
It will give you the object structure of the variable in the Javascript console, without blocking the execution.&lt;br /&gt;
&lt;br /&gt;
It&#039;s often a good idea to precede this call with a console.log( &#039;### HERE ###&#039; ); to find more easily the appropriate line in the console log.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;alert( variable_to_inspect )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
It will popup what you wish and pause the execution until you click ok.&lt;br /&gt;
&lt;br /&gt;
This won&#039;t be useful for complex structures, only native types will get plainly displayed. But this is sometimes useful just with messages to make sure which way the execution goes.&lt;br /&gt;
&lt;br /&gt;
=== Use Debugger ===&lt;br /&gt;
&lt;br /&gt;
Modern browsers also allow to put  breakpoints in your js code. &lt;br /&gt;
&lt;br /&gt;
That will stop code execution on that line and will launch the JavaScript debugger&lt;br /&gt;
&lt;br /&gt;
== Some frequent errors ==&lt;br /&gt;
&lt;br /&gt;
See [[Troubleshooting]].&lt;br /&gt;
&lt;br /&gt;
== Get the database matching a bug report ==&lt;br /&gt;
&lt;br /&gt;
When a player creates a bug report in production, a snapshot of the game database is taken. You can get access to this snapshot from the studio by following the steps below:&lt;br /&gt;
* Create a table on the studio with the same game and number of players as the table for which the report has been written. Launch this table.&lt;br /&gt;
* Open another tab on the studio and go to &amp;quot;Manage game&amp;quot; page for your project (you have to be admin for this project)&lt;br /&gt;
* In the &amp;quot;Errors in production&amp;quot; section, fill up the fields &amp;quot;Bug report ID&amp;quot; (this is the ID of the bug report in production) and &amp;quot;Studio table ID&amp;quot; (this is the ID of the table you created above) then click the &amp;quot;⇨ Load bug report state into this table save slot #1&amp;quot; button.&lt;br /&gt;
* If the snapshot is correctly retrieved, you see a &amp;quot;Done!&amp;quot; message.&lt;br /&gt;
* Go back to the tab with your studio table and click &amp;quot;Load 1&amp;quot;.&lt;br /&gt;
* The page refreshes automatically and is broken. This is normal, as the player ids from the snapshot are the player ids of the production, not those of the studio. We&#039;ll need to update them.&lt;br /&gt;
* Click on the &amp;quot;Go to game database&amp;quot; button&lt;br /&gt;
* For each table using player_ids, you&#039;ll need to update the player_ids from the production to use the player_ids from the studio. You can see the player_ids from the table page before entering the game by hovering over the player names.&lt;br /&gt;
* Tables to update:&lt;br /&gt;
** player&lt;br /&gt;
** global (value with ID 2 is the active player)&lt;br /&gt;
** stats&lt;br /&gt;
** tables specific to your schema that use player_ids&lt;br /&gt;
* If your changes to player_ids are not taken into account, it may be a cache problem: use the &amp;quot;Clear PHP cache&amp;quot; button on your &amp;quot;Manage game&amp;quot; page.&lt;br /&gt;
* Then you should be able to play with the same state of the game as when the report was created in production.&lt;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://sr.doc.boardgamearena.com/index.php?title=Practical_debugging&amp;diff=3119</id>
		<title>Practical debugging</title>
		<link rel="alternate" type="text/html" href="https://sr.doc.boardgamearena.com/index.php?title=Practical_debugging&amp;diff=3119"/>
		<updated>2018-08-02T15:21:43Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Get the database matching a bug report */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This page gives you practical tips to debug your game during the development. Don&#039;t hesitate to share with us your difficulties in order we can improve this section.&lt;br /&gt;
&lt;br /&gt;
== Tools ==&lt;br /&gt;
&lt;br /&gt;
To work on BGA Studio, we recommend you to use [http://www.google.com/chrome Google Chrome] as it&#039;s the current fastest browser for BGA platform, and it&#039;s available in all OS.&lt;br /&gt;
&lt;br /&gt;
Another reason to use Chrome is that it embed all tools you need to work on BGA Studio. You can see them by pressing &amp;quot;F12&amp;quot; or from the menu (&amp;quot;Tools &amp;gt; Development tools&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
A good practice is to use a second browser to develop the game, in order to check that your game is working fine on this browser too.&lt;br /&gt;
&lt;br /&gt;
To debug with Firefox browser, we advise you to use these 2 extensions:&lt;br /&gt;
* [https://addons.mozilla.org/firefox/addon/firebug/ Firebug]&lt;br /&gt;
* [https://addons.mozilla.org/firefox/addon/web-developer/ Web developper]&lt;br /&gt;
&lt;br /&gt;
To debug with other browsers (IE, Edge, Opera), we advise you to use one of the most recent versions. Latest versions of the browser will likely have better development tools than the previous ones...&lt;br /&gt;
&lt;br /&gt;
== General tip for debugging ==&lt;br /&gt;
&lt;br /&gt;
In general for debugging, think of using the &#039;[[Tools_and_tips_of_BGA_Studio#Save_.26_restore_state|save &amp;amp; restore]] state&#039; functionality. It enables you to save the state of your game just before the issue you are investigating, then come back to that point with one click as many times as needed to understand what is going wrong.&lt;br /&gt;
&lt;br /&gt;
You can save up to 3 different states.&lt;br /&gt;
&lt;br /&gt;
== Debugging my game when it cannot start ==&lt;br /&gt;
&lt;br /&gt;
If your game don&#039;t start because of an error, you are probably in one of these situations:&lt;br /&gt;
* There is a SQL error in your dbmodel.sql file.&lt;br /&gt;
* You have a syntax error in your PHP file.&lt;br /&gt;
* Your PHP &amp;quot;setup&amp;quot; - or any method used during the game initial states - generates an exception.&lt;br /&gt;
&lt;br /&gt;
If the error is not explicitly displayed when you click on &amp;quot;Express start&amp;quot;, you should check the &amp;quot;Gameserver error log&amp;quot; as per [[Studio logs]].&lt;br /&gt;
More cases of why game can&#039;t start described in [[Troubleshooting]] page.&lt;br /&gt;
&lt;br /&gt;
== Debugging my PHP game logic (or my view) ==&lt;br /&gt;
&lt;br /&gt;
Most of the time, debugging PHP is quite easy. Here&#039;s what I do when I want to develop/debug some game logic that is triggered by some game action:&lt;br /&gt;
&lt;br /&gt;
* At first, I make sure that I can reproduce the needed game situation in one click. To do this, I use the &amp;quot;[[Tools_and_tips_of_BGA_Studio#Save_.26_restore_state|save &amp;amp; restore]]&amp;quot; function.&lt;br /&gt;
* Another possibility for this is to place a &#039;&#039;&#039;die(&#039;ok&#039;);&#039;&#039;&#039; PHP statement right after the PHP I am developing/debugging. This way, I make sure that every request will fail and then nothing will be commited to the database, anyway.&lt;br /&gt;
* Then, I use &#039;&#039;&#039;var_dump&#039;&#039;&#039; function to dump PHP variables and check what&#039;s wrong, until it works.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// (...my code to debug)&lt;br /&gt;
&lt;br /&gt;
var_dump( $my_variable );&lt;br /&gt;
die(&#039;ok&#039;);&lt;br /&gt;
&lt;br /&gt;
// (...my code to debug)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Add traces to your code ===&lt;br /&gt;
&lt;br /&gt;
You can use the following functions in your game to add server side logging:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;self::dump( &#039;name_of_variable&#039;, $variable );&#039;&#039;&#039;  // dump variable, like var_dump but in the log debug level logging, goes to [[Studio_logs|BGA request&amp;amp;SQL logs]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;self::debug( $message );&#039;&#039;&#039;  // debug level logging, goes to [[Studio_logs|BGA request&amp;amp;SQL logs]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;self::trace( $message );&#039;&#039;&#039;  // info level logging, goes to [[Studio_logs|BGA request&amp;amp;SQL logs]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;self::warn( $message );&#039;&#039;&#039;   // warning level logging, goes to [[Studio_logs#BGA_unexpected_exceptions_logs|BGA unexpected exceptions log]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;self::error( $message );&#039;&#039;&#039;  // error level logging, goes to [[Studio_logs#BGA_unexpected_exceptions_logs|BGA unexpected exceptions log]]&lt;br /&gt;
&lt;br /&gt;
Check [[Studio logs]] for more details on how to access your logs.&lt;br /&gt;
&lt;br /&gt;
This can be useful when you need to follow the flow of your code and not just stop it to see how it goes at some point.&lt;br /&gt;
&lt;br /&gt;
Only the error log level will appear in production. This level should be used only for critical problems. &lt;br /&gt;
Other levels will show only in the development environment and can be used as you see fit.&lt;br /&gt;
&lt;br /&gt;
== Debugging my HTML/CSS layout ==&lt;br /&gt;
&lt;br /&gt;
Situation examples:&lt;br /&gt;
* why my game element doesn&#039;t show up in the interface?&lt;br /&gt;
* why my CSS property hasn&#039;t been applied to this element?&lt;br /&gt;
* why this game element is displayed at this position?&lt;br /&gt;
&lt;br /&gt;
A first useful tip when an element does not show up in the interface is to give it a red background:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#my_element {&lt;br /&gt;
  ... some CSS definitions ...&lt;br /&gt;
  background-color: red;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This way, you know if the element is not visible because of some of its CSS property or because of anything else.&lt;br /&gt;
&lt;br /&gt;
Another tip: sometimes, you change a CSS property with no visible effect on your interface. In that case, add a &amp;quot;display:none&amp;quot; property. If your element does not disappear, the bug probably comes from your CSS selector and not from your CSS property.&lt;br /&gt;
&lt;br /&gt;
Using Chrome &amp;quot;Elements&amp;quot; tab (thre first one), you can:&lt;br /&gt;
* See the CURRENT HTML of your page. Remember that the classical &amp;quot;show page source&amp;quot; is inefficient with BGA as you are modifying the page source with your Javascript code.&lt;br /&gt;
* Using the &amp;quot;magnifying glass&amp;quot;, you can click on any part of your game interface and check it&#039;s HTML code and associated CSS styles.&lt;br /&gt;
* You can even modify directly some CSS property and see if how it looks immediately on the game interface.&lt;br /&gt;
&lt;br /&gt;
== Debugging my Javascript game interface logic ==&lt;br /&gt;
&lt;br /&gt;
Compare to PHP debugging, Javascript debugging can sometimes be painful.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s are some tips to make your life easier while developing and debugging Javascript:&lt;br /&gt;
&lt;br /&gt;
=== Do complex things on PHP side ===&lt;br /&gt;
&lt;br /&gt;
The most frequent case is the following: you want to compute possible moves in a game situation. Doing it in Javascript is a nightmare. Then, do it on PHP, and transfer the result to your client interface using the &amp;quot;args&amp;quot; game state property.&lt;br /&gt;
&lt;br /&gt;
Note: check Reversi example for this.&lt;br /&gt;
&lt;br /&gt;
=== Add traces in your code ===&lt;br /&gt;
&lt;br /&gt;
You can use the following:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;console.log( variable_to_inspect )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
It will give you the object structure of the variable in the Javascript console, without blocking the execution.&lt;br /&gt;
&lt;br /&gt;
It&#039;s often a good idea to precede this call with a console.log( &#039;### HERE ###&#039; ); to find more easily the appropriate line in the console log.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;alert( variable_to_inspect )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
It will popup what you wish and pause the execution until you click ok.&lt;br /&gt;
&lt;br /&gt;
This won&#039;t be useful for complex structures, only native types will get plainly displayed. But this is sometimes useful just with messages to make sure which way the execution goes.&lt;br /&gt;
&lt;br /&gt;
=== Use Debugger ===&lt;br /&gt;
&lt;br /&gt;
Modern browsers also allow to put  breakpoints in your js code. &lt;br /&gt;
&lt;br /&gt;
That will stop code execution on that line and will launch the JavaScript debugger&lt;br /&gt;
&lt;br /&gt;
== Some frequent errors ==&lt;br /&gt;
&lt;br /&gt;
See [[Troubleshooting]].&lt;br /&gt;
&lt;br /&gt;
== Get the database matching a bug report ==&lt;br /&gt;
&lt;br /&gt;
When a player creates a bug report in production, a snapshot of the game database is taken. You can get access to this snapshot from the studio by following the steps below:&lt;br /&gt;
* Create a table on the studio with the same game and number of players as the table for which the report has been written. Launch this table.&lt;br /&gt;
* Open another tab on the studio and go to &amp;quot;Manage your project&amp;quot; page for this game (you have to be admin for this project)&lt;br /&gt;
* In the &amp;quot;Errors in production&amp;quot; section, fill up the fields &amp;quot;Bug report ID&amp;quot; (this is the ID of the bug report in production) and &amp;quot;Studio table ID&amp;quot; (this is the ID of the table you created above) then click the &amp;quot;⇨ Load bug report state into this table save slot #1&amp;quot; button.&lt;br /&gt;
* If the snapshot is correctly retrieved, you see a &amp;quot;Done!&amp;quot; message.&lt;br /&gt;
* Go back to the tab with your studio table and click &amp;quot;Load 1&amp;quot;.&lt;br /&gt;
* The page refreshes automatically and is broken. This is normal, as the player ids from the snapshot are the player ids of the production, not those of the studio. We&#039;ll need to update them.&lt;br /&gt;
* Click on the &amp;quot;Go to game database button&amp;quot;&lt;br /&gt;
* For each table using player_ids, you&#039;ll need to update the player_ids from the production to use the player_ids from the studio. You can see the player_ids from the table page before entering the game by hovering over the player names.&lt;br /&gt;
* Tables to update:&lt;br /&gt;
** player&lt;br /&gt;
** global (value with ID 2 is the active player)&lt;br /&gt;
** stats&lt;br /&gt;
** tables specific to your schema that use player_ids&lt;br /&gt;
* Then you should be able to play with the same state of the game as when the report was created in production.&lt;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://sr.doc.boardgamearena.com/index.php?title=Practical_debugging&amp;diff=3118</id>
		<title>Practical debugging</title>
		<link rel="alternate" type="text/html" href="https://sr.doc.boardgamearena.com/index.php?title=Practical_debugging&amp;diff=3118"/>
		<updated>2018-08-02T15:10:27Z</updated>

		<summary type="html">&lt;p&gt;Een: Retrieve database state&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This page gives you practical tips to debug your game during the development. Don&#039;t hesitate to share with us your difficulties in order we can improve this section.&lt;br /&gt;
&lt;br /&gt;
== Tools ==&lt;br /&gt;
&lt;br /&gt;
To work on BGA Studio, we recommend you to use [http://www.google.com/chrome Google Chrome] as it&#039;s the current fastest browser for BGA platform, and it&#039;s available in all OS.&lt;br /&gt;
&lt;br /&gt;
Another reason to use Chrome is that it embed all tools you need to work on BGA Studio. You can see them by pressing &amp;quot;F12&amp;quot; or from the menu (&amp;quot;Tools &amp;gt; Development tools&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
A good practice is to use a second browser to develop the game, in order to check that your game is working fine on this browser too.&lt;br /&gt;
&lt;br /&gt;
To debug with Firefox browser, we advise you to use these 2 extensions:&lt;br /&gt;
* [https://addons.mozilla.org/firefox/addon/firebug/ Firebug]&lt;br /&gt;
* [https://addons.mozilla.org/firefox/addon/web-developer/ Web developper]&lt;br /&gt;
&lt;br /&gt;
To debug with other browsers (IE, Edge, Opera), we advise you to use one of the most recent versions. Latest versions of the browser will likely have better development tools than the previous ones...&lt;br /&gt;
&lt;br /&gt;
== General tip for debugging ==&lt;br /&gt;
&lt;br /&gt;
In general for debugging, think of using the &#039;[[Tools_and_tips_of_BGA_Studio#Save_.26_restore_state|save &amp;amp; restore]] state&#039; functionality. It enables you to save the state of your game just before the issue you are investigating, then come back to that point with one click as many times as needed to understand what is going wrong.&lt;br /&gt;
&lt;br /&gt;
You can save up to 3 different states.&lt;br /&gt;
&lt;br /&gt;
== Debugging my game when it cannot start ==&lt;br /&gt;
&lt;br /&gt;
If your game don&#039;t start because of an error, you are probably in one of these situations:&lt;br /&gt;
* There is a SQL error in your dbmodel.sql file.&lt;br /&gt;
* You have a syntax error in your PHP file.&lt;br /&gt;
* Your PHP &amp;quot;setup&amp;quot; - or any method used during the game initial states - generates an exception.&lt;br /&gt;
&lt;br /&gt;
If the error is not explicitly displayed when you click on &amp;quot;Express start&amp;quot;, you should check the &amp;quot;Gameserver error log&amp;quot; as per [[Studio logs]].&lt;br /&gt;
More cases of why game can&#039;t start described in [[Troubleshooting]] page.&lt;br /&gt;
&lt;br /&gt;
== Debugging my PHP game logic (or my view) ==&lt;br /&gt;
&lt;br /&gt;
Most of the time, debugging PHP is quite easy. Here&#039;s what I do when I want to develop/debug some game logic that is triggered by some game action:&lt;br /&gt;
&lt;br /&gt;
* At first, I make sure that I can reproduce the needed game situation in one click. To do this, I use the &amp;quot;[[Tools_and_tips_of_BGA_Studio#Save_.26_restore_state|save &amp;amp; restore]]&amp;quot; function.&lt;br /&gt;
* Another possibility for this is to place a &#039;&#039;&#039;die(&#039;ok&#039;);&#039;&#039;&#039; PHP statement right after the PHP I am developing/debugging. This way, I make sure that every request will fail and then nothing will be commited to the database, anyway.&lt;br /&gt;
* Then, I use &#039;&#039;&#039;var_dump&#039;&#039;&#039; function to dump PHP variables and check what&#039;s wrong, until it works.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// (...my code to debug)&lt;br /&gt;
&lt;br /&gt;
var_dump( $my_variable );&lt;br /&gt;
die(&#039;ok&#039;);&lt;br /&gt;
&lt;br /&gt;
// (...my code to debug)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Add traces to your code ===&lt;br /&gt;
&lt;br /&gt;
You can use the following functions in your game to add server side logging:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;self::dump( &#039;name_of_variable&#039;, $variable );&#039;&#039;&#039;  // dump variable, like var_dump but in the log debug level logging, goes to [[Studio_logs|BGA request&amp;amp;SQL logs]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;self::debug( $message );&#039;&#039;&#039;  // debug level logging, goes to [[Studio_logs|BGA request&amp;amp;SQL logs]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;self::trace( $message );&#039;&#039;&#039;  // info level logging, goes to [[Studio_logs|BGA request&amp;amp;SQL logs]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;self::warn( $message );&#039;&#039;&#039;   // warning level logging, goes to [[Studio_logs#BGA_unexpected_exceptions_logs|BGA unexpected exceptions log]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;self::error( $message );&#039;&#039;&#039;  // error level logging, goes to [[Studio_logs#BGA_unexpected_exceptions_logs|BGA unexpected exceptions log]]&lt;br /&gt;
&lt;br /&gt;
Check [[Studio logs]] for more details on how to access your logs.&lt;br /&gt;
&lt;br /&gt;
This can be useful when you need to follow the flow of your code and not just stop it to see how it goes at some point.&lt;br /&gt;
&lt;br /&gt;
Only the error log level will appear in production. This level should be used only for critical problems. &lt;br /&gt;
Other levels will show only in the development environment and can be used as you see fit.&lt;br /&gt;
&lt;br /&gt;
== Debugging my HTML/CSS layout ==&lt;br /&gt;
&lt;br /&gt;
Situation examples:&lt;br /&gt;
* why my game element doesn&#039;t show up in the interface?&lt;br /&gt;
* why my CSS property hasn&#039;t been applied to this element?&lt;br /&gt;
* why this game element is displayed at this position?&lt;br /&gt;
&lt;br /&gt;
A first useful tip when an element does not show up in the interface is to give it a red background:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#my_element {&lt;br /&gt;
  ... some CSS definitions ...&lt;br /&gt;
  background-color: red;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This way, you know if the element is not visible because of some of its CSS property or because of anything else.&lt;br /&gt;
&lt;br /&gt;
Another tip: sometimes, you change a CSS property with no visible effect on your interface. In that case, add a &amp;quot;display:none&amp;quot; property. If your element does not disappear, the bug probably comes from your CSS selector and not from your CSS property.&lt;br /&gt;
&lt;br /&gt;
Using Chrome &amp;quot;Elements&amp;quot; tab (thre first one), you can:&lt;br /&gt;
* See the CURRENT HTML of your page. Remember that the classical &amp;quot;show page source&amp;quot; is inefficient with BGA as you are modifying the page source with your Javascript code.&lt;br /&gt;
* Using the &amp;quot;magnifying glass&amp;quot;, you can click on any part of your game interface and check it&#039;s HTML code and associated CSS styles.&lt;br /&gt;
* You can even modify directly some CSS property and see if how it looks immediately on the game interface.&lt;br /&gt;
&lt;br /&gt;
== Debugging my Javascript game interface logic ==&lt;br /&gt;
&lt;br /&gt;
Compare to PHP debugging, Javascript debugging can sometimes be painful.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s are some tips to make your life easier while developing and debugging Javascript:&lt;br /&gt;
&lt;br /&gt;
=== Do complex things on PHP side ===&lt;br /&gt;
&lt;br /&gt;
The most frequent case is the following: you want to compute possible moves in a game situation. Doing it in Javascript is a nightmare. Then, do it on PHP, and transfer the result to your client interface using the &amp;quot;args&amp;quot; game state property.&lt;br /&gt;
&lt;br /&gt;
Note: check Reversi example for this.&lt;br /&gt;
&lt;br /&gt;
=== Add traces in your code ===&lt;br /&gt;
&lt;br /&gt;
You can use the following:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;console.log( variable_to_inspect )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
It will give you the object structure of the variable in the Javascript console, without blocking the execution.&lt;br /&gt;
&lt;br /&gt;
It&#039;s often a good idea to precede this call with a console.log( &#039;### HERE ###&#039; ); to find more easily the appropriate line in the console log.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;alert( variable_to_inspect )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
It will popup what you wish and pause the execution until you click ok.&lt;br /&gt;
&lt;br /&gt;
This won&#039;t be useful for complex structures, only native types will get plainly displayed. But this is sometimes useful just with messages to make sure which way the execution goes.&lt;br /&gt;
&lt;br /&gt;
=== Use Debugger ===&lt;br /&gt;
&lt;br /&gt;
Modern browsers also allow to put  breakpoints in your js code. &lt;br /&gt;
&lt;br /&gt;
That will stop code execution on that line and will launch the JavaScript debugger&lt;br /&gt;
&lt;br /&gt;
== Some frequent errors ==&lt;br /&gt;
&lt;br /&gt;
See [[Troubleshooting]].&lt;br /&gt;
&lt;br /&gt;
== Get the database matching a bug report ==&lt;br /&gt;
&lt;br /&gt;
When a player creates a bug report in production, a snapshot of the game database is taken. You can get access to this snapshot from the studio by following the steps below:&lt;br /&gt;
* Create a table on the studio with the same game and number of players as the table for which the report has been written. Launch this table.&lt;br /&gt;
* Open another tab on the studio and go to &amp;quot;Manage your project&amp;quot; page for this game (you have to be admin for this project)&lt;br /&gt;
* In the &amp;quot;Errors in production&amp;quot; section, fill up the fields &amp;quot;Bug report ID&amp;quot; (this is the ID of the bug report in production) and &amp;quot;Studio table ID&amp;quot; (this is the ID of the table you created above) then click the &amp;quot;⇨ Load bug report state into this table save slot #1&amp;quot; button.&lt;br /&gt;
* If the snapshot is correctly retrieved, you see a &amp;quot;Done!&amp;quot; message.&lt;br /&gt;
* Go back to the tab with your studio table and click &amp;quot;Load 1&amp;quot;.&lt;br /&gt;
* The page refreshes automatically and is broken. This is normal, as the player ids from the snapshot are the player ids of the production, not those of the studio. We&#039;ll need to update them.&lt;br /&gt;
* Click on the &amp;quot;Go to game database button&amp;quot;&lt;br /&gt;
* For each table using player_ids, you&#039;ll need to update the player_ids from the production to use the player_ids from the studio. You can see the player_ids from the studio by hovering over the red arrow in the player panels.&lt;br /&gt;
* Tables to update:&lt;br /&gt;
** player&lt;br /&gt;
** global (value with ID 2 is the active player)&lt;br /&gt;
** stats&lt;br /&gt;
** tables specific to your schema that use player_ids&lt;br /&gt;
* Then you should be able to play with the same state of the game as when the report was created in production.&lt;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://sr.doc.boardgamearena.com/index.php?title=Game_interface_logic:_yourgamename.js&amp;diff=3083</id>
		<title>Game interface logic: yourgamename.js</title>
		<link rel="alternate" type="text/html" href="https://sr.doc.boardgamearena.com/index.php?title=Game_interface_logic:_yourgamename.js&amp;diff=3083"/>
		<updated>2018-05-26T09:12:48Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Dojo framework */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This is the main file for your game interface. Here you will define:&lt;br /&gt;
&lt;br /&gt;
* which actions on the page will generate calls to the server&lt;br /&gt;
* what happens when you get a notification for change from the server and how it will show in the browser. &lt;br /&gt;
&lt;br /&gt;
== File structure ==&lt;br /&gt;
&lt;br /&gt;
The details on how the file is structured is described directly with comments on the code skeleton provided to you.&lt;br /&gt;
&lt;br /&gt;
Basically, here&#039;s this structure:&lt;br /&gt;
* constructor: here you can define variable global to your whole interface.&lt;br /&gt;
* setup: this method is called when the page is refreshed, in order you can setup the game interface.&lt;br /&gt;
* onEnteringState: the method is called when entering in a new game state. This way you can customize the view for this game state.&lt;br /&gt;
* onLeavingState: the method is called when leaving a game state.&lt;br /&gt;
* onUpdateActionButtons: called when entering in a new state, in order you can add action buttons in status bar.&lt;br /&gt;
* (utility methods): at this place you can define your utility methods&lt;br /&gt;
* (player&#039;s actions): at this place you can write your handlers for player&#039;s action on the interface (ex: click on an item).&lt;br /&gt;
* setupNotifications: in this method you associate notifications with notification handlers. This way, for each game notification, you trigger a javascript method to handle it and update the game interface.&lt;br /&gt;
* (notification handlers): at this place you can define your notifications handlers.&lt;br /&gt;
&lt;br /&gt;
== General tips ==&lt;br /&gt;
&lt;br /&gt;
; this.player_id&lt;br /&gt;
: Id of the player on whose browser the code is running.&lt;br /&gt;
&lt;br /&gt;
; this.isSpectator&lt;br /&gt;
: Flag set to true if the user at the table is a spectator (not a player).&lt;br /&gt;
: Note: this is not a function, its a variable.&lt;br /&gt;
: Note: if you want to hide some element for spectators, you&#039;d better use [[Game_interface_stylesheet:_yourgamename.css#spectatorMode|CSS &#039;spectatorMode&#039; class]].&lt;br /&gt;
&lt;br /&gt;
; this.gamedatas&lt;br /&gt;
: Contains your initial set of datas to init the game, created at game start or game refresh (F5)&lt;br /&gt;
: You can update it as needed to keep an up to date reference of the game on the client side if you need it (most of the time you don&#039;t).&lt;br /&gt;
&lt;br /&gt;
; this.isCurrentPlayerActive()&lt;br /&gt;
: Returns true if the player on whose browser the code is running is currently active (it&#039;s his turn to play)&lt;br /&gt;
&lt;br /&gt;
; this.getActivePlayerId()&lt;br /&gt;
: Return the ID of active player, or null if we are not in a &amp;quot;activeplayer&amp;quot; type state.&lt;br /&gt;
&lt;br /&gt;
; this.getActivePlayers()&lt;br /&gt;
: Return an array with the IDs of players that are currently active (or an empty array if there is not).&lt;br /&gt;
&lt;br /&gt;
== Dojo framework ==&lt;br /&gt;
&lt;br /&gt;
BGA is using the [http://dojotoolkit.org/ Dojo Javascript framework].&lt;br /&gt;
&lt;br /&gt;
The Dojo framework allows us to do complex things easier, and the BGA framework is using Dojo framework a lot.&lt;br /&gt;
&lt;br /&gt;
To realize game although, you only need to use a few part of the Dojo framework. All the Dojo methods you need to use are describe on this page.&lt;br /&gt;
&lt;br /&gt;
== Shrinksafe minification ==&lt;br /&gt;
&lt;br /&gt;
For performance reasons, when deploying a game the js code is minified using Shrinksafe (based on ECMASCRIPT version 3). Some advanced syntax may not be compatible with this process. In particular:&lt;br /&gt;
* you should not use reserved keywords from the javascript language as variables&lt;br /&gt;
* you should not declare default argument values in function declaration, the following syntax is invalid for Shriksafe: function myFunc(requiredArg, optionalArg = &#039;defaultValue&#039;) {}&lt;br /&gt;
&lt;br /&gt;
== Access and manipulate the DOM ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;$(&#039;some_html_element_id&#039;)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The $() function is used to get some HTML element using its &amp;quot;id&amp;quot; attribute.&lt;br /&gt;
&lt;br /&gt;
Example 1: modify the content of a &amp;quot;span&amp;quot; element:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
In your HTML code:&lt;br /&gt;
   &amp;lt;span id=&amp;quot;a_value_in_the_game_interface&amp;quot;&amp;gt;1234&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In your Javascript code:&lt;br /&gt;
   $(&#039;a_value_in_the_game_interface&#039;).innerHTML = &amp;quot;9999&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: $() is the standard method to access some HTML element with BGA Framework. You must not use &amp;quot;getElementById&amp;quot; function.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;dojo.style&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
With dojo.style you can modify a CSS property of any HTML element of your interface.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     // Make an element disappear&lt;br /&gt;
     dojo.style( &#039;my_element&#039;, &#039;display&#039;, &#039;none&#039; );&lt;br /&gt;
&lt;br /&gt;
     // Give an element a 2px border&lt;br /&gt;
     dojo.style( &#039;my_element&#039;, &#039;borderWidth&#039;, &#039;2px&#039; );&lt;br /&gt;
&lt;br /&gt;
     // Change the background position of an element&lt;br /&gt;
     // (very practical when you are using CSS sprite to transform an element to another)&lt;br /&gt;
     dojo.style( &#039;my_element&#039;, &#039;backgroundPosition&#039;, &#039;-20px -50px&#039; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: you must always use dojo.style to modify CSS properties of HTML elements.&lt;br /&gt;
&lt;br /&gt;
Note²: if you have to modify several CSS properties of an element, or if you have some complex CSS transformation to do, you should consider using dojo.addClass/dojo.removeClass (see below).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;dojo CSS classes manipulation&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In many situation, a bunch of many small CSS property update can be replaced by a CSS class change (ie: you add a CSS class to your element instead of applying all modification manually).&lt;br /&gt;
&lt;br /&gt;
Advantages are:&lt;br /&gt;
* All your CSS stuff remains in your CSS file.&lt;br /&gt;
* You can add/remove a list of CSS modifications with a simple function and whithout error.&lt;br /&gt;
* You can test if you applied the stuff to an element with &amp;quot;dojo.hasClass&amp;quot; method.&lt;br /&gt;
&lt;br /&gt;
Example from &amp;quot;Reversi&amp;quot;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    // We add &amp;quot;possibleMove&amp;quot; to an element&lt;br /&gt;
    dojo.addClass( &#039;square_&#039;+x+&#039;_&#039;+y, &#039;possibleMove&#039; );&lt;br /&gt;
&lt;br /&gt;
    // In our CSS file, the class is defined as:&lt;br /&gt;
    .possibleMove {&lt;br /&gt;
      background-color: white;&lt;br /&gt;
      opacity: 0.2;&lt;br /&gt;
      filter:alpha(opacity=20); /* For IE8 and earlier */  &lt;br /&gt;
      cursor: pointer;  &lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
     // So we&#039;ve applied 4 CSS property change in one line of code.&lt;br /&gt;
&lt;br /&gt;
     // ... and when we need to check if a square is a possible move on client side:&lt;br /&gt;
     if( dojo.hasClass( &#039;square_&#039;+x+&#039;_&#039;+y, &#039;possibleMove&#039; ) )&lt;br /&gt;
     { ... }&lt;br /&gt;
&lt;br /&gt;
     // ... and if we want to remove all possible moves in one line of code (see &amp;quot;dojo.query&amp;quot; method):&lt;br /&gt;
     dojo.query( &#039;.possibleMove&#039; ).removeClass( &#039;possibleMove&#039; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Conclusion: we encourage you to use dojo.addClass, dojo.removeClass and dojo.hasClass to make your life easier :)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;dojo.query&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
With dojo.query, you can query a bunch of HTML elements with a single function, with a &amp;quot;CSS selector&amp;quot; style.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     // All elements with class &amp;quot;possibleMove&amp;quot;:&lt;br /&gt;
     var elements = dojo.query( &#039;.possibleMove&#039; );&lt;br /&gt;
&lt;br /&gt;
     // Count number of tokens (ie: elements with class &amp;quot;token&amp;quot;) on the board (ie: element with id &amp;quot;board&amp;quot;):&lt;br /&gt;
     dojo.query( &#039;#board .token&#039; ).length;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
But what is really cool with dojo.query is that you can combine it with almost all methods above.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     // Trigger a method when the mouse enter in any element with class &amp;quot;meeple&amp;quot;:&lt;br /&gt;
     dojo.query( &#039;.meeple&#039; ).connect( &#039;onmouseenter&#039;, this, &#039;myMethodToTrigger&#039; );&lt;br /&gt;
&lt;br /&gt;
     // Hide all meeples who are on the board&lt;br /&gt;
     dojo.query( &#039;#board .meeple&#039; ).style( &#039;display&#039;, &#039;none&#039; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;dojo.place&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
dojo.place is the best function to insert some HTML code somewhere in your game interface without breaking something. It is much better to use that &amp;quot;innerHTML=&#039;&#039;&amp;quot; method as soon as you must insert HTML tags and not only values.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     // Insert your HTML code as a child of a container element&lt;br /&gt;
     dojo.place( &amp;quot;&amp;lt;your html code&amp;gt;&amp;quot;, &amp;quot;your_container_element_id&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
     // Replace the container element with your new html&lt;br /&gt;
     dojo.place( &amp;quot;&amp;lt;your html code&amp;gt;&amp;quot;, &amp;quot;your_container_element_id&amp;quot;, &amp;quot;replace&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The third parameter of dojo.place can take various interesting value.&lt;br /&gt;
&lt;br /&gt;
values possibles :&lt;br /&gt;
&lt;br /&gt;
&amp;quot;replace&amp;quot; : (see description above).&lt;br /&gt;
&lt;br /&gt;
&amp;quot;first&amp;quot; : Places the node as a child of the reference node. The node is placed as the first child.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;last&amp;quot; : Places the node as a child of the reference node. The node is placed as the last child.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;before&amp;quot; : places the node right before the reference node.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;last (value by default) &amp;quot; : places the node right after the reference node.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;only&amp;quot; : replaces all children of the reference node with the node.&lt;br /&gt;
&lt;br /&gt;
positif integer : This parameter can be a positif integer. In this case, the node will be placed as a child of the reference node with this number (counting from 0). If the number is more than number of children, the node will be appended to the reference node making it the last child. &lt;br /&gt;
&lt;br /&gt;
See also full doc on dojo.place : [http://dojotoolkit.org/reference-guide/1.7/dojo/place.]&lt;br /&gt;
&lt;br /&gt;
Usually, when you want to insert some piece of HTML in your game interface, you should use &amp;quot;[[Game_layout:_view_and_template:_yourgamename.view.php_and_yourgamename_yourgamename.tpl#Javascript_templates|Javascript templates]]&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;addStyleToClass: function( cssClassName, cssProperty, propertyValue )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Same as dojo.style(), but for all the nodes set with the specified cssClassName&lt;br /&gt;
&lt;br /&gt;
=== Animations ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Dojo Animations&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
BGA animations is based on Dojo Animation ([http://dojotoolkit.org/documentation/tutorials/1.8/animation/ see tutorial here]).&lt;br /&gt;
&lt;br /&gt;
However, most of the time, you can just use methods below, which are built on top of Dojo Animation.&lt;br /&gt;
&lt;br /&gt;
Note: one interesting method from Dojo that could be useful from time to time is &amp;quot;Dojo.Animation&amp;quot;. It allows you to make any CSS property &amp;quot;slide&amp;quot; from one value to another.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.slideToObject( mobile_obj, target_obj, duration, delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You can use slideToObject to &amp;quot;slide&amp;quot; an element to a target position.&lt;br /&gt;
&lt;br /&gt;
Sliding element on the game area is the recommended and the most used way to animate your game interface. Using slides allow players to figure out what is happening on the game, as if they were playing with the real boardgame.&lt;br /&gt;
&lt;br /&gt;
The parameters are:&lt;br /&gt;
* mobile_obj: the ID of the object to move. This object must be &amp;quot;relative&amp;quot; or &amp;quot;absolute&amp;quot; positioned.&lt;br /&gt;
* target_obj: the ID of the target object. This object must be &amp;quot;relative&amp;quot; or &amp;quot;absolute&amp;quot; positioned. Note that it is not mandatory that mobile_obj and target_obj have the same size. If their size are different, the system slides the center of mobile_obj to the center of target_obj.&lt;br /&gt;
* duration: (optional) defines the duration in millisecond of the slide. The default is 500 milliseconds.&lt;br /&gt;
* delay: (optional). If you defines a delay, the slide will start only after this delay. This is particularly useful when you want to slide several object from the same position to the same position: you can give a 0ms delay to the first object, a 100ms delay to the second one, a 200ms delay to the third one, ... this way they won&#039;t be superposed during the slide.&lt;br /&gt;
&lt;br /&gt;
BE CAREFUL: The method returns an dojo.fx animation, so you can combine it with other animation if you want to. It means that you have to call the &amp;quot;play()&amp;quot; method, otherwise the animation WON&#039;T START.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   this.slideToObject( &amp;quot;some_token&amp;quot;, &amp;quot;some_place_on_board&amp;quot; ).play();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.slideToObjectPos( mobile_obj, target_obj, target_x, target_y, duration, delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This method does exactly the same as &amp;quot;slideToObject&amp;quot;, except than you can specify some (x,y) coordinates. This way, &amp;quot;mobile_obj&amp;quot; will slide to the specified x,y position relatively to &amp;quot;target_obj&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Example: slide a token to some place on the board, 10 pixels to the bottom:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   this.slideToObjectPos( &amp;quot;some_token&amp;quot;, &amp;quot;some_place_on_board&amp;quot;, 0, 10 ).play();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.slideTemporaryObject( mobile_obj_html, mobile_obj_parent, from, to, duration, delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This method is useful when you want to slide a temporary HTML object from one place to another. As this object does not exists before the animation and won&#039;t remain after, it could be complex to create this object (with dojo.place), to place it at its origin (with placeOnObject) to slide it (with slideToObject) and to make it disappear at the end.&lt;br /&gt;
&lt;br /&gt;
slideTemporaryObject does all of this for you:&lt;br /&gt;
* mobile_obj_html is a piece of HTML code that represent the object to slide.&lt;br /&gt;
* mobile_obj_parent is the ID of an HTML element of your interface that will be the parent of this temporary HTML object.&lt;br /&gt;
* from is the ID of the origin of the slide.&lt;br /&gt;
* to is the ID of the target of the slide.&lt;br /&gt;
* duration/delay works exactly like in &amp;quot;slideToObject&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
this.slideTemporaryObject( &#039;&amp;lt;div class=&amp;quot;token_icon&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;, &#039;tokens&#039;, &#039;my_origin_div&#039;, &#039;my_target_div&#039; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.slideToObjectAndDestroy: function( node, to, time, delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This method is a handy shortcut to slide an existing HTML object to some place then destroy it upon arrival. It can be used for example to move a victory token or a card from the board to the player panel to show that the player earns it, then destroy it when we don&#039;t need to keep it visible on the player panel.&lt;br /&gt;
&lt;br /&gt;
It works the same as this.slideToObject and takes the same arguments. &lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
this.slideToObjectAndDestroy( &amp;quot;some_token&amp;quot;, &amp;quot;some_place_on_board&amp;quot;, 1000, 0 );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.fadeOutAndDestroy( node, duration, delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This function fade out the target HTML node, then destroy it.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   this.fadeOutAndDestroy( &amp;quot;a_card_that_must_disappear&amp;quot; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
CAREFUL: the HTML node still exists until during few milliseconds, until the fadeOut has been completed.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Rotating elements&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You can check here [http://jimfulton.info/demos/dojo-animated-rotate.html an example of use] of Dojo to make an element rotate.&lt;br /&gt;
&lt;br /&gt;
This example combines &amp;quot;Dojo.Animation&amp;quot; method and a CSS3 property that allow you to rotate the element.&lt;br /&gt;
&lt;br /&gt;
IMPORTANT: to asses browser compatibility, you must select the CSS property to use just like in the example (see sourcecode below):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        var transform;&lt;br /&gt;
        dojo.forEach(&lt;br /&gt;
            [&#039;transform&#039;, &#039;WebkitTransform&#039;, &#039;msTransform&#039;,&lt;br /&gt;
             &#039;MozTransform&#039;, &#039;OTransform&#039;],&lt;br /&gt;
            function (name) {&lt;br /&gt;
                if (typeof dojo.body().style[name] != &#039;undefined&#039;) {&lt;br /&gt;
                    transform = name;&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        // ... and then use &amp;quot;transform&amp;quot; as the name of your CSS property for rotation&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Moving elements ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.placeOnObject( mobile_obj, target_obj )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
placeOnObject works exactly like &amp;quot;slideToObject&amp;quot;, except that the effect is immediate.&lt;br /&gt;
&lt;br /&gt;
This is not really an animation, but placeOnObject is frequently used before starting an animation.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  // (We just created an object &amp;quot;my_new_token&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
  // Place the new token on current player board&lt;br /&gt;
  this.placeOnObject( &amp;quot;my_new_token&amp;quot;, &amp;quot;overall_player_board_&amp;quot;+this.player_id );&lt;br /&gt;
  &lt;br /&gt;
  // Then slide it to its position on the board&lt;br /&gt;
  this.slideToObject( &amp;quot;my_new_token&amp;quot;, &amp;quot;a_place_on_board&amp;quot; ).play();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.placeOnObjectPos( mobile_obj, target_obj, target_x, target_y )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This method works exactly like placeOnObject, except than you can specify some (x,y) coordinates. This way, &amp;quot;mobile_obj&amp;quot; will be placed to the specified x,y position relatively to &amp;quot;target_obj&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.attachToNewParent( mobile_obj, target_obj )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
With this method, you change the HTML parent of &amp;quot;mobile_obj&amp;quot; element. &amp;quot;target_obj&amp;quot; is the new parent of this element. The beauty of &lt;br /&gt;
attachToNewParent is that the mobile_obj element DOES NOT MOVE during this process.&lt;br /&gt;
&lt;br /&gt;
Note: what happens is that the method calculate a relative position of mobile_obj to make sure it does not move after the HTML parent changes.&lt;br /&gt;
&lt;br /&gt;
Why using this method?&lt;br /&gt;
&lt;br /&gt;
Changing the HTML parent of an element can be useful for the following reasons:&lt;br /&gt;
* When the HTML parent moves, all its child are moving with them. If some game elements is no more linked with a parent HTML object, you may want to attach it to another place.&lt;br /&gt;
* The z_order (vertical order of display) depends on the position in the DOM, so you may need to change the parent of some game elements when they are moving in your game area.&lt;br /&gt;
&lt;br /&gt;
CAREFUL: this function destroys original object and places a clone onto a new parent, this will break all references to this HTML element (ex: dojo.connect).&lt;br /&gt;
&lt;br /&gt;
== Players input ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;dojo.connect&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Used to associate a player event with one of your notification method.&lt;br /&gt;
&lt;br /&gt;
Example: associate a click on an element (&amp;quot;my_element&amp;quot;) with one of our method (&amp;quot;onClickOnMyElement&amp;quot;):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
      dojo.connect( $(&#039;my_element&#039;), &#039;onclick&#039;, this, &#039;onClickOnMyElement&#039; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: this is the only possible correct way to associate a player input event to your code, and you must not use anything else.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.checkAction( &amp;quot;my_action_name&amp;quot; )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Usage: checkAction: function( action, nomessage )&lt;br /&gt;
&lt;br /&gt;
Check if player can do the specified action by taking into account:&lt;br /&gt;
* current game state&lt;br /&gt;
* interface locking (a player can&#039;t do any action if an action is already in progress)&lt;br /&gt;
&lt;br /&gt;
return true if action is authorized (ie: the action is listed as a &amp;quot;possibleaction&amp;quot; in current game state).&lt;br /&gt;
&lt;br /&gt;
return false and display an error message if not (display no message if nomessage parameter is true). The displayed error message could be either &amp;quot;This move is not allowed at this moment&amp;quot; or &amp;quot;An action is already in progress&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  function onClickOnGameElement( evt )&lt;br /&gt;
  {&lt;br /&gt;
     if( this.checkAction( &amp;quot;my_action&amp;quot; ) )&lt;br /&gt;
     {&lt;br /&gt;
        // Do the action&lt;br /&gt;
     }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.ajaxcall( url, parameters, obj_callback, callback, callback_error )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This method must be used to send a player input to the game server.&lt;br /&gt;
&lt;br /&gt;
* url: the url of the action to perform. For a game, it must be: &amp;quot;/&amp;lt;mygame&amp;gt;/&amp;lt;mygame&amp;gt;/myAction.html&amp;quot;&lt;br /&gt;
* parameters: an array of parameter to send to the game server. Note that &amp;quot;lock:true&amp;quot; must always be specified in this list of parameter in order the interface can be locked during the server call.&lt;br /&gt;
* obj_callback: must be set to &amp;quot;this&amp;quot;.&lt;br /&gt;
* callback: a function to trigger when the server returns and everything went fine.&lt;br /&gt;
* callback_error: (optional and rarely used) a function to trigger when the server returns an error.&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
this.ajaxcall( &#039;/mygame/mygame/myaction.html&#039;, { lock: true, &lt;br /&gt;
   arg1: myarg1, &lt;br /&gt;
   arg2: myarg2, &lt;br /&gt;
   ...&lt;br /&gt;
}, this, function( result ) {&lt;br /&gt;
   // Do some stuff after a successful call&lt;br /&gt;
} );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Restricted arguments names (please don&#039;t use them):&lt;br /&gt;
* &amp;quot;action&amp;quot;&lt;br /&gt;
* &amp;quot;module&amp;quot;&lt;br /&gt;
* &amp;quot;class&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.confirmationDialog()&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Display a confirmation dialog with a yes/no choice.&lt;br /&gt;
&lt;br /&gt;
We advice you to NOT use this function unless the player action is really critical and could ruins the game, because it slows down the game and upset players.&lt;br /&gt;
&lt;br /&gt;
Usage: this.confirmationDialog( &amp;quot;Question to displayed&amp;quot;, callback_function_if_click_on_yes );&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
this.confirmationDialog( _(&#039;Are you sure to use this bonus (points penalty at the end of the game) ?&#039;),&lt;br /&gt;
                         dojo.hitch( this, function() {&lt;br /&gt;
                           this.ajaxcall( &#039;/seasons/seasons/useBonus.html&#039;,&lt;br /&gt;
                                { id:bonus_id, lock:true }, this, function( result ) {} );&lt;br /&gt;
                        } ) ); &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; addEventToClass: function( cssClassName, eventName, functionName )&lt;br /&gt;
: Same as dojo.connect(), but for all the nodes set with the specified cssClassName&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.addActionButton( id, label, method, (opt)destination, (opt)blinking, (opt)color )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You can use this method to add an action button in the main action status bar.&lt;br /&gt;
&lt;br /&gt;
Arguments:&lt;br /&gt;
* id: an element ID that should be unique in your HTML DOM document.&lt;br /&gt;
* label: the text of the button. Should be translatable (use _() function).&lt;br /&gt;
* method: the name of your method that must be triggered when the player clicks on this button.&lt;br /&gt;
* destination (optional): deprecated, do not use this. Use &#039;&#039;&#039;null&#039;&#039;&#039; as value if you need to specify other arguments.&lt;br /&gt;
* blinking (optional): if set to &#039;&#039;&#039;true&#039;&#039;&#039;, the button is going blink to catch player&#039;s attention. Please don&#039;t abuse of blinking button.&lt;br /&gt;
* color: could be &#039;&#039;&#039;blue&#039;&#039;&#039; (default), &#039;&#039;&#039;red&#039;&#039;&#039; or &#039;&#039;&#039;gray&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
You should only use this method in your &amp;quot;onUpdateActionButtons&amp;quot; method. Usually, you use it like this (from Hears example):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        onUpdateActionButtons: function( stateName, args ) {&lt;br /&gt;
                      &lt;br /&gt;
            if (this.isCurrentPlayerActive()) {            &lt;br /&gt;
                switch( stateName ) {&lt;br /&gt;
                case &#039;giveCards&#039;:&lt;br /&gt;
                    this.addActionButton( &#039;giveCards_button&#039;, _(&#039;Give selected cards&#039;), &#039;onGiveCards&#039; ); &lt;br /&gt;
                    break;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        },   &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the example above, we are adding a &amp;quot;Give selected cards&amp;quot; button in the case we are on game state &amp;quot;giveCards&amp;quot;. When player clicks on this button, it triggers our &amp;quot;onGiveCards&amp;quot; method.&lt;br /&gt;
&lt;br /&gt;
Example using blinking red button:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     this.addActionButton( &#039;commit_button&#039;, _(&#039;Confirm&#039;), &#039;onConfirm&#039;, null, true, &#039;red&#039;); &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: at least in studio example above will make button huge, because it sets it display of blinking things to &#039;&#039;&#039;block&#039;&#039;&#039;, &lt;br /&gt;
if you don&#039;t like it you have to change css display value&lt;br /&gt;
of the button to inline-block (the id of the button is the first argument, i.e &#039;commit_button&#039; in example above)&lt;br /&gt;
&lt;br /&gt;
== Translations ==&lt;br /&gt;
&lt;br /&gt;
See [[Translations]]&lt;br /&gt;
&lt;br /&gt;
== Notifications ==&lt;br /&gt;
&lt;br /&gt;
When something happens on the server side, your game interface Javascript logic received a notification.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s how you can handle these notifications on the client side.&lt;br /&gt;
&lt;br /&gt;
=== Subscribe to notifications ===&lt;br /&gt;
&lt;br /&gt;
Your Javascript &amp;quot;setupNotifications&amp;quot; method is the place where you can subscribe to notifications from your PHP code.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s how you associate one of your Javascript method to a notification &amp;quot;playDisc&amp;quot; (from Reversi example):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   // In setupNotifications method:&lt;br /&gt;
   dojo.subscribe( &#039;playDisc&#039;, this, &amp;quot;notif_playDisc&amp;quot; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: the &amp;quot;playDisc&amp;quot; corresponds to the name of the notification you define it in your PHP code, in your &amp;quot;notifyAllPlayers&amp;quot; or &amp;quot;notifyPlayer&amp;quot; method.&lt;br /&gt;
&lt;br /&gt;
Then, you have to define your &amp;quot;notif_playDisc&amp;quot; method:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        notif_playDisc: function( notif )&lt;br /&gt;
        {&lt;br /&gt;
            // Remove current possible moves (makes the board more clear)&lt;br /&gt;
            dojo.query( &#039;.possibleMove&#039; ).removeClass( &#039;possibleMove&#039; );        &lt;br /&gt;
        &lt;br /&gt;
            this.addDiscOnBoard( notif.args.x, notif.args.y, notif.args.player_id );&lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In a notification handler like our &amp;quot;notif_playDisc&amp;quot; method, you can access to all notifications arguments with &amp;quot;notif.args&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    // If you did this on PHP side:&lt;br /&gt;
    self::notifyAllPlayers( &amp;quot;myNotification&amp;quot;, &#039;&#039;, array( &amp;quot;myArgument&amp;quot; =&amp;gt; 3 ) );&lt;br /&gt;
&lt;br /&gt;
    // On Javascript side, you can access the &amp;quot;myArgument&amp;quot; like this:&lt;br /&gt;
    notif_myNotification: function( notif )&lt;br /&gt;
    {&lt;br /&gt;
       alert( &amp;quot;myArgument = &amp;quot; + notif.args.myArgument );&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Synchronous notifications ===&lt;br /&gt;
&lt;br /&gt;
When several notifications are received by your game interface, these notifications are processed immediately, one after the other, in the same exact order they have been generated in your PHP game logic.&lt;br /&gt;
&lt;br /&gt;
However, sometimes, you need to give some time to the players to figure out what happened on the game before jumping to the next notification. Indeed, in many games, they are a lot of automatic actions, and the computer is going to resolve all these actions very fast if you don&#039;t tell it not to do so.&lt;br /&gt;
&lt;br /&gt;
As an example, for Reversi, when someone is playing a disc, we want to wait 500 milliseconds before doing anything else in order the opponent player can figure out what move has been played.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s how we do this, right after our subscription:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
       dojo.subscribe( &#039;playDisc&#039;, this, &amp;quot;notif_playDisc&amp;quot; );&lt;br /&gt;
       this.notifqueue.setSynchronous( &#039;playDisc&#039;, 500 );   // Wait 500 milliseconds after executing the playDisc handler&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Pre-defined notification types ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;tableWindow&#039;&#039;&#039; - This defines notification to display [[Game_interface_logic:_yourgamename.js#Scoring_dialogs|Scoring Dialogs]], see below.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;message&#039;&#039;&#039; - This defines notification that shows on players log and have no other effect&lt;br /&gt;
&lt;br /&gt;
   // You can call this on php side without doing anything on client side&lt;br /&gt;
    self::notifyAllPlayers( &#039;message&#039;, &#039;hello&#039;, array( ) );&lt;br /&gt;
&lt;br /&gt;
== Tooltips ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.addTooltip( nodeId, _( helpString ), _( actionString ), delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Add a simple text tooltip to the DOM node.&lt;br /&gt;
&lt;br /&gt;
Specify &#039;helpString&#039; to display some information about &amp;quot;what is this game element?&amp;quot;.&lt;br /&gt;
Specify &#039;actionString&#039; to display some information about &amp;quot;what happens when I click on this element?&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
You must specify both helpString and actionString. Most of the time, you use only one and specify a void string (&amp;quot;&amp;quot;) for the other one.&lt;br /&gt;
&lt;br /&gt;
Usually, _() must be used for the text to be marked for translation.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Delay&amp;quot; is an optional parameter. Usually, it is primarily used to specify a zero delay for some game element when the tooltip gives really important information for the game - but remember: no essential information must be placed in tooltips as they won&#039;t be displayed in some browser (see Guidelines).&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   this.addTooltip( &#039;cardcount&#039;, _(&#039;Number of cards in hand&#039;), &#039;&#039; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.addTooltipHtml( nodeId, html, delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Add an HTML tooltip to the DOM node (for more elaborate content such as presenting a bigger version of a card).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.addTooltipToClass( cssClass, _( helpString ), _( actionString ), delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Add a simple text tooltip to all the DOM nodes set with this cssClass. &lt;br /&gt;
&lt;br /&gt;
IMPORTANT: all concerned nodes must have IDs to get tooltips.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.addTooltipHtmlToClass( cssClass, html, delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Add an HTML tooltip to to all the DOM nodes set with this cssClass (for more elaborate content such as presenting a bigger version of a card).&lt;br /&gt;
&lt;br /&gt;
IMPORTANT: all concerned nodes must have IDs to get tooltips&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.removeTooltip( nodeId )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Remove a tooltip from the DOM node.&lt;br /&gt;
&lt;br /&gt;
== Dialogs, warning messages, confirmation dialogs, ... ==&lt;br /&gt;
&lt;br /&gt;
=== Warning messages ===&lt;br /&gt;
&lt;br /&gt;
Sometimes, there is something important that is happening on the game and you have to make sure all players get the message. Most of the time, the evolution of the game situation or the game log is enough, but sometimes you need something more visible.&lt;br /&gt;
&lt;br /&gt;
Ex: someone fulfill one of the end of the game condition, so this is the last turn.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.showMessage( msg, type )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
showMessage shows a message in a big rectangular area on the top of the screen of current player.&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;msg&amp;quot; is the string to display. It should be translated.&lt;br /&gt;
* &amp;quot;type&amp;quot; can be set to &amp;quot;info&amp;quot; or &amp;quot;error&amp;quot;. If set to &amp;quot;info&amp;quot;, the message will be an informative message on a white background. If set to &amp;quot;error&amp;quot;, the message will be an error message on a red background.&lt;br /&gt;
&lt;br /&gt;
Important: the normal way to inform players about the progression of the game is the game log. &amp;quot;showMessage&amp;quot; is intrusive and should not be used often.&lt;br /&gt;
&lt;br /&gt;
=== Confirmation dialog ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;confirmationDialog( message, yesHandler, noHandler )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When an important action with a lot of consequences is triggered by the player, you may want to propose a confirmation dialog.&lt;br /&gt;
&lt;br /&gt;
CAREFUL: the general guidelines of BGA is to AVOID the use of confirmation dialog. Confirmation dialogs slow down the game and bother players. The players knows that they have to pay attention about each move when they are playing online.&lt;br /&gt;
&lt;br /&gt;
The situation where you should use a confirmation dialog are the following:&lt;br /&gt;
* It must not happen very often during a game.&lt;br /&gt;
* It must be linked to an action that can really &amp;quot;kill a game&amp;quot; if the player do not pay attention.&lt;br /&gt;
* It must be something that can be done by mistake (ex: a link on the action status bar).&lt;br /&gt;
&lt;br /&gt;
How to display a confirmation dialog:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        this.confirmationDialog( _(&#039;Are you sure you want to bake the pie?&#039;), dojo.hitch( this, function() {&lt;br /&gt;
            this.bakeThePie();&lt;br /&gt;
        } ) ); &lt;br /&gt;
        return; // nothing should be called or done after calling this, all action must be done in the handler  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Multiple choice dialog ===&lt;br /&gt;
You can use this dialog to give user a choice with small amount of options:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        var keys = [1,5,10];&lt;br /&gt;
        this.multipleChoiceDialog(&lt;br /&gt;
          _(&#039;How many bugs to fix?&amp;quot;), keys, &lt;br /&gt;
            dojo.hitch(this, function(choice) {&lt;br /&gt;
                            var bugchoice = keys[choice];&lt;br /&gt;
                            console.log(&#039;dialog callback with &#039;+bugchoice);&lt;br /&gt;
                            this.ajaxcall( &#039;/mygame/mygame/fixBugs.html&#039;, { bugs: bugchoice}, this, function( result ) {} );                        }));&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Dialogs ===&lt;br /&gt;
&lt;br /&gt;
At first, you shouldn&#039;t use dialogs windows.&lt;br /&gt;
&lt;br /&gt;
BGA guidelines specify that all game elements should be displayed on the main screen. Players can eventually scroll down to see game elements they don&#039;t need to see anytime, and you may eventually create anchors to move between game area section. Of course dialogs windows are very practical, but the thing is: all players know how to scroll down, and not all players know how to show up your dialog window. In addition, when the dialog shows up, players can&#039;t access the other game components.&lt;br /&gt;
&lt;br /&gt;
Sometimes although, you need to display a dialog window. Here is how you do this:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  // Create the new dialog. You should store the handler in a member variable to access it later&lt;br /&gt;
  this.myDlg = new dijit.Dialog({ title: _(&amp;quot;my dialog title to translate&amp;quot;) });&lt;br /&gt;
  &lt;br /&gt;
  // Create the HTML of my dialog. &lt;br /&gt;
  // The best practice here is to use [[Game_layout:_view_and_template:_yourgamename.view.php_and_yourgamename_yourgamename.tpl#Javascript_templates|Javascript templates]]&lt;br /&gt;
  var html = this.format_block( &#039;jstpl_myDialogTemplate&#039;, { &lt;br /&gt;
                arg1: myArg1,&lt;br /&gt;
                arg2: myArg2,&lt;br /&gt;
                ...&lt;br /&gt;
            } );  &lt;br /&gt;
  &lt;br /&gt;
  // Show the dialog&lt;br /&gt;
  this.myDlg.attr(&amp;quot;content&amp;quot;, html );&lt;br /&gt;
  this.myDlg.show(); &lt;br /&gt;
  &lt;br /&gt;
  // Now that the dialog has been displayed, you can connect your method to some dialog elements&lt;br /&gt;
  // Example, a &amp;quot;close&amp;quot; button:&lt;br /&gt;
  dojo.connect( $(&#039;closeDlg&#039;), &#039;onclick&#039;, this, function(evt){&lt;br /&gt;
                evt.preventDefault();&lt;br /&gt;
                this.myDlg.hide();&lt;br /&gt;
            } );  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Tip: be careful with &amp;quot;hide()&amp;quot; method to close your dialog: the dialog and its content is not completely removed from the DOM. It can cause you problems if you try to display the same dialog several times. A good practice is to wrap all the content of your dialog in a &amp;lt;nowiki&amp;gt;&amp;lt;div id=&#039;myDlgContent&#039;&amp;gt;&amp;lt;/nowiki&amp;gt; div element, and to call &amp;quot;dojo.destroy(&#039;myDlgContent&#039;)&amp;quot; before displaying your dialog.&lt;br /&gt;
&lt;br /&gt;
=== Scoring dialogs ===&lt;br /&gt;
&lt;br /&gt;
Sometimes at the end of a round you want to display a big table that details the points wins in each section of the game.&lt;br /&gt;
&lt;br /&gt;
Example: in Hearts game, we display at the end of each round the number of &amp;quot;heart&amp;quot; cards collected by each player, the player who collected the Queen of Spades, and the total number of points loose by each player.&lt;br /&gt;
&lt;br /&gt;
Scoring dialogs are managed entirely on &#039;&#039;&#039;PHP side&#039;&#039;&#039;, but they are described here as their effects are visible only on client side.&lt;br /&gt;
&lt;br /&gt;
Displaying a scoring dialog is quite simple and is using a special notification type: &amp;quot;tableWindow&amp;quot;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  // on PHP side:&lt;br /&gt;
  $this-&amp;gt;notifyAllPlayers( &amp;quot;tableWindow&amp;quot;, &#039;&#039;, array(&lt;br /&gt;
            &amp;quot;id&amp;quot; =&amp;gt; &#039;finalScoring&#039;,&lt;br /&gt;
            &amp;quot;title&amp;quot; =&amp;gt; clienttranslate(&amp;quot;Title of the scoring dialog&amp;quot;),&lt;br /&gt;
            &amp;quot;table&amp;quot; =&amp;gt; $table&lt;br /&gt;
        ) ); &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;table&amp;quot; argument is a 2 dimensional PHP array that describe the table you want to display, line by line and column by column.&lt;br /&gt;
&lt;br /&gt;
Example: display an 3x3 array of strings&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   $table = array(&lt;br /&gt;
      array( &amp;quot;one&amp;quot;, &amp;quot;two&amp;quot;, &amp;quot;three&amp;quot; ),    // This is my first line&lt;br /&gt;
      array( &amp;quot;four&amp;quot;, &amp;quot;five&amp;quot;, &amp;quot;six&amp;quot; ),    // This is my second line&lt;br /&gt;
      array( &amp;quot;seven&amp;quot;, &amp;quot;height&amp;quot;, &amp;quot;nine&amp;quot; )    // This is my third line&lt;br /&gt;
   );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As you can see above, in each &amp;quot;cell&amp;quot; of your array you can display a simple string value. But you can also display a complex value with a template and associated arguments like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   $table = array(&lt;br /&gt;
      array( &amp;quot;one&amp;quot;, &amp;quot;two&amp;quot;, array( &amp;quot;str&amp;quot; =&amp;gt; &amp;quot;a string with an ${argument}&amp;quot;, &amp;quot;args&amp;quot; =&amp;gt; array( &#039;argument&#039; =&amp;gt; &#039;argument_value&#039; )  ) ),&lt;br /&gt;
      array( &amp;quot;four&amp;quot;, &amp;quot;five&amp;quot;, &amp;quot;six&amp;quot; ), &lt;br /&gt;
      array( &amp;quot;seven&amp;quot;, &amp;quot;height&amp;quot;, &amp;quot;nine&amp;quot; )&lt;br /&gt;
   );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is especially useful when you want to display player names with colors. Example from &amp;quot;Hearts&amp;quot;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        $firstRow = array( &#039;&#039; );&lt;br /&gt;
        foreach( $players as $player_id =&amp;gt; $player )&lt;br /&gt;
        {&lt;br /&gt;
            $firstRow[] = array( &#039;str&#039; =&amp;gt; &#039;${player_name}&#039;,&lt;br /&gt;
                                 &#039;args&#039; =&amp;gt; array( &#039;player_name&#039; =&amp;gt; $player[&#039;player_name&#039;] ),&lt;br /&gt;
                                 &#039;type&#039; =&amp;gt; &#039;header&#039;&lt;br /&gt;
                               );&lt;br /&gt;
        }&lt;br /&gt;
        $table[] = $firstRow;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also use three extra attributes in the parameter array for the notification:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   $this-&amp;gt;notifyAllPlayers( &amp;quot;tableWindow&amp;quot;, &#039;&#039;, array(&lt;br /&gt;
            &amp;quot;id&amp;quot; =&amp;gt; &#039;finalScoring&#039;,&lt;br /&gt;
            &amp;quot;title&amp;quot; =&amp;gt; clienttranslate(&amp;quot;Title of the scoring dialog&amp;quot;),&lt;br /&gt;
            &amp;quot;table&amp;quot; =&amp;gt; $table,&lt;br /&gt;
            &amp;quot;header&amp;quot; =&amp;gt; array(&#039;str&#039; =&amp;gt; clienttranslate(&#039;Table header with parameter ${number}&#039;),&lt;br /&gt;
                                 &#039;args&#039; =&amp;gt; array( &#039;number&#039; =&amp;gt; 3 ),&lt;br /&gt;
                               ),&lt;br /&gt;
            &amp;quot;footer&amp;quot; =&amp;gt; &#039;&amp;lt;div&amp;gt;Some footer&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
            &amp;quot;closing&amp;quot; =&amp;gt; clienttranslate( &amp;quot;Closing button label&amp;quot; )&lt;br /&gt;
        ) ); &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;header&#039;&#039;&#039;: the content for this parameter will display before the table (also, the html will be parsed and player names will be colored according to the current game colors). &lt;br /&gt;
*&#039;&#039;&#039;footer&#039;&#039;&#039;: the content for this parameter will display after the table (no parsing for coloring the player names)&lt;br /&gt;
*&#039;&#039;&#039;closing&#039;&#039;&#039;: if this parameter is used, a button will be displayed with this label at the bottom of the popup and will allow players to close it (more easily than by clicking the top right &#039;cross&#039; icon).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Scoring animated display ===&lt;br /&gt;
&lt;br /&gt;
Sometimes (Terra Mystica final scoring for example), you may want to display a score value over an element to make the scoring easier to follow for the players.&lt;br /&gt;
You can do it with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   this.displayScoring( anchor_id, color, score );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Speech bubble ===&lt;br /&gt;
&lt;br /&gt;
For better interactivity in some games (Love Letter for example), you may use comic book style speech bubbles to express the players voices.&lt;br /&gt;
This is done with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   this.showBubble( anchor_id, text, delay, duration, custom_class )&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
delay in milliseconds is optional (default 0)&lt;br /&gt;
&lt;br /&gt;
duration in milliseconds is optional (default 3000)&lt;br /&gt;
&lt;br /&gt;
custom_class is optional, if you need to override the default bubble style&lt;br /&gt;
&lt;br /&gt;
== Update players score ==&lt;br /&gt;
&lt;br /&gt;
Increase a player score (with a positive or negative number):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  this.scoreCtrl[ player_id ].incValue( score_delta );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Set a player score to a specific value:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  this.scoreCtrl[ player_id ].setValue( new_score );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Players panels ==&lt;br /&gt;
&lt;br /&gt;
=== Adding stuff to player&#039;s panel ===&lt;br /&gt;
&lt;br /&gt;
At first, create a new &amp;quot;JS template&amp;quot; string in your template (tpl) file:&lt;br /&gt;
&lt;br /&gt;
(from Gomoku example)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
var jstpl_player_board = &#039;\&amp;lt;div class=&amp;quot;cp_board&amp;quot;&amp;gt;\&lt;br /&gt;
    &amp;lt;div id=&amp;quot;stoneicon_p${id}&amp;quot; class=&amp;quot;gmk_stoneicon gmk_stoneicon_${color}&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;span id=&amp;quot;stonecount_p${id}&amp;quot;&amp;gt;0&amp;lt;/span&amp;gt;\&lt;br /&gt;
&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then, you add this piece of code in your JS file to add this template to each player panel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
            // Setting up player boards&lt;br /&gt;
            for( var player_id in gamedatas.players )&lt;br /&gt;
            {&lt;br /&gt;
                var player = gamedatas.players[player_id];&lt;br /&gt;
                         &lt;br /&gt;
                // Setting up players boards if needed&lt;br /&gt;
                var player_board_div = $(&#039;player_board_&#039;+player_id);&lt;br /&gt;
                dojo.place( this.format_block(&#039;jstpl_player_board&#039;, player ), player_board_div );&lt;br /&gt;
            }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Note: the code above is of course from your &amp;quot;setup&amp;quot; function in your Javascript).&lt;br /&gt;
&lt;br /&gt;
Very often, you have to distinguish current player and others players. In this case, you just have to create another JS template (ex: jstpl_otherplayer_board) and use it when &amp;quot;player_id&amp;quot; is different than &amp;quot;this.player_id&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Player&#039;s panel disabling/enabling ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.disablePlayerPanel( player_id )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Disable given player panel (the panel background become gray).&lt;br /&gt;
&lt;br /&gt;
Usually, this is used to signal that this played passes, or will be inactive during a while.&lt;br /&gt;
&lt;br /&gt;
Note that the only effect of this is visual. There are no consequences on the behaviour of the panel itself.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.enablePlayerPanel( player_id )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Enable a player panel that has been disabled before.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.enableAllPlayerPanels()&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Enable all player panels that has been disabled before.&lt;br /&gt;
&lt;br /&gt;
== Image loading ==&lt;br /&gt;
&lt;br /&gt;
See also [[Game_art:_img_directory]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Be careful&#039;&#039;&#039;: by default, ALL images of your img directory are loaded on a player&#039;s browser when he loads the game. For this reason, don&#039;t let in your img directory images that are not useful, otherwise it&#039;s going to slowdown the game load.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;dontPreloadImage( image_file_name )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Using dontPreloadImage, you tell the interface to not preload a specific image in your img directory.&lt;br /&gt;
&lt;br /&gt;
Example of use:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
this.dontPreloadImage( &#039;cards.png&#039; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is particularly useful if for example you have 2 different themes for a game. To accelerate the loading of the game, you can specify to not preload images corresponding to the other theme.&lt;br /&gt;
&lt;br /&gt;
Another example of use: in &amp;quot;Gosu&amp;quot; game with Kamakor extension, you play with 5 sets of cards among 10 available. Cards images are organized by sets, and we only preload the images corresponding to the 5 current sets with &#039;&#039;&#039;ensureSpecificGameImageLoading( image_file_names_array )&#039;&#039;&#039;.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// By default, do not preload anything&lt;br /&gt;
this.dontPreloadImage( &#039;cards.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan1.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan2.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan3.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan4.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan5.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan6.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan7.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan8.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan9.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan10.png&#039; );&lt;br /&gt;
var to_preload = [];&lt;br /&gt;
for( i in this.gamedatas.clans )&lt;br /&gt;
{&lt;br /&gt;
	var clan_id = this.gamedatas.clans[i];&lt;br /&gt;
	to_preload.push( &#039;clan&#039;+clan_id+&#039;.png&#039; );&lt;br /&gt;
}&lt;br /&gt;
if( to_preload.length == 5 )&lt;br /&gt;
{&lt;br /&gt;
	this.ensureSpecificGameImageLoading( to_preload );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; You don&#039;t need to specify to not preload game box images (game_box.png, game_box75.png...) since they are not preloaded by default.&lt;br /&gt;
&lt;br /&gt;
== Other useful stuff ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;dojo.hitch&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
With dojo.hitch, you can create a callback function that will run with your game object context whatever happen.&lt;br /&gt;
&lt;br /&gt;
Typical example: display a BGA confirmation dialog with a callback function created with dojo.hitch:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        this.confirmationDialog( _(&#039;Are you sure you want to make this?&#039;), dojo.hitch( this, function() {&lt;br /&gt;
            this.ajaxcall( &#039;/mygame/mygame/makeThis.html&#039;, { lock:true }, this, function( result ) {} );&lt;br /&gt;
        } ) );   &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the example above, using dojo.hitch, we are sure that the &amp;quot;this&amp;quot; object will be set when the callback is called.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; updateCounters(counters)&lt;br /&gt;
: Useful for updating game counters in the player panel (such as resources). &lt;br /&gt;
: &#039;counters&#039; arg is an associative array [counter_name_value =&amp;gt; [ &#039;counter_name&#039; =&amp;gt; counter_name_value, &#039;counter_value&#039; =&amp;gt; counter_value_value], ... ]&lt;br /&gt;
: All counters must be referenced in this.gamedatas.counters and will be updated.&lt;br /&gt;
: DOM objects referenced by &#039;counter_name&#039; will have their innerHTML updated with &#039;counter_value&#039;.&lt;br /&gt;
&lt;br /&gt;
== BGA GUI components ==&lt;br /&gt;
&lt;br /&gt;
BGA framework provides some useful ready-to-use components for the game interface:&lt;br /&gt;
&lt;br /&gt;
[[Studio#BGA_Studio_game_components_reference]]&lt;br /&gt;
&lt;br /&gt;
Note that each time you are using an additional component, you must declare it at the top of your Javascript file in the list of modules used.&lt;br /&gt;
&lt;br /&gt;
Example if you are using &amp;quot;ebg.stock&amp;quot;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
define([&lt;br /&gt;
    &amp;quot;dojo&amp;quot;,&amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
    &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
    &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
    &amp;quot;ebg/stock&amp;quot;  /// &amp;lt;=== we are using ebg.stock module&lt;br /&gt;
],&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://sr.doc.boardgamearena.com/index.php?title=Game_interface_logic:_yourgamename.js&amp;diff=3082</id>
		<title>Game interface logic: yourgamename.js</title>
		<link rel="alternate" type="text/html" href="https://sr.doc.boardgamearena.com/index.php?title=Game_interface_logic:_yourgamename.js&amp;diff=3082"/>
		<updated>2018-05-26T09:11:59Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Dojo framework */ Version ecmascript&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This is the main file for your game interface. Here you will define:&lt;br /&gt;
&lt;br /&gt;
* which actions on the page will generate calls to the server&lt;br /&gt;
* what happens when you get a notification for change from the server and how it will show in the browser. &lt;br /&gt;
&lt;br /&gt;
== File structure ==&lt;br /&gt;
&lt;br /&gt;
The details on how the file is structured is described directly with comments on the code skeleton provided to you.&lt;br /&gt;
&lt;br /&gt;
Basically, here&#039;s this structure:&lt;br /&gt;
* constructor: here you can define variable global to your whole interface.&lt;br /&gt;
* setup: this method is called when the page is refreshed, in order you can setup the game interface.&lt;br /&gt;
* onEnteringState: the method is called when entering in a new game state. This way you can customize the view for this game state.&lt;br /&gt;
* onLeavingState: the method is called when leaving a game state.&lt;br /&gt;
* onUpdateActionButtons: called when entering in a new state, in order you can add action buttons in status bar.&lt;br /&gt;
* (utility methods): at this place you can define your utility methods&lt;br /&gt;
* (player&#039;s actions): at this place you can write your handlers for player&#039;s action on the interface (ex: click on an item).&lt;br /&gt;
* setupNotifications: in this method you associate notifications with notification handlers. This way, for each game notification, you trigger a javascript method to handle it and update the game interface.&lt;br /&gt;
* (notification handlers): at this place you can define your notifications handlers.&lt;br /&gt;
&lt;br /&gt;
== General tips ==&lt;br /&gt;
&lt;br /&gt;
; this.player_id&lt;br /&gt;
: Id of the player on whose browser the code is running.&lt;br /&gt;
&lt;br /&gt;
; this.isSpectator&lt;br /&gt;
: Flag set to true if the user at the table is a spectator (not a player).&lt;br /&gt;
: Note: this is not a function, its a variable.&lt;br /&gt;
: Note: if you want to hide some element for spectators, you&#039;d better use [[Game_interface_stylesheet:_yourgamename.css#spectatorMode|CSS &#039;spectatorMode&#039; class]].&lt;br /&gt;
&lt;br /&gt;
; this.gamedatas&lt;br /&gt;
: Contains your initial set of datas to init the game, created at game start or game refresh (F5)&lt;br /&gt;
: You can update it as needed to keep an up to date reference of the game on the client side if you need it (most of the time you don&#039;t).&lt;br /&gt;
&lt;br /&gt;
; this.isCurrentPlayerActive()&lt;br /&gt;
: Returns true if the player on whose browser the code is running is currently active (it&#039;s his turn to play)&lt;br /&gt;
&lt;br /&gt;
; this.getActivePlayerId()&lt;br /&gt;
: Return the ID of active player, or null if we are not in a &amp;quot;activeplayer&amp;quot; type state.&lt;br /&gt;
&lt;br /&gt;
; this.getActivePlayers()&lt;br /&gt;
: Return an array with the IDs of players that are currently active (or an empty array if there is not).&lt;br /&gt;
&lt;br /&gt;
== Dojo framework ==&lt;br /&gt;
&lt;br /&gt;
BGA is using the [http://dojotoolkit.org/ Dojo Javascript framework].&lt;br /&gt;
&lt;br /&gt;
The Dojo framework allows us to do complex things easier, and the BGA framework is using Dojo framework a lot.&lt;br /&gt;
&lt;br /&gt;
To realize game although, you only need to use a few part of the Dojo framework. All the Dojo methods you need to use are describe on this page.&lt;br /&gt;
&lt;br /&gt;
For performance reasons, when deploying a game the js code is minified using Shrinksafe (based on ECMASCRIPT version 3). Some advanced syntax may not be compatible with this process. In particular:&lt;br /&gt;
* you should not use reserved keywords from the javascript language as variables&lt;br /&gt;
* you should not declare default argument values in function declaration, the following syntax is invalid for Shriksafe: function myFunc(requiredArg, optionalArg = &#039;defaultValue&#039;) {}&lt;br /&gt;
&lt;br /&gt;
== Access and manipulate the DOM ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;$(&#039;some_html_element_id&#039;)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The $() function is used to get some HTML element using its &amp;quot;id&amp;quot; attribute.&lt;br /&gt;
&lt;br /&gt;
Example 1: modify the content of a &amp;quot;span&amp;quot; element:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
In your HTML code:&lt;br /&gt;
   &amp;lt;span id=&amp;quot;a_value_in_the_game_interface&amp;quot;&amp;gt;1234&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In your Javascript code:&lt;br /&gt;
   $(&#039;a_value_in_the_game_interface&#039;).innerHTML = &amp;quot;9999&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: $() is the standard method to access some HTML element with BGA Framework. You must not use &amp;quot;getElementById&amp;quot; function.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;dojo.style&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
With dojo.style you can modify a CSS property of any HTML element of your interface.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     // Make an element disappear&lt;br /&gt;
     dojo.style( &#039;my_element&#039;, &#039;display&#039;, &#039;none&#039; );&lt;br /&gt;
&lt;br /&gt;
     // Give an element a 2px border&lt;br /&gt;
     dojo.style( &#039;my_element&#039;, &#039;borderWidth&#039;, &#039;2px&#039; );&lt;br /&gt;
&lt;br /&gt;
     // Change the background position of an element&lt;br /&gt;
     // (very practical when you are using CSS sprite to transform an element to another)&lt;br /&gt;
     dojo.style( &#039;my_element&#039;, &#039;backgroundPosition&#039;, &#039;-20px -50px&#039; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: you must always use dojo.style to modify CSS properties of HTML elements.&lt;br /&gt;
&lt;br /&gt;
Note²: if you have to modify several CSS properties of an element, or if you have some complex CSS transformation to do, you should consider using dojo.addClass/dojo.removeClass (see below).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;dojo CSS classes manipulation&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In many situation, a bunch of many small CSS property update can be replaced by a CSS class change (ie: you add a CSS class to your element instead of applying all modification manually).&lt;br /&gt;
&lt;br /&gt;
Advantages are:&lt;br /&gt;
* All your CSS stuff remains in your CSS file.&lt;br /&gt;
* You can add/remove a list of CSS modifications with a simple function and whithout error.&lt;br /&gt;
* You can test if you applied the stuff to an element with &amp;quot;dojo.hasClass&amp;quot; method.&lt;br /&gt;
&lt;br /&gt;
Example from &amp;quot;Reversi&amp;quot;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    // We add &amp;quot;possibleMove&amp;quot; to an element&lt;br /&gt;
    dojo.addClass( &#039;square_&#039;+x+&#039;_&#039;+y, &#039;possibleMove&#039; );&lt;br /&gt;
&lt;br /&gt;
    // In our CSS file, the class is defined as:&lt;br /&gt;
    .possibleMove {&lt;br /&gt;
      background-color: white;&lt;br /&gt;
      opacity: 0.2;&lt;br /&gt;
      filter:alpha(opacity=20); /* For IE8 and earlier */  &lt;br /&gt;
      cursor: pointer;  &lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
     // So we&#039;ve applied 4 CSS property change in one line of code.&lt;br /&gt;
&lt;br /&gt;
     // ... and when we need to check if a square is a possible move on client side:&lt;br /&gt;
     if( dojo.hasClass( &#039;square_&#039;+x+&#039;_&#039;+y, &#039;possibleMove&#039; ) )&lt;br /&gt;
     { ... }&lt;br /&gt;
&lt;br /&gt;
     // ... and if we want to remove all possible moves in one line of code (see &amp;quot;dojo.query&amp;quot; method):&lt;br /&gt;
     dojo.query( &#039;.possibleMove&#039; ).removeClass( &#039;possibleMove&#039; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Conclusion: we encourage you to use dojo.addClass, dojo.removeClass and dojo.hasClass to make your life easier :)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;dojo.query&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
With dojo.query, you can query a bunch of HTML elements with a single function, with a &amp;quot;CSS selector&amp;quot; style.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     // All elements with class &amp;quot;possibleMove&amp;quot;:&lt;br /&gt;
     var elements = dojo.query( &#039;.possibleMove&#039; );&lt;br /&gt;
&lt;br /&gt;
     // Count number of tokens (ie: elements with class &amp;quot;token&amp;quot;) on the board (ie: element with id &amp;quot;board&amp;quot;):&lt;br /&gt;
     dojo.query( &#039;#board .token&#039; ).length;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
But what is really cool with dojo.query is that you can combine it with almost all methods above.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     // Trigger a method when the mouse enter in any element with class &amp;quot;meeple&amp;quot;:&lt;br /&gt;
     dojo.query( &#039;.meeple&#039; ).connect( &#039;onmouseenter&#039;, this, &#039;myMethodToTrigger&#039; );&lt;br /&gt;
&lt;br /&gt;
     // Hide all meeples who are on the board&lt;br /&gt;
     dojo.query( &#039;#board .meeple&#039; ).style( &#039;display&#039;, &#039;none&#039; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;dojo.place&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
dojo.place is the best function to insert some HTML code somewhere in your game interface without breaking something. It is much better to use that &amp;quot;innerHTML=&#039;&#039;&amp;quot; method as soon as you must insert HTML tags and not only values.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     // Insert your HTML code as a child of a container element&lt;br /&gt;
     dojo.place( &amp;quot;&amp;lt;your html code&amp;gt;&amp;quot;, &amp;quot;your_container_element_id&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
     // Replace the container element with your new html&lt;br /&gt;
     dojo.place( &amp;quot;&amp;lt;your html code&amp;gt;&amp;quot;, &amp;quot;your_container_element_id&amp;quot;, &amp;quot;replace&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The third parameter of dojo.place can take various interesting value.&lt;br /&gt;
&lt;br /&gt;
values possibles :&lt;br /&gt;
&lt;br /&gt;
&amp;quot;replace&amp;quot; : (see description above).&lt;br /&gt;
&lt;br /&gt;
&amp;quot;first&amp;quot; : Places the node as a child of the reference node. The node is placed as the first child.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;last&amp;quot; : Places the node as a child of the reference node. The node is placed as the last child.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;before&amp;quot; : places the node right before the reference node.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;last (value by default) &amp;quot; : places the node right after the reference node.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;only&amp;quot; : replaces all children of the reference node with the node.&lt;br /&gt;
&lt;br /&gt;
positif integer : This parameter can be a positif integer. In this case, the node will be placed as a child of the reference node with this number (counting from 0). If the number is more than number of children, the node will be appended to the reference node making it the last child. &lt;br /&gt;
&lt;br /&gt;
See also full doc on dojo.place : [http://dojotoolkit.org/reference-guide/1.7/dojo/place.]&lt;br /&gt;
&lt;br /&gt;
Usually, when you want to insert some piece of HTML in your game interface, you should use &amp;quot;[[Game_layout:_view_and_template:_yourgamename.view.php_and_yourgamename_yourgamename.tpl#Javascript_templates|Javascript templates]]&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;addStyleToClass: function( cssClassName, cssProperty, propertyValue )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Same as dojo.style(), but for all the nodes set with the specified cssClassName&lt;br /&gt;
&lt;br /&gt;
=== Animations ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Dojo Animations&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
BGA animations is based on Dojo Animation ([http://dojotoolkit.org/documentation/tutorials/1.8/animation/ see tutorial here]).&lt;br /&gt;
&lt;br /&gt;
However, most of the time, you can just use methods below, which are built on top of Dojo Animation.&lt;br /&gt;
&lt;br /&gt;
Note: one interesting method from Dojo that could be useful from time to time is &amp;quot;Dojo.Animation&amp;quot;. It allows you to make any CSS property &amp;quot;slide&amp;quot; from one value to another.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.slideToObject( mobile_obj, target_obj, duration, delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You can use slideToObject to &amp;quot;slide&amp;quot; an element to a target position.&lt;br /&gt;
&lt;br /&gt;
Sliding element on the game area is the recommended and the most used way to animate your game interface. Using slides allow players to figure out what is happening on the game, as if they were playing with the real boardgame.&lt;br /&gt;
&lt;br /&gt;
The parameters are:&lt;br /&gt;
* mobile_obj: the ID of the object to move. This object must be &amp;quot;relative&amp;quot; or &amp;quot;absolute&amp;quot; positioned.&lt;br /&gt;
* target_obj: the ID of the target object. This object must be &amp;quot;relative&amp;quot; or &amp;quot;absolute&amp;quot; positioned. Note that it is not mandatory that mobile_obj and target_obj have the same size. If their size are different, the system slides the center of mobile_obj to the center of target_obj.&lt;br /&gt;
* duration: (optional) defines the duration in millisecond of the slide. The default is 500 milliseconds.&lt;br /&gt;
* delay: (optional). If you defines a delay, the slide will start only after this delay. This is particularly useful when you want to slide several object from the same position to the same position: you can give a 0ms delay to the first object, a 100ms delay to the second one, a 200ms delay to the third one, ... this way they won&#039;t be superposed during the slide.&lt;br /&gt;
&lt;br /&gt;
BE CAREFUL: The method returns an dojo.fx animation, so you can combine it with other animation if you want to. It means that you have to call the &amp;quot;play()&amp;quot; method, otherwise the animation WON&#039;T START.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   this.slideToObject( &amp;quot;some_token&amp;quot;, &amp;quot;some_place_on_board&amp;quot; ).play();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.slideToObjectPos( mobile_obj, target_obj, target_x, target_y, duration, delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This method does exactly the same as &amp;quot;slideToObject&amp;quot;, except than you can specify some (x,y) coordinates. This way, &amp;quot;mobile_obj&amp;quot; will slide to the specified x,y position relatively to &amp;quot;target_obj&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Example: slide a token to some place on the board, 10 pixels to the bottom:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   this.slideToObjectPos( &amp;quot;some_token&amp;quot;, &amp;quot;some_place_on_board&amp;quot;, 0, 10 ).play();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.slideTemporaryObject( mobile_obj_html, mobile_obj_parent, from, to, duration, delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This method is useful when you want to slide a temporary HTML object from one place to another. As this object does not exists before the animation and won&#039;t remain after, it could be complex to create this object (with dojo.place), to place it at its origin (with placeOnObject) to slide it (with slideToObject) and to make it disappear at the end.&lt;br /&gt;
&lt;br /&gt;
slideTemporaryObject does all of this for you:&lt;br /&gt;
* mobile_obj_html is a piece of HTML code that represent the object to slide.&lt;br /&gt;
* mobile_obj_parent is the ID of an HTML element of your interface that will be the parent of this temporary HTML object.&lt;br /&gt;
* from is the ID of the origin of the slide.&lt;br /&gt;
* to is the ID of the target of the slide.&lt;br /&gt;
* duration/delay works exactly like in &amp;quot;slideToObject&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
this.slideTemporaryObject( &#039;&amp;lt;div class=&amp;quot;token_icon&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;, &#039;tokens&#039;, &#039;my_origin_div&#039;, &#039;my_target_div&#039; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.slideToObjectAndDestroy: function( node, to, time, delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This method is a handy shortcut to slide an existing HTML object to some place then destroy it upon arrival. It can be used for example to move a victory token or a card from the board to the player panel to show that the player earns it, then destroy it when we don&#039;t need to keep it visible on the player panel.&lt;br /&gt;
&lt;br /&gt;
It works the same as this.slideToObject and takes the same arguments. &lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
this.slideToObjectAndDestroy( &amp;quot;some_token&amp;quot;, &amp;quot;some_place_on_board&amp;quot;, 1000, 0 );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.fadeOutAndDestroy( node, duration, delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This function fade out the target HTML node, then destroy it.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   this.fadeOutAndDestroy( &amp;quot;a_card_that_must_disappear&amp;quot; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
CAREFUL: the HTML node still exists until during few milliseconds, until the fadeOut has been completed.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Rotating elements&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You can check here [http://jimfulton.info/demos/dojo-animated-rotate.html an example of use] of Dojo to make an element rotate.&lt;br /&gt;
&lt;br /&gt;
This example combines &amp;quot;Dojo.Animation&amp;quot; method and a CSS3 property that allow you to rotate the element.&lt;br /&gt;
&lt;br /&gt;
IMPORTANT: to asses browser compatibility, you must select the CSS property to use just like in the example (see sourcecode below):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        var transform;&lt;br /&gt;
        dojo.forEach(&lt;br /&gt;
            [&#039;transform&#039;, &#039;WebkitTransform&#039;, &#039;msTransform&#039;,&lt;br /&gt;
             &#039;MozTransform&#039;, &#039;OTransform&#039;],&lt;br /&gt;
            function (name) {&lt;br /&gt;
                if (typeof dojo.body().style[name] != &#039;undefined&#039;) {&lt;br /&gt;
                    transform = name;&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        // ... and then use &amp;quot;transform&amp;quot; as the name of your CSS property for rotation&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Moving elements ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.placeOnObject( mobile_obj, target_obj )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
placeOnObject works exactly like &amp;quot;slideToObject&amp;quot;, except that the effect is immediate.&lt;br /&gt;
&lt;br /&gt;
This is not really an animation, but placeOnObject is frequently used before starting an animation.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  // (We just created an object &amp;quot;my_new_token&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
  // Place the new token on current player board&lt;br /&gt;
  this.placeOnObject( &amp;quot;my_new_token&amp;quot;, &amp;quot;overall_player_board_&amp;quot;+this.player_id );&lt;br /&gt;
  &lt;br /&gt;
  // Then slide it to its position on the board&lt;br /&gt;
  this.slideToObject( &amp;quot;my_new_token&amp;quot;, &amp;quot;a_place_on_board&amp;quot; ).play();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.placeOnObjectPos( mobile_obj, target_obj, target_x, target_y )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This method works exactly like placeOnObject, except than you can specify some (x,y) coordinates. This way, &amp;quot;mobile_obj&amp;quot; will be placed to the specified x,y position relatively to &amp;quot;target_obj&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.attachToNewParent( mobile_obj, target_obj )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
With this method, you change the HTML parent of &amp;quot;mobile_obj&amp;quot; element. &amp;quot;target_obj&amp;quot; is the new parent of this element. The beauty of &lt;br /&gt;
attachToNewParent is that the mobile_obj element DOES NOT MOVE during this process.&lt;br /&gt;
&lt;br /&gt;
Note: what happens is that the method calculate a relative position of mobile_obj to make sure it does not move after the HTML parent changes.&lt;br /&gt;
&lt;br /&gt;
Why using this method?&lt;br /&gt;
&lt;br /&gt;
Changing the HTML parent of an element can be useful for the following reasons:&lt;br /&gt;
* When the HTML parent moves, all its child are moving with them. If some game elements is no more linked with a parent HTML object, you may want to attach it to another place.&lt;br /&gt;
* The z_order (vertical order of display) depends on the position in the DOM, so you may need to change the parent of some game elements when they are moving in your game area.&lt;br /&gt;
&lt;br /&gt;
CAREFUL: this function destroys original object and places a clone onto a new parent, this will break all references to this HTML element (ex: dojo.connect).&lt;br /&gt;
&lt;br /&gt;
== Players input ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;dojo.connect&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Used to associate a player event with one of your notification method.&lt;br /&gt;
&lt;br /&gt;
Example: associate a click on an element (&amp;quot;my_element&amp;quot;) with one of our method (&amp;quot;onClickOnMyElement&amp;quot;):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
      dojo.connect( $(&#039;my_element&#039;), &#039;onclick&#039;, this, &#039;onClickOnMyElement&#039; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: this is the only possible correct way to associate a player input event to your code, and you must not use anything else.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.checkAction( &amp;quot;my_action_name&amp;quot; )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Usage: checkAction: function( action, nomessage )&lt;br /&gt;
&lt;br /&gt;
Check if player can do the specified action by taking into account:&lt;br /&gt;
* current game state&lt;br /&gt;
* interface locking (a player can&#039;t do any action if an action is already in progress)&lt;br /&gt;
&lt;br /&gt;
return true if action is authorized (ie: the action is listed as a &amp;quot;possibleaction&amp;quot; in current game state).&lt;br /&gt;
&lt;br /&gt;
return false and display an error message if not (display no message if nomessage parameter is true). The displayed error message could be either &amp;quot;This move is not allowed at this moment&amp;quot; or &amp;quot;An action is already in progress&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  function onClickOnGameElement( evt )&lt;br /&gt;
  {&lt;br /&gt;
     if( this.checkAction( &amp;quot;my_action&amp;quot; ) )&lt;br /&gt;
     {&lt;br /&gt;
        // Do the action&lt;br /&gt;
     }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.ajaxcall( url, parameters, obj_callback, callback, callback_error )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This method must be used to send a player input to the game server.&lt;br /&gt;
&lt;br /&gt;
* url: the url of the action to perform. For a game, it must be: &amp;quot;/&amp;lt;mygame&amp;gt;/&amp;lt;mygame&amp;gt;/myAction.html&amp;quot;&lt;br /&gt;
* parameters: an array of parameter to send to the game server. Note that &amp;quot;lock:true&amp;quot; must always be specified in this list of parameter in order the interface can be locked during the server call.&lt;br /&gt;
* obj_callback: must be set to &amp;quot;this&amp;quot;.&lt;br /&gt;
* callback: a function to trigger when the server returns and everything went fine.&lt;br /&gt;
* callback_error: (optional and rarely used) a function to trigger when the server returns an error.&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
this.ajaxcall( &#039;/mygame/mygame/myaction.html&#039;, { lock: true, &lt;br /&gt;
   arg1: myarg1, &lt;br /&gt;
   arg2: myarg2, &lt;br /&gt;
   ...&lt;br /&gt;
}, this, function( result ) {&lt;br /&gt;
   // Do some stuff after a successful call&lt;br /&gt;
} );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Restricted arguments names (please don&#039;t use them):&lt;br /&gt;
* &amp;quot;action&amp;quot;&lt;br /&gt;
* &amp;quot;module&amp;quot;&lt;br /&gt;
* &amp;quot;class&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.confirmationDialog()&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Display a confirmation dialog with a yes/no choice.&lt;br /&gt;
&lt;br /&gt;
We advice you to NOT use this function unless the player action is really critical and could ruins the game, because it slows down the game and upset players.&lt;br /&gt;
&lt;br /&gt;
Usage: this.confirmationDialog( &amp;quot;Question to displayed&amp;quot;, callback_function_if_click_on_yes );&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
this.confirmationDialog( _(&#039;Are you sure to use this bonus (points penalty at the end of the game) ?&#039;),&lt;br /&gt;
                         dojo.hitch( this, function() {&lt;br /&gt;
                           this.ajaxcall( &#039;/seasons/seasons/useBonus.html&#039;,&lt;br /&gt;
                                { id:bonus_id, lock:true }, this, function( result ) {} );&lt;br /&gt;
                        } ) ); &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; addEventToClass: function( cssClassName, eventName, functionName )&lt;br /&gt;
: Same as dojo.connect(), but for all the nodes set with the specified cssClassName&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.addActionButton( id, label, method, (opt)destination, (opt)blinking, (opt)color )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You can use this method to add an action button in the main action status bar.&lt;br /&gt;
&lt;br /&gt;
Arguments:&lt;br /&gt;
* id: an element ID that should be unique in your HTML DOM document.&lt;br /&gt;
* label: the text of the button. Should be translatable (use _() function).&lt;br /&gt;
* method: the name of your method that must be triggered when the player clicks on this button.&lt;br /&gt;
* destination (optional): deprecated, do not use this. Use &#039;&#039;&#039;null&#039;&#039;&#039; as value if you need to specify other arguments.&lt;br /&gt;
* blinking (optional): if set to &#039;&#039;&#039;true&#039;&#039;&#039;, the button is going blink to catch player&#039;s attention. Please don&#039;t abuse of blinking button.&lt;br /&gt;
* color: could be &#039;&#039;&#039;blue&#039;&#039;&#039; (default), &#039;&#039;&#039;red&#039;&#039;&#039; or &#039;&#039;&#039;gray&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
You should only use this method in your &amp;quot;onUpdateActionButtons&amp;quot; method. Usually, you use it like this (from Hears example):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        onUpdateActionButtons: function( stateName, args ) {&lt;br /&gt;
                      &lt;br /&gt;
            if (this.isCurrentPlayerActive()) {            &lt;br /&gt;
                switch( stateName ) {&lt;br /&gt;
                case &#039;giveCards&#039;:&lt;br /&gt;
                    this.addActionButton( &#039;giveCards_button&#039;, _(&#039;Give selected cards&#039;), &#039;onGiveCards&#039; ); &lt;br /&gt;
                    break;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        },   &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the example above, we are adding a &amp;quot;Give selected cards&amp;quot; button in the case we are on game state &amp;quot;giveCards&amp;quot;. When player clicks on this button, it triggers our &amp;quot;onGiveCards&amp;quot; method.&lt;br /&gt;
&lt;br /&gt;
Example using blinking red button:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     this.addActionButton( &#039;commit_button&#039;, _(&#039;Confirm&#039;), &#039;onConfirm&#039;, null, true, &#039;red&#039;); &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: at least in studio example above will make button huge, because it sets it display of blinking things to &#039;&#039;&#039;block&#039;&#039;&#039;, &lt;br /&gt;
if you don&#039;t like it you have to change css display value&lt;br /&gt;
of the button to inline-block (the id of the button is the first argument, i.e &#039;commit_button&#039; in example above)&lt;br /&gt;
&lt;br /&gt;
== Translations ==&lt;br /&gt;
&lt;br /&gt;
See [[Translations]]&lt;br /&gt;
&lt;br /&gt;
== Notifications ==&lt;br /&gt;
&lt;br /&gt;
When something happens on the server side, your game interface Javascript logic received a notification.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s how you can handle these notifications on the client side.&lt;br /&gt;
&lt;br /&gt;
=== Subscribe to notifications ===&lt;br /&gt;
&lt;br /&gt;
Your Javascript &amp;quot;setupNotifications&amp;quot; method is the place where you can subscribe to notifications from your PHP code.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s how you associate one of your Javascript method to a notification &amp;quot;playDisc&amp;quot; (from Reversi example):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   // In setupNotifications method:&lt;br /&gt;
   dojo.subscribe( &#039;playDisc&#039;, this, &amp;quot;notif_playDisc&amp;quot; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: the &amp;quot;playDisc&amp;quot; corresponds to the name of the notification you define it in your PHP code, in your &amp;quot;notifyAllPlayers&amp;quot; or &amp;quot;notifyPlayer&amp;quot; method.&lt;br /&gt;
&lt;br /&gt;
Then, you have to define your &amp;quot;notif_playDisc&amp;quot; method:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        notif_playDisc: function( notif )&lt;br /&gt;
        {&lt;br /&gt;
            // Remove current possible moves (makes the board more clear)&lt;br /&gt;
            dojo.query( &#039;.possibleMove&#039; ).removeClass( &#039;possibleMove&#039; );        &lt;br /&gt;
        &lt;br /&gt;
            this.addDiscOnBoard( notif.args.x, notif.args.y, notif.args.player_id );&lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In a notification handler like our &amp;quot;notif_playDisc&amp;quot; method, you can access to all notifications arguments with &amp;quot;notif.args&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    // If you did this on PHP side:&lt;br /&gt;
    self::notifyAllPlayers( &amp;quot;myNotification&amp;quot;, &#039;&#039;, array( &amp;quot;myArgument&amp;quot; =&amp;gt; 3 ) );&lt;br /&gt;
&lt;br /&gt;
    // On Javascript side, you can access the &amp;quot;myArgument&amp;quot; like this:&lt;br /&gt;
    notif_myNotification: function( notif )&lt;br /&gt;
    {&lt;br /&gt;
       alert( &amp;quot;myArgument = &amp;quot; + notif.args.myArgument );&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Synchronous notifications ===&lt;br /&gt;
&lt;br /&gt;
When several notifications are received by your game interface, these notifications are processed immediately, one after the other, in the same exact order they have been generated in your PHP game logic.&lt;br /&gt;
&lt;br /&gt;
However, sometimes, you need to give some time to the players to figure out what happened on the game before jumping to the next notification. Indeed, in many games, they are a lot of automatic actions, and the computer is going to resolve all these actions very fast if you don&#039;t tell it not to do so.&lt;br /&gt;
&lt;br /&gt;
As an example, for Reversi, when someone is playing a disc, we want to wait 500 milliseconds before doing anything else in order the opponent player can figure out what move has been played.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s how we do this, right after our subscription:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
       dojo.subscribe( &#039;playDisc&#039;, this, &amp;quot;notif_playDisc&amp;quot; );&lt;br /&gt;
       this.notifqueue.setSynchronous( &#039;playDisc&#039;, 500 );   // Wait 500 milliseconds after executing the playDisc handler&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Pre-defined notification types ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;tableWindow&#039;&#039;&#039; - This defines notification to display [[Game_interface_logic:_yourgamename.js#Scoring_dialogs|Scoring Dialogs]], see below.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;message&#039;&#039;&#039; - This defines notification that shows on players log and have no other effect&lt;br /&gt;
&lt;br /&gt;
   // You can call this on php side without doing anything on client side&lt;br /&gt;
    self::notifyAllPlayers( &#039;message&#039;, &#039;hello&#039;, array( ) );&lt;br /&gt;
&lt;br /&gt;
== Tooltips ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.addTooltip( nodeId, _( helpString ), _( actionString ), delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Add a simple text tooltip to the DOM node.&lt;br /&gt;
&lt;br /&gt;
Specify &#039;helpString&#039; to display some information about &amp;quot;what is this game element?&amp;quot;.&lt;br /&gt;
Specify &#039;actionString&#039; to display some information about &amp;quot;what happens when I click on this element?&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
You must specify both helpString and actionString. Most of the time, you use only one and specify a void string (&amp;quot;&amp;quot;) for the other one.&lt;br /&gt;
&lt;br /&gt;
Usually, _() must be used for the text to be marked for translation.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Delay&amp;quot; is an optional parameter. Usually, it is primarily used to specify a zero delay for some game element when the tooltip gives really important information for the game - but remember: no essential information must be placed in tooltips as they won&#039;t be displayed in some browser (see Guidelines).&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   this.addTooltip( &#039;cardcount&#039;, _(&#039;Number of cards in hand&#039;), &#039;&#039; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.addTooltipHtml( nodeId, html, delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Add an HTML tooltip to the DOM node (for more elaborate content such as presenting a bigger version of a card).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.addTooltipToClass( cssClass, _( helpString ), _( actionString ), delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Add a simple text tooltip to all the DOM nodes set with this cssClass. &lt;br /&gt;
&lt;br /&gt;
IMPORTANT: all concerned nodes must have IDs to get tooltips.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.addTooltipHtmlToClass( cssClass, html, delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Add an HTML tooltip to to all the DOM nodes set with this cssClass (for more elaborate content such as presenting a bigger version of a card).&lt;br /&gt;
&lt;br /&gt;
IMPORTANT: all concerned nodes must have IDs to get tooltips&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.removeTooltip( nodeId )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Remove a tooltip from the DOM node.&lt;br /&gt;
&lt;br /&gt;
== Dialogs, warning messages, confirmation dialogs, ... ==&lt;br /&gt;
&lt;br /&gt;
=== Warning messages ===&lt;br /&gt;
&lt;br /&gt;
Sometimes, there is something important that is happening on the game and you have to make sure all players get the message. Most of the time, the evolution of the game situation or the game log is enough, but sometimes you need something more visible.&lt;br /&gt;
&lt;br /&gt;
Ex: someone fulfill one of the end of the game condition, so this is the last turn.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.showMessage( msg, type )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
showMessage shows a message in a big rectangular area on the top of the screen of current player.&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;msg&amp;quot; is the string to display. It should be translated.&lt;br /&gt;
* &amp;quot;type&amp;quot; can be set to &amp;quot;info&amp;quot; or &amp;quot;error&amp;quot;. If set to &amp;quot;info&amp;quot;, the message will be an informative message on a white background. If set to &amp;quot;error&amp;quot;, the message will be an error message on a red background.&lt;br /&gt;
&lt;br /&gt;
Important: the normal way to inform players about the progression of the game is the game log. &amp;quot;showMessage&amp;quot; is intrusive and should not be used often.&lt;br /&gt;
&lt;br /&gt;
=== Confirmation dialog ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;confirmationDialog( message, yesHandler, noHandler )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When an important action with a lot of consequences is triggered by the player, you may want to propose a confirmation dialog.&lt;br /&gt;
&lt;br /&gt;
CAREFUL: the general guidelines of BGA is to AVOID the use of confirmation dialog. Confirmation dialogs slow down the game and bother players. The players knows that they have to pay attention about each move when they are playing online.&lt;br /&gt;
&lt;br /&gt;
The situation where you should use a confirmation dialog are the following:&lt;br /&gt;
* It must not happen very often during a game.&lt;br /&gt;
* It must be linked to an action that can really &amp;quot;kill a game&amp;quot; if the player do not pay attention.&lt;br /&gt;
* It must be something that can be done by mistake (ex: a link on the action status bar).&lt;br /&gt;
&lt;br /&gt;
How to display a confirmation dialog:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        this.confirmationDialog( _(&#039;Are you sure you want to bake the pie?&#039;), dojo.hitch( this, function() {&lt;br /&gt;
            this.bakeThePie();&lt;br /&gt;
        } ) ); &lt;br /&gt;
        return; // nothing should be called or done after calling this, all action must be done in the handler  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Multiple choice dialog ===&lt;br /&gt;
You can use this dialog to give user a choice with small amount of options:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        var keys = [1,5,10];&lt;br /&gt;
        this.multipleChoiceDialog(&lt;br /&gt;
          _(&#039;How many bugs to fix?&amp;quot;), keys, &lt;br /&gt;
            dojo.hitch(this, function(choice) {&lt;br /&gt;
                            var bugchoice = keys[choice];&lt;br /&gt;
                            console.log(&#039;dialog callback with &#039;+bugchoice);&lt;br /&gt;
                            this.ajaxcall( &#039;/mygame/mygame/fixBugs.html&#039;, { bugs: bugchoice}, this, function( result ) {} );                        }));&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Dialogs ===&lt;br /&gt;
&lt;br /&gt;
At first, you shouldn&#039;t use dialogs windows.&lt;br /&gt;
&lt;br /&gt;
BGA guidelines specify that all game elements should be displayed on the main screen. Players can eventually scroll down to see game elements they don&#039;t need to see anytime, and you may eventually create anchors to move between game area section. Of course dialogs windows are very practical, but the thing is: all players know how to scroll down, and not all players know how to show up your dialog window. In addition, when the dialog shows up, players can&#039;t access the other game components.&lt;br /&gt;
&lt;br /&gt;
Sometimes although, you need to display a dialog window. Here is how you do this:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  // Create the new dialog. You should store the handler in a member variable to access it later&lt;br /&gt;
  this.myDlg = new dijit.Dialog({ title: _(&amp;quot;my dialog title to translate&amp;quot;) });&lt;br /&gt;
  &lt;br /&gt;
  // Create the HTML of my dialog. &lt;br /&gt;
  // The best practice here is to use [[Game_layout:_view_and_template:_yourgamename.view.php_and_yourgamename_yourgamename.tpl#Javascript_templates|Javascript templates]]&lt;br /&gt;
  var html = this.format_block( &#039;jstpl_myDialogTemplate&#039;, { &lt;br /&gt;
                arg1: myArg1,&lt;br /&gt;
                arg2: myArg2,&lt;br /&gt;
                ...&lt;br /&gt;
            } );  &lt;br /&gt;
  &lt;br /&gt;
  // Show the dialog&lt;br /&gt;
  this.myDlg.attr(&amp;quot;content&amp;quot;, html );&lt;br /&gt;
  this.myDlg.show(); &lt;br /&gt;
  &lt;br /&gt;
  // Now that the dialog has been displayed, you can connect your method to some dialog elements&lt;br /&gt;
  // Example, a &amp;quot;close&amp;quot; button:&lt;br /&gt;
  dojo.connect( $(&#039;closeDlg&#039;), &#039;onclick&#039;, this, function(evt){&lt;br /&gt;
                evt.preventDefault();&lt;br /&gt;
                this.myDlg.hide();&lt;br /&gt;
            } );  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Tip: be careful with &amp;quot;hide()&amp;quot; method to close your dialog: the dialog and its content is not completely removed from the DOM. It can cause you problems if you try to display the same dialog several times. A good practice is to wrap all the content of your dialog in a &amp;lt;nowiki&amp;gt;&amp;lt;div id=&#039;myDlgContent&#039;&amp;gt;&amp;lt;/nowiki&amp;gt; div element, and to call &amp;quot;dojo.destroy(&#039;myDlgContent&#039;)&amp;quot; before displaying your dialog.&lt;br /&gt;
&lt;br /&gt;
=== Scoring dialogs ===&lt;br /&gt;
&lt;br /&gt;
Sometimes at the end of a round you want to display a big table that details the points wins in each section of the game.&lt;br /&gt;
&lt;br /&gt;
Example: in Hearts game, we display at the end of each round the number of &amp;quot;heart&amp;quot; cards collected by each player, the player who collected the Queen of Spades, and the total number of points loose by each player.&lt;br /&gt;
&lt;br /&gt;
Scoring dialogs are managed entirely on &#039;&#039;&#039;PHP side&#039;&#039;&#039;, but they are described here as their effects are visible only on client side.&lt;br /&gt;
&lt;br /&gt;
Displaying a scoring dialog is quite simple and is using a special notification type: &amp;quot;tableWindow&amp;quot;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  // on PHP side:&lt;br /&gt;
  $this-&amp;gt;notifyAllPlayers( &amp;quot;tableWindow&amp;quot;, &#039;&#039;, array(&lt;br /&gt;
            &amp;quot;id&amp;quot; =&amp;gt; &#039;finalScoring&#039;,&lt;br /&gt;
            &amp;quot;title&amp;quot; =&amp;gt; clienttranslate(&amp;quot;Title of the scoring dialog&amp;quot;),&lt;br /&gt;
            &amp;quot;table&amp;quot; =&amp;gt; $table&lt;br /&gt;
        ) ); &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;table&amp;quot; argument is a 2 dimensional PHP array that describe the table you want to display, line by line and column by column.&lt;br /&gt;
&lt;br /&gt;
Example: display an 3x3 array of strings&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   $table = array(&lt;br /&gt;
      array( &amp;quot;one&amp;quot;, &amp;quot;two&amp;quot;, &amp;quot;three&amp;quot; ),    // This is my first line&lt;br /&gt;
      array( &amp;quot;four&amp;quot;, &amp;quot;five&amp;quot;, &amp;quot;six&amp;quot; ),    // This is my second line&lt;br /&gt;
      array( &amp;quot;seven&amp;quot;, &amp;quot;height&amp;quot;, &amp;quot;nine&amp;quot; )    // This is my third line&lt;br /&gt;
   );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As you can see above, in each &amp;quot;cell&amp;quot; of your array you can display a simple string value. But you can also display a complex value with a template and associated arguments like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   $table = array(&lt;br /&gt;
      array( &amp;quot;one&amp;quot;, &amp;quot;two&amp;quot;, array( &amp;quot;str&amp;quot; =&amp;gt; &amp;quot;a string with an ${argument}&amp;quot;, &amp;quot;args&amp;quot; =&amp;gt; array( &#039;argument&#039; =&amp;gt; &#039;argument_value&#039; )  ) ),&lt;br /&gt;
      array( &amp;quot;four&amp;quot;, &amp;quot;five&amp;quot;, &amp;quot;six&amp;quot; ), &lt;br /&gt;
      array( &amp;quot;seven&amp;quot;, &amp;quot;height&amp;quot;, &amp;quot;nine&amp;quot; )&lt;br /&gt;
   );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is especially useful when you want to display player names with colors. Example from &amp;quot;Hearts&amp;quot;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        $firstRow = array( &#039;&#039; );&lt;br /&gt;
        foreach( $players as $player_id =&amp;gt; $player )&lt;br /&gt;
        {&lt;br /&gt;
            $firstRow[] = array( &#039;str&#039; =&amp;gt; &#039;${player_name}&#039;,&lt;br /&gt;
                                 &#039;args&#039; =&amp;gt; array( &#039;player_name&#039; =&amp;gt; $player[&#039;player_name&#039;] ),&lt;br /&gt;
                                 &#039;type&#039; =&amp;gt; &#039;header&#039;&lt;br /&gt;
                               );&lt;br /&gt;
        }&lt;br /&gt;
        $table[] = $firstRow;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also use three extra attributes in the parameter array for the notification:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   $this-&amp;gt;notifyAllPlayers( &amp;quot;tableWindow&amp;quot;, &#039;&#039;, array(&lt;br /&gt;
            &amp;quot;id&amp;quot; =&amp;gt; &#039;finalScoring&#039;,&lt;br /&gt;
            &amp;quot;title&amp;quot; =&amp;gt; clienttranslate(&amp;quot;Title of the scoring dialog&amp;quot;),&lt;br /&gt;
            &amp;quot;table&amp;quot; =&amp;gt; $table,&lt;br /&gt;
            &amp;quot;header&amp;quot; =&amp;gt; array(&#039;str&#039; =&amp;gt; clienttranslate(&#039;Table header with parameter ${number}&#039;),&lt;br /&gt;
                                 &#039;args&#039; =&amp;gt; array( &#039;number&#039; =&amp;gt; 3 ),&lt;br /&gt;
                               ),&lt;br /&gt;
            &amp;quot;footer&amp;quot; =&amp;gt; &#039;&amp;lt;div&amp;gt;Some footer&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
            &amp;quot;closing&amp;quot; =&amp;gt; clienttranslate( &amp;quot;Closing button label&amp;quot; )&lt;br /&gt;
        ) ); &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;header&#039;&#039;&#039;: the content for this parameter will display before the table (also, the html will be parsed and player names will be colored according to the current game colors). &lt;br /&gt;
*&#039;&#039;&#039;footer&#039;&#039;&#039;: the content for this parameter will display after the table (no parsing for coloring the player names)&lt;br /&gt;
*&#039;&#039;&#039;closing&#039;&#039;&#039;: if this parameter is used, a button will be displayed with this label at the bottom of the popup and will allow players to close it (more easily than by clicking the top right &#039;cross&#039; icon).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Scoring animated display ===&lt;br /&gt;
&lt;br /&gt;
Sometimes (Terra Mystica final scoring for example), you may want to display a score value over an element to make the scoring easier to follow for the players.&lt;br /&gt;
You can do it with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   this.displayScoring( anchor_id, color, score );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Speech bubble ===&lt;br /&gt;
&lt;br /&gt;
For better interactivity in some games (Love Letter for example), you may use comic book style speech bubbles to express the players voices.&lt;br /&gt;
This is done with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   this.showBubble( anchor_id, text, delay, duration, custom_class )&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
delay in milliseconds is optional (default 0)&lt;br /&gt;
&lt;br /&gt;
duration in milliseconds is optional (default 3000)&lt;br /&gt;
&lt;br /&gt;
custom_class is optional, if you need to override the default bubble style&lt;br /&gt;
&lt;br /&gt;
== Update players score ==&lt;br /&gt;
&lt;br /&gt;
Increase a player score (with a positive or negative number):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  this.scoreCtrl[ player_id ].incValue( score_delta );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Set a player score to a specific value:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  this.scoreCtrl[ player_id ].setValue( new_score );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Players panels ==&lt;br /&gt;
&lt;br /&gt;
=== Adding stuff to player&#039;s panel ===&lt;br /&gt;
&lt;br /&gt;
At first, create a new &amp;quot;JS template&amp;quot; string in your template (tpl) file:&lt;br /&gt;
&lt;br /&gt;
(from Gomoku example)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
var jstpl_player_board = &#039;\&amp;lt;div class=&amp;quot;cp_board&amp;quot;&amp;gt;\&lt;br /&gt;
    &amp;lt;div id=&amp;quot;stoneicon_p${id}&amp;quot; class=&amp;quot;gmk_stoneicon gmk_stoneicon_${color}&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;span id=&amp;quot;stonecount_p${id}&amp;quot;&amp;gt;0&amp;lt;/span&amp;gt;\&lt;br /&gt;
&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then, you add this piece of code in your JS file to add this template to each player panel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
            // Setting up player boards&lt;br /&gt;
            for( var player_id in gamedatas.players )&lt;br /&gt;
            {&lt;br /&gt;
                var player = gamedatas.players[player_id];&lt;br /&gt;
                         &lt;br /&gt;
                // Setting up players boards if needed&lt;br /&gt;
                var player_board_div = $(&#039;player_board_&#039;+player_id);&lt;br /&gt;
                dojo.place( this.format_block(&#039;jstpl_player_board&#039;, player ), player_board_div );&lt;br /&gt;
            }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Note: the code above is of course from your &amp;quot;setup&amp;quot; function in your Javascript).&lt;br /&gt;
&lt;br /&gt;
Very often, you have to distinguish current player and others players. In this case, you just have to create another JS template (ex: jstpl_otherplayer_board) and use it when &amp;quot;player_id&amp;quot; is different than &amp;quot;this.player_id&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Player&#039;s panel disabling/enabling ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.disablePlayerPanel( player_id )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Disable given player panel (the panel background become gray).&lt;br /&gt;
&lt;br /&gt;
Usually, this is used to signal that this played passes, or will be inactive during a while.&lt;br /&gt;
&lt;br /&gt;
Note that the only effect of this is visual. There are no consequences on the behaviour of the panel itself.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.enablePlayerPanel( player_id )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Enable a player panel that has been disabled before.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.enableAllPlayerPanels()&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Enable all player panels that has been disabled before.&lt;br /&gt;
&lt;br /&gt;
== Image loading ==&lt;br /&gt;
&lt;br /&gt;
See also [[Game_art:_img_directory]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Be careful&#039;&#039;&#039;: by default, ALL images of your img directory are loaded on a player&#039;s browser when he loads the game. For this reason, don&#039;t let in your img directory images that are not useful, otherwise it&#039;s going to slowdown the game load.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;dontPreloadImage( image_file_name )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Using dontPreloadImage, you tell the interface to not preload a specific image in your img directory.&lt;br /&gt;
&lt;br /&gt;
Example of use:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
this.dontPreloadImage( &#039;cards.png&#039; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is particularly useful if for example you have 2 different themes for a game. To accelerate the loading of the game, you can specify to not preload images corresponding to the other theme.&lt;br /&gt;
&lt;br /&gt;
Another example of use: in &amp;quot;Gosu&amp;quot; game with Kamakor extension, you play with 5 sets of cards among 10 available. Cards images are organized by sets, and we only preload the images corresponding to the 5 current sets with &#039;&#039;&#039;ensureSpecificGameImageLoading( image_file_names_array )&#039;&#039;&#039;.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// By default, do not preload anything&lt;br /&gt;
this.dontPreloadImage( &#039;cards.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan1.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan2.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan3.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan4.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan5.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan6.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan7.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan8.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan9.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan10.png&#039; );&lt;br /&gt;
var to_preload = [];&lt;br /&gt;
for( i in this.gamedatas.clans )&lt;br /&gt;
{&lt;br /&gt;
	var clan_id = this.gamedatas.clans[i];&lt;br /&gt;
	to_preload.push( &#039;clan&#039;+clan_id+&#039;.png&#039; );&lt;br /&gt;
}&lt;br /&gt;
if( to_preload.length == 5 )&lt;br /&gt;
{&lt;br /&gt;
	this.ensureSpecificGameImageLoading( to_preload );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; You don&#039;t need to specify to not preload game box images (game_box.png, game_box75.png...) since they are not preloaded by default.&lt;br /&gt;
&lt;br /&gt;
== Other useful stuff ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;dojo.hitch&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
With dojo.hitch, you can create a callback function that will run with your game object context whatever happen.&lt;br /&gt;
&lt;br /&gt;
Typical example: display a BGA confirmation dialog with a callback function created with dojo.hitch:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        this.confirmationDialog( _(&#039;Are you sure you want to make this?&#039;), dojo.hitch( this, function() {&lt;br /&gt;
            this.ajaxcall( &#039;/mygame/mygame/makeThis.html&#039;, { lock:true }, this, function( result ) {} );&lt;br /&gt;
        } ) );   &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the example above, using dojo.hitch, we are sure that the &amp;quot;this&amp;quot; object will be set when the callback is called.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; updateCounters(counters)&lt;br /&gt;
: Useful for updating game counters in the player panel (such as resources). &lt;br /&gt;
: &#039;counters&#039; arg is an associative array [counter_name_value =&amp;gt; [ &#039;counter_name&#039; =&amp;gt; counter_name_value, &#039;counter_value&#039; =&amp;gt; counter_value_value], ... ]&lt;br /&gt;
: All counters must be referenced in this.gamedatas.counters and will be updated.&lt;br /&gt;
: DOM objects referenced by &#039;counter_name&#039; will have their innerHTML updated with &#039;counter_value&#039;.&lt;br /&gt;
&lt;br /&gt;
== BGA GUI components ==&lt;br /&gt;
&lt;br /&gt;
BGA framework provides some useful ready-to-use components for the game interface:&lt;br /&gt;
&lt;br /&gt;
[[Studio#BGA_Studio_game_components_reference]]&lt;br /&gt;
&lt;br /&gt;
Note that each time you are using an additional component, you must declare it at the top of your Javascript file in the list of modules used.&lt;br /&gt;
&lt;br /&gt;
Example if you are using &amp;quot;ebg.stock&amp;quot;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
define([&lt;br /&gt;
    &amp;quot;dojo&amp;quot;,&amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
    &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
    &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
    &amp;quot;ebg/stock&amp;quot;  /// &amp;lt;=== we are using ebg.stock module&lt;br /&gt;
],&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://sr.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=3081</id>
		<title>SandboxScripts</title>
		<link rel="alternate" type="text/html" href="https://sr.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=3081"/>
		<updated>2018-05-25T09:03:30Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Trigger most common game actions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This is the reference of functions you can call from your Sandbox scripts.&lt;br /&gt;
&lt;br /&gt;
= Javascript =&lt;br /&gt;
&lt;br /&gt;
BGA Sandbox scripts are written in Javascript.&lt;br /&gt;
&lt;br /&gt;
Using Javascript, you can write scripts to automate moves for your Sandbox games &amp;amp; provide rules reinforcement.&lt;br /&gt;
&lt;br /&gt;
Important : in the opposite of the most common usage of Javascript, Sandbox scripts are executed &#039;&#039;&#039;on server side&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
= BGA API =&lt;br /&gt;
&lt;br /&gt;
To interact with your BGA Sandbox game, we provide you an API.&lt;br /&gt;
&lt;br /&gt;
With this API, you can get properties values of game elements from the current game situation, modify them and/or trigger the game actions (ex : move this element here, flip this card, and so on).&lt;br /&gt;
&lt;br /&gt;
= Quick start =&lt;br /&gt;
&lt;br /&gt;
== Hello World Script ==&lt;br /&gt;
&lt;br /&gt;
From Sandbox editor &amp;quot;interface view&amp;quot; tab, select an element, and access to its property (top right icon).&lt;br /&gt;
&lt;br /&gt;
Go to &amp;quot;Scripts (advanced)&amp;quot; section.&lt;br /&gt;
&lt;br /&gt;
In front of &amp;quot;When this element is clicked&amp;quot;, enter &amp;quot;onMyClick&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Close the window. Go to &amp;quot;script view&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Enter the following :&lt;br /&gt;
&lt;br /&gt;
 function onMyClick( element_id )&lt;br /&gt;
 {&lt;br /&gt;
    bga.log(&amp;quot;Hello world! You just clicked on element &amp;quot; + element_id + &amp;quot;. Congrats!&amp;quot;);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Save &amp;amp; publish your project, starts a test session, click on the previous element : your message appears in the log on the right!&lt;br /&gt;
&lt;br /&gt;
== Top useful tips ==&lt;br /&gt;
&lt;br /&gt;
* You don&#039;t have to save&amp;amp;publish from the Sandbox editor for each modification of your script : each time you save your script (control+S), the script used for all test sessions is updated. Note that the production version on BGA is of course NOT updated until you explicitly save&amp;amp;publish again your project.&lt;br /&gt;
&lt;br /&gt;
* To inspect the content of a variable, you can use bga.log() in combination with JSON.stringify(). For example :&lt;br /&gt;
&lt;br /&gt;
  bga.log( JSON.stringify( bga.getPlayers()) );&lt;br /&gt;
&lt;br /&gt;
* Alternatively to bga.log(), you can use bga.exit( &amp;quot;my message&amp;quot; ) to debug your script. With bga.exit, the script execution immediately stops and all previous game changes are cancelled, so this is very practical to try and retry an action until your script is fine.&lt;br /&gt;
&lt;br /&gt;
* We advise you to develop first a full playable version of the game without the scripts, and THEN to script it.&lt;br /&gt;
&lt;br /&gt;
* On Board Game Arena, players have come to expect fully implemented games with all rules enforced. So even if it&#039;s technically possible not to script the full game and to implement the game only partially, in most cases we&#039;ll publish only fully scripted games :)&lt;br /&gt;
&lt;br /&gt;
== Examples/Tutorials ==&lt;br /&gt;
&lt;br /&gt;
In addition to the projects you will create, you have readonly access in the sandbox to two example projects: &amp;quot;linesofaction&amp;quot; is an abstract and &amp;quot;apocalypseazcc&amp;quot; is a card game.&lt;br /&gt;
&lt;br /&gt;
These two projects are fully scripted, so you can check out the scripts and use them as examples/tutorials.&lt;br /&gt;
&lt;br /&gt;
= Functions you can use in your Sandbox scripts=&lt;br /&gt;
&lt;br /&gt;
== Debugging functions ==&lt;br /&gt;
&lt;br /&gt;
=== bga.trace( txt / obj ) ===&lt;br /&gt;
&lt;br /&gt;
Write something immediately in the BGA log (on the right of the screen).&lt;br /&gt;
&lt;br /&gt;
This is the most practical way to debug your script :)&lt;br /&gt;
&lt;br /&gt;
Important : bga.trace is for debugging purpose only and won&#039;t be displayed on production.&lt;br /&gt;
&lt;br /&gt;
Note : you can also pass an object in parameter. This will dump the content of this object in the log.&lt;br /&gt;
&lt;br /&gt;
Note : in the opposite of bga.log, bga.trace is NOT cancelled if the game action failed (after a call to bga.cancel or bga.error). This makes bga.trace very practical to debug a game action that failed, and for this reason you should probably NEVER use bga.log for debugging purpose.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  // Example : write &amp;quot;Hello world&amp;quot; in the log&lt;br /&gt;
  bga.trace( &amp;quot;Hello world&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Example : dump an associative array in the log&lt;br /&gt;
  bga.trace( { mykey: &#039;myvalue&#039;, another_key: &#039;another_value&#039; } );&lt;br /&gt;
&lt;br /&gt;
=== bga.exit( txt / obj ) ===&lt;br /&gt;
&lt;br /&gt;
Stop the script immediately, display the &amp;quot;txt&amp;quot; messages and cancel (ie : rollback) on every previous API call except bga.trace :&lt;br /&gt;
&lt;br /&gt;
ALL previous BGA api call are canceled and there will be no visible changes on the interface (ex : no moves, no visible property changes, ...). Only &amp;quot;bga.trace&amp;quot; API commands are kept so you can debug.&lt;br /&gt;
&lt;br /&gt;
bga.exit is very practical when you want to repeat a game action again and again to debug it : with a call to bga.exit at the end of your script, you make sure that your game situation will be kept unchanged after each test.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.exit( &amp;quot;My script is stopped by this call&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Example with dumping a javascript variable&lt;br /&gt;
  bga.exit( my_variable_to_dump );&lt;br /&gt;
&lt;br /&gt;
== Cancelling a game action ==&lt;br /&gt;
&lt;br /&gt;
=== bga.cancel( txt ) ===&lt;br /&gt;
&lt;br /&gt;
This is the function to use when a player is doing something against game rules.&lt;br /&gt;
&lt;br /&gt;
The text message in parameter will be displayed to this player as a &amp;quot;red message&amp;quot;, so he/she can understand the rule.&lt;br /&gt;
&lt;br /&gt;
All previous BGA api call are cancelled, and there will be no visible changes on the interface.&lt;br /&gt;
&lt;br /&gt;
   // Example :&lt;br /&gt;
   bga.cancel( _(&amp;quot;You cannot move this piece here&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
Note : most of the time, you should wrap your text inside a _() translation marker to make this string translatable.&lt;br /&gt;
&lt;br /&gt;
=== bga.error( text ) ===&lt;br /&gt;
&lt;br /&gt;
This is the function to use when some unexpected error happens in your script.&lt;br /&gt;
&lt;br /&gt;
The text message will be displayed to user, with mention &amp;quot;Unexpected error&amp;quot;. The player will be incited to fill a bug report. The purpose of the message is to help you to identify the bug.&lt;br /&gt;
&lt;br /&gt;
All previous BGA api call are cancelled, and there will be no visible changes on the interface.&lt;br /&gt;
&lt;br /&gt;
   // Example :&lt;br /&gt;
   if( card_picked === null )&lt;br /&gt;
   {&lt;br /&gt;
       bga.error( &amp;quot;Cannot find a card to pick !&amp;quot; );&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
Note : you should NEVER wrap text inside bga.error with _() translation marker, because unexpected error should not be translate (so you can eventually recognize them when reported by players in bug report).&lt;br /&gt;
&lt;br /&gt;
== Game log (history) ==&lt;br /&gt;
&lt;br /&gt;
=== bga.log( txt, (optional) args ) ===&lt;br /&gt;
&lt;br /&gt;
Write something in the BGA log on the right.&lt;br /&gt;
&lt;br /&gt;
  // Example : simple log&lt;br /&gt;
  bga.log( _(&amp;quot;A new round starts&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
You may add arguments to your log, like this :&lt;br /&gt;
&lt;br /&gt;
  // Example: log with argument to display a card name.&lt;br /&gt;
  //          In this example, variable &amp;quot;event_name&amp;quot; is specified afterwards.&lt;br /&gt;
  //          Note that using this, game translators only have to translate one &amp;quot;Event XXX is triggered&amp;quot; string for all possible events.&lt;br /&gt;
  bga.log( _(&amp;quot;Event ${event_name} is triggered&amp;quot;), {  event_name: _( &amp;quot;Armageddon&amp;quot; ) } ) );&lt;br /&gt;
&lt;br /&gt;
Note that argument &amp;quot;player_name&amp;quot; is ALWAYS pre-set with the name of the current player, so you can use it immediately.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.log( _(&amp;quot;${player_name} draw a card from the deck&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
=== bga.speechBubble( target, text, (optional) args, (optional) delay, (optional) duration, (optional) size ) ===&lt;br /&gt;
&lt;br /&gt;
Display a &amp;quot;speech bubble&amp;quot;, attached to the specified target, containing the specified text.&lt;br /&gt;
&lt;br /&gt;
You can use &amp;quot;args&amp;quot; to customize text exactly like with bga.log.&lt;br /&gt;
&lt;br /&gt;
delay : milliseconds to wait before displaying the speech bubble (default : 0).&lt;br /&gt;
duration : how long to show the speech bubble in milliseconds (default : 3000).&lt;br /&gt;
size : size of the text in percent (default: 100)&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.speechBubble( _(&amp;quot;I play ${nbr} cards&amp;quot;), { nbr : 4 }, 0 );&lt;br /&gt;
  bga.speechBubble( _(&amp;quot;Good for you!&amp;quot;), { }, 2000 );&lt;br /&gt;
&lt;br /&gt;
=== bga.displayScoring( target, color, score ) ===&lt;br /&gt;
&lt;br /&gt;
Display an animated temporary &amp;quot;score number&amp;quot;, attached to the specified target.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;color&amp;quot; should be the color of the player who is scoring for that target.&lt;br /&gt;
&lt;br /&gt;
== Get / search game elements and their properties ==&lt;br /&gt;
&lt;br /&gt;
=== bga.getElement( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Allow you to retrieve informations about one game element specified using &amp;quot;selector&amp;quot; argument.&lt;br /&gt;
&lt;br /&gt;
Return null if no element is found.&lt;br /&gt;
&lt;br /&gt;
Note : getElement throw an error if several elements matches the selector. If you want to retrieve several elements, you should use &amp;quot;getElements&amp;quot; instead of &amp;quot;getElement&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The following examples are showing all the possible use of bga.getElement :&lt;br /&gt;
&lt;br /&gt;
  // Basic example :&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve the ID of a game element using its name (&amp;quot;Deck&amp;quot;)&lt;br /&gt;
  var deck_id = bga.getElement( { name: &amp;quot;Deck&amp;quot; } );&lt;br /&gt;
  // Return : 1234  &lt;br /&gt;
&lt;br /&gt;
  // Examples using &amp;quot;field&amp;quot; parameter :&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve a specific property from a game element using its name (&amp;quot;Deck&amp;quot;)&lt;br /&gt;
  var deck_id = bga.getElement( { name: &amp;quot;Deck&amp;quot; }, &#039;x&#039; );&lt;br /&gt;
  // Return : 20&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve several properties from the previous element&lt;br /&gt;
  var deck_properties = bga.getElement( { name: &amp;quot;Deck&amp;quot; }, [&#039;name&#039;,&#039;id&#039;,&#039;parent&#039;, &#039;x&#039;,&#039;y&#039;,&#039;canShuffle&#039;] );&lt;br /&gt;
  // Return : { name:&#039;Deck&#039;, id:1234, parent:4321, x: 20, y:50, canShuffle: true }&lt;br /&gt;
  &lt;br /&gt;
  // Note : as you can see, getElement returns:&lt;br /&gt;
  //        _ the element ID by default, or&lt;br /&gt;
  //        _ a single value if you request a single field, or&lt;br /&gt;
  //        _ an object if you request several fields&lt;br /&gt;
&lt;br /&gt;
  // Examples using different &amp;quot;selector&amp;quot; paramter&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve an element name from its id&lt;br /&gt;
  var deck_name = bga.getElement( { id: 1234 }, [&#039;name&#039;] );&lt;br /&gt;
  // Return : &amp;quot;Deck&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  // Retrieve the last child element of another element&lt;br /&gt;
  // Here, we are requesting for elements who has element with ID=1234 (Deck) as their parent&lt;br /&gt;
  // Note the use of &amp;quot;limit:1&amp;quot; which allows us to retrieve only 1 element.&lt;br /&gt;
  var first_card_on_deck_id = bga.getElement( { parent: 1234, limit:1 } );&lt;br /&gt;
  &lt;br /&gt;
  // You can also get nested properties such as the ids of the child elements of one element, or a custom property placed on the parent element&lt;br /&gt;
  var totem_places = bga.getElements( {tag:&#039;TOTEMZONE&#039;}, [&#039;id&#039;,&#039;childs:id&#039;,&#039;childs:tags&#039;,&#039;parent:id&#039;,&#039;parent:c_value&#039;] );&lt;br /&gt;
&lt;br /&gt;
=== bga.getElements( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Returns an object holding the properties of the elements matching the selector.&lt;br /&gt;
&lt;br /&gt;
  // Basic example: unselect all selected elements&lt;br /&gt;
  bga.removeStyle( bga.getElements( {tag: &#039;sbstyle_selected&#039;}), &#039;selected&#039; );&lt;br /&gt;
&lt;br /&gt;
=== bga.getElementsArray( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Returns an array of all elements matching the selector, holding the required properties.&lt;br /&gt;
&lt;br /&gt;
  // Basic example: get id of selected element&lt;br /&gt;
  var selected_tokens = bga.getElementsArray( {tag: &#039;sbstyle_selected&#039; } );&lt;br /&gt;
  var token_id = null;&lt;br /&gt;
  if (selected_tokens.length &amp;gt; 0) {&lt;br /&gt;
      token_id = selected_tokens[0];&lt;br /&gt;
  }&lt;br /&gt;
  return token_id;&lt;br /&gt;
&lt;br /&gt;
  // Classic example: get array of elements and iterate over it&lt;br /&gt;
  var all_cells = bga.getElementsArray( {tag: &#039;CELL&#039;}, [&#039;id&#039;,&#039;name&#039;,&#039;tags&#039;] );&lt;br /&gt;
  for (var i=0; i&amp;lt;all_cells.length; i++) {&lt;br /&gt;
     // ... process each cell ...&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Utility methods ==&lt;br /&gt;
&lt;br /&gt;
=== bga.isOn( element_id, parent_id ) ===&lt;br /&gt;
&lt;br /&gt;
Return true if &amp;quot;element_id&amp;quot; is a descendant of &amp;quot;parent_id&amp;quot; (ie : if element_id game element has been placed on parent_id game element).&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  if( bga.isOn( bga.getElementIfByName( &#039;Turn counter&#039; ), bga.getElementIfByName( &#039;Turn 6&#039; ) )&lt;br /&gt;
  {&lt;br /&gt;
     // Trigger game end&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Trigger most common game actions ==&lt;br /&gt;
&lt;br /&gt;
=== moveTo( id, target, path ) ===&lt;br /&gt;
&lt;br /&gt;
Move element to specified target id (eventually following path defined by an array of element ids to pass over on the way)&lt;br /&gt;
&lt;br /&gt;
The exact destination of element depends on target&#039;s &amp;quot;howToArrange&amp;quot; property (&amp;quot;How elements are arranged on it?&amp;quot; : spreaded/deck/...).&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.moveTo( bga.getElementIdByName( &#039;Turn counter&#039; ), bga.getElementIdByName( &#039;Turn 3&#039; ) );&lt;br /&gt;
&lt;br /&gt;
=== removeElement( id ) ===&lt;br /&gt;
&lt;br /&gt;
Deletes all properties from this element and remove it from play. Warning: it won&#039;t be recoverable! If you may need it later, you should move it inside a zone with visibility set to &amp;quot;Everyone, but hide what&#039;s inside&amp;quot; instead of removing it.&lt;br /&gt;
&lt;br /&gt;
=== flip( element_ids ) ===&lt;br /&gt;
&lt;br /&gt;
Flip target element (or array of elements) if the elements are flippable (ex: cards).&lt;br /&gt;
&lt;br /&gt;
=== shuffle( element_ids ) ===&lt;br /&gt;
&lt;br /&gt;
Shuffle elements contained inside the target element (or array of elements).&lt;br /&gt;
&lt;br /&gt;
=== roll( element_ids ) ===&lt;br /&gt;
&lt;br /&gt;
Roll the target element (or array of elements). Target elements must have the property &amp;quot;Can be rolled&amp;quot; set.&lt;br /&gt;
&lt;br /&gt;
=== setDie( element_ids, value ) ===&lt;br /&gt;
&lt;br /&gt;
Set the target element (or array of elements) with this value. Target elements must have the property &amp;quot;Can set value&amp;quot; set.&lt;br /&gt;
&lt;br /&gt;
=== deal( deck_id, target_tag, nbr_per_target ) ===&lt;br /&gt;
&lt;br /&gt;
Deal nbr_per_target cards from deck_id element to all elements having target_tag.&lt;br /&gt;
&lt;br /&gt;
=== incScore( color, value ) ===&lt;br /&gt;
&lt;br /&gt;
Increases the score for the player with the specified color, of the specified increment value.&lt;br /&gt;
&lt;br /&gt;
=== setScore( color, value ) ===&lt;br /&gt;
&lt;br /&gt;
Sets the score for the player with the specified color.&lt;br /&gt;
&lt;br /&gt;
=== getScore( color ) ===&lt;br /&gt;
&lt;br /&gt;
Gets the score of the player with the specified color.&lt;br /&gt;
&lt;br /&gt;
== Gamestate functions ==&lt;br /&gt;
&lt;br /&gt;
You can define your game flow with a list of states by adding a &amp;quot;states&amp;quot; function to your script.&lt;br /&gt;
&lt;br /&gt;
  function states()&lt;br /&gt;
  {&lt;br /&gt;
      return {&lt;br /&gt;
        // Init game&lt;br /&gt;
        100: {&lt;br /&gt;
            onState: &#039;postSetup&#039;,&lt;br /&gt;
            transitions: { done:200 }&lt;br /&gt;
        },&lt;br /&gt;
        200: {&lt;br /&gt;
            description: _(&#039;${actplayer} must move a piece&#039;),&lt;br /&gt;
            descriptionmyturn: _(&#039;${you} must move a piece&#039;),&lt;br /&gt;
            possibleactions: [&#039;movePiece&#039;],&lt;br /&gt;
            transitions: { nextPlayer: 200 }&lt;br /&gt;
        },&lt;br /&gt;
      };&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Then, you will be able to use the following functions to manage the game flow.&lt;br /&gt;
&lt;br /&gt;
=== checkAction( action ) ===&lt;br /&gt;
&lt;br /&gt;
Check if action is valid regarding current game state and raise an error if it&#039;s not the case.&lt;br /&gt;
&lt;br /&gt;
=== isActionPossible( action ) ===&lt;br /&gt;
&lt;br /&gt;
Check if action is valid regarding current game state and returns a boolean with the appropriate value.&lt;br /&gt;
&lt;br /&gt;
=== getActivePlayerColor() ===&lt;br /&gt;
&lt;br /&gt;
Returns the color code of the currently active player&lt;br /&gt;
&lt;br /&gt;
=== getActivePlayerName() ===&lt;br /&gt;
&lt;br /&gt;
Returns the color code of the currently active player&lt;br /&gt;
&lt;br /&gt;
=== nextPlayer() ===&lt;br /&gt;
&lt;br /&gt;
Activates the next player in play order.&lt;br /&gt;
&lt;br /&gt;
=== activeAllPlayers() ===&lt;br /&gt;
&lt;br /&gt;
Activates all players (multiactive state).&lt;br /&gt;
&lt;br /&gt;
=== endTurn( transition ) ===&lt;br /&gt;
&lt;br /&gt;
Make the current player inactive and go to the next state matching the provided transition if all players are inactive (multiactive state)&lt;br /&gt;
&lt;br /&gt;
=== getActivePlayerColors() ===&lt;br /&gt;
&lt;br /&gt;
Returns the colors code of the currently active players&lt;br /&gt;
&lt;br /&gt;
=== getCurrentPlayerColor() ===&lt;br /&gt;
&lt;br /&gt;
Returns the color code of the current player (the player who made the interface action being handled; may not be the active player).&lt;br /&gt;
&lt;br /&gt;
=== nextState( transition ) ===&lt;br /&gt;
&lt;br /&gt;
Moves to the next state matching the provided transition.&lt;br /&gt;
&lt;br /&gt;
=== gotoState( state_id ) ===&lt;br /&gt;
&lt;br /&gt;
Jumps to specified state.&lt;br /&gt;
&lt;br /&gt;
=== getPlayers() ===&lt;br /&gt;
&lt;br /&gt;
Returns an array of players with the players information.&lt;br /&gt;
&lt;br /&gt;
=== setGameProgression( progression ) ===&lt;br /&gt;
&lt;br /&gt;
Updates the game progression percentage (progression must be an integer between 0 and 100)&lt;br /&gt;
&lt;br /&gt;
=== endGame() ===&lt;br /&gt;
&lt;br /&gt;
When the end game condition is met, you can use this function to end the game (after setting the appropriate scores!)&lt;br /&gt;
&lt;br /&gt;
== Other functions ==&lt;br /&gt;
&lt;br /&gt;
=== pause( milliseconds ) ===&lt;br /&gt;
&lt;br /&gt;
Pause the client interface during a specified number of milliseconds.&lt;br /&gt;
&lt;br /&gt;
If you do not use bga.pause, all Sandbox game actions are executed immediately and synchronously.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.log( &amp;quot;1&amp;quot; );    // Will be displayed immediately on the log&lt;br /&gt;
  bga.pause( 3000 ); // pause during 3 seconds&lt;br /&gt;
  bga.log( &amp;quot;2&amp;quot; );    // Will be displayed after the 3 second on the log&lt;br /&gt;
  bga.log( &amp;quot;3&amp;quot; );    // Will be displayed right after the previous one, without delay.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Tips : if you want to execute several consecutive &amp;quot;moveTo&amp;quot;, you should &amp;quot;bga.pause&amp;quot; between them, otherwise your element will move directly to the final destination.&lt;br /&gt;
&lt;br /&gt;
=== stopEvent() ===&lt;br /&gt;
&lt;br /&gt;
Must be used to stop the event propagation if you have two clickable elements on top of one another and you want only the onclick function matching the one on top to be triggered.&lt;br /&gt;
&lt;br /&gt;
  function onClickCard( card_id, selection_ids ) {&lt;br /&gt;
      // Cancel event propagation&lt;br /&gt;
      bga.stopEvent();&lt;br /&gt;
      [... manage the event ...]&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
=== hasTag( id, tag ) ===&lt;br /&gt;
&lt;br /&gt;
Returns true if the element with this id has this tag.&lt;br /&gt;
&lt;br /&gt;
=== addTag( id, tag ) ===&lt;br /&gt;
&lt;br /&gt;
Adds this tag to the element with this id.&lt;br /&gt;
&lt;br /&gt;
=== removeTag( id, tag ) ===&lt;br /&gt;
&lt;br /&gt;
Removes this tag from the element with this id.&lt;br /&gt;
&lt;br /&gt;
=== addStyle( id, style ) ===&lt;br /&gt;
&lt;br /&gt;
Adds this style to the element with this id.&lt;br /&gt;
&lt;br /&gt;
Predefined styles are: SELECTED / LIGHT / LIGHTBACKGROUND / REDSELECTED / CLICKABLE / ROUNDED / CLICKABLE_ROUNDED&lt;br /&gt;
&lt;br /&gt;
=== removeStyle( id, style ) ===&lt;br /&gt;
&lt;br /&gt;
Removes this style from the element with this id.&lt;br /&gt;
&lt;br /&gt;
=== setProperties( props ) ===&lt;br /&gt;
&lt;br /&gt;
This function allows to directly update properties of an object, and to manage custom properties if needed (custom properties must start with prefix &amp;quot;c_&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
    // Update player labels for player zones from &amp;quot;&amp;lt;color&amp;gt; player&amp;quot; to actual player name&lt;br /&gt;
    var players = bga.getPlayers();&lt;br /&gt;
    for (var color in players) {&lt;br /&gt;
        player = players[color];&lt;br /&gt;
        &lt;br /&gt;
        var labelId = null;&lt;br /&gt;
        if (color == &#039;ff0000&#039;) labelId = bga.getElement( {name: &#039;Red player&#039;} );&lt;br /&gt;
        if (color == &#039;008000&#039;) labelId = bga.getElement( {name: &#039;Green player&#039;} );&lt;br /&gt;
        if (color == &#039;0000ff&#039;) labelId = bga.getElement( {name: &#039;Blue player&#039;} );&lt;br /&gt;
        if (color == &#039;ffa500&#039;) labelId = bga.getElement( {name: &#039;Yellow player&#039;} );&lt;br /&gt;
        &lt;br /&gt;
        var props = [];&lt;br /&gt;
        props[labelId] = {name: player.name};&lt;br /&gt;
        bga.setProperties( props );&lt;br /&gt;
    }&lt;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://sr.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=3076</id>
		<title>SandboxScripts</title>
		<link rel="alternate" type="text/html" href="https://sr.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=3076"/>
		<updated>2018-05-22T09:18:56Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Examples/Tutorials */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This is the reference of functions you can call from your Sandbox scripts.&lt;br /&gt;
&lt;br /&gt;
= Javascript =&lt;br /&gt;
&lt;br /&gt;
BGA Sandbox scripts are written in Javascript.&lt;br /&gt;
&lt;br /&gt;
Using Javascript, you can write scripts to automate moves for your Sandbox games &amp;amp; provide rules reinforcement.&lt;br /&gt;
&lt;br /&gt;
Important : in the opposite of the most common usage of Javascript, Sandbox scripts are executed &#039;&#039;&#039;on server side&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
= BGA API =&lt;br /&gt;
&lt;br /&gt;
To interact with your BGA Sandbox game, we provide you an API.&lt;br /&gt;
&lt;br /&gt;
With this API, you can get properties values of game elements from the current game situation, modify them and/or trigger the game actions (ex : move this element here, flip this card, and so on).&lt;br /&gt;
&lt;br /&gt;
= Quick start =&lt;br /&gt;
&lt;br /&gt;
== Hello World Script ==&lt;br /&gt;
&lt;br /&gt;
From Sandbox editor &amp;quot;interface view&amp;quot; tab, select an element, and access to its property (top right icon).&lt;br /&gt;
&lt;br /&gt;
Go to &amp;quot;Scripts (advanced)&amp;quot; section.&lt;br /&gt;
&lt;br /&gt;
In front of &amp;quot;When this element is clicked&amp;quot;, enter &amp;quot;onMyClick&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Close the window. Go to &amp;quot;script view&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Enter the following :&lt;br /&gt;
&lt;br /&gt;
 function onMyClick( element_id )&lt;br /&gt;
 {&lt;br /&gt;
    bga.log(&amp;quot;Hello world! You just clicked on element &amp;quot; + element_id + &amp;quot;. Congrats!&amp;quot;);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Save &amp;amp; publish your project, starts a test session, click on the previous element : your message appears in the log on the right!&lt;br /&gt;
&lt;br /&gt;
== Top useful tips ==&lt;br /&gt;
&lt;br /&gt;
* You don&#039;t have to save&amp;amp;publish from the Sandbox editor for each modification of your script : each time you save your script (control+S), the script used for all test sessions is updated. Note that the production version on BGA is of course NOT updated until you explicitly save&amp;amp;publish again your project.&lt;br /&gt;
&lt;br /&gt;
* To inspect the content of a variable, you can use bga.log() in combination with JSON.stringify(). For example :&lt;br /&gt;
&lt;br /&gt;
  bga.log( JSON.stringify( bga.getPlayers()) );&lt;br /&gt;
&lt;br /&gt;
* Alternatively to bga.log(), you can use bga.exit( &amp;quot;my message&amp;quot; ) to debug your script. With bga.exit, the script execution immediately stops and all previous game changes are cancelled, so this is very practical to try and retry an action until your script is fine.&lt;br /&gt;
&lt;br /&gt;
* We advise you to develop first a full playable version of the game without the scripts, and THEN to script it.&lt;br /&gt;
&lt;br /&gt;
* On Board Game Arena, players have come to expect fully implemented games with all rules enforced. So even if it&#039;s technically possible not to script the full game and to implement the game only partially, in most cases we&#039;ll publish only fully scripted games :)&lt;br /&gt;
&lt;br /&gt;
== Examples/Tutorials ==&lt;br /&gt;
&lt;br /&gt;
In addition to the projects you will create, you have readonly access in the sandbox to two example projects: &amp;quot;linesofaction&amp;quot; is an abstract and &amp;quot;apocalypseazcc&amp;quot; is a card game.&lt;br /&gt;
&lt;br /&gt;
These two projects are fully scripted, so you can check out the scripts and use them as examples/tutorials.&lt;br /&gt;
&lt;br /&gt;
= Functions you can use in your Sandbox scripts=&lt;br /&gt;
&lt;br /&gt;
== Debugging functions ==&lt;br /&gt;
&lt;br /&gt;
=== bga.trace( txt / obj ) ===&lt;br /&gt;
&lt;br /&gt;
Write something immediately in the BGA log (on the right of the screen).&lt;br /&gt;
&lt;br /&gt;
This is the most practical way to debug your script :)&lt;br /&gt;
&lt;br /&gt;
Important : bga.trace is for debugging purpose only and won&#039;t be displayed on production.&lt;br /&gt;
&lt;br /&gt;
Note : you can also pass an object in parameter. This will dump the content of this object in the log.&lt;br /&gt;
&lt;br /&gt;
Note : in the opposite of bga.log, bga.trace is NOT cancelled if the game action failed (after a call to bga.cancel or bga.error). This makes bga.trace very practical to debug a game action that failed, and for this reason you should probably NEVER use bga.log for debugging purpose.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  // Example : write &amp;quot;Hello world&amp;quot; in the log&lt;br /&gt;
  bga.trace( &amp;quot;Hello world&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Example : dump an associative array in the log&lt;br /&gt;
  bga.trace( { mykey: &#039;myvalue&#039;, another_key: &#039;another_value&#039; } );&lt;br /&gt;
&lt;br /&gt;
=== bga.exit( txt / obj ) ===&lt;br /&gt;
&lt;br /&gt;
Stop the script immediately, display the &amp;quot;txt&amp;quot; messages and cancel (ie : rollback) on every previous API call except bga.trace :&lt;br /&gt;
&lt;br /&gt;
ALL previous BGA api call are canceled and there will be no visible changes on the interface (ex : no moves, no visible property changes, ...). Only &amp;quot;bga.trace&amp;quot; API commands are kept so you can debug.&lt;br /&gt;
&lt;br /&gt;
bga.exit is very practical when you want to repeat a game action again and again to debug it : with a call to bga.exit at the end of your script, you make sure that your game situation will be kept unchanged after each test.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.exit( &amp;quot;My script is stopped by this call&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Example with dumping a javascript variable&lt;br /&gt;
  bga.exit( my_variable_to_dump );&lt;br /&gt;
&lt;br /&gt;
== Cancelling a game action ==&lt;br /&gt;
&lt;br /&gt;
=== bga.cancel( txt ) ===&lt;br /&gt;
&lt;br /&gt;
This is the function to use when a player is doing something against game rules.&lt;br /&gt;
&lt;br /&gt;
The text message in parameter will be displayed to this player as a &amp;quot;red message&amp;quot;, so he/she can understand the rule.&lt;br /&gt;
&lt;br /&gt;
All previous BGA api call are cancelled, and there will be no visible changes on the interface.&lt;br /&gt;
&lt;br /&gt;
   // Example :&lt;br /&gt;
   bga.cancel( _(&amp;quot;You cannot move this piece here&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
Note : most of the time, you should wrap your text inside a _() translation marker to make this string translatable.&lt;br /&gt;
&lt;br /&gt;
=== bga.error( text ) ===&lt;br /&gt;
&lt;br /&gt;
This is the function to use when some unexpected error happens in your script.&lt;br /&gt;
&lt;br /&gt;
The text message will be displayed to user, with mention &amp;quot;Unexpected error&amp;quot;. The player will be incited to fill a bug report. The purpose of the message is to help you to identify the bug.&lt;br /&gt;
&lt;br /&gt;
All previous BGA api call are cancelled, and there will be no visible changes on the interface.&lt;br /&gt;
&lt;br /&gt;
   // Example :&lt;br /&gt;
   if( card_picked === null )&lt;br /&gt;
   {&lt;br /&gt;
       bga.error( &amp;quot;Cannot find a card to pick !&amp;quot; );&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
Note : you should NEVER wrap text inside bga.error with _() translation marker, because unexpected error should not be translate (so you can eventually recognize them when reported by players in bug report).&lt;br /&gt;
&lt;br /&gt;
== Game log (history) ==&lt;br /&gt;
&lt;br /&gt;
=== bga.log( txt, (optional) args ) ===&lt;br /&gt;
&lt;br /&gt;
Write something in the BGA log on the right.&lt;br /&gt;
&lt;br /&gt;
  // Example : simple log&lt;br /&gt;
  bga.log( _(&amp;quot;A new round starts&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
You may add arguments to your log, like this :&lt;br /&gt;
&lt;br /&gt;
  // Example: log with argument to display a card name.&lt;br /&gt;
  //          In this example, variable &amp;quot;event_name&amp;quot; is specified afterwards.&lt;br /&gt;
  //          Note that using this, game translators only have to translate one &amp;quot;Event XXX is triggered&amp;quot; string for all possible events.&lt;br /&gt;
  bga.log( _(&amp;quot;Event ${event_name} is triggered&amp;quot;), {  event_name: _( &amp;quot;Armageddon&amp;quot; ) } ) );&lt;br /&gt;
&lt;br /&gt;
Note that argument &amp;quot;player_name&amp;quot; is ALWAYS pre-set with the name of the current player, so you can use it immediately.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.log( _(&amp;quot;${player_name} draw a card from the deck&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
=== bga.speechBubble( target, text, (optional) args, (optional) delay, (optional) duration, (optional) size ) ===&lt;br /&gt;
&lt;br /&gt;
Display a &amp;quot;speech bubble&amp;quot;, attached to the specified target, containing the specified text.&lt;br /&gt;
&lt;br /&gt;
You can use &amp;quot;args&amp;quot; to customize text exactly like with bga.log.&lt;br /&gt;
&lt;br /&gt;
delay : milliseconds to wait before displaying the speech bubble (default : 0).&lt;br /&gt;
duration : how long to show the speech bubble in milliseconds (default : 3000).&lt;br /&gt;
size : size of the text in percent (default: 100)&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.speechBubble( _(&amp;quot;I play ${nbr} cards&amp;quot;), { nbr : 4 }, 0 );&lt;br /&gt;
  bga.speechBubble( _(&amp;quot;Good for you!&amp;quot;), { }, 2000 );&lt;br /&gt;
&lt;br /&gt;
=== bga.displayScoring( target, color, score ) ===&lt;br /&gt;
&lt;br /&gt;
Display an animated temporary &amp;quot;score number&amp;quot;, attached to the specified target.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;color&amp;quot; should be the color of the player who is scoring for that target.&lt;br /&gt;
&lt;br /&gt;
== Get / search game elements and their properties ==&lt;br /&gt;
&lt;br /&gt;
=== bga.getElement( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Allow you to retrieve informations about one game element specified using &amp;quot;selector&amp;quot; argument.&lt;br /&gt;
&lt;br /&gt;
Return null if no element is found.&lt;br /&gt;
&lt;br /&gt;
Note : getElement throw an error if several elements matches the selector. If you want to retrieve several elements, you should use &amp;quot;getElements&amp;quot; instead of &amp;quot;getElement&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The following examples are showing all the possible use of bga.getElement :&lt;br /&gt;
&lt;br /&gt;
  // Basic example :&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve the ID of a game element using its name (&amp;quot;Deck&amp;quot;)&lt;br /&gt;
  var deck_id = bga.getElement( { name: &amp;quot;Deck&amp;quot; } );&lt;br /&gt;
  // Return : 1234  &lt;br /&gt;
&lt;br /&gt;
  // Examples using &amp;quot;field&amp;quot; parameter :&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve a specific property from a game element using its name (&amp;quot;Deck&amp;quot;)&lt;br /&gt;
  var deck_id = bga.getElement( { name: &amp;quot;Deck&amp;quot; }, &#039;x&#039; );&lt;br /&gt;
  // Return : 20&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve several properties from the previous element&lt;br /&gt;
  var deck_properties = bga.getElement( { name: &amp;quot;Deck&amp;quot; }, [&#039;name&#039;,&#039;id&#039;,&#039;parent&#039;, &#039;x&#039;,&#039;y&#039;,&#039;canShuffle&#039;] );&lt;br /&gt;
  // Return : { name:&#039;Deck&#039;, id:1234, parent:4321, x: 20, y:50, canShuffle: true }&lt;br /&gt;
  &lt;br /&gt;
  // Note : as you can see, getElement returns:&lt;br /&gt;
  //        _ the element ID by default, or&lt;br /&gt;
  //        _ a single value if you request a single field, or&lt;br /&gt;
  //        _ an object if you request several fields&lt;br /&gt;
&lt;br /&gt;
  // Examples using different &amp;quot;selector&amp;quot; paramter&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve an element name from its id&lt;br /&gt;
  var deck_name = bga.getElement( { id: 1234 }, [&#039;name&#039;] );&lt;br /&gt;
  // Return : &amp;quot;Deck&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  // Retrieve the last child element of another element&lt;br /&gt;
  // Here, we are requesting for elements who has element with ID=1234 (Deck) as their parent&lt;br /&gt;
  // Note the use of &amp;quot;limit:1&amp;quot; which allows us to retrieve only 1 element.&lt;br /&gt;
  var first_card_on_deck_id = bga.getElement( { parent: 1234, limit:1 } );&lt;br /&gt;
  &lt;br /&gt;
  // You can also get nested properties such as the ids of the child elements of one element, or a custom property placed on the parent element&lt;br /&gt;
  var totem_places = bga.getElements( {tag:&#039;TOTEMZONE&#039;}, [&#039;id&#039;,&#039;childs:id&#039;,&#039;childs:tags&#039;,&#039;parent:id&#039;,&#039;parent:c_value&#039;] );&lt;br /&gt;
&lt;br /&gt;
=== bga.getElements( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Returns an object holding the properties of the elements matching the selector.&lt;br /&gt;
&lt;br /&gt;
  // Basic example: unselect all selected elements&lt;br /&gt;
  bga.removeStyle( bga.getElements( {tag: &#039;sbstyle_selected&#039;}), &#039;selected&#039; );&lt;br /&gt;
&lt;br /&gt;
=== bga.getElementsArray( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Returns an array of all elements matching the selector, holding the required properties.&lt;br /&gt;
&lt;br /&gt;
  // Basic example: get id of selected element&lt;br /&gt;
  var selected_tokens = bga.getElementsArray( {tag: &#039;sbstyle_selected&#039; } );&lt;br /&gt;
  var token_id = null;&lt;br /&gt;
  if (selected_tokens.length &amp;gt; 0) {&lt;br /&gt;
      token_id = selected_tokens[0];&lt;br /&gt;
  }&lt;br /&gt;
  return token_id;&lt;br /&gt;
&lt;br /&gt;
  // Classic example: get array of elements and iterate over it&lt;br /&gt;
  var all_cells = bga.getElementsArray( {tag: &#039;CELL&#039;}, [&#039;id&#039;,&#039;name&#039;,&#039;tags&#039;] );&lt;br /&gt;
  for (var i=0; i&amp;lt;all_cells.length; i++) {&lt;br /&gt;
     // ... process each cell ...&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Utility methods ==&lt;br /&gt;
&lt;br /&gt;
=== bga.isOn( element_id, parent_id ) ===&lt;br /&gt;
&lt;br /&gt;
Return true if &amp;quot;element_id&amp;quot; is a descendant of &amp;quot;parent_id&amp;quot; (ie : if element_id game element has been placed on parent_id game element).&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  if( bga.isOn( bga.getElementIfByName( &#039;Turn counter&#039; ), bga.getElementIfByName( &#039;Turn 6&#039; ) )&lt;br /&gt;
  {&lt;br /&gt;
     // Trigger game end&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Trigger most common game actions ==&lt;br /&gt;
&lt;br /&gt;
=== moveTo( id, target, path ) ===&lt;br /&gt;
&lt;br /&gt;
Move element to specified target id (eventually following path defined by an array of element ids to pass over on the way)&lt;br /&gt;
&lt;br /&gt;
The exact destination of element depends on target&#039;s &amp;quot;howToArrange&amp;quot; property (&amp;quot;How elements are arranged on it?&amp;quot; : spreaded/deck/...).&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.moveTo( bga.getElementIdByName( &#039;Turn counter&#039; ), bga.getElementIdByName( &#039;Turn 3&#039; ) );&lt;br /&gt;
&lt;br /&gt;
=== removeElement( id ) ===&lt;br /&gt;
&lt;br /&gt;
Deletes all properties from this element and remove it from play. Warning: it won&#039;t be recoverable! If you may need it later, you should move it inside a zone with visibility set to &amp;quot;Everyone, but hide what&#039;s inside&amp;quot; instead of removing it.&lt;br /&gt;
&lt;br /&gt;
=== flip( element_ids ) ===&lt;br /&gt;
&lt;br /&gt;
Flip target element (or array of elements) if the elements are flippable (ex: cards).&lt;br /&gt;
&lt;br /&gt;
=== shuffle( element_ids ) ===&lt;br /&gt;
&lt;br /&gt;
Shuffle elements contained inside this element (or array of elements).&lt;br /&gt;
&lt;br /&gt;
=== deal( deck_id, target_tag, nbr_per_target ) ===&lt;br /&gt;
&lt;br /&gt;
Deal nbr_per_target cards from deck_id element to all elements having target_tag.&lt;br /&gt;
&lt;br /&gt;
=== incScore( color, value ) ===&lt;br /&gt;
&lt;br /&gt;
Increases the score for the player with the specified color, of the specified increment value.&lt;br /&gt;
&lt;br /&gt;
=== setScore( color, value ) ===&lt;br /&gt;
&lt;br /&gt;
Sets the score for the player with the specified color.&lt;br /&gt;
&lt;br /&gt;
=== getScore( color ) ===&lt;br /&gt;
&lt;br /&gt;
Gets the score of the player with the specified color.&lt;br /&gt;
&lt;br /&gt;
== Gamestate functions ==&lt;br /&gt;
&lt;br /&gt;
You can define your game flow with a list of states by adding a &amp;quot;states&amp;quot; function to your script.&lt;br /&gt;
&lt;br /&gt;
  function states()&lt;br /&gt;
  {&lt;br /&gt;
      return {&lt;br /&gt;
        // Init game&lt;br /&gt;
        100: {&lt;br /&gt;
            onState: &#039;postSetup&#039;,&lt;br /&gt;
            transitions: { done:200 }&lt;br /&gt;
        },&lt;br /&gt;
        200: {&lt;br /&gt;
            description: _(&#039;${actplayer} must move a piece&#039;),&lt;br /&gt;
            descriptionmyturn: _(&#039;${you} must move a piece&#039;),&lt;br /&gt;
            possibleactions: [&#039;movePiece&#039;],&lt;br /&gt;
            transitions: { nextPlayer: 200 }&lt;br /&gt;
        },&lt;br /&gt;
      };&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Then, you will be able to use the following functions to manage the game flow.&lt;br /&gt;
&lt;br /&gt;
=== checkAction( action ) ===&lt;br /&gt;
&lt;br /&gt;
Check if action is valid regarding current game state and raise an error if it&#039;s not the case.&lt;br /&gt;
&lt;br /&gt;
=== isActionPossible( action ) ===&lt;br /&gt;
&lt;br /&gt;
Check if action is valid regarding current game state and returns a boolean with the appropriate value.&lt;br /&gt;
&lt;br /&gt;
=== getActivePlayerColor() ===&lt;br /&gt;
&lt;br /&gt;
Returns the color code of the currently active player&lt;br /&gt;
&lt;br /&gt;
=== getActivePlayerName() ===&lt;br /&gt;
&lt;br /&gt;
Returns the color code of the currently active player&lt;br /&gt;
&lt;br /&gt;
=== nextPlayer() ===&lt;br /&gt;
&lt;br /&gt;
Activates the next player in play order.&lt;br /&gt;
&lt;br /&gt;
=== activeAllPlayers() ===&lt;br /&gt;
&lt;br /&gt;
Activates all players (multiactive state).&lt;br /&gt;
&lt;br /&gt;
=== endTurn( transition ) ===&lt;br /&gt;
&lt;br /&gt;
Make the current player inactive and go to the next state matching the provided transition if all players are inactive (multiactive state)&lt;br /&gt;
&lt;br /&gt;
=== getActivePlayerColors() ===&lt;br /&gt;
&lt;br /&gt;
Returns the colors code of the currently active players&lt;br /&gt;
&lt;br /&gt;
=== getCurrentPlayerColor() ===&lt;br /&gt;
&lt;br /&gt;
Returns the color code of the current player (the player who made the interface action being handled; may not be the active player).&lt;br /&gt;
&lt;br /&gt;
=== nextState( transition ) ===&lt;br /&gt;
&lt;br /&gt;
Moves to the next state matching the provided transition.&lt;br /&gt;
&lt;br /&gt;
=== gotoState( state_id ) ===&lt;br /&gt;
&lt;br /&gt;
Jumps to specified state.&lt;br /&gt;
&lt;br /&gt;
=== getPlayers() ===&lt;br /&gt;
&lt;br /&gt;
Returns an array of players with the players information.&lt;br /&gt;
&lt;br /&gt;
=== setGameProgression( progression ) ===&lt;br /&gt;
&lt;br /&gt;
Updates the game progression percentage (progression must be an integer between 0 and 100)&lt;br /&gt;
&lt;br /&gt;
=== endGame() ===&lt;br /&gt;
&lt;br /&gt;
When the end game condition is met, you can use this function to end the game (after setting the appropriate scores!)&lt;br /&gt;
&lt;br /&gt;
== Other functions ==&lt;br /&gt;
&lt;br /&gt;
=== pause( milliseconds ) ===&lt;br /&gt;
&lt;br /&gt;
Pause the client interface during a specified number of milliseconds.&lt;br /&gt;
&lt;br /&gt;
If you do not use bga.pause, all Sandbox game actions are executed immediately and synchronously.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.log( &amp;quot;1&amp;quot; );    // Will be displayed immediately on the log&lt;br /&gt;
  bga.pause( 3000 ); // pause during 3 seconds&lt;br /&gt;
  bga.log( &amp;quot;2&amp;quot; );    // Will be displayed after the 3 second on the log&lt;br /&gt;
  bga.log( &amp;quot;3&amp;quot; );    // Will be displayed right after the previous one, without delay.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Tips : if you want to execute several consecutive &amp;quot;moveTo&amp;quot;, you should &amp;quot;bga.pause&amp;quot; between them, otherwise your element will move directly to the final destination.&lt;br /&gt;
&lt;br /&gt;
=== stopEvent() ===&lt;br /&gt;
&lt;br /&gt;
Must be used to stop the event propagation if you have two clickable elements on top of one another and you want only the onclick function matching the one on top to be triggered.&lt;br /&gt;
&lt;br /&gt;
  function onClickCard( card_id, selection_ids ) {&lt;br /&gt;
      // Cancel event propagation&lt;br /&gt;
      bga.stopEvent();&lt;br /&gt;
      [... manage the event ...]&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
=== hasTag( id, tag ) ===&lt;br /&gt;
&lt;br /&gt;
Returns true if the element with this id has this tag.&lt;br /&gt;
&lt;br /&gt;
=== addTag( id, tag ) ===&lt;br /&gt;
&lt;br /&gt;
Adds this tag to the element with this id.&lt;br /&gt;
&lt;br /&gt;
=== removeTag( id, tag ) ===&lt;br /&gt;
&lt;br /&gt;
Removes this tag from the element with this id.&lt;br /&gt;
&lt;br /&gt;
=== addStyle( id, style ) ===&lt;br /&gt;
&lt;br /&gt;
Adds this style to the element with this id.&lt;br /&gt;
&lt;br /&gt;
Predefined styles are: SELECTED / LIGHT / LIGHTBACKGROUND / REDSELECTED / CLICKABLE / ROUNDED / CLICKABLE_ROUNDED&lt;br /&gt;
&lt;br /&gt;
=== removeStyle( id, style ) ===&lt;br /&gt;
&lt;br /&gt;
Removes this style from the element with this id.&lt;br /&gt;
&lt;br /&gt;
=== setProperties( props ) ===&lt;br /&gt;
&lt;br /&gt;
This function allows to directly update properties of an object, and to manage custom properties if needed (custom properties must start with prefix &amp;quot;c_&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
    // Update player labels for player zones from &amp;quot;&amp;lt;color&amp;gt; player&amp;quot; to actual player name&lt;br /&gt;
    var players = bga.getPlayers();&lt;br /&gt;
    for (var color in players) {&lt;br /&gt;
        player = players[color];&lt;br /&gt;
        &lt;br /&gt;
        var labelId = null;&lt;br /&gt;
        if (color == &#039;ff0000&#039;) labelId = bga.getElement( {name: &#039;Red player&#039;} );&lt;br /&gt;
        if (color == &#039;008000&#039;) labelId = bga.getElement( {name: &#039;Green player&#039;} );&lt;br /&gt;
        if (color == &#039;0000ff&#039;) labelId = bga.getElement( {name: &#039;Blue player&#039;} );&lt;br /&gt;
        if (color == &#039;ffa500&#039;) labelId = bga.getElement( {name: &#039;Yellow player&#039;} );&lt;br /&gt;
        &lt;br /&gt;
        var props = [];&lt;br /&gt;
        props[labelId] = {name: player.name};&lt;br /&gt;
        bga.setProperties( props );&lt;br /&gt;
    }&lt;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://sr.doc.boardgamearena.com/index.php?title=BGA_Code_Sharing&amp;diff=3069</id>
		<title>BGA Code Sharing</title>
		<link rel="alternate" type="text/html" href="https://sr.doc.boardgamearena.com/index.php?title=BGA_Code_Sharing&amp;diff=3069"/>
		<updated>2018-05-21T16:41:47Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Projects hosted not in studio */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is for listing of externally hosted bga projects, tools and resources, as well as internal project&lt;br /&gt;
intended for sharing&lt;br /&gt;
&lt;br /&gt;
== Projects hosted not in studio ==&lt;br /&gt;
&lt;br /&gt;
See the table a link and nickname of the developer on bga (same as used for dev forum), and short description&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important notice about artwork on BGA Open Source projects: original hi-resolution images from publishers must not be published on the repositories. In addition, it is better to specify that the images derivated from publishers artwork are copyrighted and cannot be licensed under a free license like Creative Commons.&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! NAME&lt;br /&gt;
! CODE LINK&lt;br /&gt;
! DEVELOPER&lt;br /&gt;
|-&lt;br /&gt;
| Shared Code (not a game)&lt;br /&gt;
| https://github.com/elaskavaia/bga-sharedcode&lt;br /&gt;
| Victoria_La&lt;br /&gt;
|-&lt;br /&gt;
| BoardGameArena Workbench (not a game)&lt;br /&gt;
| https://github.com/danielholmes/bga-workbench&lt;br /&gt;
| Daniel Holmes (dhau)&lt;br /&gt;
|-&lt;br /&gt;
| Eruption&lt;br /&gt;
| https://github.com/AndyKerrison/bga-eruption&lt;br /&gt;
| Andy_K&lt;br /&gt;
|-&lt;br /&gt;
| Nile&lt;br /&gt;
| https://github.com/AndyKerrison/bga-nile&lt;br /&gt;
| Andy_K&lt;br /&gt;
|-&lt;br /&gt;
| Assyria &lt;br /&gt;
| https://github.com/sebastien-prudhomme/bga-assyria&lt;br /&gt;
| daikinee &lt;br /&gt;
|-&lt;br /&gt;
| Florenza: The Card Game&lt;br /&gt;
| https://github.com/alberto-bottarini/bga-florenza&lt;br /&gt;
| tarini &lt;br /&gt;
|-&lt;br /&gt;
| Incan Gold&lt;br /&gt;
| https://github.com/AntonioSoler/bga-incangold&lt;br /&gt;
| Morgalad &lt;br /&gt;
|-&lt;br /&gt;
| Marco Polo&lt;br /&gt;
| https://github.com/rcitaliano/MarcoPolo&lt;br /&gt;
| rcitaliano&lt;br /&gt;
|-&lt;br /&gt;
| Bonbons&lt;br /&gt;
| https://github.com/AntonioSoler/bga-bonbons&lt;br /&gt;
| Morgalad &lt;br /&gt;
|-&lt;br /&gt;
| Takara Island&lt;br /&gt;
| https://github.com/AntonioSoler/bga-takaraisland&lt;br /&gt;
| Morgalad&lt;br /&gt;
|-&lt;br /&gt;
| Noir: Killer vs Inspector&lt;br /&gt;
| https://bitbucket.org/chhuang76/bga_noirkvi&lt;br /&gt;
| ch huang&lt;br /&gt;
|-&lt;br /&gt;
| Hearts (Tutorial)&lt;br /&gt;
| https://github.com/elaskavaia/bga-heartsla&lt;br /&gt;
| Victoria_La&lt;br /&gt;
|-&lt;br /&gt;
| The Battle for Hill 218&lt;br /&gt;
| https://github.com/danielholmes/battle-for-hill-218&lt;br /&gt;
| Daniel Holmes (dhau)&lt;br /&gt;
|-&lt;br /&gt;
| Coup: City State&lt;br /&gt;
| https://github.com/quietmint/bga-coupcitystate&lt;br /&gt;
| quietmint&lt;br /&gt;
|-&lt;br /&gt;
| Tablut&lt;br /&gt;
| https://github.com/Lucas-C/tablut&lt;br /&gt;
| Lucas-C &amp;amp; ntaffore&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Projects on studio ==&lt;br /&gt;
&lt;br /&gt;
Links to studio project which owner wish share as read only.&lt;br /&gt;
Project owner please add you project here, dev nickname and short description if you would like to share it.&lt;br /&gt;
For the projects below any developer can add themselves to a project as read-only from http://en.studio.boardgamearena.com/#!projects page.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! NAME&lt;br /&gt;
! CODE LINK&lt;br /&gt;
! DEVELOPER&lt;br /&gt;
|-&lt;br /&gt;
| Shared Code&lt;br /&gt;
| http://en.studio.boardgamearena.com/#!studiogame?game=sharedcode&lt;br /&gt;
| Victoria_La&lt;br /&gt;
|-&lt;br /&gt;
| Original BGA template&lt;br /&gt;
| http://en.studio.boardgamearena.com/#!studiogame?game=template&lt;br /&gt;
| Victoria_La&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Other useful resources ==&lt;br /&gt;
&lt;br /&gt;
* Archive of tutorial projects https://www.dropbox.com/s/rsd5r4v49xudpp0/Studio.zip?dl=0&lt;br /&gt;
** Note: Hearts project is corrupted there, use Hearts tutorial project above&lt;br /&gt;
* Website with bunch of textures and sounds http://www.grsites.com/archive/textures/&lt;br /&gt;
* Shrink images without loss of quality https://tinypng.com/ or http://www.iloveimg.com/ (recommended by Gregory Isabelli)&lt;br /&gt;
* CSS shapes https://css-tricks.com/examples/ShapesOfCSS/&lt;br /&gt;
* PDF Scraper - extract images - http://www.extractpdf.com/&lt;br /&gt;
* BoardGameArena Workbench - set of tools to help test and deploy BGA projects - https://github.com/danielholmes/bga-workbench&lt;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://sr.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=3058</id>
		<title>SandboxScripts</title>
		<link rel="alternate" type="text/html" href="https://sr.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=3058"/>
		<updated>2018-05-18T16:00:55Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Quick start */ Examples&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This is the reference of functions you can call from your Sandbox scripts.&lt;br /&gt;
&lt;br /&gt;
= Javascript =&lt;br /&gt;
&lt;br /&gt;
BGA Sandbox scripts are written in Javascript.&lt;br /&gt;
&lt;br /&gt;
Using Javascript, you can write scripts to automate moves for your Sandbox games &amp;amp; provide rules reinforcement.&lt;br /&gt;
&lt;br /&gt;
Important : in the opposite of the most common usage of Javascript, Sandbox scripts are executed &#039;&#039;&#039;on server side&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
= BGA API =&lt;br /&gt;
&lt;br /&gt;
To interact with your BGA Sandbox game, we provide you an API.&lt;br /&gt;
&lt;br /&gt;
With this API, you can get properties values of game elements from the current game situation, modify them and/or trigger the game actions (ex : move this element here, flip this card, and so on).&lt;br /&gt;
&lt;br /&gt;
= Quick start =&lt;br /&gt;
&lt;br /&gt;
== Hello World Script ==&lt;br /&gt;
&lt;br /&gt;
From Sandbox editor &amp;quot;interface view&amp;quot; tab, select an element, and access to its property (top right icon).&lt;br /&gt;
&lt;br /&gt;
Go to &amp;quot;Scripts (advanced)&amp;quot; section.&lt;br /&gt;
&lt;br /&gt;
In front of &amp;quot;When this element is clicked&amp;quot;, enter &amp;quot;onMyClick&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Close the window. Go to &amp;quot;script view&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Enter the following :&lt;br /&gt;
&lt;br /&gt;
 function onMyClick( element_id )&lt;br /&gt;
 {&lt;br /&gt;
    bga.log(&amp;quot;Hello world! You just clicked on element &amp;quot; + element_id + &amp;quot;. Congrats!&amp;quot;);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Save &amp;amp; publish your project, starts a test session, click on the previous element : your message appears in the log on the right!&lt;br /&gt;
&lt;br /&gt;
== Top useful tips ==&lt;br /&gt;
&lt;br /&gt;
* You don&#039;t have to save&amp;amp;publish from the Sandbox editor for each modification of your script : each time you save your script (control+S), the script used for all test sessions is updated. Note that the production version on BGA is of course NOT updated until you explicitly save&amp;amp;publish again your project.&lt;br /&gt;
&lt;br /&gt;
* To inspect the content of a variable, you can use bga.log() in combination with JSON.stringify(). For example :&lt;br /&gt;
&lt;br /&gt;
  bga.log( JSON.stringify( bga.getPlayers()) );&lt;br /&gt;
&lt;br /&gt;
* Alternatively to bga.log(), you can use bga.exit( &amp;quot;my message&amp;quot; ) to debug your script. With bga.exit, the script execution immediately stops and all previous game changes are cancelled, so this is very practical to try and retry an action until your script is fine.&lt;br /&gt;
&lt;br /&gt;
* We advise you to develop first a full playable version of the game without the scripts, and THEN to script it.&lt;br /&gt;
&lt;br /&gt;
* On Board Game Arena, players have come to expect fully implemented games with all rules enforced. So even if it&#039;s technically possible not to script the full game and to implement the game only partially, in most cases we&#039;ll publish only fully scripted games :)&lt;br /&gt;
&lt;br /&gt;
== Examples/Tutorials ==&lt;br /&gt;
&lt;br /&gt;
In addition to the projects you will create, you have readonly access in the sandbox to two example projects (one is an abstract, the other one is a card game).&lt;br /&gt;
&lt;br /&gt;
These two projects are fully scripted, so you can check out the scripts and use them as examples/tutorials.&lt;br /&gt;
&lt;br /&gt;
= Functions you can use in your Sandbox scripts=&lt;br /&gt;
&lt;br /&gt;
== Debugging functions ==&lt;br /&gt;
&lt;br /&gt;
=== bga.trace( txt / obj ) ===&lt;br /&gt;
&lt;br /&gt;
Write something immediately in the BGA log (on the right of the screen).&lt;br /&gt;
&lt;br /&gt;
This is the most practical way to debug your script :)&lt;br /&gt;
&lt;br /&gt;
Important : bga.trace is for debugging purpose only and won&#039;t be displayed on production.&lt;br /&gt;
&lt;br /&gt;
Note : you can also pass an object in parameter. This will dump the content of this object in the log.&lt;br /&gt;
&lt;br /&gt;
Note : in the opposite of bga.log, bga.trace is NOT cancelled if the game action failed (after a call to bga.cancel or bga.error). This makes bga.trace very practical to debug a game action that failed, and for this reason you should probably NEVER use bga.log for debugging purpose.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  // Example : write &amp;quot;Hello world&amp;quot; in the log&lt;br /&gt;
  bga.trace( &amp;quot;Hello world&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Example : dump an associative array in the log&lt;br /&gt;
  bga.trace( { mykey: &#039;myvalue&#039;, another_key: &#039;another_value&#039; } );&lt;br /&gt;
&lt;br /&gt;
=== bga.exit( txt / obj ) ===&lt;br /&gt;
&lt;br /&gt;
Stop the script immediately, display the &amp;quot;txt&amp;quot; messages and cancel (ie : rollback) on every previous API call except bga.trace :&lt;br /&gt;
&lt;br /&gt;
ALL previous BGA api call are canceled and there will be no visible changes on the interface (ex : no moves, no visible property changes, ...). Only &amp;quot;bga.trace&amp;quot; API commands are kept so you can debug.&lt;br /&gt;
&lt;br /&gt;
bga.exit is very practical when you want to repeat a game action again and again to debug it : with a call to bga.exit at the end of your script, you make sure that your game situation will be kept unchanged after each test.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.exit( &amp;quot;My script is stopped by this call&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Example with dumping a javascript variable&lt;br /&gt;
  bga.exit( my_variable_to_dump );&lt;br /&gt;
&lt;br /&gt;
== Cancelling a game action ==&lt;br /&gt;
&lt;br /&gt;
=== bga.cancel( txt ) ===&lt;br /&gt;
&lt;br /&gt;
This is the function to use when a player is doing something against game rules.&lt;br /&gt;
&lt;br /&gt;
The text message in parameter will be displayed to this player as a &amp;quot;red message&amp;quot;, so he/she can understand the rule.&lt;br /&gt;
&lt;br /&gt;
All previous BGA api call are cancelled, and there will be no visible changes on the interface.&lt;br /&gt;
&lt;br /&gt;
   // Example :&lt;br /&gt;
   bga.cancel( _(&amp;quot;You cannot move this piece here&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
Note : most of the time, you should wrap your text inside a _() translation marker to make this string translatable.&lt;br /&gt;
&lt;br /&gt;
=== bga.error( text ) ===&lt;br /&gt;
&lt;br /&gt;
This is the function to use when some unexpected error happens in your script.&lt;br /&gt;
&lt;br /&gt;
The text message will be displayed to user, with mention &amp;quot;Unexpected error&amp;quot;. The player will be incited to fill a bug report. The purpose of the message is to help you to identify the bug.&lt;br /&gt;
&lt;br /&gt;
All previous BGA api call are cancelled, and there will be no visible changes on the interface.&lt;br /&gt;
&lt;br /&gt;
   // Example :&lt;br /&gt;
   if( card_picked === null )&lt;br /&gt;
   {&lt;br /&gt;
       bga.error( &amp;quot;Cannot find a card to pick !&amp;quot; );&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
Note : you should NEVER wrap text inside bga.error with _() translation marker, because unexpected error should not be translate (so you can eventually recognize them when reported by players in bug report).&lt;br /&gt;
&lt;br /&gt;
== Game log (history) ==&lt;br /&gt;
&lt;br /&gt;
=== bga.log( txt, (optional) args ) ===&lt;br /&gt;
&lt;br /&gt;
Write something in the BGA log on the right.&lt;br /&gt;
&lt;br /&gt;
  // Example : simple log&lt;br /&gt;
  bga.log( _(&amp;quot;A new round starts&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
You may add arguments to your log, like this :&lt;br /&gt;
&lt;br /&gt;
  // Example: log with argument to display a card name.&lt;br /&gt;
  //          In this example, variable &amp;quot;event_name&amp;quot; is specified afterwards.&lt;br /&gt;
  //          Note that using this, game translators only have to translate one &amp;quot;Event XXX is triggered&amp;quot; string for all possible events.&lt;br /&gt;
  bga.log( _(&amp;quot;Event ${event_name} is triggered&amp;quot;), {  event_name: _( &amp;quot;Armageddon&amp;quot; ) } ) );&lt;br /&gt;
&lt;br /&gt;
Note that argument &amp;quot;player_name&amp;quot; is ALWAYS pre-set with the name of the current player, so you can use it immediately.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.log( _(&amp;quot;${player_name} draw a card from the deck&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
=== bga.speechBubble( target, text, (optional) args, (optional) delay, (optional) duration, (optional) size ) ===&lt;br /&gt;
&lt;br /&gt;
Display a &amp;quot;speech bubble&amp;quot;, attached to the specified target, containing the specified text.&lt;br /&gt;
&lt;br /&gt;
You can use &amp;quot;args&amp;quot; to customize text exactly like with bga.log.&lt;br /&gt;
&lt;br /&gt;
delay : milliseconds to wait before displaying the speech bubble (default : 0).&lt;br /&gt;
duration : how long to show the speech bubble in milliseconds (default : 3000).&lt;br /&gt;
size : size of the text in percent (default: 100)&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.speechBubble( _(&amp;quot;I play ${nbr} cards&amp;quot;), { nbr : 4 }, 0 );&lt;br /&gt;
  bga.speechBubble( _(&amp;quot;Good for you!&amp;quot;), { }, 2000 );&lt;br /&gt;
&lt;br /&gt;
=== bga.displayScoring( target, color, score ) ===&lt;br /&gt;
&lt;br /&gt;
Display an animated temporary &amp;quot;score number&amp;quot;, attached to the specified target.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;color&amp;quot; should be the color of the player who is scoring for that target.&lt;br /&gt;
&lt;br /&gt;
== Get / search game elements and their properties ==&lt;br /&gt;
&lt;br /&gt;
=== bga.getElement( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Allow you to retrieve informations about one game element specified using &amp;quot;selector&amp;quot; argument.&lt;br /&gt;
&lt;br /&gt;
Return null if no element is found.&lt;br /&gt;
&lt;br /&gt;
Note : getElement throw an error if several elements matches the selector. If you want to retrieve several elements, you should use &amp;quot;getElements&amp;quot; instead of &amp;quot;getElement&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The following examples are showing all the possible use of bga.getElement :&lt;br /&gt;
&lt;br /&gt;
  // Basic example :&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve the ID of a game element using its name (&amp;quot;Deck&amp;quot;)&lt;br /&gt;
  var deck_id = bga.getElement( { name: &amp;quot;Deck&amp;quot; } );&lt;br /&gt;
  // Return : 1234  &lt;br /&gt;
&lt;br /&gt;
  // Examples using &amp;quot;field&amp;quot; parameter :&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve a specific property from a game element using its name (&amp;quot;Deck&amp;quot;)&lt;br /&gt;
  var deck_id = bga.getElement( { name: &amp;quot;Deck&amp;quot; }, &#039;x&#039; );&lt;br /&gt;
  // Return : 20&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve several properties from the previous element&lt;br /&gt;
  var deck_properties = bga.getElement( { name: &amp;quot;Deck&amp;quot; }, [&#039;name&#039;,&#039;id&#039;,&#039;parent&#039;, &#039;x&#039;,&#039;y&#039;,&#039;canShuffle&#039;] );&lt;br /&gt;
  // Return : { name:&#039;Deck&#039;, id:1234, parent:4321, x: 20, y:50, canShuffle: true }&lt;br /&gt;
  &lt;br /&gt;
  // Note : as you can see, getElement returns:&lt;br /&gt;
  //        _ the element ID by default, or&lt;br /&gt;
  //        _ a single value if you request a single field, or&lt;br /&gt;
  //        _ an object if you request several fields&lt;br /&gt;
&lt;br /&gt;
  // Examples using different &amp;quot;selector&amp;quot; paramter&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve an element name from its id&lt;br /&gt;
  var deck_name = bga.getElement( { id: 1234 }, [&#039;name&#039;] );&lt;br /&gt;
  // Return : &amp;quot;Deck&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  // Retrieve the last child element of another element&lt;br /&gt;
  // Here, we are requesting for elements who has element with ID=1234 (Deck) as their parent&lt;br /&gt;
  // Note the use of &amp;quot;limit:1&amp;quot; which allows us to retrieve only 1 element.&lt;br /&gt;
  var first_card_on_deck_id = bga.getElement( { parent: 1234, limit:1 } );&lt;br /&gt;
  &lt;br /&gt;
  // You can also get nested properties such as the ids of the child elements of one element, or a custom property placed on the parent element&lt;br /&gt;
  var totem_places = bga.getElements( {tag:&#039;TOTEMZONE&#039;}, [&#039;id&#039;,&#039;childs:id&#039;,&#039;childs:tags&#039;,&#039;parent:id&#039;,&#039;parent:c_value&#039;] );&lt;br /&gt;
&lt;br /&gt;
=== bga.getElements( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Returns an object holding the properties of the elements matching the selector.&lt;br /&gt;
&lt;br /&gt;
  // Basic example: unselect all selected elements&lt;br /&gt;
  bga.removeStyle( bga.getElements( {tag: &#039;sbstyle_selected&#039;}), &#039;selected&#039; );&lt;br /&gt;
&lt;br /&gt;
=== bga.getElementsArray( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Returns an array of all elements matching the selector, holding the required properties.&lt;br /&gt;
&lt;br /&gt;
  // Basic example: get id of selected element&lt;br /&gt;
  var selected_tokens = bga.getElementsArray( {tag: &#039;sbstyle_selected&#039; } );&lt;br /&gt;
  var token_id = null;&lt;br /&gt;
  if (selected_tokens.length &amp;gt; 0) {&lt;br /&gt;
      token_id = selected_tokens[0];&lt;br /&gt;
  }&lt;br /&gt;
  return token_id;&lt;br /&gt;
&lt;br /&gt;
  // Classic example: get array of elements and iterate over it&lt;br /&gt;
  var all_cells = bga.getElementsArray( {tag: &#039;CELL&#039;}, [&#039;id&#039;,&#039;name&#039;,&#039;tags&#039;] );&lt;br /&gt;
  for (var i=0; i&amp;lt;all_cells.length; i++) {&lt;br /&gt;
     // ... process each cell ...&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Utility methods ==&lt;br /&gt;
&lt;br /&gt;
=== bga.isOn( element_id, parent_id ) ===&lt;br /&gt;
&lt;br /&gt;
Return true if &amp;quot;element_id&amp;quot; is a descendant of &amp;quot;parent_id&amp;quot; (ie : if element_id game element has been placed on parent_id game element).&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  if( bga.isOn( bga.getElementIfByName( &#039;Turn counter&#039; ), bga.getElementIfByName( &#039;Turn 6&#039; ) )&lt;br /&gt;
  {&lt;br /&gt;
     // Trigger game end&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Trigger most common game actions ==&lt;br /&gt;
&lt;br /&gt;
=== moveTo( id, target, path ) ===&lt;br /&gt;
&lt;br /&gt;
Move element to specified target id (eventually following path defined by an array of element ids to pass over on the way)&lt;br /&gt;
&lt;br /&gt;
The exact destination of element depends on target&#039;s &amp;quot;howToArrange&amp;quot; property (&amp;quot;How elements are arranged on it?&amp;quot; : spreaded/deck/...).&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.moveTo( bga.getElementIdByName( &#039;Turn counter&#039; ), bga.getElementIdByName( &#039;Turn 3&#039; ) );&lt;br /&gt;
&lt;br /&gt;
=== removeElement( id ) ===&lt;br /&gt;
&lt;br /&gt;
Deletes all properties from this element and remove it from play. Warning: it won&#039;t be recoverable! If you may need it later, you should move it inside a zone with visibility set to &amp;quot;Everyone, but hide what&#039;s inside&amp;quot; instead of removing it.&lt;br /&gt;
&lt;br /&gt;
=== flip( element_ids ) ===&lt;br /&gt;
&lt;br /&gt;
Flip target element (or array of elements) if the elements are flippable (ex: cards).&lt;br /&gt;
&lt;br /&gt;
=== shuffle( element_ids ) ===&lt;br /&gt;
&lt;br /&gt;
Shuffle elements contained inside this element (or array of elements).&lt;br /&gt;
&lt;br /&gt;
=== deal( deck_id, target_tag, nbr_per_target ) ===&lt;br /&gt;
&lt;br /&gt;
Deal nbr_per_target cards from deck_id element to all elements having target_tag.&lt;br /&gt;
&lt;br /&gt;
=== incScore( color, value ) ===&lt;br /&gt;
&lt;br /&gt;
Increases the score for the player with the specified color, of the specified increment value.&lt;br /&gt;
&lt;br /&gt;
=== setScore( color, value ) ===&lt;br /&gt;
&lt;br /&gt;
Sets the score for the player with the specified color.&lt;br /&gt;
&lt;br /&gt;
=== getScore( color ) ===&lt;br /&gt;
&lt;br /&gt;
Gets the score of the player with the specified color.&lt;br /&gt;
&lt;br /&gt;
== Gamestate functions ==&lt;br /&gt;
&lt;br /&gt;
You can define your game flow with a list of states by adding a &amp;quot;states&amp;quot; function to your script.&lt;br /&gt;
&lt;br /&gt;
  function states()&lt;br /&gt;
  {&lt;br /&gt;
      return {&lt;br /&gt;
        // Init game&lt;br /&gt;
        100: {&lt;br /&gt;
            onState: &#039;postSetup&#039;,&lt;br /&gt;
            transitions: { done:200 }&lt;br /&gt;
        },&lt;br /&gt;
        200: {&lt;br /&gt;
            description: _(&#039;${actplayer} must move a piece&#039;),&lt;br /&gt;
            descriptionmyturn: _(&#039;${you} must move a piece&#039;),&lt;br /&gt;
            possibleactions: [&#039;movePiece&#039;],&lt;br /&gt;
            transitions: { nextPlayer: 200 }&lt;br /&gt;
        },&lt;br /&gt;
      };&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Then, you will be able to use the following functions to manage the game flow.&lt;br /&gt;
&lt;br /&gt;
=== checkAction( action ) ===&lt;br /&gt;
&lt;br /&gt;
Check if action is valid regarding current game state and raise an error if it&#039;s not the case.&lt;br /&gt;
&lt;br /&gt;
=== isActionPossible( action ) ===&lt;br /&gt;
&lt;br /&gt;
Check if action is valid regarding current game state and returns a boolean with the appropriate value.&lt;br /&gt;
&lt;br /&gt;
=== getActivePlayerColor() ===&lt;br /&gt;
&lt;br /&gt;
Returns the color code of the currently active player&lt;br /&gt;
&lt;br /&gt;
=== getActivePlayerName() ===&lt;br /&gt;
&lt;br /&gt;
Returns the color code of the currently active player&lt;br /&gt;
&lt;br /&gt;
=== nextPlayer() ===&lt;br /&gt;
&lt;br /&gt;
Activates the next player in play order.&lt;br /&gt;
&lt;br /&gt;
=== activeAllPlayers() ===&lt;br /&gt;
&lt;br /&gt;
Activates all players (multiactive state).&lt;br /&gt;
&lt;br /&gt;
=== endTurn( transition ) ===&lt;br /&gt;
&lt;br /&gt;
Make the current player inactive and go to the next state matching the provided transition if all players are inactive (multiactive state)&lt;br /&gt;
&lt;br /&gt;
=== getActivePlayerColors() ===&lt;br /&gt;
&lt;br /&gt;
Returns the colors code of the currently active players&lt;br /&gt;
&lt;br /&gt;
=== getCurrentPlayerColor() ===&lt;br /&gt;
&lt;br /&gt;
Returns the color code of the current player (the player who made the interface action being handled; may not be the active player).&lt;br /&gt;
&lt;br /&gt;
=== nextState( transition ) ===&lt;br /&gt;
&lt;br /&gt;
Moves to the next state matching the provided transition.&lt;br /&gt;
&lt;br /&gt;
=== gotoState( state_id ) ===&lt;br /&gt;
&lt;br /&gt;
Jumps to specified state.&lt;br /&gt;
&lt;br /&gt;
=== getPlayers() ===&lt;br /&gt;
&lt;br /&gt;
Returns an array of players with the players information.&lt;br /&gt;
&lt;br /&gt;
=== setGameProgression( progression ) ===&lt;br /&gt;
&lt;br /&gt;
Updates the game progression percentage (progression must be an integer between 0 and 100)&lt;br /&gt;
&lt;br /&gt;
=== endGame() ===&lt;br /&gt;
&lt;br /&gt;
When the end game condition is met, you can use this function to end the game (after setting the appropriate scores!)&lt;br /&gt;
&lt;br /&gt;
== Other functions ==&lt;br /&gt;
&lt;br /&gt;
=== pause( milliseconds ) ===&lt;br /&gt;
&lt;br /&gt;
Pause the client interface during a specified number of milliseconds.&lt;br /&gt;
&lt;br /&gt;
If you do not use bga.pause, all Sandbox game actions are executed immediately and synchronously.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.log( &amp;quot;1&amp;quot; );    // Will be displayed immediately on the log&lt;br /&gt;
  bga.pause( 3000 ); // pause during 3 seconds&lt;br /&gt;
  bga.log( &amp;quot;2&amp;quot; );    // Will be displayed after the 3 second on the log&lt;br /&gt;
  bga.log( &amp;quot;3&amp;quot; );    // Will be displayed right after the previous one, without delay.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Tips : if you want to execute several consecutive &amp;quot;moveTo&amp;quot;, you should &amp;quot;bga.pause&amp;quot; between them, otherwise your element will move directly to the final destination.&lt;br /&gt;
&lt;br /&gt;
=== stopEvent() ===&lt;br /&gt;
&lt;br /&gt;
Must be used to stop the event propagation if you have two clickable elements on top of one another and you want only the onclick function matching the one on top to be triggered.&lt;br /&gt;
&lt;br /&gt;
  function onClickCard( card_id, selection_ids ) {&lt;br /&gt;
      // Cancel event propagation&lt;br /&gt;
      bga.stopEvent();&lt;br /&gt;
      [... manage the event ...]&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
=== hasTag( id, tag ) ===&lt;br /&gt;
&lt;br /&gt;
Returns true if the element with this id has this tag.&lt;br /&gt;
&lt;br /&gt;
=== addTag( id, tag ) ===&lt;br /&gt;
&lt;br /&gt;
Adds this tag to the element with this id.&lt;br /&gt;
&lt;br /&gt;
=== removeTag( id, tag ) ===&lt;br /&gt;
&lt;br /&gt;
Removes this tag from the element with this id.&lt;br /&gt;
&lt;br /&gt;
=== addStyle( id, style ) ===&lt;br /&gt;
&lt;br /&gt;
Adds this style to the element with this id.&lt;br /&gt;
&lt;br /&gt;
Predefined styles are: SELECTED / LIGHT / LIGHTBACKGROUND / REDSELECTED / CLICKABLE / ROUNDED / CLICKABLE_ROUNDED&lt;br /&gt;
&lt;br /&gt;
=== removeStyle( id, style ) ===&lt;br /&gt;
&lt;br /&gt;
Removes this style from the element with this id.&lt;br /&gt;
&lt;br /&gt;
=== setProperties( props ) ===&lt;br /&gt;
&lt;br /&gt;
This function allows to directly update properties of an object, and to manage custom properties if needed (custom properties must start with prefix &amp;quot;c_&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
    // Update player labels for player zones from &amp;quot;&amp;lt;color&amp;gt; player&amp;quot; to actual player name&lt;br /&gt;
    var players = bga.getPlayers();&lt;br /&gt;
    for (var color in players) {&lt;br /&gt;
        player = players[color];&lt;br /&gt;
        &lt;br /&gt;
        var labelId = null;&lt;br /&gt;
        if (color == &#039;ff0000&#039;) labelId = bga.getElement( {name: &#039;Red player&#039;} );&lt;br /&gt;
        if (color == &#039;008000&#039;) labelId = bga.getElement( {name: &#039;Green player&#039;} );&lt;br /&gt;
        if (color == &#039;0000ff&#039;) labelId = bga.getElement( {name: &#039;Blue player&#039;} );&lt;br /&gt;
        if (color == &#039;ffa500&#039;) labelId = bga.getElement( {name: &#039;Yellow player&#039;} );&lt;br /&gt;
        &lt;br /&gt;
        var props = [];&lt;br /&gt;
        props[labelId] = {name: player.name};&lt;br /&gt;
        bga.setProperties( props );&lt;br /&gt;
    }&lt;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://sr.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=3057</id>
		<title>SandboxScripts</title>
		<link rel="alternate" type="text/html" href="https://sr.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=3057"/>
		<updated>2018-05-18T08:58:17Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Trigger most common game actions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This is the reference of functions you can call from your Sandbox scripts.&lt;br /&gt;
&lt;br /&gt;
= Javascript =&lt;br /&gt;
&lt;br /&gt;
BGA Sandbox scripts are written in Javascript.&lt;br /&gt;
&lt;br /&gt;
Using Javascript, you can write scripts to automate moves for your Sandbox games &amp;amp; provide rules reinforcement.&lt;br /&gt;
&lt;br /&gt;
Important : in the opposite of the most common usage of Javascript, Sandbox scripts are executed &#039;&#039;&#039;on server side&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
= BGA API =&lt;br /&gt;
&lt;br /&gt;
To interact with your BGA Sandbox game, we provide you an API.&lt;br /&gt;
&lt;br /&gt;
With this API, you can get properties values of game elements from the current game situation, modify them and/or trigger the game actions (ex : move this element here, flip this card, and so on).&lt;br /&gt;
&lt;br /&gt;
= Quick start =&lt;br /&gt;
&lt;br /&gt;
== Hello World Script ==&lt;br /&gt;
&lt;br /&gt;
From Sandbox editor &amp;quot;interface view&amp;quot; tab, select an element, and access to its property (top right icon).&lt;br /&gt;
&lt;br /&gt;
Go to &amp;quot;Scripts (advanced)&amp;quot; section.&lt;br /&gt;
&lt;br /&gt;
In front of &amp;quot;When this element is clicked&amp;quot;, enter &amp;quot;onMyClick&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Close the window. Go to &amp;quot;script view&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Enter the following :&lt;br /&gt;
&lt;br /&gt;
 function onMyClick( element_id )&lt;br /&gt;
 {&lt;br /&gt;
    bga.log(&amp;quot;Hello world! You just clicked on element &amp;quot; + element_id + &amp;quot;. Congrats!&amp;quot;);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Save &amp;amp; publish your project, starts a test session, click on the previous element : your message appears in the log on the right!&lt;br /&gt;
&lt;br /&gt;
== Top useful tips ==&lt;br /&gt;
&lt;br /&gt;
* You don&#039;t have to save&amp;amp;publish from the Sandbox editor for each modification of your script : each time you save your script (control+S), the script used for all test sessions is updated. Note that the production version on BGA is of course NOT updated until you explicitly save&amp;amp;publish again your project.&lt;br /&gt;
&lt;br /&gt;
* To inspect the content of a variable, you can use bga.log() in combination with JSON.stringify(). For example :&lt;br /&gt;
&lt;br /&gt;
  bga.log( JSON.stringify( bga.getPlayers()) );&lt;br /&gt;
&lt;br /&gt;
* Alternatively to bga.log(), you can use bga.exit( &amp;quot;my message&amp;quot; ) to debug your script. With bga.exit, the script execution immediately stops and all previous game changes are cancelled, so this is very practical to try and retry an action until your script is fine.&lt;br /&gt;
&lt;br /&gt;
* We advise you to develop first a full playable version of the game without the scripts, and THEN to script it.&lt;br /&gt;
&lt;br /&gt;
* On Board Game Arena, players have come to expect fully implemented games with all rules enforced. So even if it&#039;s technically possible not to script the full game and to implement the game only partially, in most cases we&#039;ll publish only fully scripted games :)&lt;br /&gt;
&lt;br /&gt;
= Functions you can use in your Sandbox scripts=&lt;br /&gt;
&lt;br /&gt;
== Debugging functions ==&lt;br /&gt;
&lt;br /&gt;
=== bga.trace( txt / obj ) ===&lt;br /&gt;
&lt;br /&gt;
Write something immediately in the BGA log (on the right of the screen).&lt;br /&gt;
&lt;br /&gt;
This is the most practical way to debug your script :)&lt;br /&gt;
&lt;br /&gt;
Important : bga.trace is for debugging purpose only and won&#039;t be displayed on production.&lt;br /&gt;
&lt;br /&gt;
Note : you can also pass an object in parameter. This will dump the content of this object in the log.&lt;br /&gt;
&lt;br /&gt;
Note : in the opposite of bga.log, bga.trace is NOT cancelled if the game action failed (after a call to bga.cancel or bga.error). This makes bga.trace very practical to debug a game action that failed, and for this reason you should probably NEVER use bga.log for debugging purpose.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  // Example : write &amp;quot;Hello world&amp;quot; in the log&lt;br /&gt;
  bga.trace( &amp;quot;Hello world&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Example : dump an associative array in the log&lt;br /&gt;
  bga.trace( { mykey: &#039;myvalue&#039;, another_key: &#039;another_value&#039; } );&lt;br /&gt;
&lt;br /&gt;
=== bga.exit( txt / obj ) ===&lt;br /&gt;
&lt;br /&gt;
Stop the script immediately, display the &amp;quot;txt&amp;quot; messages and cancel (ie : rollback) on every previous API call except bga.trace :&lt;br /&gt;
&lt;br /&gt;
ALL previous BGA api call are canceled and there will be no visible changes on the interface (ex : no moves, no visible property changes, ...). Only &amp;quot;bga.trace&amp;quot; API commands are kept so you can debug.&lt;br /&gt;
&lt;br /&gt;
bga.exit is very practical when you want to repeat a game action again and again to debug it : with a call to bga.exit at the end of your script, you make sure that your game situation will be kept unchanged after each test.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.exit( &amp;quot;My script is stopped by this call&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Example with dumping a javascript variable&lt;br /&gt;
  bga.exit( my_variable_to_dump );&lt;br /&gt;
&lt;br /&gt;
== Cancelling a game action ==&lt;br /&gt;
&lt;br /&gt;
=== bga.cancel( txt ) ===&lt;br /&gt;
&lt;br /&gt;
This is the function to use when a player is doing something against game rules.&lt;br /&gt;
&lt;br /&gt;
The text message in parameter will be displayed to this player as a &amp;quot;red message&amp;quot;, so he/she can understand the rule.&lt;br /&gt;
&lt;br /&gt;
All previous BGA api call are cancelled, and there will be no visible changes on the interface.&lt;br /&gt;
&lt;br /&gt;
   // Example :&lt;br /&gt;
   bga.cancel( _(&amp;quot;You cannot move this piece here&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
Note : most of the time, you should wrap your text inside a _() translation marker to make this string translatable.&lt;br /&gt;
&lt;br /&gt;
=== bga.error( text ) ===&lt;br /&gt;
&lt;br /&gt;
This is the function to use when some unexpected error happens in your script.&lt;br /&gt;
&lt;br /&gt;
The text message will be displayed to user, with mention &amp;quot;Unexpected error&amp;quot;. The player will be incited to fill a bug report. The purpose of the message is to help you to identify the bug.&lt;br /&gt;
&lt;br /&gt;
All previous BGA api call are cancelled, and there will be no visible changes on the interface.&lt;br /&gt;
&lt;br /&gt;
   // Example :&lt;br /&gt;
   if( card_picked === null )&lt;br /&gt;
   {&lt;br /&gt;
       bga.error( &amp;quot;Cannot find a card to pick !&amp;quot; );&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
Note : you should NEVER wrap text inside bga.error with _() translation marker, because unexpected error should not be translate (so you can eventually recognize them when reported by players in bug report).&lt;br /&gt;
&lt;br /&gt;
== Game log (history) ==&lt;br /&gt;
&lt;br /&gt;
=== bga.log( txt, (optional) args ) ===&lt;br /&gt;
&lt;br /&gt;
Write something in the BGA log on the right.&lt;br /&gt;
&lt;br /&gt;
  // Example : simple log&lt;br /&gt;
  bga.log( _(&amp;quot;A new round starts&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
You may add arguments to your log, like this :&lt;br /&gt;
&lt;br /&gt;
  // Example: log with argument to display a card name.&lt;br /&gt;
  //          In this example, variable &amp;quot;event_name&amp;quot; is specified afterwards.&lt;br /&gt;
  //          Note that using this, game translators only have to translate one &amp;quot;Event XXX is triggered&amp;quot; string for all possible events.&lt;br /&gt;
  bga.log( _(&amp;quot;Event ${event_name} is triggered&amp;quot;), {  event_name: _( &amp;quot;Armageddon&amp;quot; ) } ) );&lt;br /&gt;
&lt;br /&gt;
Note that argument &amp;quot;player_name&amp;quot; is ALWAYS pre-set with the name of the current player, so you can use it immediately.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.log( _(&amp;quot;${player_name} draw a card from the deck&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
=== bga.speechBubble( target, text, (optional) args, (optional) delay, (optional) duration, (optional) size ) ===&lt;br /&gt;
&lt;br /&gt;
Display a &amp;quot;speech bubble&amp;quot;, attached to the specified target, containing the specified text.&lt;br /&gt;
&lt;br /&gt;
You can use &amp;quot;args&amp;quot; to customize text exactly like with bga.log.&lt;br /&gt;
&lt;br /&gt;
delay : milliseconds to wait before displaying the speech bubble (default : 0).&lt;br /&gt;
duration : how long to show the speech bubble in milliseconds (default : 3000).&lt;br /&gt;
size : size of the text in percent (default: 100)&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.speechBubble( _(&amp;quot;I play ${nbr} cards&amp;quot;), { nbr : 4 }, 0 );&lt;br /&gt;
  bga.speechBubble( _(&amp;quot;Good for you!&amp;quot;), { }, 2000 );&lt;br /&gt;
&lt;br /&gt;
=== bga.displayScoring( target, color, score ) ===&lt;br /&gt;
&lt;br /&gt;
Display an animated temporary &amp;quot;score number&amp;quot;, attached to the specified target.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;color&amp;quot; should be the color of the player who is scoring for that target.&lt;br /&gt;
&lt;br /&gt;
== Get / search game elements and their properties ==&lt;br /&gt;
&lt;br /&gt;
=== bga.getElement( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Allow you to retrieve informations about one game element specified using &amp;quot;selector&amp;quot; argument.&lt;br /&gt;
&lt;br /&gt;
Return null if no element is found.&lt;br /&gt;
&lt;br /&gt;
Note : getElement throw an error if several elements matches the selector. If you want to retrieve several elements, you should use &amp;quot;getElements&amp;quot; instead of &amp;quot;getElement&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The following examples are showing all the possible use of bga.getElement :&lt;br /&gt;
&lt;br /&gt;
  // Basic example :&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve the ID of a game element using its name (&amp;quot;Deck&amp;quot;)&lt;br /&gt;
  var deck_id = bga.getElement( { name: &amp;quot;Deck&amp;quot; } );&lt;br /&gt;
  // Return : 1234  &lt;br /&gt;
&lt;br /&gt;
  // Examples using &amp;quot;field&amp;quot; parameter :&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve a specific property from a game element using its name (&amp;quot;Deck&amp;quot;)&lt;br /&gt;
  var deck_id = bga.getElement( { name: &amp;quot;Deck&amp;quot; }, &#039;x&#039; );&lt;br /&gt;
  // Return : 20&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve several properties from the previous element&lt;br /&gt;
  var deck_properties = bga.getElement( { name: &amp;quot;Deck&amp;quot; }, [&#039;name&#039;,&#039;id&#039;,&#039;parent&#039;, &#039;x&#039;,&#039;y&#039;,&#039;canShuffle&#039;] );&lt;br /&gt;
  // Return : { name:&#039;Deck&#039;, id:1234, parent:4321, x: 20, y:50, canShuffle: true }&lt;br /&gt;
  &lt;br /&gt;
  // Note : as you can see, getElement returns:&lt;br /&gt;
  //        _ the element ID by default, or&lt;br /&gt;
  //        _ a single value if you request a single field, or&lt;br /&gt;
  //        _ an object if you request several fields&lt;br /&gt;
&lt;br /&gt;
  // Examples using different &amp;quot;selector&amp;quot; paramter&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve an element name from its id&lt;br /&gt;
  var deck_name = bga.getElement( { id: 1234 }, [&#039;name&#039;] );&lt;br /&gt;
  // Return : &amp;quot;Deck&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  // Retrieve the last child element of another element&lt;br /&gt;
  // Here, we are requesting for elements who has element with ID=1234 (Deck) as their parent&lt;br /&gt;
  // Note the use of &amp;quot;limit:1&amp;quot; which allows us to retrieve only 1 element.&lt;br /&gt;
  var first_card_on_deck_id = bga.getElement( { parent: 1234, limit:1 } );&lt;br /&gt;
  &lt;br /&gt;
  // You can also get nested properties such as the ids of the child elements of one element, or a custom property placed on the parent element&lt;br /&gt;
  var totem_places = bga.getElements( {tag:&#039;TOTEMZONE&#039;}, [&#039;id&#039;,&#039;childs:id&#039;,&#039;childs:tags&#039;,&#039;parent:id&#039;,&#039;parent:c_value&#039;] );&lt;br /&gt;
&lt;br /&gt;
=== bga.getElements( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Returns an object holding the properties of the elements matching the selector.&lt;br /&gt;
&lt;br /&gt;
  // Basic example: unselect all selected elements&lt;br /&gt;
  bga.removeStyle( bga.getElements( {tag: &#039;sbstyle_selected&#039;}), &#039;selected&#039; );&lt;br /&gt;
&lt;br /&gt;
=== bga.getElementsArray( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Returns an array of all elements matching the selector, holding the required properties.&lt;br /&gt;
&lt;br /&gt;
  // Basic example: get id of selected element&lt;br /&gt;
  var selected_tokens = bga.getElementsArray( {tag: &#039;sbstyle_selected&#039; } );&lt;br /&gt;
  var token_id = null;&lt;br /&gt;
  if (selected_tokens.length &amp;gt; 0) {&lt;br /&gt;
      token_id = selected_tokens[0];&lt;br /&gt;
  }&lt;br /&gt;
  return token_id;&lt;br /&gt;
&lt;br /&gt;
  // Classic example: get array of elements and iterate over it&lt;br /&gt;
  var all_cells = bga.getElementsArray( {tag: &#039;CELL&#039;}, [&#039;id&#039;,&#039;name&#039;,&#039;tags&#039;] );&lt;br /&gt;
  for (var i=0; i&amp;lt;all_cells.length; i++) {&lt;br /&gt;
     // ... process each cell ...&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Utility methods ==&lt;br /&gt;
&lt;br /&gt;
=== bga.isOn( element_id, parent_id ) ===&lt;br /&gt;
&lt;br /&gt;
Return true if &amp;quot;element_id&amp;quot; is a descendant of &amp;quot;parent_id&amp;quot; (ie : if element_id game element has been placed on parent_id game element).&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  if( bga.isOn( bga.getElementIfByName( &#039;Turn counter&#039; ), bga.getElementIfByName( &#039;Turn 6&#039; ) )&lt;br /&gt;
  {&lt;br /&gt;
     // Trigger game end&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Trigger most common game actions ==&lt;br /&gt;
&lt;br /&gt;
=== moveTo( id, target, path ) ===&lt;br /&gt;
&lt;br /&gt;
Move element to specified target id (eventually following path defined by an array of element ids to pass over on the way)&lt;br /&gt;
&lt;br /&gt;
The exact destination of element depends on target&#039;s &amp;quot;howToArrange&amp;quot; property (&amp;quot;How elements are arranged on it?&amp;quot; : spreaded/deck/...).&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.moveTo( bga.getElementIdByName( &#039;Turn counter&#039; ), bga.getElementIdByName( &#039;Turn 3&#039; ) );&lt;br /&gt;
&lt;br /&gt;
=== removeElement( id ) ===&lt;br /&gt;
&lt;br /&gt;
Deletes all properties from this element and remove it from play. Warning: it won&#039;t be recoverable! If you may need it later, you should move it inside a zone with visibility set to &amp;quot;Everyone, but hide what&#039;s inside&amp;quot; instead of removing it.&lt;br /&gt;
&lt;br /&gt;
=== flip( element_ids ) ===&lt;br /&gt;
&lt;br /&gt;
Flip target element (or array of elements) if the elements are flippable (ex: cards).&lt;br /&gt;
&lt;br /&gt;
=== shuffle( element_ids ) ===&lt;br /&gt;
&lt;br /&gt;
Shuffle elements contained inside this element (or array of elements).&lt;br /&gt;
&lt;br /&gt;
=== deal( deck_id, target_tag, nbr_per_target ) ===&lt;br /&gt;
&lt;br /&gt;
Deal nbr_per_target cards from deck_id element to all elements having target_tag.&lt;br /&gt;
&lt;br /&gt;
=== incScore( color, value ) ===&lt;br /&gt;
&lt;br /&gt;
Increases the score for the player with the specified color, of the specified increment value.&lt;br /&gt;
&lt;br /&gt;
=== setScore( color, value ) ===&lt;br /&gt;
&lt;br /&gt;
Sets the score for the player with the specified color.&lt;br /&gt;
&lt;br /&gt;
=== getScore( color ) ===&lt;br /&gt;
&lt;br /&gt;
Gets the score of the player with the specified color.&lt;br /&gt;
&lt;br /&gt;
== Gamestate functions ==&lt;br /&gt;
&lt;br /&gt;
You can define your game flow with a list of states by adding a &amp;quot;states&amp;quot; function to your script.&lt;br /&gt;
&lt;br /&gt;
  function states()&lt;br /&gt;
  {&lt;br /&gt;
      return {&lt;br /&gt;
        // Init game&lt;br /&gt;
        100: {&lt;br /&gt;
            onState: &#039;postSetup&#039;,&lt;br /&gt;
            transitions: { done:200 }&lt;br /&gt;
        },&lt;br /&gt;
        200: {&lt;br /&gt;
            description: _(&#039;${actplayer} must move a piece&#039;),&lt;br /&gt;
            descriptionmyturn: _(&#039;${you} must move a piece&#039;),&lt;br /&gt;
            possibleactions: [&#039;movePiece&#039;],&lt;br /&gt;
            transitions: { nextPlayer: 200 }&lt;br /&gt;
        },&lt;br /&gt;
      };&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Then, you will be able to use the following functions to manage the game flow.&lt;br /&gt;
&lt;br /&gt;
=== checkAction( action ) ===&lt;br /&gt;
&lt;br /&gt;
Check if action is valid regarding current game state and raise an error if it&#039;s not the case.&lt;br /&gt;
&lt;br /&gt;
=== isActionPossible( action ) ===&lt;br /&gt;
&lt;br /&gt;
Check if action is valid regarding current game state and returns a boolean with the appropriate value.&lt;br /&gt;
&lt;br /&gt;
=== getActivePlayerColor() ===&lt;br /&gt;
&lt;br /&gt;
Returns the color code of the currently active player&lt;br /&gt;
&lt;br /&gt;
=== getActivePlayerName() ===&lt;br /&gt;
&lt;br /&gt;
Returns the color code of the currently active player&lt;br /&gt;
&lt;br /&gt;
=== nextPlayer() ===&lt;br /&gt;
&lt;br /&gt;
Activates the next player in play order.&lt;br /&gt;
&lt;br /&gt;
=== activeAllPlayers() ===&lt;br /&gt;
&lt;br /&gt;
Activates all players (multiactive state).&lt;br /&gt;
&lt;br /&gt;
=== endTurn( transition ) ===&lt;br /&gt;
&lt;br /&gt;
Make the current player inactive and go to the next state matching the provided transition if all players are inactive (multiactive state)&lt;br /&gt;
&lt;br /&gt;
=== getActivePlayerColors() ===&lt;br /&gt;
&lt;br /&gt;
Returns the colors code of the currently active players&lt;br /&gt;
&lt;br /&gt;
=== getCurrentPlayerColor() ===&lt;br /&gt;
&lt;br /&gt;
Returns the color code of the current player (the player who made the interface action being handled; may not be the active player).&lt;br /&gt;
&lt;br /&gt;
=== nextState( transition ) ===&lt;br /&gt;
&lt;br /&gt;
Moves to the next state matching the provided transition.&lt;br /&gt;
&lt;br /&gt;
=== gotoState( state_id ) ===&lt;br /&gt;
&lt;br /&gt;
Jumps to specified state.&lt;br /&gt;
&lt;br /&gt;
=== getPlayers() ===&lt;br /&gt;
&lt;br /&gt;
Returns an array of players with the players information.&lt;br /&gt;
&lt;br /&gt;
=== setGameProgression( progression ) ===&lt;br /&gt;
&lt;br /&gt;
Updates the game progression percentage (progression must be an integer between 0 and 100)&lt;br /&gt;
&lt;br /&gt;
=== endGame() ===&lt;br /&gt;
&lt;br /&gt;
When the end game condition is met, you can use this function to end the game (after setting the appropriate scores!)&lt;br /&gt;
&lt;br /&gt;
== Other functions ==&lt;br /&gt;
&lt;br /&gt;
=== pause( milliseconds ) ===&lt;br /&gt;
&lt;br /&gt;
Pause the client interface during a specified number of milliseconds.&lt;br /&gt;
&lt;br /&gt;
If you do not use bga.pause, all Sandbox game actions are executed immediately and synchronously.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.log( &amp;quot;1&amp;quot; );    // Will be displayed immediately on the log&lt;br /&gt;
  bga.pause( 3000 ); // pause during 3 seconds&lt;br /&gt;
  bga.log( &amp;quot;2&amp;quot; );    // Will be displayed after the 3 second on the log&lt;br /&gt;
  bga.log( &amp;quot;3&amp;quot; );    // Will be displayed right after the previous one, without delay.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Tips : if you want to execute several consecutive &amp;quot;moveTo&amp;quot;, you should &amp;quot;bga.pause&amp;quot; between them, otherwise your element will move directly to the final destination.&lt;br /&gt;
&lt;br /&gt;
=== stopEvent() ===&lt;br /&gt;
&lt;br /&gt;
Must be used to stop the event propagation if you have two clickable elements on top of one another and you want only the onclick function matching the one on top to be triggered.&lt;br /&gt;
&lt;br /&gt;
  function onClickCard( card_id, selection_ids ) {&lt;br /&gt;
      // Cancel event propagation&lt;br /&gt;
      bga.stopEvent();&lt;br /&gt;
      [... manage the event ...]&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
=== hasTag( id, tag ) ===&lt;br /&gt;
&lt;br /&gt;
Returns true if the element with this id has this tag.&lt;br /&gt;
&lt;br /&gt;
=== addTag( id, tag ) ===&lt;br /&gt;
&lt;br /&gt;
Adds this tag to the element with this id.&lt;br /&gt;
&lt;br /&gt;
=== removeTag( id, tag ) ===&lt;br /&gt;
&lt;br /&gt;
Removes this tag from the element with this id.&lt;br /&gt;
&lt;br /&gt;
=== addStyle( id, style ) ===&lt;br /&gt;
&lt;br /&gt;
Adds this style to the element with this id.&lt;br /&gt;
&lt;br /&gt;
Predefined styles are: SELECTED / LIGHT / LIGHTBACKGROUND / REDSELECTED / CLICKABLE / ROUNDED / CLICKABLE_ROUNDED&lt;br /&gt;
&lt;br /&gt;
=== removeStyle( id, style ) ===&lt;br /&gt;
&lt;br /&gt;
Removes this style from the element with this id.&lt;br /&gt;
&lt;br /&gt;
=== setProperties( props ) ===&lt;br /&gt;
&lt;br /&gt;
This function allows to directly update properties of an object, and to manage custom properties if needed (custom properties must start with prefix &amp;quot;c_&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
    // Update player labels for player zones from &amp;quot;&amp;lt;color&amp;gt; player&amp;quot; to actual player name&lt;br /&gt;
    var players = bga.getPlayers();&lt;br /&gt;
    for (var color in players) {&lt;br /&gt;
        player = players[color];&lt;br /&gt;
        &lt;br /&gt;
        var labelId = null;&lt;br /&gt;
        if (color == &#039;ff0000&#039;) labelId = bga.getElement( {name: &#039;Red player&#039;} );&lt;br /&gt;
        if (color == &#039;008000&#039;) labelId = bga.getElement( {name: &#039;Green player&#039;} );&lt;br /&gt;
        if (color == &#039;0000ff&#039;) labelId = bga.getElement( {name: &#039;Blue player&#039;} );&lt;br /&gt;
        if (color == &#039;ffa500&#039;) labelId = bga.getElement( {name: &#039;Yellow player&#039;} );&lt;br /&gt;
        &lt;br /&gt;
        var props = [];&lt;br /&gt;
        props[labelId] = {name: player.name};&lt;br /&gt;
        bga.setProperties( props );&lt;br /&gt;
    }&lt;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://sr.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=3056</id>
		<title>SandboxScripts</title>
		<link rel="alternate" type="text/html" href="https://sr.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=3056"/>
		<updated>2018-05-18T08:54:38Z</updated>

		<summary type="html">&lt;p&gt;Een: /* stopEvent() */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This is the reference of functions you can call from your Sandbox scripts.&lt;br /&gt;
&lt;br /&gt;
= Javascript =&lt;br /&gt;
&lt;br /&gt;
BGA Sandbox scripts are written in Javascript.&lt;br /&gt;
&lt;br /&gt;
Using Javascript, you can write scripts to automate moves for your Sandbox games &amp;amp; provide rules reinforcement.&lt;br /&gt;
&lt;br /&gt;
Important : in the opposite of the most common usage of Javascript, Sandbox scripts are executed &#039;&#039;&#039;on server side&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
= BGA API =&lt;br /&gt;
&lt;br /&gt;
To interact with your BGA Sandbox game, we provide you an API.&lt;br /&gt;
&lt;br /&gt;
With this API, you can get properties values of game elements from the current game situation, modify them and/or trigger the game actions (ex : move this element here, flip this card, and so on).&lt;br /&gt;
&lt;br /&gt;
= Quick start =&lt;br /&gt;
&lt;br /&gt;
== Hello World Script ==&lt;br /&gt;
&lt;br /&gt;
From Sandbox editor &amp;quot;interface view&amp;quot; tab, select an element, and access to its property (top right icon).&lt;br /&gt;
&lt;br /&gt;
Go to &amp;quot;Scripts (advanced)&amp;quot; section.&lt;br /&gt;
&lt;br /&gt;
In front of &amp;quot;When this element is clicked&amp;quot;, enter &amp;quot;onMyClick&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Close the window. Go to &amp;quot;script view&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Enter the following :&lt;br /&gt;
&lt;br /&gt;
 function onMyClick( element_id )&lt;br /&gt;
 {&lt;br /&gt;
    bga.log(&amp;quot;Hello world! You just clicked on element &amp;quot; + element_id + &amp;quot;. Congrats!&amp;quot;);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Save &amp;amp; publish your project, starts a test session, click on the previous element : your message appears in the log on the right!&lt;br /&gt;
&lt;br /&gt;
== Top useful tips ==&lt;br /&gt;
&lt;br /&gt;
* You don&#039;t have to save&amp;amp;publish from the Sandbox editor for each modification of your script : each time you save your script (control+S), the script used for all test sessions is updated. Note that the production version on BGA is of course NOT updated until you explicitly save&amp;amp;publish again your project.&lt;br /&gt;
&lt;br /&gt;
* To inspect the content of a variable, you can use bga.log() in combination with JSON.stringify(). For example :&lt;br /&gt;
&lt;br /&gt;
  bga.log( JSON.stringify( bga.getPlayers()) );&lt;br /&gt;
&lt;br /&gt;
* Alternatively to bga.log(), you can use bga.exit( &amp;quot;my message&amp;quot; ) to debug your script. With bga.exit, the script execution immediately stops and all previous game changes are cancelled, so this is very practical to try and retry an action until your script is fine.&lt;br /&gt;
&lt;br /&gt;
* We advise you to develop first a full playable version of the game without the scripts, and THEN to script it.&lt;br /&gt;
&lt;br /&gt;
* On Board Game Arena, players have come to expect fully implemented games with all rules enforced. So even if it&#039;s technically possible not to script the full game and to implement the game only partially, in most cases we&#039;ll publish only fully scripted games :)&lt;br /&gt;
&lt;br /&gt;
= Functions you can use in your Sandbox scripts=&lt;br /&gt;
&lt;br /&gt;
== Debugging functions ==&lt;br /&gt;
&lt;br /&gt;
=== bga.trace( txt / obj ) ===&lt;br /&gt;
&lt;br /&gt;
Write something immediately in the BGA log (on the right of the screen).&lt;br /&gt;
&lt;br /&gt;
This is the most practical way to debug your script :)&lt;br /&gt;
&lt;br /&gt;
Important : bga.trace is for debugging purpose only and won&#039;t be displayed on production.&lt;br /&gt;
&lt;br /&gt;
Note : you can also pass an object in parameter. This will dump the content of this object in the log.&lt;br /&gt;
&lt;br /&gt;
Note : in the opposite of bga.log, bga.trace is NOT cancelled if the game action failed (after a call to bga.cancel or bga.error). This makes bga.trace very practical to debug a game action that failed, and for this reason you should probably NEVER use bga.log for debugging purpose.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  // Example : write &amp;quot;Hello world&amp;quot; in the log&lt;br /&gt;
  bga.trace( &amp;quot;Hello world&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Example : dump an associative array in the log&lt;br /&gt;
  bga.trace( { mykey: &#039;myvalue&#039;, another_key: &#039;another_value&#039; } );&lt;br /&gt;
&lt;br /&gt;
=== bga.exit( txt / obj ) ===&lt;br /&gt;
&lt;br /&gt;
Stop the script immediately, display the &amp;quot;txt&amp;quot; messages and cancel (ie : rollback) on every previous API call except bga.trace :&lt;br /&gt;
&lt;br /&gt;
ALL previous BGA api call are canceled and there will be no visible changes on the interface (ex : no moves, no visible property changes, ...). Only &amp;quot;bga.trace&amp;quot; API commands are kept so you can debug.&lt;br /&gt;
&lt;br /&gt;
bga.exit is very practical when you want to repeat a game action again and again to debug it : with a call to bga.exit at the end of your script, you make sure that your game situation will be kept unchanged after each test.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.exit( &amp;quot;My script is stopped by this call&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Example with dumping a javascript variable&lt;br /&gt;
  bga.exit( my_variable_to_dump );&lt;br /&gt;
&lt;br /&gt;
== Cancelling a game action ==&lt;br /&gt;
&lt;br /&gt;
=== bga.cancel( txt ) ===&lt;br /&gt;
&lt;br /&gt;
This is the function to use when a player is doing something against game rules.&lt;br /&gt;
&lt;br /&gt;
The text message in parameter will be displayed to this player as a &amp;quot;red message&amp;quot;, so he/she can understand the rule.&lt;br /&gt;
&lt;br /&gt;
All previous BGA api call are cancelled, and there will be no visible changes on the interface.&lt;br /&gt;
&lt;br /&gt;
   // Example :&lt;br /&gt;
   bga.cancel( _(&amp;quot;You cannot move this piece here&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
Note : most of the time, you should wrap your text inside a _() translation marker to make this string translatable.&lt;br /&gt;
&lt;br /&gt;
=== bga.error( text ) ===&lt;br /&gt;
&lt;br /&gt;
This is the function to use when some unexpected error happens in your script.&lt;br /&gt;
&lt;br /&gt;
The text message will be displayed to user, with mention &amp;quot;Unexpected error&amp;quot;. The player will be incited to fill a bug report. The purpose of the message is to help you to identify the bug.&lt;br /&gt;
&lt;br /&gt;
All previous BGA api call are cancelled, and there will be no visible changes on the interface.&lt;br /&gt;
&lt;br /&gt;
   // Example :&lt;br /&gt;
   if( card_picked === null )&lt;br /&gt;
   {&lt;br /&gt;
       bga.error( &amp;quot;Cannot find a card to pick !&amp;quot; );&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
Note : you should NEVER wrap text inside bga.error with _() translation marker, because unexpected error should not be translate (so you can eventually recognize them when reported by players in bug report).&lt;br /&gt;
&lt;br /&gt;
== Game log (history) ==&lt;br /&gt;
&lt;br /&gt;
=== bga.log( txt, (optional) args ) ===&lt;br /&gt;
&lt;br /&gt;
Write something in the BGA log on the right.&lt;br /&gt;
&lt;br /&gt;
  // Example : simple log&lt;br /&gt;
  bga.log( _(&amp;quot;A new round starts&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
You may add arguments to your log, like this :&lt;br /&gt;
&lt;br /&gt;
  // Example: log with argument to display a card name.&lt;br /&gt;
  //          In this example, variable &amp;quot;event_name&amp;quot; is specified afterwards.&lt;br /&gt;
  //          Note that using this, game translators only have to translate one &amp;quot;Event XXX is triggered&amp;quot; string for all possible events.&lt;br /&gt;
  bga.log( _(&amp;quot;Event ${event_name} is triggered&amp;quot;), {  event_name: _( &amp;quot;Armageddon&amp;quot; ) } ) );&lt;br /&gt;
&lt;br /&gt;
Note that argument &amp;quot;player_name&amp;quot; is ALWAYS pre-set with the name of the current player, so you can use it immediately.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.log( _(&amp;quot;${player_name} draw a card from the deck&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
=== bga.speechBubble( target, text, (optional) args, (optional) delay, (optional) duration, (optional) size ) ===&lt;br /&gt;
&lt;br /&gt;
Display a &amp;quot;speech bubble&amp;quot;, attached to the specified target, containing the specified text.&lt;br /&gt;
&lt;br /&gt;
You can use &amp;quot;args&amp;quot; to customize text exactly like with bga.log.&lt;br /&gt;
&lt;br /&gt;
delay : milliseconds to wait before displaying the speech bubble (default : 0).&lt;br /&gt;
duration : how long to show the speech bubble in milliseconds (default : 3000).&lt;br /&gt;
size : size of the text in percent (default: 100)&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.speechBubble( _(&amp;quot;I play ${nbr} cards&amp;quot;), { nbr : 4 }, 0 );&lt;br /&gt;
  bga.speechBubble( _(&amp;quot;Good for you!&amp;quot;), { }, 2000 );&lt;br /&gt;
&lt;br /&gt;
=== bga.displayScoring( target, color, score ) ===&lt;br /&gt;
&lt;br /&gt;
Display an animated temporary &amp;quot;score number&amp;quot;, attached to the specified target.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;color&amp;quot; should be the color of the player who is scoring for that target.&lt;br /&gt;
&lt;br /&gt;
== Get / search game elements and their properties ==&lt;br /&gt;
&lt;br /&gt;
=== bga.getElement( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Allow you to retrieve informations about one game element specified using &amp;quot;selector&amp;quot; argument.&lt;br /&gt;
&lt;br /&gt;
Return null if no element is found.&lt;br /&gt;
&lt;br /&gt;
Note : getElement throw an error if several elements matches the selector. If you want to retrieve several elements, you should use &amp;quot;getElements&amp;quot; instead of &amp;quot;getElement&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The following examples are showing all the possible use of bga.getElement :&lt;br /&gt;
&lt;br /&gt;
  // Basic example :&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve the ID of a game element using its name (&amp;quot;Deck&amp;quot;)&lt;br /&gt;
  var deck_id = bga.getElement( { name: &amp;quot;Deck&amp;quot; } );&lt;br /&gt;
  // Return : 1234  &lt;br /&gt;
&lt;br /&gt;
  // Examples using &amp;quot;field&amp;quot; parameter :&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve a specific property from a game element using its name (&amp;quot;Deck&amp;quot;)&lt;br /&gt;
  var deck_id = bga.getElement( { name: &amp;quot;Deck&amp;quot; }, &#039;x&#039; );&lt;br /&gt;
  // Return : 20&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve several properties from the previous element&lt;br /&gt;
  var deck_properties = bga.getElement( { name: &amp;quot;Deck&amp;quot; }, [&#039;name&#039;,&#039;id&#039;,&#039;parent&#039;, &#039;x&#039;,&#039;y&#039;,&#039;canShuffle&#039;] );&lt;br /&gt;
  // Return : { name:&#039;Deck&#039;, id:1234, parent:4321, x: 20, y:50, canShuffle: true }&lt;br /&gt;
  &lt;br /&gt;
  // Note : as you can see, getElement returns:&lt;br /&gt;
  //        _ the element ID by default, or&lt;br /&gt;
  //        _ a single value if you request a single field, or&lt;br /&gt;
  //        _ an object if you request several fields&lt;br /&gt;
&lt;br /&gt;
  // Examples using different &amp;quot;selector&amp;quot; paramter&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve an element name from its id&lt;br /&gt;
  var deck_name = bga.getElement( { id: 1234 }, [&#039;name&#039;] );&lt;br /&gt;
  // Return : &amp;quot;Deck&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  // Retrieve the last child element of another element&lt;br /&gt;
  // Here, we are requesting for elements who has element with ID=1234 (Deck) as their parent&lt;br /&gt;
  // Note the use of &amp;quot;limit:1&amp;quot; which allows us to retrieve only 1 element.&lt;br /&gt;
  var first_card_on_deck_id = bga.getElement( { parent: 1234, limit:1 } );&lt;br /&gt;
  &lt;br /&gt;
  // You can also get nested properties such as the ids of the child elements of one element, or a custom property placed on the parent element&lt;br /&gt;
  var totem_places = bga.getElements( {tag:&#039;TOTEMZONE&#039;}, [&#039;id&#039;,&#039;childs:id&#039;,&#039;childs:tags&#039;,&#039;parent:id&#039;,&#039;parent:c_value&#039;] );&lt;br /&gt;
&lt;br /&gt;
=== bga.getElements( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Returns an object holding the properties of the elements matching the selector.&lt;br /&gt;
&lt;br /&gt;
  // Basic example: unselect all selected elements&lt;br /&gt;
  bga.removeStyle( bga.getElements( {tag: &#039;sbstyle_selected&#039;}), &#039;selected&#039; );&lt;br /&gt;
&lt;br /&gt;
=== bga.getElementsArray( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Returns an array of all elements matching the selector, holding the required properties.&lt;br /&gt;
&lt;br /&gt;
  // Basic example: get id of selected element&lt;br /&gt;
  var selected_tokens = bga.getElementsArray( {tag: &#039;sbstyle_selected&#039; } );&lt;br /&gt;
  var token_id = null;&lt;br /&gt;
  if (selected_tokens.length &amp;gt; 0) {&lt;br /&gt;
      token_id = selected_tokens[0];&lt;br /&gt;
  }&lt;br /&gt;
  return token_id;&lt;br /&gt;
&lt;br /&gt;
  // Classic example: get array of elements and iterate over it&lt;br /&gt;
  var all_cells = bga.getElementsArray( {tag: &#039;CELL&#039;}, [&#039;id&#039;,&#039;name&#039;,&#039;tags&#039;] );&lt;br /&gt;
  for (var i=0; i&amp;lt;all_cells.length; i++) {&lt;br /&gt;
     // ... process each cell ...&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Utility methods ==&lt;br /&gt;
&lt;br /&gt;
=== bga.isOn( element_id, parent_id ) ===&lt;br /&gt;
&lt;br /&gt;
Return true if &amp;quot;element_id&amp;quot; is a descendant of &amp;quot;parent_id&amp;quot; (ie : if element_id game element has been placed on parent_id game element).&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  if( bga.isOn( bga.getElementIfByName( &#039;Turn counter&#039; ), bga.getElementIfByName( &#039;Turn 6&#039; ) )&lt;br /&gt;
  {&lt;br /&gt;
     // Trigger game end&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Trigger most common game actions ==&lt;br /&gt;
&lt;br /&gt;
=== moveTo( id, target, path ) ===&lt;br /&gt;
&lt;br /&gt;
Move element to specified target id (eventually following path defined by an array of element ids to pass over on the way)&lt;br /&gt;
&lt;br /&gt;
The exact destination of element depends on target&#039;s &amp;quot;howToArrange&amp;quot; property (&amp;quot;How elements are arranged on it?&amp;quot; : spreaded/deck/...).&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.moveTo( bga.getElementIdByName( &#039;Turn counter&#039; ), bga.getElementIdByName( &#039;Turn 3&#039; ) );&lt;br /&gt;
&lt;br /&gt;
=== flip( element_ids ) ===&lt;br /&gt;
&lt;br /&gt;
Flip target element (or array of elements) if the elements are flippable (ex: cards).&lt;br /&gt;
&lt;br /&gt;
=== shuffle( element_ids ) ===&lt;br /&gt;
&lt;br /&gt;
Shuffle elements contained inside this element (or array of elements).&lt;br /&gt;
&lt;br /&gt;
=== deal( deck_id, target_tag, nbr_per_target ) ===&lt;br /&gt;
&lt;br /&gt;
Deal nbr_per_target cards from deck_id element to all elements having target_tag.&lt;br /&gt;
&lt;br /&gt;
=== incScore( color, value ) ===&lt;br /&gt;
&lt;br /&gt;
Increases the score for the player with the specified color, of the specified increment value.&lt;br /&gt;
&lt;br /&gt;
=== setScore( color, value ) ===&lt;br /&gt;
&lt;br /&gt;
Sets the score for the player with the specified color.&lt;br /&gt;
&lt;br /&gt;
=== getScore( color ) ===&lt;br /&gt;
&lt;br /&gt;
Gets the score of the player with the specified color.&lt;br /&gt;
&lt;br /&gt;
== Gamestate functions ==&lt;br /&gt;
&lt;br /&gt;
You can define your game flow with a list of states by adding a &amp;quot;states&amp;quot; function to your script.&lt;br /&gt;
&lt;br /&gt;
  function states()&lt;br /&gt;
  {&lt;br /&gt;
      return {&lt;br /&gt;
        // Init game&lt;br /&gt;
        100: {&lt;br /&gt;
            onState: &#039;postSetup&#039;,&lt;br /&gt;
            transitions: { done:200 }&lt;br /&gt;
        },&lt;br /&gt;
        200: {&lt;br /&gt;
            description: _(&#039;${actplayer} must move a piece&#039;),&lt;br /&gt;
            descriptionmyturn: _(&#039;${you} must move a piece&#039;),&lt;br /&gt;
            possibleactions: [&#039;movePiece&#039;],&lt;br /&gt;
            transitions: { nextPlayer: 200 }&lt;br /&gt;
        },&lt;br /&gt;
      };&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Then, you will be able to use the following functions to manage the game flow.&lt;br /&gt;
&lt;br /&gt;
=== checkAction( action ) ===&lt;br /&gt;
&lt;br /&gt;
Check if action is valid regarding current game state and raise an error if it&#039;s not the case.&lt;br /&gt;
&lt;br /&gt;
=== isActionPossible( action ) ===&lt;br /&gt;
&lt;br /&gt;
Check if action is valid regarding current game state and returns a boolean with the appropriate value.&lt;br /&gt;
&lt;br /&gt;
=== getActivePlayerColor() ===&lt;br /&gt;
&lt;br /&gt;
Returns the color code of the currently active player&lt;br /&gt;
&lt;br /&gt;
=== getActivePlayerName() ===&lt;br /&gt;
&lt;br /&gt;
Returns the color code of the currently active player&lt;br /&gt;
&lt;br /&gt;
=== nextPlayer() ===&lt;br /&gt;
&lt;br /&gt;
Activates the next player in play order.&lt;br /&gt;
&lt;br /&gt;
=== activeAllPlayers() ===&lt;br /&gt;
&lt;br /&gt;
Activates all players (multiactive state).&lt;br /&gt;
&lt;br /&gt;
=== endTurn( transition ) ===&lt;br /&gt;
&lt;br /&gt;
Make the current player inactive and go to the next state matching the provided transition if all players are inactive (multiactive state)&lt;br /&gt;
&lt;br /&gt;
=== getActivePlayerColors() ===&lt;br /&gt;
&lt;br /&gt;
Returns the colors code of the currently active players&lt;br /&gt;
&lt;br /&gt;
=== getCurrentPlayerColor() ===&lt;br /&gt;
&lt;br /&gt;
Returns the color code of the current player (the player who made the interface action being handled; may not be the active player).&lt;br /&gt;
&lt;br /&gt;
=== nextState( transition ) ===&lt;br /&gt;
&lt;br /&gt;
Moves to the next state matching the provided transition.&lt;br /&gt;
&lt;br /&gt;
=== gotoState( state_id ) ===&lt;br /&gt;
&lt;br /&gt;
Jumps to specified state.&lt;br /&gt;
&lt;br /&gt;
=== getPlayers() ===&lt;br /&gt;
&lt;br /&gt;
Returns an array of players with the players information.&lt;br /&gt;
&lt;br /&gt;
=== setGameProgression( progression ) ===&lt;br /&gt;
&lt;br /&gt;
Updates the game progression percentage (progression must be an integer between 0 and 100)&lt;br /&gt;
&lt;br /&gt;
=== endGame() ===&lt;br /&gt;
&lt;br /&gt;
When the end game condition is met, you can use this function to end the game (after setting the appropriate scores!)&lt;br /&gt;
&lt;br /&gt;
== Other functions ==&lt;br /&gt;
&lt;br /&gt;
=== pause( milliseconds ) ===&lt;br /&gt;
&lt;br /&gt;
Pause the client interface during a specified number of milliseconds.&lt;br /&gt;
&lt;br /&gt;
If you do not use bga.pause, all Sandbox game actions are executed immediately and synchronously.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.log( &amp;quot;1&amp;quot; );    // Will be displayed immediately on the log&lt;br /&gt;
  bga.pause( 3000 ); // pause during 3 seconds&lt;br /&gt;
  bga.log( &amp;quot;2&amp;quot; );    // Will be displayed after the 3 second on the log&lt;br /&gt;
  bga.log( &amp;quot;3&amp;quot; );    // Will be displayed right after the previous one, without delay.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Tips : if you want to execute several consecutive &amp;quot;moveTo&amp;quot;, you should &amp;quot;bga.pause&amp;quot; between them, otherwise your element will move directly to the final destination.&lt;br /&gt;
&lt;br /&gt;
=== stopEvent() ===&lt;br /&gt;
&lt;br /&gt;
Must be used to stop the event propagation if you have two clickable elements on top of one another and you want only the onclick function matching the one on top to be triggered.&lt;br /&gt;
&lt;br /&gt;
  function onClickCard( card_id, selection_ids ) {&lt;br /&gt;
      // Cancel event propagation&lt;br /&gt;
      bga.stopEvent();&lt;br /&gt;
      [... manage the event ...]&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
=== hasTag( id, tag ) ===&lt;br /&gt;
&lt;br /&gt;
Returns true if the element with this id has this tag.&lt;br /&gt;
&lt;br /&gt;
=== addTag( id, tag ) ===&lt;br /&gt;
&lt;br /&gt;
Adds this tag to the element with this id.&lt;br /&gt;
&lt;br /&gt;
=== removeTag( id, tag ) ===&lt;br /&gt;
&lt;br /&gt;
Removes this tag from the element with this id.&lt;br /&gt;
&lt;br /&gt;
=== addStyle( id, style ) ===&lt;br /&gt;
&lt;br /&gt;
Adds this style to the element with this id.&lt;br /&gt;
&lt;br /&gt;
Predefined styles are: SELECTED / LIGHT / LIGHTBACKGROUND / REDSELECTED / CLICKABLE / ROUNDED / CLICKABLE_ROUNDED&lt;br /&gt;
&lt;br /&gt;
=== removeStyle( id, style ) ===&lt;br /&gt;
&lt;br /&gt;
Removes this style from the element with this id.&lt;br /&gt;
&lt;br /&gt;
=== setProperties( props ) ===&lt;br /&gt;
&lt;br /&gt;
This function allows to directly update properties of an object, and to manage custom properties if needed (custom properties must start with prefix &amp;quot;c_&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
    // Update player labels for player zones from &amp;quot;&amp;lt;color&amp;gt; player&amp;quot; to actual player name&lt;br /&gt;
    var players = bga.getPlayers();&lt;br /&gt;
    for (var color in players) {&lt;br /&gt;
        player = players[color];&lt;br /&gt;
        &lt;br /&gt;
        var labelId = null;&lt;br /&gt;
        if (color == &#039;ff0000&#039;) labelId = bga.getElement( {name: &#039;Red player&#039;} );&lt;br /&gt;
        if (color == &#039;008000&#039;) labelId = bga.getElement( {name: &#039;Green player&#039;} );&lt;br /&gt;
        if (color == &#039;0000ff&#039;) labelId = bga.getElement( {name: &#039;Blue player&#039;} );&lt;br /&gt;
        if (color == &#039;ffa500&#039;) labelId = bga.getElement( {name: &#039;Yellow player&#039;} );&lt;br /&gt;
        &lt;br /&gt;
        var props = [];&lt;br /&gt;
        props[labelId] = {name: player.name};&lt;br /&gt;
        bga.setProperties( props );&lt;br /&gt;
    }&lt;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://sr.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=3055</id>
		<title>SandboxScripts</title>
		<link rel="alternate" type="text/html" href="https://sr.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=3055"/>
		<updated>2018-05-18T08:54:29Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Other functions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This is the reference of functions you can call from your Sandbox scripts.&lt;br /&gt;
&lt;br /&gt;
= Javascript =&lt;br /&gt;
&lt;br /&gt;
BGA Sandbox scripts are written in Javascript.&lt;br /&gt;
&lt;br /&gt;
Using Javascript, you can write scripts to automate moves for your Sandbox games &amp;amp; provide rules reinforcement.&lt;br /&gt;
&lt;br /&gt;
Important : in the opposite of the most common usage of Javascript, Sandbox scripts are executed &#039;&#039;&#039;on server side&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
= BGA API =&lt;br /&gt;
&lt;br /&gt;
To interact with your BGA Sandbox game, we provide you an API.&lt;br /&gt;
&lt;br /&gt;
With this API, you can get properties values of game elements from the current game situation, modify them and/or trigger the game actions (ex : move this element here, flip this card, and so on).&lt;br /&gt;
&lt;br /&gt;
= Quick start =&lt;br /&gt;
&lt;br /&gt;
== Hello World Script ==&lt;br /&gt;
&lt;br /&gt;
From Sandbox editor &amp;quot;interface view&amp;quot; tab, select an element, and access to its property (top right icon).&lt;br /&gt;
&lt;br /&gt;
Go to &amp;quot;Scripts (advanced)&amp;quot; section.&lt;br /&gt;
&lt;br /&gt;
In front of &amp;quot;When this element is clicked&amp;quot;, enter &amp;quot;onMyClick&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Close the window. Go to &amp;quot;script view&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Enter the following :&lt;br /&gt;
&lt;br /&gt;
 function onMyClick( element_id )&lt;br /&gt;
 {&lt;br /&gt;
    bga.log(&amp;quot;Hello world! You just clicked on element &amp;quot; + element_id + &amp;quot;. Congrats!&amp;quot;);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Save &amp;amp; publish your project, starts a test session, click on the previous element : your message appears in the log on the right!&lt;br /&gt;
&lt;br /&gt;
== Top useful tips ==&lt;br /&gt;
&lt;br /&gt;
* You don&#039;t have to save&amp;amp;publish from the Sandbox editor for each modification of your script : each time you save your script (control+S), the script used for all test sessions is updated. Note that the production version on BGA is of course NOT updated until you explicitly save&amp;amp;publish again your project.&lt;br /&gt;
&lt;br /&gt;
* To inspect the content of a variable, you can use bga.log() in combination with JSON.stringify(). For example :&lt;br /&gt;
&lt;br /&gt;
  bga.log( JSON.stringify( bga.getPlayers()) );&lt;br /&gt;
&lt;br /&gt;
* Alternatively to bga.log(), you can use bga.exit( &amp;quot;my message&amp;quot; ) to debug your script. With bga.exit, the script execution immediately stops and all previous game changes are cancelled, so this is very practical to try and retry an action until your script is fine.&lt;br /&gt;
&lt;br /&gt;
* We advise you to develop first a full playable version of the game without the scripts, and THEN to script it.&lt;br /&gt;
&lt;br /&gt;
* On Board Game Arena, players have come to expect fully implemented games with all rules enforced. So even if it&#039;s technically possible not to script the full game and to implement the game only partially, in most cases we&#039;ll publish only fully scripted games :)&lt;br /&gt;
&lt;br /&gt;
= Functions you can use in your Sandbox scripts=&lt;br /&gt;
&lt;br /&gt;
== Debugging functions ==&lt;br /&gt;
&lt;br /&gt;
=== bga.trace( txt / obj ) ===&lt;br /&gt;
&lt;br /&gt;
Write something immediately in the BGA log (on the right of the screen).&lt;br /&gt;
&lt;br /&gt;
This is the most practical way to debug your script :)&lt;br /&gt;
&lt;br /&gt;
Important : bga.trace is for debugging purpose only and won&#039;t be displayed on production.&lt;br /&gt;
&lt;br /&gt;
Note : you can also pass an object in parameter. This will dump the content of this object in the log.&lt;br /&gt;
&lt;br /&gt;
Note : in the opposite of bga.log, bga.trace is NOT cancelled if the game action failed (after a call to bga.cancel or bga.error). This makes bga.trace very practical to debug a game action that failed, and for this reason you should probably NEVER use bga.log for debugging purpose.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  // Example : write &amp;quot;Hello world&amp;quot; in the log&lt;br /&gt;
  bga.trace( &amp;quot;Hello world&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Example : dump an associative array in the log&lt;br /&gt;
  bga.trace( { mykey: &#039;myvalue&#039;, another_key: &#039;another_value&#039; } );&lt;br /&gt;
&lt;br /&gt;
=== bga.exit( txt / obj ) ===&lt;br /&gt;
&lt;br /&gt;
Stop the script immediately, display the &amp;quot;txt&amp;quot; messages and cancel (ie : rollback) on every previous API call except bga.trace :&lt;br /&gt;
&lt;br /&gt;
ALL previous BGA api call are canceled and there will be no visible changes on the interface (ex : no moves, no visible property changes, ...). Only &amp;quot;bga.trace&amp;quot; API commands are kept so you can debug.&lt;br /&gt;
&lt;br /&gt;
bga.exit is very practical when you want to repeat a game action again and again to debug it : with a call to bga.exit at the end of your script, you make sure that your game situation will be kept unchanged after each test.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.exit( &amp;quot;My script is stopped by this call&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Example with dumping a javascript variable&lt;br /&gt;
  bga.exit( my_variable_to_dump );&lt;br /&gt;
&lt;br /&gt;
== Cancelling a game action ==&lt;br /&gt;
&lt;br /&gt;
=== bga.cancel( txt ) ===&lt;br /&gt;
&lt;br /&gt;
This is the function to use when a player is doing something against game rules.&lt;br /&gt;
&lt;br /&gt;
The text message in parameter will be displayed to this player as a &amp;quot;red message&amp;quot;, so he/she can understand the rule.&lt;br /&gt;
&lt;br /&gt;
All previous BGA api call are cancelled, and there will be no visible changes on the interface.&lt;br /&gt;
&lt;br /&gt;
   // Example :&lt;br /&gt;
   bga.cancel( _(&amp;quot;You cannot move this piece here&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
Note : most of the time, you should wrap your text inside a _() translation marker to make this string translatable.&lt;br /&gt;
&lt;br /&gt;
=== bga.error( text ) ===&lt;br /&gt;
&lt;br /&gt;
This is the function to use when some unexpected error happens in your script.&lt;br /&gt;
&lt;br /&gt;
The text message will be displayed to user, with mention &amp;quot;Unexpected error&amp;quot;. The player will be incited to fill a bug report. The purpose of the message is to help you to identify the bug.&lt;br /&gt;
&lt;br /&gt;
All previous BGA api call are cancelled, and there will be no visible changes on the interface.&lt;br /&gt;
&lt;br /&gt;
   // Example :&lt;br /&gt;
   if( card_picked === null )&lt;br /&gt;
   {&lt;br /&gt;
       bga.error( &amp;quot;Cannot find a card to pick !&amp;quot; );&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
Note : you should NEVER wrap text inside bga.error with _() translation marker, because unexpected error should not be translate (so you can eventually recognize them when reported by players in bug report).&lt;br /&gt;
&lt;br /&gt;
== Game log (history) ==&lt;br /&gt;
&lt;br /&gt;
=== bga.log( txt, (optional) args ) ===&lt;br /&gt;
&lt;br /&gt;
Write something in the BGA log on the right.&lt;br /&gt;
&lt;br /&gt;
  // Example : simple log&lt;br /&gt;
  bga.log( _(&amp;quot;A new round starts&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
You may add arguments to your log, like this :&lt;br /&gt;
&lt;br /&gt;
  // Example: log with argument to display a card name.&lt;br /&gt;
  //          In this example, variable &amp;quot;event_name&amp;quot; is specified afterwards.&lt;br /&gt;
  //          Note that using this, game translators only have to translate one &amp;quot;Event XXX is triggered&amp;quot; string for all possible events.&lt;br /&gt;
  bga.log( _(&amp;quot;Event ${event_name} is triggered&amp;quot;), {  event_name: _( &amp;quot;Armageddon&amp;quot; ) } ) );&lt;br /&gt;
&lt;br /&gt;
Note that argument &amp;quot;player_name&amp;quot; is ALWAYS pre-set with the name of the current player, so you can use it immediately.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.log( _(&amp;quot;${player_name} draw a card from the deck&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
=== bga.speechBubble( target, text, (optional) args, (optional) delay, (optional) duration, (optional) size ) ===&lt;br /&gt;
&lt;br /&gt;
Display a &amp;quot;speech bubble&amp;quot;, attached to the specified target, containing the specified text.&lt;br /&gt;
&lt;br /&gt;
You can use &amp;quot;args&amp;quot; to customize text exactly like with bga.log.&lt;br /&gt;
&lt;br /&gt;
delay : milliseconds to wait before displaying the speech bubble (default : 0).&lt;br /&gt;
duration : how long to show the speech bubble in milliseconds (default : 3000).&lt;br /&gt;
size : size of the text in percent (default: 100)&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.speechBubble( _(&amp;quot;I play ${nbr} cards&amp;quot;), { nbr : 4 }, 0 );&lt;br /&gt;
  bga.speechBubble( _(&amp;quot;Good for you!&amp;quot;), { }, 2000 );&lt;br /&gt;
&lt;br /&gt;
=== bga.displayScoring( target, color, score ) ===&lt;br /&gt;
&lt;br /&gt;
Display an animated temporary &amp;quot;score number&amp;quot;, attached to the specified target.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;color&amp;quot; should be the color of the player who is scoring for that target.&lt;br /&gt;
&lt;br /&gt;
== Get / search game elements and their properties ==&lt;br /&gt;
&lt;br /&gt;
=== bga.getElement( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Allow you to retrieve informations about one game element specified using &amp;quot;selector&amp;quot; argument.&lt;br /&gt;
&lt;br /&gt;
Return null if no element is found.&lt;br /&gt;
&lt;br /&gt;
Note : getElement throw an error if several elements matches the selector. If you want to retrieve several elements, you should use &amp;quot;getElements&amp;quot; instead of &amp;quot;getElement&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The following examples are showing all the possible use of bga.getElement :&lt;br /&gt;
&lt;br /&gt;
  // Basic example :&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve the ID of a game element using its name (&amp;quot;Deck&amp;quot;)&lt;br /&gt;
  var deck_id = bga.getElement( { name: &amp;quot;Deck&amp;quot; } );&lt;br /&gt;
  // Return : 1234  &lt;br /&gt;
&lt;br /&gt;
  // Examples using &amp;quot;field&amp;quot; parameter :&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve a specific property from a game element using its name (&amp;quot;Deck&amp;quot;)&lt;br /&gt;
  var deck_id = bga.getElement( { name: &amp;quot;Deck&amp;quot; }, &#039;x&#039; );&lt;br /&gt;
  // Return : 20&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve several properties from the previous element&lt;br /&gt;
  var deck_properties = bga.getElement( { name: &amp;quot;Deck&amp;quot; }, [&#039;name&#039;,&#039;id&#039;,&#039;parent&#039;, &#039;x&#039;,&#039;y&#039;,&#039;canShuffle&#039;] );&lt;br /&gt;
  // Return : { name:&#039;Deck&#039;, id:1234, parent:4321, x: 20, y:50, canShuffle: true }&lt;br /&gt;
  &lt;br /&gt;
  // Note : as you can see, getElement returns:&lt;br /&gt;
  //        _ the element ID by default, or&lt;br /&gt;
  //        _ a single value if you request a single field, or&lt;br /&gt;
  //        _ an object if you request several fields&lt;br /&gt;
&lt;br /&gt;
  // Examples using different &amp;quot;selector&amp;quot; paramter&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve an element name from its id&lt;br /&gt;
  var deck_name = bga.getElement( { id: 1234 }, [&#039;name&#039;] );&lt;br /&gt;
  // Return : &amp;quot;Deck&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  // Retrieve the last child element of another element&lt;br /&gt;
  // Here, we are requesting for elements who has element with ID=1234 (Deck) as their parent&lt;br /&gt;
  // Note the use of &amp;quot;limit:1&amp;quot; which allows us to retrieve only 1 element.&lt;br /&gt;
  var first_card_on_deck_id = bga.getElement( { parent: 1234, limit:1 } );&lt;br /&gt;
  &lt;br /&gt;
  // You can also get nested properties such as the ids of the child elements of one element, or a custom property placed on the parent element&lt;br /&gt;
  var totem_places = bga.getElements( {tag:&#039;TOTEMZONE&#039;}, [&#039;id&#039;,&#039;childs:id&#039;,&#039;childs:tags&#039;,&#039;parent:id&#039;,&#039;parent:c_value&#039;] );&lt;br /&gt;
&lt;br /&gt;
=== bga.getElements( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Returns an object holding the properties of the elements matching the selector.&lt;br /&gt;
&lt;br /&gt;
  // Basic example: unselect all selected elements&lt;br /&gt;
  bga.removeStyle( bga.getElements( {tag: &#039;sbstyle_selected&#039;}), &#039;selected&#039; );&lt;br /&gt;
&lt;br /&gt;
=== bga.getElementsArray( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Returns an array of all elements matching the selector, holding the required properties.&lt;br /&gt;
&lt;br /&gt;
  // Basic example: get id of selected element&lt;br /&gt;
  var selected_tokens = bga.getElementsArray( {tag: &#039;sbstyle_selected&#039; } );&lt;br /&gt;
  var token_id = null;&lt;br /&gt;
  if (selected_tokens.length &amp;gt; 0) {&lt;br /&gt;
      token_id = selected_tokens[0];&lt;br /&gt;
  }&lt;br /&gt;
  return token_id;&lt;br /&gt;
&lt;br /&gt;
  // Classic example: get array of elements and iterate over it&lt;br /&gt;
  var all_cells = bga.getElementsArray( {tag: &#039;CELL&#039;}, [&#039;id&#039;,&#039;name&#039;,&#039;tags&#039;] );&lt;br /&gt;
  for (var i=0; i&amp;lt;all_cells.length; i++) {&lt;br /&gt;
     // ... process each cell ...&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Utility methods ==&lt;br /&gt;
&lt;br /&gt;
=== bga.isOn( element_id, parent_id ) ===&lt;br /&gt;
&lt;br /&gt;
Return true if &amp;quot;element_id&amp;quot; is a descendant of &amp;quot;parent_id&amp;quot; (ie : if element_id game element has been placed on parent_id game element).&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  if( bga.isOn( bga.getElementIfByName( &#039;Turn counter&#039; ), bga.getElementIfByName( &#039;Turn 6&#039; ) )&lt;br /&gt;
  {&lt;br /&gt;
     // Trigger game end&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Trigger most common game actions ==&lt;br /&gt;
&lt;br /&gt;
=== moveTo( id, target, path ) ===&lt;br /&gt;
&lt;br /&gt;
Move element to specified target id (eventually following path defined by an array of element ids to pass over on the way)&lt;br /&gt;
&lt;br /&gt;
The exact destination of element depends on target&#039;s &amp;quot;howToArrange&amp;quot; property (&amp;quot;How elements are arranged on it?&amp;quot; : spreaded/deck/...).&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.moveTo( bga.getElementIdByName( &#039;Turn counter&#039; ), bga.getElementIdByName( &#039;Turn 3&#039; ) );&lt;br /&gt;
&lt;br /&gt;
=== flip( element_ids ) ===&lt;br /&gt;
&lt;br /&gt;
Flip target element (or array of elements) if the elements are flippable (ex: cards).&lt;br /&gt;
&lt;br /&gt;
=== shuffle( element_ids ) ===&lt;br /&gt;
&lt;br /&gt;
Shuffle elements contained inside this element (or array of elements).&lt;br /&gt;
&lt;br /&gt;
=== deal( deck_id, target_tag, nbr_per_target ) ===&lt;br /&gt;
&lt;br /&gt;
Deal nbr_per_target cards from deck_id element to all elements having target_tag.&lt;br /&gt;
&lt;br /&gt;
=== incScore( color, value ) ===&lt;br /&gt;
&lt;br /&gt;
Increases the score for the player with the specified color, of the specified increment value.&lt;br /&gt;
&lt;br /&gt;
=== setScore( color, value ) ===&lt;br /&gt;
&lt;br /&gt;
Sets the score for the player with the specified color.&lt;br /&gt;
&lt;br /&gt;
=== getScore( color ) ===&lt;br /&gt;
&lt;br /&gt;
Gets the score of the player with the specified color.&lt;br /&gt;
&lt;br /&gt;
== Gamestate functions ==&lt;br /&gt;
&lt;br /&gt;
You can define your game flow with a list of states by adding a &amp;quot;states&amp;quot; function to your script.&lt;br /&gt;
&lt;br /&gt;
  function states()&lt;br /&gt;
  {&lt;br /&gt;
      return {&lt;br /&gt;
        // Init game&lt;br /&gt;
        100: {&lt;br /&gt;
            onState: &#039;postSetup&#039;,&lt;br /&gt;
            transitions: { done:200 }&lt;br /&gt;
        },&lt;br /&gt;
        200: {&lt;br /&gt;
            description: _(&#039;${actplayer} must move a piece&#039;),&lt;br /&gt;
            descriptionmyturn: _(&#039;${you} must move a piece&#039;),&lt;br /&gt;
            possibleactions: [&#039;movePiece&#039;],&lt;br /&gt;
            transitions: { nextPlayer: 200 }&lt;br /&gt;
        },&lt;br /&gt;
      };&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Then, you will be able to use the following functions to manage the game flow.&lt;br /&gt;
&lt;br /&gt;
=== checkAction( action ) ===&lt;br /&gt;
&lt;br /&gt;
Check if action is valid regarding current game state and raise an error if it&#039;s not the case.&lt;br /&gt;
&lt;br /&gt;
=== isActionPossible( action ) ===&lt;br /&gt;
&lt;br /&gt;
Check if action is valid regarding current game state and returns a boolean with the appropriate value.&lt;br /&gt;
&lt;br /&gt;
=== getActivePlayerColor() ===&lt;br /&gt;
&lt;br /&gt;
Returns the color code of the currently active player&lt;br /&gt;
&lt;br /&gt;
=== getActivePlayerName() ===&lt;br /&gt;
&lt;br /&gt;
Returns the color code of the currently active player&lt;br /&gt;
&lt;br /&gt;
=== nextPlayer() ===&lt;br /&gt;
&lt;br /&gt;
Activates the next player in play order.&lt;br /&gt;
&lt;br /&gt;
=== activeAllPlayers() ===&lt;br /&gt;
&lt;br /&gt;
Activates all players (multiactive state).&lt;br /&gt;
&lt;br /&gt;
=== endTurn( transition ) ===&lt;br /&gt;
&lt;br /&gt;
Make the current player inactive and go to the next state matching the provided transition if all players are inactive (multiactive state)&lt;br /&gt;
&lt;br /&gt;
=== getActivePlayerColors() ===&lt;br /&gt;
&lt;br /&gt;
Returns the colors code of the currently active players&lt;br /&gt;
&lt;br /&gt;
=== getCurrentPlayerColor() ===&lt;br /&gt;
&lt;br /&gt;
Returns the color code of the current player (the player who made the interface action being handled; may not be the active player).&lt;br /&gt;
&lt;br /&gt;
=== nextState( transition ) ===&lt;br /&gt;
&lt;br /&gt;
Moves to the next state matching the provided transition.&lt;br /&gt;
&lt;br /&gt;
=== gotoState( state_id ) ===&lt;br /&gt;
&lt;br /&gt;
Jumps to specified state.&lt;br /&gt;
&lt;br /&gt;
=== getPlayers() ===&lt;br /&gt;
&lt;br /&gt;
Returns an array of players with the players information.&lt;br /&gt;
&lt;br /&gt;
=== setGameProgression( progression ) ===&lt;br /&gt;
&lt;br /&gt;
Updates the game progression percentage (progression must be an integer between 0 and 100)&lt;br /&gt;
&lt;br /&gt;
=== endGame() ===&lt;br /&gt;
&lt;br /&gt;
When the end game condition is met, you can use this function to end the game (after setting the appropriate scores!)&lt;br /&gt;
&lt;br /&gt;
== Other functions ==&lt;br /&gt;
&lt;br /&gt;
=== pause( milliseconds ) ===&lt;br /&gt;
&lt;br /&gt;
Pause the client interface during a specified number of milliseconds.&lt;br /&gt;
&lt;br /&gt;
If you do not use bga.pause, all Sandbox game actions are executed immediately and synchronously.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.log( &amp;quot;1&amp;quot; );    // Will be displayed immediately on the log&lt;br /&gt;
  bga.pause( 3000 ); // pause during 3 seconds&lt;br /&gt;
  bga.log( &amp;quot;2&amp;quot; );    // Will be displayed after the 3 second on the log&lt;br /&gt;
  bga.log( &amp;quot;3&amp;quot; );    // Will be displayed right after the previous one, without delay.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Tips : if you want to execute several consecutive &amp;quot;moveTo&amp;quot;, you should &amp;quot;bga.pause&amp;quot; between them, otherwise your element will move directly to the final destination.&lt;br /&gt;
&lt;br /&gt;
=== stopEvent() ===&lt;br /&gt;
&lt;br /&gt;
Must be used to stop the event propagation if you have two clickable elements on top of one another and you want only the onclick function matching the one on top to be triggered.&lt;br /&gt;
&lt;br /&gt;
  function onClickCard( card_id, selection_ids ) {&lt;br /&gt;
      // Cancel event propagation&lt;br /&gt;
      bga.stopEvent();&lt;br /&gt;
&lt;br /&gt;
      [... manage the event ...]&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
=== hasTag( id, tag ) ===&lt;br /&gt;
&lt;br /&gt;
Returns true if the element with this id has this tag.&lt;br /&gt;
&lt;br /&gt;
=== addTag( id, tag ) ===&lt;br /&gt;
&lt;br /&gt;
Adds this tag to the element with this id.&lt;br /&gt;
&lt;br /&gt;
=== removeTag( id, tag ) ===&lt;br /&gt;
&lt;br /&gt;
Removes this tag from the element with this id.&lt;br /&gt;
&lt;br /&gt;
=== addStyle( id, style ) ===&lt;br /&gt;
&lt;br /&gt;
Adds this style to the element with this id.&lt;br /&gt;
&lt;br /&gt;
Predefined styles are: SELECTED / LIGHT / LIGHTBACKGROUND / REDSELECTED / CLICKABLE / ROUNDED / CLICKABLE_ROUNDED&lt;br /&gt;
&lt;br /&gt;
=== removeStyle( id, style ) ===&lt;br /&gt;
&lt;br /&gt;
Removes this style from the element with this id.&lt;br /&gt;
&lt;br /&gt;
=== setProperties( props ) ===&lt;br /&gt;
&lt;br /&gt;
This function allows to directly update properties of an object, and to manage custom properties if needed (custom properties must start with prefix &amp;quot;c_&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
    // Update player labels for player zones from &amp;quot;&amp;lt;color&amp;gt; player&amp;quot; to actual player name&lt;br /&gt;
    var players = bga.getPlayers();&lt;br /&gt;
    for (var color in players) {&lt;br /&gt;
        player = players[color];&lt;br /&gt;
        &lt;br /&gt;
        var labelId = null;&lt;br /&gt;
        if (color == &#039;ff0000&#039;) labelId = bga.getElement( {name: &#039;Red player&#039;} );&lt;br /&gt;
        if (color == &#039;008000&#039;) labelId = bga.getElement( {name: &#039;Green player&#039;} );&lt;br /&gt;
        if (color == &#039;0000ff&#039;) labelId = bga.getElement( {name: &#039;Blue player&#039;} );&lt;br /&gt;
        if (color == &#039;ffa500&#039;) labelId = bga.getElement( {name: &#039;Yellow player&#039;} );&lt;br /&gt;
        &lt;br /&gt;
        var props = [];&lt;br /&gt;
        props[labelId] = {name: player.name};&lt;br /&gt;
        bga.setProperties( props );&lt;br /&gt;
    }&lt;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://sr.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=3054</id>
		<title>SandboxScripts</title>
		<link rel="alternate" type="text/html" href="https://sr.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=3054"/>
		<updated>2018-05-18T08:52:12Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Gamestate functions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This is the reference of functions you can call from your Sandbox scripts.&lt;br /&gt;
&lt;br /&gt;
= Javascript =&lt;br /&gt;
&lt;br /&gt;
BGA Sandbox scripts are written in Javascript.&lt;br /&gt;
&lt;br /&gt;
Using Javascript, you can write scripts to automate moves for your Sandbox games &amp;amp; provide rules reinforcement.&lt;br /&gt;
&lt;br /&gt;
Important : in the opposite of the most common usage of Javascript, Sandbox scripts are executed &#039;&#039;&#039;on server side&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
= BGA API =&lt;br /&gt;
&lt;br /&gt;
To interact with your BGA Sandbox game, we provide you an API.&lt;br /&gt;
&lt;br /&gt;
With this API, you can get properties values of game elements from the current game situation, modify them and/or trigger the game actions (ex : move this element here, flip this card, and so on).&lt;br /&gt;
&lt;br /&gt;
= Quick start =&lt;br /&gt;
&lt;br /&gt;
== Hello World Script ==&lt;br /&gt;
&lt;br /&gt;
From Sandbox editor &amp;quot;interface view&amp;quot; tab, select an element, and access to its property (top right icon).&lt;br /&gt;
&lt;br /&gt;
Go to &amp;quot;Scripts (advanced)&amp;quot; section.&lt;br /&gt;
&lt;br /&gt;
In front of &amp;quot;When this element is clicked&amp;quot;, enter &amp;quot;onMyClick&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Close the window. Go to &amp;quot;script view&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Enter the following :&lt;br /&gt;
&lt;br /&gt;
 function onMyClick( element_id )&lt;br /&gt;
 {&lt;br /&gt;
    bga.log(&amp;quot;Hello world! You just clicked on element &amp;quot; + element_id + &amp;quot;. Congrats!&amp;quot;);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Save &amp;amp; publish your project, starts a test session, click on the previous element : your message appears in the log on the right!&lt;br /&gt;
&lt;br /&gt;
== Top useful tips ==&lt;br /&gt;
&lt;br /&gt;
* You don&#039;t have to save&amp;amp;publish from the Sandbox editor for each modification of your script : each time you save your script (control+S), the script used for all test sessions is updated. Note that the production version on BGA is of course NOT updated until you explicitly save&amp;amp;publish again your project.&lt;br /&gt;
&lt;br /&gt;
* To inspect the content of a variable, you can use bga.log() in combination with JSON.stringify(). For example :&lt;br /&gt;
&lt;br /&gt;
  bga.log( JSON.stringify( bga.getPlayers()) );&lt;br /&gt;
&lt;br /&gt;
* Alternatively to bga.log(), you can use bga.exit( &amp;quot;my message&amp;quot; ) to debug your script. With bga.exit, the script execution immediately stops and all previous game changes are cancelled, so this is very practical to try and retry an action until your script is fine.&lt;br /&gt;
&lt;br /&gt;
* We advise you to develop first a full playable version of the game without the scripts, and THEN to script it.&lt;br /&gt;
&lt;br /&gt;
* On Board Game Arena, players have come to expect fully implemented games with all rules enforced. So even if it&#039;s technically possible not to script the full game and to implement the game only partially, in most cases we&#039;ll publish only fully scripted games :)&lt;br /&gt;
&lt;br /&gt;
= Functions you can use in your Sandbox scripts=&lt;br /&gt;
&lt;br /&gt;
== Debugging functions ==&lt;br /&gt;
&lt;br /&gt;
=== bga.trace( txt / obj ) ===&lt;br /&gt;
&lt;br /&gt;
Write something immediately in the BGA log (on the right of the screen).&lt;br /&gt;
&lt;br /&gt;
This is the most practical way to debug your script :)&lt;br /&gt;
&lt;br /&gt;
Important : bga.trace is for debugging purpose only and won&#039;t be displayed on production.&lt;br /&gt;
&lt;br /&gt;
Note : you can also pass an object in parameter. This will dump the content of this object in the log.&lt;br /&gt;
&lt;br /&gt;
Note : in the opposite of bga.log, bga.trace is NOT cancelled if the game action failed (after a call to bga.cancel or bga.error). This makes bga.trace very practical to debug a game action that failed, and for this reason you should probably NEVER use bga.log for debugging purpose.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  // Example : write &amp;quot;Hello world&amp;quot; in the log&lt;br /&gt;
  bga.trace( &amp;quot;Hello world&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Example : dump an associative array in the log&lt;br /&gt;
  bga.trace( { mykey: &#039;myvalue&#039;, another_key: &#039;another_value&#039; } );&lt;br /&gt;
&lt;br /&gt;
=== bga.exit( txt / obj ) ===&lt;br /&gt;
&lt;br /&gt;
Stop the script immediately, display the &amp;quot;txt&amp;quot; messages and cancel (ie : rollback) on every previous API call except bga.trace :&lt;br /&gt;
&lt;br /&gt;
ALL previous BGA api call are canceled and there will be no visible changes on the interface (ex : no moves, no visible property changes, ...). Only &amp;quot;bga.trace&amp;quot; API commands are kept so you can debug.&lt;br /&gt;
&lt;br /&gt;
bga.exit is very practical when you want to repeat a game action again and again to debug it : with a call to bga.exit at the end of your script, you make sure that your game situation will be kept unchanged after each test.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.exit( &amp;quot;My script is stopped by this call&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Example with dumping a javascript variable&lt;br /&gt;
  bga.exit( my_variable_to_dump );&lt;br /&gt;
&lt;br /&gt;
== Cancelling a game action ==&lt;br /&gt;
&lt;br /&gt;
=== bga.cancel( txt ) ===&lt;br /&gt;
&lt;br /&gt;
This is the function to use when a player is doing something against game rules.&lt;br /&gt;
&lt;br /&gt;
The text message in parameter will be displayed to this player as a &amp;quot;red message&amp;quot;, so he/she can understand the rule.&lt;br /&gt;
&lt;br /&gt;
All previous BGA api call are cancelled, and there will be no visible changes on the interface.&lt;br /&gt;
&lt;br /&gt;
   // Example :&lt;br /&gt;
   bga.cancel( _(&amp;quot;You cannot move this piece here&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
Note : most of the time, you should wrap your text inside a _() translation marker to make this string translatable.&lt;br /&gt;
&lt;br /&gt;
=== bga.error( text ) ===&lt;br /&gt;
&lt;br /&gt;
This is the function to use when some unexpected error happens in your script.&lt;br /&gt;
&lt;br /&gt;
The text message will be displayed to user, with mention &amp;quot;Unexpected error&amp;quot;. The player will be incited to fill a bug report. The purpose of the message is to help you to identify the bug.&lt;br /&gt;
&lt;br /&gt;
All previous BGA api call are cancelled, and there will be no visible changes on the interface.&lt;br /&gt;
&lt;br /&gt;
   // Example :&lt;br /&gt;
   if( card_picked === null )&lt;br /&gt;
   {&lt;br /&gt;
       bga.error( &amp;quot;Cannot find a card to pick !&amp;quot; );&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
Note : you should NEVER wrap text inside bga.error with _() translation marker, because unexpected error should not be translate (so you can eventually recognize them when reported by players in bug report).&lt;br /&gt;
&lt;br /&gt;
== Game log (history) ==&lt;br /&gt;
&lt;br /&gt;
=== bga.log( txt, (optional) args ) ===&lt;br /&gt;
&lt;br /&gt;
Write something in the BGA log on the right.&lt;br /&gt;
&lt;br /&gt;
  // Example : simple log&lt;br /&gt;
  bga.log( _(&amp;quot;A new round starts&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
You may add arguments to your log, like this :&lt;br /&gt;
&lt;br /&gt;
  // Example: log with argument to display a card name.&lt;br /&gt;
  //          In this example, variable &amp;quot;event_name&amp;quot; is specified afterwards.&lt;br /&gt;
  //          Note that using this, game translators only have to translate one &amp;quot;Event XXX is triggered&amp;quot; string for all possible events.&lt;br /&gt;
  bga.log( _(&amp;quot;Event ${event_name} is triggered&amp;quot;), {  event_name: _( &amp;quot;Armageddon&amp;quot; ) } ) );&lt;br /&gt;
&lt;br /&gt;
Note that argument &amp;quot;player_name&amp;quot; is ALWAYS pre-set with the name of the current player, so you can use it immediately.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.log( _(&amp;quot;${player_name} draw a card from the deck&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
=== bga.speechBubble( target, text, (optional) args, (optional) delay, (optional) duration, (optional) size ) ===&lt;br /&gt;
&lt;br /&gt;
Display a &amp;quot;speech bubble&amp;quot;, attached to the specified target, containing the specified text.&lt;br /&gt;
&lt;br /&gt;
You can use &amp;quot;args&amp;quot; to customize text exactly like with bga.log.&lt;br /&gt;
&lt;br /&gt;
delay : milliseconds to wait before displaying the speech bubble (default : 0).&lt;br /&gt;
duration : how long to show the speech bubble in milliseconds (default : 3000).&lt;br /&gt;
size : size of the text in percent (default: 100)&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.speechBubble( _(&amp;quot;I play ${nbr} cards&amp;quot;), { nbr : 4 }, 0 );&lt;br /&gt;
  bga.speechBubble( _(&amp;quot;Good for you!&amp;quot;), { }, 2000 );&lt;br /&gt;
&lt;br /&gt;
=== bga.displayScoring( target, color, score ) ===&lt;br /&gt;
&lt;br /&gt;
Display an animated temporary &amp;quot;score number&amp;quot;, attached to the specified target.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;color&amp;quot; should be the color of the player who is scoring for that target.&lt;br /&gt;
&lt;br /&gt;
== Get / search game elements and their properties ==&lt;br /&gt;
&lt;br /&gt;
=== bga.getElement( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Allow you to retrieve informations about one game element specified using &amp;quot;selector&amp;quot; argument.&lt;br /&gt;
&lt;br /&gt;
Return null if no element is found.&lt;br /&gt;
&lt;br /&gt;
Note : getElement throw an error if several elements matches the selector. If you want to retrieve several elements, you should use &amp;quot;getElements&amp;quot; instead of &amp;quot;getElement&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The following examples are showing all the possible use of bga.getElement :&lt;br /&gt;
&lt;br /&gt;
  // Basic example :&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve the ID of a game element using its name (&amp;quot;Deck&amp;quot;)&lt;br /&gt;
  var deck_id = bga.getElement( { name: &amp;quot;Deck&amp;quot; } );&lt;br /&gt;
  // Return : 1234  &lt;br /&gt;
&lt;br /&gt;
  // Examples using &amp;quot;field&amp;quot; parameter :&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve a specific property from a game element using its name (&amp;quot;Deck&amp;quot;)&lt;br /&gt;
  var deck_id = bga.getElement( { name: &amp;quot;Deck&amp;quot; }, &#039;x&#039; );&lt;br /&gt;
  // Return : 20&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve several properties from the previous element&lt;br /&gt;
  var deck_properties = bga.getElement( { name: &amp;quot;Deck&amp;quot; }, [&#039;name&#039;,&#039;id&#039;,&#039;parent&#039;, &#039;x&#039;,&#039;y&#039;,&#039;canShuffle&#039;] );&lt;br /&gt;
  // Return : { name:&#039;Deck&#039;, id:1234, parent:4321, x: 20, y:50, canShuffle: true }&lt;br /&gt;
  &lt;br /&gt;
  // Note : as you can see, getElement returns:&lt;br /&gt;
  //        _ the element ID by default, or&lt;br /&gt;
  //        _ a single value if you request a single field, or&lt;br /&gt;
  //        _ an object if you request several fields&lt;br /&gt;
&lt;br /&gt;
  // Examples using different &amp;quot;selector&amp;quot; paramter&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve an element name from its id&lt;br /&gt;
  var deck_name = bga.getElement( { id: 1234 }, [&#039;name&#039;] );&lt;br /&gt;
  // Return : &amp;quot;Deck&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  // Retrieve the last child element of another element&lt;br /&gt;
  // Here, we are requesting for elements who has element with ID=1234 (Deck) as their parent&lt;br /&gt;
  // Note the use of &amp;quot;limit:1&amp;quot; which allows us to retrieve only 1 element.&lt;br /&gt;
  var first_card_on_deck_id = bga.getElement( { parent: 1234, limit:1 } );&lt;br /&gt;
  &lt;br /&gt;
  // You can also get nested properties such as the ids of the child elements of one element, or a custom property placed on the parent element&lt;br /&gt;
  var totem_places = bga.getElements( {tag:&#039;TOTEMZONE&#039;}, [&#039;id&#039;,&#039;childs:id&#039;,&#039;childs:tags&#039;,&#039;parent:id&#039;,&#039;parent:c_value&#039;] );&lt;br /&gt;
&lt;br /&gt;
=== bga.getElements( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Returns an object holding the properties of the elements matching the selector.&lt;br /&gt;
&lt;br /&gt;
  // Basic example: unselect all selected elements&lt;br /&gt;
  bga.removeStyle( bga.getElements( {tag: &#039;sbstyle_selected&#039;}), &#039;selected&#039; );&lt;br /&gt;
&lt;br /&gt;
=== bga.getElementsArray( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Returns an array of all elements matching the selector, holding the required properties.&lt;br /&gt;
&lt;br /&gt;
  // Basic example: get id of selected element&lt;br /&gt;
  var selected_tokens = bga.getElementsArray( {tag: &#039;sbstyle_selected&#039; } );&lt;br /&gt;
  var token_id = null;&lt;br /&gt;
  if (selected_tokens.length &amp;gt; 0) {&lt;br /&gt;
      token_id = selected_tokens[0];&lt;br /&gt;
  }&lt;br /&gt;
  return token_id;&lt;br /&gt;
&lt;br /&gt;
  // Classic example: get array of elements and iterate over it&lt;br /&gt;
  var all_cells = bga.getElementsArray( {tag: &#039;CELL&#039;}, [&#039;id&#039;,&#039;name&#039;,&#039;tags&#039;] );&lt;br /&gt;
  for (var i=0; i&amp;lt;all_cells.length; i++) {&lt;br /&gt;
     // ... process each cell ...&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Utility methods ==&lt;br /&gt;
&lt;br /&gt;
=== bga.isOn( element_id, parent_id ) ===&lt;br /&gt;
&lt;br /&gt;
Return true if &amp;quot;element_id&amp;quot; is a descendant of &amp;quot;parent_id&amp;quot; (ie : if element_id game element has been placed on parent_id game element).&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  if( bga.isOn( bga.getElementIfByName( &#039;Turn counter&#039; ), bga.getElementIfByName( &#039;Turn 6&#039; ) )&lt;br /&gt;
  {&lt;br /&gt;
     // Trigger game end&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Trigger most common game actions ==&lt;br /&gt;
&lt;br /&gt;
=== moveTo( id, target, path ) ===&lt;br /&gt;
&lt;br /&gt;
Move element to specified target id (eventually following path defined by an array of element ids to pass over on the way)&lt;br /&gt;
&lt;br /&gt;
The exact destination of element depends on target&#039;s &amp;quot;howToArrange&amp;quot; property (&amp;quot;How elements are arranged on it?&amp;quot; : spreaded/deck/...).&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.moveTo( bga.getElementIdByName( &#039;Turn counter&#039; ), bga.getElementIdByName( &#039;Turn 3&#039; ) );&lt;br /&gt;
&lt;br /&gt;
=== flip( element_ids ) ===&lt;br /&gt;
&lt;br /&gt;
Flip target element (or array of elements) if the elements are flippable (ex: cards).&lt;br /&gt;
&lt;br /&gt;
=== shuffle( element_ids ) ===&lt;br /&gt;
&lt;br /&gt;
Shuffle elements contained inside this element (or array of elements).&lt;br /&gt;
&lt;br /&gt;
=== deal( deck_id, target_tag, nbr_per_target ) ===&lt;br /&gt;
&lt;br /&gt;
Deal nbr_per_target cards from deck_id element to all elements having target_tag.&lt;br /&gt;
&lt;br /&gt;
=== incScore( color, value ) ===&lt;br /&gt;
&lt;br /&gt;
Increases the score for the player with the specified color, of the specified increment value.&lt;br /&gt;
&lt;br /&gt;
=== setScore( color, value ) ===&lt;br /&gt;
&lt;br /&gt;
Sets the score for the player with the specified color.&lt;br /&gt;
&lt;br /&gt;
=== getScore( color ) ===&lt;br /&gt;
&lt;br /&gt;
Gets the score of the player with the specified color.&lt;br /&gt;
&lt;br /&gt;
== Gamestate functions ==&lt;br /&gt;
&lt;br /&gt;
You can define your game flow with a list of states by adding a &amp;quot;states&amp;quot; function to your script.&lt;br /&gt;
&lt;br /&gt;
  function states()&lt;br /&gt;
  {&lt;br /&gt;
      return {&lt;br /&gt;
        // Init game&lt;br /&gt;
        100: {&lt;br /&gt;
            onState: &#039;postSetup&#039;,&lt;br /&gt;
            transitions: { done:200 }&lt;br /&gt;
        },&lt;br /&gt;
        200: {&lt;br /&gt;
            description: _(&#039;${actplayer} must move a piece&#039;),&lt;br /&gt;
            descriptionmyturn: _(&#039;${you} must move a piece&#039;),&lt;br /&gt;
            possibleactions: [&#039;movePiece&#039;],&lt;br /&gt;
            transitions: { nextPlayer: 200 }&lt;br /&gt;
        },&lt;br /&gt;
      };&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Then, you will be able to use the following functions to manage the game flow.&lt;br /&gt;
&lt;br /&gt;
=== checkAction( action ) ===&lt;br /&gt;
&lt;br /&gt;
Check if action is valid regarding current game state and raise an error if it&#039;s not the case.&lt;br /&gt;
&lt;br /&gt;
=== isActionPossible( action ) ===&lt;br /&gt;
&lt;br /&gt;
Check if action is valid regarding current game state and returns a boolean with the appropriate value.&lt;br /&gt;
&lt;br /&gt;
=== getActivePlayerColor() ===&lt;br /&gt;
&lt;br /&gt;
Returns the color code of the currently active player&lt;br /&gt;
&lt;br /&gt;
=== getActivePlayerName() ===&lt;br /&gt;
&lt;br /&gt;
Returns the color code of the currently active player&lt;br /&gt;
&lt;br /&gt;
=== nextPlayer() ===&lt;br /&gt;
&lt;br /&gt;
Activates the next player in play order.&lt;br /&gt;
&lt;br /&gt;
=== activeAllPlayers() ===&lt;br /&gt;
&lt;br /&gt;
Activates all players (multiactive state).&lt;br /&gt;
&lt;br /&gt;
=== endTurn( transition ) ===&lt;br /&gt;
&lt;br /&gt;
Make the current player inactive and go to the next state matching the provided transition if all players are inactive (multiactive state)&lt;br /&gt;
&lt;br /&gt;
=== getActivePlayerColors() ===&lt;br /&gt;
&lt;br /&gt;
Returns the colors code of the currently active players&lt;br /&gt;
&lt;br /&gt;
=== getCurrentPlayerColor() ===&lt;br /&gt;
&lt;br /&gt;
Returns the color code of the current player (the player who made the interface action being handled; may not be the active player).&lt;br /&gt;
&lt;br /&gt;
=== nextState( transition ) ===&lt;br /&gt;
&lt;br /&gt;
Moves to the next state matching the provided transition.&lt;br /&gt;
&lt;br /&gt;
=== gotoState( state_id ) ===&lt;br /&gt;
&lt;br /&gt;
Jumps to specified state.&lt;br /&gt;
&lt;br /&gt;
=== getPlayers() ===&lt;br /&gt;
&lt;br /&gt;
Returns an array of players with the players information.&lt;br /&gt;
&lt;br /&gt;
=== setGameProgression( progression ) ===&lt;br /&gt;
&lt;br /&gt;
Updates the game progression percentage (progression must be an integer between 0 and 100)&lt;br /&gt;
&lt;br /&gt;
=== endGame() ===&lt;br /&gt;
&lt;br /&gt;
When the end game condition is met, you can use this function to end the game (after setting the appropriate scores!)&lt;br /&gt;
&lt;br /&gt;
== Other functions ==&lt;br /&gt;
&lt;br /&gt;
=== pause( milliseconds ) ===&lt;br /&gt;
&lt;br /&gt;
Pause the client interface during a specified number of milliseconds.&lt;br /&gt;
&lt;br /&gt;
If you do not use bga.pause, all Sandbox game actions are executed immediately and synchronously.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.log( &amp;quot;1&amp;quot; );    // Will be displayed immediately on the log&lt;br /&gt;
  bga.pause( 3000 ); // pause during 3 seconds&lt;br /&gt;
  bga.log( &amp;quot;2&amp;quot; );    // Will be displayed after the 3 second on the log&lt;br /&gt;
  bga.log( &amp;quot;3&amp;quot; );    // Will be displayed right after the previous one, without delay.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Tips : if you want to execute several consecutive &amp;quot;moveTo&amp;quot;, you should &amp;quot;bga.pause&amp;quot; between them, otherwise your element will move directly to the final destination.&lt;br /&gt;
&lt;br /&gt;
=== hasTag( id, tag ) ===&lt;br /&gt;
&lt;br /&gt;
Returns true if the element with this id has this tag.&lt;br /&gt;
&lt;br /&gt;
=== addTag( id, tag ) ===&lt;br /&gt;
&lt;br /&gt;
Adds this tag to the element with this id.&lt;br /&gt;
&lt;br /&gt;
=== removeTag( id, tag ) ===&lt;br /&gt;
&lt;br /&gt;
Removes this tag from the element with this id.&lt;br /&gt;
&lt;br /&gt;
=== addStyle( id, style ) ===&lt;br /&gt;
&lt;br /&gt;
Adds this style to the element with this id.&lt;br /&gt;
&lt;br /&gt;
Predefined styles are: SELECTED / LIGHT / LIGHTBACKGROUND / REDSELECTED / CLICKABLE / ROUNDED / CLICKABLE_ROUNDED&lt;br /&gt;
&lt;br /&gt;
=== removeStyle( id, style ) ===&lt;br /&gt;
&lt;br /&gt;
Removes this style from the element with this id.&lt;br /&gt;
&lt;br /&gt;
=== setProperties( props ) ===&lt;br /&gt;
&lt;br /&gt;
This function allows to directly update properties of an object, and to manage custom properties if needed (custom properties must start with prefix &amp;quot;c_&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
    // Update player labels for player zones from &amp;quot;&amp;lt;color&amp;gt; player&amp;quot; to actual player name&lt;br /&gt;
    var players = bga.getPlayers();&lt;br /&gt;
    for (var color in players) {&lt;br /&gt;
        player = players[color];&lt;br /&gt;
        &lt;br /&gt;
        var labelId = null;&lt;br /&gt;
        if (color == &#039;ff0000&#039;) labelId = bga.getElement( {name: &#039;Red player&#039;} );&lt;br /&gt;
        if (color == &#039;008000&#039;) labelId = bga.getElement( {name: &#039;Green player&#039;} );&lt;br /&gt;
        if (color == &#039;0000ff&#039;) labelId = bga.getElement( {name: &#039;Blue player&#039;} );&lt;br /&gt;
        if (color == &#039;ffa500&#039;) labelId = bga.getElement( {name: &#039;Yellow player&#039;} );&lt;br /&gt;
        &lt;br /&gt;
        var props = [];&lt;br /&gt;
        props[labelId] = {name: player.name};&lt;br /&gt;
        bga.setProperties( props );&lt;br /&gt;
    }&lt;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://sr.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=3053</id>
		<title>SandboxScripts</title>
		<link rel="alternate" type="text/html" href="https://sr.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=3053"/>
		<updated>2018-05-18T08:50:40Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Trigger most common game actions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This is the reference of functions you can call from your Sandbox scripts.&lt;br /&gt;
&lt;br /&gt;
= Javascript =&lt;br /&gt;
&lt;br /&gt;
BGA Sandbox scripts are written in Javascript.&lt;br /&gt;
&lt;br /&gt;
Using Javascript, you can write scripts to automate moves for your Sandbox games &amp;amp; provide rules reinforcement.&lt;br /&gt;
&lt;br /&gt;
Important : in the opposite of the most common usage of Javascript, Sandbox scripts are executed &#039;&#039;&#039;on server side&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
= BGA API =&lt;br /&gt;
&lt;br /&gt;
To interact with your BGA Sandbox game, we provide you an API.&lt;br /&gt;
&lt;br /&gt;
With this API, you can get properties values of game elements from the current game situation, modify them and/or trigger the game actions (ex : move this element here, flip this card, and so on).&lt;br /&gt;
&lt;br /&gt;
= Quick start =&lt;br /&gt;
&lt;br /&gt;
== Hello World Script ==&lt;br /&gt;
&lt;br /&gt;
From Sandbox editor &amp;quot;interface view&amp;quot; tab, select an element, and access to its property (top right icon).&lt;br /&gt;
&lt;br /&gt;
Go to &amp;quot;Scripts (advanced)&amp;quot; section.&lt;br /&gt;
&lt;br /&gt;
In front of &amp;quot;When this element is clicked&amp;quot;, enter &amp;quot;onMyClick&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Close the window. Go to &amp;quot;script view&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Enter the following :&lt;br /&gt;
&lt;br /&gt;
 function onMyClick( element_id )&lt;br /&gt;
 {&lt;br /&gt;
    bga.log(&amp;quot;Hello world! You just clicked on element &amp;quot; + element_id + &amp;quot;. Congrats!&amp;quot;);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Save &amp;amp; publish your project, starts a test session, click on the previous element : your message appears in the log on the right!&lt;br /&gt;
&lt;br /&gt;
== Top useful tips ==&lt;br /&gt;
&lt;br /&gt;
* You don&#039;t have to save&amp;amp;publish from the Sandbox editor for each modification of your script : each time you save your script (control+S), the script used for all test sessions is updated. Note that the production version on BGA is of course NOT updated until you explicitly save&amp;amp;publish again your project.&lt;br /&gt;
&lt;br /&gt;
* To inspect the content of a variable, you can use bga.log() in combination with JSON.stringify(). For example :&lt;br /&gt;
&lt;br /&gt;
  bga.log( JSON.stringify( bga.getPlayers()) );&lt;br /&gt;
&lt;br /&gt;
* Alternatively to bga.log(), you can use bga.exit( &amp;quot;my message&amp;quot; ) to debug your script. With bga.exit, the script execution immediately stops and all previous game changes are cancelled, so this is very practical to try and retry an action until your script is fine.&lt;br /&gt;
&lt;br /&gt;
* We advise you to develop first a full playable version of the game without the scripts, and THEN to script it.&lt;br /&gt;
&lt;br /&gt;
* On Board Game Arena, players have come to expect fully implemented games with all rules enforced. So even if it&#039;s technically possible not to script the full game and to implement the game only partially, in most cases we&#039;ll publish only fully scripted games :)&lt;br /&gt;
&lt;br /&gt;
= Functions you can use in your Sandbox scripts=&lt;br /&gt;
&lt;br /&gt;
== Debugging functions ==&lt;br /&gt;
&lt;br /&gt;
=== bga.trace( txt / obj ) ===&lt;br /&gt;
&lt;br /&gt;
Write something immediately in the BGA log (on the right of the screen).&lt;br /&gt;
&lt;br /&gt;
This is the most practical way to debug your script :)&lt;br /&gt;
&lt;br /&gt;
Important : bga.trace is for debugging purpose only and won&#039;t be displayed on production.&lt;br /&gt;
&lt;br /&gt;
Note : you can also pass an object in parameter. This will dump the content of this object in the log.&lt;br /&gt;
&lt;br /&gt;
Note : in the opposite of bga.log, bga.trace is NOT cancelled if the game action failed (after a call to bga.cancel or bga.error). This makes bga.trace very practical to debug a game action that failed, and for this reason you should probably NEVER use bga.log for debugging purpose.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  // Example : write &amp;quot;Hello world&amp;quot; in the log&lt;br /&gt;
  bga.trace( &amp;quot;Hello world&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Example : dump an associative array in the log&lt;br /&gt;
  bga.trace( { mykey: &#039;myvalue&#039;, another_key: &#039;another_value&#039; } );&lt;br /&gt;
&lt;br /&gt;
=== bga.exit( txt / obj ) ===&lt;br /&gt;
&lt;br /&gt;
Stop the script immediately, display the &amp;quot;txt&amp;quot; messages and cancel (ie : rollback) on every previous API call except bga.trace :&lt;br /&gt;
&lt;br /&gt;
ALL previous BGA api call are canceled and there will be no visible changes on the interface (ex : no moves, no visible property changes, ...). Only &amp;quot;bga.trace&amp;quot; API commands are kept so you can debug.&lt;br /&gt;
&lt;br /&gt;
bga.exit is very practical when you want to repeat a game action again and again to debug it : with a call to bga.exit at the end of your script, you make sure that your game situation will be kept unchanged after each test.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.exit( &amp;quot;My script is stopped by this call&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Example with dumping a javascript variable&lt;br /&gt;
  bga.exit( my_variable_to_dump );&lt;br /&gt;
&lt;br /&gt;
== Cancelling a game action ==&lt;br /&gt;
&lt;br /&gt;
=== bga.cancel( txt ) ===&lt;br /&gt;
&lt;br /&gt;
This is the function to use when a player is doing something against game rules.&lt;br /&gt;
&lt;br /&gt;
The text message in parameter will be displayed to this player as a &amp;quot;red message&amp;quot;, so he/she can understand the rule.&lt;br /&gt;
&lt;br /&gt;
All previous BGA api call are cancelled, and there will be no visible changes on the interface.&lt;br /&gt;
&lt;br /&gt;
   // Example :&lt;br /&gt;
   bga.cancel( _(&amp;quot;You cannot move this piece here&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
Note : most of the time, you should wrap your text inside a _() translation marker to make this string translatable.&lt;br /&gt;
&lt;br /&gt;
=== bga.error( text ) ===&lt;br /&gt;
&lt;br /&gt;
This is the function to use when some unexpected error happens in your script.&lt;br /&gt;
&lt;br /&gt;
The text message will be displayed to user, with mention &amp;quot;Unexpected error&amp;quot;. The player will be incited to fill a bug report. The purpose of the message is to help you to identify the bug.&lt;br /&gt;
&lt;br /&gt;
All previous BGA api call are cancelled, and there will be no visible changes on the interface.&lt;br /&gt;
&lt;br /&gt;
   // Example :&lt;br /&gt;
   if( card_picked === null )&lt;br /&gt;
   {&lt;br /&gt;
       bga.error( &amp;quot;Cannot find a card to pick !&amp;quot; );&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
Note : you should NEVER wrap text inside bga.error with _() translation marker, because unexpected error should not be translate (so you can eventually recognize them when reported by players in bug report).&lt;br /&gt;
&lt;br /&gt;
== Game log (history) ==&lt;br /&gt;
&lt;br /&gt;
=== bga.log( txt, (optional) args ) ===&lt;br /&gt;
&lt;br /&gt;
Write something in the BGA log on the right.&lt;br /&gt;
&lt;br /&gt;
  // Example : simple log&lt;br /&gt;
  bga.log( _(&amp;quot;A new round starts&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
You may add arguments to your log, like this :&lt;br /&gt;
&lt;br /&gt;
  // Example: log with argument to display a card name.&lt;br /&gt;
  //          In this example, variable &amp;quot;event_name&amp;quot; is specified afterwards.&lt;br /&gt;
  //          Note that using this, game translators only have to translate one &amp;quot;Event XXX is triggered&amp;quot; string for all possible events.&lt;br /&gt;
  bga.log( _(&amp;quot;Event ${event_name} is triggered&amp;quot;), {  event_name: _( &amp;quot;Armageddon&amp;quot; ) } ) );&lt;br /&gt;
&lt;br /&gt;
Note that argument &amp;quot;player_name&amp;quot; is ALWAYS pre-set with the name of the current player, so you can use it immediately.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.log( _(&amp;quot;${player_name} draw a card from the deck&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
=== bga.speechBubble( target, text, (optional) args, (optional) delay, (optional) duration, (optional) size ) ===&lt;br /&gt;
&lt;br /&gt;
Display a &amp;quot;speech bubble&amp;quot;, attached to the specified target, containing the specified text.&lt;br /&gt;
&lt;br /&gt;
You can use &amp;quot;args&amp;quot; to customize text exactly like with bga.log.&lt;br /&gt;
&lt;br /&gt;
delay : milliseconds to wait before displaying the speech bubble (default : 0).&lt;br /&gt;
duration : how long to show the speech bubble in milliseconds (default : 3000).&lt;br /&gt;
size : size of the text in percent (default: 100)&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.speechBubble( _(&amp;quot;I play ${nbr} cards&amp;quot;), { nbr : 4 }, 0 );&lt;br /&gt;
  bga.speechBubble( _(&amp;quot;Good for you!&amp;quot;), { }, 2000 );&lt;br /&gt;
&lt;br /&gt;
=== bga.displayScoring( target, color, score ) ===&lt;br /&gt;
&lt;br /&gt;
Display an animated temporary &amp;quot;score number&amp;quot;, attached to the specified target.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;color&amp;quot; should be the color of the player who is scoring for that target.&lt;br /&gt;
&lt;br /&gt;
== Get / search game elements and their properties ==&lt;br /&gt;
&lt;br /&gt;
=== bga.getElement( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Allow you to retrieve informations about one game element specified using &amp;quot;selector&amp;quot; argument.&lt;br /&gt;
&lt;br /&gt;
Return null if no element is found.&lt;br /&gt;
&lt;br /&gt;
Note : getElement throw an error if several elements matches the selector. If you want to retrieve several elements, you should use &amp;quot;getElements&amp;quot; instead of &amp;quot;getElement&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The following examples are showing all the possible use of bga.getElement :&lt;br /&gt;
&lt;br /&gt;
  // Basic example :&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve the ID of a game element using its name (&amp;quot;Deck&amp;quot;)&lt;br /&gt;
  var deck_id = bga.getElement( { name: &amp;quot;Deck&amp;quot; } );&lt;br /&gt;
  // Return : 1234  &lt;br /&gt;
&lt;br /&gt;
  // Examples using &amp;quot;field&amp;quot; parameter :&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve a specific property from a game element using its name (&amp;quot;Deck&amp;quot;)&lt;br /&gt;
  var deck_id = bga.getElement( { name: &amp;quot;Deck&amp;quot; }, &#039;x&#039; );&lt;br /&gt;
  // Return : 20&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve several properties from the previous element&lt;br /&gt;
  var deck_properties = bga.getElement( { name: &amp;quot;Deck&amp;quot; }, [&#039;name&#039;,&#039;id&#039;,&#039;parent&#039;, &#039;x&#039;,&#039;y&#039;,&#039;canShuffle&#039;] );&lt;br /&gt;
  // Return : { name:&#039;Deck&#039;, id:1234, parent:4321, x: 20, y:50, canShuffle: true }&lt;br /&gt;
  &lt;br /&gt;
  // Note : as you can see, getElement returns:&lt;br /&gt;
  //        _ the element ID by default, or&lt;br /&gt;
  //        _ a single value if you request a single field, or&lt;br /&gt;
  //        _ an object if you request several fields&lt;br /&gt;
&lt;br /&gt;
  // Examples using different &amp;quot;selector&amp;quot; paramter&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve an element name from its id&lt;br /&gt;
  var deck_name = bga.getElement( { id: 1234 }, [&#039;name&#039;] );&lt;br /&gt;
  // Return : &amp;quot;Deck&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  // Retrieve the last child element of another element&lt;br /&gt;
  // Here, we are requesting for elements who has element with ID=1234 (Deck) as their parent&lt;br /&gt;
  // Note the use of &amp;quot;limit:1&amp;quot; which allows us to retrieve only 1 element.&lt;br /&gt;
  var first_card_on_deck_id = bga.getElement( { parent: 1234, limit:1 } );&lt;br /&gt;
  &lt;br /&gt;
  // You can also get nested properties such as the ids of the child elements of one element, or a custom property placed on the parent element&lt;br /&gt;
  var totem_places = bga.getElements( {tag:&#039;TOTEMZONE&#039;}, [&#039;id&#039;,&#039;childs:id&#039;,&#039;childs:tags&#039;,&#039;parent:id&#039;,&#039;parent:c_value&#039;] );&lt;br /&gt;
&lt;br /&gt;
=== bga.getElements( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Returns an object holding the properties of the elements matching the selector.&lt;br /&gt;
&lt;br /&gt;
  // Basic example: unselect all selected elements&lt;br /&gt;
  bga.removeStyle( bga.getElements( {tag: &#039;sbstyle_selected&#039;}), &#039;selected&#039; );&lt;br /&gt;
&lt;br /&gt;
=== bga.getElementsArray( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Returns an array of all elements matching the selector, holding the required properties.&lt;br /&gt;
&lt;br /&gt;
  // Basic example: get id of selected element&lt;br /&gt;
  var selected_tokens = bga.getElementsArray( {tag: &#039;sbstyle_selected&#039; } );&lt;br /&gt;
  var token_id = null;&lt;br /&gt;
  if (selected_tokens.length &amp;gt; 0) {&lt;br /&gt;
      token_id = selected_tokens[0];&lt;br /&gt;
  }&lt;br /&gt;
  return token_id;&lt;br /&gt;
&lt;br /&gt;
  // Classic example: get array of elements and iterate over it&lt;br /&gt;
  var all_cells = bga.getElementsArray( {tag: &#039;CELL&#039;}, [&#039;id&#039;,&#039;name&#039;,&#039;tags&#039;] );&lt;br /&gt;
  for (var i=0; i&amp;lt;all_cells.length; i++) {&lt;br /&gt;
     // ... process each cell ...&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Utility methods ==&lt;br /&gt;
&lt;br /&gt;
=== bga.isOn( element_id, parent_id ) ===&lt;br /&gt;
&lt;br /&gt;
Return true if &amp;quot;element_id&amp;quot; is a descendant of &amp;quot;parent_id&amp;quot; (ie : if element_id game element has been placed on parent_id game element).&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  if( bga.isOn( bga.getElementIfByName( &#039;Turn counter&#039; ), bga.getElementIfByName( &#039;Turn 6&#039; ) )&lt;br /&gt;
  {&lt;br /&gt;
     // Trigger game end&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Trigger most common game actions ==&lt;br /&gt;
&lt;br /&gt;
=== moveTo( id, target, path ) ===&lt;br /&gt;
&lt;br /&gt;
Move element to specified target id (eventually following path defined by an array of element ids to pass over on the way)&lt;br /&gt;
&lt;br /&gt;
The exact destination of element depends on target&#039;s &amp;quot;howToArrange&amp;quot; property (&amp;quot;How elements are arranged on it?&amp;quot; : spreaded/deck/...).&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.moveTo( bga.getElementIdByName( &#039;Turn counter&#039; ), bga.getElementIdByName( &#039;Turn 3&#039; ) );&lt;br /&gt;
&lt;br /&gt;
=== flip( element_ids ) ===&lt;br /&gt;
&lt;br /&gt;
Flip target element (or array of elements) if the elements are flippable (ex: cards).&lt;br /&gt;
&lt;br /&gt;
=== shuffle( element_ids ) ===&lt;br /&gt;
&lt;br /&gt;
Shuffle elements contained inside this element (or array of elements).&lt;br /&gt;
&lt;br /&gt;
=== deal( deck_id, target_tag, nbr_per_target ) ===&lt;br /&gt;
&lt;br /&gt;
Deal nbr_per_target cards from deck_id element to all elements having target_tag.&lt;br /&gt;
&lt;br /&gt;
=== incScore( color, value ) ===&lt;br /&gt;
&lt;br /&gt;
Increases the score for the player with the specified color, of the specified increment value.&lt;br /&gt;
&lt;br /&gt;
=== setScore( color, value ) ===&lt;br /&gt;
&lt;br /&gt;
Sets the score for the player with the specified color.&lt;br /&gt;
&lt;br /&gt;
=== getScore( color ) ===&lt;br /&gt;
&lt;br /&gt;
Gets the score of the player with the specified color.&lt;br /&gt;
&lt;br /&gt;
== Gamestate functions ==&lt;br /&gt;
&lt;br /&gt;
You can define your game flow with a list of states by adding a &amp;quot;states&amp;quot; function to your script.&lt;br /&gt;
&lt;br /&gt;
  function states()&lt;br /&gt;
  {&lt;br /&gt;
      return {&lt;br /&gt;
        // Init game&lt;br /&gt;
        100: {&lt;br /&gt;
            onState: &#039;postSetup&#039;,&lt;br /&gt;
            transitions: { done:200 }&lt;br /&gt;
        },&lt;br /&gt;
        200: {&lt;br /&gt;
            description: _(&#039;${actplayer} must move a piece&#039;),&lt;br /&gt;
            descriptionmyturn: _(&#039;${you} must move a piece&#039;),&lt;br /&gt;
            possibleactions: [&#039;movePiece&#039;],&lt;br /&gt;
            transitions: { nextPlayer: 200 }&lt;br /&gt;
        },&lt;br /&gt;
      };&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Then, you will be able to use the following functions to manage the game flow.&lt;br /&gt;
&lt;br /&gt;
=== checkAction( action ) ===&lt;br /&gt;
&lt;br /&gt;
Check if action is valid regarding current game state and raise an error if it&#039;s not the case.&lt;br /&gt;
&lt;br /&gt;
=== isActionPossible( action ) ===&lt;br /&gt;
&lt;br /&gt;
Check if action is valid regarding current game state and returns a boolean with the appropriate value.&lt;br /&gt;
&lt;br /&gt;
=== getActivePlayerColor() ===&lt;br /&gt;
&lt;br /&gt;
Returns the color code of the currently active player&lt;br /&gt;
&lt;br /&gt;
=== getActivePlayerName() ===&lt;br /&gt;
&lt;br /&gt;
Returns the color code of the currently active player&lt;br /&gt;
&lt;br /&gt;
=== nextPlayer() ===&lt;br /&gt;
&lt;br /&gt;
Activates the next player in play order.&lt;br /&gt;
&lt;br /&gt;
=== activeAllPlayers() ===&lt;br /&gt;
&lt;br /&gt;
Activates all players (multiactive state).&lt;br /&gt;
&lt;br /&gt;
=== endTurn( transition ) ===&lt;br /&gt;
&lt;br /&gt;
Make the current player inactive and go to the next state matching the provided transition if all players are inactive (multiactive state)&lt;br /&gt;
&lt;br /&gt;
=== getActivePlayerColors() ===&lt;br /&gt;
&lt;br /&gt;
Returns the colors code of the currently active players&lt;br /&gt;
&lt;br /&gt;
=== getCurrentPlayerColor() ===&lt;br /&gt;
&lt;br /&gt;
Returns the color code of the current player (the player who made the interface action being handled; may not be the active player).&lt;br /&gt;
&lt;br /&gt;
=== nextState( transition ) ===&lt;br /&gt;
&lt;br /&gt;
Moves to the next state matching the provided transition.&lt;br /&gt;
&lt;br /&gt;
=== gotoState( state_id ) ===&lt;br /&gt;
&lt;br /&gt;
Jumps to specified state.&lt;br /&gt;
&lt;br /&gt;
=== getPlayers() ===&lt;br /&gt;
&lt;br /&gt;
Returns an array of players with the players information.&lt;br /&gt;
&lt;br /&gt;
=== endGame() ===&lt;br /&gt;
&lt;br /&gt;
When the end game condition is met, you can use this function to end the game (after setting the appropriate scores!)&lt;br /&gt;
&lt;br /&gt;
== Other functions ==&lt;br /&gt;
&lt;br /&gt;
=== pause( milliseconds ) ===&lt;br /&gt;
&lt;br /&gt;
Pause the client interface during a specified number of milliseconds.&lt;br /&gt;
&lt;br /&gt;
If you do not use bga.pause, all Sandbox game actions are executed immediately and synchronously.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.log( &amp;quot;1&amp;quot; );    // Will be displayed immediately on the log&lt;br /&gt;
  bga.pause( 3000 ); // pause during 3 seconds&lt;br /&gt;
  bga.log( &amp;quot;2&amp;quot; );    // Will be displayed after the 3 second on the log&lt;br /&gt;
  bga.log( &amp;quot;3&amp;quot; );    // Will be displayed right after the previous one, without delay.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Tips : if you want to execute several consecutive &amp;quot;moveTo&amp;quot;, you should &amp;quot;bga.pause&amp;quot; between them, otherwise your element will move directly to the final destination.&lt;br /&gt;
&lt;br /&gt;
=== hasTag( id, tag ) ===&lt;br /&gt;
&lt;br /&gt;
Returns true if the element with this id has this tag.&lt;br /&gt;
&lt;br /&gt;
=== addTag( id, tag ) ===&lt;br /&gt;
&lt;br /&gt;
Adds this tag to the element with this id.&lt;br /&gt;
&lt;br /&gt;
=== removeTag( id, tag ) ===&lt;br /&gt;
&lt;br /&gt;
Removes this tag from the element with this id.&lt;br /&gt;
&lt;br /&gt;
=== addStyle( id, style ) ===&lt;br /&gt;
&lt;br /&gt;
Adds this style to the element with this id.&lt;br /&gt;
&lt;br /&gt;
Predefined styles are: SELECTED / LIGHT / LIGHTBACKGROUND / REDSELECTED / CLICKABLE / ROUNDED / CLICKABLE_ROUNDED&lt;br /&gt;
&lt;br /&gt;
=== removeStyle( id, style ) ===&lt;br /&gt;
&lt;br /&gt;
Removes this style from the element with this id.&lt;br /&gt;
&lt;br /&gt;
=== setProperties( props ) ===&lt;br /&gt;
&lt;br /&gt;
This function allows to directly update properties of an object, and to manage custom properties if needed (custom properties must start with prefix &amp;quot;c_&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
    // Update player labels for player zones from &amp;quot;&amp;lt;color&amp;gt; player&amp;quot; to actual player name&lt;br /&gt;
    var players = bga.getPlayers();&lt;br /&gt;
    for (var color in players) {&lt;br /&gt;
        player = players[color];&lt;br /&gt;
        &lt;br /&gt;
        var labelId = null;&lt;br /&gt;
        if (color == &#039;ff0000&#039;) labelId = bga.getElement( {name: &#039;Red player&#039;} );&lt;br /&gt;
        if (color == &#039;008000&#039;) labelId = bga.getElement( {name: &#039;Green player&#039;} );&lt;br /&gt;
        if (color == &#039;0000ff&#039;) labelId = bga.getElement( {name: &#039;Blue player&#039;} );&lt;br /&gt;
        if (color == &#039;ffa500&#039;) labelId = bga.getElement( {name: &#039;Yellow player&#039;} );&lt;br /&gt;
        &lt;br /&gt;
        var props = [];&lt;br /&gt;
        props[labelId] = {name: player.name};&lt;br /&gt;
        bga.setProperties( props );&lt;br /&gt;
    }&lt;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://sr.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=3052</id>
		<title>SandboxScripts</title>
		<link rel="alternate" type="text/html" href="https://sr.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=3052"/>
		<updated>2018-05-18T08:48:52Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Gamestate functions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This is the reference of functions you can call from your Sandbox scripts.&lt;br /&gt;
&lt;br /&gt;
= Javascript =&lt;br /&gt;
&lt;br /&gt;
BGA Sandbox scripts are written in Javascript.&lt;br /&gt;
&lt;br /&gt;
Using Javascript, you can write scripts to automate moves for your Sandbox games &amp;amp; provide rules reinforcement.&lt;br /&gt;
&lt;br /&gt;
Important : in the opposite of the most common usage of Javascript, Sandbox scripts are executed &#039;&#039;&#039;on server side&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
= BGA API =&lt;br /&gt;
&lt;br /&gt;
To interact with your BGA Sandbox game, we provide you an API.&lt;br /&gt;
&lt;br /&gt;
With this API, you can get properties values of game elements from the current game situation, modify them and/or trigger the game actions (ex : move this element here, flip this card, and so on).&lt;br /&gt;
&lt;br /&gt;
= Quick start =&lt;br /&gt;
&lt;br /&gt;
== Hello World Script ==&lt;br /&gt;
&lt;br /&gt;
From Sandbox editor &amp;quot;interface view&amp;quot; tab, select an element, and access to its property (top right icon).&lt;br /&gt;
&lt;br /&gt;
Go to &amp;quot;Scripts (advanced)&amp;quot; section.&lt;br /&gt;
&lt;br /&gt;
In front of &amp;quot;When this element is clicked&amp;quot;, enter &amp;quot;onMyClick&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Close the window. Go to &amp;quot;script view&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Enter the following :&lt;br /&gt;
&lt;br /&gt;
 function onMyClick( element_id )&lt;br /&gt;
 {&lt;br /&gt;
    bga.log(&amp;quot;Hello world! You just clicked on element &amp;quot; + element_id + &amp;quot;. Congrats!&amp;quot;);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Save &amp;amp; publish your project, starts a test session, click on the previous element : your message appears in the log on the right!&lt;br /&gt;
&lt;br /&gt;
== Top useful tips ==&lt;br /&gt;
&lt;br /&gt;
* You don&#039;t have to save&amp;amp;publish from the Sandbox editor for each modification of your script : each time you save your script (control+S), the script used for all test sessions is updated. Note that the production version on BGA is of course NOT updated until you explicitly save&amp;amp;publish again your project.&lt;br /&gt;
&lt;br /&gt;
* To inspect the content of a variable, you can use bga.log() in combination with JSON.stringify(). For example :&lt;br /&gt;
&lt;br /&gt;
  bga.log( JSON.stringify( bga.getPlayers()) );&lt;br /&gt;
&lt;br /&gt;
* Alternatively to bga.log(), you can use bga.exit( &amp;quot;my message&amp;quot; ) to debug your script. With bga.exit, the script execution immediately stops and all previous game changes are cancelled, so this is very practical to try and retry an action until your script is fine.&lt;br /&gt;
&lt;br /&gt;
* We advise you to develop first a full playable version of the game without the scripts, and THEN to script it.&lt;br /&gt;
&lt;br /&gt;
* On Board Game Arena, players have come to expect fully implemented games with all rules enforced. So even if it&#039;s technically possible not to script the full game and to implement the game only partially, in most cases we&#039;ll publish only fully scripted games :)&lt;br /&gt;
&lt;br /&gt;
= Functions you can use in your Sandbox scripts=&lt;br /&gt;
&lt;br /&gt;
== Debugging functions ==&lt;br /&gt;
&lt;br /&gt;
=== bga.trace( txt / obj ) ===&lt;br /&gt;
&lt;br /&gt;
Write something immediately in the BGA log (on the right of the screen).&lt;br /&gt;
&lt;br /&gt;
This is the most practical way to debug your script :)&lt;br /&gt;
&lt;br /&gt;
Important : bga.trace is for debugging purpose only and won&#039;t be displayed on production.&lt;br /&gt;
&lt;br /&gt;
Note : you can also pass an object in parameter. This will dump the content of this object in the log.&lt;br /&gt;
&lt;br /&gt;
Note : in the opposite of bga.log, bga.trace is NOT cancelled if the game action failed (after a call to bga.cancel or bga.error). This makes bga.trace very practical to debug a game action that failed, and for this reason you should probably NEVER use bga.log for debugging purpose.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  // Example : write &amp;quot;Hello world&amp;quot; in the log&lt;br /&gt;
  bga.trace( &amp;quot;Hello world&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Example : dump an associative array in the log&lt;br /&gt;
  bga.trace( { mykey: &#039;myvalue&#039;, another_key: &#039;another_value&#039; } );&lt;br /&gt;
&lt;br /&gt;
=== bga.exit( txt / obj ) ===&lt;br /&gt;
&lt;br /&gt;
Stop the script immediately, display the &amp;quot;txt&amp;quot; messages and cancel (ie : rollback) on every previous API call except bga.trace :&lt;br /&gt;
&lt;br /&gt;
ALL previous BGA api call are canceled and there will be no visible changes on the interface (ex : no moves, no visible property changes, ...). Only &amp;quot;bga.trace&amp;quot; API commands are kept so you can debug.&lt;br /&gt;
&lt;br /&gt;
bga.exit is very practical when you want to repeat a game action again and again to debug it : with a call to bga.exit at the end of your script, you make sure that your game situation will be kept unchanged after each test.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.exit( &amp;quot;My script is stopped by this call&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Example with dumping a javascript variable&lt;br /&gt;
  bga.exit( my_variable_to_dump );&lt;br /&gt;
&lt;br /&gt;
== Cancelling a game action ==&lt;br /&gt;
&lt;br /&gt;
=== bga.cancel( txt ) ===&lt;br /&gt;
&lt;br /&gt;
This is the function to use when a player is doing something against game rules.&lt;br /&gt;
&lt;br /&gt;
The text message in parameter will be displayed to this player as a &amp;quot;red message&amp;quot;, so he/she can understand the rule.&lt;br /&gt;
&lt;br /&gt;
All previous BGA api call are cancelled, and there will be no visible changes on the interface.&lt;br /&gt;
&lt;br /&gt;
   // Example :&lt;br /&gt;
   bga.cancel( _(&amp;quot;You cannot move this piece here&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
Note : most of the time, you should wrap your text inside a _() translation marker to make this string translatable.&lt;br /&gt;
&lt;br /&gt;
=== bga.error( text ) ===&lt;br /&gt;
&lt;br /&gt;
This is the function to use when some unexpected error happens in your script.&lt;br /&gt;
&lt;br /&gt;
The text message will be displayed to user, with mention &amp;quot;Unexpected error&amp;quot;. The player will be incited to fill a bug report. The purpose of the message is to help you to identify the bug.&lt;br /&gt;
&lt;br /&gt;
All previous BGA api call are cancelled, and there will be no visible changes on the interface.&lt;br /&gt;
&lt;br /&gt;
   // Example :&lt;br /&gt;
   if( card_picked === null )&lt;br /&gt;
   {&lt;br /&gt;
       bga.error( &amp;quot;Cannot find a card to pick !&amp;quot; );&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
Note : you should NEVER wrap text inside bga.error with _() translation marker, because unexpected error should not be translate (so you can eventually recognize them when reported by players in bug report).&lt;br /&gt;
&lt;br /&gt;
== Game log (history) ==&lt;br /&gt;
&lt;br /&gt;
=== bga.log( txt, (optional) args ) ===&lt;br /&gt;
&lt;br /&gt;
Write something in the BGA log on the right.&lt;br /&gt;
&lt;br /&gt;
  // Example : simple log&lt;br /&gt;
  bga.log( _(&amp;quot;A new round starts&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
You may add arguments to your log, like this :&lt;br /&gt;
&lt;br /&gt;
  // Example: log with argument to display a card name.&lt;br /&gt;
  //          In this example, variable &amp;quot;event_name&amp;quot; is specified afterwards.&lt;br /&gt;
  //          Note that using this, game translators only have to translate one &amp;quot;Event XXX is triggered&amp;quot; string for all possible events.&lt;br /&gt;
  bga.log( _(&amp;quot;Event ${event_name} is triggered&amp;quot;), {  event_name: _( &amp;quot;Armageddon&amp;quot; ) } ) );&lt;br /&gt;
&lt;br /&gt;
Note that argument &amp;quot;player_name&amp;quot; is ALWAYS pre-set with the name of the current player, so you can use it immediately.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.log( _(&amp;quot;${player_name} draw a card from the deck&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
=== bga.speechBubble( target, text, (optional) args, (optional) delay, (optional) duration, (optional) size ) ===&lt;br /&gt;
&lt;br /&gt;
Display a &amp;quot;speech bubble&amp;quot;, attached to the specified target, containing the specified text.&lt;br /&gt;
&lt;br /&gt;
You can use &amp;quot;args&amp;quot; to customize text exactly like with bga.log.&lt;br /&gt;
&lt;br /&gt;
delay : milliseconds to wait before displaying the speech bubble (default : 0).&lt;br /&gt;
duration : how long to show the speech bubble in milliseconds (default : 3000).&lt;br /&gt;
size : size of the text in percent (default: 100)&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.speechBubble( _(&amp;quot;I play ${nbr} cards&amp;quot;), { nbr : 4 }, 0 );&lt;br /&gt;
  bga.speechBubble( _(&amp;quot;Good for you!&amp;quot;), { }, 2000 );&lt;br /&gt;
&lt;br /&gt;
=== bga.displayScoring( target, color, score ) ===&lt;br /&gt;
&lt;br /&gt;
Display an animated temporary &amp;quot;score number&amp;quot;, attached to the specified target.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;color&amp;quot; should be the color of the player who is scoring for that target.&lt;br /&gt;
&lt;br /&gt;
== Get / search game elements and their properties ==&lt;br /&gt;
&lt;br /&gt;
=== bga.getElement( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Allow you to retrieve informations about one game element specified using &amp;quot;selector&amp;quot; argument.&lt;br /&gt;
&lt;br /&gt;
Return null if no element is found.&lt;br /&gt;
&lt;br /&gt;
Note : getElement throw an error if several elements matches the selector. If you want to retrieve several elements, you should use &amp;quot;getElements&amp;quot; instead of &amp;quot;getElement&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The following examples are showing all the possible use of bga.getElement :&lt;br /&gt;
&lt;br /&gt;
  // Basic example :&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve the ID of a game element using its name (&amp;quot;Deck&amp;quot;)&lt;br /&gt;
  var deck_id = bga.getElement( { name: &amp;quot;Deck&amp;quot; } );&lt;br /&gt;
  // Return : 1234  &lt;br /&gt;
&lt;br /&gt;
  // Examples using &amp;quot;field&amp;quot; parameter :&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve a specific property from a game element using its name (&amp;quot;Deck&amp;quot;)&lt;br /&gt;
  var deck_id = bga.getElement( { name: &amp;quot;Deck&amp;quot; }, &#039;x&#039; );&lt;br /&gt;
  // Return : 20&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve several properties from the previous element&lt;br /&gt;
  var deck_properties = bga.getElement( { name: &amp;quot;Deck&amp;quot; }, [&#039;name&#039;,&#039;id&#039;,&#039;parent&#039;, &#039;x&#039;,&#039;y&#039;,&#039;canShuffle&#039;] );&lt;br /&gt;
  // Return : { name:&#039;Deck&#039;, id:1234, parent:4321, x: 20, y:50, canShuffle: true }&lt;br /&gt;
  &lt;br /&gt;
  // Note : as you can see, getElement returns:&lt;br /&gt;
  //        _ the element ID by default, or&lt;br /&gt;
  //        _ a single value if you request a single field, or&lt;br /&gt;
  //        _ an object if you request several fields&lt;br /&gt;
&lt;br /&gt;
  // Examples using different &amp;quot;selector&amp;quot; paramter&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve an element name from its id&lt;br /&gt;
  var deck_name = bga.getElement( { id: 1234 }, [&#039;name&#039;] );&lt;br /&gt;
  // Return : &amp;quot;Deck&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  // Retrieve the last child element of another element&lt;br /&gt;
  // Here, we are requesting for elements who has element with ID=1234 (Deck) as their parent&lt;br /&gt;
  // Note the use of &amp;quot;limit:1&amp;quot; which allows us to retrieve only 1 element.&lt;br /&gt;
  var first_card_on_deck_id = bga.getElement( { parent: 1234, limit:1 } );&lt;br /&gt;
  &lt;br /&gt;
  // You can also get nested properties such as the ids of the child elements of one element, or a custom property placed on the parent element&lt;br /&gt;
  var totem_places = bga.getElements( {tag:&#039;TOTEMZONE&#039;}, [&#039;id&#039;,&#039;childs:id&#039;,&#039;childs:tags&#039;,&#039;parent:id&#039;,&#039;parent:c_value&#039;] );&lt;br /&gt;
&lt;br /&gt;
=== bga.getElements( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Returns an object holding the properties of the elements matching the selector.&lt;br /&gt;
&lt;br /&gt;
  // Basic example: unselect all selected elements&lt;br /&gt;
  bga.removeStyle( bga.getElements( {tag: &#039;sbstyle_selected&#039;}), &#039;selected&#039; );&lt;br /&gt;
&lt;br /&gt;
=== bga.getElementsArray( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Returns an array of all elements matching the selector, holding the required properties.&lt;br /&gt;
&lt;br /&gt;
  // Basic example: get id of selected element&lt;br /&gt;
  var selected_tokens = bga.getElementsArray( {tag: &#039;sbstyle_selected&#039; } );&lt;br /&gt;
  var token_id = null;&lt;br /&gt;
  if (selected_tokens.length &amp;gt; 0) {&lt;br /&gt;
      token_id = selected_tokens[0];&lt;br /&gt;
  }&lt;br /&gt;
  return token_id;&lt;br /&gt;
&lt;br /&gt;
  // Classic example: get array of elements and iterate over it&lt;br /&gt;
  var all_cells = bga.getElementsArray( {tag: &#039;CELL&#039;}, [&#039;id&#039;,&#039;name&#039;,&#039;tags&#039;] );&lt;br /&gt;
  for (var i=0; i&amp;lt;all_cells.length; i++) {&lt;br /&gt;
     // ... process each cell ...&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Utility methods ==&lt;br /&gt;
&lt;br /&gt;
=== bga.isOn( element_id, parent_id ) ===&lt;br /&gt;
&lt;br /&gt;
Return true if &amp;quot;element_id&amp;quot; is a descendant of &amp;quot;parent_id&amp;quot; (ie : if element_id game element has been placed on parent_id game element).&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  if( bga.isOn( bga.getElementIfByName( &#039;Turn counter&#039; ), bga.getElementIfByName( &#039;Turn 6&#039; ) )&lt;br /&gt;
  {&lt;br /&gt;
     // Trigger game end&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Trigger most common game actions ==&lt;br /&gt;
&lt;br /&gt;
=== moveTo( id, target, path ) ===&lt;br /&gt;
&lt;br /&gt;
Move element to specified target id (eventually following path defined by an array of element ids to pass over on the way)&lt;br /&gt;
&lt;br /&gt;
The exact destination of element depends on target&#039;s &amp;quot;howToArrange&amp;quot; property (&amp;quot;How elements are arranged on it?&amp;quot; : spreaded/deck/...).&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.moveTo( bga.getElementIdByName( &#039;Turn counter&#039; ), bga.getElementIdByName( &#039;Turn 3&#039; ) );&lt;br /&gt;
&lt;br /&gt;
=== flip( element_ids ) ===&lt;br /&gt;
&lt;br /&gt;
Flip target element (or array of elements) if the elements are flippable (ex: cards).&lt;br /&gt;
&lt;br /&gt;
=== shuffle( element_ids ) ===&lt;br /&gt;
&lt;br /&gt;
Shuffle elements contained inside this element (or array of elements).&lt;br /&gt;
&lt;br /&gt;
=== incScore( color, value ) ===&lt;br /&gt;
&lt;br /&gt;
Increases the score for the player with the specified color, of the specified increment value.&lt;br /&gt;
&lt;br /&gt;
=== setScore( color, value ) ===&lt;br /&gt;
&lt;br /&gt;
Sets the score for the player with the specified color.&lt;br /&gt;
&lt;br /&gt;
=== getScore( color ) ===&lt;br /&gt;
&lt;br /&gt;
Gets the score of the player with the specified color.&lt;br /&gt;
&lt;br /&gt;
== Gamestate functions ==&lt;br /&gt;
&lt;br /&gt;
You can define your game flow with a list of states by adding a &amp;quot;states&amp;quot; function to your script.&lt;br /&gt;
&lt;br /&gt;
  function states()&lt;br /&gt;
  {&lt;br /&gt;
      return {&lt;br /&gt;
        // Init game&lt;br /&gt;
        100: {&lt;br /&gt;
            onState: &#039;postSetup&#039;,&lt;br /&gt;
            transitions: { done:200 }&lt;br /&gt;
        },&lt;br /&gt;
        200: {&lt;br /&gt;
            description: _(&#039;${actplayer} must move a piece&#039;),&lt;br /&gt;
            descriptionmyturn: _(&#039;${you} must move a piece&#039;),&lt;br /&gt;
            possibleactions: [&#039;movePiece&#039;],&lt;br /&gt;
            transitions: { nextPlayer: 200 }&lt;br /&gt;
        },&lt;br /&gt;
      };&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Then, you will be able to use the following functions to manage the game flow.&lt;br /&gt;
&lt;br /&gt;
=== checkAction( action ) ===&lt;br /&gt;
&lt;br /&gt;
Check if action is valid regarding current game state and raise an error if it&#039;s not the case.&lt;br /&gt;
&lt;br /&gt;
=== isActionPossible( action ) ===&lt;br /&gt;
&lt;br /&gt;
Check if action is valid regarding current game state and returns a boolean with the appropriate value.&lt;br /&gt;
&lt;br /&gt;
=== getActivePlayerColor() ===&lt;br /&gt;
&lt;br /&gt;
Returns the color code of the currently active player&lt;br /&gt;
&lt;br /&gt;
=== getActivePlayerName() ===&lt;br /&gt;
&lt;br /&gt;
Returns the color code of the currently active player&lt;br /&gt;
&lt;br /&gt;
=== nextPlayer() ===&lt;br /&gt;
&lt;br /&gt;
Activates the next player in play order.&lt;br /&gt;
&lt;br /&gt;
=== activeAllPlayers() ===&lt;br /&gt;
&lt;br /&gt;
Activates all players (multiactive state).&lt;br /&gt;
&lt;br /&gt;
=== endTurn( transition ) ===&lt;br /&gt;
&lt;br /&gt;
Make the current player inactive and go to the next state matching the provided transition if all players are inactive (multiactive state)&lt;br /&gt;
&lt;br /&gt;
=== getActivePlayerColors() ===&lt;br /&gt;
&lt;br /&gt;
Returns the colors code of the currently active players&lt;br /&gt;
&lt;br /&gt;
=== getCurrentPlayerColor() ===&lt;br /&gt;
&lt;br /&gt;
Returns the color code of the current player (the player who made the interface action being handled; may not be the active player).&lt;br /&gt;
&lt;br /&gt;
=== nextState( transition ) ===&lt;br /&gt;
&lt;br /&gt;
Moves to the next state matching the provided transition.&lt;br /&gt;
&lt;br /&gt;
=== gotoState( state_id ) ===&lt;br /&gt;
&lt;br /&gt;
Jumps to specified state.&lt;br /&gt;
&lt;br /&gt;
=== getPlayers() ===&lt;br /&gt;
&lt;br /&gt;
Returns an array of players with the players information.&lt;br /&gt;
&lt;br /&gt;
=== endGame() ===&lt;br /&gt;
&lt;br /&gt;
When the end game condition is met, you can use this function to end the game (after setting the appropriate scores!)&lt;br /&gt;
&lt;br /&gt;
== Other functions ==&lt;br /&gt;
&lt;br /&gt;
=== pause( milliseconds ) ===&lt;br /&gt;
&lt;br /&gt;
Pause the client interface during a specified number of milliseconds.&lt;br /&gt;
&lt;br /&gt;
If you do not use bga.pause, all Sandbox game actions are executed immediately and synchronously.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.log( &amp;quot;1&amp;quot; );    // Will be displayed immediately on the log&lt;br /&gt;
  bga.pause( 3000 ); // pause during 3 seconds&lt;br /&gt;
  bga.log( &amp;quot;2&amp;quot; );    // Will be displayed after the 3 second on the log&lt;br /&gt;
  bga.log( &amp;quot;3&amp;quot; );    // Will be displayed right after the previous one, without delay.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Tips : if you want to execute several consecutive &amp;quot;moveTo&amp;quot;, you should &amp;quot;bga.pause&amp;quot; between them, otherwise your element will move directly to the final destination.&lt;br /&gt;
&lt;br /&gt;
=== hasTag( id, tag ) ===&lt;br /&gt;
&lt;br /&gt;
Returns true if the element with this id has this tag.&lt;br /&gt;
&lt;br /&gt;
=== addTag( id, tag ) ===&lt;br /&gt;
&lt;br /&gt;
Adds this tag to the element with this id.&lt;br /&gt;
&lt;br /&gt;
=== removeTag( id, tag ) ===&lt;br /&gt;
&lt;br /&gt;
Removes this tag from the element with this id.&lt;br /&gt;
&lt;br /&gt;
=== addStyle( id, style ) ===&lt;br /&gt;
&lt;br /&gt;
Adds this style to the element with this id.&lt;br /&gt;
&lt;br /&gt;
Predefined styles are: SELECTED / LIGHT / LIGHTBACKGROUND / REDSELECTED / CLICKABLE / ROUNDED / CLICKABLE_ROUNDED&lt;br /&gt;
&lt;br /&gt;
=== removeStyle( id, style ) ===&lt;br /&gt;
&lt;br /&gt;
Removes this style from the element with this id.&lt;br /&gt;
&lt;br /&gt;
=== setProperties( props ) ===&lt;br /&gt;
&lt;br /&gt;
This function allows to directly update properties of an object, and to manage custom properties if needed (custom properties must start with prefix &amp;quot;c_&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
    // Update player labels for player zones from &amp;quot;&amp;lt;color&amp;gt; player&amp;quot; to actual player name&lt;br /&gt;
    var players = bga.getPlayers();&lt;br /&gt;
    for (var color in players) {&lt;br /&gt;
        player = players[color];&lt;br /&gt;
        &lt;br /&gt;
        var labelId = null;&lt;br /&gt;
        if (color == &#039;ff0000&#039;) labelId = bga.getElement( {name: &#039;Red player&#039;} );&lt;br /&gt;
        if (color == &#039;008000&#039;) labelId = bga.getElement( {name: &#039;Green player&#039;} );&lt;br /&gt;
        if (color == &#039;0000ff&#039;) labelId = bga.getElement( {name: &#039;Blue player&#039;} );&lt;br /&gt;
        if (color == &#039;ffa500&#039;) labelId = bga.getElement( {name: &#039;Yellow player&#039;} );&lt;br /&gt;
        &lt;br /&gt;
        var props = [];&lt;br /&gt;
        props[labelId] = {name: player.name};&lt;br /&gt;
        bga.setProperties( props );&lt;br /&gt;
    }&lt;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://sr.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=3051</id>
		<title>SandboxScripts</title>
		<link rel="alternate" type="text/html" href="https://sr.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=3051"/>
		<updated>2018-05-18T08:47:35Z</updated>

		<summary type="html">&lt;p&gt;Een: /* = shuffle( element_ids ) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This is the reference of functions you can call from your Sandbox scripts.&lt;br /&gt;
&lt;br /&gt;
= Javascript =&lt;br /&gt;
&lt;br /&gt;
BGA Sandbox scripts are written in Javascript.&lt;br /&gt;
&lt;br /&gt;
Using Javascript, you can write scripts to automate moves for your Sandbox games &amp;amp; provide rules reinforcement.&lt;br /&gt;
&lt;br /&gt;
Important : in the opposite of the most common usage of Javascript, Sandbox scripts are executed &#039;&#039;&#039;on server side&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
= BGA API =&lt;br /&gt;
&lt;br /&gt;
To interact with your BGA Sandbox game, we provide you an API.&lt;br /&gt;
&lt;br /&gt;
With this API, you can get properties values of game elements from the current game situation, modify them and/or trigger the game actions (ex : move this element here, flip this card, and so on).&lt;br /&gt;
&lt;br /&gt;
= Quick start =&lt;br /&gt;
&lt;br /&gt;
== Hello World Script ==&lt;br /&gt;
&lt;br /&gt;
From Sandbox editor &amp;quot;interface view&amp;quot; tab, select an element, and access to its property (top right icon).&lt;br /&gt;
&lt;br /&gt;
Go to &amp;quot;Scripts (advanced)&amp;quot; section.&lt;br /&gt;
&lt;br /&gt;
In front of &amp;quot;When this element is clicked&amp;quot;, enter &amp;quot;onMyClick&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Close the window. Go to &amp;quot;script view&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Enter the following :&lt;br /&gt;
&lt;br /&gt;
 function onMyClick( element_id )&lt;br /&gt;
 {&lt;br /&gt;
    bga.log(&amp;quot;Hello world! You just clicked on element &amp;quot; + element_id + &amp;quot;. Congrats!&amp;quot;);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Save &amp;amp; publish your project, starts a test session, click on the previous element : your message appears in the log on the right!&lt;br /&gt;
&lt;br /&gt;
== Top useful tips ==&lt;br /&gt;
&lt;br /&gt;
* You don&#039;t have to save&amp;amp;publish from the Sandbox editor for each modification of your script : each time you save your script (control+S), the script used for all test sessions is updated. Note that the production version on BGA is of course NOT updated until you explicitly save&amp;amp;publish again your project.&lt;br /&gt;
&lt;br /&gt;
* To inspect the content of a variable, you can use bga.log() in combination with JSON.stringify(). For example :&lt;br /&gt;
&lt;br /&gt;
  bga.log( JSON.stringify( bga.getPlayers()) );&lt;br /&gt;
&lt;br /&gt;
* Alternatively to bga.log(), you can use bga.exit( &amp;quot;my message&amp;quot; ) to debug your script. With bga.exit, the script execution immediately stops and all previous game changes are cancelled, so this is very practical to try and retry an action until your script is fine.&lt;br /&gt;
&lt;br /&gt;
* We advise you to develop first a full playable version of the game without the scripts, and THEN to script it.&lt;br /&gt;
&lt;br /&gt;
* On Board Game Arena, players have come to expect fully implemented games with all rules enforced. So even if it&#039;s technically possible not to script the full game and to implement the game only partially, in most cases we&#039;ll publish only fully scripted games :)&lt;br /&gt;
&lt;br /&gt;
= Functions you can use in your Sandbox scripts=&lt;br /&gt;
&lt;br /&gt;
== Debugging functions ==&lt;br /&gt;
&lt;br /&gt;
=== bga.trace( txt / obj ) ===&lt;br /&gt;
&lt;br /&gt;
Write something immediately in the BGA log (on the right of the screen).&lt;br /&gt;
&lt;br /&gt;
This is the most practical way to debug your script :)&lt;br /&gt;
&lt;br /&gt;
Important : bga.trace is for debugging purpose only and won&#039;t be displayed on production.&lt;br /&gt;
&lt;br /&gt;
Note : you can also pass an object in parameter. This will dump the content of this object in the log.&lt;br /&gt;
&lt;br /&gt;
Note : in the opposite of bga.log, bga.trace is NOT cancelled if the game action failed (after a call to bga.cancel or bga.error). This makes bga.trace very practical to debug a game action that failed, and for this reason you should probably NEVER use bga.log for debugging purpose.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  // Example : write &amp;quot;Hello world&amp;quot; in the log&lt;br /&gt;
  bga.trace( &amp;quot;Hello world&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Example : dump an associative array in the log&lt;br /&gt;
  bga.trace( { mykey: &#039;myvalue&#039;, another_key: &#039;another_value&#039; } );&lt;br /&gt;
&lt;br /&gt;
=== bga.exit( txt / obj ) ===&lt;br /&gt;
&lt;br /&gt;
Stop the script immediately, display the &amp;quot;txt&amp;quot; messages and cancel (ie : rollback) on every previous API call except bga.trace :&lt;br /&gt;
&lt;br /&gt;
ALL previous BGA api call are canceled and there will be no visible changes on the interface (ex : no moves, no visible property changes, ...). Only &amp;quot;bga.trace&amp;quot; API commands are kept so you can debug.&lt;br /&gt;
&lt;br /&gt;
bga.exit is very practical when you want to repeat a game action again and again to debug it : with a call to bga.exit at the end of your script, you make sure that your game situation will be kept unchanged after each test.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.exit( &amp;quot;My script is stopped by this call&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Example with dumping a javascript variable&lt;br /&gt;
  bga.exit( my_variable_to_dump );&lt;br /&gt;
&lt;br /&gt;
== Cancelling a game action ==&lt;br /&gt;
&lt;br /&gt;
=== bga.cancel( txt ) ===&lt;br /&gt;
&lt;br /&gt;
This is the function to use when a player is doing something against game rules.&lt;br /&gt;
&lt;br /&gt;
The text message in parameter will be displayed to this player as a &amp;quot;red message&amp;quot;, so he/she can understand the rule.&lt;br /&gt;
&lt;br /&gt;
All previous BGA api call are cancelled, and there will be no visible changes on the interface.&lt;br /&gt;
&lt;br /&gt;
   // Example :&lt;br /&gt;
   bga.cancel( _(&amp;quot;You cannot move this piece here&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
Note : most of the time, you should wrap your text inside a _() translation marker to make this string translatable.&lt;br /&gt;
&lt;br /&gt;
=== bga.error( text ) ===&lt;br /&gt;
&lt;br /&gt;
This is the function to use when some unexpected error happens in your script.&lt;br /&gt;
&lt;br /&gt;
The text message will be displayed to user, with mention &amp;quot;Unexpected error&amp;quot;. The player will be incited to fill a bug report. The purpose of the message is to help you to identify the bug.&lt;br /&gt;
&lt;br /&gt;
All previous BGA api call are cancelled, and there will be no visible changes on the interface.&lt;br /&gt;
&lt;br /&gt;
   // Example :&lt;br /&gt;
   if( card_picked === null )&lt;br /&gt;
   {&lt;br /&gt;
       bga.error( &amp;quot;Cannot find a card to pick !&amp;quot; );&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
Note : you should NEVER wrap text inside bga.error with _() translation marker, because unexpected error should not be translate (so you can eventually recognize them when reported by players in bug report).&lt;br /&gt;
&lt;br /&gt;
== Game log (history) ==&lt;br /&gt;
&lt;br /&gt;
=== bga.log( txt, (optional) args ) ===&lt;br /&gt;
&lt;br /&gt;
Write something in the BGA log on the right.&lt;br /&gt;
&lt;br /&gt;
  // Example : simple log&lt;br /&gt;
  bga.log( _(&amp;quot;A new round starts&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
You may add arguments to your log, like this :&lt;br /&gt;
&lt;br /&gt;
  // Example: log with argument to display a card name.&lt;br /&gt;
  //          In this example, variable &amp;quot;event_name&amp;quot; is specified afterwards.&lt;br /&gt;
  //          Note that using this, game translators only have to translate one &amp;quot;Event XXX is triggered&amp;quot; string for all possible events.&lt;br /&gt;
  bga.log( _(&amp;quot;Event ${event_name} is triggered&amp;quot;), {  event_name: _( &amp;quot;Armageddon&amp;quot; ) } ) );&lt;br /&gt;
&lt;br /&gt;
Note that argument &amp;quot;player_name&amp;quot; is ALWAYS pre-set with the name of the current player, so you can use it immediately.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.log( _(&amp;quot;${player_name} draw a card from the deck&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
=== bga.speechBubble( target, text, (optional) args, (optional) delay, (optional) duration, (optional) size ) ===&lt;br /&gt;
&lt;br /&gt;
Display a &amp;quot;speech bubble&amp;quot;, attached to the specified target, containing the specified text.&lt;br /&gt;
&lt;br /&gt;
You can use &amp;quot;args&amp;quot; to customize text exactly like with bga.log.&lt;br /&gt;
&lt;br /&gt;
delay : milliseconds to wait before displaying the speech bubble (default : 0).&lt;br /&gt;
duration : how long to show the speech bubble in milliseconds (default : 3000).&lt;br /&gt;
size : size of the text in percent (default: 100)&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.speechBubble( _(&amp;quot;I play ${nbr} cards&amp;quot;), { nbr : 4 }, 0 );&lt;br /&gt;
  bga.speechBubble( _(&amp;quot;Good for you!&amp;quot;), { }, 2000 );&lt;br /&gt;
&lt;br /&gt;
=== bga.displayScoring( target, color, score ) ===&lt;br /&gt;
&lt;br /&gt;
Display an animated temporary &amp;quot;score number&amp;quot;, attached to the specified target.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;color&amp;quot; should be the color of the player who is scoring for that target.&lt;br /&gt;
&lt;br /&gt;
== Get / search game elements and their properties ==&lt;br /&gt;
&lt;br /&gt;
=== bga.getElement( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Allow you to retrieve informations about one game element specified using &amp;quot;selector&amp;quot; argument.&lt;br /&gt;
&lt;br /&gt;
Return null if no element is found.&lt;br /&gt;
&lt;br /&gt;
Note : getElement throw an error if several elements matches the selector. If you want to retrieve several elements, you should use &amp;quot;getElements&amp;quot; instead of &amp;quot;getElement&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The following examples are showing all the possible use of bga.getElement :&lt;br /&gt;
&lt;br /&gt;
  // Basic example :&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve the ID of a game element using its name (&amp;quot;Deck&amp;quot;)&lt;br /&gt;
  var deck_id = bga.getElement( { name: &amp;quot;Deck&amp;quot; } );&lt;br /&gt;
  // Return : 1234  &lt;br /&gt;
&lt;br /&gt;
  // Examples using &amp;quot;field&amp;quot; parameter :&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve a specific property from a game element using its name (&amp;quot;Deck&amp;quot;)&lt;br /&gt;
  var deck_id = bga.getElement( { name: &amp;quot;Deck&amp;quot; }, &#039;x&#039; );&lt;br /&gt;
  // Return : 20&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve several properties from the previous element&lt;br /&gt;
  var deck_properties = bga.getElement( { name: &amp;quot;Deck&amp;quot; }, [&#039;name&#039;,&#039;id&#039;,&#039;parent&#039;, &#039;x&#039;,&#039;y&#039;,&#039;canShuffle&#039;] );&lt;br /&gt;
  // Return : { name:&#039;Deck&#039;, id:1234, parent:4321, x: 20, y:50, canShuffle: true }&lt;br /&gt;
  &lt;br /&gt;
  // Note : as you can see, getElement returns:&lt;br /&gt;
  //        _ the element ID by default, or&lt;br /&gt;
  //        _ a single value if you request a single field, or&lt;br /&gt;
  //        _ an object if you request several fields&lt;br /&gt;
&lt;br /&gt;
  // Examples using different &amp;quot;selector&amp;quot; paramter&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve an element name from its id&lt;br /&gt;
  var deck_name = bga.getElement( { id: 1234 }, [&#039;name&#039;] );&lt;br /&gt;
  // Return : &amp;quot;Deck&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  // Retrieve the last child element of another element&lt;br /&gt;
  // Here, we are requesting for elements who has element with ID=1234 (Deck) as their parent&lt;br /&gt;
  // Note the use of &amp;quot;limit:1&amp;quot; which allows us to retrieve only 1 element.&lt;br /&gt;
  var first_card_on_deck_id = bga.getElement( { parent: 1234, limit:1 } );&lt;br /&gt;
  &lt;br /&gt;
  // You can also get nested properties such as the ids of the child elements of one element, or a custom property placed on the parent element&lt;br /&gt;
  var totem_places = bga.getElements( {tag:&#039;TOTEMZONE&#039;}, [&#039;id&#039;,&#039;childs:id&#039;,&#039;childs:tags&#039;,&#039;parent:id&#039;,&#039;parent:c_value&#039;] );&lt;br /&gt;
&lt;br /&gt;
=== bga.getElements( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Returns an object holding the properties of the elements matching the selector.&lt;br /&gt;
&lt;br /&gt;
  // Basic example: unselect all selected elements&lt;br /&gt;
  bga.removeStyle( bga.getElements( {tag: &#039;sbstyle_selected&#039;}), &#039;selected&#039; );&lt;br /&gt;
&lt;br /&gt;
=== bga.getElementsArray( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Returns an array of all elements matching the selector, holding the required properties.&lt;br /&gt;
&lt;br /&gt;
  // Basic example: get id of selected element&lt;br /&gt;
  var selected_tokens = bga.getElementsArray( {tag: &#039;sbstyle_selected&#039; } );&lt;br /&gt;
  var token_id = null;&lt;br /&gt;
  if (selected_tokens.length &amp;gt; 0) {&lt;br /&gt;
      token_id = selected_tokens[0];&lt;br /&gt;
  }&lt;br /&gt;
  return token_id;&lt;br /&gt;
&lt;br /&gt;
  // Classic example: get array of elements and iterate over it&lt;br /&gt;
  var all_cells = bga.getElementsArray( {tag: &#039;CELL&#039;}, [&#039;id&#039;,&#039;name&#039;,&#039;tags&#039;] );&lt;br /&gt;
  for (var i=0; i&amp;lt;all_cells.length; i++) {&lt;br /&gt;
     // ... process each cell ...&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Utility methods ==&lt;br /&gt;
&lt;br /&gt;
=== bga.isOn( element_id, parent_id ) ===&lt;br /&gt;
&lt;br /&gt;
Return true if &amp;quot;element_id&amp;quot; is a descendant of &amp;quot;parent_id&amp;quot; (ie : if element_id game element has been placed on parent_id game element).&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  if( bga.isOn( bga.getElementIfByName( &#039;Turn counter&#039; ), bga.getElementIfByName( &#039;Turn 6&#039; ) )&lt;br /&gt;
  {&lt;br /&gt;
     // Trigger game end&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Trigger most common game actions ==&lt;br /&gt;
&lt;br /&gt;
=== moveTo( id, target, path ) ===&lt;br /&gt;
&lt;br /&gt;
Move element to specified target id (eventually following path defined by an array of element ids to pass over on the way)&lt;br /&gt;
&lt;br /&gt;
The exact destination of element depends on target&#039;s &amp;quot;howToArrange&amp;quot; property (&amp;quot;How elements are arranged on it?&amp;quot; : spreaded/deck/...).&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.moveTo( bga.getElementIdByName( &#039;Turn counter&#039; ), bga.getElementIdByName( &#039;Turn 3&#039; ) );&lt;br /&gt;
&lt;br /&gt;
=== flip( element_ids ) ===&lt;br /&gt;
&lt;br /&gt;
Flip target element (or array of elements) if the elements are flippable (ex: cards).&lt;br /&gt;
&lt;br /&gt;
=== shuffle( element_ids ) ===&lt;br /&gt;
&lt;br /&gt;
Shuffle elements contained inside this element (or array of elements).&lt;br /&gt;
&lt;br /&gt;
=== incScore( color, value ) ===&lt;br /&gt;
&lt;br /&gt;
Increases the score for the player with the specified color, of the specified increment value.&lt;br /&gt;
&lt;br /&gt;
=== setScore( color, value ) ===&lt;br /&gt;
&lt;br /&gt;
Sets the score for the player with the specified color.&lt;br /&gt;
&lt;br /&gt;
=== getScore( color ) ===&lt;br /&gt;
&lt;br /&gt;
Gets the score of the player with the specified color.&lt;br /&gt;
&lt;br /&gt;
== Gamestate functions ==&lt;br /&gt;
&lt;br /&gt;
You can define your game flow with a list of states by adding a &amp;quot;states&amp;quot; function to your script.&lt;br /&gt;
&lt;br /&gt;
  function states()&lt;br /&gt;
  {&lt;br /&gt;
      return {&lt;br /&gt;
        // Init game&lt;br /&gt;
        100: {&lt;br /&gt;
            onState: &#039;postSetup&#039;,&lt;br /&gt;
            transitions: { done:200 }&lt;br /&gt;
        },&lt;br /&gt;
        200: {&lt;br /&gt;
            description: _(&#039;${actplayer} must move a piece&#039;),&lt;br /&gt;
            descriptionmyturn: _(&#039;${you} must move a piece&#039;),&lt;br /&gt;
            possibleactions: [&#039;movePiece&#039;],&lt;br /&gt;
            transitions: { nextPlayer: 200 }&lt;br /&gt;
        },&lt;br /&gt;
      };&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Then, you will be able to use the following functions to manage the game flow.&lt;br /&gt;
&lt;br /&gt;
=== checkAction( action ) ===&lt;br /&gt;
&lt;br /&gt;
Check if action is valid regarding current game state and raise an error if it&#039;s not the case.&lt;br /&gt;
&lt;br /&gt;
=== isActionPossible( action ) ===&lt;br /&gt;
&lt;br /&gt;
Check if action is valid regarding current game state and returns a boolean with the appropriate value.&lt;br /&gt;
&lt;br /&gt;
=== getActivePlayerColor() ===&lt;br /&gt;
&lt;br /&gt;
Returns the color code of the currently active player&lt;br /&gt;
&lt;br /&gt;
=== getActivePlayerName() ===&lt;br /&gt;
&lt;br /&gt;
Returns the color code of the currently active player&lt;br /&gt;
&lt;br /&gt;
=== nextPlayer() ===&lt;br /&gt;
&lt;br /&gt;
Activates the next player in play order.&lt;br /&gt;
&lt;br /&gt;
=== activeAllPlayers() ===&lt;br /&gt;
&lt;br /&gt;
Activates all players (multiactive state).&lt;br /&gt;
&lt;br /&gt;
=== endTurn( transition ) ===&lt;br /&gt;
&lt;br /&gt;
Make the current player inactive and go to the next state matching the provided transition if all players are inactive (multiactive state)&lt;br /&gt;
&lt;br /&gt;
=== getActivePlayerColors() ===&lt;br /&gt;
&lt;br /&gt;
Returns the colors code of the currently active players&lt;br /&gt;
&lt;br /&gt;
=== getCurrentPlayerColor() ===&lt;br /&gt;
&lt;br /&gt;
Returns the color code of the current player (the player who made the interface action being handled; may not be the active player).&lt;br /&gt;
&lt;br /&gt;
=== nextState( transition ) ===&lt;br /&gt;
&lt;br /&gt;
Moves to the next state matching the provided transition.&lt;br /&gt;
&lt;br /&gt;
=== getPlayers() ===&lt;br /&gt;
&lt;br /&gt;
Returns an array of players with the players information.&lt;br /&gt;
&lt;br /&gt;
=== endGame() ===&lt;br /&gt;
&lt;br /&gt;
When the end game condition is met, you can use this function to end the game (after setting the appropriate scores!)&lt;br /&gt;
&lt;br /&gt;
== Other functions ==&lt;br /&gt;
&lt;br /&gt;
=== pause( milliseconds ) ===&lt;br /&gt;
&lt;br /&gt;
Pause the client interface during a specified number of milliseconds.&lt;br /&gt;
&lt;br /&gt;
If you do not use bga.pause, all Sandbox game actions are executed immediately and synchronously.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.log( &amp;quot;1&amp;quot; );    // Will be displayed immediately on the log&lt;br /&gt;
  bga.pause( 3000 ); // pause during 3 seconds&lt;br /&gt;
  bga.log( &amp;quot;2&amp;quot; );    // Will be displayed after the 3 second on the log&lt;br /&gt;
  bga.log( &amp;quot;3&amp;quot; );    // Will be displayed right after the previous one, without delay.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Tips : if you want to execute several consecutive &amp;quot;moveTo&amp;quot;, you should &amp;quot;bga.pause&amp;quot; between them, otherwise your element will move directly to the final destination.&lt;br /&gt;
&lt;br /&gt;
=== hasTag( id, tag ) ===&lt;br /&gt;
&lt;br /&gt;
Returns true if the element with this id has this tag.&lt;br /&gt;
&lt;br /&gt;
=== addTag( id, tag ) ===&lt;br /&gt;
&lt;br /&gt;
Adds this tag to the element with this id.&lt;br /&gt;
&lt;br /&gt;
=== removeTag( id, tag ) ===&lt;br /&gt;
&lt;br /&gt;
Removes this tag from the element with this id.&lt;br /&gt;
&lt;br /&gt;
=== addStyle( id, style ) ===&lt;br /&gt;
&lt;br /&gt;
Adds this style to the element with this id.&lt;br /&gt;
&lt;br /&gt;
Predefined styles are: SELECTED / LIGHT / LIGHTBACKGROUND / REDSELECTED / CLICKABLE / ROUNDED / CLICKABLE_ROUNDED&lt;br /&gt;
&lt;br /&gt;
=== removeStyle( id, style ) ===&lt;br /&gt;
&lt;br /&gt;
Removes this style from the element with this id.&lt;br /&gt;
&lt;br /&gt;
=== setProperties( props ) ===&lt;br /&gt;
&lt;br /&gt;
This function allows to directly update properties of an object, and to manage custom properties if needed (custom properties must start with prefix &amp;quot;c_&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
    // Update player labels for player zones from &amp;quot;&amp;lt;color&amp;gt; player&amp;quot; to actual player name&lt;br /&gt;
    var players = bga.getPlayers();&lt;br /&gt;
    for (var color in players) {&lt;br /&gt;
        player = players[color];&lt;br /&gt;
        &lt;br /&gt;
        var labelId = null;&lt;br /&gt;
        if (color == &#039;ff0000&#039;) labelId = bga.getElement( {name: &#039;Red player&#039;} );&lt;br /&gt;
        if (color == &#039;008000&#039;) labelId = bga.getElement( {name: &#039;Green player&#039;} );&lt;br /&gt;
        if (color == &#039;0000ff&#039;) labelId = bga.getElement( {name: &#039;Blue player&#039;} );&lt;br /&gt;
        if (color == &#039;ffa500&#039;) labelId = bga.getElement( {name: &#039;Yellow player&#039;} );&lt;br /&gt;
        &lt;br /&gt;
        var props = [];&lt;br /&gt;
        props[labelId] = {name: player.name};&lt;br /&gt;
        bga.setProperties( props );&lt;br /&gt;
    }&lt;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://sr.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=3050</id>
		<title>SandboxScripts</title>
		<link rel="alternate" type="text/html" href="https://sr.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=3050"/>
		<updated>2018-05-18T08:47:25Z</updated>

		<summary type="html">&lt;p&gt;Een: /* = flip( element_ids ) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This is the reference of functions you can call from your Sandbox scripts.&lt;br /&gt;
&lt;br /&gt;
= Javascript =&lt;br /&gt;
&lt;br /&gt;
BGA Sandbox scripts are written in Javascript.&lt;br /&gt;
&lt;br /&gt;
Using Javascript, you can write scripts to automate moves for your Sandbox games &amp;amp; provide rules reinforcement.&lt;br /&gt;
&lt;br /&gt;
Important : in the opposite of the most common usage of Javascript, Sandbox scripts are executed &#039;&#039;&#039;on server side&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
= BGA API =&lt;br /&gt;
&lt;br /&gt;
To interact with your BGA Sandbox game, we provide you an API.&lt;br /&gt;
&lt;br /&gt;
With this API, you can get properties values of game elements from the current game situation, modify them and/or trigger the game actions (ex : move this element here, flip this card, and so on).&lt;br /&gt;
&lt;br /&gt;
= Quick start =&lt;br /&gt;
&lt;br /&gt;
== Hello World Script ==&lt;br /&gt;
&lt;br /&gt;
From Sandbox editor &amp;quot;interface view&amp;quot; tab, select an element, and access to its property (top right icon).&lt;br /&gt;
&lt;br /&gt;
Go to &amp;quot;Scripts (advanced)&amp;quot; section.&lt;br /&gt;
&lt;br /&gt;
In front of &amp;quot;When this element is clicked&amp;quot;, enter &amp;quot;onMyClick&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Close the window. Go to &amp;quot;script view&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Enter the following :&lt;br /&gt;
&lt;br /&gt;
 function onMyClick( element_id )&lt;br /&gt;
 {&lt;br /&gt;
    bga.log(&amp;quot;Hello world! You just clicked on element &amp;quot; + element_id + &amp;quot;. Congrats!&amp;quot;);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Save &amp;amp; publish your project, starts a test session, click on the previous element : your message appears in the log on the right!&lt;br /&gt;
&lt;br /&gt;
== Top useful tips ==&lt;br /&gt;
&lt;br /&gt;
* You don&#039;t have to save&amp;amp;publish from the Sandbox editor for each modification of your script : each time you save your script (control+S), the script used for all test sessions is updated. Note that the production version on BGA is of course NOT updated until you explicitly save&amp;amp;publish again your project.&lt;br /&gt;
&lt;br /&gt;
* To inspect the content of a variable, you can use bga.log() in combination with JSON.stringify(). For example :&lt;br /&gt;
&lt;br /&gt;
  bga.log( JSON.stringify( bga.getPlayers()) );&lt;br /&gt;
&lt;br /&gt;
* Alternatively to bga.log(), you can use bga.exit( &amp;quot;my message&amp;quot; ) to debug your script. With bga.exit, the script execution immediately stops and all previous game changes are cancelled, so this is very practical to try and retry an action until your script is fine.&lt;br /&gt;
&lt;br /&gt;
* We advise you to develop first a full playable version of the game without the scripts, and THEN to script it.&lt;br /&gt;
&lt;br /&gt;
* On Board Game Arena, players have come to expect fully implemented games with all rules enforced. So even if it&#039;s technically possible not to script the full game and to implement the game only partially, in most cases we&#039;ll publish only fully scripted games :)&lt;br /&gt;
&lt;br /&gt;
= Functions you can use in your Sandbox scripts=&lt;br /&gt;
&lt;br /&gt;
== Debugging functions ==&lt;br /&gt;
&lt;br /&gt;
=== bga.trace( txt / obj ) ===&lt;br /&gt;
&lt;br /&gt;
Write something immediately in the BGA log (on the right of the screen).&lt;br /&gt;
&lt;br /&gt;
This is the most practical way to debug your script :)&lt;br /&gt;
&lt;br /&gt;
Important : bga.trace is for debugging purpose only and won&#039;t be displayed on production.&lt;br /&gt;
&lt;br /&gt;
Note : you can also pass an object in parameter. This will dump the content of this object in the log.&lt;br /&gt;
&lt;br /&gt;
Note : in the opposite of bga.log, bga.trace is NOT cancelled if the game action failed (after a call to bga.cancel or bga.error). This makes bga.trace very practical to debug a game action that failed, and for this reason you should probably NEVER use bga.log for debugging purpose.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  // Example : write &amp;quot;Hello world&amp;quot; in the log&lt;br /&gt;
  bga.trace( &amp;quot;Hello world&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Example : dump an associative array in the log&lt;br /&gt;
  bga.trace( { mykey: &#039;myvalue&#039;, another_key: &#039;another_value&#039; } );&lt;br /&gt;
&lt;br /&gt;
=== bga.exit( txt / obj ) ===&lt;br /&gt;
&lt;br /&gt;
Stop the script immediately, display the &amp;quot;txt&amp;quot; messages and cancel (ie : rollback) on every previous API call except bga.trace :&lt;br /&gt;
&lt;br /&gt;
ALL previous BGA api call are canceled and there will be no visible changes on the interface (ex : no moves, no visible property changes, ...). Only &amp;quot;bga.trace&amp;quot; API commands are kept so you can debug.&lt;br /&gt;
&lt;br /&gt;
bga.exit is very practical when you want to repeat a game action again and again to debug it : with a call to bga.exit at the end of your script, you make sure that your game situation will be kept unchanged after each test.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.exit( &amp;quot;My script is stopped by this call&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Example with dumping a javascript variable&lt;br /&gt;
  bga.exit( my_variable_to_dump );&lt;br /&gt;
&lt;br /&gt;
== Cancelling a game action ==&lt;br /&gt;
&lt;br /&gt;
=== bga.cancel( txt ) ===&lt;br /&gt;
&lt;br /&gt;
This is the function to use when a player is doing something against game rules.&lt;br /&gt;
&lt;br /&gt;
The text message in parameter will be displayed to this player as a &amp;quot;red message&amp;quot;, so he/she can understand the rule.&lt;br /&gt;
&lt;br /&gt;
All previous BGA api call are cancelled, and there will be no visible changes on the interface.&lt;br /&gt;
&lt;br /&gt;
   // Example :&lt;br /&gt;
   bga.cancel( _(&amp;quot;You cannot move this piece here&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
Note : most of the time, you should wrap your text inside a _() translation marker to make this string translatable.&lt;br /&gt;
&lt;br /&gt;
=== bga.error( text ) ===&lt;br /&gt;
&lt;br /&gt;
This is the function to use when some unexpected error happens in your script.&lt;br /&gt;
&lt;br /&gt;
The text message will be displayed to user, with mention &amp;quot;Unexpected error&amp;quot;. The player will be incited to fill a bug report. The purpose of the message is to help you to identify the bug.&lt;br /&gt;
&lt;br /&gt;
All previous BGA api call are cancelled, and there will be no visible changes on the interface.&lt;br /&gt;
&lt;br /&gt;
   // Example :&lt;br /&gt;
   if( card_picked === null )&lt;br /&gt;
   {&lt;br /&gt;
       bga.error( &amp;quot;Cannot find a card to pick !&amp;quot; );&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
Note : you should NEVER wrap text inside bga.error with _() translation marker, because unexpected error should not be translate (so you can eventually recognize them when reported by players in bug report).&lt;br /&gt;
&lt;br /&gt;
== Game log (history) ==&lt;br /&gt;
&lt;br /&gt;
=== bga.log( txt, (optional) args ) ===&lt;br /&gt;
&lt;br /&gt;
Write something in the BGA log on the right.&lt;br /&gt;
&lt;br /&gt;
  // Example : simple log&lt;br /&gt;
  bga.log( _(&amp;quot;A new round starts&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
You may add arguments to your log, like this :&lt;br /&gt;
&lt;br /&gt;
  // Example: log with argument to display a card name.&lt;br /&gt;
  //          In this example, variable &amp;quot;event_name&amp;quot; is specified afterwards.&lt;br /&gt;
  //          Note that using this, game translators only have to translate one &amp;quot;Event XXX is triggered&amp;quot; string for all possible events.&lt;br /&gt;
  bga.log( _(&amp;quot;Event ${event_name} is triggered&amp;quot;), {  event_name: _( &amp;quot;Armageddon&amp;quot; ) } ) );&lt;br /&gt;
&lt;br /&gt;
Note that argument &amp;quot;player_name&amp;quot; is ALWAYS pre-set with the name of the current player, so you can use it immediately.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.log( _(&amp;quot;${player_name} draw a card from the deck&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
=== bga.speechBubble( target, text, (optional) args, (optional) delay, (optional) duration, (optional) size ) ===&lt;br /&gt;
&lt;br /&gt;
Display a &amp;quot;speech bubble&amp;quot;, attached to the specified target, containing the specified text.&lt;br /&gt;
&lt;br /&gt;
You can use &amp;quot;args&amp;quot; to customize text exactly like with bga.log.&lt;br /&gt;
&lt;br /&gt;
delay : milliseconds to wait before displaying the speech bubble (default : 0).&lt;br /&gt;
duration : how long to show the speech bubble in milliseconds (default : 3000).&lt;br /&gt;
size : size of the text in percent (default: 100)&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.speechBubble( _(&amp;quot;I play ${nbr} cards&amp;quot;), { nbr : 4 }, 0 );&lt;br /&gt;
  bga.speechBubble( _(&amp;quot;Good for you!&amp;quot;), { }, 2000 );&lt;br /&gt;
&lt;br /&gt;
=== bga.displayScoring( target, color, score ) ===&lt;br /&gt;
&lt;br /&gt;
Display an animated temporary &amp;quot;score number&amp;quot;, attached to the specified target.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;color&amp;quot; should be the color of the player who is scoring for that target.&lt;br /&gt;
&lt;br /&gt;
== Get / search game elements and their properties ==&lt;br /&gt;
&lt;br /&gt;
=== bga.getElement( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Allow you to retrieve informations about one game element specified using &amp;quot;selector&amp;quot; argument.&lt;br /&gt;
&lt;br /&gt;
Return null if no element is found.&lt;br /&gt;
&lt;br /&gt;
Note : getElement throw an error if several elements matches the selector. If you want to retrieve several elements, you should use &amp;quot;getElements&amp;quot; instead of &amp;quot;getElement&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The following examples are showing all the possible use of bga.getElement :&lt;br /&gt;
&lt;br /&gt;
  // Basic example :&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve the ID of a game element using its name (&amp;quot;Deck&amp;quot;)&lt;br /&gt;
  var deck_id = bga.getElement( { name: &amp;quot;Deck&amp;quot; } );&lt;br /&gt;
  // Return : 1234  &lt;br /&gt;
&lt;br /&gt;
  // Examples using &amp;quot;field&amp;quot; parameter :&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve a specific property from a game element using its name (&amp;quot;Deck&amp;quot;)&lt;br /&gt;
  var deck_id = bga.getElement( { name: &amp;quot;Deck&amp;quot; }, &#039;x&#039; );&lt;br /&gt;
  // Return : 20&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve several properties from the previous element&lt;br /&gt;
  var deck_properties = bga.getElement( { name: &amp;quot;Deck&amp;quot; }, [&#039;name&#039;,&#039;id&#039;,&#039;parent&#039;, &#039;x&#039;,&#039;y&#039;,&#039;canShuffle&#039;] );&lt;br /&gt;
  // Return : { name:&#039;Deck&#039;, id:1234, parent:4321, x: 20, y:50, canShuffle: true }&lt;br /&gt;
  &lt;br /&gt;
  // Note : as you can see, getElement returns:&lt;br /&gt;
  //        _ the element ID by default, or&lt;br /&gt;
  //        _ a single value if you request a single field, or&lt;br /&gt;
  //        _ an object if you request several fields&lt;br /&gt;
&lt;br /&gt;
  // Examples using different &amp;quot;selector&amp;quot; paramter&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve an element name from its id&lt;br /&gt;
  var deck_name = bga.getElement( { id: 1234 }, [&#039;name&#039;] );&lt;br /&gt;
  // Return : &amp;quot;Deck&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  // Retrieve the last child element of another element&lt;br /&gt;
  // Here, we are requesting for elements who has element with ID=1234 (Deck) as their parent&lt;br /&gt;
  // Note the use of &amp;quot;limit:1&amp;quot; which allows us to retrieve only 1 element.&lt;br /&gt;
  var first_card_on_deck_id = bga.getElement( { parent: 1234, limit:1 } );&lt;br /&gt;
  &lt;br /&gt;
  // You can also get nested properties such as the ids of the child elements of one element, or a custom property placed on the parent element&lt;br /&gt;
  var totem_places = bga.getElements( {tag:&#039;TOTEMZONE&#039;}, [&#039;id&#039;,&#039;childs:id&#039;,&#039;childs:tags&#039;,&#039;parent:id&#039;,&#039;parent:c_value&#039;] );&lt;br /&gt;
&lt;br /&gt;
=== bga.getElements( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Returns an object holding the properties of the elements matching the selector.&lt;br /&gt;
&lt;br /&gt;
  // Basic example: unselect all selected elements&lt;br /&gt;
  bga.removeStyle( bga.getElements( {tag: &#039;sbstyle_selected&#039;}), &#039;selected&#039; );&lt;br /&gt;
&lt;br /&gt;
=== bga.getElementsArray( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Returns an array of all elements matching the selector, holding the required properties.&lt;br /&gt;
&lt;br /&gt;
  // Basic example: get id of selected element&lt;br /&gt;
  var selected_tokens = bga.getElementsArray( {tag: &#039;sbstyle_selected&#039; } );&lt;br /&gt;
  var token_id = null;&lt;br /&gt;
  if (selected_tokens.length &amp;gt; 0) {&lt;br /&gt;
      token_id = selected_tokens[0];&lt;br /&gt;
  }&lt;br /&gt;
  return token_id;&lt;br /&gt;
&lt;br /&gt;
  // Classic example: get array of elements and iterate over it&lt;br /&gt;
  var all_cells = bga.getElementsArray( {tag: &#039;CELL&#039;}, [&#039;id&#039;,&#039;name&#039;,&#039;tags&#039;] );&lt;br /&gt;
  for (var i=0; i&amp;lt;all_cells.length; i++) {&lt;br /&gt;
     // ... process each cell ...&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Utility methods ==&lt;br /&gt;
&lt;br /&gt;
=== bga.isOn( element_id, parent_id ) ===&lt;br /&gt;
&lt;br /&gt;
Return true if &amp;quot;element_id&amp;quot; is a descendant of &amp;quot;parent_id&amp;quot; (ie : if element_id game element has been placed on parent_id game element).&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  if( bga.isOn( bga.getElementIfByName( &#039;Turn counter&#039; ), bga.getElementIfByName( &#039;Turn 6&#039; ) )&lt;br /&gt;
  {&lt;br /&gt;
     // Trigger game end&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Trigger most common game actions ==&lt;br /&gt;
&lt;br /&gt;
=== moveTo( id, target, path ) ===&lt;br /&gt;
&lt;br /&gt;
Move element to specified target id (eventually following path defined by an array of element ids to pass over on the way)&lt;br /&gt;
&lt;br /&gt;
The exact destination of element depends on target&#039;s &amp;quot;howToArrange&amp;quot; property (&amp;quot;How elements are arranged on it?&amp;quot; : spreaded/deck/...).&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.moveTo( bga.getElementIdByName( &#039;Turn counter&#039; ), bga.getElementIdByName( &#039;Turn 3&#039; ) );&lt;br /&gt;
&lt;br /&gt;
=== flip( element_ids ) ===&lt;br /&gt;
&lt;br /&gt;
Flip target element (or array of elements) if the elements are flippable (ex: cards).&lt;br /&gt;
&lt;br /&gt;
=== shuffle( element_ids ) ==&lt;br /&gt;
&lt;br /&gt;
Shuffle elements contained inside this element (or array of elements).&lt;br /&gt;
&lt;br /&gt;
=== incScore( color, value ) ===&lt;br /&gt;
&lt;br /&gt;
Increases the score for the player with the specified color, of the specified increment value.&lt;br /&gt;
&lt;br /&gt;
=== setScore( color, value ) ===&lt;br /&gt;
&lt;br /&gt;
Sets the score for the player with the specified color.&lt;br /&gt;
&lt;br /&gt;
=== getScore( color ) ===&lt;br /&gt;
&lt;br /&gt;
Gets the score of the player with the specified color.&lt;br /&gt;
&lt;br /&gt;
== Gamestate functions ==&lt;br /&gt;
&lt;br /&gt;
You can define your game flow with a list of states by adding a &amp;quot;states&amp;quot; function to your script.&lt;br /&gt;
&lt;br /&gt;
  function states()&lt;br /&gt;
  {&lt;br /&gt;
      return {&lt;br /&gt;
        // Init game&lt;br /&gt;
        100: {&lt;br /&gt;
            onState: &#039;postSetup&#039;,&lt;br /&gt;
            transitions: { done:200 }&lt;br /&gt;
        },&lt;br /&gt;
        200: {&lt;br /&gt;
            description: _(&#039;${actplayer} must move a piece&#039;),&lt;br /&gt;
            descriptionmyturn: _(&#039;${you} must move a piece&#039;),&lt;br /&gt;
            possibleactions: [&#039;movePiece&#039;],&lt;br /&gt;
            transitions: { nextPlayer: 200 }&lt;br /&gt;
        },&lt;br /&gt;
      };&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Then, you will be able to use the following functions to manage the game flow.&lt;br /&gt;
&lt;br /&gt;
=== checkAction( action ) ===&lt;br /&gt;
&lt;br /&gt;
Check if action is valid regarding current game state and raise an error if it&#039;s not the case.&lt;br /&gt;
&lt;br /&gt;
=== isActionPossible( action ) ===&lt;br /&gt;
&lt;br /&gt;
Check if action is valid regarding current game state and returns a boolean with the appropriate value.&lt;br /&gt;
&lt;br /&gt;
=== getActivePlayerColor() ===&lt;br /&gt;
&lt;br /&gt;
Returns the color code of the currently active player&lt;br /&gt;
&lt;br /&gt;
=== getActivePlayerName() ===&lt;br /&gt;
&lt;br /&gt;
Returns the color code of the currently active player&lt;br /&gt;
&lt;br /&gt;
=== nextPlayer() ===&lt;br /&gt;
&lt;br /&gt;
Activates the next player in play order.&lt;br /&gt;
&lt;br /&gt;
=== activeAllPlayers() ===&lt;br /&gt;
&lt;br /&gt;
Activates all players (multiactive state).&lt;br /&gt;
&lt;br /&gt;
=== endTurn( transition ) ===&lt;br /&gt;
&lt;br /&gt;
Make the current player inactive and go to the next state matching the provided transition if all players are inactive (multiactive state)&lt;br /&gt;
&lt;br /&gt;
=== getActivePlayerColors() ===&lt;br /&gt;
&lt;br /&gt;
Returns the colors code of the currently active players&lt;br /&gt;
&lt;br /&gt;
=== getCurrentPlayerColor() ===&lt;br /&gt;
&lt;br /&gt;
Returns the color code of the current player (the player who made the interface action being handled; may not be the active player).&lt;br /&gt;
&lt;br /&gt;
=== nextState( transition ) ===&lt;br /&gt;
&lt;br /&gt;
Moves to the next state matching the provided transition.&lt;br /&gt;
&lt;br /&gt;
=== getPlayers() ===&lt;br /&gt;
&lt;br /&gt;
Returns an array of players with the players information.&lt;br /&gt;
&lt;br /&gt;
=== endGame() ===&lt;br /&gt;
&lt;br /&gt;
When the end game condition is met, you can use this function to end the game (after setting the appropriate scores!)&lt;br /&gt;
&lt;br /&gt;
== Other functions ==&lt;br /&gt;
&lt;br /&gt;
=== pause( milliseconds ) ===&lt;br /&gt;
&lt;br /&gt;
Pause the client interface during a specified number of milliseconds.&lt;br /&gt;
&lt;br /&gt;
If you do not use bga.pause, all Sandbox game actions are executed immediately and synchronously.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.log( &amp;quot;1&amp;quot; );    // Will be displayed immediately on the log&lt;br /&gt;
  bga.pause( 3000 ); // pause during 3 seconds&lt;br /&gt;
  bga.log( &amp;quot;2&amp;quot; );    // Will be displayed after the 3 second on the log&lt;br /&gt;
  bga.log( &amp;quot;3&amp;quot; );    // Will be displayed right after the previous one, without delay.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Tips : if you want to execute several consecutive &amp;quot;moveTo&amp;quot;, you should &amp;quot;bga.pause&amp;quot; between them, otherwise your element will move directly to the final destination.&lt;br /&gt;
&lt;br /&gt;
=== hasTag( id, tag ) ===&lt;br /&gt;
&lt;br /&gt;
Returns true if the element with this id has this tag.&lt;br /&gt;
&lt;br /&gt;
=== addTag( id, tag ) ===&lt;br /&gt;
&lt;br /&gt;
Adds this tag to the element with this id.&lt;br /&gt;
&lt;br /&gt;
=== removeTag( id, tag ) ===&lt;br /&gt;
&lt;br /&gt;
Removes this tag from the element with this id.&lt;br /&gt;
&lt;br /&gt;
=== addStyle( id, style ) ===&lt;br /&gt;
&lt;br /&gt;
Adds this style to the element with this id.&lt;br /&gt;
&lt;br /&gt;
Predefined styles are: SELECTED / LIGHT / LIGHTBACKGROUND / REDSELECTED / CLICKABLE / ROUNDED / CLICKABLE_ROUNDED&lt;br /&gt;
&lt;br /&gt;
=== removeStyle( id, style ) ===&lt;br /&gt;
&lt;br /&gt;
Removes this style from the element with this id.&lt;br /&gt;
&lt;br /&gt;
=== setProperties( props ) ===&lt;br /&gt;
&lt;br /&gt;
This function allows to directly update properties of an object, and to manage custom properties if needed (custom properties must start with prefix &amp;quot;c_&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
    // Update player labels for player zones from &amp;quot;&amp;lt;color&amp;gt; player&amp;quot; to actual player name&lt;br /&gt;
    var players = bga.getPlayers();&lt;br /&gt;
    for (var color in players) {&lt;br /&gt;
        player = players[color];&lt;br /&gt;
        &lt;br /&gt;
        var labelId = null;&lt;br /&gt;
        if (color == &#039;ff0000&#039;) labelId = bga.getElement( {name: &#039;Red player&#039;} );&lt;br /&gt;
        if (color == &#039;008000&#039;) labelId = bga.getElement( {name: &#039;Green player&#039;} );&lt;br /&gt;
        if (color == &#039;0000ff&#039;) labelId = bga.getElement( {name: &#039;Blue player&#039;} );&lt;br /&gt;
        if (color == &#039;ffa500&#039;) labelId = bga.getElement( {name: &#039;Yellow player&#039;} );&lt;br /&gt;
        &lt;br /&gt;
        var props = [];&lt;br /&gt;
        props[labelId] = {name: player.name};&lt;br /&gt;
        bga.setProperties( props );&lt;br /&gt;
    }&lt;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://sr.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=3049</id>
		<title>SandboxScripts</title>
		<link rel="alternate" type="text/html" href="https://sr.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=3049"/>
		<updated>2018-05-18T08:47:05Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Trigger most common game actions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This is the reference of functions you can call from your Sandbox scripts.&lt;br /&gt;
&lt;br /&gt;
= Javascript =&lt;br /&gt;
&lt;br /&gt;
BGA Sandbox scripts are written in Javascript.&lt;br /&gt;
&lt;br /&gt;
Using Javascript, you can write scripts to automate moves for your Sandbox games &amp;amp; provide rules reinforcement.&lt;br /&gt;
&lt;br /&gt;
Important : in the opposite of the most common usage of Javascript, Sandbox scripts are executed &#039;&#039;&#039;on server side&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
= BGA API =&lt;br /&gt;
&lt;br /&gt;
To interact with your BGA Sandbox game, we provide you an API.&lt;br /&gt;
&lt;br /&gt;
With this API, you can get properties values of game elements from the current game situation, modify them and/or trigger the game actions (ex : move this element here, flip this card, and so on).&lt;br /&gt;
&lt;br /&gt;
= Quick start =&lt;br /&gt;
&lt;br /&gt;
== Hello World Script ==&lt;br /&gt;
&lt;br /&gt;
From Sandbox editor &amp;quot;interface view&amp;quot; tab, select an element, and access to its property (top right icon).&lt;br /&gt;
&lt;br /&gt;
Go to &amp;quot;Scripts (advanced)&amp;quot; section.&lt;br /&gt;
&lt;br /&gt;
In front of &amp;quot;When this element is clicked&amp;quot;, enter &amp;quot;onMyClick&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Close the window. Go to &amp;quot;script view&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Enter the following :&lt;br /&gt;
&lt;br /&gt;
 function onMyClick( element_id )&lt;br /&gt;
 {&lt;br /&gt;
    bga.log(&amp;quot;Hello world! You just clicked on element &amp;quot; + element_id + &amp;quot;. Congrats!&amp;quot;);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Save &amp;amp; publish your project, starts a test session, click on the previous element : your message appears in the log on the right!&lt;br /&gt;
&lt;br /&gt;
== Top useful tips ==&lt;br /&gt;
&lt;br /&gt;
* You don&#039;t have to save&amp;amp;publish from the Sandbox editor for each modification of your script : each time you save your script (control+S), the script used for all test sessions is updated. Note that the production version on BGA is of course NOT updated until you explicitly save&amp;amp;publish again your project.&lt;br /&gt;
&lt;br /&gt;
* To inspect the content of a variable, you can use bga.log() in combination with JSON.stringify(). For example :&lt;br /&gt;
&lt;br /&gt;
  bga.log( JSON.stringify( bga.getPlayers()) );&lt;br /&gt;
&lt;br /&gt;
* Alternatively to bga.log(), you can use bga.exit( &amp;quot;my message&amp;quot; ) to debug your script. With bga.exit, the script execution immediately stops and all previous game changes are cancelled, so this is very practical to try and retry an action until your script is fine.&lt;br /&gt;
&lt;br /&gt;
* We advise you to develop first a full playable version of the game without the scripts, and THEN to script it.&lt;br /&gt;
&lt;br /&gt;
* On Board Game Arena, players have come to expect fully implemented games with all rules enforced. So even if it&#039;s technically possible not to script the full game and to implement the game only partially, in most cases we&#039;ll publish only fully scripted games :)&lt;br /&gt;
&lt;br /&gt;
= Functions you can use in your Sandbox scripts=&lt;br /&gt;
&lt;br /&gt;
== Debugging functions ==&lt;br /&gt;
&lt;br /&gt;
=== bga.trace( txt / obj ) ===&lt;br /&gt;
&lt;br /&gt;
Write something immediately in the BGA log (on the right of the screen).&lt;br /&gt;
&lt;br /&gt;
This is the most practical way to debug your script :)&lt;br /&gt;
&lt;br /&gt;
Important : bga.trace is for debugging purpose only and won&#039;t be displayed on production.&lt;br /&gt;
&lt;br /&gt;
Note : you can also pass an object in parameter. This will dump the content of this object in the log.&lt;br /&gt;
&lt;br /&gt;
Note : in the opposite of bga.log, bga.trace is NOT cancelled if the game action failed (after a call to bga.cancel or bga.error). This makes bga.trace very practical to debug a game action that failed, and for this reason you should probably NEVER use bga.log for debugging purpose.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  // Example : write &amp;quot;Hello world&amp;quot; in the log&lt;br /&gt;
  bga.trace( &amp;quot;Hello world&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Example : dump an associative array in the log&lt;br /&gt;
  bga.trace( { mykey: &#039;myvalue&#039;, another_key: &#039;another_value&#039; } );&lt;br /&gt;
&lt;br /&gt;
=== bga.exit( txt / obj ) ===&lt;br /&gt;
&lt;br /&gt;
Stop the script immediately, display the &amp;quot;txt&amp;quot; messages and cancel (ie : rollback) on every previous API call except bga.trace :&lt;br /&gt;
&lt;br /&gt;
ALL previous BGA api call are canceled and there will be no visible changes on the interface (ex : no moves, no visible property changes, ...). Only &amp;quot;bga.trace&amp;quot; API commands are kept so you can debug.&lt;br /&gt;
&lt;br /&gt;
bga.exit is very practical when you want to repeat a game action again and again to debug it : with a call to bga.exit at the end of your script, you make sure that your game situation will be kept unchanged after each test.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.exit( &amp;quot;My script is stopped by this call&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Example with dumping a javascript variable&lt;br /&gt;
  bga.exit( my_variable_to_dump );&lt;br /&gt;
&lt;br /&gt;
== Cancelling a game action ==&lt;br /&gt;
&lt;br /&gt;
=== bga.cancel( txt ) ===&lt;br /&gt;
&lt;br /&gt;
This is the function to use when a player is doing something against game rules.&lt;br /&gt;
&lt;br /&gt;
The text message in parameter will be displayed to this player as a &amp;quot;red message&amp;quot;, so he/she can understand the rule.&lt;br /&gt;
&lt;br /&gt;
All previous BGA api call are cancelled, and there will be no visible changes on the interface.&lt;br /&gt;
&lt;br /&gt;
   // Example :&lt;br /&gt;
   bga.cancel( _(&amp;quot;You cannot move this piece here&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
Note : most of the time, you should wrap your text inside a _() translation marker to make this string translatable.&lt;br /&gt;
&lt;br /&gt;
=== bga.error( text ) ===&lt;br /&gt;
&lt;br /&gt;
This is the function to use when some unexpected error happens in your script.&lt;br /&gt;
&lt;br /&gt;
The text message will be displayed to user, with mention &amp;quot;Unexpected error&amp;quot;. The player will be incited to fill a bug report. The purpose of the message is to help you to identify the bug.&lt;br /&gt;
&lt;br /&gt;
All previous BGA api call are cancelled, and there will be no visible changes on the interface.&lt;br /&gt;
&lt;br /&gt;
   // Example :&lt;br /&gt;
   if( card_picked === null )&lt;br /&gt;
   {&lt;br /&gt;
       bga.error( &amp;quot;Cannot find a card to pick !&amp;quot; );&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
Note : you should NEVER wrap text inside bga.error with _() translation marker, because unexpected error should not be translate (so you can eventually recognize them when reported by players in bug report).&lt;br /&gt;
&lt;br /&gt;
== Game log (history) ==&lt;br /&gt;
&lt;br /&gt;
=== bga.log( txt, (optional) args ) ===&lt;br /&gt;
&lt;br /&gt;
Write something in the BGA log on the right.&lt;br /&gt;
&lt;br /&gt;
  // Example : simple log&lt;br /&gt;
  bga.log( _(&amp;quot;A new round starts&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
You may add arguments to your log, like this :&lt;br /&gt;
&lt;br /&gt;
  // Example: log with argument to display a card name.&lt;br /&gt;
  //          In this example, variable &amp;quot;event_name&amp;quot; is specified afterwards.&lt;br /&gt;
  //          Note that using this, game translators only have to translate one &amp;quot;Event XXX is triggered&amp;quot; string for all possible events.&lt;br /&gt;
  bga.log( _(&amp;quot;Event ${event_name} is triggered&amp;quot;), {  event_name: _( &amp;quot;Armageddon&amp;quot; ) } ) );&lt;br /&gt;
&lt;br /&gt;
Note that argument &amp;quot;player_name&amp;quot; is ALWAYS pre-set with the name of the current player, so you can use it immediately.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.log( _(&amp;quot;${player_name} draw a card from the deck&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
=== bga.speechBubble( target, text, (optional) args, (optional) delay, (optional) duration, (optional) size ) ===&lt;br /&gt;
&lt;br /&gt;
Display a &amp;quot;speech bubble&amp;quot;, attached to the specified target, containing the specified text.&lt;br /&gt;
&lt;br /&gt;
You can use &amp;quot;args&amp;quot; to customize text exactly like with bga.log.&lt;br /&gt;
&lt;br /&gt;
delay : milliseconds to wait before displaying the speech bubble (default : 0).&lt;br /&gt;
duration : how long to show the speech bubble in milliseconds (default : 3000).&lt;br /&gt;
size : size of the text in percent (default: 100)&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.speechBubble( _(&amp;quot;I play ${nbr} cards&amp;quot;), { nbr : 4 }, 0 );&lt;br /&gt;
  bga.speechBubble( _(&amp;quot;Good for you!&amp;quot;), { }, 2000 );&lt;br /&gt;
&lt;br /&gt;
=== bga.displayScoring( target, color, score ) ===&lt;br /&gt;
&lt;br /&gt;
Display an animated temporary &amp;quot;score number&amp;quot;, attached to the specified target.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;color&amp;quot; should be the color of the player who is scoring for that target.&lt;br /&gt;
&lt;br /&gt;
== Get / search game elements and their properties ==&lt;br /&gt;
&lt;br /&gt;
=== bga.getElement( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Allow you to retrieve informations about one game element specified using &amp;quot;selector&amp;quot; argument.&lt;br /&gt;
&lt;br /&gt;
Return null if no element is found.&lt;br /&gt;
&lt;br /&gt;
Note : getElement throw an error if several elements matches the selector. If you want to retrieve several elements, you should use &amp;quot;getElements&amp;quot; instead of &amp;quot;getElement&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The following examples are showing all the possible use of bga.getElement :&lt;br /&gt;
&lt;br /&gt;
  // Basic example :&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve the ID of a game element using its name (&amp;quot;Deck&amp;quot;)&lt;br /&gt;
  var deck_id = bga.getElement( { name: &amp;quot;Deck&amp;quot; } );&lt;br /&gt;
  // Return : 1234  &lt;br /&gt;
&lt;br /&gt;
  // Examples using &amp;quot;field&amp;quot; parameter :&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve a specific property from a game element using its name (&amp;quot;Deck&amp;quot;)&lt;br /&gt;
  var deck_id = bga.getElement( { name: &amp;quot;Deck&amp;quot; }, &#039;x&#039; );&lt;br /&gt;
  // Return : 20&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve several properties from the previous element&lt;br /&gt;
  var deck_properties = bga.getElement( { name: &amp;quot;Deck&amp;quot; }, [&#039;name&#039;,&#039;id&#039;,&#039;parent&#039;, &#039;x&#039;,&#039;y&#039;,&#039;canShuffle&#039;] );&lt;br /&gt;
  // Return : { name:&#039;Deck&#039;, id:1234, parent:4321, x: 20, y:50, canShuffle: true }&lt;br /&gt;
  &lt;br /&gt;
  // Note : as you can see, getElement returns:&lt;br /&gt;
  //        _ the element ID by default, or&lt;br /&gt;
  //        _ a single value if you request a single field, or&lt;br /&gt;
  //        _ an object if you request several fields&lt;br /&gt;
&lt;br /&gt;
  // Examples using different &amp;quot;selector&amp;quot; paramter&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve an element name from its id&lt;br /&gt;
  var deck_name = bga.getElement( { id: 1234 }, [&#039;name&#039;] );&lt;br /&gt;
  // Return : &amp;quot;Deck&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  // Retrieve the last child element of another element&lt;br /&gt;
  // Here, we are requesting for elements who has element with ID=1234 (Deck) as their parent&lt;br /&gt;
  // Note the use of &amp;quot;limit:1&amp;quot; which allows us to retrieve only 1 element.&lt;br /&gt;
  var first_card_on_deck_id = bga.getElement( { parent: 1234, limit:1 } );&lt;br /&gt;
  &lt;br /&gt;
  // You can also get nested properties such as the ids of the child elements of one element, or a custom property placed on the parent element&lt;br /&gt;
  var totem_places = bga.getElements( {tag:&#039;TOTEMZONE&#039;}, [&#039;id&#039;,&#039;childs:id&#039;,&#039;childs:tags&#039;,&#039;parent:id&#039;,&#039;parent:c_value&#039;] );&lt;br /&gt;
&lt;br /&gt;
=== bga.getElements( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Returns an object holding the properties of the elements matching the selector.&lt;br /&gt;
&lt;br /&gt;
  // Basic example: unselect all selected elements&lt;br /&gt;
  bga.removeStyle( bga.getElements( {tag: &#039;sbstyle_selected&#039;}), &#039;selected&#039; );&lt;br /&gt;
&lt;br /&gt;
=== bga.getElementsArray( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Returns an array of all elements matching the selector, holding the required properties.&lt;br /&gt;
&lt;br /&gt;
  // Basic example: get id of selected element&lt;br /&gt;
  var selected_tokens = bga.getElementsArray( {tag: &#039;sbstyle_selected&#039; } );&lt;br /&gt;
  var token_id = null;&lt;br /&gt;
  if (selected_tokens.length &amp;gt; 0) {&lt;br /&gt;
      token_id = selected_tokens[0];&lt;br /&gt;
  }&lt;br /&gt;
  return token_id;&lt;br /&gt;
&lt;br /&gt;
  // Classic example: get array of elements and iterate over it&lt;br /&gt;
  var all_cells = bga.getElementsArray( {tag: &#039;CELL&#039;}, [&#039;id&#039;,&#039;name&#039;,&#039;tags&#039;] );&lt;br /&gt;
  for (var i=0; i&amp;lt;all_cells.length; i++) {&lt;br /&gt;
     // ... process each cell ...&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Utility methods ==&lt;br /&gt;
&lt;br /&gt;
=== bga.isOn( element_id, parent_id ) ===&lt;br /&gt;
&lt;br /&gt;
Return true if &amp;quot;element_id&amp;quot; is a descendant of &amp;quot;parent_id&amp;quot; (ie : if element_id game element has been placed on parent_id game element).&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  if( bga.isOn( bga.getElementIfByName( &#039;Turn counter&#039; ), bga.getElementIfByName( &#039;Turn 6&#039; ) )&lt;br /&gt;
  {&lt;br /&gt;
     // Trigger game end&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Trigger most common game actions ==&lt;br /&gt;
&lt;br /&gt;
=== moveTo( id, target, path ) ===&lt;br /&gt;
&lt;br /&gt;
Move element to specified target id (eventually following path defined by an array of element ids to pass over on the way)&lt;br /&gt;
&lt;br /&gt;
The exact destination of element depends on target&#039;s &amp;quot;howToArrange&amp;quot; property (&amp;quot;How elements are arranged on it?&amp;quot; : spreaded/deck/...).&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.moveTo( bga.getElementIdByName( &#039;Turn counter&#039; ), bga.getElementIdByName( &#039;Turn 3&#039; ) );&lt;br /&gt;
&lt;br /&gt;
=== flip( element_ids ) ==&lt;br /&gt;
&lt;br /&gt;
Flip target element (or array of elements) if the elements are flippable (ex: cards).&lt;br /&gt;
&lt;br /&gt;
=== shuffle( element_ids ) ==&lt;br /&gt;
&lt;br /&gt;
Shuffle elements contained inside this element (or array of elements).&lt;br /&gt;
&lt;br /&gt;
=== incScore( color, value ) ===&lt;br /&gt;
&lt;br /&gt;
Increases the score for the player with the specified color, of the specified increment value.&lt;br /&gt;
&lt;br /&gt;
=== setScore( color, value ) ===&lt;br /&gt;
&lt;br /&gt;
Sets the score for the player with the specified color.&lt;br /&gt;
&lt;br /&gt;
=== getScore( color ) ===&lt;br /&gt;
&lt;br /&gt;
Gets the score of the player with the specified color.&lt;br /&gt;
&lt;br /&gt;
== Gamestate functions ==&lt;br /&gt;
&lt;br /&gt;
You can define your game flow with a list of states by adding a &amp;quot;states&amp;quot; function to your script.&lt;br /&gt;
&lt;br /&gt;
  function states()&lt;br /&gt;
  {&lt;br /&gt;
      return {&lt;br /&gt;
        // Init game&lt;br /&gt;
        100: {&lt;br /&gt;
            onState: &#039;postSetup&#039;,&lt;br /&gt;
            transitions: { done:200 }&lt;br /&gt;
        },&lt;br /&gt;
        200: {&lt;br /&gt;
            description: _(&#039;${actplayer} must move a piece&#039;),&lt;br /&gt;
            descriptionmyturn: _(&#039;${you} must move a piece&#039;),&lt;br /&gt;
            possibleactions: [&#039;movePiece&#039;],&lt;br /&gt;
            transitions: { nextPlayer: 200 }&lt;br /&gt;
        },&lt;br /&gt;
      };&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Then, you will be able to use the following functions to manage the game flow.&lt;br /&gt;
&lt;br /&gt;
=== checkAction( action ) ===&lt;br /&gt;
&lt;br /&gt;
Check if action is valid regarding current game state and raise an error if it&#039;s not the case.&lt;br /&gt;
&lt;br /&gt;
=== isActionPossible( action ) ===&lt;br /&gt;
&lt;br /&gt;
Check if action is valid regarding current game state and returns a boolean with the appropriate value.&lt;br /&gt;
&lt;br /&gt;
=== getActivePlayerColor() ===&lt;br /&gt;
&lt;br /&gt;
Returns the color code of the currently active player&lt;br /&gt;
&lt;br /&gt;
=== getActivePlayerName() ===&lt;br /&gt;
&lt;br /&gt;
Returns the color code of the currently active player&lt;br /&gt;
&lt;br /&gt;
=== nextPlayer() ===&lt;br /&gt;
&lt;br /&gt;
Activates the next player in play order.&lt;br /&gt;
&lt;br /&gt;
=== activeAllPlayers() ===&lt;br /&gt;
&lt;br /&gt;
Activates all players (multiactive state).&lt;br /&gt;
&lt;br /&gt;
=== endTurn( transition ) ===&lt;br /&gt;
&lt;br /&gt;
Make the current player inactive and go to the next state matching the provided transition if all players are inactive (multiactive state)&lt;br /&gt;
&lt;br /&gt;
=== getActivePlayerColors() ===&lt;br /&gt;
&lt;br /&gt;
Returns the colors code of the currently active players&lt;br /&gt;
&lt;br /&gt;
=== getCurrentPlayerColor() ===&lt;br /&gt;
&lt;br /&gt;
Returns the color code of the current player (the player who made the interface action being handled; may not be the active player).&lt;br /&gt;
&lt;br /&gt;
=== nextState( transition ) ===&lt;br /&gt;
&lt;br /&gt;
Moves to the next state matching the provided transition.&lt;br /&gt;
&lt;br /&gt;
=== getPlayers() ===&lt;br /&gt;
&lt;br /&gt;
Returns an array of players with the players information.&lt;br /&gt;
&lt;br /&gt;
=== endGame() ===&lt;br /&gt;
&lt;br /&gt;
When the end game condition is met, you can use this function to end the game (after setting the appropriate scores!)&lt;br /&gt;
&lt;br /&gt;
== Other functions ==&lt;br /&gt;
&lt;br /&gt;
=== pause( milliseconds ) ===&lt;br /&gt;
&lt;br /&gt;
Pause the client interface during a specified number of milliseconds.&lt;br /&gt;
&lt;br /&gt;
If you do not use bga.pause, all Sandbox game actions are executed immediately and synchronously.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.log( &amp;quot;1&amp;quot; );    // Will be displayed immediately on the log&lt;br /&gt;
  bga.pause( 3000 ); // pause during 3 seconds&lt;br /&gt;
  bga.log( &amp;quot;2&amp;quot; );    // Will be displayed after the 3 second on the log&lt;br /&gt;
  bga.log( &amp;quot;3&amp;quot; );    // Will be displayed right after the previous one, without delay.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Tips : if you want to execute several consecutive &amp;quot;moveTo&amp;quot;, you should &amp;quot;bga.pause&amp;quot; between them, otherwise your element will move directly to the final destination.&lt;br /&gt;
&lt;br /&gt;
=== hasTag( id, tag ) ===&lt;br /&gt;
&lt;br /&gt;
Returns true if the element with this id has this tag.&lt;br /&gt;
&lt;br /&gt;
=== addTag( id, tag ) ===&lt;br /&gt;
&lt;br /&gt;
Adds this tag to the element with this id.&lt;br /&gt;
&lt;br /&gt;
=== removeTag( id, tag ) ===&lt;br /&gt;
&lt;br /&gt;
Removes this tag from the element with this id.&lt;br /&gt;
&lt;br /&gt;
=== addStyle( id, style ) ===&lt;br /&gt;
&lt;br /&gt;
Adds this style to the element with this id.&lt;br /&gt;
&lt;br /&gt;
Predefined styles are: SELECTED / LIGHT / LIGHTBACKGROUND / REDSELECTED / CLICKABLE / ROUNDED / CLICKABLE_ROUNDED&lt;br /&gt;
&lt;br /&gt;
=== removeStyle( id, style ) ===&lt;br /&gt;
&lt;br /&gt;
Removes this style from the element with this id.&lt;br /&gt;
&lt;br /&gt;
=== setProperties( props ) ===&lt;br /&gt;
&lt;br /&gt;
This function allows to directly update properties of an object, and to manage custom properties if needed (custom properties must start with prefix &amp;quot;c_&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
    // Update player labels for player zones from &amp;quot;&amp;lt;color&amp;gt; player&amp;quot; to actual player name&lt;br /&gt;
    var players = bga.getPlayers();&lt;br /&gt;
    for (var color in players) {&lt;br /&gt;
        player = players[color];&lt;br /&gt;
        &lt;br /&gt;
        var labelId = null;&lt;br /&gt;
        if (color == &#039;ff0000&#039;) labelId = bga.getElement( {name: &#039;Red player&#039;} );&lt;br /&gt;
        if (color == &#039;008000&#039;) labelId = bga.getElement( {name: &#039;Green player&#039;} );&lt;br /&gt;
        if (color == &#039;0000ff&#039;) labelId = bga.getElement( {name: &#039;Blue player&#039;} );&lt;br /&gt;
        if (color == &#039;ffa500&#039;) labelId = bga.getElement( {name: &#039;Yellow player&#039;} );&lt;br /&gt;
        &lt;br /&gt;
        var props = [];&lt;br /&gt;
        props[labelId] = {name: player.name};&lt;br /&gt;
        bga.setProperties( props );&lt;br /&gt;
    }&lt;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://sr.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=3048</id>
		<title>SandboxScripts</title>
		<link rel="alternate" type="text/html" href="https://sr.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=3048"/>
		<updated>2018-05-18T08:39:37Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Gamestate functions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This is the reference of functions you can call from your Sandbox scripts.&lt;br /&gt;
&lt;br /&gt;
= Javascript =&lt;br /&gt;
&lt;br /&gt;
BGA Sandbox scripts are written in Javascript.&lt;br /&gt;
&lt;br /&gt;
Using Javascript, you can write scripts to automate moves for your Sandbox games &amp;amp; provide rules reinforcement.&lt;br /&gt;
&lt;br /&gt;
Important : in the opposite of the most common usage of Javascript, Sandbox scripts are executed &#039;&#039;&#039;on server side&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
= BGA API =&lt;br /&gt;
&lt;br /&gt;
To interact with your BGA Sandbox game, we provide you an API.&lt;br /&gt;
&lt;br /&gt;
With this API, you can get properties values of game elements from the current game situation, modify them and/or trigger the game actions (ex : move this element here, flip this card, and so on).&lt;br /&gt;
&lt;br /&gt;
= Quick start =&lt;br /&gt;
&lt;br /&gt;
== Hello World Script ==&lt;br /&gt;
&lt;br /&gt;
From Sandbox editor &amp;quot;interface view&amp;quot; tab, select an element, and access to its property (top right icon).&lt;br /&gt;
&lt;br /&gt;
Go to &amp;quot;Scripts (advanced)&amp;quot; section.&lt;br /&gt;
&lt;br /&gt;
In front of &amp;quot;When this element is clicked&amp;quot;, enter &amp;quot;onMyClick&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Close the window. Go to &amp;quot;script view&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Enter the following :&lt;br /&gt;
&lt;br /&gt;
 function onMyClick( element_id )&lt;br /&gt;
 {&lt;br /&gt;
    bga.log(&amp;quot;Hello world! You just clicked on element &amp;quot; + element_id + &amp;quot;. Congrats!&amp;quot;);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Save &amp;amp; publish your project, starts a test session, click on the previous element : your message appears in the log on the right!&lt;br /&gt;
&lt;br /&gt;
== Top useful tips ==&lt;br /&gt;
&lt;br /&gt;
* You don&#039;t have to save&amp;amp;publish from the Sandbox editor for each modification of your script : each time you save your script (control+S), the script used for all test sessions is updated. Note that the production version on BGA is of course NOT updated until you explicitly save&amp;amp;publish again your project.&lt;br /&gt;
&lt;br /&gt;
* To inspect the content of a variable, you can use bga.log() in combination with JSON.stringify(). For example :&lt;br /&gt;
&lt;br /&gt;
  bga.log( JSON.stringify( bga.getPlayers()) );&lt;br /&gt;
&lt;br /&gt;
* Alternatively to bga.log(), you can use bga.exit( &amp;quot;my message&amp;quot; ) to debug your script. With bga.exit, the script execution immediately stops and all previous game changes are cancelled, so this is very practical to try and retry an action until your script is fine.&lt;br /&gt;
&lt;br /&gt;
* We advise you to develop first a full playable version of the game without the scripts, and THEN to script it.&lt;br /&gt;
&lt;br /&gt;
* On Board Game Arena, players have come to expect fully implemented games with all rules enforced. So even if it&#039;s technically possible not to script the full game and to implement the game only partially, in most cases we&#039;ll publish only fully scripted games :)&lt;br /&gt;
&lt;br /&gt;
= Functions you can use in your Sandbox scripts=&lt;br /&gt;
&lt;br /&gt;
== Debugging functions ==&lt;br /&gt;
&lt;br /&gt;
=== bga.trace( txt / obj ) ===&lt;br /&gt;
&lt;br /&gt;
Write something immediately in the BGA log (on the right of the screen).&lt;br /&gt;
&lt;br /&gt;
This is the most practical way to debug your script :)&lt;br /&gt;
&lt;br /&gt;
Important : bga.trace is for debugging purpose only and won&#039;t be displayed on production.&lt;br /&gt;
&lt;br /&gt;
Note : you can also pass an object in parameter. This will dump the content of this object in the log.&lt;br /&gt;
&lt;br /&gt;
Note : in the opposite of bga.log, bga.trace is NOT cancelled if the game action failed (after a call to bga.cancel or bga.error). This makes bga.trace very practical to debug a game action that failed, and for this reason you should probably NEVER use bga.log for debugging purpose.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  // Example : write &amp;quot;Hello world&amp;quot; in the log&lt;br /&gt;
  bga.trace( &amp;quot;Hello world&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Example : dump an associative array in the log&lt;br /&gt;
  bga.trace( { mykey: &#039;myvalue&#039;, another_key: &#039;another_value&#039; } );&lt;br /&gt;
&lt;br /&gt;
=== bga.exit( txt / obj ) ===&lt;br /&gt;
&lt;br /&gt;
Stop the script immediately, display the &amp;quot;txt&amp;quot; messages and cancel (ie : rollback) on every previous API call except bga.trace :&lt;br /&gt;
&lt;br /&gt;
ALL previous BGA api call are canceled and there will be no visible changes on the interface (ex : no moves, no visible property changes, ...). Only &amp;quot;bga.trace&amp;quot; API commands are kept so you can debug.&lt;br /&gt;
&lt;br /&gt;
bga.exit is very practical when you want to repeat a game action again and again to debug it : with a call to bga.exit at the end of your script, you make sure that your game situation will be kept unchanged after each test.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.exit( &amp;quot;My script is stopped by this call&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Example with dumping a javascript variable&lt;br /&gt;
  bga.exit( my_variable_to_dump );&lt;br /&gt;
&lt;br /&gt;
== Cancelling a game action ==&lt;br /&gt;
&lt;br /&gt;
=== bga.cancel( txt ) ===&lt;br /&gt;
&lt;br /&gt;
This is the function to use when a player is doing something against game rules.&lt;br /&gt;
&lt;br /&gt;
The text message in parameter will be displayed to this player as a &amp;quot;red message&amp;quot;, so he/she can understand the rule.&lt;br /&gt;
&lt;br /&gt;
All previous BGA api call are cancelled, and there will be no visible changes on the interface.&lt;br /&gt;
&lt;br /&gt;
   // Example :&lt;br /&gt;
   bga.cancel( _(&amp;quot;You cannot move this piece here&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
Note : most of the time, you should wrap your text inside a _() translation marker to make this string translatable.&lt;br /&gt;
&lt;br /&gt;
=== bga.error( text ) ===&lt;br /&gt;
&lt;br /&gt;
This is the function to use when some unexpected error happens in your script.&lt;br /&gt;
&lt;br /&gt;
The text message will be displayed to user, with mention &amp;quot;Unexpected error&amp;quot;. The player will be incited to fill a bug report. The purpose of the message is to help you to identify the bug.&lt;br /&gt;
&lt;br /&gt;
All previous BGA api call are cancelled, and there will be no visible changes on the interface.&lt;br /&gt;
&lt;br /&gt;
   // Example :&lt;br /&gt;
   if( card_picked === null )&lt;br /&gt;
   {&lt;br /&gt;
       bga.error( &amp;quot;Cannot find a card to pick !&amp;quot; );&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
Note : you should NEVER wrap text inside bga.error with _() translation marker, because unexpected error should not be translate (so you can eventually recognize them when reported by players in bug report).&lt;br /&gt;
&lt;br /&gt;
== Game log (history) ==&lt;br /&gt;
&lt;br /&gt;
=== bga.log( txt, (optional) args ) ===&lt;br /&gt;
&lt;br /&gt;
Write something in the BGA log on the right.&lt;br /&gt;
&lt;br /&gt;
  // Example : simple log&lt;br /&gt;
  bga.log( _(&amp;quot;A new round starts&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
You may add arguments to your log, like this :&lt;br /&gt;
&lt;br /&gt;
  // Example: log with argument to display a card name.&lt;br /&gt;
  //          In this example, variable &amp;quot;event_name&amp;quot; is specified afterwards.&lt;br /&gt;
  //          Note that using this, game translators only have to translate one &amp;quot;Event XXX is triggered&amp;quot; string for all possible events.&lt;br /&gt;
  bga.log( _(&amp;quot;Event ${event_name} is triggered&amp;quot;), {  event_name: _( &amp;quot;Armageddon&amp;quot; ) } ) );&lt;br /&gt;
&lt;br /&gt;
Note that argument &amp;quot;player_name&amp;quot; is ALWAYS pre-set with the name of the current player, so you can use it immediately.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.log( _(&amp;quot;${player_name} draw a card from the deck&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
=== bga.speechBubble( target, text, (optional) args, (optional) delay, (optional) duration, (optional) size ) ===&lt;br /&gt;
&lt;br /&gt;
Display a &amp;quot;speech bubble&amp;quot;, attached to the specified target, containing the specified text.&lt;br /&gt;
&lt;br /&gt;
You can use &amp;quot;args&amp;quot; to customize text exactly like with bga.log.&lt;br /&gt;
&lt;br /&gt;
delay : milliseconds to wait before displaying the speech bubble (default : 0).&lt;br /&gt;
duration : how long to show the speech bubble in milliseconds (default : 3000).&lt;br /&gt;
size : size of the text in percent (default: 100)&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.speechBubble( _(&amp;quot;I play ${nbr} cards&amp;quot;), { nbr : 4 }, 0 );&lt;br /&gt;
  bga.speechBubble( _(&amp;quot;Good for you!&amp;quot;), { }, 2000 );&lt;br /&gt;
&lt;br /&gt;
=== bga.displayScoring( target, color, score ) ===&lt;br /&gt;
&lt;br /&gt;
Display an animated temporary &amp;quot;score number&amp;quot;, attached to the specified target.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;color&amp;quot; should be the color of the player who is scoring for that target.&lt;br /&gt;
&lt;br /&gt;
== Get / search game elements and their properties ==&lt;br /&gt;
&lt;br /&gt;
=== bga.getElement( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Allow you to retrieve informations about one game element specified using &amp;quot;selector&amp;quot; argument.&lt;br /&gt;
&lt;br /&gt;
Return null if no element is found.&lt;br /&gt;
&lt;br /&gt;
Note : getElement throw an error if several elements matches the selector. If you want to retrieve several elements, you should use &amp;quot;getElements&amp;quot; instead of &amp;quot;getElement&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The following examples are showing all the possible use of bga.getElement :&lt;br /&gt;
&lt;br /&gt;
  // Basic example :&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve the ID of a game element using its name (&amp;quot;Deck&amp;quot;)&lt;br /&gt;
  var deck_id = bga.getElement( { name: &amp;quot;Deck&amp;quot; } );&lt;br /&gt;
  // Return : 1234  &lt;br /&gt;
&lt;br /&gt;
  // Examples using &amp;quot;field&amp;quot; parameter :&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve a specific property from a game element using its name (&amp;quot;Deck&amp;quot;)&lt;br /&gt;
  var deck_id = bga.getElement( { name: &amp;quot;Deck&amp;quot; }, &#039;x&#039; );&lt;br /&gt;
  // Return : 20&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve several properties from the previous element&lt;br /&gt;
  var deck_properties = bga.getElement( { name: &amp;quot;Deck&amp;quot; }, [&#039;name&#039;,&#039;id&#039;,&#039;parent&#039;, &#039;x&#039;,&#039;y&#039;,&#039;canShuffle&#039;] );&lt;br /&gt;
  // Return : { name:&#039;Deck&#039;, id:1234, parent:4321, x: 20, y:50, canShuffle: true }&lt;br /&gt;
  &lt;br /&gt;
  // Note : as you can see, getElement returns:&lt;br /&gt;
  //        _ the element ID by default, or&lt;br /&gt;
  //        _ a single value if you request a single field, or&lt;br /&gt;
  //        _ an object if you request several fields&lt;br /&gt;
&lt;br /&gt;
  // Examples using different &amp;quot;selector&amp;quot; paramter&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve an element name from its id&lt;br /&gt;
  var deck_name = bga.getElement( { id: 1234 }, [&#039;name&#039;] );&lt;br /&gt;
  // Return : &amp;quot;Deck&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  // Retrieve the last child element of another element&lt;br /&gt;
  // Here, we are requesting for elements who has element with ID=1234 (Deck) as their parent&lt;br /&gt;
  // Note the use of &amp;quot;limit:1&amp;quot; which allows us to retrieve only 1 element.&lt;br /&gt;
  var first_card_on_deck_id = bga.getElement( { parent: 1234, limit:1 } );&lt;br /&gt;
  &lt;br /&gt;
  // You can also get nested properties such as the ids of the child elements of one element, or a custom property placed on the parent element&lt;br /&gt;
  var totem_places = bga.getElements( {tag:&#039;TOTEMZONE&#039;}, [&#039;id&#039;,&#039;childs:id&#039;,&#039;childs:tags&#039;,&#039;parent:id&#039;,&#039;parent:c_value&#039;] );&lt;br /&gt;
&lt;br /&gt;
=== bga.getElements( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Returns an object holding the properties of the elements matching the selector.&lt;br /&gt;
&lt;br /&gt;
  // Basic example: unselect all selected elements&lt;br /&gt;
  bga.removeStyle( bga.getElements( {tag: &#039;sbstyle_selected&#039;}), &#039;selected&#039; );&lt;br /&gt;
&lt;br /&gt;
=== bga.getElementsArray( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Returns an array of all elements matching the selector, holding the required properties.&lt;br /&gt;
&lt;br /&gt;
  // Basic example: get id of selected element&lt;br /&gt;
  var selected_tokens = bga.getElementsArray( {tag: &#039;sbstyle_selected&#039; } );&lt;br /&gt;
  var token_id = null;&lt;br /&gt;
  if (selected_tokens.length &amp;gt; 0) {&lt;br /&gt;
      token_id = selected_tokens[0];&lt;br /&gt;
  }&lt;br /&gt;
  return token_id;&lt;br /&gt;
&lt;br /&gt;
  // Classic example: get array of elements and iterate over it&lt;br /&gt;
  var all_cells = bga.getElementsArray( {tag: &#039;CELL&#039;}, [&#039;id&#039;,&#039;name&#039;,&#039;tags&#039;] );&lt;br /&gt;
  for (var i=0; i&amp;lt;all_cells.length; i++) {&lt;br /&gt;
     // ... process each cell ...&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Utility methods ==&lt;br /&gt;
&lt;br /&gt;
=== bga.isOn( element_id, parent_id ) ===&lt;br /&gt;
&lt;br /&gt;
Return true if &amp;quot;element_id&amp;quot; is a descendant of &amp;quot;parent_id&amp;quot; (ie : if element_id game element has been placed on parent_id game element).&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  if( bga.isOn( bga.getElementIfByName( &#039;Turn counter&#039; ), bga.getElementIfByName( &#039;Turn 6&#039; ) )&lt;br /&gt;
  {&lt;br /&gt;
     // Trigger game end&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Trigger most common game actions ==&lt;br /&gt;
&lt;br /&gt;
=== moveTo( id, target, path ) ===&lt;br /&gt;
&lt;br /&gt;
Move element to specified target id (eventually following path defined by an array of element ids to pass over on the way)&lt;br /&gt;
&lt;br /&gt;
The exact destination of element depends on target&#039;s &amp;quot;howToArrange&amp;quot; property (&amp;quot;How elements are arranged on it?&amp;quot; : spreaded/deck/...).&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.moveTo( bga.getElementIdByName( &#039;Turn counter&#039; ), bga.getElementIdByName( &#039;Turn 3&#039; ) );&lt;br /&gt;
&lt;br /&gt;
=== incScore( color, value ) ===&lt;br /&gt;
&lt;br /&gt;
Increases the score for the player with the specified color, of the specified increment value.&lt;br /&gt;
&lt;br /&gt;
== Gamestate functions ==&lt;br /&gt;
&lt;br /&gt;
You can define your game flow with a list of states by adding a &amp;quot;states&amp;quot; function to your script.&lt;br /&gt;
&lt;br /&gt;
  function states()&lt;br /&gt;
  {&lt;br /&gt;
      return {&lt;br /&gt;
        // Init game&lt;br /&gt;
        100: {&lt;br /&gt;
            onState: &#039;postSetup&#039;,&lt;br /&gt;
            transitions: { done:200 }&lt;br /&gt;
        },&lt;br /&gt;
        200: {&lt;br /&gt;
            description: _(&#039;${actplayer} must move a piece&#039;),&lt;br /&gt;
            descriptionmyturn: _(&#039;${you} must move a piece&#039;),&lt;br /&gt;
            possibleactions: [&#039;movePiece&#039;],&lt;br /&gt;
            transitions: { nextPlayer: 200 }&lt;br /&gt;
        },&lt;br /&gt;
      };&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Then, you will be able to use the following functions to manage the game flow.&lt;br /&gt;
&lt;br /&gt;
=== checkAction( action ) ===&lt;br /&gt;
&lt;br /&gt;
Check if action is valid regarding current game state and raise an error if it&#039;s not the case.&lt;br /&gt;
&lt;br /&gt;
=== isActionPossible( action ) ===&lt;br /&gt;
&lt;br /&gt;
Check if action is valid regarding current game state and returns a boolean with the appropriate value.&lt;br /&gt;
&lt;br /&gt;
=== getActivePlayerColor() ===&lt;br /&gt;
&lt;br /&gt;
Returns the color code of the currently active player&lt;br /&gt;
&lt;br /&gt;
=== getActivePlayerName() ===&lt;br /&gt;
&lt;br /&gt;
Returns the color code of the currently active player&lt;br /&gt;
&lt;br /&gt;
=== nextPlayer() ===&lt;br /&gt;
&lt;br /&gt;
Activates the next player in play order.&lt;br /&gt;
&lt;br /&gt;
=== activeAllPlayers() ===&lt;br /&gt;
&lt;br /&gt;
Activates all players (multiactive state).&lt;br /&gt;
&lt;br /&gt;
=== endTurn( transition ) ===&lt;br /&gt;
&lt;br /&gt;
Make the current player inactive and go to the next state matching the provided transition if all players are inactive (multiactive state)&lt;br /&gt;
&lt;br /&gt;
=== getActivePlayerColors() ===&lt;br /&gt;
&lt;br /&gt;
Returns the colors code of the currently active players&lt;br /&gt;
&lt;br /&gt;
=== getCurrentPlayerColor() ===&lt;br /&gt;
&lt;br /&gt;
Returns the color code of the current player (the player who made the interface action being handled; may not be the active player).&lt;br /&gt;
&lt;br /&gt;
=== nextState( transition ) ===&lt;br /&gt;
&lt;br /&gt;
Moves to the next state matching the provided transition.&lt;br /&gt;
&lt;br /&gt;
=== getPlayers() ===&lt;br /&gt;
&lt;br /&gt;
Returns an array of players with the players information.&lt;br /&gt;
&lt;br /&gt;
=== endGame() ===&lt;br /&gt;
&lt;br /&gt;
When the end game condition is met, you can use this function to end the game (after setting the appropriate scores!)&lt;br /&gt;
&lt;br /&gt;
== Other functions ==&lt;br /&gt;
&lt;br /&gt;
=== pause( milliseconds ) ===&lt;br /&gt;
&lt;br /&gt;
Pause the client interface during a specified number of milliseconds.&lt;br /&gt;
&lt;br /&gt;
If you do not use bga.pause, all Sandbox game actions are executed immediately and synchronously.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.log( &amp;quot;1&amp;quot; );    // Will be displayed immediately on the log&lt;br /&gt;
  bga.pause( 3000 ); // pause during 3 seconds&lt;br /&gt;
  bga.log( &amp;quot;2&amp;quot; );    // Will be displayed after the 3 second on the log&lt;br /&gt;
  bga.log( &amp;quot;3&amp;quot; );    // Will be displayed right after the previous one, without delay.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Tips : if you want to execute several consecutive &amp;quot;moveTo&amp;quot;, you should &amp;quot;bga.pause&amp;quot; between them, otherwise your element will move directly to the final destination.&lt;br /&gt;
&lt;br /&gt;
=== hasTag( id, tag ) ===&lt;br /&gt;
&lt;br /&gt;
Returns true if the element with this id has this tag.&lt;br /&gt;
&lt;br /&gt;
=== addTag( id, tag ) ===&lt;br /&gt;
&lt;br /&gt;
Adds this tag to the element with this id.&lt;br /&gt;
&lt;br /&gt;
=== removeTag( id, tag ) ===&lt;br /&gt;
&lt;br /&gt;
Removes this tag from the element with this id.&lt;br /&gt;
&lt;br /&gt;
=== addStyle( id, style ) ===&lt;br /&gt;
&lt;br /&gt;
Adds this style to the element with this id.&lt;br /&gt;
&lt;br /&gt;
Predefined styles are: SELECTED / LIGHT / LIGHTBACKGROUND / REDSELECTED / CLICKABLE / ROUNDED / CLICKABLE_ROUNDED&lt;br /&gt;
&lt;br /&gt;
=== removeStyle( id, style ) ===&lt;br /&gt;
&lt;br /&gt;
Removes this style from the element with this id.&lt;br /&gt;
&lt;br /&gt;
=== setProperties( props ) ===&lt;br /&gt;
&lt;br /&gt;
This function allows to directly update properties of an object, and to manage custom properties if needed (custom properties must start with prefix &amp;quot;c_&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
    // Update player labels for player zones from &amp;quot;&amp;lt;color&amp;gt; player&amp;quot; to actual player name&lt;br /&gt;
    var players = bga.getPlayers();&lt;br /&gt;
    for (var color in players) {&lt;br /&gt;
        player = players[color];&lt;br /&gt;
        &lt;br /&gt;
        var labelId = null;&lt;br /&gt;
        if (color == &#039;ff0000&#039;) labelId = bga.getElement( {name: &#039;Red player&#039;} );&lt;br /&gt;
        if (color == &#039;008000&#039;) labelId = bga.getElement( {name: &#039;Green player&#039;} );&lt;br /&gt;
        if (color == &#039;0000ff&#039;) labelId = bga.getElement( {name: &#039;Blue player&#039;} );&lt;br /&gt;
        if (color == &#039;ffa500&#039;) labelId = bga.getElement( {name: &#039;Yellow player&#039;} );&lt;br /&gt;
        &lt;br /&gt;
        var props = [];&lt;br /&gt;
        props[labelId] = {name: player.name};&lt;br /&gt;
        bga.setProperties( props );&lt;br /&gt;
    }&lt;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://sr.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=3047</id>
		<title>SandboxScripts</title>
		<link rel="alternate" type="text/html" href="https://sr.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=3047"/>
		<updated>2018-05-17T16:26:38Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Gamestate functions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This is the reference of functions you can call from your Sandbox scripts.&lt;br /&gt;
&lt;br /&gt;
= Javascript =&lt;br /&gt;
&lt;br /&gt;
BGA Sandbox scripts are written in Javascript.&lt;br /&gt;
&lt;br /&gt;
Using Javascript, you can write scripts to automate moves for your Sandbox games &amp;amp; provide rules reinforcement.&lt;br /&gt;
&lt;br /&gt;
Important : in the opposite of the most common usage of Javascript, Sandbox scripts are executed &#039;&#039;&#039;on server side&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
= BGA API =&lt;br /&gt;
&lt;br /&gt;
To interact with your BGA Sandbox game, we provide you an API.&lt;br /&gt;
&lt;br /&gt;
With this API, you can get properties values of game elements from the current game situation, modify them and/or trigger the game actions (ex : move this element here, flip this card, and so on).&lt;br /&gt;
&lt;br /&gt;
= Quick start =&lt;br /&gt;
&lt;br /&gt;
== Hello World Script ==&lt;br /&gt;
&lt;br /&gt;
From Sandbox editor &amp;quot;interface view&amp;quot; tab, select an element, and access to its property (top right icon).&lt;br /&gt;
&lt;br /&gt;
Go to &amp;quot;Scripts (advanced)&amp;quot; section.&lt;br /&gt;
&lt;br /&gt;
In front of &amp;quot;When this element is clicked&amp;quot;, enter &amp;quot;onMyClick&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Close the window. Go to &amp;quot;script view&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Enter the following :&lt;br /&gt;
&lt;br /&gt;
 function onMyClick( element_id )&lt;br /&gt;
 {&lt;br /&gt;
    bga.log(&amp;quot;Hello world! You just clicked on element &amp;quot; + element_id + &amp;quot;. Congrats!&amp;quot;);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Save &amp;amp; publish your project, starts a test session, click on the previous element : your message appears in the log on the right!&lt;br /&gt;
&lt;br /&gt;
== Top useful tips ==&lt;br /&gt;
&lt;br /&gt;
* You don&#039;t have to save&amp;amp;publish from the Sandbox editor for each modification of your script : each time you save your script (control+S), the script used for all test sessions is updated. Note that the production version on BGA is of course NOT updated until you explicitly save&amp;amp;publish again your project.&lt;br /&gt;
&lt;br /&gt;
* To inspect the content of a variable, you can use bga.log() in combination with JSON.stringify(). For example :&lt;br /&gt;
&lt;br /&gt;
  bga.log( JSON.stringify( bga.getPlayers()) );&lt;br /&gt;
&lt;br /&gt;
* Alternatively to bga.log(), you can use bga.exit( &amp;quot;my message&amp;quot; ) to debug your script. With bga.exit, the script execution immediately stops and all previous game changes are cancelled, so this is very practical to try and retry an action until your script is fine.&lt;br /&gt;
&lt;br /&gt;
* We advise you to develop first a full playable version of the game without the scripts, and THEN to script it.&lt;br /&gt;
&lt;br /&gt;
* On Board Game Arena, players have come to expect fully implemented games with all rules enforced. So even if it&#039;s technically possible not to script the full game and to implement the game only partially, in most cases we&#039;ll publish only fully scripted games :)&lt;br /&gt;
&lt;br /&gt;
= Functions you can use in your Sandbox scripts=&lt;br /&gt;
&lt;br /&gt;
== Debugging functions ==&lt;br /&gt;
&lt;br /&gt;
=== bga.trace( txt / obj ) ===&lt;br /&gt;
&lt;br /&gt;
Write something immediately in the BGA log (on the right of the screen).&lt;br /&gt;
&lt;br /&gt;
This is the most practical way to debug your script :)&lt;br /&gt;
&lt;br /&gt;
Important : bga.trace is for debugging purpose only and won&#039;t be displayed on production.&lt;br /&gt;
&lt;br /&gt;
Note : you can also pass an object in parameter. This will dump the content of this object in the log.&lt;br /&gt;
&lt;br /&gt;
Note : in the opposite of bga.log, bga.trace is NOT cancelled if the game action failed (after a call to bga.cancel or bga.error). This makes bga.trace very practical to debug a game action that failed, and for this reason you should probably NEVER use bga.log for debugging purpose.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  // Example : write &amp;quot;Hello world&amp;quot; in the log&lt;br /&gt;
  bga.trace( &amp;quot;Hello world&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Example : dump an associative array in the log&lt;br /&gt;
  bga.trace( { mykey: &#039;myvalue&#039;, another_key: &#039;another_value&#039; } );&lt;br /&gt;
&lt;br /&gt;
=== bga.exit( txt / obj ) ===&lt;br /&gt;
&lt;br /&gt;
Stop the script immediately, display the &amp;quot;txt&amp;quot; messages and cancel (ie : rollback) on every previous API call except bga.trace :&lt;br /&gt;
&lt;br /&gt;
ALL previous BGA api call are canceled and there will be no visible changes on the interface (ex : no moves, no visible property changes, ...). Only &amp;quot;bga.trace&amp;quot; API commands are kept so you can debug.&lt;br /&gt;
&lt;br /&gt;
bga.exit is very practical when you want to repeat a game action again and again to debug it : with a call to bga.exit at the end of your script, you make sure that your game situation will be kept unchanged after each test.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.exit( &amp;quot;My script is stopped by this call&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Example with dumping a javascript variable&lt;br /&gt;
  bga.exit( my_variable_to_dump );&lt;br /&gt;
&lt;br /&gt;
== Cancelling a game action ==&lt;br /&gt;
&lt;br /&gt;
=== bga.cancel( txt ) ===&lt;br /&gt;
&lt;br /&gt;
This is the function to use when a player is doing something against game rules.&lt;br /&gt;
&lt;br /&gt;
The text message in parameter will be displayed to this player as a &amp;quot;red message&amp;quot;, so he/she can understand the rule.&lt;br /&gt;
&lt;br /&gt;
All previous BGA api call are cancelled, and there will be no visible changes on the interface.&lt;br /&gt;
&lt;br /&gt;
   // Example :&lt;br /&gt;
   bga.cancel( _(&amp;quot;You cannot move this piece here&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
Note : most of the time, you should wrap your text inside a _() translation marker to make this string translatable.&lt;br /&gt;
&lt;br /&gt;
=== bga.error( text ) ===&lt;br /&gt;
&lt;br /&gt;
This is the function to use when some unexpected error happens in your script.&lt;br /&gt;
&lt;br /&gt;
The text message will be displayed to user, with mention &amp;quot;Unexpected error&amp;quot;. The player will be incited to fill a bug report. The purpose of the message is to help you to identify the bug.&lt;br /&gt;
&lt;br /&gt;
All previous BGA api call are cancelled, and there will be no visible changes on the interface.&lt;br /&gt;
&lt;br /&gt;
   // Example :&lt;br /&gt;
   if( card_picked === null )&lt;br /&gt;
   {&lt;br /&gt;
       bga.error( &amp;quot;Cannot find a card to pick !&amp;quot; );&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
Note : you should NEVER wrap text inside bga.error with _() translation marker, because unexpected error should not be translate (so you can eventually recognize them when reported by players in bug report).&lt;br /&gt;
&lt;br /&gt;
== Game log (history) ==&lt;br /&gt;
&lt;br /&gt;
=== bga.log( txt, (optional) args ) ===&lt;br /&gt;
&lt;br /&gt;
Write something in the BGA log on the right.&lt;br /&gt;
&lt;br /&gt;
  // Example : simple log&lt;br /&gt;
  bga.log( _(&amp;quot;A new round starts&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
You may add arguments to your log, like this :&lt;br /&gt;
&lt;br /&gt;
  // Example: log with argument to display a card name.&lt;br /&gt;
  //          In this example, variable &amp;quot;event_name&amp;quot; is specified afterwards.&lt;br /&gt;
  //          Note that using this, game translators only have to translate one &amp;quot;Event XXX is triggered&amp;quot; string for all possible events.&lt;br /&gt;
  bga.log( _(&amp;quot;Event ${event_name} is triggered&amp;quot;), {  event_name: _( &amp;quot;Armageddon&amp;quot; ) } ) );&lt;br /&gt;
&lt;br /&gt;
Note that argument &amp;quot;player_name&amp;quot; is ALWAYS pre-set with the name of the current player, so you can use it immediately.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.log( _(&amp;quot;${player_name} draw a card from the deck&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
=== bga.speechBubble( target, text, (optional) args, (optional) delay, (optional) duration, (optional) size ) ===&lt;br /&gt;
&lt;br /&gt;
Display a &amp;quot;speech bubble&amp;quot;, attached to the specified target, containing the specified text.&lt;br /&gt;
&lt;br /&gt;
You can use &amp;quot;args&amp;quot; to customize text exactly like with bga.log.&lt;br /&gt;
&lt;br /&gt;
delay : milliseconds to wait before displaying the speech bubble (default : 0).&lt;br /&gt;
duration : how long to show the speech bubble in milliseconds (default : 3000).&lt;br /&gt;
size : size of the text in percent (default: 100)&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.speechBubble( _(&amp;quot;I play ${nbr} cards&amp;quot;), { nbr : 4 }, 0 );&lt;br /&gt;
  bga.speechBubble( _(&amp;quot;Good for you!&amp;quot;), { }, 2000 );&lt;br /&gt;
&lt;br /&gt;
=== bga.displayScoring( target, color, score ) ===&lt;br /&gt;
&lt;br /&gt;
Display an animated temporary &amp;quot;score number&amp;quot;, attached to the specified target.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;color&amp;quot; should be the color of the player who is scoring for that target.&lt;br /&gt;
&lt;br /&gt;
== Get / search game elements and their properties ==&lt;br /&gt;
&lt;br /&gt;
=== bga.getElement( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Allow you to retrieve informations about one game element specified using &amp;quot;selector&amp;quot; argument.&lt;br /&gt;
&lt;br /&gt;
Return null if no element is found.&lt;br /&gt;
&lt;br /&gt;
Note : getElement throw an error if several elements matches the selector. If you want to retrieve several elements, you should use &amp;quot;getElements&amp;quot; instead of &amp;quot;getElement&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The following examples are showing all the possible use of bga.getElement :&lt;br /&gt;
&lt;br /&gt;
  // Basic example :&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve the ID of a game element using its name (&amp;quot;Deck&amp;quot;)&lt;br /&gt;
  var deck_id = bga.getElement( { name: &amp;quot;Deck&amp;quot; } );&lt;br /&gt;
  // Return : 1234  &lt;br /&gt;
&lt;br /&gt;
  // Examples using &amp;quot;field&amp;quot; parameter :&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve a specific property from a game element using its name (&amp;quot;Deck&amp;quot;)&lt;br /&gt;
  var deck_id = bga.getElement( { name: &amp;quot;Deck&amp;quot; }, &#039;x&#039; );&lt;br /&gt;
  // Return : 20&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve several properties from the previous element&lt;br /&gt;
  var deck_properties = bga.getElement( { name: &amp;quot;Deck&amp;quot; }, [&#039;name&#039;,&#039;id&#039;,&#039;parent&#039;, &#039;x&#039;,&#039;y&#039;,&#039;canShuffle&#039;] );&lt;br /&gt;
  // Return : { name:&#039;Deck&#039;, id:1234, parent:4321, x: 20, y:50, canShuffle: true }&lt;br /&gt;
  &lt;br /&gt;
  // Note : as you can see, getElement returns:&lt;br /&gt;
  //        _ the element ID by default, or&lt;br /&gt;
  //        _ a single value if you request a single field, or&lt;br /&gt;
  //        _ an object if you request several fields&lt;br /&gt;
&lt;br /&gt;
  // Examples using different &amp;quot;selector&amp;quot; paramter&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve an element name from its id&lt;br /&gt;
  var deck_name = bga.getElement( { id: 1234 }, [&#039;name&#039;] );&lt;br /&gt;
  // Return : &amp;quot;Deck&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  // Retrieve the last child element of another element&lt;br /&gt;
  // Here, we are requesting for elements who has element with ID=1234 (Deck) as their parent&lt;br /&gt;
  // Note the use of &amp;quot;limit:1&amp;quot; which allows us to retrieve only 1 element.&lt;br /&gt;
  var first_card_on_deck_id = bga.getElement( { parent: 1234, limit:1 } );&lt;br /&gt;
  &lt;br /&gt;
  // You can also get nested properties such as the ids of the child elements of one element, or a custom property placed on the parent element&lt;br /&gt;
  var totem_places = bga.getElements( {tag:&#039;TOTEMZONE&#039;}, [&#039;id&#039;,&#039;childs:id&#039;,&#039;childs:tags&#039;,&#039;parent:id&#039;,&#039;parent:c_value&#039;] );&lt;br /&gt;
&lt;br /&gt;
=== bga.getElements( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Returns an object holding the properties of the elements matching the selector.&lt;br /&gt;
&lt;br /&gt;
  // Basic example: unselect all selected elements&lt;br /&gt;
  bga.removeStyle( bga.getElements( {tag: &#039;sbstyle_selected&#039;}), &#039;selected&#039; );&lt;br /&gt;
&lt;br /&gt;
=== bga.getElementsArray( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Returns an array of all elements matching the selector, holding the required properties.&lt;br /&gt;
&lt;br /&gt;
  // Basic example: get id of selected element&lt;br /&gt;
  var selected_tokens = bga.getElementsArray( {tag: &#039;sbstyle_selected&#039; } );&lt;br /&gt;
  var token_id = null;&lt;br /&gt;
  if (selected_tokens.length &amp;gt; 0) {&lt;br /&gt;
      token_id = selected_tokens[0];&lt;br /&gt;
  }&lt;br /&gt;
  return token_id;&lt;br /&gt;
&lt;br /&gt;
  // Classic example: get array of elements and iterate over it&lt;br /&gt;
  var all_cells = bga.getElementsArray( {tag: &#039;CELL&#039;}, [&#039;id&#039;,&#039;name&#039;,&#039;tags&#039;] );&lt;br /&gt;
  for (var i=0; i&amp;lt;all_cells.length; i++) {&lt;br /&gt;
     // ... process each cell ...&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Utility methods ==&lt;br /&gt;
&lt;br /&gt;
=== bga.isOn( element_id, parent_id ) ===&lt;br /&gt;
&lt;br /&gt;
Return true if &amp;quot;element_id&amp;quot; is a descendant of &amp;quot;parent_id&amp;quot; (ie : if element_id game element has been placed on parent_id game element).&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  if( bga.isOn( bga.getElementIfByName( &#039;Turn counter&#039; ), bga.getElementIfByName( &#039;Turn 6&#039; ) )&lt;br /&gt;
  {&lt;br /&gt;
     // Trigger game end&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Trigger most common game actions ==&lt;br /&gt;
&lt;br /&gt;
=== moveTo( id, target, path ) ===&lt;br /&gt;
&lt;br /&gt;
Move element to specified target id (eventually following path defined by an array of element ids to pass over on the way)&lt;br /&gt;
&lt;br /&gt;
The exact destination of element depends on target&#039;s &amp;quot;howToArrange&amp;quot; property (&amp;quot;How elements are arranged on it?&amp;quot; : spreaded/deck/...).&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.moveTo( bga.getElementIdByName( &#039;Turn counter&#039; ), bga.getElementIdByName( &#039;Turn 3&#039; ) );&lt;br /&gt;
&lt;br /&gt;
=== incScore( color, value ) ===&lt;br /&gt;
&lt;br /&gt;
Increases the score for the player with the specified color, of the specified increment value.&lt;br /&gt;
&lt;br /&gt;
== Gamestate functions ==&lt;br /&gt;
&lt;br /&gt;
You can define your game flow with a list of states by adding a &amp;quot;states&amp;quot; function to your script.&lt;br /&gt;
&lt;br /&gt;
  function states()&lt;br /&gt;
  {&lt;br /&gt;
      return {&lt;br /&gt;
        // Init game&lt;br /&gt;
        100: {&lt;br /&gt;
            onState: &#039;postSetup&#039;,&lt;br /&gt;
            transitions: { done:200 }&lt;br /&gt;
        },&lt;br /&gt;
        200: {&lt;br /&gt;
            description: _(&#039;${actplayer} must move a piece&#039;),&lt;br /&gt;
            descriptionmyturn: _(&#039;${you} must move a piece&#039;),&lt;br /&gt;
            possibleactions: [&#039;movePiece&#039;],&lt;br /&gt;
            transitions: { nextPlayer: 200 }&lt;br /&gt;
        },&lt;br /&gt;
      };&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Then, you will be able to use the following functions to manage the game flow.&lt;br /&gt;
&lt;br /&gt;
=== checkAction( action ) ===&lt;br /&gt;
&lt;br /&gt;
Check if action is valid regarding current game state and raise an error if it&#039;s not the case.&lt;br /&gt;
&lt;br /&gt;
=== isActionPossible( action ) ===&lt;br /&gt;
&lt;br /&gt;
Check if action is valid regarding current game state and returns a boolean with the appropriate value.&lt;br /&gt;
&lt;br /&gt;
=== getActivePlayerColor() ===&lt;br /&gt;
&lt;br /&gt;
Returns the color code of the currently active player&lt;br /&gt;
&lt;br /&gt;
=== nextPlayer() ===&lt;br /&gt;
&lt;br /&gt;
Activates the next player in play order.&lt;br /&gt;
&lt;br /&gt;
=== nextState( transition ) ===&lt;br /&gt;
&lt;br /&gt;
Moves to the next state matching the provided transition.&lt;br /&gt;
&lt;br /&gt;
=== getPlayers() ===&lt;br /&gt;
&lt;br /&gt;
Returns an array of players with the players information.&lt;br /&gt;
&lt;br /&gt;
=== endGame() ===&lt;br /&gt;
&lt;br /&gt;
When the end game condition is met, you can use this function to end the game (after setting the appropriate scores!)&lt;br /&gt;
&lt;br /&gt;
== Other functions ==&lt;br /&gt;
&lt;br /&gt;
=== pause( milliseconds ) ===&lt;br /&gt;
&lt;br /&gt;
Pause the client interface during a specified number of milliseconds.&lt;br /&gt;
&lt;br /&gt;
If you do not use bga.pause, all Sandbox game actions are executed immediately and synchronously.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.log( &amp;quot;1&amp;quot; );    // Will be displayed immediately on the log&lt;br /&gt;
  bga.pause( 3000 ); // pause during 3 seconds&lt;br /&gt;
  bga.log( &amp;quot;2&amp;quot; );    // Will be displayed after the 3 second on the log&lt;br /&gt;
  bga.log( &amp;quot;3&amp;quot; );    // Will be displayed right after the previous one, without delay.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Tips : if you want to execute several consecutive &amp;quot;moveTo&amp;quot;, you should &amp;quot;bga.pause&amp;quot; between them, otherwise your element will move directly to the final destination.&lt;br /&gt;
&lt;br /&gt;
=== hasTag( id, tag ) ===&lt;br /&gt;
&lt;br /&gt;
Returns true if the element with this id has this tag.&lt;br /&gt;
&lt;br /&gt;
=== addTag( id, tag ) ===&lt;br /&gt;
&lt;br /&gt;
Adds this tag to the element with this id.&lt;br /&gt;
&lt;br /&gt;
=== removeTag( id, tag ) ===&lt;br /&gt;
&lt;br /&gt;
Removes this tag from the element with this id.&lt;br /&gt;
&lt;br /&gt;
=== addStyle( id, style ) ===&lt;br /&gt;
&lt;br /&gt;
Adds this style to the element with this id.&lt;br /&gt;
&lt;br /&gt;
Predefined styles are: SELECTED / LIGHT / LIGHTBACKGROUND / REDSELECTED / CLICKABLE / ROUNDED / CLICKABLE_ROUNDED&lt;br /&gt;
&lt;br /&gt;
=== removeStyle( id, style ) ===&lt;br /&gt;
&lt;br /&gt;
Removes this style from the element with this id.&lt;br /&gt;
&lt;br /&gt;
=== setProperties( props ) ===&lt;br /&gt;
&lt;br /&gt;
This function allows to directly update properties of an object, and to manage custom properties if needed (custom properties must start with prefix &amp;quot;c_&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
    // Update player labels for player zones from &amp;quot;&amp;lt;color&amp;gt; player&amp;quot; to actual player name&lt;br /&gt;
    var players = bga.getPlayers();&lt;br /&gt;
    for (var color in players) {&lt;br /&gt;
        player = players[color];&lt;br /&gt;
        &lt;br /&gt;
        var labelId = null;&lt;br /&gt;
        if (color == &#039;ff0000&#039;) labelId = bga.getElement( {name: &#039;Red player&#039;} );&lt;br /&gt;
        if (color == &#039;008000&#039;) labelId = bga.getElement( {name: &#039;Green player&#039;} );&lt;br /&gt;
        if (color == &#039;0000ff&#039;) labelId = bga.getElement( {name: &#039;Blue player&#039;} );&lt;br /&gt;
        if (color == &#039;ffa500&#039;) labelId = bga.getElement( {name: &#039;Yellow player&#039;} );&lt;br /&gt;
        &lt;br /&gt;
        var props = [];&lt;br /&gt;
        props[labelId] = {name: player.name};&lt;br /&gt;
        bga.setProperties( props );&lt;br /&gt;
    }&lt;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://sr.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=3046</id>
		<title>SandboxScripts</title>
		<link rel="alternate" type="text/html" href="https://sr.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=3046"/>
		<updated>2018-05-17T16:26:03Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Gamestate functions */ gamestates functions&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This is the reference of functions you can call from your Sandbox scripts.&lt;br /&gt;
&lt;br /&gt;
= Javascript =&lt;br /&gt;
&lt;br /&gt;
BGA Sandbox scripts are written in Javascript.&lt;br /&gt;
&lt;br /&gt;
Using Javascript, you can write scripts to automate moves for your Sandbox games &amp;amp; provide rules reinforcement.&lt;br /&gt;
&lt;br /&gt;
Important : in the opposite of the most common usage of Javascript, Sandbox scripts are executed &#039;&#039;&#039;on server side&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
= BGA API =&lt;br /&gt;
&lt;br /&gt;
To interact with your BGA Sandbox game, we provide you an API.&lt;br /&gt;
&lt;br /&gt;
With this API, you can get properties values of game elements from the current game situation, modify them and/or trigger the game actions (ex : move this element here, flip this card, and so on).&lt;br /&gt;
&lt;br /&gt;
= Quick start =&lt;br /&gt;
&lt;br /&gt;
== Hello World Script ==&lt;br /&gt;
&lt;br /&gt;
From Sandbox editor &amp;quot;interface view&amp;quot; tab, select an element, and access to its property (top right icon).&lt;br /&gt;
&lt;br /&gt;
Go to &amp;quot;Scripts (advanced)&amp;quot; section.&lt;br /&gt;
&lt;br /&gt;
In front of &amp;quot;When this element is clicked&amp;quot;, enter &amp;quot;onMyClick&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Close the window. Go to &amp;quot;script view&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Enter the following :&lt;br /&gt;
&lt;br /&gt;
 function onMyClick( element_id )&lt;br /&gt;
 {&lt;br /&gt;
    bga.log(&amp;quot;Hello world! You just clicked on element &amp;quot; + element_id + &amp;quot;. Congrats!&amp;quot;);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Save &amp;amp; publish your project, starts a test session, click on the previous element : your message appears in the log on the right!&lt;br /&gt;
&lt;br /&gt;
== Top useful tips ==&lt;br /&gt;
&lt;br /&gt;
* You don&#039;t have to save&amp;amp;publish from the Sandbox editor for each modification of your script : each time you save your script (control+S), the script used for all test sessions is updated. Note that the production version on BGA is of course NOT updated until you explicitly save&amp;amp;publish again your project.&lt;br /&gt;
&lt;br /&gt;
* To inspect the content of a variable, you can use bga.log() in combination with JSON.stringify(). For example :&lt;br /&gt;
&lt;br /&gt;
  bga.log( JSON.stringify( bga.getPlayers()) );&lt;br /&gt;
&lt;br /&gt;
* Alternatively to bga.log(), you can use bga.exit( &amp;quot;my message&amp;quot; ) to debug your script. With bga.exit, the script execution immediately stops and all previous game changes are cancelled, so this is very practical to try and retry an action until your script is fine.&lt;br /&gt;
&lt;br /&gt;
* We advise you to develop first a full playable version of the game without the scripts, and THEN to script it.&lt;br /&gt;
&lt;br /&gt;
* On Board Game Arena, players have come to expect fully implemented games with all rules enforced. So even if it&#039;s technically possible not to script the full game and to implement the game only partially, in most cases we&#039;ll publish only fully scripted games :)&lt;br /&gt;
&lt;br /&gt;
= Functions you can use in your Sandbox scripts=&lt;br /&gt;
&lt;br /&gt;
== Debugging functions ==&lt;br /&gt;
&lt;br /&gt;
=== bga.trace( txt / obj ) ===&lt;br /&gt;
&lt;br /&gt;
Write something immediately in the BGA log (on the right of the screen).&lt;br /&gt;
&lt;br /&gt;
This is the most practical way to debug your script :)&lt;br /&gt;
&lt;br /&gt;
Important : bga.trace is for debugging purpose only and won&#039;t be displayed on production.&lt;br /&gt;
&lt;br /&gt;
Note : you can also pass an object in parameter. This will dump the content of this object in the log.&lt;br /&gt;
&lt;br /&gt;
Note : in the opposite of bga.log, bga.trace is NOT cancelled if the game action failed (after a call to bga.cancel or bga.error). This makes bga.trace very practical to debug a game action that failed, and for this reason you should probably NEVER use bga.log for debugging purpose.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  // Example : write &amp;quot;Hello world&amp;quot; in the log&lt;br /&gt;
  bga.trace( &amp;quot;Hello world&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Example : dump an associative array in the log&lt;br /&gt;
  bga.trace( { mykey: &#039;myvalue&#039;, another_key: &#039;another_value&#039; } );&lt;br /&gt;
&lt;br /&gt;
=== bga.exit( txt / obj ) ===&lt;br /&gt;
&lt;br /&gt;
Stop the script immediately, display the &amp;quot;txt&amp;quot; messages and cancel (ie : rollback) on every previous API call except bga.trace :&lt;br /&gt;
&lt;br /&gt;
ALL previous BGA api call are canceled and there will be no visible changes on the interface (ex : no moves, no visible property changes, ...). Only &amp;quot;bga.trace&amp;quot; API commands are kept so you can debug.&lt;br /&gt;
&lt;br /&gt;
bga.exit is very practical when you want to repeat a game action again and again to debug it : with a call to bga.exit at the end of your script, you make sure that your game situation will be kept unchanged after each test.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.exit( &amp;quot;My script is stopped by this call&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Example with dumping a javascript variable&lt;br /&gt;
  bga.exit( my_variable_to_dump );&lt;br /&gt;
&lt;br /&gt;
== Cancelling a game action ==&lt;br /&gt;
&lt;br /&gt;
=== bga.cancel( txt ) ===&lt;br /&gt;
&lt;br /&gt;
This is the function to use when a player is doing something against game rules.&lt;br /&gt;
&lt;br /&gt;
The text message in parameter will be displayed to this player as a &amp;quot;red message&amp;quot;, so he/she can understand the rule.&lt;br /&gt;
&lt;br /&gt;
All previous BGA api call are cancelled, and there will be no visible changes on the interface.&lt;br /&gt;
&lt;br /&gt;
   // Example :&lt;br /&gt;
   bga.cancel( _(&amp;quot;You cannot move this piece here&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
Note : most of the time, you should wrap your text inside a _() translation marker to make this string translatable.&lt;br /&gt;
&lt;br /&gt;
=== bga.error( text ) ===&lt;br /&gt;
&lt;br /&gt;
This is the function to use when some unexpected error happens in your script.&lt;br /&gt;
&lt;br /&gt;
The text message will be displayed to user, with mention &amp;quot;Unexpected error&amp;quot;. The player will be incited to fill a bug report. The purpose of the message is to help you to identify the bug.&lt;br /&gt;
&lt;br /&gt;
All previous BGA api call are cancelled, and there will be no visible changes on the interface.&lt;br /&gt;
&lt;br /&gt;
   // Example :&lt;br /&gt;
   if( card_picked === null )&lt;br /&gt;
   {&lt;br /&gt;
       bga.error( &amp;quot;Cannot find a card to pick !&amp;quot; );&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
Note : you should NEVER wrap text inside bga.error with _() translation marker, because unexpected error should not be translate (so you can eventually recognize them when reported by players in bug report).&lt;br /&gt;
&lt;br /&gt;
== Game log (history) ==&lt;br /&gt;
&lt;br /&gt;
=== bga.log( txt, (optional) args ) ===&lt;br /&gt;
&lt;br /&gt;
Write something in the BGA log on the right.&lt;br /&gt;
&lt;br /&gt;
  // Example : simple log&lt;br /&gt;
  bga.log( _(&amp;quot;A new round starts&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
You may add arguments to your log, like this :&lt;br /&gt;
&lt;br /&gt;
  // Example: log with argument to display a card name.&lt;br /&gt;
  //          In this example, variable &amp;quot;event_name&amp;quot; is specified afterwards.&lt;br /&gt;
  //          Note that using this, game translators only have to translate one &amp;quot;Event XXX is triggered&amp;quot; string for all possible events.&lt;br /&gt;
  bga.log( _(&amp;quot;Event ${event_name} is triggered&amp;quot;), {  event_name: _( &amp;quot;Armageddon&amp;quot; ) } ) );&lt;br /&gt;
&lt;br /&gt;
Note that argument &amp;quot;player_name&amp;quot; is ALWAYS pre-set with the name of the current player, so you can use it immediately.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.log( _(&amp;quot;${player_name} draw a card from the deck&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
=== bga.speechBubble( target, text, (optional) args, (optional) delay, (optional) duration, (optional) size ) ===&lt;br /&gt;
&lt;br /&gt;
Display a &amp;quot;speech bubble&amp;quot;, attached to the specified target, containing the specified text.&lt;br /&gt;
&lt;br /&gt;
You can use &amp;quot;args&amp;quot; to customize text exactly like with bga.log.&lt;br /&gt;
&lt;br /&gt;
delay : milliseconds to wait before displaying the speech bubble (default : 0).&lt;br /&gt;
duration : how long to show the speech bubble in milliseconds (default : 3000).&lt;br /&gt;
size : size of the text in percent (default: 100)&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.speechBubble( _(&amp;quot;I play ${nbr} cards&amp;quot;), { nbr : 4 }, 0 );&lt;br /&gt;
  bga.speechBubble( _(&amp;quot;Good for you!&amp;quot;), { }, 2000 );&lt;br /&gt;
&lt;br /&gt;
=== bga.displayScoring( target, color, score ) ===&lt;br /&gt;
&lt;br /&gt;
Display an animated temporary &amp;quot;score number&amp;quot;, attached to the specified target.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;color&amp;quot; should be the color of the player who is scoring for that target.&lt;br /&gt;
&lt;br /&gt;
== Get / search game elements and their properties ==&lt;br /&gt;
&lt;br /&gt;
=== bga.getElement( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Allow you to retrieve informations about one game element specified using &amp;quot;selector&amp;quot; argument.&lt;br /&gt;
&lt;br /&gt;
Return null if no element is found.&lt;br /&gt;
&lt;br /&gt;
Note : getElement throw an error if several elements matches the selector. If you want to retrieve several elements, you should use &amp;quot;getElements&amp;quot; instead of &amp;quot;getElement&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The following examples are showing all the possible use of bga.getElement :&lt;br /&gt;
&lt;br /&gt;
  // Basic example :&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve the ID of a game element using its name (&amp;quot;Deck&amp;quot;)&lt;br /&gt;
  var deck_id = bga.getElement( { name: &amp;quot;Deck&amp;quot; } );&lt;br /&gt;
  // Return : 1234  &lt;br /&gt;
&lt;br /&gt;
  // Examples using &amp;quot;field&amp;quot; parameter :&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve a specific property from a game element using its name (&amp;quot;Deck&amp;quot;)&lt;br /&gt;
  var deck_id = bga.getElement( { name: &amp;quot;Deck&amp;quot; }, &#039;x&#039; );&lt;br /&gt;
  // Return : 20&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve several properties from the previous element&lt;br /&gt;
  var deck_properties = bga.getElement( { name: &amp;quot;Deck&amp;quot; }, [&#039;name&#039;,&#039;id&#039;,&#039;parent&#039;, &#039;x&#039;,&#039;y&#039;,&#039;canShuffle&#039;] );&lt;br /&gt;
  // Return : { name:&#039;Deck&#039;, id:1234, parent:4321, x: 20, y:50, canShuffle: true }&lt;br /&gt;
  &lt;br /&gt;
  // Note : as you can see, getElement returns:&lt;br /&gt;
  //        _ the element ID by default, or&lt;br /&gt;
  //        _ a single value if you request a single field, or&lt;br /&gt;
  //        _ an object if you request several fields&lt;br /&gt;
&lt;br /&gt;
  // Examples using different &amp;quot;selector&amp;quot; paramter&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve an element name from its id&lt;br /&gt;
  var deck_name = bga.getElement( { id: 1234 }, [&#039;name&#039;] );&lt;br /&gt;
  // Return : &amp;quot;Deck&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  // Retrieve the last child element of another element&lt;br /&gt;
  // Here, we are requesting for elements who has element with ID=1234 (Deck) as their parent&lt;br /&gt;
  // Note the use of &amp;quot;limit:1&amp;quot; which allows us to retrieve only 1 element.&lt;br /&gt;
  var first_card_on_deck_id = bga.getElement( { parent: 1234, limit:1 } );&lt;br /&gt;
  &lt;br /&gt;
  // You can also get nested properties such as the ids of the child elements of one element, or a custom property placed on the parent element&lt;br /&gt;
  var totem_places = bga.getElements( {tag:&#039;TOTEMZONE&#039;}, [&#039;id&#039;,&#039;childs:id&#039;,&#039;childs:tags&#039;,&#039;parent:id&#039;,&#039;parent:c_value&#039;] );&lt;br /&gt;
&lt;br /&gt;
=== bga.getElements( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Returns an object holding the properties of the elements matching the selector.&lt;br /&gt;
&lt;br /&gt;
  // Basic example: unselect all selected elements&lt;br /&gt;
  bga.removeStyle( bga.getElements( {tag: &#039;sbstyle_selected&#039;}), &#039;selected&#039; );&lt;br /&gt;
&lt;br /&gt;
=== bga.getElementsArray( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Returns an array of all elements matching the selector, holding the required properties.&lt;br /&gt;
&lt;br /&gt;
  // Basic example: get id of selected element&lt;br /&gt;
  var selected_tokens = bga.getElementsArray( {tag: &#039;sbstyle_selected&#039; } );&lt;br /&gt;
  var token_id = null;&lt;br /&gt;
  if (selected_tokens.length &amp;gt; 0) {&lt;br /&gt;
      token_id = selected_tokens[0];&lt;br /&gt;
  }&lt;br /&gt;
  return token_id;&lt;br /&gt;
&lt;br /&gt;
  // Classic example: get array of elements and iterate over it&lt;br /&gt;
  var all_cells = bga.getElementsArray( {tag: &#039;CELL&#039;}, [&#039;id&#039;,&#039;name&#039;,&#039;tags&#039;] );&lt;br /&gt;
  for (var i=0; i&amp;lt;all_cells.length; i++) {&lt;br /&gt;
     // ... process each cell ...&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Utility methods ==&lt;br /&gt;
&lt;br /&gt;
=== bga.isOn( element_id, parent_id ) ===&lt;br /&gt;
&lt;br /&gt;
Return true if &amp;quot;element_id&amp;quot; is a descendant of &amp;quot;parent_id&amp;quot; (ie : if element_id game element has been placed on parent_id game element).&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  if( bga.isOn( bga.getElementIfByName( &#039;Turn counter&#039; ), bga.getElementIfByName( &#039;Turn 6&#039; ) )&lt;br /&gt;
  {&lt;br /&gt;
     // Trigger game end&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Trigger most common game actions ==&lt;br /&gt;
&lt;br /&gt;
=== moveTo( id, target, path ) ===&lt;br /&gt;
&lt;br /&gt;
Move element to specified target id (eventually following path defined by an array of element ids to pass over on the way)&lt;br /&gt;
&lt;br /&gt;
The exact destination of element depends on target&#039;s &amp;quot;howToArrange&amp;quot; property (&amp;quot;How elements are arranged on it?&amp;quot; : spreaded/deck/...).&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.moveTo( bga.getElementIdByName( &#039;Turn counter&#039; ), bga.getElementIdByName( &#039;Turn 3&#039; ) );&lt;br /&gt;
&lt;br /&gt;
=== incScore( color, value ) ===&lt;br /&gt;
&lt;br /&gt;
Increases the score for the player with the specified color, of the specified increment value.&lt;br /&gt;
&lt;br /&gt;
== Gamestate functions ==&lt;br /&gt;
&lt;br /&gt;
You can define your game flow with a list of states by adding a &amp;quot;states&amp;quot; function to your script.&lt;br /&gt;
&lt;br /&gt;
  function states()&lt;br /&gt;
  {&lt;br /&gt;
      return {&lt;br /&gt;
&lt;br /&gt;
        // Init game&lt;br /&gt;
        100: {&lt;br /&gt;
            onState: &#039;postSetup&#039;,&lt;br /&gt;
            transitions: { done:200 }&lt;br /&gt;
        },&lt;br /&gt;
        &lt;br /&gt;
        200: {&lt;br /&gt;
            description: _(&#039;${actplayer} must move a piece&#039;),&lt;br /&gt;
            descriptionmyturn: _(&#039;${you} must move a piece&#039;),&lt;br /&gt;
            possibleactions: [&#039;movePiece&#039;],&lt;br /&gt;
            transitions: { nextPlayer: 200 }&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
      };&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Then, you will be able to use the following functions to manage the game flow.&lt;br /&gt;
&lt;br /&gt;
=== checkAction( action ) ===&lt;br /&gt;
&lt;br /&gt;
Check if action is valid regarding current game state and raise an error if it&#039;s not the case.&lt;br /&gt;
&lt;br /&gt;
=== isActionPossible( action ) ===&lt;br /&gt;
&lt;br /&gt;
Check if action is valid regarding current game state and returns a boolean with the appropriate value.&lt;br /&gt;
&lt;br /&gt;
=== getActivePlayerColor() ===&lt;br /&gt;
&lt;br /&gt;
Returns the color code of the currently active player&lt;br /&gt;
&lt;br /&gt;
=== nextPlayer() ===&lt;br /&gt;
&lt;br /&gt;
Activates the next player in play order.&lt;br /&gt;
&lt;br /&gt;
=== nextState( transition ) ===&lt;br /&gt;
&lt;br /&gt;
Moves to the next state matching the provided transition.&lt;br /&gt;
&lt;br /&gt;
=== getPlayers() ===&lt;br /&gt;
&lt;br /&gt;
Returns an array of players with the players information.&lt;br /&gt;
&lt;br /&gt;
=== endGame() ===&lt;br /&gt;
&lt;br /&gt;
When the end game condition is met, you can use this function to end the game (after setting the appropriate scores!)&lt;br /&gt;
&lt;br /&gt;
== Other functions ==&lt;br /&gt;
&lt;br /&gt;
=== pause( milliseconds ) ===&lt;br /&gt;
&lt;br /&gt;
Pause the client interface during a specified number of milliseconds.&lt;br /&gt;
&lt;br /&gt;
If you do not use bga.pause, all Sandbox game actions are executed immediately and synchronously.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.log( &amp;quot;1&amp;quot; );    // Will be displayed immediately on the log&lt;br /&gt;
  bga.pause( 3000 ); // pause during 3 seconds&lt;br /&gt;
  bga.log( &amp;quot;2&amp;quot; );    // Will be displayed after the 3 second on the log&lt;br /&gt;
  bga.log( &amp;quot;3&amp;quot; );    // Will be displayed right after the previous one, without delay.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Tips : if you want to execute several consecutive &amp;quot;moveTo&amp;quot;, you should &amp;quot;bga.pause&amp;quot; between them, otherwise your element will move directly to the final destination.&lt;br /&gt;
&lt;br /&gt;
=== hasTag( id, tag ) ===&lt;br /&gt;
&lt;br /&gt;
Returns true if the element with this id has this tag.&lt;br /&gt;
&lt;br /&gt;
=== addTag( id, tag ) ===&lt;br /&gt;
&lt;br /&gt;
Adds this tag to the element with this id.&lt;br /&gt;
&lt;br /&gt;
=== removeTag( id, tag ) ===&lt;br /&gt;
&lt;br /&gt;
Removes this tag from the element with this id.&lt;br /&gt;
&lt;br /&gt;
=== addStyle( id, style ) ===&lt;br /&gt;
&lt;br /&gt;
Adds this style to the element with this id.&lt;br /&gt;
&lt;br /&gt;
Predefined styles are: SELECTED / LIGHT / LIGHTBACKGROUND / REDSELECTED / CLICKABLE / ROUNDED / CLICKABLE_ROUNDED&lt;br /&gt;
&lt;br /&gt;
=== removeStyle( id, style ) ===&lt;br /&gt;
&lt;br /&gt;
Removes this style from the element with this id.&lt;br /&gt;
&lt;br /&gt;
=== setProperties( props ) ===&lt;br /&gt;
&lt;br /&gt;
This function allows to directly update properties of an object, and to manage custom properties if needed (custom properties must start with prefix &amp;quot;c_&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
    // Update player labels for player zones from &amp;quot;&amp;lt;color&amp;gt; player&amp;quot; to actual player name&lt;br /&gt;
    var players = bga.getPlayers();&lt;br /&gt;
    for (var color in players) {&lt;br /&gt;
        player = players[color];&lt;br /&gt;
        &lt;br /&gt;
        var labelId = null;&lt;br /&gt;
        if (color == &#039;ff0000&#039;) labelId = bga.getElement( {name: &#039;Red player&#039;} );&lt;br /&gt;
        if (color == &#039;008000&#039;) labelId = bga.getElement( {name: &#039;Green player&#039;} );&lt;br /&gt;
        if (color == &#039;0000ff&#039;) labelId = bga.getElement( {name: &#039;Blue player&#039;} );&lt;br /&gt;
        if (color == &#039;ffa500&#039;) labelId = bga.getElement( {name: &#039;Yellow player&#039;} );&lt;br /&gt;
        &lt;br /&gt;
        var props = [];&lt;br /&gt;
        props[labelId] = {name: player.name};&lt;br /&gt;
        bga.setProperties( props );&lt;br /&gt;
    }&lt;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://sr.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=3045</id>
		<title>SandboxScripts</title>
		<link rel="alternate" type="text/html" href="https://sr.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=3045"/>
		<updated>2018-05-17T16:08:08Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Other functions */ tag &amp;amp; styles&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This is the reference of functions you can call from your Sandbox scripts.&lt;br /&gt;
&lt;br /&gt;
= Javascript =&lt;br /&gt;
&lt;br /&gt;
BGA Sandbox scripts are written in Javascript.&lt;br /&gt;
&lt;br /&gt;
Using Javascript, you can write scripts to automate moves for your Sandbox games &amp;amp; provide rules reinforcement.&lt;br /&gt;
&lt;br /&gt;
Important : in the opposite of the most common usage of Javascript, Sandbox scripts are executed &#039;&#039;&#039;on server side&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
= BGA API =&lt;br /&gt;
&lt;br /&gt;
To interact with your BGA Sandbox game, we provide you an API.&lt;br /&gt;
&lt;br /&gt;
With this API, you can get properties values of game elements from the current game situation, modify them and/or trigger the game actions (ex : move this element here, flip this card, and so on).&lt;br /&gt;
&lt;br /&gt;
= Quick start =&lt;br /&gt;
&lt;br /&gt;
== Hello World Script ==&lt;br /&gt;
&lt;br /&gt;
From Sandbox editor &amp;quot;interface view&amp;quot; tab, select an element, and access to its property (top right icon).&lt;br /&gt;
&lt;br /&gt;
Go to &amp;quot;Scripts (advanced)&amp;quot; section.&lt;br /&gt;
&lt;br /&gt;
In front of &amp;quot;When this element is clicked&amp;quot;, enter &amp;quot;onMyClick&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Close the window. Go to &amp;quot;script view&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Enter the following :&lt;br /&gt;
&lt;br /&gt;
 function onMyClick( element_id )&lt;br /&gt;
 {&lt;br /&gt;
    bga.log(&amp;quot;Hello world! You just clicked on element &amp;quot; + element_id + &amp;quot;. Congrats!&amp;quot;);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Save &amp;amp; publish your project, starts a test session, click on the previous element : your message appears in the log on the right!&lt;br /&gt;
&lt;br /&gt;
== Top useful tips ==&lt;br /&gt;
&lt;br /&gt;
* You don&#039;t have to save&amp;amp;publish from the Sandbox editor for each modification of your script : each time you save your script (control+S), the script used for all test sessions is updated. Note that the production version on BGA is of course NOT updated until you explicitly save&amp;amp;publish again your project.&lt;br /&gt;
&lt;br /&gt;
* To inspect the content of a variable, you can use bga.log() in combination with JSON.stringify(). For example :&lt;br /&gt;
&lt;br /&gt;
  bga.log( JSON.stringify( bga.getPlayers()) );&lt;br /&gt;
&lt;br /&gt;
* Alternatively to bga.log(), you can use bga.exit( &amp;quot;my message&amp;quot; ) to debug your script. With bga.exit, the script execution immediately stops and all previous game changes are cancelled, so this is very practical to try and retry an action until your script is fine.&lt;br /&gt;
&lt;br /&gt;
* We advise you to develop first a full playable version of the game without the scripts, and THEN to script it.&lt;br /&gt;
&lt;br /&gt;
* On Board Game Arena, players have come to expect fully implemented games with all rules enforced. So even if it&#039;s technically possible not to script the full game and to implement the game only partially, in most cases we&#039;ll publish only fully scripted games :)&lt;br /&gt;
&lt;br /&gt;
= Functions you can use in your Sandbox scripts=&lt;br /&gt;
&lt;br /&gt;
== Debugging functions ==&lt;br /&gt;
&lt;br /&gt;
=== bga.trace( txt / obj ) ===&lt;br /&gt;
&lt;br /&gt;
Write something immediately in the BGA log (on the right of the screen).&lt;br /&gt;
&lt;br /&gt;
This is the most practical way to debug your script :)&lt;br /&gt;
&lt;br /&gt;
Important : bga.trace is for debugging purpose only and won&#039;t be displayed on production.&lt;br /&gt;
&lt;br /&gt;
Note : you can also pass an object in parameter. This will dump the content of this object in the log.&lt;br /&gt;
&lt;br /&gt;
Note : in the opposite of bga.log, bga.trace is NOT cancelled if the game action failed (after a call to bga.cancel or bga.error). This makes bga.trace very practical to debug a game action that failed, and for this reason you should probably NEVER use bga.log for debugging purpose.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  // Example : write &amp;quot;Hello world&amp;quot; in the log&lt;br /&gt;
  bga.trace( &amp;quot;Hello world&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Example : dump an associative array in the log&lt;br /&gt;
  bga.trace( { mykey: &#039;myvalue&#039;, another_key: &#039;another_value&#039; } );&lt;br /&gt;
&lt;br /&gt;
=== bga.exit( txt / obj ) ===&lt;br /&gt;
&lt;br /&gt;
Stop the script immediately, display the &amp;quot;txt&amp;quot; messages and cancel (ie : rollback) on every previous API call except bga.trace :&lt;br /&gt;
&lt;br /&gt;
ALL previous BGA api call are canceled and there will be no visible changes on the interface (ex : no moves, no visible property changes, ...). Only &amp;quot;bga.trace&amp;quot; API commands are kept so you can debug.&lt;br /&gt;
&lt;br /&gt;
bga.exit is very practical when you want to repeat a game action again and again to debug it : with a call to bga.exit at the end of your script, you make sure that your game situation will be kept unchanged after each test.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.exit( &amp;quot;My script is stopped by this call&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Example with dumping a javascript variable&lt;br /&gt;
  bga.exit( my_variable_to_dump );&lt;br /&gt;
&lt;br /&gt;
== Cancelling a game action ==&lt;br /&gt;
&lt;br /&gt;
=== bga.cancel( txt ) ===&lt;br /&gt;
&lt;br /&gt;
This is the function to use when a player is doing something against game rules.&lt;br /&gt;
&lt;br /&gt;
The text message in parameter will be displayed to this player as a &amp;quot;red message&amp;quot;, so he/she can understand the rule.&lt;br /&gt;
&lt;br /&gt;
All previous BGA api call are cancelled, and there will be no visible changes on the interface.&lt;br /&gt;
&lt;br /&gt;
   // Example :&lt;br /&gt;
   bga.cancel( _(&amp;quot;You cannot move this piece here&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
Note : most of the time, you should wrap your text inside a _() translation marker to make this string translatable.&lt;br /&gt;
&lt;br /&gt;
=== bga.error( text ) ===&lt;br /&gt;
&lt;br /&gt;
This is the function to use when some unexpected error happens in your script.&lt;br /&gt;
&lt;br /&gt;
The text message will be displayed to user, with mention &amp;quot;Unexpected error&amp;quot;. The player will be incited to fill a bug report. The purpose of the message is to help you to identify the bug.&lt;br /&gt;
&lt;br /&gt;
All previous BGA api call are cancelled, and there will be no visible changes on the interface.&lt;br /&gt;
&lt;br /&gt;
   // Example :&lt;br /&gt;
   if( card_picked === null )&lt;br /&gt;
   {&lt;br /&gt;
       bga.error( &amp;quot;Cannot find a card to pick !&amp;quot; );&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
Note : you should NEVER wrap text inside bga.error with _() translation marker, because unexpected error should not be translate (so you can eventually recognize them when reported by players in bug report).&lt;br /&gt;
&lt;br /&gt;
== Game log (history) ==&lt;br /&gt;
&lt;br /&gt;
=== bga.log( txt, (optional) args ) ===&lt;br /&gt;
&lt;br /&gt;
Write something in the BGA log on the right.&lt;br /&gt;
&lt;br /&gt;
  // Example : simple log&lt;br /&gt;
  bga.log( _(&amp;quot;A new round starts&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
You may add arguments to your log, like this :&lt;br /&gt;
&lt;br /&gt;
  // Example: log with argument to display a card name.&lt;br /&gt;
  //          In this example, variable &amp;quot;event_name&amp;quot; is specified afterwards.&lt;br /&gt;
  //          Note that using this, game translators only have to translate one &amp;quot;Event XXX is triggered&amp;quot; string for all possible events.&lt;br /&gt;
  bga.log( _(&amp;quot;Event ${event_name} is triggered&amp;quot;), {  event_name: _( &amp;quot;Armageddon&amp;quot; ) } ) );&lt;br /&gt;
&lt;br /&gt;
Note that argument &amp;quot;player_name&amp;quot; is ALWAYS pre-set with the name of the current player, so you can use it immediately.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.log( _(&amp;quot;${player_name} draw a card from the deck&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
=== bga.speechBubble( target, text, (optional) args, (optional) delay, (optional) duration, (optional) size ) ===&lt;br /&gt;
&lt;br /&gt;
Display a &amp;quot;speech bubble&amp;quot;, attached to the specified target, containing the specified text.&lt;br /&gt;
&lt;br /&gt;
You can use &amp;quot;args&amp;quot; to customize text exactly like with bga.log.&lt;br /&gt;
&lt;br /&gt;
delay : milliseconds to wait before displaying the speech bubble (default : 0).&lt;br /&gt;
duration : how long to show the speech bubble in milliseconds (default : 3000).&lt;br /&gt;
size : size of the text in percent (default: 100)&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.speechBubble( _(&amp;quot;I play ${nbr} cards&amp;quot;), { nbr : 4 }, 0 );&lt;br /&gt;
  bga.speechBubble( _(&amp;quot;Good for you!&amp;quot;), { }, 2000 );&lt;br /&gt;
&lt;br /&gt;
=== bga.displayScoring( target, color, score ) ===&lt;br /&gt;
&lt;br /&gt;
Display an animated temporary &amp;quot;score number&amp;quot;, attached to the specified target.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;color&amp;quot; should be the color of the player who is scoring for that target.&lt;br /&gt;
&lt;br /&gt;
== Get / search game elements and their properties ==&lt;br /&gt;
&lt;br /&gt;
=== bga.getElement( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Allow you to retrieve informations about one game element specified using &amp;quot;selector&amp;quot; argument.&lt;br /&gt;
&lt;br /&gt;
Return null if no element is found.&lt;br /&gt;
&lt;br /&gt;
Note : getElement throw an error if several elements matches the selector. If you want to retrieve several elements, you should use &amp;quot;getElements&amp;quot; instead of &amp;quot;getElement&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The following examples are showing all the possible use of bga.getElement :&lt;br /&gt;
&lt;br /&gt;
  // Basic example :&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve the ID of a game element using its name (&amp;quot;Deck&amp;quot;)&lt;br /&gt;
  var deck_id = bga.getElement( { name: &amp;quot;Deck&amp;quot; } );&lt;br /&gt;
  // Return : 1234  &lt;br /&gt;
&lt;br /&gt;
  // Examples using &amp;quot;field&amp;quot; parameter :&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve a specific property from a game element using its name (&amp;quot;Deck&amp;quot;)&lt;br /&gt;
  var deck_id = bga.getElement( { name: &amp;quot;Deck&amp;quot; }, &#039;x&#039; );&lt;br /&gt;
  // Return : 20&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve several properties from the previous element&lt;br /&gt;
  var deck_properties = bga.getElement( { name: &amp;quot;Deck&amp;quot; }, [&#039;name&#039;,&#039;id&#039;,&#039;parent&#039;, &#039;x&#039;,&#039;y&#039;,&#039;canShuffle&#039;] );&lt;br /&gt;
  // Return : { name:&#039;Deck&#039;, id:1234, parent:4321, x: 20, y:50, canShuffle: true }&lt;br /&gt;
  &lt;br /&gt;
  // Note : as you can see, getElement returns:&lt;br /&gt;
  //        _ the element ID by default, or&lt;br /&gt;
  //        _ a single value if you request a single field, or&lt;br /&gt;
  //        _ an object if you request several fields&lt;br /&gt;
&lt;br /&gt;
  // Examples using different &amp;quot;selector&amp;quot; paramter&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve an element name from its id&lt;br /&gt;
  var deck_name = bga.getElement( { id: 1234 }, [&#039;name&#039;] );&lt;br /&gt;
  // Return : &amp;quot;Deck&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  // Retrieve the last child element of another element&lt;br /&gt;
  // Here, we are requesting for elements who has element with ID=1234 (Deck) as their parent&lt;br /&gt;
  // Note the use of &amp;quot;limit:1&amp;quot; which allows us to retrieve only 1 element.&lt;br /&gt;
  var first_card_on_deck_id = bga.getElement( { parent: 1234, limit:1 } );&lt;br /&gt;
  &lt;br /&gt;
  // You can also get nested properties such as the ids of the child elements of one element, or a custom property placed on the parent element&lt;br /&gt;
  var totem_places = bga.getElements( {tag:&#039;TOTEMZONE&#039;}, [&#039;id&#039;,&#039;childs:id&#039;,&#039;childs:tags&#039;,&#039;parent:id&#039;,&#039;parent:c_value&#039;] );&lt;br /&gt;
&lt;br /&gt;
=== bga.getElements( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Returns an object holding the properties of the elements matching the selector.&lt;br /&gt;
&lt;br /&gt;
  // Basic example: unselect all selected elements&lt;br /&gt;
  bga.removeStyle( bga.getElements( {tag: &#039;sbstyle_selected&#039;}), &#039;selected&#039; );&lt;br /&gt;
&lt;br /&gt;
=== bga.getElementsArray( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Returns an array of all elements matching the selector, holding the required properties.&lt;br /&gt;
&lt;br /&gt;
  // Basic example: get id of selected element&lt;br /&gt;
  var selected_tokens = bga.getElementsArray( {tag: &#039;sbstyle_selected&#039; } );&lt;br /&gt;
  var token_id = null;&lt;br /&gt;
  if (selected_tokens.length &amp;gt; 0) {&lt;br /&gt;
      token_id = selected_tokens[0];&lt;br /&gt;
  }&lt;br /&gt;
  return token_id;&lt;br /&gt;
&lt;br /&gt;
  // Classic example: get array of elements and iterate over it&lt;br /&gt;
  var all_cells = bga.getElementsArray( {tag: &#039;CELL&#039;}, [&#039;id&#039;,&#039;name&#039;,&#039;tags&#039;] );&lt;br /&gt;
  for (var i=0; i&amp;lt;all_cells.length; i++) {&lt;br /&gt;
     // ... process each cell ...&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Utility methods ==&lt;br /&gt;
&lt;br /&gt;
=== bga.isOn( element_id, parent_id ) ===&lt;br /&gt;
&lt;br /&gt;
Return true if &amp;quot;element_id&amp;quot; is a descendant of &amp;quot;parent_id&amp;quot; (ie : if element_id game element has been placed on parent_id game element).&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  if( bga.isOn( bga.getElementIfByName( &#039;Turn counter&#039; ), bga.getElementIfByName( &#039;Turn 6&#039; ) )&lt;br /&gt;
  {&lt;br /&gt;
     // Trigger game end&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Trigger most common game actions ==&lt;br /&gt;
&lt;br /&gt;
=== moveTo( id, target, path ) ===&lt;br /&gt;
&lt;br /&gt;
Move element to specified target id (eventually following path defined by an array of element ids to pass over on the way)&lt;br /&gt;
&lt;br /&gt;
The exact destination of element depends on target&#039;s &amp;quot;howToArrange&amp;quot; property (&amp;quot;How elements are arranged on it?&amp;quot; : spreaded/deck/...).&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.moveTo( bga.getElementIdByName( &#039;Turn counter&#039; ), bga.getElementIdByName( &#039;Turn 3&#039; ) );&lt;br /&gt;
&lt;br /&gt;
=== incScore( color, value ) ===&lt;br /&gt;
&lt;br /&gt;
Increases the score for the player with the specified color, of the specified increment value.&lt;br /&gt;
&lt;br /&gt;
== Gamestate functions ==&lt;br /&gt;
&lt;br /&gt;
You can define your game flow with a list of states by adding a &amp;quot;states&amp;quot; function to your script.&lt;br /&gt;
&lt;br /&gt;
  function states()&lt;br /&gt;
  {&lt;br /&gt;
      return {&lt;br /&gt;
&lt;br /&gt;
        // Init game&lt;br /&gt;
        100: {&lt;br /&gt;
            onState: &#039;postSetup&#039;,&lt;br /&gt;
            transitions: { done:200 }&lt;br /&gt;
        },&lt;br /&gt;
        &lt;br /&gt;
        200: {&lt;br /&gt;
            description: _(&#039;${actplayer} must move a piece&#039;),&lt;br /&gt;
            descriptionmyturn: _(&#039;${you} must move a piece&#039;),&lt;br /&gt;
            possibleactions: [&#039;movePiece&#039;],&lt;br /&gt;
            transitions: { nextPlayer: 200 }&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
      };&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Then, you will be able to use the following functions to manage the game flow.&lt;br /&gt;
&lt;br /&gt;
=== checkAction( action ) ===&lt;br /&gt;
&lt;br /&gt;
=== isActionPossible( action ) ===&lt;br /&gt;
&lt;br /&gt;
=== getActivePlayerColor() ===&lt;br /&gt;
&lt;br /&gt;
=== nextState() ===&lt;br /&gt;
&lt;br /&gt;
=== nextPlayer() ===&lt;br /&gt;
&lt;br /&gt;
=== getPlayers() ===&lt;br /&gt;
&lt;br /&gt;
=== endGame() ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Other functions ==&lt;br /&gt;
&lt;br /&gt;
=== pause( milliseconds ) ===&lt;br /&gt;
&lt;br /&gt;
Pause the client interface during a specified number of milliseconds.&lt;br /&gt;
&lt;br /&gt;
If you do not use bga.pause, all Sandbox game actions are executed immediately and synchronously.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.log( &amp;quot;1&amp;quot; );    // Will be displayed immediately on the log&lt;br /&gt;
  bga.pause( 3000 ); // pause during 3 seconds&lt;br /&gt;
  bga.log( &amp;quot;2&amp;quot; );    // Will be displayed after the 3 second on the log&lt;br /&gt;
  bga.log( &amp;quot;3&amp;quot; );    // Will be displayed right after the previous one, without delay.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Tips : if you want to execute several consecutive &amp;quot;moveTo&amp;quot;, you should &amp;quot;bga.pause&amp;quot; between them, otherwise your element will move directly to the final destination.&lt;br /&gt;
&lt;br /&gt;
=== hasTag( id, tag ) ===&lt;br /&gt;
&lt;br /&gt;
Returns true if the element with this id has this tag.&lt;br /&gt;
&lt;br /&gt;
=== addTag( id, tag ) ===&lt;br /&gt;
&lt;br /&gt;
Adds this tag to the element with this id.&lt;br /&gt;
&lt;br /&gt;
=== removeTag( id, tag ) ===&lt;br /&gt;
&lt;br /&gt;
Removes this tag from the element with this id.&lt;br /&gt;
&lt;br /&gt;
=== addStyle( id, style ) ===&lt;br /&gt;
&lt;br /&gt;
Adds this style to the element with this id.&lt;br /&gt;
&lt;br /&gt;
Predefined styles are: SELECTED / LIGHT / LIGHTBACKGROUND / REDSELECTED / CLICKABLE / ROUNDED / CLICKABLE_ROUNDED&lt;br /&gt;
&lt;br /&gt;
=== removeStyle( id, style ) ===&lt;br /&gt;
&lt;br /&gt;
Removes this style from the element with this id.&lt;br /&gt;
&lt;br /&gt;
=== setProperties( props ) ===&lt;br /&gt;
&lt;br /&gt;
This function allows to directly update properties of an object, and to manage custom properties if needed (custom properties must start with prefix &amp;quot;c_&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
    // Update player labels for player zones from &amp;quot;&amp;lt;color&amp;gt; player&amp;quot; to actual player name&lt;br /&gt;
    var players = bga.getPlayers();&lt;br /&gt;
    for (var color in players) {&lt;br /&gt;
        player = players[color];&lt;br /&gt;
        &lt;br /&gt;
        var labelId = null;&lt;br /&gt;
        if (color == &#039;ff0000&#039;) labelId = bga.getElement( {name: &#039;Red player&#039;} );&lt;br /&gt;
        if (color == &#039;008000&#039;) labelId = bga.getElement( {name: &#039;Green player&#039;} );&lt;br /&gt;
        if (color == &#039;0000ff&#039;) labelId = bga.getElement( {name: &#039;Blue player&#039;} );&lt;br /&gt;
        if (color == &#039;ffa500&#039;) labelId = bga.getElement( {name: &#039;Yellow player&#039;} );&lt;br /&gt;
        &lt;br /&gt;
        var props = [];&lt;br /&gt;
        props[labelId] = {name: player.name};&lt;br /&gt;
        bga.setProperties( props );&lt;br /&gt;
    }&lt;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://sr.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=3044</id>
		<title>SandboxScripts</title>
		<link rel="alternate" type="text/html" href="https://sr.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=3044"/>
		<updated>2018-05-17T15:16:20Z</updated>

		<summary type="html">&lt;p&gt;Een: gamestate&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This is the reference of functions you can call from your Sandbox scripts.&lt;br /&gt;
&lt;br /&gt;
= Javascript =&lt;br /&gt;
&lt;br /&gt;
BGA Sandbox scripts are written in Javascript.&lt;br /&gt;
&lt;br /&gt;
Using Javascript, you can write scripts to automate moves for your Sandbox games &amp;amp; provide rules reinforcement.&lt;br /&gt;
&lt;br /&gt;
Important : in the opposite of the most common usage of Javascript, Sandbox scripts are executed &#039;&#039;&#039;on server side&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
= BGA API =&lt;br /&gt;
&lt;br /&gt;
To interact with your BGA Sandbox game, we provide you an API.&lt;br /&gt;
&lt;br /&gt;
With this API, you can get properties values of game elements from the current game situation, modify them and/or trigger the game actions (ex : move this element here, flip this card, and so on).&lt;br /&gt;
&lt;br /&gt;
= Quick start =&lt;br /&gt;
&lt;br /&gt;
== Hello World Script ==&lt;br /&gt;
&lt;br /&gt;
From Sandbox editor &amp;quot;interface view&amp;quot; tab, select an element, and access to its property (top right icon).&lt;br /&gt;
&lt;br /&gt;
Go to &amp;quot;Scripts (advanced)&amp;quot; section.&lt;br /&gt;
&lt;br /&gt;
In front of &amp;quot;When this element is clicked&amp;quot;, enter &amp;quot;onMyClick&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Close the window. Go to &amp;quot;script view&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Enter the following :&lt;br /&gt;
&lt;br /&gt;
 function onMyClick( element_id )&lt;br /&gt;
 {&lt;br /&gt;
    bga.log(&amp;quot;Hello world! You just clicked on element &amp;quot; + element_id + &amp;quot;. Congrats!&amp;quot;);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Save &amp;amp; publish your project, starts a test session, click on the previous element : your message appears in the log on the right!&lt;br /&gt;
&lt;br /&gt;
== Top useful tips ==&lt;br /&gt;
&lt;br /&gt;
* You don&#039;t have to save&amp;amp;publish from the Sandbox editor for each modification of your script : each time you save your script (control+S), the script used for all test sessions is updated. Note that the production version on BGA is of course NOT updated until you explicitly save&amp;amp;publish again your project.&lt;br /&gt;
&lt;br /&gt;
* To inspect the content of a variable, you can use bga.log() in combination with JSON.stringify(). For example :&lt;br /&gt;
&lt;br /&gt;
  bga.log( JSON.stringify( bga.getPlayers()) );&lt;br /&gt;
&lt;br /&gt;
* Alternatively to bga.log(), you can use bga.exit( &amp;quot;my message&amp;quot; ) to debug your script. With bga.exit, the script execution immediately stops and all previous game changes are cancelled, so this is very practical to try and retry an action until your script is fine.&lt;br /&gt;
&lt;br /&gt;
* We advise you to develop first a full playable version of the game without the scripts, and THEN to script it.&lt;br /&gt;
&lt;br /&gt;
* On Board Game Arena, players have come to expect fully implemented games with all rules enforced. So even if it&#039;s technically possible not to script the full game and to implement the game only partially, in most cases we&#039;ll publish only fully scripted games :)&lt;br /&gt;
&lt;br /&gt;
= Functions you can use in your Sandbox scripts=&lt;br /&gt;
&lt;br /&gt;
== Debugging functions ==&lt;br /&gt;
&lt;br /&gt;
=== bga.trace( txt / obj ) ===&lt;br /&gt;
&lt;br /&gt;
Write something immediately in the BGA log (on the right of the screen).&lt;br /&gt;
&lt;br /&gt;
This is the most practical way to debug your script :)&lt;br /&gt;
&lt;br /&gt;
Important : bga.trace is for debugging purpose only and won&#039;t be displayed on production.&lt;br /&gt;
&lt;br /&gt;
Note : you can also pass an object in parameter. This will dump the content of this object in the log.&lt;br /&gt;
&lt;br /&gt;
Note : in the opposite of bga.log, bga.trace is NOT cancelled if the game action failed (after a call to bga.cancel or bga.error). This makes bga.trace very practical to debug a game action that failed, and for this reason you should probably NEVER use bga.log for debugging purpose.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  // Example : write &amp;quot;Hello world&amp;quot; in the log&lt;br /&gt;
  bga.trace( &amp;quot;Hello world&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Example : dump an associative array in the log&lt;br /&gt;
  bga.trace( { mykey: &#039;myvalue&#039;, another_key: &#039;another_value&#039; } );&lt;br /&gt;
&lt;br /&gt;
=== bga.exit( txt / obj ) ===&lt;br /&gt;
&lt;br /&gt;
Stop the script immediately, display the &amp;quot;txt&amp;quot; messages and cancel (ie : rollback) on every previous API call except bga.trace :&lt;br /&gt;
&lt;br /&gt;
ALL previous BGA api call are canceled and there will be no visible changes on the interface (ex : no moves, no visible property changes, ...). Only &amp;quot;bga.trace&amp;quot; API commands are kept so you can debug.&lt;br /&gt;
&lt;br /&gt;
bga.exit is very practical when you want to repeat a game action again and again to debug it : with a call to bga.exit at the end of your script, you make sure that your game situation will be kept unchanged after each test.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.exit( &amp;quot;My script is stopped by this call&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Example with dumping a javascript variable&lt;br /&gt;
  bga.exit( my_variable_to_dump );&lt;br /&gt;
&lt;br /&gt;
== Cancelling a game action ==&lt;br /&gt;
&lt;br /&gt;
=== bga.cancel( txt ) ===&lt;br /&gt;
&lt;br /&gt;
This is the function to use when a player is doing something against game rules.&lt;br /&gt;
&lt;br /&gt;
The text message in parameter will be displayed to this player as a &amp;quot;red message&amp;quot;, so he/she can understand the rule.&lt;br /&gt;
&lt;br /&gt;
All previous BGA api call are cancelled, and there will be no visible changes on the interface.&lt;br /&gt;
&lt;br /&gt;
   // Example :&lt;br /&gt;
   bga.cancel( _(&amp;quot;You cannot move this piece here&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
Note : most of the time, you should wrap your text inside a _() translation marker to make this string translatable.&lt;br /&gt;
&lt;br /&gt;
=== bga.error( text ) ===&lt;br /&gt;
&lt;br /&gt;
This is the function to use when some unexpected error happens in your script.&lt;br /&gt;
&lt;br /&gt;
The text message will be displayed to user, with mention &amp;quot;Unexpected error&amp;quot;. The player will be incited to fill a bug report. The purpose of the message is to help you to identify the bug.&lt;br /&gt;
&lt;br /&gt;
All previous BGA api call are cancelled, and there will be no visible changes on the interface.&lt;br /&gt;
&lt;br /&gt;
   // Example :&lt;br /&gt;
   if( card_picked === null )&lt;br /&gt;
   {&lt;br /&gt;
       bga.error( &amp;quot;Cannot find a card to pick !&amp;quot; );&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
Note : you should NEVER wrap text inside bga.error with _() translation marker, because unexpected error should not be translate (so you can eventually recognize them when reported by players in bug report).&lt;br /&gt;
&lt;br /&gt;
== Game log (history) ==&lt;br /&gt;
&lt;br /&gt;
=== bga.log( txt, (optional) args ) ===&lt;br /&gt;
&lt;br /&gt;
Write something in the BGA log on the right.&lt;br /&gt;
&lt;br /&gt;
  // Example : simple log&lt;br /&gt;
  bga.log( _(&amp;quot;A new round starts&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
You may add arguments to your log, like this :&lt;br /&gt;
&lt;br /&gt;
  // Example: log with argument to display a card name.&lt;br /&gt;
  //          In this example, variable &amp;quot;event_name&amp;quot; is specified afterwards.&lt;br /&gt;
  //          Note that using this, game translators only have to translate one &amp;quot;Event XXX is triggered&amp;quot; string for all possible events.&lt;br /&gt;
  bga.log( _(&amp;quot;Event ${event_name} is triggered&amp;quot;), {  event_name: _( &amp;quot;Armageddon&amp;quot; ) } ) );&lt;br /&gt;
&lt;br /&gt;
Note that argument &amp;quot;player_name&amp;quot; is ALWAYS pre-set with the name of the current player, so you can use it immediately.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.log( _(&amp;quot;${player_name} draw a card from the deck&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
=== bga.speechBubble( target, text, (optional) args, (optional) delay, (optional) duration, (optional) size ) ===&lt;br /&gt;
&lt;br /&gt;
Display a &amp;quot;speech bubble&amp;quot;, attached to the specified target, containing the specified text.&lt;br /&gt;
&lt;br /&gt;
You can use &amp;quot;args&amp;quot; to customize text exactly like with bga.log.&lt;br /&gt;
&lt;br /&gt;
delay : milliseconds to wait before displaying the speech bubble (default : 0).&lt;br /&gt;
duration : how long to show the speech bubble in milliseconds (default : 3000).&lt;br /&gt;
size : size of the text in percent (default: 100)&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.speechBubble( _(&amp;quot;I play ${nbr} cards&amp;quot;), { nbr : 4 }, 0 );&lt;br /&gt;
  bga.speechBubble( _(&amp;quot;Good for you!&amp;quot;), { }, 2000 );&lt;br /&gt;
&lt;br /&gt;
=== bga.displayScoring( target, color, score ) ===&lt;br /&gt;
&lt;br /&gt;
Display an animated temporary &amp;quot;score number&amp;quot;, attached to the specified target.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;color&amp;quot; should be the color of the player who is scoring for that target.&lt;br /&gt;
&lt;br /&gt;
== Get / search game elements and their properties ==&lt;br /&gt;
&lt;br /&gt;
=== bga.getElement( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Allow you to retrieve informations about one game element specified using &amp;quot;selector&amp;quot; argument.&lt;br /&gt;
&lt;br /&gt;
Return null if no element is found.&lt;br /&gt;
&lt;br /&gt;
Note : getElement throw an error if several elements matches the selector. If you want to retrieve several elements, you should use &amp;quot;getElements&amp;quot; instead of &amp;quot;getElement&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The following examples are showing all the possible use of bga.getElement :&lt;br /&gt;
&lt;br /&gt;
  // Basic example :&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve the ID of a game element using its name (&amp;quot;Deck&amp;quot;)&lt;br /&gt;
  var deck_id = bga.getElement( { name: &amp;quot;Deck&amp;quot; } );&lt;br /&gt;
  // Return : 1234  &lt;br /&gt;
&lt;br /&gt;
  // Examples using &amp;quot;field&amp;quot; parameter :&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve a specific property from a game element using its name (&amp;quot;Deck&amp;quot;)&lt;br /&gt;
  var deck_id = bga.getElement( { name: &amp;quot;Deck&amp;quot; }, &#039;x&#039; );&lt;br /&gt;
  // Return : 20&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve several properties from the previous element&lt;br /&gt;
  var deck_properties = bga.getElement( { name: &amp;quot;Deck&amp;quot; }, [&#039;name&#039;,&#039;id&#039;,&#039;parent&#039;, &#039;x&#039;,&#039;y&#039;,&#039;canShuffle&#039;] );&lt;br /&gt;
  // Return : { name:&#039;Deck&#039;, id:1234, parent:4321, x: 20, y:50, canShuffle: true }&lt;br /&gt;
  &lt;br /&gt;
  // Note : as you can see, getElement returns:&lt;br /&gt;
  //        _ the element ID by default, or&lt;br /&gt;
  //        _ a single value if you request a single field, or&lt;br /&gt;
  //        _ an object if you request several fields&lt;br /&gt;
&lt;br /&gt;
  // Examples using different &amp;quot;selector&amp;quot; paramter&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve an element name from its id&lt;br /&gt;
  var deck_name = bga.getElement( { id: 1234 }, [&#039;name&#039;] );&lt;br /&gt;
  // Return : &amp;quot;Deck&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  // Retrieve the last child element of another element&lt;br /&gt;
  // Here, we are requesting for elements who has element with ID=1234 (Deck) as their parent&lt;br /&gt;
  // Note the use of &amp;quot;limit:1&amp;quot; which allows us to retrieve only 1 element.&lt;br /&gt;
  var first_card_on_deck_id = bga.getElement( { parent: 1234, limit:1 } );&lt;br /&gt;
  &lt;br /&gt;
  // You can also get nested properties such as the ids of the child elements of one element, or a custom property placed on the parent element&lt;br /&gt;
  var totem_places = bga.getElements( {tag:&#039;TOTEMZONE&#039;}, [&#039;id&#039;,&#039;childs:id&#039;,&#039;childs:tags&#039;,&#039;parent:id&#039;,&#039;parent:c_value&#039;] );&lt;br /&gt;
&lt;br /&gt;
=== bga.getElements( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Returns an object holding the properties of the elements matching the selector.&lt;br /&gt;
&lt;br /&gt;
  // Basic example: unselect all selected elements&lt;br /&gt;
  bga.removeStyle( bga.getElements( {tag: &#039;sbstyle_selected&#039;}), &#039;selected&#039; );&lt;br /&gt;
&lt;br /&gt;
=== bga.getElementsArray( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Returns an array of all elements matching the selector, holding the required properties.&lt;br /&gt;
&lt;br /&gt;
  // Basic example: get id of selected element&lt;br /&gt;
  var selected_tokens = bga.getElementsArray( {tag: &#039;sbstyle_selected&#039; } );&lt;br /&gt;
  var token_id = null;&lt;br /&gt;
  if (selected_tokens.length &amp;gt; 0) {&lt;br /&gt;
      token_id = selected_tokens[0];&lt;br /&gt;
  }&lt;br /&gt;
  return token_id;&lt;br /&gt;
&lt;br /&gt;
  // Classic example: get array of elements and iterate over it&lt;br /&gt;
  var all_cells = bga.getElementsArray( {tag: &#039;CELL&#039;}, [&#039;id&#039;,&#039;name&#039;,&#039;tags&#039;] );&lt;br /&gt;
  for (var i=0; i&amp;lt;all_cells.length; i++) {&lt;br /&gt;
     // ... process each cell ...&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Utility methods ==&lt;br /&gt;
&lt;br /&gt;
=== bga.isOn( element_id, parent_id ) ===&lt;br /&gt;
&lt;br /&gt;
Return true if &amp;quot;element_id&amp;quot; is a descendant of &amp;quot;parent_id&amp;quot; (ie : if element_id game element has been placed on parent_id game element).&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  if( bga.isOn( bga.getElementIfByName( &#039;Turn counter&#039; ), bga.getElementIfByName( &#039;Turn 6&#039; ) )&lt;br /&gt;
  {&lt;br /&gt;
     // Trigger game end&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Trigger most common game actions ==&lt;br /&gt;
&lt;br /&gt;
=== moveTo( id, target, path ) ===&lt;br /&gt;
&lt;br /&gt;
Move element to specified target id (eventually following path defined by an array of element ids to pass over on the way)&lt;br /&gt;
&lt;br /&gt;
The exact destination of element depends on target&#039;s &amp;quot;howToArrange&amp;quot; property (&amp;quot;How elements are arranged on it?&amp;quot; : spreaded/deck/...).&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.moveTo( bga.getElementIdByName( &#039;Turn counter&#039; ), bga.getElementIdByName( &#039;Turn 3&#039; ) );&lt;br /&gt;
&lt;br /&gt;
=== incScore( color, value ) ===&lt;br /&gt;
&lt;br /&gt;
Increases the score for the player with the specified color, of the specified increment value.&lt;br /&gt;
&lt;br /&gt;
== Gamestate functions ==&lt;br /&gt;
&lt;br /&gt;
You can define your game flow with a list of states by adding a &amp;quot;states&amp;quot; function to your script.&lt;br /&gt;
&lt;br /&gt;
  function states()&lt;br /&gt;
  {&lt;br /&gt;
      return {&lt;br /&gt;
&lt;br /&gt;
        // Init game&lt;br /&gt;
        100: {&lt;br /&gt;
            onState: &#039;postSetup&#039;,&lt;br /&gt;
            transitions: { done:200 }&lt;br /&gt;
        },&lt;br /&gt;
        &lt;br /&gt;
        200: {&lt;br /&gt;
            description: _(&#039;${actplayer} must move a piece&#039;),&lt;br /&gt;
            descriptionmyturn: _(&#039;${you} must move a piece&#039;),&lt;br /&gt;
            possibleactions: [&#039;movePiece&#039;],&lt;br /&gt;
            transitions: { nextPlayer: 200 }&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
      };&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
Then, you will be able to use the following functions to manage the game flow.&lt;br /&gt;
&lt;br /&gt;
=== checkAction( action ) ===&lt;br /&gt;
&lt;br /&gt;
=== isActionPossible( action ) ===&lt;br /&gt;
&lt;br /&gt;
=== getActivePlayerColor() ===&lt;br /&gt;
&lt;br /&gt;
=== nextState() ===&lt;br /&gt;
&lt;br /&gt;
=== nextPlayer() ===&lt;br /&gt;
&lt;br /&gt;
=== getPlayers() ===&lt;br /&gt;
&lt;br /&gt;
=== endGame() ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Other functions ==&lt;br /&gt;
&lt;br /&gt;
=== pause( milliseconds ) ===&lt;br /&gt;
&lt;br /&gt;
Pause the client interface during a specified number of milliseconds.&lt;br /&gt;
&lt;br /&gt;
If you do not use bga.pause, all Sandbox game actions are executed immediately and synchronously.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.log( &amp;quot;1&amp;quot; );    // Will be displayed immediately on the log&lt;br /&gt;
  bga.pause( 3000 ); // pause during 3 seconds&lt;br /&gt;
  bga.log( &amp;quot;2&amp;quot; );    // Will be displayed after the 3 second on the log&lt;br /&gt;
  bga.log( &amp;quot;3&amp;quot; );    // Will be displayed right after the previous one, without delay.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Tips : if you want to execute several consecutive &amp;quot;moveTo&amp;quot;, you should &amp;quot;bga.pause&amp;quot; between them, otherwise your element will move directly to the final destination.&lt;br /&gt;
&lt;br /&gt;
=== setProperties( props ) ===&lt;br /&gt;
&lt;br /&gt;
This function allows to directly update properties of an object, and to manage custom properties if needed (custom properties must start with prefix &amp;quot;c_&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
    // Update player labels for player zones from &amp;quot;&amp;lt;color&amp;gt; player&amp;quot; to actual player name&lt;br /&gt;
    var players = bga.getPlayers();&lt;br /&gt;
    for (var color in players) {&lt;br /&gt;
        player = players[color];&lt;br /&gt;
        &lt;br /&gt;
        var labelId = null;&lt;br /&gt;
        if (color == &#039;ff0000&#039;) labelId = bga.getElement( {name: &#039;Red player&#039;} );&lt;br /&gt;
        if (color == &#039;008000&#039;) labelId = bga.getElement( {name: &#039;Green player&#039;} );&lt;br /&gt;
        if (color == &#039;0000ff&#039;) labelId = bga.getElement( {name: &#039;Blue player&#039;} );&lt;br /&gt;
        if (color == &#039;ffa500&#039;) labelId = bga.getElement( {name: &#039;Yellow player&#039;} );&lt;br /&gt;
        &lt;br /&gt;
        var props = [];&lt;br /&gt;
        props[labelId] = {name: player.name};&lt;br /&gt;
        bga.setProperties( props );&lt;br /&gt;
    }&lt;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://sr.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=3043</id>
		<title>SandboxScripts</title>
		<link rel="alternate" type="text/html" href="https://sr.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=3043"/>
		<updated>2018-05-17T14:30:23Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Other functions */ setProperties&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This is the reference of functions you can call from your Sandbox scripts.&lt;br /&gt;
&lt;br /&gt;
= Javascript =&lt;br /&gt;
&lt;br /&gt;
BGA Sandbox scripts are written in Javascript.&lt;br /&gt;
&lt;br /&gt;
Using Javascript, you can write scripts to automate moves for your Sandbox games &amp;amp; provide rules reinforcement.&lt;br /&gt;
&lt;br /&gt;
Important : in the opposite of the most common usage of Javascript, Sandbox scripts are executed &#039;&#039;&#039;on server side&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
= BGA API =&lt;br /&gt;
&lt;br /&gt;
To interact with your BGA Sandbox game, we provide you an API.&lt;br /&gt;
&lt;br /&gt;
With this API, you can get properties values of game elements from the current game situation, modify them and/or trigger the game actions (ex : move this element here, flip this card, and so on).&lt;br /&gt;
&lt;br /&gt;
= Quick start =&lt;br /&gt;
&lt;br /&gt;
== Hello World Script ==&lt;br /&gt;
&lt;br /&gt;
From Sandbox editor &amp;quot;interface view&amp;quot; tab, select an element, and access to its property (top right icon).&lt;br /&gt;
&lt;br /&gt;
Go to &amp;quot;Scripts (advanced)&amp;quot; section.&lt;br /&gt;
&lt;br /&gt;
In front of &amp;quot;When this element is clicked&amp;quot;, enter &amp;quot;onMyClick&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Close the window. Go to &amp;quot;script view&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Enter the following :&lt;br /&gt;
&lt;br /&gt;
 function onMyClick( element_id )&lt;br /&gt;
 {&lt;br /&gt;
    bga.log(&amp;quot;Hello world! You just clicked on element &amp;quot; + element_id + &amp;quot;. Congrats!&amp;quot;);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Save &amp;amp; publish your project, starts a test session, click on the previous element : your message appears in the log on the right!&lt;br /&gt;
&lt;br /&gt;
== Top useful tips ==&lt;br /&gt;
&lt;br /&gt;
* You don&#039;t have to save&amp;amp;publish from the Sandbox editor for each modification of your script : each time you save your script (control+S), the script used for all test sessions is updated. Note that the production version on BGA is of course NOT updated until you explicitly save&amp;amp;publish again your project.&lt;br /&gt;
&lt;br /&gt;
* To inspect the content of a variable, you can use bga.log() in combination with JSON.stringify(). For example :&lt;br /&gt;
&lt;br /&gt;
  bga.log( JSON.stringify( bga.getPlayers()) );&lt;br /&gt;
&lt;br /&gt;
* Alternatively to bga.log(), you can use bga.exit( &amp;quot;my message&amp;quot; ) to debug your script. With bga.exit, the script execution immediately stops and all previous game changes are cancelled, so this is very practical to try and retry an action until your script is fine.&lt;br /&gt;
&lt;br /&gt;
* We advise you to develop first a full playable version of the game without the scripts, and THEN to script it.&lt;br /&gt;
&lt;br /&gt;
* On Board Game Arena, players have come to expect fully implemented games with all rules enforced. So even if it&#039;s technically possible not to script the full game and to implement the game only partially, in most cases we&#039;ll publish only fully scripted games :)&lt;br /&gt;
&lt;br /&gt;
= Functions you can use in your Sandbox scripts=&lt;br /&gt;
&lt;br /&gt;
== Debugging functions ==&lt;br /&gt;
&lt;br /&gt;
=== bga.trace( txt / obj ) ===&lt;br /&gt;
&lt;br /&gt;
Write something immediately in the BGA log (on the right of the screen).&lt;br /&gt;
&lt;br /&gt;
This is the most practical way to debug your script :)&lt;br /&gt;
&lt;br /&gt;
Important : bga.trace is for debugging purpose only and won&#039;t be displayed on production.&lt;br /&gt;
&lt;br /&gt;
Note : you can also pass an object in parameter. This will dump the content of this object in the log.&lt;br /&gt;
&lt;br /&gt;
Note : in the opposite of bga.log, bga.trace is NOT cancelled if the game action failed (after a call to bga.cancel or bga.error). This makes bga.trace very practical to debug a game action that failed, and for this reason you should probably NEVER use bga.log for debugging purpose.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  // Example : write &amp;quot;Hello world&amp;quot; in the log&lt;br /&gt;
  bga.trace( &amp;quot;Hello world&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Example : dump an associative array in the log&lt;br /&gt;
  bga.trace( { mykey: &#039;myvalue&#039;, another_key: &#039;another_value&#039; } );&lt;br /&gt;
&lt;br /&gt;
=== bga.exit( txt / obj ) ===&lt;br /&gt;
&lt;br /&gt;
Stop the script immediately, display the &amp;quot;txt&amp;quot; messages and cancel (ie : rollback) on every previous API call except bga.trace :&lt;br /&gt;
&lt;br /&gt;
ALL previous BGA api call are canceled and there will be no visible changes on the interface (ex : no moves, no visible property changes, ...). Only &amp;quot;bga.trace&amp;quot; API commands are kept so you can debug.&lt;br /&gt;
&lt;br /&gt;
bga.exit is very practical when you want to repeat a game action again and again to debug it : with a call to bga.exit at the end of your script, you make sure that your game situation will be kept unchanged after each test.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.exit( &amp;quot;My script is stopped by this call&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Example with dumping a javascript variable&lt;br /&gt;
  bga.exit( my_variable_to_dump );&lt;br /&gt;
&lt;br /&gt;
== Cancelling a game action ==&lt;br /&gt;
&lt;br /&gt;
=== bga.cancel( txt ) ===&lt;br /&gt;
&lt;br /&gt;
This is the function to use when a player is doing something against game rules.&lt;br /&gt;
&lt;br /&gt;
The text message in parameter will be displayed to this player as a &amp;quot;red message&amp;quot;, so he/she can understand the rule.&lt;br /&gt;
&lt;br /&gt;
All previous BGA api call are cancelled, and there will be no visible changes on the interface.&lt;br /&gt;
&lt;br /&gt;
   // Example :&lt;br /&gt;
   bga.cancel( _(&amp;quot;You cannot move this piece here&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
Note : most of the time, you should wrap your text inside a _() translation marker to make this string translatable.&lt;br /&gt;
&lt;br /&gt;
=== bga.error( text ) ===&lt;br /&gt;
&lt;br /&gt;
This is the function to use when some unexpected error happens in your script.&lt;br /&gt;
&lt;br /&gt;
The text message will be displayed to user, with mention &amp;quot;Unexpected error&amp;quot;. The player will be incited to fill a bug report. The purpose of the message is to help you to identify the bug.&lt;br /&gt;
&lt;br /&gt;
All previous BGA api call are cancelled, and there will be no visible changes on the interface.&lt;br /&gt;
&lt;br /&gt;
   // Example :&lt;br /&gt;
   if( card_picked === null )&lt;br /&gt;
   {&lt;br /&gt;
       bga.error( &amp;quot;Cannot find a card to pick !&amp;quot; );&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
Note : you should NEVER wrap text inside bga.error with _() translation marker, because unexpected error should not be translate (so you can eventually recognize them when reported by players in bug report).&lt;br /&gt;
&lt;br /&gt;
== Game log (history) ==&lt;br /&gt;
&lt;br /&gt;
=== bga.log( txt, (optional) args ) ===&lt;br /&gt;
&lt;br /&gt;
Write something in the BGA log on the right.&lt;br /&gt;
&lt;br /&gt;
  // Example : simple log&lt;br /&gt;
  bga.log( _(&amp;quot;A new round starts&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
You may add arguments to your log, like this :&lt;br /&gt;
&lt;br /&gt;
  // Example: log with argument to display a card name.&lt;br /&gt;
  //          In this example, variable &amp;quot;event_name&amp;quot; is specified afterwards.&lt;br /&gt;
  //          Note that using this, game translators only have to translate one &amp;quot;Event XXX is triggered&amp;quot; string for all possible events.&lt;br /&gt;
  bga.log( _(&amp;quot;Event ${event_name} is triggered&amp;quot;), {  event_name: _( &amp;quot;Armageddon&amp;quot; ) } ) );&lt;br /&gt;
&lt;br /&gt;
Note that argument &amp;quot;player_name&amp;quot; is ALWAYS pre-set with the name of the current player, so you can use it immediately.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.log( _(&amp;quot;${player_name} draw a card from the deck&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
=== bga.speechBubble( target, text, (optional) args, (optional) delay, (optional) duration, (optional) size ) ===&lt;br /&gt;
&lt;br /&gt;
Display a &amp;quot;speech bubble&amp;quot;, attached to the specified target, containing the specified text.&lt;br /&gt;
&lt;br /&gt;
You can use &amp;quot;args&amp;quot; to customize text exactly like with bga.log.&lt;br /&gt;
&lt;br /&gt;
delay : milliseconds to wait before displaying the speech bubble (default : 0).&lt;br /&gt;
duration : how long to show the speech bubble in milliseconds (default : 3000).&lt;br /&gt;
size : size of the text in percent (default: 100)&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.speechBubble( _(&amp;quot;I play ${nbr} cards&amp;quot;), { nbr : 4 }, 0 );&lt;br /&gt;
  bga.speechBubble( _(&amp;quot;Good for you!&amp;quot;), { }, 2000 );&lt;br /&gt;
&lt;br /&gt;
=== bga.displayScoring( target, color, score ) ===&lt;br /&gt;
&lt;br /&gt;
Display an animated temporary &amp;quot;score number&amp;quot;, attached to the specified target.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;color&amp;quot; should be the color of the player who is scoring for that target.&lt;br /&gt;
&lt;br /&gt;
== Get / search game elements and their properties ==&lt;br /&gt;
&lt;br /&gt;
=== bga.getElement( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Allow you to retrieve informations about one game element specified using &amp;quot;selector&amp;quot; argument.&lt;br /&gt;
&lt;br /&gt;
Return null if no element is found.&lt;br /&gt;
&lt;br /&gt;
Note : getElement throw an error if several elements matches the selector. If you want to retrieve several elements, you should use &amp;quot;getElements&amp;quot; instead of &amp;quot;getElement&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The following examples are showing all the possible use of bga.getElement :&lt;br /&gt;
&lt;br /&gt;
  // Basic example :&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve the ID of a game element using its name (&amp;quot;Deck&amp;quot;)&lt;br /&gt;
  var deck_id = bga.getElement( { name: &amp;quot;Deck&amp;quot; } );&lt;br /&gt;
  // Return : 1234  &lt;br /&gt;
&lt;br /&gt;
  // Examples using &amp;quot;field&amp;quot; parameter :&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve a specific property from a game element using its name (&amp;quot;Deck&amp;quot;)&lt;br /&gt;
  var deck_id = bga.getElement( { name: &amp;quot;Deck&amp;quot; }, &#039;x&#039; );&lt;br /&gt;
  // Return : 20&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve several properties from the previous element&lt;br /&gt;
  var deck_properties = bga.getElement( { name: &amp;quot;Deck&amp;quot; }, [&#039;name&#039;,&#039;id&#039;,&#039;parent&#039;, &#039;x&#039;,&#039;y&#039;,&#039;canShuffle&#039;] );&lt;br /&gt;
  // Return : { name:&#039;Deck&#039;, id:1234, parent:4321, x: 20, y:50, canShuffle: true }&lt;br /&gt;
  &lt;br /&gt;
  // Note : as you can see, getElement returns:&lt;br /&gt;
  //        _ the element ID by default, or&lt;br /&gt;
  //        _ a single value if you request a single field, or&lt;br /&gt;
  //        _ an object if you request several fields&lt;br /&gt;
&lt;br /&gt;
  // Examples using different &amp;quot;selector&amp;quot; paramter&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve an element name from its id&lt;br /&gt;
  var deck_name = bga.getElement( { id: 1234 }, [&#039;name&#039;] );&lt;br /&gt;
  // Return : &amp;quot;Deck&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  // Retrieve the last child element of another element&lt;br /&gt;
  // Here, we are requesting for elements who has element with ID=1234 (Deck) as their parent&lt;br /&gt;
  // Note the use of &amp;quot;limit:1&amp;quot; which allows us to retrieve only 1 element.&lt;br /&gt;
  var first_card_on_deck_id = bga.getElement( { parent: 1234, limit:1 } );&lt;br /&gt;
  &lt;br /&gt;
  // You can also get nested properties such as the ids of the child elements of one element, or a custom property placed on the parent element&lt;br /&gt;
  var totem_places = bga.getElements( {tag:&#039;TOTEMZONE&#039;}, [&#039;id&#039;,&#039;childs:id&#039;,&#039;childs:tags&#039;,&#039;parent:id&#039;,&#039;parent:c_value&#039;] );&lt;br /&gt;
&lt;br /&gt;
=== bga.getElements( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Returns an object holding the properties of the elements matching the selector.&lt;br /&gt;
&lt;br /&gt;
  // Basic example: unselect all selected elements&lt;br /&gt;
  bga.removeStyle( bga.getElements( {tag: &#039;sbstyle_selected&#039;}), &#039;selected&#039; );&lt;br /&gt;
&lt;br /&gt;
=== bga.getElementsArray( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Returns an array of all elements matching the selector, holding the required properties.&lt;br /&gt;
&lt;br /&gt;
  // Basic example: get id of selected element&lt;br /&gt;
  var selected_tokens = bga.getElementsArray( {tag: &#039;sbstyle_selected&#039; } );&lt;br /&gt;
  var token_id = null;&lt;br /&gt;
  if (selected_tokens.length &amp;gt; 0) {&lt;br /&gt;
      token_id = selected_tokens[0];&lt;br /&gt;
  }&lt;br /&gt;
  return token_id;&lt;br /&gt;
&lt;br /&gt;
  // Classic example: get array of elements and iterate over it&lt;br /&gt;
  var all_cells = bga.getElementsArray( {tag: &#039;CELL&#039;}, [&#039;id&#039;,&#039;name&#039;,&#039;tags&#039;] );&lt;br /&gt;
  for (var i=0; i&amp;lt;all_cells.length; i++) {&lt;br /&gt;
     // ... process each cell ...&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Utility methods ==&lt;br /&gt;
&lt;br /&gt;
=== bga.isOn( element_id, parent_id ) ===&lt;br /&gt;
&lt;br /&gt;
Return true if &amp;quot;element_id&amp;quot; is a descendant of &amp;quot;parent_id&amp;quot; (ie : if element_id game element has been placed on parent_id game element).&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  if( bga.isOn( bga.getElementIfByName( &#039;Turn counter&#039; ), bga.getElementIfByName( &#039;Turn 6&#039; ) )&lt;br /&gt;
  {&lt;br /&gt;
     // Trigger game end&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Trigger most common game actions ==&lt;br /&gt;
&lt;br /&gt;
=== moveTo( id, target, path ) ===&lt;br /&gt;
&lt;br /&gt;
Move element to specified target id (eventually following path defined by an array of element ids to pass over on the way)&lt;br /&gt;
&lt;br /&gt;
The exact destination of element depends on target&#039;s &amp;quot;howToArrange&amp;quot; property (&amp;quot;How elements are arranged on it?&amp;quot; : spreaded/deck/...).&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.moveTo( bga.getElementIdByName( &#039;Turn counter&#039; ), bga.getElementIdByName( &#039;Turn 3&#039; ) );&lt;br /&gt;
&lt;br /&gt;
=== incScore( color, value ) ===&lt;br /&gt;
&lt;br /&gt;
Increases the score for the player with the specified color, of the specified increment value.&lt;br /&gt;
&lt;br /&gt;
== Other functions ==&lt;br /&gt;
&lt;br /&gt;
=== pause( milliseconds ) ===&lt;br /&gt;
&lt;br /&gt;
Pause the client interface during a specified number of milliseconds.&lt;br /&gt;
&lt;br /&gt;
If you do not use bga.pause, all Sandbox game actions are executed immediately and synchronously.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.log( &amp;quot;1&amp;quot; );    // Will be displayed immediately on the log&lt;br /&gt;
  bga.pause( 3000 ); // pause during 3 seconds&lt;br /&gt;
  bga.log( &amp;quot;2&amp;quot; );    // Will be displayed after the 3 second on the log&lt;br /&gt;
  bga.log( &amp;quot;3&amp;quot; );    // Will be displayed right after the previous one, without delay.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Tips : if you want to execute several consecutive &amp;quot;moveTo&amp;quot;, you should &amp;quot;bga.pause&amp;quot; between them, otherwise your element will move directly to the final destination.&lt;br /&gt;
&lt;br /&gt;
=== setProperties( props ) ===&lt;br /&gt;
&lt;br /&gt;
This function allows to directly update properties of an object, and to manage custom properties if needed (custom properties must start with prefix &amp;quot;c_&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
    // Update player labels for player zones from &amp;quot;&amp;lt;color&amp;gt; player&amp;quot; to actual player name&lt;br /&gt;
    var players = bga.getPlayers();&lt;br /&gt;
    for (var color in players) {&lt;br /&gt;
        player = players[color];&lt;br /&gt;
        &lt;br /&gt;
        var labelId = null;&lt;br /&gt;
        if (color == &#039;ff0000&#039;) labelId = bga.getElement( {name: &#039;Red player&#039;} );&lt;br /&gt;
        if (color == &#039;008000&#039;) labelId = bga.getElement( {name: &#039;Green player&#039;} );&lt;br /&gt;
        if (color == &#039;0000ff&#039;) labelId = bga.getElement( {name: &#039;Blue player&#039;} );&lt;br /&gt;
        if (color == &#039;ffa500&#039;) labelId = bga.getElement( {name: &#039;Yellow player&#039;} );&lt;br /&gt;
        &lt;br /&gt;
        var props = [];&lt;br /&gt;
        props[labelId] = {name: player.name};&lt;br /&gt;
        bga.setProperties( props );&lt;br /&gt;
    }&lt;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://sr.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=3042</id>
		<title>SandboxScripts</title>
		<link rel="alternate" type="text/html" href="https://sr.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=3042"/>
		<updated>2018-05-17T14:26:14Z</updated>

		<summary type="html">&lt;p&gt;Een: /* incScore( playerColor, incValue ) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This is the reference of functions you can call from your Sandbox scripts.&lt;br /&gt;
&lt;br /&gt;
= Javascript =&lt;br /&gt;
&lt;br /&gt;
BGA Sandbox scripts are written in Javascript.&lt;br /&gt;
&lt;br /&gt;
Using Javascript, you can write scripts to automate moves for your Sandbox games &amp;amp; provide rules reinforcement.&lt;br /&gt;
&lt;br /&gt;
Important : in the opposite of the most common usage of Javascript, Sandbox scripts are executed &#039;&#039;&#039;on server side&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
= BGA API =&lt;br /&gt;
&lt;br /&gt;
To interact with your BGA Sandbox game, we provide you an API.&lt;br /&gt;
&lt;br /&gt;
With this API, you can get properties values of game elements from the current game situation, modify them and/or trigger the game actions (ex : move this element here, flip this card, and so on).&lt;br /&gt;
&lt;br /&gt;
= Quick start =&lt;br /&gt;
&lt;br /&gt;
== Hello World Script ==&lt;br /&gt;
&lt;br /&gt;
From Sandbox editor &amp;quot;interface view&amp;quot; tab, select an element, and access to its property (top right icon).&lt;br /&gt;
&lt;br /&gt;
Go to &amp;quot;Scripts (advanced)&amp;quot; section.&lt;br /&gt;
&lt;br /&gt;
In front of &amp;quot;When this element is clicked&amp;quot;, enter &amp;quot;onMyClick&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Close the window. Go to &amp;quot;script view&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Enter the following :&lt;br /&gt;
&lt;br /&gt;
 function onMyClick( element_id )&lt;br /&gt;
 {&lt;br /&gt;
    bga.log(&amp;quot;Hello world! You just clicked on element &amp;quot; + element_id + &amp;quot;. Congrats!&amp;quot;);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Save &amp;amp; publish your project, starts a test session, click on the previous element : your message appears in the log on the right!&lt;br /&gt;
&lt;br /&gt;
== Top useful tips ==&lt;br /&gt;
&lt;br /&gt;
* You don&#039;t have to save&amp;amp;publish from the Sandbox editor for each modification of your script : each time you save your script (control+S), the script used for all test sessions is updated. Note that the production version on BGA is of course NOT updated until you explicitly save&amp;amp;publish again your project.&lt;br /&gt;
&lt;br /&gt;
* To inspect the content of a variable, you can use bga.log() in combination with JSON.stringify(). For example :&lt;br /&gt;
&lt;br /&gt;
  bga.log( JSON.stringify( bga.getPlayers()) );&lt;br /&gt;
&lt;br /&gt;
* Alternatively to bga.log(), you can use bga.exit( &amp;quot;my message&amp;quot; ) to debug your script. With bga.exit, the script execution immediately stops and all previous game changes are cancelled, so this is very practical to try and retry an action until your script is fine.&lt;br /&gt;
&lt;br /&gt;
* We advise you to develop first a full playable version of the game without the scripts, and THEN to script it.&lt;br /&gt;
&lt;br /&gt;
* On Board Game Arena, players have come to expect fully implemented games with all rules enforced. So even if it&#039;s technically possible not to script the full game and to implement the game only partially, in most cases we&#039;ll publish only fully scripted games :)&lt;br /&gt;
&lt;br /&gt;
= Functions you can use in your Sandbox scripts=&lt;br /&gt;
&lt;br /&gt;
== Debugging functions ==&lt;br /&gt;
&lt;br /&gt;
=== bga.trace( txt / obj ) ===&lt;br /&gt;
&lt;br /&gt;
Write something immediately in the BGA log (on the right of the screen).&lt;br /&gt;
&lt;br /&gt;
This is the most practical way to debug your script :)&lt;br /&gt;
&lt;br /&gt;
Important : bga.trace is for debugging purpose only and won&#039;t be displayed on production.&lt;br /&gt;
&lt;br /&gt;
Note : you can also pass an object in parameter. This will dump the content of this object in the log.&lt;br /&gt;
&lt;br /&gt;
Note : in the opposite of bga.log, bga.trace is NOT cancelled if the game action failed (after a call to bga.cancel or bga.error). This makes bga.trace very practical to debug a game action that failed, and for this reason you should probably NEVER use bga.log for debugging purpose.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  // Example : write &amp;quot;Hello world&amp;quot; in the log&lt;br /&gt;
  bga.trace( &amp;quot;Hello world&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Example : dump an associative array in the log&lt;br /&gt;
  bga.trace( { mykey: &#039;myvalue&#039;, another_key: &#039;another_value&#039; } );&lt;br /&gt;
&lt;br /&gt;
=== bga.exit( txt / obj ) ===&lt;br /&gt;
&lt;br /&gt;
Stop the script immediately, display the &amp;quot;txt&amp;quot; messages and cancel (ie : rollback) on every previous API call except bga.trace :&lt;br /&gt;
&lt;br /&gt;
ALL previous BGA api call are canceled and there will be no visible changes on the interface (ex : no moves, no visible property changes, ...). Only &amp;quot;bga.trace&amp;quot; API commands are kept so you can debug.&lt;br /&gt;
&lt;br /&gt;
bga.exit is very practical when you want to repeat a game action again and again to debug it : with a call to bga.exit at the end of your script, you make sure that your game situation will be kept unchanged after each test.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.exit( &amp;quot;My script is stopped by this call&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Example with dumping a javascript variable&lt;br /&gt;
  bga.exit( my_variable_to_dump );&lt;br /&gt;
&lt;br /&gt;
== Cancelling a game action ==&lt;br /&gt;
&lt;br /&gt;
=== bga.cancel( txt ) ===&lt;br /&gt;
&lt;br /&gt;
This is the function to use when a player is doing something against game rules.&lt;br /&gt;
&lt;br /&gt;
The text message in parameter will be displayed to this player as a &amp;quot;red message&amp;quot;, so he/she can understand the rule.&lt;br /&gt;
&lt;br /&gt;
All previous BGA api call are cancelled, and there will be no visible changes on the interface.&lt;br /&gt;
&lt;br /&gt;
   // Example :&lt;br /&gt;
   bga.cancel( _(&amp;quot;You cannot move this piece here&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
Note : most of the time, you should wrap your text inside a _() translation marker to make this string translatable.&lt;br /&gt;
&lt;br /&gt;
=== bga.error( text ) ===&lt;br /&gt;
&lt;br /&gt;
This is the function to use when some unexpected error happens in your script.&lt;br /&gt;
&lt;br /&gt;
The text message will be displayed to user, with mention &amp;quot;Unexpected error&amp;quot;. The player will be incited to fill a bug report. The purpose of the message is to help you to identify the bug.&lt;br /&gt;
&lt;br /&gt;
All previous BGA api call are cancelled, and there will be no visible changes on the interface.&lt;br /&gt;
&lt;br /&gt;
   // Example :&lt;br /&gt;
   if( card_picked === null )&lt;br /&gt;
   {&lt;br /&gt;
       bga.error( &amp;quot;Cannot find a card to pick !&amp;quot; );&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
Note : you should NEVER wrap text inside bga.error with _() translation marker, because unexpected error should not be translate (so you can eventually recognize them when reported by players in bug report).&lt;br /&gt;
&lt;br /&gt;
== Game log (history) ==&lt;br /&gt;
&lt;br /&gt;
=== bga.log( txt, (optional) args ) ===&lt;br /&gt;
&lt;br /&gt;
Write something in the BGA log on the right.&lt;br /&gt;
&lt;br /&gt;
  // Example : simple log&lt;br /&gt;
  bga.log( _(&amp;quot;A new round starts&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
You may add arguments to your log, like this :&lt;br /&gt;
&lt;br /&gt;
  // Example: log with argument to display a card name.&lt;br /&gt;
  //          In this example, variable &amp;quot;event_name&amp;quot; is specified afterwards.&lt;br /&gt;
  //          Note that using this, game translators only have to translate one &amp;quot;Event XXX is triggered&amp;quot; string for all possible events.&lt;br /&gt;
  bga.log( _(&amp;quot;Event ${event_name} is triggered&amp;quot;), {  event_name: _( &amp;quot;Armageddon&amp;quot; ) } ) );&lt;br /&gt;
&lt;br /&gt;
Note that argument &amp;quot;player_name&amp;quot; is ALWAYS pre-set with the name of the current player, so you can use it immediately.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.log( _(&amp;quot;${player_name} draw a card from the deck&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
=== bga.speechBubble( target, text, (optional) args, (optional) delay, (optional) duration, (optional) size ) ===&lt;br /&gt;
&lt;br /&gt;
Display a &amp;quot;speech bubble&amp;quot;, attached to the specified target, containing the specified text.&lt;br /&gt;
&lt;br /&gt;
You can use &amp;quot;args&amp;quot; to customize text exactly like with bga.log.&lt;br /&gt;
&lt;br /&gt;
delay : milliseconds to wait before displaying the speech bubble (default : 0).&lt;br /&gt;
duration : how long to show the speech bubble in milliseconds (default : 3000).&lt;br /&gt;
size : size of the text in percent (default: 100)&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.speechBubble( _(&amp;quot;I play ${nbr} cards&amp;quot;), { nbr : 4 }, 0 );&lt;br /&gt;
  bga.speechBubble( _(&amp;quot;Good for you!&amp;quot;), { }, 2000 );&lt;br /&gt;
&lt;br /&gt;
=== bga.displayScoring( target, color, score ) ===&lt;br /&gt;
&lt;br /&gt;
Display an animated temporary &amp;quot;score number&amp;quot;, attached to the specified target.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;color&amp;quot; should be the color of the player who is scoring for that target.&lt;br /&gt;
&lt;br /&gt;
== Get / search game elements and their properties ==&lt;br /&gt;
&lt;br /&gt;
=== bga.getElement( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Allow you to retrieve informations about one game element specified using &amp;quot;selector&amp;quot; argument.&lt;br /&gt;
&lt;br /&gt;
Return null if no element is found.&lt;br /&gt;
&lt;br /&gt;
Note : getElement throw an error if several elements matches the selector. If you want to retrieve several elements, you should use &amp;quot;getElements&amp;quot; instead of &amp;quot;getElement&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The following examples are showing all the possible use of bga.getElement :&lt;br /&gt;
&lt;br /&gt;
  // Basic example :&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve the ID of a game element using its name (&amp;quot;Deck&amp;quot;)&lt;br /&gt;
  var deck_id = bga.getElement( { name: &amp;quot;Deck&amp;quot; } );&lt;br /&gt;
  // Return : 1234  &lt;br /&gt;
&lt;br /&gt;
  // Examples using &amp;quot;field&amp;quot; parameter :&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve a specific property from a game element using its name (&amp;quot;Deck&amp;quot;)&lt;br /&gt;
  var deck_id = bga.getElement( { name: &amp;quot;Deck&amp;quot; }, &#039;x&#039; );&lt;br /&gt;
  // Return : 20&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve several properties from the previous element&lt;br /&gt;
  var deck_properties = bga.getElement( { name: &amp;quot;Deck&amp;quot; }, [&#039;name&#039;,&#039;id&#039;,&#039;parent&#039;, &#039;x&#039;,&#039;y&#039;,&#039;canShuffle&#039;] );&lt;br /&gt;
  // Return : { name:&#039;Deck&#039;, id:1234, parent:4321, x: 20, y:50, canShuffle: true }&lt;br /&gt;
  &lt;br /&gt;
  // Note : as you can see, getElement returns:&lt;br /&gt;
  //        _ the element ID by default, or&lt;br /&gt;
  //        _ a single value if you request a single field, or&lt;br /&gt;
  //        _ an object if you request several fields&lt;br /&gt;
&lt;br /&gt;
  // Examples using different &amp;quot;selector&amp;quot; paramter&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve an element name from its id&lt;br /&gt;
  var deck_name = bga.getElement( { id: 1234 }, [&#039;name&#039;] );&lt;br /&gt;
  // Return : &amp;quot;Deck&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  // Retrieve the last child element of another element&lt;br /&gt;
  // Here, we are requesting for elements who has element with ID=1234 (Deck) as their parent&lt;br /&gt;
  // Note the use of &amp;quot;limit:1&amp;quot; which allows us to retrieve only 1 element.&lt;br /&gt;
  var first_card_on_deck_id = bga.getElement( { parent: 1234, limit:1 } );&lt;br /&gt;
  &lt;br /&gt;
  // You can also get nested properties such as the ids of the child elements of one element, or a custom property placed on the parent element&lt;br /&gt;
  var totem_places = bga.getElements( {tag:&#039;TOTEMZONE&#039;}, [&#039;id&#039;,&#039;childs:id&#039;,&#039;childs:tags&#039;,&#039;parent:id&#039;,&#039;parent:c_value&#039;] );&lt;br /&gt;
&lt;br /&gt;
=== bga.getElements( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Returns an object holding the properties of the elements matching the selector.&lt;br /&gt;
&lt;br /&gt;
  // Basic example: unselect all selected elements&lt;br /&gt;
  bga.removeStyle( bga.getElements( {tag: &#039;sbstyle_selected&#039;}), &#039;selected&#039; );&lt;br /&gt;
&lt;br /&gt;
=== bga.getElementsArray( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Returns an array of all elements matching the selector, holding the required properties.&lt;br /&gt;
&lt;br /&gt;
  // Basic example: get id of selected element&lt;br /&gt;
  var selected_tokens = bga.getElementsArray( {tag: &#039;sbstyle_selected&#039; } );&lt;br /&gt;
  var token_id = null;&lt;br /&gt;
  if (selected_tokens.length &amp;gt; 0) {&lt;br /&gt;
      token_id = selected_tokens[0];&lt;br /&gt;
  }&lt;br /&gt;
  return token_id;&lt;br /&gt;
&lt;br /&gt;
  // Classic example: get array of elements and iterate over it&lt;br /&gt;
  var all_cells = bga.getElementsArray( {tag: &#039;CELL&#039;}, [&#039;id&#039;,&#039;name&#039;,&#039;tags&#039;] );&lt;br /&gt;
  for (var i=0; i&amp;lt;all_cells.length; i++) {&lt;br /&gt;
     // ... process each cell ...&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Utility methods ==&lt;br /&gt;
&lt;br /&gt;
=== bga.isOn( element_id, parent_id ) ===&lt;br /&gt;
&lt;br /&gt;
Return true if &amp;quot;element_id&amp;quot; is a descendant of &amp;quot;parent_id&amp;quot; (ie : if element_id game element has been placed on parent_id game element).&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  if( bga.isOn( bga.getElementIfByName( &#039;Turn counter&#039; ), bga.getElementIfByName( &#039;Turn 6&#039; ) )&lt;br /&gt;
  {&lt;br /&gt;
     // Trigger game end&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Trigger most common game actions ==&lt;br /&gt;
&lt;br /&gt;
=== moveTo( id, target, path ) ===&lt;br /&gt;
&lt;br /&gt;
Move element to specified target id (eventually following path defined by an array of element ids to pass over on the way)&lt;br /&gt;
&lt;br /&gt;
The exact destination of element depends on target&#039;s &amp;quot;howToArrange&amp;quot; property (&amp;quot;How elements are arranged on it?&amp;quot; : spreaded/deck/...).&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.moveTo( bga.getElementIdByName( &#039;Turn counter&#039; ), bga.getElementIdByName( &#039;Turn 3&#039; ) );&lt;br /&gt;
&lt;br /&gt;
=== incScore( color, value ) ===&lt;br /&gt;
&lt;br /&gt;
Increases the score for the player with the specified color, of the specified increment value.&lt;br /&gt;
&lt;br /&gt;
== Other functions ==&lt;br /&gt;
&lt;br /&gt;
=== pause( milliseconds ) ===&lt;br /&gt;
&lt;br /&gt;
Pause the client interface during a specified number of milliseconds.&lt;br /&gt;
&lt;br /&gt;
If you do not use bga.pause, all Sandbox game actions are executed immediately and synchronously.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.log( &amp;quot;1&amp;quot; );    // Will be displayed immediately on the log&lt;br /&gt;
  bga.pause( 3000 ); // pause during 3 seconds&lt;br /&gt;
  bga.log( &amp;quot;2&amp;quot; );    // Will be displayed after the 3 second on the log&lt;br /&gt;
  bga.log( &amp;quot;3&amp;quot; );    // Will be displayed right after the previous one, without delay.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Tips : if you want to execute several consecutive &amp;quot;moveTo&amp;quot;, you should &amp;quot;bga.pause&amp;quot; between them, otherwise your element will move directly to the final destination.&lt;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://sr.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=3041</id>
		<title>SandboxScripts</title>
		<link rel="alternate" type="text/html" href="https://sr.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=3041"/>
		<updated>2018-05-17T14:25:25Z</updated>

		<summary type="html">&lt;p&gt;Een: /* moveTo( id, target, path ) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This is the reference of functions you can call from your Sandbox scripts.&lt;br /&gt;
&lt;br /&gt;
= Javascript =&lt;br /&gt;
&lt;br /&gt;
BGA Sandbox scripts are written in Javascript.&lt;br /&gt;
&lt;br /&gt;
Using Javascript, you can write scripts to automate moves for your Sandbox games &amp;amp; provide rules reinforcement.&lt;br /&gt;
&lt;br /&gt;
Important : in the opposite of the most common usage of Javascript, Sandbox scripts are executed &#039;&#039;&#039;on server side&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
= BGA API =&lt;br /&gt;
&lt;br /&gt;
To interact with your BGA Sandbox game, we provide you an API.&lt;br /&gt;
&lt;br /&gt;
With this API, you can get properties values of game elements from the current game situation, modify them and/or trigger the game actions (ex : move this element here, flip this card, and so on).&lt;br /&gt;
&lt;br /&gt;
= Quick start =&lt;br /&gt;
&lt;br /&gt;
== Hello World Script ==&lt;br /&gt;
&lt;br /&gt;
From Sandbox editor &amp;quot;interface view&amp;quot; tab, select an element, and access to its property (top right icon).&lt;br /&gt;
&lt;br /&gt;
Go to &amp;quot;Scripts (advanced)&amp;quot; section.&lt;br /&gt;
&lt;br /&gt;
In front of &amp;quot;When this element is clicked&amp;quot;, enter &amp;quot;onMyClick&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Close the window. Go to &amp;quot;script view&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Enter the following :&lt;br /&gt;
&lt;br /&gt;
 function onMyClick( element_id )&lt;br /&gt;
 {&lt;br /&gt;
    bga.log(&amp;quot;Hello world! You just clicked on element &amp;quot; + element_id + &amp;quot;. Congrats!&amp;quot;);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Save &amp;amp; publish your project, starts a test session, click on the previous element : your message appears in the log on the right!&lt;br /&gt;
&lt;br /&gt;
== Top useful tips ==&lt;br /&gt;
&lt;br /&gt;
* You don&#039;t have to save&amp;amp;publish from the Sandbox editor for each modification of your script : each time you save your script (control+S), the script used for all test sessions is updated. Note that the production version on BGA is of course NOT updated until you explicitly save&amp;amp;publish again your project.&lt;br /&gt;
&lt;br /&gt;
* To inspect the content of a variable, you can use bga.log() in combination with JSON.stringify(). For example :&lt;br /&gt;
&lt;br /&gt;
  bga.log( JSON.stringify( bga.getPlayers()) );&lt;br /&gt;
&lt;br /&gt;
* Alternatively to bga.log(), you can use bga.exit( &amp;quot;my message&amp;quot; ) to debug your script. With bga.exit, the script execution immediately stops and all previous game changes are cancelled, so this is very practical to try and retry an action until your script is fine.&lt;br /&gt;
&lt;br /&gt;
* We advise you to develop first a full playable version of the game without the scripts, and THEN to script it.&lt;br /&gt;
&lt;br /&gt;
* On Board Game Arena, players have come to expect fully implemented games with all rules enforced. So even if it&#039;s technically possible not to script the full game and to implement the game only partially, in most cases we&#039;ll publish only fully scripted games :)&lt;br /&gt;
&lt;br /&gt;
= Functions you can use in your Sandbox scripts=&lt;br /&gt;
&lt;br /&gt;
== Debugging functions ==&lt;br /&gt;
&lt;br /&gt;
=== bga.trace( txt / obj ) ===&lt;br /&gt;
&lt;br /&gt;
Write something immediately in the BGA log (on the right of the screen).&lt;br /&gt;
&lt;br /&gt;
This is the most practical way to debug your script :)&lt;br /&gt;
&lt;br /&gt;
Important : bga.trace is for debugging purpose only and won&#039;t be displayed on production.&lt;br /&gt;
&lt;br /&gt;
Note : you can also pass an object in parameter. This will dump the content of this object in the log.&lt;br /&gt;
&lt;br /&gt;
Note : in the opposite of bga.log, bga.trace is NOT cancelled if the game action failed (after a call to bga.cancel or bga.error). This makes bga.trace very practical to debug a game action that failed, and for this reason you should probably NEVER use bga.log for debugging purpose.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  // Example : write &amp;quot;Hello world&amp;quot; in the log&lt;br /&gt;
  bga.trace( &amp;quot;Hello world&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Example : dump an associative array in the log&lt;br /&gt;
  bga.trace( { mykey: &#039;myvalue&#039;, another_key: &#039;another_value&#039; } );&lt;br /&gt;
&lt;br /&gt;
=== bga.exit( txt / obj ) ===&lt;br /&gt;
&lt;br /&gt;
Stop the script immediately, display the &amp;quot;txt&amp;quot; messages and cancel (ie : rollback) on every previous API call except bga.trace :&lt;br /&gt;
&lt;br /&gt;
ALL previous BGA api call are canceled and there will be no visible changes on the interface (ex : no moves, no visible property changes, ...). Only &amp;quot;bga.trace&amp;quot; API commands are kept so you can debug.&lt;br /&gt;
&lt;br /&gt;
bga.exit is very practical when you want to repeat a game action again and again to debug it : with a call to bga.exit at the end of your script, you make sure that your game situation will be kept unchanged after each test.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.exit( &amp;quot;My script is stopped by this call&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Example with dumping a javascript variable&lt;br /&gt;
  bga.exit( my_variable_to_dump );&lt;br /&gt;
&lt;br /&gt;
== Cancelling a game action ==&lt;br /&gt;
&lt;br /&gt;
=== bga.cancel( txt ) ===&lt;br /&gt;
&lt;br /&gt;
This is the function to use when a player is doing something against game rules.&lt;br /&gt;
&lt;br /&gt;
The text message in parameter will be displayed to this player as a &amp;quot;red message&amp;quot;, so he/she can understand the rule.&lt;br /&gt;
&lt;br /&gt;
All previous BGA api call are cancelled, and there will be no visible changes on the interface.&lt;br /&gt;
&lt;br /&gt;
   // Example :&lt;br /&gt;
   bga.cancel( _(&amp;quot;You cannot move this piece here&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
Note : most of the time, you should wrap your text inside a _() translation marker to make this string translatable.&lt;br /&gt;
&lt;br /&gt;
=== bga.error( text ) ===&lt;br /&gt;
&lt;br /&gt;
This is the function to use when some unexpected error happens in your script.&lt;br /&gt;
&lt;br /&gt;
The text message will be displayed to user, with mention &amp;quot;Unexpected error&amp;quot;. The player will be incited to fill a bug report. The purpose of the message is to help you to identify the bug.&lt;br /&gt;
&lt;br /&gt;
All previous BGA api call are cancelled, and there will be no visible changes on the interface.&lt;br /&gt;
&lt;br /&gt;
   // Example :&lt;br /&gt;
   if( card_picked === null )&lt;br /&gt;
   {&lt;br /&gt;
       bga.error( &amp;quot;Cannot find a card to pick !&amp;quot; );&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
Note : you should NEVER wrap text inside bga.error with _() translation marker, because unexpected error should not be translate (so you can eventually recognize them when reported by players in bug report).&lt;br /&gt;
&lt;br /&gt;
== Game log (history) ==&lt;br /&gt;
&lt;br /&gt;
=== bga.log( txt, (optional) args ) ===&lt;br /&gt;
&lt;br /&gt;
Write something in the BGA log on the right.&lt;br /&gt;
&lt;br /&gt;
  // Example : simple log&lt;br /&gt;
  bga.log( _(&amp;quot;A new round starts&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
You may add arguments to your log, like this :&lt;br /&gt;
&lt;br /&gt;
  // Example: log with argument to display a card name.&lt;br /&gt;
  //          In this example, variable &amp;quot;event_name&amp;quot; is specified afterwards.&lt;br /&gt;
  //          Note that using this, game translators only have to translate one &amp;quot;Event XXX is triggered&amp;quot; string for all possible events.&lt;br /&gt;
  bga.log( _(&amp;quot;Event ${event_name} is triggered&amp;quot;), {  event_name: _( &amp;quot;Armageddon&amp;quot; ) } ) );&lt;br /&gt;
&lt;br /&gt;
Note that argument &amp;quot;player_name&amp;quot; is ALWAYS pre-set with the name of the current player, so you can use it immediately.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.log( _(&amp;quot;${player_name} draw a card from the deck&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
=== bga.speechBubble( target, text, (optional) args, (optional) delay, (optional) duration, (optional) size ) ===&lt;br /&gt;
&lt;br /&gt;
Display a &amp;quot;speech bubble&amp;quot;, attached to the specified target, containing the specified text.&lt;br /&gt;
&lt;br /&gt;
You can use &amp;quot;args&amp;quot; to customize text exactly like with bga.log.&lt;br /&gt;
&lt;br /&gt;
delay : milliseconds to wait before displaying the speech bubble (default : 0).&lt;br /&gt;
duration : how long to show the speech bubble in milliseconds (default : 3000).&lt;br /&gt;
size : size of the text in percent (default: 100)&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.speechBubble( _(&amp;quot;I play ${nbr} cards&amp;quot;), { nbr : 4 }, 0 );&lt;br /&gt;
  bga.speechBubble( _(&amp;quot;Good for you!&amp;quot;), { }, 2000 );&lt;br /&gt;
&lt;br /&gt;
=== bga.displayScoring( target, color, score ) ===&lt;br /&gt;
&lt;br /&gt;
Display an animated temporary &amp;quot;score number&amp;quot;, attached to the specified target.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;color&amp;quot; should be the color of the player who is scoring for that target.&lt;br /&gt;
&lt;br /&gt;
== Get / search game elements and their properties ==&lt;br /&gt;
&lt;br /&gt;
=== bga.getElement( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Allow you to retrieve informations about one game element specified using &amp;quot;selector&amp;quot; argument.&lt;br /&gt;
&lt;br /&gt;
Return null if no element is found.&lt;br /&gt;
&lt;br /&gt;
Note : getElement throw an error if several elements matches the selector. If you want to retrieve several elements, you should use &amp;quot;getElements&amp;quot; instead of &amp;quot;getElement&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The following examples are showing all the possible use of bga.getElement :&lt;br /&gt;
&lt;br /&gt;
  // Basic example :&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve the ID of a game element using its name (&amp;quot;Deck&amp;quot;)&lt;br /&gt;
  var deck_id = bga.getElement( { name: &amp;quot;Deck&amp;quot; } );&lt;br /&gt;
  // Return : 1234  &lt;br /&gt;
&lt;br /&gt;
  // Examples using &amp;quot;field&amp;quot; parameter :&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve a specific property from a game element using its name (&amp;quot;Deck&amp;quot;)&lt;br /&gt;
  var deck_id = bga.getElement( { name: &amp;quot;Deck&amp;quot; }, &#039;x&#039; );&lt;br /&gt;
  // Return : 20&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve several properties from the previous element&lt;br /&gt;
  var deck_properties = bga.getElement( { name: &amp;quot;Deck&amp;quot; }, [&#039;name&#039;,&#039;id&#039;,&#039;parent&#039;, &#039;x&#039;,&#039;y&#039;,&#039;canShuffle&#039;] );&lt;br /&gt;
  // Return : { name:&#039;Deck&#039;, id:1234, parent:4321, x: 20, y:50, canShuffle: true }&lt;br /&gt;
  &lt;br /&gt;
  // Note : as you can see, getElement returns:&lt;br /&gt;
  //        _ the element ID by default, or&lt;br /&gt;
  //        _ a single value if you request a single field, or&lt;br /&gt;
  //        _ an object if you request several fields&lt;br /&gt;
&lt;br /&gt;
  // Examples using different &amp;quot;selector&amp;quot; paramter&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve an element name from its id&lt;br /&gt;
  var deck_name = bga.getElement( { id: 1234 }, [&#039;name&#039;] );&lt;br /&gt;
  // Return : &amp;quot;Deck&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  // Retrieve the last child element of another element&lt;br /&gt;
  // Here, we are requesting for elements who has element with ID=1234 (Deck) as their parent&lt;br /&gt;
  // Note the use of &amp;quot;limit:1&amp;quot; which allows us to retrieve only 1 element.&lt;br /&gt;
  var first_card_on_deck_id = bga.getElement( { parent: 1234, limit:1 } );&lt;br /&gt;
  &lt;br /&gt;
  // You can also get nested properties such as the ids of the child elements of one element, or a custom property placed on the parent element&lt;br /&gt;
  var totem_places = bga.getElements( {tag:&#039;TOTEMZONE&#039;}, [&#039;id&#039;,&#039;childs:id&#039;,&#039;childs:tags&#039;,&#039;parent:id&#039;,&#039;parent:c_value&#039;] );&lt;br /&gt;
&lt;br /&gt;
=== bga.getElements( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Returns an object holding the properties of the elements matching the selector.&lt;br /&gt;
&lt;br /&gt;
  // Basic example: unselect all selected elements&lt;br /&gt;
  bga.removeStyle( bga.getElements( {tag: &#039;sbstyle_selected&#039;}), &#039;selected&#039; );&lt;br /&gt;
&lt;br /&gt;
=== bga.getElementsArray( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Returns an array of all elements matching the selector, holding the required properties.&lt;br /&gt;
&lt;br /&gt;
  // Basic example: get id of selected element&lt;br /&gt;
  var selected_tokens = bga.getElementsArray( {tag: &#039;sbstyle_selected&#039; } );&lt;br /&gt;
  var token_id = null;&lt;br /&gt;
  if (selected_tokens.length &amp;gt; 0) {&lt;br /&gt;
      token_id = selected_tokens[0];&lt;br /&gt;
  }&lt;br /&gt;
  return token_id;&lt;br /&gt;
&lt;br /&gt;
  // Classic example: get array of elements and iterate over it&lt;br /&gt;
  var all_cells = bga.getElementsArray( {tag: &#039;CELL&#039;}, [&#039;id&#039;,&#039;name&#039;,&#039;tags&#039;] );&lt;br /&gt;
  for (var i=0; i&amp;lt;all_cells.length; i++) {&lt;br /&gt;
     // ... process each cell ...&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Utility methods ==&lt;br /&gt;
&lt;br /&gt;
=== bga.isOn( element_id, parent_id ) ===&lt;br /&gt;
&lt;br /&gt;
Return true if &amp;quot;element_id&amp;quot; is a descendant of &amp;quot;parent_id&amp;quot; (ie : if element_id game element has been placed on parent_id game element).&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  if( bga.isOn( bga.getElementIfByName( &#039;Turn counter&#039; ), bga.getElementIfByName( &#039;Turn 6&#039; ) )&lt;br /&gt;
  {&lt;br /&gt;
     // Trigger game end&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Trigger most common game actions ==&lt;br /&gt;
&lt;br /&gt;
=== moveTo( id, target, path ) ===&lt;br /&gt;
&lt;br /&gt;
Move element to specified target id (eventually following path defined by an array of element ids to pass over on the way)&lt;br /&gt;
&lt;br /&gt;
The exact destination of element depends on target&#039;s &amp;quot;howToArrange&amp;quot; property (&amp;quot;How elements are arranged on it?&amp;quot; : spreaded/deck/...).&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.moveTo( bga.getElementIdByName( &#039;Turn counter&#039; ), bga.getElementIdByName( &#039;Turn 3&#039; ) );&lt;br /&gt;
&lt;br /&gt;
=== incScore( playerColor, incValue ) ===&lt;br /&gt;
&lt;br /&gt;
Increases the score for the player with the specified color of the specified increment value.&lt;br /&gt;
&lt;br /&gt;
== Other functions ==&lt;br /&gt;
&lt;br /&gt;
=== pause( milliseconds ) ===&lt;br /&gt;
&lt;br /&gt;
Pause the client interface during a specified number of milliseconds.&lt;br /&gt;
&lt;br /&gt;
If you do not use bga.pause, all Sandbox game actions are executed immediately and synchronously.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.log( &amp;quot;1&amp;quot; );    // Will be displayed immediately on the log&lt;br /&gt;
  bga.pause( 3000 ); // pause during 3 seconds&lt;br /&gt;
  bga.log( &amp;quot;2&amp;quot; );    // Will be displayed after the 3 second on the log&lt;br /&gt;
  bga.log( &amp;quot;3&amp;quot; );    // Will be displayed right after the previous one, without delay.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Tips : if you want to execute several consecutive &amp;quot;moveTo&amp;quot;, you should &amp;quot;bga.pause&amp;quot; between them, otherwise your element will move directly to the final destination.&lt;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://sr.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=3040</id>
		<title>SandboxScripts</title>
		<link rel="alternate" type="text/html" href="https://sr.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=3040"/>
		<updated>2018-05-17T14:25:12Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Trigger most common game actions */  incScore&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This is the reference of functions you can call from your Sandbox scripts.&lt;br /&gt;
&lt;br /&gt;
= Javascript =&lt;br /&gt;
&lt;br /&gt;
BGA Sandbox scripts are written in Javascript.&lt;br /&gt;
&lt;br /&gt;
Using Javascript, you can write scripts to automate moves for your Sandbox games &amp;amp; provide rules reinforcement.&lt;br /&gt;
&lt;br /&gt;
Important : in the opposite of the most common usage of Javascript, Sandbox scripts are executed &#039;&#039;&#039;on server side&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
= BGA API =&lt;br /&gt;
&lt;br /&gt;
To interact with your BGA Sandbox game, we provide you an API.&lt;br /&gt;
&lt;br /&gt;
With this API, you can get properties values of game elements from the current game situation, modify them and/or trigger the game actions (ex : move this element here, flip this card, and so on).&lt;br /&gt;
&lt;br /&gt;
= Quick start =&lt;br /&gt;
&lt;br /&gt;
== Hello World Script ==&lt;br /&gt;
&lt;br /&gt;
From Sandbox editor &amp;quot;interface view&amp;quot; tab, select an element, and access to its property (top right icon).&lt;br /&gt;
&lt;br /&gt;
Go to &amp;quot;Scripts (advanced)&amp;quot; section.&lt;br /&gt;
&lt;br /&gt;
In front of &amp;quot;When this element is clicked&amp;quot;, enter &amp;quot;onMyClick&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Close the window. Go to &amp;quot;script view&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Enter the following :&lt;br /&gt;
&lt;br /&gt;
 function onMyClick( element_id )&lt;br /&gt;
 {&lt;br /&gt;
    bga.log(&amp;quot;Hello world! You just clicked on element &amp;quot; + element_id + &amp;quot;. Congrats!&amp;quot;);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Save &amp;amp; publish your project, starts a test session, click on the previous element : your message appears in the log on the right!&lt;br /&gt;
&lt;br /&gt;
== Top useful tips ==&lt;br /&gt;
&lt;br /&gt;
* You don&#039;t have to save&amp;amp;publish from the Sandbox editor for each modification of your script : each time you save your script (control+S), the script used for all test sessions is updated. Note that the production version on BGA is of course NOT updated until you explicitly save&amp;amp;publish again your project.&lt;br /&gt;
&lt;br /&gt;
* To inspect the content of a variable, you can use bga.log() in combination with JSON.stringify(). For example :&lt;br /&gt;
&lt;br /&gt;
  bga.log( JSON.stringify( bga.getPlayers()) );&lt;br /&gt;
&lt;br /&gt;
* Alternatively to bga.log(), you can use bga.exit( &amp;quot;my message&amp;quot; ) to debug your script. With bga.exit, the script execution immediately stops and all previous game changes are cancelled, so this is very practical to try and retry an action until your script is fine.&lt;br /&gt;
&lt;br /&gt;
* We advise you to develop first a full playable version of the game without the scripts, and THEN to script it.&lt;br /&gt;
&lt;br /&gt;
* On Board Game Arena, players have come to expect fully implemented games with all rules enforced. So even if it&#039;s technically possible not to script the full game and to implement the game only partially, in most cases we&#039;ll publish only fully scripted games :)&lt;br /&gt;
&lt;br /&gt;
= Functions you can use in your Sandbox scripts=&lt;br /&gt;
&lt;br /&gt;
== Debugging functions ==&lt;br /&gt;
&lt;br /&gt;
=== bga.trace( txt / obj ) ===&lt;br /&gt;
&lt;br /&gt;
Write something immediately in the BGA log (on the right of the screen).&lt;br /&gt;
&lt;br /&gt;
This is the most practical way to debug your script :)&lt;br /&gt;
&lt;br /&gt;
Important : bga.trace is for debugging purpose only and won&#039;t be displayed on production.&lt;br /&gt;
&lt;br /&gt;
Note : you can also pass an object in parameter. This will dump the content of this object in the log.&lt;br /&gt;
&lt;br /&gt;
Note : in the opposite of bga.log, bga.trace is NOT cancelled if the game action failed (after a call to bga.cancel or bga.error). This makes bga.trace very practical to debug a game action that failed, and for this reason you should probably NEVER use bga.log for debugging purpose.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  // Example : write &amp;quot;Hello world&amp;quot; in the log&lt;br /&gt;
  bga.trace( &amp;quot;Hello world&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Example : dump an associative array in the log&lt;br /&gt;
  bga.trace( { mykey: &#039;myvalue&#039;, another_key: &#039;another_value&#039; } );&lt;br /&gt;
&lt;br /&gt;
=== bga.exit( txt / obj ) ===&lt;br /&gt;
&lt;br /&gt;
Stop the script immediately, display the &amp;quot;txt&amp;quot; messages and cancel (ie : rollback) on every previous API call except bga.trace :&lt;br /&gt;
&lt;br /&gt;
ALL previous BGA api call are canceled and there will be no visible changes on the interface (ex : no moves, no visible property changes, ...). Only &amp;quot;bga.trace&amp;quot; API commands are kept so you can debug.&lt;br /&gt;
&lt;br /&gt;
bga.exit is very practical when you want to repeat a game action again and again to debug it : with a call to bga.exit at the end of your script, you make sure that your game situation will be kept unchanged after each test.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.exit( &amp;quot;My script is stopped by this call&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Example with dumping a javascript variable&lt;br /&gt;
  bga.exit( my_variable_to_dump );&lt;br /&gt;
&lt;br /&gt;
== Cancelling a game action ==&lt;br /&gt;
&lt;br /&gt;
=== bga.cancel( txt ) ===&lt;br /&gt;
&lt;br /&gt;
This is the function to use when a player is doing something against game rules.&lt;br /&gt;
&lt;br /&gt;
The text message in parameter will be displayed to this player as a &amp;quot;red message&amp;quot;, so he/she can understand the rule.&lt;br /&gt;
&lt;br /&gt;
All previous BGA api call are cancelled, and there will be no visible changes on the interface.&lt;br /&gt;
&lt;br /&gt;
   // Example :&lt;br /&gt;
   bga.cancel( _(&amp;quot;You cannot move this piece here&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
Note : most of the time, you should wrap your text inside a _() translation marker to make this string translatable.&lt;br /&gt;
&lt;br /&gt;
=== bga.error( text ) ===&lt;br /&gt;
&lt;br /&gt;
This is the function to use when some unexpected error happens in your script.&lt;br /&gt;
&lt;br /&gt;
The text message will be displayed to user, with mention &amp;quot;Unexpected error&amp;quot;. The player will be incited to fill a bug report. The purpose of the message is to help you to identify the bug.&lt;br /&gt;
&lt;br /&gt;
All previous BGA api call are cancelled, and there will be no visible changes on the interface.&lt;br /&gt;
&lt;br /&gt;
   // Example :&lt;br /&gt;
   if( card_picked === null )&lt;br /&gt;
   {&lt;br /&gt;
       bga.error( &amp;quot;Cannot find a card to pick !&amp;quot; );&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
Note : you should NEVER wrap text inside bga.error with _() translation marker, because unexpected error should not be translate (so you can eventually recognize them when reported by players in bug report).&lt;br /&gt;
&lt;br /&gt;
== Game log (history) ==&lt;br /&gt;
&lt;br /&gt;
=== bga.log( txt, (optional) args ) ===&lt;br /&gt;
&lt;br /&gt;
Write something in the BGA log on the right.&lt;br /&gt;
&lt;br /&gt;
  // Example : simple log&lt;br /&gt;
  bga.log( _(&amp;quot;A new round starts&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
You may add arguments to your log, like this :&lt;br /&gt;
&lt;br /&gt;
  // Example: log with argument to display a card name.&lt;br /&gt;
  //          In this example, variable &amp;quot;event_name&amp;quot; is specified afterwards.&lt;br /&gt;
  //          Note that using this, game translators only have to translate one &amp;quot;Event XXX is triggered&amp;quot; string for all possible events.&lt;br /&gt;
  bga.log( _(&amp;quot;Event ${event_name} is triggered&amp;quot;), {  event_name: _( &amp;quot;Armageddon&amp;quot; ) } ) );&lt;br /&gt;
&lt;br /&gt;
Note that argument &amp;quot;player_name&amp;quot; is ALWAYS pre-set with the name of the current player, so you can use it immediately.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.log( _(&amp;quot;${player_name} draw a card from the deck&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
=== bga.speechBubble( target, text, (optional) args, (optional) delay, (optional) duration, (optional) size ) ===&lt;br /&gt;
&lt;br /&gt;
Display a &amp;quot;speech bubble&amp;quot;, attached to the specified target, containing the specified text.&lt;br /&gt;
&lt;br /&gt;
You can use &amp;quot;args&amp;quot; to customize text exactly like with bga.log.&lt;br /&gt;
&lt;br /&gt;
delay : milliseconds to wait before displaying the speech bubble (default : 0).&lt;br /&gt;
duration : how long to show the speech bubble in milliseconds (default : 3000).&lt;br /&gt;
size : size of the text in percent (default: 100)&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.speechBubble( _(&amp;quot;I play ${nbr} cards&amp;quot;), { nbr : 4 }, 0 );&lt;br /&gt;
  bga.speechBubble( _(&amp;quot;Good for you!&amp;quot;), { }, 2000 );&lt;br /&gt;
&lt;br /&gt;
=== bga.displayScoring( target, color, score ) ===&lt;br /&gt;
&lt;br /&gt;
Display an animated temporary &amp;quot;score number&amp;quot;, attached to the specified target.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;color&amp;quot; should be the color of the player who is scoring for that target.&lt;br /&gt;
&lt;br /&gt;
== Get / search game elements and their properties ==&lt;br /&gt;
&lt;br /&gt;
=== bga.getElement( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Allow you to retrieve informations about one game element specified using &amp;quot;selector&amp;quot; argument.&lt;br /&gt;
&lt;br /&gt;
Return null if no element is found.&lt;br /&gt;
&lt;br /&gt;
Note : getElement throw an error if several elements matches the selector. If you want to retrieve several elements, you should use &amp;quot;getElements&amp;quot; instead of &amp;quot;getElement&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The following examples are showing all the possible use of bga.getElement :&lt;br /&gt;
&lt;br /&gt;
  // Basic example :&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve the ID of a game element using its name (&amp;quot;Deck&amp;quot;)&lt;br /&gt;
  var deck_id = bga.getElement( { name: &amp;quot;Deck&amp;quot; } );&lt;br /&gt;
  // Return : 1234  &lt;br /&gt;
&lt;br /&gt;
  // Examples using &amp;quot;field&amp;quot; parameter :&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve a specific property from a game element using its name (&amp;quot;Deck&amp;quot;)&lt;br /&gt;
  var deck_id = bga.getElement( { name: &amp;quot;Deck&amp;quot; }, &#039;x&#039; );&lt;br /&gt;
  // Return : 20&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve several properties from the previous element&lt;br /&gt;
  var deck_properties = bga.getElement( { name: &amp;quot;Deck&amp;quot; }, [&#039;name&#039;,&#039;id&#039;,&#039;parent&#039;, &#039;x&#039;,&#039;y&#039;,&#039;canShuffle&#039;] );&lt;br /&gt;
  // Return : { name:&#039;Deck&#039;, id:1234, parent:4321, x: 20, y:50, canShuffle: true }&lt;br /&gt;
  &lt;br /&gt;
  // Note : as you can see, getElement returns:&lt;br /&gt;
  //        _ the element ID by default, or&lt;br /&gt;
  //        _ a single value if you request a single field, or&lt;br /&gt;
  //        _ an object if you request several fields&lt;br /&gt;
&lt;br /&gt;
  // Examples using different &amp;quot;selector&amp;quot; paramter&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve an element name from its id&lt;br /&gt;
  var deck_name = bga.getElement( { id: 1234 }, [&#039;name&#039;] );&lt;br /&gt;
  // Return : &amp;quot;Deck&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  // Retrieve the last child element of another element&lt;br /&gt;
  // Here, we are requesting for elements who has element with ID=1234 (Deck) as their parent&lt;br /&gt;
  // Note the use of &amp;quot;limit:1&amp;quot; which allows us to retrieve only 1 element.&lt;br /&gt;
  var first_card_on_deck_id = bga.getElement( { parent: 1234, limit:1 } );&lt;br /&gt;
  &lt;br /&gt;
  // You can also get nested properties such as the ids of the child elements of one element, or a custom property placed on the parent element&lt;br /&gt;
  var totem_places = bga.getElements( {tag:&#039;TOTEMZONE&#039;}, [&#039;id&#039;,&#039;childs:id&#039;,&#039;childs:tags&#039;,&#039;parent:id&#039;,&#039;parent:c_value&#039;] );&lt;br /&gt;
&lt;br /&gt;
=== bga.getElements( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Returns an object holding the properties of the elements matching the selector.&lt;br /&gt;
&lt;br /&gt;
  // Basic example: unselect all selected elements&lt;br /&gt;
  bga.removeStyle( bga.getElements( {tag: &#039;sbstyle_selected&#039;}), &#039;selected&#039; );&lt;br /&gt;
&lt;br /&gt;
=== bga.getElementsArray( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Returns an array of all elements matching the selector, holding the required properties.&lt;br /&gt;
&lt;br /&gt;
  // Basic example: get id of selected element&lt;br /&gt;
  var selected_tokens = bga.getElementsArray( {tag: &#039;sbstyle_selected&#039; } );&lt;br /&gt;
  var token_id = null;&lt;br /&gt;
  if (selected_tokens.length &amp;gt; 0) {&lt;br /&gt;
      token_id = selected_tokens[0];&lt;br /&gt;
  }&lt;br /&gt;
  return token_id;&lt;br /&gt;
&lt;br /&gt;
  // Classic example: get array of elements and iterate over it&lt;br /&gt;
  var all_cells = bga.getElementsArray( {tag: &#039;CELL&#039;}, [&#039;id&#039;,&#039;name&#039;,&#039;tags&#039;] );&lt;br /&gt;
  for (var i=0; i&amp;lt;all_cells.length; i++) {&lt;br /&gt;
     // ... process each cell ...&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Utility methods ==&lt;br /&gt;
&lt;br /&gt;
=== bga.isOn( element_id, parent_id ) ===&lt;br /&gt;
&lt;br /&gt;
Return true if &amp;quot;element_id&amp;quot; is a descendant of &amp;quot;parent_id&amp;quot; (ie : if element_id game element has been placed on parent_id game element).&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  if( bga.isOn( bga.getElementIfByName( &#039;Turn counter&#039; ), bga.getElementIfByName( &#039;Turn 6&#039; ) )&lt;br /&gt;
  {&lt;br /&gt;
     // Trigger game end&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Trigger most common game actions ==&lt;br /&gt;
&lt;br /&gt;
=== moveTo( id, target, path ) ===&lt;br /&gt;
&lt;br /&gt;
Move element to specified target id (eventually following path defined by an array of element ids to pass over on the way)&lt;br /&gt;
&lt;br /&gt;
The exact destination of element depends on target&#039;s &amp;quot;howToArrange&amp;quot; property (&amp;quot;How elements are arranged on it?&amp;quot; : spreaded/deck/...).&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.moveTo( bga.getElementIdByName( &#039;Turn counter&#039; ), bga.getElementIdByName( &#039;Turn 3&#039; ) );&lt;br /&gt;
&lt;br /&gt;
=== incScore( playerColor, incValue )&lt;br /&gt;
&lt;br /&gt;
Increases the score for the player with the specified color of the specified increment value.&lt;br /&gt;
&lt;br /&gt;
== Other functions ==&lt;br /&gt;
&lt;br /&gt;
=== pause( milliseconds ) ===&lt;br /&gt;
&lt;br /&gt;
Pause the client interface during a specified number of milliseconds.&lt;br /&gt;
&lt;br /&gt;
If you do not use bga.pause, all Sandbox game actions are executed immediately and synchronously.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.log( &amp;quot;1&amp;quot; );    // Will be displayed immediately on the log&lt;br /&gt;
  bga.pause( 3000 ); // pause during 3 seconds&lt;br /&gt;
  bga.log( &amp;quot;2&amp;quot; );    // Will be displayed after the 3 second on the log&lt;br /&gt;
  bga.log( &amp;quot;3&amp;quot; );    // Will be displayed right after the previous one, without delay.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Tips : if you want to execute several consecutive &amp;quot;moveTo&amp;quot;, you should &amp;quot;bga.pause&amp;quot; between them, otherwise your element will move directly to the final destination.&lt;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://sr.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=3039</id>
		<title>SandboxScripts</title>
		<link rel="alternate" type="text/html" href="https://sr.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=3039"/>
		<updated>2018-05-17T14:21:21Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Top useful tips */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This is the reference of functions you can call from your Sandbox scripts.&lt;br /&gt;
&lt;br /&gt;
= Javascript =&lt;br /&gt;
&lt;br /&gt;
BGA Sandbox scripts are written in Javascript.&lt;br /&gt;
&lt;br /&gt;
Using Javascript, you can write scripts to automate moves for your Sandbox games &amp;amp; provide rules reinforcement.&lt;br /&gt;
&lt;br /&gt;
Important : in the opposite of the most common usage of Javascript, Sandbox scripts are executed &#039;&#039;&#039;on server side&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
= BGA API =&lt;br /&gt;
&lt;br /&gt;
To interact with your BGA Sandbox game, we provide you an API.&lt;br /&gt;
&lt;br /&gt;
With this API, you can get properties values of game elements from the current game situation, modify them and/or trigger the game actions (ex : move this element here, flip this card, and so on).&lt;br /&gt;
&lt;br /&gt;
= Quick start =&lt;br /&gt;
&lt;br /&gt;
== Hello World Script ==&lt;br /&gt;
&lt;br /&gt;
From Sandbox editor &amp;quot;interface view&amp;quot; tab, select an element, and access to its property (top right icon).&lt;br /&gt;
&lt;br /&gt;
Go to &amp;quot;Scripts (advanced)&amp;quot; section.&lt;br /&gt;
&lt;br /&gt;
In front of &amp;quot;When this element is clicked&amp;quot;, enter &amp;quot;onMyClick&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Close the window. Go to &amp;quot;script view&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Enter the following :&lt;br /&gt;
&lt;br /&gt;
 function onMyClick( element_id )&lt;br /&gt;
 {&lt;br /&gt;
    bga.log(&amp;quot;Hello world! You just clicked on element &amp;quot; + element_id + &amp;quot;. Congrats!&amp;quot;);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Save &amp;amp; publish your project, starts a test session, click on the previous element : your message appears in the log on the right!&lt;br /&gt;
&lt;br /&gt;
== Top useful tips ==&lt;br /&gt;
&lt;br /&gt;
* You don&#039;t have to save&amp;amp;publish from the Sandbox editor for each modification of your script : each time you save your script (control+S), the script used for all test sessions is updated. Note that the production version on BGA is of course NOT updated until you explicitly save&amp;amp;publish again your project.&lt;br /&gt;
&lt;br /&gt;
* To inspect the content of a variable, you can use bga.log() in combination with JSON.stringify(). For example :&lt;br /&gt;
&lt;br /&gt;
  bga.log( JSON.stringify( bga.getPlayers()) );&lt;br /&gt;
&lt;br /&gt;
* Alternatively to bga.log(), you can use bga.exit( &amp;quot;my message&amp;quot; ) to debug your script. With bga.exit, the script execution immediately stops and all previous game changes are cancelled, so this is very practical to try and retry an action until your script is fine.&lt;br /&gt;
&lt;br /&gt;
* We advise you to develop first a full playable version of the game without the scripts, and THEN to script it.&lt;br /&gt;
&lt;br /&gt;
* On Board Game Arena, players have come to expect fully implemented games with all rules enforced. So even if it&#039;s technically possible not to script the full game and to implement the game only partially, in most cases we&#039;ll publish only fully scripted games :)&lt;br /&gt;
&lt;br /&gt;
= Functions you can use in your Sandbox scripts=&lt;br /&gt;
&lt;br /&gt;
== Debugging functions ==&lt;br /&gt;
&lt;br /&gt;
=== bga.trace( txt / obj ) ===&lt;br /&gt;
&lt;br /&gt;
Write something immediately in the BGA log (on the right of the screen).&lt;br /&gt;
&lt;br /&gt;
This is the most practical way to debug your script :)&lt;br /&gt;
&lt;br /&gt;
Important : bga.trace is for debugging purpose only and won&#039;t be displayed on production.&lt;br /&gt;
&lt;br /&gt;
Note : you can also pass an object in parameter. This will dump the content of this object in the log.&lt;br /&gt;
&lt;br /&gt;
Note : in the opposite of bga.log, bga.trace is NOT cancelled if the game action failed (after a call to bga.cancel or bga.error). This makes bga.trace very practical to debug a game action that failed, and for this reason you should probably NEVER use bga.log for debugging purpose.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  // Example : write &amp;quot;Hello world&amp;quot; in the log&lt;br /&gt;
  bga.trace( &amp;quot;Hello world&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Example : dump an associative array in the log&lt;br /&gt;
  bga.trace( { mykey: &#039;myvalue&#039;, another_key: &#039;another_value&#039; } );&lt;br /&gt;
&lt;br /&gt;
=== bga.exit( txt / obj ) ===&lt;br /&gt;
&lt;br /&gt;
Stop the script immediately, display the &amp;quot;txt&amp;quot; messages and cancel (ie : rollback) on every previous API call except bga.trace :&lt;br /&gt;
&lt;br /&gt;
ALL previous BGA api call are canceled and there will be no visible changes on the interface (ex : no moves, no visible property changes, ...). Only &amp;quot;bga.trace&amp;quot; API commands are kept so you can debug.&lt;br /&gt;
&lt;br /&gt;
bga.exit is very practical when you want to repeat a game action again and again to debug it : with a call to bga.exit at the end of your script, you make sure that your game situation will be kept unchanged after each test.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.exit( &amp;quot;My script is stopped by this call&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Example with dumping a javascript variable&lt;br /&gt;
  bga.exit( my_variable_to_dump );&lt;br /&gt;
&lt;br /&gt;
== Cancelling a game action ==&lt;br /&gt;
&lt;br /&gt;
=== bga.cancel( txt ) ===&lt;br /&gt;
&lt;br /&gt;
This is the function to use when a player is doing something against game rules.&lt;br /&gt;
&lt;br /&gt;
The text message in parameter will be displayed to this player as a &amp;quot;red message&amp;quot;, so he/she can understand the rule.&lt;br /&gt;
&lt;br /&gt;
All previous BGA api call are cancelled, and there will be no visible changes on the interface.&lt;br /&gt;
&lt;br /&gt;
   // Example :&lt;br /&gt;
   bga.cancel( _(&amp;quot;You cannot move this piece here&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
Note : most of the time, you should wrap your text inside a _() translation marker to make this string translatable.&lt;br /&gt;
&lt;br /&gt;
=== bga.error( text ) ===&lt;br /&gt;
&lt;br /&gt;
This is the function to use when some unexpected error happens in your script.&lt;br /&gt;
&lt;br /&gt;
The text message will be displayed to user, with mention &amp;quot;Unexpected error&amp;quot;. The player will be incited to fill a bug report. The purpose of the message is to help you to identify the bug.&lt;br /&gt;
&lt;br /&gt;
All previous BGA api call are cancelled, and there will be no visible changes on the interface.&lt;br /&gt;
&lt;br /&gt;
   // Example :&lt;br /&gt;
   if( card_picked === null )&lt;br /&gt;
   {&lt;br /&gt;
       bga.error( &amp;quot;Cannot find a card to pick !&amp;quot; );&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
Note : you should NEVER wrap text inside bga.error with _() translation marker, because unexpected error should not be translate (so you can eventually recognize them when reported by players in bug report).&lt;br /&gt;
&lt;br /&gt;
== Game log (history) ==&lt;br /&gt;
&lt;br /&gt;
=== bga.log( txt, (optional) args ) ===&lt;br /&gt;
&lt;br /&gt;
Write something in the BGA log on the right.&lt;br /&gt;
&lt;br /&gt;
  // Example : simple log&lt;br /&gt;
  bga.log( _(&amp;quot;A new round starts&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
You may add arguments to your log, like this :&lt;br /&gt;
&lt;br /&gt;
  // Example: log with argument to display a card name.&lt;br /&gt;
  //          In this example, variable &amp;quot;event_name&amp;quot; is specified afterwards.&lt;br /&gt;
  //          Note that using this, game translators only have to translate one &amp;quot;Event XXX is triggered&amp;quot; string for all possible events.&lt;br /&gt;
  bga.log( _(&amp;quot;Event ${event_name} is triggered&amp;quot;), {  event_name: _( &amp;quot;Armageddon&amp;quot; ) } ) );&lt;br /&gt;
&lt;br /&gt;
Note that argument &amp;quot;player_name&amp;quot; is ALWAYS pre-set with the name of the current player, so you can use it immediately.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.log( _(&amp;quot;${player_name} draw a card from the deck&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
=== bga.speechBubble( target, text, (optional) args, (optional) delay, (optional) duration, (optional) size ) ===&lt;br /&gt;
&lt;br /&gt;
Display a &amp;quot;speech bubble&amp;quot;, attached to the specified target, containing the specified text.&lt;br /&gt;
&lt;br /&gt;
You can use &amp;quot;args&amp;quot; to customize text exactly like with bga.log.&lt;br /&gt;
&lt;br /&gt;
delay : milliseconds to wait before displaying the speech bubble (default : 0).&lt;br /&gt;
duration : how long to show the speech bubble in milliseconds (default : 3000).&lt;br /&gt;
size : size of the text in percent (default: 100)&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.speechBubble( _(&amp;quot;I play ${nbr} cards&amp;quot;), { nbr : 4 }, 0 );&lt;br /&gt;
  bga.speechBubble( _(&amp;quot;Good for you!&amp;quot;), { }, 2000 );&lt;br /&gt;
&lt;br /&gt;
=== bga.displayScoring( target, color, score ) ===&lt;br /&gt;
&lt;br /&gt;
Display an animated temporary &amp;quot;score number&amp;quot;, attached to the specified target.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;color&amp;quot; should be the color of the player who is scoring for that target.&lt;br /&gt;
&lt;br /&gt;
== Get / search game elements and their properties ==&lt;br /&gt;
&lt;br /&gt;
=== bga.getElement( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Allow you to retrieve informations about one game element specified using &amp;quot;selector&amp;quot; argument.&lt;br /&gt;
&lt;br /&gt;
Return null if no element is found.&lt;br /&gt;
&lt;br /&gt;
Note : getElement throw an error if several elements matches the selector. If you want to retrieve several elements, you should use &amp;quot;getElements&amp;quot; instead of &amp;quot;getElement&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The following examples are showing all the possible use of bga.getElement :&lt;br /&gt;
&lt;br /&gt;
  // Basic example :&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve the ID of a game element using its name (&amp;quot;Deck&amp;quot;)&lt;br /&gt;
  var deck_id = bga.getElement( { name: &amp;quot;Deck&amp;quot; } );&lt;br /&gt;
  // Return : 1234  &lt;br /&gt;
&lt;br /&gt;
  // Examples using &amp;quot;field&amp;quot; parameter :&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve a specific property from a game element using its name (&amp;quot;Deck&amp;quot;)&lt;br /&gt;
  var deck_id = bga.getElement( { name: &amp;quot;Deck&amp;quot; }, &#039;x&#039; );&lt;br /&gt;
  // Return : 20&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve several properties from the previous element&lt;br /&gt;
  var deck_properties = bga.getElement( { name: &amp;quot;Deck&amp;quot; }, [&#039;name&#039;,&#039;id&#039;,&#039;parent&#039;, &#039;x&#039;,&#039;y&#039;,&#039;canShuffle&#039;] );&lt;br /&gt;
  // Return : { name:&#039;Deck&#039;, id:1234, parent:4321, x: 20, y:50, canShuffle: true }&lt;br /&gt;
  &lt;br /&gt;
  // Note : as you can see, getElement returns:&lt;br /&gt;
  //        _ the element ID by default, or&lt;br /&gt;
  //        _ a single value if you request a single field, or&lt;br /&gt;
  //        _ an object if you request several fields&lt;br /&gt;
&lt;br /&gt;
  // Examples using different &amp;quot;selector&amp;quot; paramter&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve an element name from its id&lt;br /&gt;
  var deck_name = bga.getElement( { id: 1234 }, [&#039;name&#039;] );&lt;br /&gt;
  // Return : &amp;quot;Deck&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  // Retrieve the last child element of another element&lt;br /&gt;
  // Here, we are requesting for elements who has element with ID=1234 (Deck) as their parent&lt;br /&gt;
  // Note the use of &amp;quot;limit:1&amp;quot; which allows us to retrieve only 1 element.&lt;br /&gt;
  var first_card_on_deck_id = bga.getElement( { parent: 1234, limit:1 } );&lt;br /&gt;
  &lt;br /&gt;
  // You can also get nested properties such as the ids of the child elements of one element, or a custom property placed on the parent element&lt;br /&gt;
  var totem_places = bga.getElements( {tag:&#039;TOTEMZONE&#039;}, [&#039;id&#039;,&#039;childs:id&#039;,&#039;childs:tags&#039;,&#039;parent:id&#039;,&#039;parent:c_value&#039;] );&lt;br /&gt;
&lt;br /&gt;
=== bga.getElements( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Returns an object holding the properties of the elements matching the selector.&lt;br /&gt;
&lt;br /&gt;
  // Basic example: unselect all selected elements&lt;br /&gt;
  bga.removeStyle( bga.getElements( {tag: &#039;sbstyle_selected&#039;}), &#039;selected&#039; );&lt;br /&gt;
&lt;br /&gt;
=== bga.getElementsArray( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Returns an array of all elements matching the selector, holding the required properties.&lt;br /&gt;
&lt;br /&gt;
  // Basic example: get id of selected element&lt;br /&gt;
  var selected_tokens = bga.getElementsArray( {tag: &#039;sbstyle_selected&#039; } );&lt;br /&gt;
  var token_id = null;&lt;br /&gt;
  if (selected_tokens.length &amp;gt; 0) {&lt;br /&gt;
      token_id = selected_tokens[0];&lt;br /&gt;
  }&lt;br /&gt;
  return token_id;&lt;br /&gt;
&lt;br /&gt;
  // Classic example: get array of elements and iterate over it&lt;br /&gt;
  var all_cells = bga.getElementsArray( {tag: &#039;CELL&#039;}, [&#039;id&#039;,&#039;name&#039;,&#039;tags&#039;] );&lt;br /&gt;
  for (var i=0; i&amp;lt;all_cells.length; i++) {&lt;br /&gt;
     // ... process each cell ...&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Utility methods ==&lt;br /&gt;
&lt;br /&gt;
=== bga.isOn( element_id, parent_id ) ===&lt;br /&gt;
&lt;br /&gt;
Return true if &amp;quot;element_id&amp;quot; is a descendant of &amp;quot;parent_id&amp;quot; (ie : if element_id game element has been placed on parent_id game element).&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  if( bga.isOn( bga.getElementIfByName( &#039;Turn counter&#039; ), bga.getElementIfByName( &#039;Turn 6&#039; ) )&lt;br /&gt;
  {&lt;br /&gt;
     // Trigger game end&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Trigger most common game actions ==&lt;br /&gt;
&lt;br /&gt;
=== moveTo( $id, $target, $path=array() ) ===&lt;br /&gt;
&lt;br /&gt;
Move element to specified target id (eventually following path defined by an array of other element ids)&lt;br /&gt;
&lt;br /&gt;
The exact destination of element depends on target&#039;s &amp;quot;howToArrange&amp;quot; property (&amp;quot;How elements are arranged on it?&amp;quot; : spreaded/deck/...).&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.moveTo( bga.getElementIdByName( &#039;Turn counter&#039; ), bga.getElementIdByName( &#039;Turn 3&#039; ) );&lt;br /&gt;
&lt;br /&gt;
== Other functions ==&lt;br /&gt;
&lt;br /&gt;
=== pause( milliseconds ) ===&lt;br /&gt;
&lt;br /&gt;
Pause the client interface during a specified number of milliseconds.&lt;br /&gt;
&lt;br /&gt;
If you do not use bga.pause, all Sandbox game actions are executed immediately and synchronously.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.log( &amp;quot;1&amp;quot; );    // Will be displayed immediately on the log&lt;br /&gt;
  bga.pause( 3000 ); // pause during 3 seconds&lt;br /&gt;
  bga.log( &amp;quot;2&amp;quot; );    // Will be displayed after the 3 second on the log&lt;br /&gt;
  bga.log( &amp;quot;3&amp;quot; );    // Will be displayed right after the previous one, without delay.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Tips : if you want to execute several consecutive &amp;quot;moveTo&amp;quot;, you should &amp;quot;bga.pause&amp;quot; between them, otherwise your element will move directly to the final destination.&lt;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://sr.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=3038</id>
		<title>SandboxScripts</title>
		<link rel="alternate" type="text/html" href="https://sr.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=3038"/>
		<updated>2018-05-17T14:11:11Z</updated>

		<summary type="html">&lt;p&gt;Een: /* bga.getElement( selector, (optional) fields ) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This is the reference of functions you can call from your Sandbox scripts.&lt;br /&gt;
&lt;br /&gt;
= Javascript =&lt;br /&gt;
&lt;br /&gt;
BGA Sandbox scripts are written in Javascript.&lt;br /&gt;
&lt;br /&gt;
Using Javascript, you can write scripts to automate moves for your Sandbox games &amp;amp; provide rules reinforcement.&lt;br /&gt;
&lt;br /&gt;
Important : in the opposite of the most common usage of Javascript, Sandbox scripts are executed &#039;&#039;&#039;on server side&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
= BGA API =&lt;br /&gt;
&lt;br /&gt;
To interact with your BGA Sandbox game, we provide you an API.&lt;br /&gt;
&lt;br /&gt;
With this API, you can get properties values of game elements from the current game situation, modify them and/or trigger the game actions (ex : move this element here, flip this card, and so on).&lt;br /&gt;
&lt;br /&gt;
= Quick start =&lt;br /&gt;
&lt;br /&gt;
== Hello World Script ==&lt;br /&gt;
&lt;br /&gt;
From Sandbox editor &amp;quot;interface view&amp;quot; tab, select an element, and access to its property (top right icon).&lt;br /&gt;
&lt;br /&gt;
Go to &amp;quot;Scripts (advanced)&amp;quot; section.&lt;br /&gt;
&lt;br /&gt;
In front of &amp;quot;When this element is clicked&amp;quot;, enter &amp;quot;onMyClick&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Close the window. Go to &amp;quot;script view&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Enter the following :&lt;br /&gt;
&lt;br /&gt;
 function onMyClick( element_id )&lt;br /&gt;
 {&lt;br /&gt;
    bga.log(&amp;quot;Hello world! You just clicked on element &amp;quot; + element_id + &amp;quot;. Congrats!&amp;quot;);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Save &amp;amp; publish your project, starts a test session, click on the previous element : your message appears in the log on the right!&lt;br /&gt;
&lt;br /&gt;
== Top useful tips ==&lt;br /&gt;
&lt;br /&gt;
* You don&#039;t have to save&amp;amp;publish from the Sandbox editor for each modification of your script : each time you save your script (control+S), the script used for all test sessions is updated. Note that the production version on BGA is of course NOT updated until you explicitly save&amp;amp;publish again your project.&lt;br /&gt;
&lt;br /&gt;
* Alternatively to bga.log(), you can use bga.exit( &amp;quot;my message&amp;quot; ) to debug your script. With bga.exit, the script execution immediately stops and all previous game changes are cancelled, so this is very practical to try and retry an action until your script is fine.&lt;br /&gt;
&lt;br /&gt;
* We advise you to develop first a full playable version of the game without the scripts, and THEN to script it.&lt;br /&gt;
&lt;br /&gt;
* On Board Game Arena, players have come to expect fully implemented games with all rules enforced. So even if it&#039;s technically possible not to script the full game and to implement the game only partially, in most cases we&#039;ll publish only fully scripted games :)&lt;br /&gt;
&lt;br /&gt;
= Functions you can use in your Sandbox scripts=&lt;br /&gt;
&lt;br /&gt;
== Debugging functions ==&lt;br /&gt;
&lt;br /&gt;
=== bga.trace( txt / obj ) ===&lt;br /&gt;
&lt;br /&gt;
Write something immediately in the BGA log (on the right of the screen).&lt;br /&gt;
&lt;br /&gt;
This is the most practical way to debug your script :)&lt;br /&gt;
&lt;br /&gt;
Important : bga.trace is for debugging purpose only and won&#039;t be displayed on production.&lt;br /&gt;
&lt;br /&gt;
Note : you can also pass an object in parameter. This will dump the content of this object in the log.&lt;br /&gt;
&lt;br /&gt;
Note : in the opposite of bga.log, bga.trace is NOT cancelled if the game action failed (after a call to bga.cancel or bga.error). This makes bga.trace very practical to debug a game action that failed, and for this reason you should probably NEVER use bga.log for debugging purpose.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  // Example : write &amp;quot;Hello world&amp;quot; in the log&lt;br /&gt;
  bga.trace( &amp;quot;Hello world&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Example : dump an associative array in the log&lt;br /&gt;
  bga.trace( { mykey: &#039;myvalue&#039;, another_key: &#039;another_value&#039; } );&lt;br /&gt;
&lt;br /&gt;
=== bga.exit( txt / obj ) ===&lt;br /&gt;
&lt;br /&gt;
Stop the script immediately, display the &amp;quot;txt&amp;quot; messages and cancel (ie : rollback) on every previous API call except bga.trace :&lt;br /&gt;
&lt;br /&gt;
ALL previous BGA api call are canceled and there will be no visible changes on the interface (ex : no moves, no visible property changes, ...). Only &amp;quot;bga.trace&amp;quot; API commands are kept so you can debug.&lt;br /&gt;
&lt;br /&gt;
bga.exit is very practical when you want to repeat a game action again and again to debug it : with a call to bga.exit at the end of your script, you make sure that your game situation will be kept unchanged after each test.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.exit( &amp;quot;My script is stopped by this call&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Example with dumping a javascript variable&lt;br /&gt;
  bga.exit( my_variable_to_dump );&lt;br /&gt;
&lt;br /&gt;
== Cancelling a game action ==&lt;br /&gt;
&lt;br /&gt;
=== bga.cancel( txt ) ===&lt;br /&gt;
&lt;br /&gt;
This is the function to use when a player is doing something against game rules.&lt;br /&gt;
&lt;br /&gt;
The text message in parameter will be displayed to this player as a &amp;quot;red message&amp;quot;, so he/she can understand the rule.&lt;br /&gt;
&lt;br /&gt;
All previous BGA api call are cancelled, and there will be no visible changes on the interface.&lt;br /&gt;
&lt;br /&gt;
   // Example :&lt;br /&gt;
   bga.cancel( _(&amp;quot;You cannot move this piece here&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
Note : most of the time, you should wrap your text inside a _() translation marker to make this string translatable.&lt;br /&gt;
&lt;br /&gt;
=== bga.error( text ) ===&lt;br /&gt;
&lt;br /&gt;
This is the function to use when some unexpected error happens in your script.&lt;br /&gt;
&lt;br /&gt;
The text message will be displayed to user, with mention &amp;quot;Unexpected error&amp;quot;. The player will be incited to fill a bug report. The purpose of the message is to help you to identify the bug.&lt;br /&gt;
&lt;br /&gt;
All previous BGA api call are cancelled, and there will be no visible changes on the interface.&lt;br /&gt;
&lt;br /&gt;
   // Example :&lt;br /&gt;
   if( card_picked === null )&lt;br /&gt;
   {&lt;br /&gt;
       bga.error( &amp;quot;Cannot find a card to pick !&amp;quot; );&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
Note : you should NEVER wrap text inside bga.error with _() translation marker, because unexpected error should not be translate (so you can eventually recognize them when reported by players in bug report).&lt;br /&gt;
&lt;br /&gt;
== Game log (history) ==&lt;br /&gt;
&lt;br /&gt;
=== bga.log( txt, (optional) args ) ===&lt;br /&gt;
&lt;br /&gt;
Write something in the BGA log on the right.&lt;br /&gt;
&lt;br /&gt;
  // Example : simple log&lt;br /&gt;
  bga.log( _(&amp;quot;A new round starts&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
You may add arguments to your log, like this :&lt;br /&gt;
&lt;br /&gt;
  // Example: log with argument to display a card name.&lt;br /&gt;
  //          In this example, variable &amp;quot;event_name&amp;quot; is specified afterwards.&lt;br /&gt;
  //          Note that using this, game translators only have to translate one &amp;quot;Event XXX is triggered&amp;quot; string for all possible events.&lt;br /&gt;
  bga.log( _(&amp;quot;Event ${event_name} is triggered&amp;quot;), {  event_name: _( &amp;quot;Armageddon&amp;quot; ) } ) );&lt;br /&gt;
&lt;br /&gt;
Note that argument &amp;quot;player_name&amp;quot; is ALWAYS pre-set with the name of the current player, so you can use it immediately.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.log( _(&amp;quot;${player_name} draw a card from the deck&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
=== bga.speechBubble( target, text, (optional) args, (optional) delay, (optional) duration, (optional) size ) ===&lt;br /&gt;
&lt;br /&gt;
Display a &amp;quot;speech bubble&amp;quot;, attached to the specified target, containing the specified text.&lt;br /&gt;
&lt;br /&gt;
You can use &amp;quot;args&amp;quot; to customize text exactly like with bga.log.&lt;br /&gt;
&lt;br /&gt;
delay : milliseconds to wait before displaying the speech bubble (default : 0).&lt;br /&gt;
duration : how long to show the speech bubble in milliseconds (default : 3000).&lt;br /&gt;
size : size of the text in percent (default: 100)&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.speechBubble( _(&amp;quot;I play ${nbr} cards&amp;quot;), { nbr : 4 }, 0 );&lt;br /&gt;
  bga.speechBubble( _(&amp;quot;Good for you!&amp;quot;), { }, 2000 );&lt;br /&gt;
&lt;br /&gt;
=== bga.displayScoring( target, color, score ) ===&lt;br /&gt;
&lt;br /&gt;
Display an animated temporary &amp;quot;score number&amp;quot;, attached to the specified target.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;color&amp;quot; should be the color of the player who is scoring for that target.&lt;br /&gt;
&lt;br /&gt;
== Get / search game elements and their properties ==&lt;br /&gt;
&lt;br /&gt;
=== bga.getElement( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Allow you to retrieve informations about one game element specified using &amp;quot;selector&amp;quot; argument.&lt;br /&gt;
&lt;br /&gt;
Return null if no element is found.&lt;br /&gt;
&lt;br /&gt;
Note : getElement throw an error if several elements matches the selector. If you want to retrieve several elements, you should use &amp;quot;getElements&amp;quot; instead of &amp;quot;getElement&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The following examples are showing all the possible use of bga.getElement :&lt;br /&gt;
&lt;br /&gt;
  // Basic example :&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve the ID of a game element using its name (&amp;quot;Deck&amp;quot;)&lt;br /&gt;
  var deck_id = bga.getElement( { name: &amp;quot;Deck&amp;quot; } );&lt;br /&gt;
  // Return : 1234  &lt;br /&gt;
&lt;br /&gt;
  // Examples using &amp;quot;field&amp;quot; parameter :&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve a specific property from a game element using its name (&amp;quot;Deck&amp;quot;)&lt;br /&gt;
  var deck_id = bga.getElement( { name: &amp;quot;Deck&amp;quot; }, &#039;x&#039; );&lt;br /&gt;
  // Return : 20&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve several properties from the previous element&lt;br /&gt;
  var deck_properties = bga.getElement( { name: &amp;quot;Deck&amp;quot; }, [&#039;name&#039;,&#039;id&#039;,&#039;parent&#039;, &#039;x&#039;,&#039;y&#039;,&#039;canShuffle&#039;] );&lt;br /&gt;
  // Return : { name:&#039;Deck&#039;, id:1234, parent:4321, x: 20, y:50, canShuffle: true }&lt;br /&gt;
  &lt;br /&gt;
  // Note : as you can see, getElement returns:&lt;br /&gt;
  //        _ the element ID by default, or&lt;br /&gt;
  //        _ a single value if you request a single field, or&lt;br /&gt;
  //        _ an object if you request several fields&lt;br /&gt;
&lt;br /&gt;
  // Examples using different &amp;quot;selector&amp;quot; paramter&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve an element name from its id&lt;br /&gt;
  var deck_name = bga.getElement( { id: 1234 }, [&#039;name&#039;] );&lt;br /&gt;
  // Return : &amp;quot;Deck&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  // Retrieve the last child element of another element&lt;br /&gt;
  // Here, we are requesting for elements who has element with ID=1234 (Deck) as their parent&lt;br /&gt;
  // Note the use of &amp;quot;limit:1&amp;quot; which allows us to retrieve only 1 element.&lt;br /&gt;
  var first_card_on_deck_id = bga.getElement( { parent: 1234, limit:1 } );&lt;br /&gt;
  &lt;br /&gt;
  // You can also get nested properties such as the ids of the child elements of one element, or a custom property placed on the parent element&lt;br /&gt;
  var totem_places = bga.getElements( {tag:&#039;TOTEMZONE&#039;}, [&#039;id&#039;,&#039;childs:id&#039;,&#039;childs:tags&#039;,&#039;parent:id&#039;,&#039;parent:c_value&#039;] );&lt;br /&gt;
&lt;br /&gt;
=== bga.getElements( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Returns an object holding the properties of the elements matching the selector.&lt;br /&gt;
&lt;br /&gt;
  // Basic example: unselect all selected elements&lt;br /&gt;
  bga.removeStyle( bga.getElements( {tag: &#039;sbstyle_selected&#039;}), &#039;selected&#039; );&lt;br /&gt;
&lt;br /&gt;
=== bga.getElementsArray( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Returns an array of all elements matching the selector, holding the required properties.&lt;br /&gt;
&lt;br /&gt;
  // Basic example: get id of selected element&lt;br /&gt;
  var selected_tokens = bga.getElementsArray( {tag: &#039;sbstyle_selected&#039; } );&lt;br /&gt;
  var token_id = null;&lt;br /&gt;
  if (selected_tokens.length &amp;gt; 0) {&lt;br /&gt;
      token_id = selected_tokens[0];&lt;br /&gt;
  }&lt;br /&gt;
  return token_id;&lt;br /&gt;
&lt;br /&gt;
  // Classic example: get array of elements and iterate over it&lt;br /&gt;
  var all_cells = bga.getElementsArray( {tag: &#039;CELL&#039;}, [&#039;id&#039;,&#039;name&#039;,&#039;tags&#039;] );&lt;br /&gt;
  for (var i=0; i&amp;lt;all_cells.length; i++) {&lt;br /&gt;
     // ... process each cell ...&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Utility methods ==&lt;br /&gt;
&lt;br /&gt;
=== bga.isOn( element_id, parent_id ) ===&lt;br /&gt;
&lt;br /&gt;
Return true if &amp;quot;element_id&amp;quot; is a descendant of &amp;quot;parent_id&amp;quot; (ie : if element_id game element has been placed on parent_id game element).&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  if( bga.isOn( bga.getElementIfByName( &#039;Turn counter&#039; ), bga.getElementIfByName( &#039;Turn 6&#039; ) )&lt;br /&gt;
  {&lt;br /&gt;
     // Trigger game end&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Trigger most common game actions ==&lt;br /&gt;
&lt;br /&gt;
=== moveTo( $id, $target, $path=array() ) ===&lt;br /&gt;
&lt;br /&gt;
Move element to specified target id (eventually following path defined by an array of other element ids)&lt;br /&gt;
&lt;br /&gt;
The exact destination of element depends on target&#039;s &amp;quot;howToArrange&amp;quot; property (&amp;quot;How elements are arranged on it?&amp;quot; : spreaded/deck/...).&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.moveTo( bga.getElementIdByName( &#039;Turn counter&#039; ), bga.getElementIdByName( &#039;Turn 3&#039; ) );&lt;br /&gt;
&lt;br /&gt;
== Other functions ==&lt;br /&gt;
&lt;br /&gt;
=== pause( milliseconds ) ===&lt;br /&gt;
&lt;br /&gt;
Pause the client interface during a specified number of milliseconds.&lt;br /&gt;
&lt;br /&gt;
If you do not use bga.pause, all Sandbox game actions are executed immediately and synchronously.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.log( &amp;quot;1&amp;quot; );    // Will be displayed immediately on the log&lt;br /&gt;
  bga.pause( 3000 ); // pause during 3 seconds&lt;br /&gt;
  bga.log( &amp;quot;2&amp;quot; );    // Will be displayed after the 3 second on the log&lt;br /&gt;
  bga.log( &amp;quot;3&amp;quot; );    // Will be displayed right after the previous one, without delay.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Tips : if you want to execute several consecutive &amp;quot;moveTo&amp;quot;, you should &amp;quot;bga.pause&amp;quot; between them, otherwise your element will move directly to the final destination.&lt;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://sr.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=3037</id>
		<title>SandboxScripts</title>
		<link rel="alternate" type="text/html" href="https://sr.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=3037"/>
		<updated>2018-05-17T13:55:16Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Trigger most common game actions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This is the reference of functions you can call from your Sandbox scripts.&lt;br /&gt;
&lt;br /&gt;
= Javascript =&lt;br /&gt;
&lt;br /&gt;
BGA Sandbox scripts are written in Javascript.&lt;br /&gt;
&lt;br /&gt;
Using Javascript, you can write scripts to automate moves for your Sandbox games &amp;amp; provide rules reinforcement.&lt;br /&gt;
&lt;br /&gt;
Important : in the opposite of the most common usage of Javascript, Sandbox scripts are executed &#039;&#039;&#039;on server side&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
= BGA API =&lt;br /&gt;
&lt;br /&gt;
To interact with your BGA Sandbox game, we provide you an API.&lt;br /&gt;
&lt;br /&gt;
With this API, you can get properties values of game elements from the current game situation, modify them and/or trigger the game actions (ex : move this element here, flip this card, and so on).&lt;br /&gt;
&lt;br /&gt;
= Quick start =&lt;br /&gt;
&lt;br /&gt;
== Hello World Script ==&lt;br /&gt;
&lt;br /&gt;
From Sandbox editor &amp;quot;interface view&amp;quot; tab, select an element, and access to its property (top right icon).&lt;br /&gt;
&lt;br /&gt;
Go to &amp;quot;Scripts (advanced)&amp;quot; section.&lt;br /&gt;
&lt;br /&gt;
In front of &amp;quot;When this element is clicked&amp;quot;, enter &amp;quot;onMyClick&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Close the window. Go to &amp;quot;script view&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Enter the following :&lt;br /&gt;
&lt;br /&gt;
 function onMyClick( element_id )&lt;br /&gt;
 {&lt;br /&gt;
    bga.log(&amp;quot;Hello world! You just clicked on element &amp;quot; + element_id + &amp;quot;. Congrats!&amp;quot;);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Save &amp;amp; publish your project, starts a test session, click on the previous element : your message appears in the log on the right!&lt;br /&gt;
&lt;br /&gt;
== Top useful tips ==&lt;br /&gt;
&lt;br /&gt;
* You don&#039;t have to save&amp;amp;publish from the Sandbox editor for each modification of your script : each time you save your script (control+S), the script used for all test sessions is updated. Note that the production version on BGA is of course NOT updated until you explicitly save&amp;amp;publish again your project.&lt;br /&gt;
&lt;br /&gt;
* Alternatively to bga.log(), you can use bga.exit( &amp;quot;my message&amp;quot; ) to debug your script. With bga.exit, the script execution immediately stops and all previous game changes are cancelled, so this is very practical to try and retry an action until your script is fine.&lt;br /&gt;
&lt;br /&gt;
* We advise you to develop first a full playable version of the game without the scripts, and THEN to script it.&lt;br /&gt;
&lt;br /&gt;
* On Board Game Arena, players have come to expect fully implemented games with all rules enforced. So even if it&#039;s technically possible not to script the full game and to implement the game only partially, in most cases we&#039;ll publish only fully scripted games :)&lt;br /&gt;
&lt;br /&gt;
= Functions you can use in your Sandbox scripts=&lt;br /&gt;
&lt;br /&gt;
== Debugging functions ==&lt;br /&gt;
&lt;br /&gt;
=== bga.trace( txt / obj ) ===&lt;br /&gt;
&lt;br /&gt;
Write something immediately in the BGA log (on the right of the screen).&lt;br /&gt;
&lt;br /&gt;
This is the most practical way to debug your script :)&lt;br /&gt;
&lt;br /&gt;
Important : bga.trace is for debugging purpose only and won&#039;t be displayed on production.&lt;br /&gt;
&lt;br /&gt;
Note : you can also pass an object in parameter. This will dump the content of this object in the log.&lt;br /&gt;
&lt;br /&gt;
Note : in the opposite of bga.log, bga.trace is NOT cancelled if the game action failed (after a call to bga.cancel or bga.error). This makes bga.trace very practical to debug a game action that failed, and for this reason you should probably NEVER use bga.log for debugging purpose.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  // Example : write &amp;quot;Hello world&amp;quot; in the log&lt;br /&gt;
  bga.trace( &amp;quot;Hello world&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Example : dump an associative array in the log&lt;br /&gt;
  bga.trace( { mykey: &#039;myvalue&#039;, another_key: &#039;another_value&#039; } );&lt;br /&gt;
&lt;br /&gt;
=== bga.exit( txt / obj ) ===&lt;br /&gt;
&lt;br /&gt;
Stop the script immediately, display the &amp;quot;txt&amp;quot; messages and cancel (ie : rollback) on every previous API call except bga.trace :&lt;br /&gt;
&lt;br /&gt;
ALL previous BGA api call are canceled and there will be no visible changes on the interface (ex : no moves, no visible property changes, ...). Only &amp;quot;bga.trace&amp;quot; API commands are kept so you can debug.&lt;br /&gt;
&lt;br /&gt;
bga.exit is very practical when you want to repeat a game action again and again to debug it : with a call to bga.exit at the end of your script, you make sure that your game situation will be kept unchanged after each test.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.exit( &amp;quot;My script is stopped by this call&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Example with dumping a javascript variable&lt;br /&gt;
  bga.exit( my_variable_to_dump );&lt;br /&gt;
&lt;br /&gt;
== Cancelling a game action ==&lt;br /&gt;
&lt;br /&gt;
=== bga.cancel( txt ) ===&lt;br /&gt;
&lt;br /&gt;
This is the function to use when a player is doing something against game rules.&lt;br /&gt;
&lt;br /&gt;
The text message in parameter will be displayed to this player as a &amp;quot;red message&amp;quot;, so he/she can understand the rule.&lt;br /&gt;
&lt;br /&gt;
All previous BGA api call are cancelled, and there will be no visible changes on the interface.&lt;br /&gt;
&lt;br /&gt;
   // Example :&lt;br /&gt;
   bga.cancel( _(&amp;quot;You cannot move this piece here&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
Note : most of the time, you should wrap your text inside a _() translation marker to make this string translatable.&lt;br /&gt;
&lt;br /&gt;
=== bga.error( text ) ===&lt;br /&gt;
&lt;br /&gt;
This is the function to use when some unexpected error happens in your script.&lt;br /&gt;
&lt;br /&gt;
The text message will be displayed to user, with mention &amp;quot;Unexpected error&amp;quot;. The player will be incited to fill a bug report. The purpose of the message is to help you to identify the bug.&lt;br /&gt;
&lt;br /&gt;
All previous BGA api call are cancelled, and there will be no visible changes on the interface.&lt;br /&gt;
&lt;br /&gt;
   // Example :&lt;br /&gt;
   if( card_picked === null )&lt;br /&gt;
   {&lt;br /&gt;
       bga.error( &amp;quot;Cannot find a card to pick !&amp;quot; );&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
Note : you should NEVER wrap text inside bga.error with _() translation marker, because unexpected error should not be translate (so you can eventually recognize them when reported by players in bug report).&lt;br /&gt;
&lt;br /&gt;
== Game log (history) ==&lt;br /&gt;
&lt;br /&gt;
=== bga.log( txt, (optional) args ) ===&lt;br /&gt;
&lt;br /&gt;
Write something in the BGA log on the right.&lt;br /&gt;
&lt;br /&gt;
  // Example : simple log&lt;br /&gt;
  bga.log( _(&amp;quot;A new round starts&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
You may add arguments to your log, like this :&lt;br /&gt;
&lt;br /&gt;
  // Example: log with argument to display a card name.&lt;br /&gt;
  //          In this example, variable &amp;quot;event_name&amp;quot; is specified afterwards.&lt;br /&gt;
  //          Note that using this, game translators only have to translate one &amp;quot;Event XXX is triggered&amp;quot; string for all possible events.&lt;br /&gt;
  bga.log( _(&amp;quot;Event ${event_name} is triggered&amp;quot;), {  event_name: _( &amp;quot;Armageddon&amp;quot; ) } ) );&lt;br /&gt;
&lt;br /&gt;
Note that argument &amp;quot;player_name&amp;quot; is ALWAYS pre-set with the name of the current player, so you can use it immediately.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.log( _(&amp;quot;${player_name} draw a card from the deck&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
=== bga.speechBubble( target, text, (optional) args, (optional) delay, (optional) duration, (optional) size ) ===&lt;br /&gt;
&lt;br /&gt;
Display a &amp;quot;speech bubble&amp;quot;, attached to the specified target, containing the specified text.&lt;br /&gt;
&lt;br /&gt;
You can use &amp;quot;args&amp;quot; to customize text exactly like with bga.log.&lt;br /&gt;
&lt;br /&gt;
delay : milliseconds to wait before displaying the speech bubble (default : 0).&lt;br /&gt;
duration : how long to show the speech bubble in milliseconds (default : 3000).&lt;br /&gt;
size : size of the text in percent (default: 100)&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.speechBubble( _(&amp;quot;I play ${nbr} cards&amp;quot;), { nbr : 4 }, 0 );&lt;br /&gt;
  bga.speechBubble( _(&amp;quot;Good for you!&amp;quot;), { }, 2000 );&lt;br /&gt;
&lt;br /&gt;
=== bga.displayScoring( target, color, score ) ===&lt;br /&gt;
&lt;br /&gt;
Display an animated temporary &amp;quot;score number&amp;quot;, attached to the specified target.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;color&amp;quot; should be the color of the player who is scoring for that target.&lt;br /&gt;
&lt;br /&gt;
== Get / search game elements and their properties ==&lt;br /&gt;
&lt;br /&gt;
=== bga.getElement( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Allow you to retrieve informations about one game element specified using &amp;quot;selector&amp;quot; argument.&lt;br /&gt;
&lt;br /&gt;
Return null if no element is found.&lt;br /&gt;
&lt;br /&gt;
Note : getElement throw an error if several elements matches the selector. If you want to retrieve several elements, you should use &amp;quot;getElements&amp;quot; instead of &amp;quot;getElement&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The following examples are showing all the possible use of bga.getElement :&lt;br /&gt;
&lt;br /&gt;
  // Basic example :&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve the ID of a game element using its name (&amp;quot;Deck&amp;quot;)&lt;br /&gt;
  var deck_id = bga.getElement( { name: &amp;quot;Deck&amp;quot; } );&lt;br /&gt;
  // Return : 1234  &lt;br /&gt;
&lt;br /&gt;
  // Examples using &amp;quot;field&amp;quot; parameter :&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve a specific property from a game element using its name (&amp;quot;Deck&amp;quot;)&lt;br /&gt;
  var deck_id = bga.getElement( { name: &amp;quot;Deck&amp;quot; }, &#039;x&#039; );&lt;br /&gt;
  // Return : 20&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve several properties from the previous element&lt;br /&gt;
  var deck_properties = bga.getElement( { name: &amp;quot;Deck&amp;quot; }, [&#039;name&#039;,&#039;id&#039;,&#039;parent&#039;, &#039;x&#039;,&#039;y&#039;,&#039;canShuffle&#039;] );&lt;br /&gt;
  // Return : { name:&#039;Deck&#039;, id:1234, parent:4321, x: 20, y:50, canShuffle: true }&lt;br /&gt;
  &lt;br /&gt;
  // Note : as you can see, getElement returns:&lt;br /&gt;
  //        _ the element ID by default, or&lt;br /&gt;
  //        _ a single value if you request a single field, or&lt;br /&gt;
  //        _ an object if you request several fields&lt;br /&gt;
&lt;br /&gt;
  // Examples using different &amp;quot;selector&amp;quot; paramter&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve an element name from its id&lt;br /&gt;
  var deck_name = bga.getElement( { id: 1234 }, [&#039;name&#039;] );&lt;br /&gt;
  // Return : &amp;quot;Deck&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  // Retrieve the last child element of another element&lt;br /&gt;
  // Here, we are requesting for elements who has element with ID=1234 (Deck) as their parent&lt;br /&gt;
  // Note the use of &amp;quot;limit:1&amp;quot; which allows us to retrieve only 1 element.&lt;br /&gt;
  var first_card_on_deck_id = bga.getElement( { parent: 1234, limit:1 } );&lt;br /&gt;
  //&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== bga.getElements( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Returns an object holding the properties of the elements matching the selector.&lt;br /&gt;
&lt;br /&gt;
  // Basic example: unselect all selected elements&lt;br /&gt;
  bga.removeStyle( bga.getElements( {tag: &#039;sbstyle_selected&#039;}), &#039;selected&#039; );&lt;br /&gt;
&lt;br /&gt;
=== bga.getElementsArray( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Returns an array of all elements matching the selector, holding the required properties.&lt;br /&gt;
&lt;br /&gt;
  // Basic example: get id of selected element&lt;br /&gt;
  var selected_tokens = bga.getElementsArray( {tag: &#039;sbstyle_selected&#039; } );&lt;br /&gt;
  var token_id = null;&lt;br /&gt;
  if (selected_tokens.length &amp;gt; 0) {&lt;br /&gt;
      token_id = selected_tokens[0];&lt;br /&gt;
  }&lt;br /&gt;
  return token_id;&lt;br /&gt;
&lt;br /&gt;
  // Classic example: get array of elements and iterate over it&lt;br /&gt;
  var all_cells = bga.getElementsArray( {tag: &#039;CELL&#039;}, [&#039;id&#039;,&#039;name&#039;,&#039;tags&#039;] );&lt;br /&gt;
  for (var i=0; i&amp;lt;all_cells.length; i++) {&lt;br /&gt;
     // ... process each cell ...&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Utility methods ==&lt;br /&gt;
&lt;br /&gt;
=== bga.isOn( element_id, parent_id ) ===&lt;br /&gt;
&lt;br /&gt;
Return true if &amp;quot;element_id&amp;quot; is a descendant of &amp;quot;parent_id&amp;quot; (ie : if element_id game element has been placed on parent_id game element).&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  if( bga.isOn( bga.getElementIfByName( &#039;Turn counter&#039; ), bga.getElementIfByName( &#039;Turn 6&#039; ) )&lt;br /&gt;
  {&lt;br /&gt;
     // Trigger game end&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Trigger most common game actions ==&lt;br /&gt;
&lt;br /&gt;
=== moveTo( $id, $target, $path=array() ) ===&lt;br /&gt;
&lt;br /&gt;
Move element to specified target id (eventually following path defined by an array of other element ids)&lt;br /&gt;
&lt;br /&gt;
The exact destination of element depends on target&#039;s &amp;quot;howToArrange&amp;quot; property (&amp;quot;How elements are arranged on it?&amp;quot; : spreaded/deck/...).&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.moveTo( bga.getElementIdByName( &#039;Turn counter&#039; ), bga.getElementIdByName( &#039;Turn 3&#039; ) );&lt;br /&gt;
&lt;br /&gt;
== Other functions ==&lt;br /&gt;
&lt;br /&gt;
=== pause( milliseconds ) ===&lt;br /&gt;
&lt;br /&gt;
Pause the client interface during a specified number of milliseconds.&lt;br /&gt;
&lt;br /&gt;
If you do not use bga.pause, all Sandbox game actions are executed immediately and synchronously.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.log( &amp;quot;1&amp;quot; );    // Will be displayed immediately on the log&lt;br /&gt;
  bga.pause( 3000 ); // pause during 3 seconds&lt;br /&gt;
  bga.log( &amp;quot;2&amp;quot; );    // Will be displayed after the 3 second on the log&lt;br /&gt;
  bga.log( &amp;quot;3&amp;quot; );    // Will be displayed right after the previous one, without delay.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Tips : if you want to execute several consecutive &amp;quot;moveTo&amp;quot;, you should &amp;quot;bga.pause&amp;quot; between them, otherwise your element will move directly to the final destination.&lt;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://sr.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=3036</id>
		<title>SandboxScripts</title>
		<link rel="alternate" type="text/html" href="https://sr.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=3036"/>
		<updated>2018-05-17T13:54:57Z</updated>

		<summary type="html">&lt;p&gt;Een: /* moveElement( element_id, target_id ) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This is the reference of functions you can call from your Sandbox scripts.&lt;br /&gt;
&lt;br /&gt;
= Javascript =&lt;br /&gt;
&lt;br /&gt;
BGA Sandbox scripts are written in Javascript.&lt;br /&gt;
&lt;br /&gt;
Using Javascript, you can write scripts to automate moves for your Sandbox games &amp;amp; provide rules reinforcement.&lt;br /&gt;
&lt;br /&gt;
Important : in the opposite of the most common usage of Javascript, Sandbox scripts are executed &#039;&#039;&#039;on server side&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
= BGA API =&lt;br /&gt;
&lt;br /&gt;
To interact with your BGA Sandbox game, we provide you an API.&lt;br /&gt;
&lt;br /&gt;
With this API, you can get properties values of game elements from the current game situation, modify them and/or trigger the game actions (ex : move this element here, flip this card, and so on).&lt;br /&gt;
&lt;br /&gt;
= Quick start =&lt;br /&gt;
&lt;br /&gt;
== Hello World Script ==&lt;br /&gt;
&lt;br /&gt;
From Sandbox editor &amp;quot;interface view&amp;quot; tab, select an element, and access to its property (top right icon).&lt;br /&gt;
&lt;br /&gt;
Go to &amp;quot;Scripts (advanced)&amp;quot; section.&lt;br /&gt;
&lt;br /&gt;
In front of &amp;quot;When this element is clicked&amp;quot;, enter &amp;quot;onMyClick&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Close the window. Go to &amp;quot;script view&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Enter the following :&lt;br /&gt;
&lt;br /&gt;
 function onMyClick( element_id )&lt;br /&gt;
 {&lt;br /&gt;
    bga.log(&amp;quot;Hello world! You just clicked on element &amp;quot; + element_id + &amp;quot;. Congrats!&amp;quot;);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Save &amp;amp; publish your project, starts a test session, click on the previous element : your message appears in the log on the right!&lt;br /&gt;
&lt;br /&gt;
== Top useful tips ==&lt;br /&gt;
&lt;br /&gt;
* You don&#039;t have to save&amp;amp;publish from the Sandbox editor for each modification of your script : each time you save your script (control+S), the script used for all test sessions is updated. Note that the production version on BGA is of course NOT updated until you explicitly save&amp;amp;publish again your project.&lt;br /&gt;
&lt;br /&gt;
* Alternatively to bga.log(), you can use bga.exit( &amp;quot;my message&amp;quot; ) to debug your script. With bga.exit, the script execution immediately stops and all previous game changes are cancelled, so this is very practical to try and retry an action until your script is fine.&lt;br /&gt;
&lt;br /&gt;
* We advise you to develop first a full playable version of the game without the scripts, and THEN to script it.&lt;br /&gt;
&lt;br /&gt;
* On Board Game Arena, players have come to expect fully implemented games with all rules enforced. So even if it&#039;s technically possible not to script the full game and to implement the game only partially, in most cases we&#039;ll publish only fully scripted games :)&lt;br /&gt;
&lt;br /&gt;
= Functions you can use in your Sandbox scripts=&lt;br /&gt;
&lt;br /&gt;
== Debugging functions ==&lt;br /&gt;
&lt;br /&gt;
=== bga.trace( txt / obj ) ===&lt;br /&gt;
&lt;br /&gt;
Write something immediately in the BGA log (on the right of the screen).&lt;br /&gt;
&lt;br /&gt;
This is the most practical way to debug your script :)&lt;br /&gt;
&lt;br /&gt;
Important : bga.trace is for debugging purpose only and won&#039;t be displayed on production.&lt;br /&gt;
&lt;br /&gt;
Note : you can also pass an object in parameter. This will dump the content of this object in the log.&lt;br /&gt;
&lt;br /&gt;
Note : in the opposite of bga.log, bga.trace is NOT cancelled if the game action failed (after a call to bga.cancel or bga.error). This makes bga.trace very practical to debug a game action that failed, and for this reason you should probably NEVER use bga.log for debugging purpose.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  // Example : write &amp;quot;Hello world&amp;quot; in the log&lt;br /&gt;
  bga.trace( &amp;quot;Hello world&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Example : dump an associative array in the log&lt;br /&gt;
  bga.trace( { mykey: &#039;myvalue&#039;, another_key: &#039;another_value&#039; } );&lt;br /&gt;
&lt;br /&gt;
=== bga.exit( txt / obj ) ===&lt;br /&gt;
&lt;br /&gt;
Stop the script immediately, display the &amp;quot;txt&amp;quot; messages and cancel (ie : rollback) on every previous API call except bga.trace :&lt;br /&gt;
&lt;br /&gt;
ALL previous BGA api call are canceled and there will be no visible changes on the interface (ex : no moves, no visible property changes, ...). Only &amp;quot;bga.trace&amp;quot; API commands are kept so you can debug.&lt;br /&gt;
&lt;br /&gt;
bga.exit is very practical when you want to repeat a game action again and again to debug it : with a call to bga.exit at the end of your script, you make sure that your game situation will be kept unchanged after each test.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.exit( &amp;quot;My script is stopped by this call&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Example with dumping a javascript variable&lt;br /&gt;
  bga.exit( my_variable_to_dump );&lt;br /&gt;
&lt;br /&gt;
== Cancelling a game action ==&lt;br /&gt;
&lt;br /&gt;
=== bga.cancel( txt ) ===&lt;br /&gt;
&lt;br /&gt;
This is the function to use when a player is doing something against game rules.&lt;br /&gt;
&lt;br /&gt;
The text message in parameter will be displayed to this player as a &amp;quot;red message&amp;quot;, so he/she can understand the rule.&lt;br /&gt;
&lt;br /&gt;
All previous BGA api call are cancelled, and there will be no visible changes on the interface.&lt;br /&gt;
&lt;br /&gt;
   // Example :&lt;br /&gt;
   bga.cancel( _(&amp;quot;You cannot move this piece here&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
Note : most of the time, you should wrap your text inside a _() translation marker to make this string translatable.&lt;br /&gt;
&lt;br /&gt;
=== bga.error( text ) ===&lt;br /&gt;
&lt;br /&gt;
This is the function to use when some unexpected error happens in your script.&lt;br /&gt;
&lt;br /&gt;
The text message will be displayed to user, with mention &amp;quot;Unexpected error&amp;quot;. The player will be incited to fill a bug report. The purpose of the message is to help you to identify the bug.&lt;br /&gt;
&lt;br /&gt;
All previous BGA api call are cancelled, and there will be no visible changes on the interface.&lt;br /&gt;
&lt;br /&gt;
   // Example :&lt;br /&gt;
   if( card_picked === null )&lt;br /&gt;
   {&lt;br /&gt;
       bga.error( &amp;quot;Cannot find a card to pick !&amp;quot; );&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
Note : you should NEVER wrap text inside bga.error with _() translation marker, because unexpected error should not be translate (so you can eventually recognize them when reported by players in bug report).&lt;br /&gt;
&lt;br /&gt;
== Game log (history) ==&lt;br /&gt;
&lt;br /&gt;
=== bga.log( txt, (optional) args ) ===&lt;br /&gt;
&lt;br /&gt;
Write something in the BGA log on the right.&lt;br /&gt;
&lt;br /&gt;
  // Example : simple log&lt;br /&gt;
  bga.log( _(&amp;quot;A new round starts&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
You may add arguments to your log, like this :&lt;br /&gt;
&lt;br /&gt;
  // Example: log with argument to display a card name.&lt;br /&gt;
  //          In this example, variable &amp;quot;event_name&amp;quot; is specified afterwards.&lt;br /&gt;
  //          Note that using this, game translators only have to translate one &amp;quot;Event XXX is triggered&amp;quot; string for all possible events.&lt;br /&gt;
  bga.log( _(&amp;quot;Event ${event_name} is triggered&amp;quot;), {  event_name: _( &amp;quot;Armageddon&amp;quot; ) } ) );&lt;br /&gt;
&lt;br /&gt;
Note that argument &amp;quot;player_name&amp;quot; is ALWAYS pre-set with the name of the current player, so you can use it immediately.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.log( _(&amp;quot;${player_name} draw a card from the deck&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
=== bga.speechBubble( target, text, (optional) args, (optional) delay, (optional) duration, (optional) size ) ===&lt;br /&gt;
&lt;br /&gt;
Display a &amp;quot;speech bubble&amp;quot;, attached to the specified target, containing the specified text.&lt;br /&gt;
&lt;br /&gt;
You can use &amp;quot;args&amp;quot; to customize text exactly like with bga.log.&lt;br /&gt;
&lt;br /&gt;
delay : milliseconds to wait before displaying the speech bubble (default : 0).&lt;br /&gt;
duration : how long to show the speech bubble in milliseconds (default : 3000).&lt;br /&gt;
size : size of the text in percent (default: 100)&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.speechBubble( _(&amp;quot;I play ${nbr} cards&amp;quot;), { nbr : 4 }, 0 );&lt;br /&gt;
  bga.speechBubble( _(&amp;quot;Good for you!&amp;quot;), { }, 2000 );&lt;br /&gt;
&lt;br /&gt;
=== bga.displayScoring( target, color, score ) ===&lt;br /&gt;
&lt;br /&gt;
Display an animated temporary &amp;quot;score number&amp;quot;, attached to the specified target.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;color&amp;quot; should be the color of the player who is scoring for that target.&lt;br /&gt;
&lt;br /&gt;
== Get / search game elements and their properties ==&lt;br /&gt;
&lt;br /&gt;
=== bga.getElement( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Allow you to retrieve informations about one game element specified using &amp;quot;selector&amp;quot; argument.&lt;br /&gt;
&lt;br /&gt;
Return null if no element is found.&lt;br /&gt;
&lt;br /&gt;
Note : getElement throw an error if several elements matches the selector. If you want to retrieve several elements, you should use &amp;quot;getElements&amp;quot; instead of &amp;quot;getElement&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The following examples are showing all the possible use of bga.getElement :&lt;br /&gt;
&lt;br /&gt;
  // Basic example :&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve the ID of a game element using its name (&amp;quot;Deck&amp;quot;)&lt;br /&gt;
  var deck_id = bga.getElement( { name: &amp;quot;Deck&amp;quot; } );&lt;br /&gt;
  // Return : 1234  &lt;br /&gt;
&lt;br /&gt;
  // Examples using &amp;quot;field&amp;quot; parameter :&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve a specific property from a game element using its name (&amp;quot;Deck&amp;quot;)&lt;br /&gt;
  var deck_id = bga.getElement( { name: &amp;quot;Deck&amp;quot; }, &#039;x&#039; );&lt;br /&gt;
  // Return : 20&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve several properties from the previous element&lt;br /&gt;
  var deck_properties = bga.getElement( { name: &amp;quot;Deck&amp;quot; }, [&#039;name&#039;,&#039;id&#039;,&#039;parent&#039;, &#039;x&#039;,&#039;y&#039;,&#039;canShuffle&#039;] );&lt;br /&gt;
  // Return : { name:&#039;Deck&#039;, id:1234, parent:4321, x: 20, y:50, canShuffle: true }&lt;br /&gt;
  &lt;br /&gt;
  // Note : as you can see, getElement returns:&lt;br /&gt;
  //        _ the element ID by default, or&lt;br /&gt;
  //        _ a single value if you request a single field, or&lt;br /&gt;
  //        _ an object if you request several fields&lt;br /&gt;
&lt;br /&gt;
  // Examples using different &amp;quot;selector&amp;quot; paramter&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve an element name from its id&lt;br /&gt;
  var deck_name = bga.getElement( { id: 1234 }, [&#039;name&#039;] );&lt;br /&gt;
  // Return : &amp;quot;Deck&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  // Retrieve the last child element of another element&lt;br /&gt;
  // Here, we are requesting for elements who has element with ID=1234 (Deck) as their parent&lt;br /&gt;
  // Note the use of &amp;quot;limit:1&amp;quot; which allows us to retrieve only 1 element.&lt;br /&gt;
  var first_card_on_deck_id = bga.getElement( { parent: 1234, limit:1 } );&lt;br /&gt;
  //&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== bga.getElements( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Returns an object holding the properties of the elements matching the selector.&lt;br /&gt;
&lt;br /&gt;
  // Basic example: unselect all selected elements&lt;br /&gt;
  bga.removeStyle( bga.getElements( {tag: &#039;sbstyle_selected&#039;}), &#039;selected&#039; );&lt;br /&gt;
&lt;br /&gt;
=== bga.getElementsArray( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Returns an array of all elements matching the selector, holding the required properties.&lt;br /&gt;
&lt;br /&gt;
  // Basic example: get id of selected element&lt;br /&gt;
  var selected_tokens = bga.getElementsArray( {tag: &#039;sbstyle_selected&#039; } );&lt;br /&gt;
  var token_id = null;&lt;br /&gt;
  if (selected_tokens.length &amp;gt; 0) {&lt;br /&gt;
      token_id = selected_tokens[0];&lt;br /&gt;
  }&lt;br /&gt;
  return token_id;&lt;br /&gt;
&lt;br /&gt;
  // Classic example: get array of elements and iterate over it&lt;br /&gt;
  var all_cells = bga.getElementsArray( {tag: &#039;CELL&#039;}, [&#039;id&#039;,&#039;name&#039;,&#039;tags&#039;] );&lt;br /&gt;
  for (var i=0; i&amp;lt;all_cells.length; i++) {&lt;br /&gt;
     // ... process each cell ...&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Utility methods ==&lt;br /&gt;
&lt;br /&gt;
=== bga.isOn( element_id, parent_id ) ===&lt;br /&gt;
&lt;br /&gt;
Return true if &amp;quot;element_id&amp;quot; is a descendant of &amp;quot;parent_id&amp;quot; (ie : if element_id game element has been placed on parent_id game element).&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  if( bga.isOn( bga.getElementIfByName( &#039;Turn counter&#039; ), bga.getElementIfByName( &#039;Turn 6&#039; ) )&lt;br /&gt;
  {&lt;br /&gt;
     // Trigger game end&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Trigger most common game actions ==&lt;br /&gt;
&lt;br /&gt;
===moveTo($id, $target, $path=array() )===&lt;br /&gt;
&lt;br /&gt;
Move element to specified target id (eventually following path defined by an array of other element ids)&lt;br /&gt;
&lt;br /&gt;
The exact destination of element depends on target&#039;s &amp;quot;howToArrange&amp;quot; property (&amp;quot;How elements are arranged on it?&amp;quot; : spreaded/deck/...).&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.moveTo( bga.getElementIdByName( &#039;Turn counter&#039; ), bga.getElementIdByName( &#039;Turn 3&#039; ) );&lt;br /&gt;
&lt;br /&gt;
== Other functions ==&lt;br /&gt;
&lt;br /&gt;
=== pause( milliseconds ) ===&lt;br /&gt;
&lt;br /&gt;
Pause the client interface during a specified number of milliseconds.&lt;br /&gt;
&lt;br /&gt;
If you do not use bga.pause, all Sandbox game actions are executed immediately and synchronously.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.log( &amp;quot;1&amp;quot; );    // Will be displayed immediately on the log&lt;br /&gt;
  bga.pause( 3000 ); // pause during 3 seconds&lt;br /&gt;
  bga.log( &amp;quot;2&amp;quot; );    // Will be displayed after the 3 second on the log&lt;br /&gt;
  bga.log( &amp;quot;3&amp;quot; );    // Will be displayed right after the previous one, without delay.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Tips : if you want to execute several consecutive &amp;quot;moveTo&amp;quot;, you should &amp;quot;bga.pause&amp;quot; between them, otherwise your element will move directly to the final destination.&lt;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://sr.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=3035</id>
		<title>SandboxScripts</title>
		<link rel="alternate" type="text/html" href="https://sr.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=3035"/>
		<updated>2018-05-17T13:45:35Z</updated>

		<summary type="html">&lt;p&gt;Een: /* bga.displayScoring( target, color, score ) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This is the reference of functions you can call from your Sandbox scripts.&lt;br /&gt;
&lt;br /&gt;
= Javascript =&lt;br /&gt;
&lt;br /&gt;
BGA Sandbox scripts are written in Javascript.&lt;br /&gt;
&lt;br /&gt;
Using Javascript, you can write scripts to automate moves for your Sandbox games &amp;amp; provide rules reinforcement.&lt;br /&gt;
&lt;br /&gt;
Important : in the opposite of the most common usage of Javascript, Sandbox scripts are executed &#039;&#039;&#039;on server side&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
= BGA API =&lt;br /&gt;
&lt;br /&gt;
To interact with your BGA Sandbox game, we provide you an API.&lt;br /&gt;
&lt;br /&gt;
With this API, you can get properties values of game elements from the current game situation, modify them and/or trigger the game actions (ex : move this element here, flip this card, and so on).&lt;br /&gt;
&lt;br /&gt;
= Quick start =&lt;br /&gt;
&lt;br /&gt;
== Hello World Script ==&lt;br /&gt;
&lt;br /&gt;
From Sandbox editor &amp;quot;interface view&amp;quot; tab, select an element, and access to its property (top right icon).&lt;br /&gt;
&lt;br /&gt;
Go to &amp;quot;Scripts (advanced)&amp;quot; section.&lt;br /&gt;
&lt;br /&gt;
In front of &amp;quot;When this element is clicked&amp;quot;, enter &amp;quot;onMyClick&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Close the window. Go to &amp;quot;script view&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Enter the following :&lt;br /&gt;
&lt;br /&gt;
 function onMyClick( element_id )&lt;br /&gt;
 {&lt;br /&gt;
    bga.log(&amp;quot;Hello world! You just clicked on element &amp;quot; + element_id + &amp;quot;. Congrats!&amp;quot;);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Save &amp;amp; publish your project, starts a test session, click on the previous element : your message appears in the log on the right!&lt;br /&gt;
&lt;br /&gt;
== Top useful tips ==&lt;br /&gt;
&lt;br /&gt;
* You don&#039;t have to save&amp;amp;publish from the Sandbox editor for each modification of your script : each time you save your script (control+S), the script used for all test sessions is updated. Note that the production version on BGA is of course NOT updated until you explicitly save&amp;amp;publish again your project.&lt;br /&gt;
&lt;br /&gt;
* Alternatively to bga.log(), you can use bga.exit( &amp;quot;my message&amp;quot; ) to debug your script. With bga.exit, the script execution immediately stops and all previous game changes are cancelled, so this is very practical to try and retry an action until your script is fine.&lt;br /&gt;
&lt;br /&gt;
* We advise you to develop first a full playable version of the game without the scripts, and THEN to script it.&lt;br /&gt;
&lt;br /&gt;
* On Board Game Arena, players have come to expect fully implemented games with all rules enforced. So even if it&#039;s technically possible not to script the full game and to implement the game only partially, in most cases we&#039;ll publish only fully scripted games :)&lt;br /&gt;
&lt;br /&gt;
= Functions you can use in your Sandbox scripts=&lt;br /&gt;
&lt;br /&gt;
== Debugging functions ==&lt;br /&gt;
&lt;br /&gt;
=== bga.trace( txt / obj ) ===&lt;br /&gt;
&lt;br /&gt;
Write something immediately in the BGA log (on the right of the screen).&lt;br /&gt;
&lt;br /&gt;
This is the most practical way to debug your script :)&lt;br /&gt;
&lt;br /&gt;
Important : bga.trace is for debugging purpose only and won&#039;t be displayed on production.&lt;br /&gt;
&lt;br /&gt;
Note : you can also pass an object in parameter. This will dump the content of this object in the log.&lt;br /&gt;
&lt;br /&gt;
Note : in the opposite of bga.log, bga.trace is NOT cancelled if the game action failed (after a call to bga.cancel or bga.error). This makes bga.trace very practical to debug a game action that failed, and for this reason you should probably NEVER use bga.log for debugging purpose.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  // Example : write &amp;quot;Hello world&amp;quot; in the log&lt;br /&gt;
  bga.trace( &amp;quot;Hello world&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Example : dump an associative array in the log&lt;br /&gt;
  bga.trace( { mykey: &#039;myvalue&#039;, another_key: &#039;another_value&#039; } );&lt;br /&gt;
&lt;br /&gt;
=== bga.exit( txt / obj ) ===&lt;br /&gt;
&lt;br /&gt;
Stop the script immediately, display the &amp;quot;txt&amp;quot; messages and cancel (ie : rollback) on every previous API call except bga.trace :&lt;br /&gt;
&lt;br /&gt;
ALL previous BGA api call are canceled and there will be no visible changes on the interface (ex : no moves, no visible property changes, ...). Only &amp;quot;bga.trace&amp;quot; API commands are kept so you can debug.&lt;br /&gt;
&lt;br /&gt;
bga.exit is very practical when you want to repeat a game action again and again to debug it : with a call to bga.exit at the end of your script, you make sure that your game situation will be kept unchanged after each test.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.exit( &amp;quot;My script is stopped by this call&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Example with dumping a javascript variable&lt;br /&gt;
  bga.exit( my_variable_to_dump );&lt;br /&gt;
&lt;br /&gt;
== Cancelling a game action ==&lt;br /&gt;
&lt;br /&gt;
=== bga.cancel( txt ) ===&lt;br /&gt;
&lt;br /&gt;
This is the function to use when a player is doing something against game rules.&lt;br /&gt;
&lt;br /&gt;
The text message in parameter will be displayed to this player as a &amp;quot;red message&amp;quot;, so he/she can understand the rule.&lt;br /&gt;
&lt;br /&gt;
All previous BGA api call are cancelled, and there will be no visible changes on the interface.&lt;br /&gt;
&lt;br /&gt;
   // Example :&lt;br /&gt;
   bga.cancel( _(&amp;quot;You cannot move this piece here&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
Note : most of the time, you should wrap your text inside a _() translation marker to make this string translatable.&lt;br /&gt;
&lt;br /&gt;
=== bga.error( text ) ===&lt;br /&gt;
&lt;br /&gt;
This is the function to use when some unexpected error happens in your script.&lt;br /&gt;
&lt;br /&gt;
The text message will be displayed to user, with mention &amp;quot;Unexpected error&amp;quot;. The player will be incited to fill a bug report. The purpose of the message is to help you to identify the bug.&lt;br /&gt;
&lt;br /&gt;
All previous BGA api call are cancelled, and there will be no visible changes on the interface.&lt;br /&gt;
&lt;br /&gt;
   // Example :&lt;br /&gt;
   if( card_picked === null )&lt;br /&gt;
   {&lt;br /&gt;
       bga.error( &amp;quot;Cannot find a card to pick !&amp;quot; );&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
Note : you should NEVER wrap text inside bga.error with _() translation marker, because unexpected error should not be translate (so you can eventually recognize them when reported by players in bug report).&lt;br /&gt;
&lt;br /&gt;
== Game log (history) ==&lt;br /&gt;
&lt;br /&gt;
=== bga.log( txt, (optional) args ) ===&lt;br /&gt;
&lt;br /&gt;
Write something in the BGA log on the right.&lt;br /&gt;
&lt;br /&gt;
  // Example : simple log&lt;br /&gt;
  bga.log( _(&amp;quot;A new round starts&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
You may add arguments to your log, like this :&lt;br /&gt;
&lt;br /&gt;
  // Example: log with argument to display a card name.&lt;br /&gt;
  //          In this example, variable &amp;quot;event_name&amp;quot; is specified afterwards.&lt;br /&gt;
  //          Note that using this, game translators only have to translate one &amp;quot;Event XXX is triggered&amp;quot; string for all possible events.&lt;br /&gt;
  bga.log( _(&amp;quot;Event ${event_name} is triggered&amp;quot;), {  event_name: _( &amp;quot;Armageddon&amp;quot; ) } ) );&lt;br /&gt;
&lt;br /&gt;
Note that argument &amp;quot;player_name&amp;quot; is ALWAYS pre-set with the name of the current player, so you can use it immediately.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.log( _(&amp;quot;${player_name} draw a card from the deck&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
=== bga.speechBubble( target, text, (optional) args, (optional) delay, (optional) duration, (optional) size ) ===&lt;br /&gt;
&lt;br /&gt;
Display a &amp;quot;speech bubble&amp;quot;, attached to the specified target, containing the specified text.&lt;br /&gt;
&lt;br /&gt;
You can use &amp;quot;args&amp;quot; to customize text exactly like with bga.log.&lt;br /&gt;
&lt;br /&gt;
delay : milliseconds to wait before displaying the speech bubble (default : 0).&lt;br /&gt;
duration : how long to show the speech bubble in milliseconds (default : 3000).&lt;br /&gt;
size : size of the text in percent (default: 100)&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.speechBubble( _(&amp;quot;I play ${nbr} cards&amp;quot;), { nbr : 4 }, 0 );&lt;br /&gt;
  bga.speechBubble( _(&amp;quot;Good for you!&amp;quot;), { }, 2000 );&lt;br /&gt;
&lt;br /&gt;
=== bga.displayScoring( target, color, score ) ===&lt;br /&gt;
&lt;br /&gt;
Display an animated temporary &amp;quot;score number&amp;quot;, attached to the specified target.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;color&amp;quot; should be the color of the player who is scoring for that target.&lt;br /&gt;
&lt;br /&gt;
== Get / search game elements and their properties ==&lt;br /&gt;
&lt;br /&gt;
=== bga.getElement( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Allow you to retrieve informations about one game element specified using &amp;quot;selector&amp;quot; argument.&lt;br /&gt;
&lt;br /&gt;
Return null if no element is found.&lt;br /&gt;
&lt;br /&gt;
Note : getElement throw an error if several elements matches the selector. If you want to retrieve several elements, you should use &amp;quot;getElements&amp;quot; instead of &amp;quot;getElement&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The following examples are showing all the possible use of bga.getElement :&lt;br /&gt;
&lt;br /&gt;
  // Basic example :&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve the ID of a game element using its name (&amp;quot;Deck&amp;quot;)&lt;br /&gt;
  var deck_id = bga.getElement( { name: &amp;quot;Deck&amp;quot; } );&lt;br /&gt;
  // Return : 1234  &lt;br /&gt;
&lt;br /&gt;
  // Examples using &amp;quot;field&amp;quot; parameter :&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve a specific property from a game element using its name (&amp;quot;Deck&amp;quot;)&lt;br /&gt;
  var deck_id = bga.getElement( { name: &amp;quot;Deck&amp;quot; }, &#039;x&#039; );&lt;br /&gt;
  // Return : 20&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve several properties from the previous element&lt;br /&gt;
  var deck_properties = bga.getElement( { name: &amp;quot;Deck&amp;quot; }, [&#039;name&#039;,&#039;id&#039;,&#039;parent&#039;, &#039;x&#039;,&#039;y&#039;,&#039;canShuffle&#039;] );&lt;br /&gt;
  // Return : { name:&#039;Deck&#039;, id:1234, parent:4321, x: 20, y:50, canShuffle: true }&lt;br /&gt;
  &lt;br /&gt;
  // Note : as you can see, getElement returns:&lt;br /&gt;
  //        _ the element ID by default, or&lt;br /&gt;
  //        _ a single value if you request a single field, or&lt;br /&gt;
  //        _ an object if you request several fields&lt;br /&gt;
&lt;br /&gt;
  // Examples using different &amp;quot;selector&amp;quot; paramter&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve an element name from its id&lt;br /&gt;
  var deck_name = bga.getElement( { id: 1234 }, [&#039;name&#039;] );&lt;br /&gt;
  // Return : &amp;quot;Deck&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  // Retrieve the last child element of another element&lt;br /&gt;
  // Here, we are requesting for elements who has element with ID=1234 (Deck) as their parent&lt;br /&gt;
  // Note the use of &amp;quot;limit:1&amp;quot; which allows us to retrieve only 1 element.&lt;br /&gt;
  var first_card_on_deck_id = bga.getElement( { parent: 1234, limit:1 } );&lt;br /&gt;
  //&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== bga.getElements( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Returns an object holding the properties of the elements matching the selector.&lt;br /&gt;
&lt;br /&gt;
  // Basic example: unselect all selected elements&lt;br /&gt;
  bga.removeStyle( bga.getElements( {tag: &#039;sbstyle_selected&#039;}), &#039;selected&#039; );&lt;br /&gt;
&lt;br /&gt;
=== bga.getElementsArray( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Returns an array of all elements matching the selector, holding the required properties.&lt;br /&gt;
&lt;br /&gt;
  // Basic example: get id of selected element&lt;br /&gt;
  var selected_tokens = bga.getElementsArray( {tag: &#039;sbstyle_selected&#039; } );&lt;br /&gt;
  var token_id = null;&lt;br /&gt;
  if (selected_tokens.length &amp;gt; 0) {&lt;br /&gt;
      token_id = selected_tokens[0];&lt;br /&gt;
  }&lt;br /&gt;
  return token_id;&lt;br /&gt;
&lt;br /&gt;
  // Classic example: get array of elements and iterate over it&lt;br /&gt;
  var all_cells = bga.getElementsArray( {tag: &#039;CELL&#039;}, [&#039;id&#039;,&#039;name&#039;,&#039;tags&#039;] );&lt;br /&gt;
  for (var i=0; i&amp;lt;all_cells.length; i++) {&lt;br /&gt;
     // ... process each cell ...&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Utility methods ==&lt;br /&gt;
&lt;br /&gt;
=== bga.isOn( element_id, parent_id ) ===&lt;br /&gt;
&lt;br /&gt;
Return true if &amp;quot;element_id&amp;quot; is a descendant of &amp;quot;parent_id&amp;quot; (ie : if element_id game element has been placed on parent_id game element).&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  if( bga.isOn( bga.getElementIfByName( &#039;Turn counter&#039; ), bga.getElementIfByName( &#039;Turn 6&#039; ) )&lt;br /&gt;
  {&lt;br /&gt;
     // Trigger game end&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Trigger most common game actions ==&lt;br /&gt;
&lt;br /&gt;
===moveElement( element_id, target_id )===&lt;br /&gt;
&lt;br /&gt;
Move element to specified target id.&lt;br /&gt;
&lt;br /&gt;
The exact destination of element depends on target &amp;quot;howToArrange&amp;quot; property (&amp;quot;How elements are arranged on it?&amp;quot; : spreaded/deck/...).&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.moveElement( bga.getElementIdByName( &#039;Turn counter&#039; ), bga.getElementIdByName( &#039;Turn 3&#039; ) );&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Other functions ==&lt;br /&gt;
&lt;br /&gt;
=== pause( milliseconds ) ===&lt;br /&gt;
&lt;br /&gt;
Pause the client interface during a specified number of milliseconds.&lt;br /&gt;
&lt;br /&gt;
If you do not use bga.pause, all Sandbox game actions are executed immediately and synchronously.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.log( &amp;quot;1&amp;quot; );    // Will be displayed immediately on the log&lt;br /&gt;
  bga.pause( 3000 ); // pause during 3 seconds&lt;br /&gt;
  bga.log( &amp;quot;2&amp;quot; );    // Will be displayed after the 3 second on the log&lt;br /&gt;
  bga.log( &amp;quot;3&amp;quot; );    // Will be displayed right after the previous one, without delay.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Tips : if you want to execute several consecutive &amp;quot;moveTo&amp;quot;, you should &amp;quot;bga.pause&amp;quot; between them, otherwise your element will move directly to the final destination.&lt;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://sr.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=3034</id>
		<title>SandboxScripts</title>
		<link rel="alternate" type="text/html" href="https://sr.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=3034"/>
		<updated>2018-05-17T13:45:25Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Game log (history) */  displayScoring&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This is the reference of functions you can call from your Sandbox scripts.&lt;br /&gt;
&lt;br /&gt;
= Javascript =&lt;br /&gt;
&lt;br /&gt;
BGA Sandbox scripts are written in Javascript.&lt;br /&gt;
&lt;br /&gt;
Using Javascript, you can write scripts to automate moves for your Sandbox games &amp;amp; provide rules reinforcement.&lt;br /&gt;
&lt;br /&gt;
Important : in the opposite of the most common usage of Javascript, Sandbox scripts are executed &#039;&#039;&#039;on server side&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
= BGA API =&lt;br /&gt;
&lt;br /&gt;
To interact with your BGA Sandbox game, we provide you an API.&lt;br /&gt;
&lt;br /&gt;
With this API, you can get properties values of game elements from the current game situation, modify them and/or trigger the game actions (ex : move this element here, flip this card, and so on).&lt;br /&gt;
&lt;br /&gt;
= Quick start =&lt;br /&gt;
&lt;br /&gt;
== Hello World Script ==&lt;br /&gt;
&lt;br /&gt;
From Sandbox editor &amp;quot;interface view&amp;quot; tab, select an element, and access to its property (top right icon).&lt;br /&gt;
&lt;br /&gt;
Go to &amp;quot;Scripts (advanced)&amp;quot; section.&lt;br /&gt;
&lt;br /&gt;
In front of &amp;quot;When this element is clicked&amp;quot;, enter &amp;quot;onMyClick&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Close the window. Go to &amp;quot;script view&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Enter the following :&lt;br /&gt;
&lt;br /&gt;
 function onMyClick( element_id )&lt;br /&gt;
 {&lt;br /&gt;
    bga.log(&amp;quot;Hello world! You just clicked on element &amp;quot; + element_id + &amp;quot;. Congrats!&amp;quot;);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Save &amp;amp; publish your project, starts a test session, click on the previous element : your message appears in the log on the right!&lt;br /&gt;
&lt;br /&gt;
== Top useful tips ==&lt;br /&gt;
&lt;br /&gt;
* You don&#039;t have to save&amp;amp;publish from the Sandbox editor for each modification of your script : each time you save your script (control+S), the script used for all test sessions is updated. Note that the production version on BGA is of course NOT updated until you explicitly save&amp;amp;publish again your project.&lt;br /&gt;
&lt;br /&gt;
* Alternatively to bga.log(), you can use bga.exit( &amp;quot;my message&amp;quot; ) to debug your script. With bga.exit, the script execution immediately stops and all previous game changes are cancelled, so this is very practical to try and retry an action until your script is fine.&lt;br /&gt;
&lt;br /&gt;
* We advise you to develop first a full playable version of the game without the scripts, and THEN to script it.&lt;br /&gt;
&lt;br /&gt;
* On Board Game Arena, players have come to expect fully implemented games with all rules enforced. So even if it&#039;s technically possible not to script the full game and to implement the game only partially, in most cases we&#039;ll publish only fully scripted games :)&lt;br /&gt;
&lt;br /&gt;
= Functions you can use in your Sandbox scripts=&lt;br /&gt;
&lt;br /&gt;
== Debugging functions ==&lt;br /&gt;
&lt;br /&gt;
=== bga.trace( txt / obj ) ===&lt;br /&gt;
&lt;br /&gt;
Write something immediately in the BGA log (on the right of the screen).&lt;br /&gt;
&lt;br /&gt;
This is the most practical way to debug your script :)&lt;br /&gt;
&lt;br /&gt;
Important : bga.trace is for debugging purpose only and won&#039;t be displayed on production.&lt;br /&gt;
&lt;br /&gt;
Note : you can also pass an object in parameter. This will dump the content of this object in the log.&lt;br /&gt;
&lt;br /&gt;
Note : in the opposite of bga.log, bga.trace is NOT cancelled if the game action failed (after a call to bga.cancel or bga.error). This makes bga.trace very practical to debug a game action that failed, and for this reason you should probably NEVER use bga.log for debugging purpose.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  // Example : write &amp;quot;Hello world&amp;quot; in the log&lt;br /&gt;
  bga.trace( &amp;quot;Hello world&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Example : dump an associative array in the log&lt;br /&gt;
  bga.trace( { mykey: &#039;myvalue&#039;, another_key: &#039;another_value&#039; } );&lt;br /&gt;
&lt;br /&gt;
=== bga.exit( txt / obj ) ===&lt;br /&gt;
&lt;br /&gt;
Stop the script immediately, display the &amp;quot;txt&amp;quot; messages and cancel (ie : rollback) on every previous API call except bga.trace :&lt;br /&gt;
&lt;br /&gt;
ALL previous BGA api call are canceled and there will be no visible changes on the interface (ex : no moves, no visible property changes, ...). Only &amp;quot;bga.trace&amp;quot; API commands are kept so you can debug.&lt;br /&gt;
&lt;br /&gt;
bga.exit is very practical when you want to repeat a game action again and again to debug it : with a call to bga.exit at the end of your script, you make sure that your game situation will be kept unchanged after each test.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.exit( &amp;quot;My script is stopped by this call&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Example with dumping a javascript variable&lt;br /&gt;
  bga.exit( my_variable_to_dump );&lt;br /&gt;
&lt;br /&gt;
== Cancelling a game action ==&lt;br /&gt;
&lt;br /&gt;
=== bga.cancel( txt ) ===&lt;br /&gt;
&lt;br /&gt;
This is the function to use when a player is doing something against game rules.&lt;br /&gt;
&lt;br /&gt;
The text message in parameter will be displayed to this player as a &amp;quot;red message&amp;quot;, so he/she can understand the rule.&lt;br /&gt;
&lt;br /&gt;
All previous BGA api call are cancelled, and there will be no visible changes on the interface.&lt;br /&gt;
&lt;br /&gt;
   // Example :&lt;br /&gt;
   bga.cancel( _(&amp;quot;You cannot move this piece here&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
Note : most of the time, you should wrap your text inside a _() translation marker to make this string translatable.&lt;br /&gt;
&lt;br /&gt;
=== bga.error( text ) ===&lt;br /&gt;
&lt;br /&gt;
This is the function to use when some unexpected error happens in your script.&lt;br /&gt;
&lt;br /&gt;
The text message will be displayed to user, with mention &amp;quot;Unexpected error&amp;quot;. The player will be incited to fill a bug report. The purpose of the message is to help you to identify the bug.&lt;br /&gt;
&lt;br /&gt;
All previous BGA api call are cancelled, and there will be no visible changes on the interface.&lt;br /&gt;
&lt;br /&gt;
   // Example :&lt;br /&gt;
   if( card_picked === null )&lt;br /&gt;
   {&lt;br /&gt;
       bga.error( &amp;quot;Cannot find a card to pick !&amp;quot; );&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
Note : you should NEVER wrap text inside bga.error with _() translation marker, because unexpected error should not be translate (so you can eventually recognize them when reported by players in bug report).&lt;br /&gt;
&lt;br /&gt;
== Game log (history) ==&lt;br /&gt;
&lt;br /&gt;
=== bga.log( txt, (optional) args ) ===&lt;br /&gt;
&lt;br /&gt;
Write something in the BGA log on the right.&lt;br /&gt;
&lt;br /&gt;
  // Example : simple log&lt;br /&gt;
  bga.log( _(&amp;quot;A new round starts&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
You may add arguments to your log, like this :&lt;br /&gt;
&lt;br /&gt;
  // Example: log with argument to display a card name.&lt;br /&gt;
  //          In this example, variable &amp;quot;event_name&amp;quot; is specified afterwards.&lt;br /&gt;
  //          Note that using this, game translators only have to translate one &amp;quot;Event XXX is triggered&amp;quot; string for all possible events.&lt;br /&gt;
  bga.log( _(&amp;quot;Event ${event_name} is triggered&amp;quot;), {  event_name: _( &amp;quot;Armageddon&amp;quot; ) } ) );&lt;br /&gt;
&lt;br /&gt;
Note that argument &amp;quot;player_name&amp;quot; is ALWAYS pre-set with the name of the current player, so you can use it immediately.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.log( _(&amp;quot;${player_name} draw a card from the deck&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
=== bga.speechBubble( target, text, (optional) args, (optional) delay, (optional) duration, (optional) size ) ===&lt;br /&gt;
&lt;br /&gt;
Display a &amp;quot;speech bubble&amp;quot;, attached to the specified target, containing the specified text.&lt;br /&gt;
&lt;br /&gt;
You can use &amp;quot;args&amp;quot; to customize text exactly like with bga.log.&lt;br /&gt;
&lt;br /&gt;
delay : milliseconds to wait before displaying the speech bubble (default : 0).&lt;br /&gt;
duration : how long to show the speech bubble in milliseconds (default : 3000).&lt;br /&gt;
size : size of the text in percent (default: 100)&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.speechBubble( _(&amp;quot;I play ${nbr} cards&amp;quot;), { nbr : 4 }, 0 );&lt;br /&gt;
  bga.speechBubble( _(&amp;quot;Good for you!&amp;quot;), { }, 2000 );&lt;br /&gt;
&lt;br /&gt;
=== bga.displayScoring( target, color, score ) ===&lt;br /&gt;
&lt;br /&gt;
Display an animated temporary &amp;quot;score number&amp;quot;, attached to the specified target.&lt;br /&gt;
&amp;quot;color&amp;quot; should be the color of the player who is scoring for that target.&lt;br /&gt;
&lt;br /&gt;
== Get / search game elements and their properties ==&lt;br /&gt;
&lt;br /&gt;
=== bga.getElement( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Allow you to retrieve informations about one game element specified using &amp;quot;selector&amp;quot; argument.&lt;br /&gt;
&lt;br /&gt;
Return null if no element is found.&lt;br /&gt;
&lt;br /&gt;
Note : getElement throw an error if several elements matches the selector. If you want to retrieve several elements, you should use &amp;quot;getElements&amp;quot; instead of &amp;quot;getElement&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The following examples are showing all the possible use of bga.getElement :&lt;br /&gt;
&lt;br /&gt;
  // Basic example :&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve the ID of a game element using its name (&amp;quot;Deck&amp;quot;)&lt;br /&gt;
  var deck_id = bga.getElement( { name: &amp;quot;Deck&amp;quot; } );&lt;br /&gt;
  // Return : 1234  &lt;br /&gt;
&lt;br /&gt;
  // Examples using &amp;quot;field&amp;quot; parameter :&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve a specific property from a game element using its name (&amp;quot;Deck&amp;quot;)&lt;br /&gt;
  var deck_id = bga.getElement( { name: &amp;quot;Deck&amp;quot; }, &#039;x&#039; );&lt;br /&gt;
  // Return : 20&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve several properties from the previous element&lt;br /&gt;
  var deck_properties = bga.getElement( { name: &amp;quot;Deck&amp;quot; }, [&#039;name&#039;,&#039;id&#039;,&#039;parent&#039;, &#039;x&#039;,&#039;y&#039;,&#039;canShuffle&#039;] );&lt;br /&gt;
  // Return : { name:&#039;Deck&#039;, id:1234, parent:4321, x: 20, y:50, canShuffle: true }&lt;br /&gt;
  &lt;br /&gt;
  // Note : as you can see, getElement returns:&lt;br /&gt;
  //        _ the element ID by default, or&lt;br /&gt;
  //        _ a single value if you request a single field, or&lt;br /&gt;
  //        _ an object if you request several fields&lt;br /&gt;
&lt;br /&gt;
  // Examples using different &amp;quot;selector&amp;quot; paramter&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve an element name from its id&lt;br /&gt;
  var deck_name = bga.getElement( { id: 1234 }, [&#039;name&#039;] );&lt;br /&gt;
  // Return : &amp;quot;Deck&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  // Retrieve the last child element of another element&lt;br /&gt;
  // Here, we are requesting for elements who has element with ID=1234 (Deck) as their parent&lt;br /&gt;
  // Note the use of &amp;quot;limit:1&amp;quot; which allows us to retrieve only 1 element.&lt;br /&gt;
  var first_card_on_deck_id = bga.getElement( { parent: 1234, limit:1 } );&lt;br /&gt;
  //&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== bga.getElements( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Returns an object holding the properties of the elements matching the selector.&lt;br /&gt;
&lt;br /&gt;
  // Basic example: unselect all selected elements&lt;br /&gt;
  bga.removeStyle( bga.getElements( {tag: &#039;sbstyle_selected&#039;}), &#039;selected&#039; );&lt;br /&gt;
&lt;br /&gt;
=== bga.getElementsArray( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Returns an array of all elements matching the selector, holding the required properties.&lt;br /&gt;
&lt;br /&gt;
  // Basic example: get id of selected element&lt;br /&gt;
  var selected_tokens = bga.getElementsArray( {tag: &#039;sbstyle_selected&#039; } );&lt;br /&gt;
  var token_id = null;&lt;br /&gt;
  if (selected_tokens.length &amp;gt; 0) {&lt;br /&gt;
      token_id = selected_tokens[0];&lt;br /&gt;
  }&lt;br /&gt;
  return token_id;&lt;br /&gt;
&lt;br /&gt;
  // Classic example: get array of elements and iterate over it&lt;br /&gt;
  var all_cells = bga.getElementsArray( {tag: &#039;CELL&#039;}, [&#039;id&#039;,&#039;name&#039;,&#039;tags&#039;] );&lt;br /&gt;
  for (var i=0; i&amp;lt;all_cells.length; i++) {&lt;br /&gt;
     // ... process each cell ...&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Utility methods ==&lt;br /&gt;
&lt;br /&gt;
=== bga.isOn( element_id, parent_id ) ===&lt;br /&gt;
&lt;br /&gt;
Return true if &amp;quot;element_id&amp;quot; is a descendant of &amp;quot;parent_id&amp;quot; (ie : if element_id game element has been placed on parent_id game element).&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  if( bga.isOn( bga.getElementIfByName( &#039;Turn counter&#039; ), bga.getElementIfByName( &#039;Turn 6&#039; ) )&lt;br /&gt;
  {&lt;br /&gt;
     // Trigger game end&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Trigger most common game actions ==&lt;br /&gt;
&lt;br /&gt;
===moveElement( element_id, target_id )===&lt;br /&gt;
&lt;br /&gt;
Move element to specified target id.&lt;br /&gt;
&lt;br /&gt;
The exact destination of element depends on target &amp;quot;howToArrange&amp;quot; property (&amp;quot;How elements are arranged on it?&amp;quot; : spreaded/deck/...).&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.moveElement( bga.getElementIdByName( &#039;Turn counter&#039; ), bga.getElementIdByName( &#039;Turn 3&#039; ) );&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Other functions ==&lt;br /&gt;
&lt;br /&gt;
=== pause( milliseconds ) ===&lt;br /&gt;
&lt;br /&gt;
Pause the client interface during a specified number of milliseconds.&lt;br /&gt;
&lt;br /&gt;
If you do not use bga.pause, all Sandbox game actions are executed immediately and synchronously.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.log( &amp;quot;1&amp;quot; );    // Will be displayed immediately on the log&lt;br /&gt;
  bga.pause( 3000 ); // pause during 3 seconds&lt;br /&gt;
  bga.log( &amp;quot;2&amp;quot; );    // Will be displayed after the 3 second on the log&lt;br /&gt;
  bga.log( &amp;quot;3&amp;quot; );    // Will be displayed right after the previous one, without delay.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Tips : if you want to execute several consecutive &amp;quot;moveTo&amp;quot;, you should &amp;quot;bga.pause&amp;quot; between them, otherwise your element will move directly to the final destination.&lt;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://sr.doc.boardgamearena.com/index.php?title=Game_interface_logic:_yourgamename.js&amp;diff=3030</id>
		<title>Game interface logic: yourgamename.js</title>
		<link rel="alternate" type="text/html" href="https://sr.doc.boardgamearena.com/index.php?title=Game_interface_logic:_yourgamename.js&amp;diff=3030"/>
		<updated>2018-05-15T10:01:54Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Dialogs, warning messages, confirmation dialogs, ... */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This is the main file for your game interface. Here you will define:&lt;br /&gt;
&lt;br /&gt;
* which actions on the page will generate calls to the server&lt;br /&gt;
* what happens when you get a notification for change from the server and how it will show in the browser. &lt;br /&gt;
&lt;br /&gt;
== File structure ==&lt;br /&gt;
&lt;br /&gt;
The details on how the file is structured is described directly with comments on the code skeleton provided to you.&lt;br /&gt;
&lt;br /&gt;
Basically, here&#039;s this structure:&lt;br /&gt;
* constructor: here you can define variable global to your whole interface.&lt;br /&gt;
* setup: this method is called when the page is refreshed, in order you can setup the game interface.&lt;br /&gt;
* onEnteringState: the method is called when entering in a new game state. This way you can customize the view for this game state.&lt;br /&gt;
* onLeavingState: the method is called when leaving a game state.&lt;br /&gt;
* onUpdateActionButtons: called when entering in a new state, in order you can add action buttons in status bar.&lt;br /&gt;
* (utility methods): at this place you can define your utility methods&lt;br /&gt;
* (player&#039;s actions): at this place you can write your handlers for player&#039;s action on the interface (ex: click on an item).&lt;br /&gt;
* setupNotifications: in this method you associate notifications with notification handlers. This way, for each game notification, you trigger a javascript method to handle it and update the game interface.&lt;br /&gt;
* (notification handlers): at this place you can define your notifications handlers.&lt;br /&gt;
&lt;br /&gt;
== General tips ==&lt;br /&gt;
&lt;br /&gt;
; this.player_id&lt;br /&gt;
: Id of the player on whose browser the code is running.&lt;br /&gt;
&lt;br /&gt;
; this.isSpectator&lt;br /&gt;
: Flag set to true if the user at the table is a spectator (not a player).&lt;br /&gt;
: Note: this is not a function, its a variable.&lt;br /&gt;
: Note: if you want to hide some element for spectators, you&#039;d better use [[Game_interface_stylesheet:_yourgamename.css#spectatorMode|CSS &#039;spectatorMode&#039; class]].&lt;br /&gt;
&lt;br /&gt;
; this.gamedatas&lt;br /&gt;
: Contains your initial set of datas to init the game, created at game start or game refresh (F5)&lt;br /&gt;
: You can update it as needed to keep an up to date reference of the game on the client side if you need it (most of the time you don&#039;t).&lt;br /&gt;
&lt;br /&gt;
; this.isCurrentPlayerActive()&lt;br /&gt;
: Returns true if the player on whose browser the code is running is currently active (it&#039;s his turn to play)&lt;br /&gt;
&lt;br /&gt;
; this.getActivePlayerId()&lt;br /&gt;
: Return the ID of active player, or null if we are not in a &amp;quot;activeplayer&amp;quot; type state.&lt;br /&gt;
&lt;br /&gt;
; this.getActivePlayers()&lt;br /&gt;
: Return an array with the IDs of players that are currently active (or an empty array if there is not).&lt;br /&gt;
&lt;br /&gt;
== Dojo framework ==&lt;br /&gt;
&lt;br /&gt;
BGA is using the [http://dojotoolkit.org/ Dojo Javascript framework].&lt;br /&gt;
&lt;br /&gt;
The Dojo framework allows us to do complex things easier, and the BGA framework is using Dojo framework a lot.&lt;br /&gt;
&lt;br /&gt;
To realize game although, you only need to use a few part of the Dojo framework. All the Dojo methods you need to use are describe on this page.&lt;br /&gt;
&lt;br /&gt;
For performance reason, when deploying a game the js code is minified using Shrinksafe. Some advanced syntax may not be compatible with this process. In particular:&lt;br /&gt;
* you should not use reserved keywords from the javascript language as variables&lt;br /&gt;
* you should not declare default argument values in function declaration, the following syntax is invalid for Shriksafe: function myFunc(requiredArg, optionalArg = &#039;defaultValue&#039;) {}&lt;br /&gt;
&lt;br /&gt;
== Access and manipulate the DOM ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;$(&#039;some_html_element_id&#039;)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The $() function is used to get some HTML element using its &amp;quot;id&amp;quot; attribute.&lt;br /&gt;
&lt;br /&gt;
Example 1: modify the content of a &amp;quot;span&amp;quot; element:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
In your HTML code:&lt;br /&gt;
   &amp;lt;span id=&amp;quot;a_value_in_the_game_interface&amp;quot;&amp;gt;1234&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In your Javascript code:&lt;br /&gt;
   $(&#039;a_value_in_the_game_interface&#039;).innerHTML = &amp;quot;9999&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: $() is the standard method to access some HTML element with BGA Framework. You must not use &amp;quot;getElementById&amp;quot; function.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;dojo.style&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
With dojo.style you can modify a CSS property of any HTML element of your interface.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     // Make an element disappear&lt;br /&gt;
     dojo.style( &#039;my_element&#039;, &#039;display&#039;, &#039;none&#039; );&lt;br /&gt;
&lt;br /&gt;
     // Give an element a 2px border&lt;br /&gt;
     dojo.style( &#039;my_element&#039;, &#039;borderWidth&#039;, &#039;2px&#039; );&lt;br /&gt;
&lt;br /&gt;
     // Change the background position of an element&lt;br /&gt;
     // (very practical when you are using CSS sprite to transform an element to another)&lt;br /&gt;
     dojo.style( &#039;my_element&#039;, &#039;backgroundPosition&#039;, &#039;-20px -50px&#039; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: you must always use dojo.style to modify CSS properties of HTML elements.&lt;br /&gt;
&lt;br /&gt;
Note²: if you have to modify several CSS properties of an element, or if you have some complex CSS transformation to do, you should consider using dojo.addClass/dojo.removeClass (see below).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;dojo CSS classes manipulation&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In many situation, a bunch of many small CSS property update can be replaced by a CSS class change (ie: you add a CSS class to your element instead of applying all modification manually).&lt;br /&gt;
&lt;br /&gt;
Advantages are:&lt;br /&gt;
* All your CSS stuff remains in your CSS file.&lt;br /&gt;
* You can add/remove a list of CSS modifications with a simple function and whithout error.&lt;br /&gt;
* You can test if you applied the stuff to an element with &amp;quot;dojo.hasClass&amp;quot; method.&lt;br /&gt;
&lt;br /&gt;
Example from &amp;quot;Reversi&amp;quot;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    // We add &amp;quot;possibleMove&amp;quot; to an element&lt;br /&gt;
    dojo.addClass( &#039;square_&#039;+x+&#039;_&#039;+y, &#039;possibleMove&#039; );&lt;br /&gt;
&lt;br /&gt;
    // In our CSS file, the class is defined as:&lt;br /&gt;
    .possibleMove {&lt;br /&gt;
      background-color: white;&lt;br /&gt;
      opacity: 0.2;&lt;br /&gt;
      filter:alpha(opacity=20); /* For IE8 and earlier */  &lt;br /&gt;
      cursor: pointer;  &lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
     // So we&#039;ve applied 4 CSS property change in one line of code.&lt;br /&gt;
&lt;br /&gt;
     // ... and when we need to check if a square is a possible move on client side:&lt;br /&gt;
     if( dojo.hasClass( &#039;square_&#039;+x+&#039;_&#039;+y, &#039;possibleMove&#039; ) )&lt;br /&gt;
     { ... }&lt;br /&gt;
&lt;br /&gt;
     // ... and if we want to remove all possible moves in one line of code (see &amp;quot;dojo.query&amp;quot; method):&lt;br /&gt;
     dojo.query( &#039;.possibleMove&#039; ).removeClass( &#039;possibleMove&#039; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Conclusion: we encourage you to use dojo.addClass, dojo.removeClass and dojo.hasClass to make your life easier :)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;dojo.query&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
With dojo.query, you can query a bunch of HTML elements with a single function, with a &amp;quot;CSS selector&amp;quot; style.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     // All elements with class &amp;quot;possibleMove&amp;quot;:&lt;br /&gt;
     var elements = dojo.query( &#039;.possibleMove&#039; );&lt;br /&gt;
&lt;br /&gt;
     // Count number of tokens (ie: elements with class &amp;quot;token&amp;quot;) on the board (ie: element with id &amp;quot;board&amp;quot;):&lt;br /&gt;
     dojo.query( &#039;#board .token&#039; ).length;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
But what is really cool with dojo.query is that you can combine it with almost all methods above.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     // Trigger a method when the mouse enter in any element with class &amp;quot;meeple&amp;quot;:&lt;br /&gt;
     dojo.query( &#039;.meeple&#039; ).connect( &#039;onmouseenter&#039;, this, &#039;myMethodToTrigger&#039; );&lt;br /&gt;
&lt;br /&gt;
     // Hide all meeples who are on the board&lt;br /&gt;
     dojo.query( &#039;#board .meeple&#039; ).style( &#039;display&#039;, &#039;none&#039; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;dojo.place&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
dojo.place is the best function to insert some HTML code somewhere in your game interface without breaking something. It is much better to use that &amp;quot;innerHTML=&#039;&#039;&amp;quot; method as soon as you must insert HTML tags and not only values.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     // Insert your HTML code as a child of a container element&lt;br /&gt;
     dojo.place( &amp;quot;&amp;lt;your html code&amp;gt;&amp;quot;, &amp;quot;your_container_element_id&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
     // Replace the container element with your new html&lt;br /&gt;
     dojo.place( &amp;quot;&amp;lt;your html code&amp;gt;&amp;quot;, &amp;quot;your_container_element_id&amp;quot;, &amp;quot;replace&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The third parameter of dojo.place can take various interesting value.&lt;br /&gt;
&lt;br /&gt;
values possibles :&lt;br /&gt;
&lt;br /&gt;
&amp;quot;replace&amp;quot; : (see description above).&lt;br /&gt;
&lt;br /&gt;
&amp;quot;first&amp;quot; : Places the node as a child of the reference node. The node is placed as the first child.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;last&amp;quot; : Places the node as a child of the reference node. The node is placed as the last child.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;before&amp;quot; : places the node right before the reference node.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;last (value by default) &amp;quot; : places the node right after the reference node.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;only&amp;quot; : replaces all children of the reference node with the node.&lt;br /&gt;
&lt;br /&gt;
positif integer : This parameter can be a positif integer. In this case, the node will be placed as a child of the reference node with this number (counting from 0). If the number is more than number of children, the node will be appended to the reference node making it the last child. &lt;br /&gt;
&lt;br /&gt;
See also full doc on dojo.place : [http://dojotoolkit.org/reference-guide/1.7/dojo/place.]&lt;br /&gt;
&lt;br /&gt;
Usually, when you want to insert some piece of HTML in your game interface, you should use &amp;quot;[[Game_layout:_view_and_template:_yourgamename.view.php_and_yourgamename_yourgamename.tpl#Javascript_templates|Javascript templates]]&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;addStyleToClass: function( cssClassName, cssProperty, propertyValue )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Same as dojo.style(), but for all the nodes set with the specified cssClassName&lt;br /&gt;
&lt;br /&gt;
=== Animations ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Dojo Animations&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
BGA animations is based on Dojo Animation ([http://dojotoolkit.org/documentation/tutorials/1.8/animation/ see tutorial here]).&lt;br /&gt;
&lt;br /&gt;
However, most of the time, you can just use methods below, which are built on top of Dojo Animation.&lt;br /&gt;
&lt;br /&gt;
Note: one interesting method from Dojo that could be useful from time to time is &amp;quot;Dojo.Animation&amp;quot;. It allows you to make any CSS property &amp;quot;slide&amp;quot; from one value to another.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.slideToObject( mobile_obj, target_obj, duration, delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You can use slideToObject to &amp;quot;slide&amp;quot; an element to a target position.&lt;br /&gt;
&lt;br /&gt;
Sliding element on the game area is the recommended and the most used way to animate your game interface. Using slides allow players to figure out what is happening on the game, as if they were playing with the real boardgame.&lt;br /&gt;
&lt;br /&gt;
The parameters are:&lt;br /&gt;
* mobile_obj: the ID of the object to move. This object must be &amp;quot;relative&amp;quot; or &amp;quot;absolute&amp;quot; positioned.&lt;br /&gt;
* target_obj: the ID of the target object. This object must be &amp;quot;relative&amp;quot; or &amp;quot;absolute&amp;quot; positioned. Note that it is not mandatory that mobile_obj and target_obj have the same size. If their size are different, the system slides the center of mobile_obj to the center of target_obj.&lt;br /&gt;
* duration: (optional) defines the duration in millisecond of the slide. The default is 500 milliseconds.&lt;br /&gt;
* delay: (optional). If you defines a delay, the slide will start only after this delay. This is particularly useful when you want to slide several object from the same position to the same position: you can give a 0ms delay to the first object, a 100ms delay to the second one, a 200ms delay to the third one, ... this way they won&#039;t be superposed during the slide.&lt;br /&gt;
&lt;br /&gt;
BE CAREFUL: The method returns an dojo.fx animation, so you can combine it with other animation if you want to. It means that you have to call the &amp;quot;play()&amp;quot; method, otherwise the animation WON&#039;T START.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   this.slideToObject( &amp;quot;some_token&amp;quot;, &amp;quot;some_place_on_board&amp;quot; ).play();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.slideToObjectPos( mobile_obj, target_obj, target_x, target_y, duration, delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This method does exactly the same as &amp;quot;slideToObject&amp;quot;, except than you can specify some (x,y) coordinates. This way, &amp;quot;mobile_obj&amp;quot; will slide to the specified x,y position relatively to &amp;quot;target_obj&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Example: slide a token to some place on the board, 10 pixels to the bottom:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   this.slideToObjectPos( &amp;quot;some_token&amp;quot;, &amp;quot;some_place_on_board&amp;quot;, 0, 10 ).play();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.slideTemporaryObject( mobile_obj_html, mobile_obj_parent, from, to, duration, delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This method is useful when you want to slide a temporary HTML object from one place to another. As this object does not exists before the animation and won&#039;t remain after, it could be complex to create this object (with dojo.place), to place it at its origin (with placeOnObject) to slide it (with slideToObject) and to make it disappear at the end.&lt;br /&gt;
&lt;br /&gt;
slideTemporaryObject does all of this for you:&lt;br /&gt;
* mobile_obj_html is a piece of HTML code that represent the object to slide.&lt;br /&gt;
* mobile_obj_parent is the ID of an HTML element of your interface that will be the parent of this temporary HTML object.&lt;br /&gt;
* from is the ID of the origin of the slide.&lt;br /&gt;
* to is the ID of the target of the slide.&lt;br /&gt;
* duration/delay works exactly like in &amp;quot;slideToObject&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
this.slideTemporaryObject( &#039;&amp;lt;div class=&amp;quot;token_icon&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;, &#039;tokens&#039;, &#039;my_origin_div&#039;, &#039;my_target_div&#039; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.slideToObjectAndDestroy: function( node, to, time, delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This method is a handy shortcut to slide an existing HTML object to some place then destroy it upon arrival. It can be used for example to move a victory token or a card from the board to the player panel to show that the player earns it, then destroy it when we don&#039;t need to keep it visible on the player panel.&lt;br /&gt;
&lt;br /&gt;
It works the same as this.slideToObject and takes the same arguments. &lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
this.slideToObjectAndDestroy( &amp;quot;some_token&amp;quot;, &amp;quot;some_place_on_board&amp;quot;, 1000, 0 );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.fadeOutAndDestroy( node, duration, delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This function fade out the target HTML node, then destroy it.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   this.fadeOutAndDestroy( &amp;quot;a_card_that_must_disappear&amp;quot; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
CAREFUL: the HTML node still exists until during few milliseconds, until the fadeOut has been completed.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Rotating elements&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You can check here [http://jimfulton.info/demos/dojo-animated-rotate.html an example of use] of Dojo to make an element rotate.&lt;br /&gt;
&lt;br /&gt;
This example combines &amp;quot;Dojo.Animation&amp;quot; method and a CSS3 property that allow you to rotate the element.&lt;br /&gt;
&lt;br /&gt;
IMPORTANT: to asses browser compatibility, you must select the CSS property to use just like in the example (see sourcecode below):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        var transform;&lt;br /&gt;
        dojo.forEach(&lt;br /&gt;
            [&#039;transform&#039;, &#039;WebkitTransform&#039;, &#039;msTransform&#039;,&lt;br /&gt;
             &#039;MozTransform&#039;, &#039;OTransform&#039;],&lt;br /&gt;
            function (name) {&lt;br /&gt;
                if (typeof dojo.body().style[name] != &#039;undefined&#039;) {&lt;br /&gt;
                    transform = name;&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        // ... and then use &amp;quot;transform&amp;quot; as the name of your CSS property for rotation&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Moving elements ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.placeOnObject( mobile_obj, target_obj )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
placeOnObject works exactly like &amp;quot;slideToObject&amp;quot;, except that the effect is immediate.&lt;br /&gt;
&lt;br /&gt;
This is not really an animation, but placeOnObject is frequently used before starting an animation.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  // (We just created an object &amp;quot;my_new_token&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
  // Place the new token on current player board&lt;br /&gt;
  this.placeOnObject( &amp;quot;my_new_token&amp;quot;, &amp;quot;overall_player_board_&amp;quot;+this.player_id );&lt;br /&gt;
  &lt;br /&gt;
  // Then slide it to its position on the board&lt;br /&gt;
  this.slideToObject( &amp;quot;my_new_token&amp;quot;, &amp;quot;a_place_on_board&amp;quot; ).play();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.placeOnObjectPos( mobile_obj, target_obj, target_x, target_y )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This method works exactly like placeOnObject, except than you can specify some (x,y) coordinates. This way, &amp;quot;mobile_obj&amp;quot; will be placed to the specified x,y position relatively to &amp;quot;target_obj&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.attachToNewParent( mobile_obj, target_obj )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
With this method, you change the HTML parent of &amp;quot;mobile_obj&amp;quot; element. &amp;quot;target_obj&amp;quot; is the new parent of this element. The beauty of &lt;br /&gt;
attachToNewParent is that the mobile_obj element DOES NOT MOVE during this process.&lt;br /&gt;
&lt;br /&gt;
Note: what happens is that the method calculate a relative position of mobile_obj to make sure it does not move after the HTML parent changes.&lt;br /&gt;
&lt;br /&gt;
Why using this method?&lt;br /&gt;
&lt;br /&gt;
Changing the HTML parent of an element can be useful for the following reasons:&lt;br /&gt;
* When the HTML parent moves, all its child are moving with them. If some game elements is no more linked with a parent HTML object, you may want to attach it to another place.&lt;br /&gt;
* The z_order (vertical order of display) depends on the position in the DOM, so you may need to change the parent of some game elements when they are moving in your game area.&lt;br /&gt;
&lt;br /&gt;
CAREFUL: this function destroys original object and places a clone onto a new parent, this will break all references to this HTML element (ex: dojo.connect).&lt;br /&gt;
&lt;br /&gt;
== Players input ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;dojo.connect&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Used to associate a player event with one of your notification method.&lt;br /&gt;
&lt;br /&gt;
Example: associate a click on an element (&amp;quot;my_element&amp;quot;) with one of our method (&amp;quot;onClickOnMyElement&amp;quot;):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
      dojo.connect( $(&#039;my_element&#039;), &#039;onclick&#039;, this, &#039;onClickOnMyElement&#039; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: this is the only possible correct way to associate a player input event to your code, and you must not use anything else.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.checkAction( &amp;quot;my_action_name&amp;quot; )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Usage: checkAction: function( action, nomessage )&lt;br /&gt;
&lt;br /&gt;
Check if player can do the specified action by taking into account:&lt;br /&gt;
* current game state&lt;br /&gt;
* interface locking (a player can&#039;t do any action if an action is already in progress)&lt;br /&gt;
&lt;br /&gt;
return true if action is authorized (ie: the action is listed as a &amp;quot;possibleaction&amp;quot; in current game state).&lt;br /&gt;
&lt;br /&gt;
return false and display an error message if not (display no message if nomessage parameter is true). The displayed error message could be either &amp;quot;This move is not allowed at this moment&amp;quot; or &amp;quot;An action is already in progress&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  function onClickOnGameElement( evt )&lt;br /&gt;
  {&lt;br /&gt;
     if( this.checkAction( &amp;quot;my_action&amp;quot; ) )&lt;br /&gt;
     {&lt;br /&gt;
        // Do the action&lt;br /&gt;
     }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.ajaxcall( url, parameters, obj_callback, callback, callback_error )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This method must be used to send a player input to the game server.&lt;br /&gt;
&lt;br /&gt;
* url: the url of the action to perform. For a game, it must be: &amp;quot;/&amp;lt;mygame&amp;gt;/&amp;lt;mygame&amp;gt;/myAction.html&amp;quot;&lt;br /&gt;
* parameters: an array of parameter to send to the game server. Note that &amp;quot;lock:true&amp;quot; must always be specified in this list of parameter in order the interface can be locked during the server call.&lt;br /&gt;
* obj_callback: must be set to &amp;quot;this&amp;quot;.&lt;br /&gt;
* callback: a function to trigger when the server returns and everything went fine.&lt;br /&gt;
* callback_error: (optional and rarely used) a function to trigger when the server returns an error.&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
this.ajaxcall( &#039;/mygame/mygame/myaction.html&#039;, { lock: true, &lt;br /&gt;
   arg1: myarg1, &lt;br /&gt;
   arg2: myarg2, &lt;br /&gt;
   ...&lt;br /&gt;
}, this, function( result ) {&lt;br /&gt;
   // Do some stuff after a successful call&lt;br /&gt;
} );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Restricted arguments names (please don&#039;t use them):&lt;br /&gt;
* &amp;quot;action&amp;quot;&lt;br /&gt;
* &amp;quot;module&amp;quot;&lt;br /&gt;
* &amp;quot;class&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.confirmationDialog()&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Display a confirmation dialog with a yes/no choice.&lt;br /&gt;
&lt;br /&gt;
We advice you to NOT use this function unless the player action is really critical and could ruins the game, because it slows down the game and upset players.&lt;br /&gt;
&lt;br /&gt;
Usage: this.confirmationDialog( &amp;quot;Question to displayed&amp;quot;, callback_function_if_click_on_yes );&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
this.confirmationDialog( _(&#039;Are you sure to use this bonus (points penalty at the end of the game) ?&#039;),&lt;br /&gt;
                         dojo.hitch( this, function() {&lt;br /&gt;
                           this.ajaxcall( &#039;/seasons/seasons/useBonus.html&#039;,&lt;br /&gt;
                                { id:bonus_id, lock:true }, this, function( result ) {} );&lt;br /&gt;
                        } ) ); &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; addEventToClass: function( cssClassName, eventName, functionName )&lt;br /&gt;
: Same as dojo.connect(), but for all the nodes set with the specified cssClassName&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.addActionButton( id, label, method, (opt)destination, (opt)blinking, (opt)color )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You can use this method to add an action button in the main action status bar.&lt;br /&gt;
&lt;br /&gt;
Arguments:&lt;br /&gt;
* id: an element ID that should be unique in your HTML DOM document.&lt;br /&gt;
* label: the text of the button. Should be translatable (use _() function).&lt;br /&gt;
* method: the name of your method that must be triggered when the player clicks on this button.&lt;br /&gt;
* destination (optional): deprecated, do not use this. Use &#039;&#039;&#039;null&#039;&#039;&#039; as value if you need to specify other arguments.&lt;br /&gt;
* blinking (optional): if set to &#039;&#039;&#039;true&#039;&#039;&#039;, the button is going blink to catch player&#039;s attention. Please don&#039;t abuse of blinking button.&lt;br /&gt;
* color: could be &#039;&#039;&#039;blue&#039;&#039;&#039; (default), &#039;&#039;&#039;red&#039;&#039;&#039; or &#039;&#039;&#039;gray&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
You should only use this method in your &amp;quot;onUpdateActionButtons&amp;quot; method. Usually, you use it like this (from Hears example):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        onUpdateActionButtons: function( stateName, args ) {&lt;br /&gt;
                      &lt;br /&gt;
            if (this.isCurrentPlayerActive()) {            &lt;br /&gt;
                switch( stateName ) {&lt;br /&gt;
                case &#039;giveCards&#039;:&lt;br /&gt;
                    this.addActionButton( &#039;giveCards_button&#039;, _(&#039;Give selected cards&#039;), &#039;onGiveCards&#039; ); &lt;br /&gt;
                    break;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        },   &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the example above, we are adding a &amp;quot;Give selected cards&amp;quot; button in the case we are on game state &amp;quot;giveCards&amp;quot;. When player clicks on this button, it triggers our &amp;quot;onGiveCards&amp;quot; method.&lt;br /&gt;
&lt;br /&gt;
Example using blinking red button:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     this.addActionButton( &#039;commit_button&#039;, _(&#039;Confirm&#039;), &#039;onConfirm&#039;, null, true, &#039;red&#039;); &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: at least in studio example above will make button huge, because it sets it display of blinking things to &#039;&#039;&#039;block&#039;&#039;&#039;, &lt;br /&gt;
if you don&#039;t like it you have to change css display value&lt;br /&gt;
of the button to inline-block (the id of the button is the first argument, i.e &#039;commit_button&#039; in example above)&lt;br /&gt;
&lt;br /&gt;
== Translations ==&lt;br /&gt;
&lt;br /&gt;
See [[Translations]]&lt;br /&gt;
&lt;br /&gt;
== Notifications ==&lt;br /&gt;
&lt;br /&gt;
When something happens on the server side, your game interface Javascript logic received a notification.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s how you can handle these notifications on the client side.&lt;br /&gt;
&lt;br /&gt;
=== Subscribe to notifications ===&lt;br /&gt;
&lt;br /&gt;
Your Javascript &amp;quot;setupNotifications&amp;quot; method is the place where you can subscribe to notifications from your PHP code.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s how you associate one of your Javascript method to a notification &amp;quot;playDisc&amp;quot; (from Reversi example):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   // In setupNotifications method:&lt;br /&gt;
   dojo.subscribe( &#039;playDisc&#039;, this, &amp;quot;notif_playDisc&amp;quot; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: the &amp;quot;playDisc&amp;quot; corresponds to the name of the notification you define it in your PHP code, in your &amp;quot;notifyAllPlayers&amp;quot; or &amp;quot;notifyPlayer&amp;quot; method.&lt;br /&gt;
&lt;br /&gt;
Then, you have to define your &amp;quot;notif_playDisc&amp;quot; method:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        notif_playDisc: function( notif )&lt;br /&gt;
        {&lt;br /&gt;
            // Remove current possible moves (makes the board more clear)&lt;br /&gt;
            dojo.query( &#039;.possibleMove&#039; ).removeClass( &#039;possibleMove&#039; );        &lt;br /&gt;
        &lt;br /&gt;
            this.addDiscOnBoard( notif.args.x, notif.args.y, notif.args.player_id );&lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In a notification handler like our &amp;quot;notif_playDisc&amp;quot; method, you can access to all notifications arguments with &amp;quot;notif.args&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    // If you did this on PHP side:&lt;br /&gt;
    self::notifyAllPlayers( &amp;quot;myNotification&amp;quot;, &#039;&#039;, array( &amp;quot;myArgument&amp;quot; =&amp;gt; 3 ) );&lt;br /&gt;
&lt;br /&gt;
    // On Javascript side, you can access the &amp;quot;myArgument&amp;quot; like this:&lt;br /&gt;
    notif_myNotification: function( notif )&lt;br /&gt;
    {&lt;br /&gt;
       alert( &amp;quot;myArgument = &amp;quot; + notif.args.myArgument );&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Synchronous notifications ===&lt;br /&gt;
&lt;br /&gt;
When several notifications are received by your game interface, these notifications are processed immediately, one after the other, in the same exact order they have been generated in your PHP game logic.&lt;br /&gt;
&lt;br /&gt;
However, sometimes, you need to give some time to the players to figure out what happened on the game before jumping to the next notification. Indeed, in many games, they are a lot of automatic actions, and the computer is going to resolve all these actions very fast if you don&#039;t tell it not to do so.&lt;br /&gt;
&lt;br /&gt;
As an example, for Reversi, when someone is playing a disc, we want to wait 500 milliseconds before doing anything else in order the opponent player can figure out what move has been played.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s how we do this, right after our subscription:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
       dojo.subscribe( &#039;playDisc&#039;, this, &amp;quot;notif_playDisc&amp;quot; );&lt;br /&gt;
       this.notifqueue.setSynchronous( &#039;playDisc&#039;, 500 );   // Wait 500 milliseconds after executing the playDisc handler&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Pre-defined notification types ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;tableWindow&#039;&#039;&#039; - This defines notification to display [[Game_interface_logic:_yourgamename.js#Scoring_dialogs|Scoring Dialogs]], see below.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;message&#039;&#039;&#039; - This defines notification that shows on players log and have no other effect&lt;br /&gt;
&lt;br /&gt;
   // You can call this on php side without doing anything on client side&lt;br /&gt;
    self::notifyAllPlayers( &#039;message&#039;, &#039;hello&#039;, array( ) );&lt;br /&gt;
&lt;br /&gt;
== Tooltips ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.addTooltip( nodeId, _( helpString ), _( actionString ), delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Add a simple text tooltip to the DOM node.&lt;br /&gt;
&lt;br /&gt;
Specify &#039;helpString&#039; to display some information about &amp;quot;what is this game element?&amp;quot;.&lt;br /&gt;
Specify &#039;actionString&#039; to display some information about &amp;quot;what happens when I click on this element?&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
You must specify both helpString and actionString. Most of the time, you use only one and specify a void string (&amp;quot;&amp;quot;) for the other one.&lt;br /&gt;
&lt;br /&gt;
Usually, _() must be used for the text to be marked for translation.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Delay&amp;quot; is an optional parameter. Usually, it is primarily used to specify a zero delay for some game element when the tooltip gives really important information for the game - but remember: no essential information must be placed in tooltips as they won&#039;t be displayed in some browser (see Guidelines).&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   this.addTooltip( &#039;cardcount&#039;, _(&#039;Number of cards in hand&#039;), &#039;&#039; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.addTooltipHtml( nodeId, html, delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Add an HTML tooltip to the DOM node (for more elaborate content such as presenting a bigger version of a card).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.addTooltipToClass( cssClass, _( helpString ), _( actionString ), delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Add a simple text tooltip to all the DOM nodes set with this cssClass. &lt;br /&gt;
&lt;br /&gt;
IMPORTANT: all concerned nodes must have IDs to get tooltips.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.addTooltipHtmlToClass( cssClass, html, delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Add an HTML tooltip to to all the DOM nodes set with this cssClass (for more elaborate content such as presenting a bigger version of a card).&lt;br /&gt;
&lt;br /&gt;
IMPORTANT: all concerned nodes must have IDs to get tooltips&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.removeTooltip( nodeId )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Remove a tooltip from the DOM node.&lt;br /&gt;
&lt;br /&gt;
== Dialogs, warning messages, confirmation dialogs, ... ==&lt;br /&gt;
&lt;br /&gt;
=== Warning messages ===&lt;br /&gt;
&lt;br /&gt;
Sometimes, there is something important that is happening on the game and you have to make sure all players get the message. Most of the time, the evolution of the game situation or the game log is enough, but sometimes you need something more visible.&lt;br /&gt;
&lt;br /&gt;
Ex: someone fulfill one of the end of the game condition, so this is the last turn.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.showMessage( msg, type )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
showMessage shows a message in a big rectangular area on the top of the screen of current player.&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;msg&amp;quot; is the string to display. It should be translated.&lt;br /&gt;
* &amp;quot;type&amp;quot; can be set to &amp;quot;info&amp;quot; or &amp;quot;error&amp;quot;. If set to &amp;quot;info&amp;quot;, the message will be an informative message on a white background. If set to &amp;quot;error&amp;quot;, the message will be an error message on a red background.&lt;br /&gt;
&lt;br /&gt;
Important: the normal way to inform players about the progression of the game is the game log. &amp;quot;showMessage&amp;quot; is intrusive and should not be used often.&lt;br /&gt;
&lt;br /&gt;
=== Confirmation dialog ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;confirmationDialog( message, yesHandler, noHandler )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When an important action with a lot of consequences is triggered by the player, you may want to propose a confirmation dialog.&lt;br /&gt;
&lt;br /&gt;
CAREFUL: the general guidelines of BGA is to AVOID the use of confirmation dialog. Confirmation dialogs slow down the game and bother players. The players knows that they have to pay attention about each move when they are playing online.&lt;br /&gt;
&lt;br /&gt;
The situation where you should use a confirmation dialog are the following:&lt;br /&gt;
* It must not happen very often during a game.&lt;br /&gt;
* It must be linked to an action that can really &amp;quot;kill a game&amp;quot; if the player do not pay attention.&lt;br /&gt;
* It must be something that can be done by mistake (ex: a link on the action status bar).&lt;br /&gt;
&lt;br /&gt;
How to display a confirmation dialog:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        this.confirmationDialog( _(&#039;Are you sure you want to bake the pie?&#039;), dojo.hitch( this, function() {&lt;br /&gt;
            this.bakeThePie();&lt;br /&gt;
        } ) ); &lt;br /&gt;
        return; // nothing should be called or done after calling this, all action must be done in the handler  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Multiple choice dialog ===&lt;br /&gt;
You can use this dialog to give user a choice with small amount of options:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        var keys = [1,5,10];&lt;br /&gt;
        this.multipleChoiceDialog(&lt;br /&gt;
          _(&#039;How many bugs to fix?&amp;quot;), keys, &lt;br /&gt;
            dojo.hitch(this, function(choice) {&lt;br /&gt;
                            var bugchoice = keys[choice];&lt;br /&gt;
                            console.log(&#039;dialog callback with &#039;+bugchoice);&lt;br /&gt;
                            this.ajaxcall( &#039;/mygame/mygame/fixBugs.html&#039;, { bugs: bugchoice}, this, function( result ) {} );                        }));&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Dialogs ===&lt;br /&gt;
&lt;br /&gt;
At first, you shouldn&#039;t use dialogs windows.&lt;br /&gt;
&lt;br /&gt;
BGA guidelines specify that all game elements should be displayed on the main screen. Players can eventually scroll down to see game elements they don&#039;t need to see anytime, and you may eventually create anchors to move between game area section. Of course dialogs windows are very practical, but the thing is: all players know how to scroll down, and not all players know how to show up your dialog window. In addition, when the dialog shows up, players can&#039;t access the other game components.&lt;br /&gt;
&lt;br /&gt;
Sometimes although, you need to display a dialog window. Here is how you do this:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  // Create the new dialog. You should store the handler in a member variable to access it later&lt;br /&gt;
  this.myDlg = new dijit.Dialog({ title: _(&amp;quot;my dialog title to translate&amp;quot;) });&lt;br /&gt;
  &lt;br /&gt;
  // Create the HTML of my dialog. &lt;br /&gt;
  // The best practice here is to use [[Game_layout:_view_and_template:_yourgamename.view.php_and_yourgamename_yourgamename.tpl#Javascript_templates|Javascript templates]]&lt;br /&gt;
  var html = this.format_block( &#039;jstpl_myDialogTemplate&#039;, { &lt;br /&gt;
                arg1: myArg1,&lt;br /&gt;
                arg2: myArg2,&lt;br /&gt;
                ...&lt;br /&gt;
            } );  &lt;br /&gt;
  &lt;br /&gt;
  // Show the dialog&lt;br /&gt;
  this.myDlg.attr(&amp;quot;content&amp;quot;, html );&lt;br /&gt;
  this.myDlg.show(); &lt;br /&gt;
  &lt;br /&gt;
  // Now that the dialog has been displayed, you can connect your method to some dialog elements&lt;br /&gt;
  // Example, a &amp;quot;close&amp;quot; button:&lt;br /&gt;
  dojo.connect( $(&#039;closeDlg&#039;), &#039;onclick&#039;, this, function(evt){&lt;br /&gt;
                evt.preventDefault();&lt;br /&gt;
                this.myDlg.hide();&lt;br /&gt;
            } );  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Tip: be careful with &amp;quot;hide()&amp;quot; method to close your dialog: the dialog and its content is not completely removed from the DOM. It can cause you problems if you try to display the same dialog several times. A good practice is to wrap all the content of your dialog in a &amp;lt;nowiki&amp;gt;&amp;lt;div id=&#039;myDlgContent&#039;&amp;gt;&amp;lt;/nowiki&amp;gt; div element, and to call &amp;quot;dojo.destroy(&#039;myDlgContent&#039;)&amp;quot; before displaying your dialog.&lt;br /&gt;
&lt;br /&gt;
=== Scoring dialogs ===&lt;br /&gt;
&lt;br /&gt;
Sometimes at the end of a round you want to display a big table that details the points wins in each section of the game.&lt;br /&gt;
&lt;br /&gt;
Example: in Hearts game, we display at the end of each round the number of &amp;quot;heart&amp;quot; cards collected by each player, the player who collected the Queen of Spades, and the total number of points loose by each player.&lt;br /&gt;
&lt;br /&gt;
Scoring dialogs are managed entirely on &#039;&#039;&#039;PHP side&#039;&#039;&#039;, but they are described here as their effects are visible only on client side.&lt;br /&gt;
&lt;br /&gt;
Displaying a scoring dialog is quite simple and is using a special notification type: &amp;quot;tableWindow&amp;quot;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  // on PHP side:&lt;br /&gt;
  $this-&amp;gt;notifyAllPlayers( &amp;quot;tableWindow&amp;quot;, &#039;&#039;, array(&lt;br /&gt;
            &amp;quot;id&amp;quot; =&amp;gt; &#039;finalScoring&#039;,&lt;br /&gt;
            &amp;quot;title&amp;quot; =&amp;gt; clienttranslate(&amp;quot;Title of the scoring dialog&amp;quot;),&lt;br /&gt;
            &amp;quot;table&amp;quot; =&amp;gt; $table&lt;br /&gt;
        ) ); &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;table&amp;quot; argument is a 2 dimensional PHP array that describe the table you want to display, line by line and column by column.&lt;br /&gt;
&lt;br /&gt;
Example: display an 3x3 array of strings&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   $table = array(&lt;br /&gt;
      array( &amp;quot;one&amp;quot;, &amp;quot;two&amp;quot;, &amp;quot;three&amp;quot; ),    // This is my first line&lt;br /&gt;
      array( &amp;quot;four&amp;quot;, &amp;quot;five&amp;quot;, &amp;quot;six&amp;quot; ),    // This is my second line&lt;br /&gt;
      array( &amp;quot;seven&amp;quot;, &amp;quot;height&amp;quot;, &amp;quot;nine&amp;quot; )    // This is my third line&lt;br /&gt;
   );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As you can see above, in each &amp;quot;cell&amp;quot; of your array you can display a simple string value. But you can also display a complex value with a template and associated arguments like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   $table = array(&lt;br /&gt;
      array( &amp;quot;one&amp;quot;, &amp;quot;two&amp;quot;, array( &amp;quot;str&amp;quot; =&amp;gt; &amp;quot;a string with an ${argument}&amp;quot;, &amp;quot;args&amp;quot; =&amp;gt; array( &#039;argument&#039; =&amp;gt; &#039;argument_value&#039; )  ) ),&lt;br /&gt;
      array( &amp;quot;four&amp;quot;, &amp;quot;five&amp;quot;, &amp;quot;six&amp;quot; ), &lt;br /&gt;
      array( &amp;quot;seven&amp;quot;, &amp;quot;height&amp;quot;, &amp;quot;nine&amp;quot; )&lt;br /&gt;
   );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is especially useful when you want to display player names with colors. Example from &amp;quot;Hearts&amp;quot;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        $firstRow = array( &#039;&#039; );&lt;br /&gt;
        foreach( $players as $player_id =&amp;gt; $player )&lt;br /&gt;
        {&lt;br /&gt;
            $firstRow[] = array( &#039;str&#039; =&amp;gt; &#039;${player_name}&#039;,&lt;br /&gt;
                                 &#039;args&#039; =&amp;gt; array( &#039;player_name&#039; =&amp;gt; $player[&#039;player_name&#039;] ),&lt;br /&gt;
                                 &#039;type&#039; =&amp;gt; &#039;header&#039;&lt;br /&gt;
                               );&lt;br /&gt;
        }&lt;br /&gt;
        $table[] = $firstRow;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also use three extra attributes in the parameter array for the notification:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   $this-&amp;gt;notifyAllPlayers( &amp;quot;tableWindow&amp;quot;, &#039;&#039;, array(&lt;br /&gt;
            &amp;quot;id&amp;quot; =&amp;gt; &#039;finalScoring&#039;,&lt;br /&gt;
            &amp;quot;title&amp;quot; =&amp;gt; clienttranslate(&amp;quot;Title of the scoring dialog&amp;quot;),&lt;br /&gt;
            &amp;quot;table&amp;quot; =&amp;gt; $table,&lt;br /&gt;
            &amp;quot;header&amp;quot; =&amp;gt; array(&#039;str&#039; =&amp;gt; clienttranslate(&#039;Table header with parameter ${number}&#039;),&lt;br /&gt;
                                 &#039;args&#039; =&amp;gt; array( &#039;number&#039; =&amp;gt; 3 ),&lt;br /&gt;
                               ),&lt;br /&gt;
            &amp;quot;footer&amp;quot; =&amp;gt; &#039;&amp;lt;div&amp;gt;Some footer&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
            &amp;quot;closing&amp;quot; =&amp;gt; clienttranslate( &amp;quot;Closing button label&amp;quot; )&lt;br /&gt;
        ) ); &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;header&#039;&#039;&#039;: the content for this parameter will display before the table (also, the html will be parsed and player names will be colored according to the current game colors). &lt;br /&gt;
*&#039;&#039;&#039;footer&#039;&#039;&#039;: the content for this parameter will display after the table (no parsing for coloring the player names)&lt;br /&gt;
*&#039;&#039;&#039;closing&#039;&#039;&#039;: if this parameter is used, a button will be displayed with this label at the bottom of the popup and will allow players to close it (more easily than by clicking the top right &#039;cross&#039; icon).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Scoring animated display ===&lt;br /&gt;
&lt;br /&gt;
Sometimes (Terra Mystica final scoring for example), you may want to display a score value over an element to make the scoring easier to follow for the players.&lt;br /&gt;
You can do it with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   this.displayScoring( anchor_id, color, score );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Speech bubble ===&lt;br /&gt;
&lt;br /&gt;
For better interactivity in some games (Love Letter for example), you may use comic book style speech bubbles to express the players voices.&lt;br /&gt;
This is done with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   this.showBubble( anchor_id, text, delay, duration, custom_class )&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
delay in milliseconds is optional (default 0)&lt;br /&gt;
&lt;br /&gt;
duration in milliseconds is optional (default 3000)&lt;br /&gt;
&lt;br /&gt;
custom_class is optional, if you need to override the default bubble style&lt;br /&gt;
&lt;br /&gt;
== Update players score ==&lt;br /&gt;
&lt;br /&gt;
Increase a player score (with a positive or negative number):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  this.scoreCtrl[ player_id ].incValue( score_delta );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Set a player score to a specific value:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  this.scoreCtrl[ player_id ].setValue( new_score );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Players panels ==&lt;br /&gt;
&lt;br /&gt;
=== Adding stuff to player&#039;s panel ===&lt;br /&gt;
&lt;br /&gt;
At first, create a new &amp;quot;JS template&amp;quot; string in your template (tpl) file:&lt;br /&gt;
&lt;br /&gt;
(from Gomoku example)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
var jstpl_player_board = &#039;\&amp;lt;div class=&amp;quot;cp_board&amp;quot;&amp;gt;\&lt;br /&gt;
    &amp;lt;div id=&amp;quot;stoneicon_p${id}&amp;quot; class=&amp;quot;gmk_stoneicon gmk_stoneicon_${color}&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;span id=&amp;quot;stonecount_p${id}&amp;quot;&amp;gt;0&amp;lt;/span&amp;gt;\&lt;br /&gt;
&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then, you add this piece of code in your JS file to add this template to each player panel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
            // Setting up player boards&lt;br /&gt;
            for( var player_id in gamedatas.players )&lt;br /&gt;
            {&lt;br /&gt;
                var player = gamedatas.players[player_id];&lt;br /&gt;
                         &lt;br /&gt;
                // Setting up players boards if needed&lt;br /&gt;
                var player_board_div = $(&#039;player_board_&#039;+player_id);&lt;br /&gt;
                dojo.place( this.format_block(&#039;jstpl_player_board&#039;, player ), player_board_div );&lt;br /&gt;
            }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Note: the code above is of course from your &amp;quot;setup&amp;quot; function in your Javascript).&lt;br /&gt;
&lt;br /&gt;
Very often, you have to distinguish current player and others players. In this case, you just have to create another JS template (ex: jstpl_otherplayer_board) and use it when &amp;quot;player_id&amp;quot; is different than &amp;quot;this.player_id&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Player&#039;s panel disabling/enabling ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.disablePlayerPanel( player_id )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Disable given player panel (the panel background become gray).&lt;br /&gt;
&lt;br /&gt;
Usually, this is used to signal that this played passes, or will be inactive during a while.&lt;br /&gt;
&lt;br /&gt;
Note that the only effect of this is visual. There are no consequences on the behaviour of the panel itself.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.enablePlayerPanel( player_id )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Enable a player panel that has been disabled before.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.enableAllPlayerPanels()&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Enable all player panels that has been disabled before.&lt;br /&gt;
&lt;br /&gt;
== Image loading ==&lt;br /&gt;
&lt;br /&gt;
See also [[Game_art:_img_directory]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Be careful&#039;&#039;&#039;: by default, ALL images of your img directory are loaded on a player&#039;s browser when he loads the game. For this reason, don&#039;t let in your img directory images that are not useful, otherwise it&#039;s going to slowdown the game load.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;dontPreloadImage( image_file_name )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Using dontPreloadImage, you tell the interface to not preload a specific image in your img directory.&lt;br /&gt;
&lt;br /&gt;
Example of use:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
this.dontPreloadImage( &#039;cards.png&#039; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is particularly useful if for example you have 2 different themes for a game. To accelerate the loading of the game, you can specify to not preload images corresponding to the other theme.&lt;br /&gt;
&lt;br /&gt;
Another example of use: in &amp;quot;Gosu&amp;quot; game with Kamakor extension, you play with 5 sets of cards among 10 available. Cards images are organized by sets, and we only preload the images corresponding to the 5 current sets with &#039;&#039;&#039;ensureSpecificGameImageLoading( image_file_names_array )&#039;&#039;&#039;.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// By default, do not preload anything&lt;br /&gt;
this.dontPreloadImage( &#039;cards.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan1.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan2.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan3.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan4.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan5.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan6.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan7.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan8.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan9.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan10.png&#039; );&lt;br /&gt;
var to_preload = [];&lt;br /&gt;
for( i in this.gamedatas.clans )&lt;br /&gt;
{&lt;br /&gt;
	var clan_id = this.gamedatas.clans[i];&lt;br /&gt;
	to_preload.push( &#039;clan&#039;+clan_id+&#039;.png&#039; );&lt;br /&gt;
}&lt;br /&gt;
if( to_preload.length == 5 )&lt;br /&gt;
{&lt;br /&gt;
	this.ensureSpecificGameImageLoading( to_preload );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; You don&#039;t need to specify to not preload game box images (game_box.png, game_box75.png...) since they are not preloaded by default.&lt;br /&gt;
&lt;br /&gt;
== Other useful stuff ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;dojo.hitch&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
With dojo.hitch, you can create a callback function that will run with your game object context whatever happen.&lt;br /&gt;
&lt;br /&gt;
Typical example: display a BGA confirmation dialog with a callback function created with dojo.hitch:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        this.confirmationDialog( _(&#039;Are you sure you want to make this?&#039;), dojo.hitch( this, function() {&lt;br /&gt;
            this.ajaxcall( &#039;/mygame/mygame/makeThis.html&#039;, { lock:true }, this, function( result ) {} );&lt;br /&gt;
        } ) );   &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the example above, using dojo.hitch, we are sure that the &amp;quot;this&amp;quot; object will be set when the callback is called.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; updateCounters(counters)&lt;br /&gt;
: Useful for updating game counters in the player panel (such as resources). &lt;br /&gt;
: &#039;counters&#039; arg is an associative array [counter_name_value =&amp;gt; [ &#039;counter_name&#039; =&amp;gt; counter_name_value, &#039;counter_value&#039; =&amp;gt; counter_value_value], ... ]&lt;br /&gt;
: All counters must be referenced in this.gamedatas.counters and will be updated.&lt;br /&gt;
: DOM objects referenced by &#039;counter_name&#039; will have their innerHTML updated with &#039;counter_value&#039;.&lt;br /&gt;
&lt;br /&gt;
== BGA GUI components ==&lt;br /&gt;
&lt;br /&gt;
BGA framework provides some useful ready-to-use components for the game interface:&lt;br /&gt;
&lt;br /&gt;
[[Studio#BGA_Studio_game_components_reference]]&lt;br /&gt;
&lt;br /&gt;
Note that each time you are using an additional component, you must declare it at the top of your Javascript file in the list of modules used.&lt;br /&gt;
&lt;br /&gt;
Example if you are using &amp;quot;ebg.stock&amp;quot;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
define([&lt;br /&gt;
    &amp;quot;dojo&amp;quot;,&amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
    &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
    &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
    &amp;quot;ebg/stock&amp;quot;  /// &amp;lt;=== we are using ebg.stock module&lt;br /&gt;
],&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://sr.doc.boardgamearena.com/index.php?title=Game_interface_logic:_yourgamename.js&amp;diff=3029</id>
		<title>Game interface logic: yourgamename.js</title>
		<link rel="alternate" type="text/html" href="https://sr.doc.boardgamearena.com/index.php?title=Game_interface_logic:_yourgamename.js&amp;diff=3029"/>
		<updated>2018-05-15T10:00:42Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Speech bubble */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This is the main file for your game interface. Here you will define:&lt;br /&gt;
&lt;br /&gt;
* which actions on the page will generate calls to the server&lt;br /&gt;
* what happens when you get a notification for change from the server and how it will show in the browser. &lt;br /&gt;
&lt;br /&gt;
== File structure ==&lt;br /&gt;
&lt;br /&gt;
The details on how the file is structured is described directly with comments on the code skeleton provided to you.&lt;br /&gt;
&lt;br /&gt;
Basically, here&#039;s this structure:&lt;br /&gt;
* constructor: here you can define variable global to your whole interface.&lt;br /&gt;
* setup: this method is called when the page is refreshed, in order you can setup the game interface.&lt;br /&gt;
* onEnteringState: the method is called when entering in a new game state. This way you can customize the view for this game state.&lt;br /&gt;
* onLeavingState: the method is called when leaving a game state.&lt;br /&gt;
* onUpdateActionButtons: called when entering in a new state, in order you can add action buttons in status bar.&lt;br /&gt;
* (utility methods): at this place you can define your utility methods&lt;br /&gt;
* (player&#039;s actions): at this place you can write your handlers for player&#039;s action on the interface (ex: click on an item).&lt;br /&gt;
* setupNotifications: in this method you associate notifications with notification handlers. This way, for each game notification, you trigger a javascript method to handle it and update the game interface.&lt;br /&gt;
* (notification handlers): at this place you can define your notifications handlers.&lt;br /&gt;
&lt;br /&gt;
== General tips ==&lt;br /&gt;
&lt;br /&gt;
; this.player_id&lt;br /&gt;
: Id of the player on whose browser the code is running.&lt;br /&gt;
&lt;br /&gt;
; this.isSpectator&lt;br /&gt;
: Flag set to true if the user at the table is a spectator (not a player).&lt;br /&gt;
: Note: this is not a function, its a variable.&lt;br /&gt;
: Note: if you want to hide some element for spectators, you&#039;d better use [[Game_interface_stylesheet:_yourgamename.css#spectatorMode|CSS &#039;spectatorMode&#039; class]].&lt;br /&gt;
&lt;br /&gt;
; this.gamedatas&lt;br /&gt;
: Contains your initial set of datas to init the game, created at game start or game refresh (F5)&lt;br /&gt;
: You can update it as needed to keep an up to date reference of the game on the client side if you need it (most of the time you don&#039;t).&lt;br /&gt;
&lt;br /&gt;
; this.isCurrentPlayerActive()&lt;br /&gt;
: Returns true if the player on whose browser the code is running is currently active (it&#039;s his turn to play)&lt;br /&gt;
&lt;br /&gt;
; this.getActivePlayerId()&lt;br /&gt;
: Return the ID of active player, or null if we are not in a &amp;quot;activeplayer&amp;quot; type state.&lt;br /&gt;
&lt;br /&gt;
; this.getActivePlayers()&lt;br /&gt;
: Return an array with the IDs of players that are currently active (or an empty array if there is not).&lt;br /&gt;
&lt;br /&gt;
== Dojo framework ==&lt;br /&gt;
&lt;br /&gt;
BGA is using the [http://dojotoolkit.org/ Dojo Javascript framework].&lt;br /&gt;
&lt;br /&gt;
The Dojo framework allows us to do complex things easier, and the BGA framework is using Dojo framework a lot.&lt;br /&gt;
&lt;br /&gt;
To realize game although, you only need to use a few part of the Dojo framework. All the Dojo methods you need to use are describe on this page.&lt;br /&gt;
&lt;br /&gt;
For performance reason, when deploying a game the js code is minified using Shrinksafe. Some advanced syntax may not be compatible with this process. In particular:&lt;br /&gt;
* you should not use reserved keywords from the javascript language as variables&lt;br /&gt;
* you should not declare default argument values in function declaration, the following syntax is invalid for Shriksafe: function myFunc(requiredArg, optionalArg = &#039;defaultValue&#039;) {}&lt;br /&gt;
&lt;br /&gt;
== Access and manipulate the DOM ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;$(&#039;some_html_element_id&#039;)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The $() function is used to get some HTML element using its &amp;quot;id&amp;quot; attribute.&lt;br /&gt;
&lt;br /&gt;
Example 1: modify the content of a &amp;quot;span&amp;quot; element:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
In your HTML code:&lt;br /&gt;
   &amp;lt;span id=&amp;quot;a_value_in_the_game_interface&amp;quot;&amp;gt;1234&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In your Javascript code:&lt;br /&gt;
   $(&#039;a_value_in_the_game_interface&#039;).innerHTML = &amp;quot;9999&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: $() is the standard method to access some HTML element with BGA Framework. You must not use &amp;quot;getElementById&amp;quot; function.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;dojo.style&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
With dojo.style you can modify a CSS property of any HTML element of your interface.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     // Make an element disappear&lt;br /&gt;
     dojo.style( &#039;my_element&#039;, &#039;display&#039;, &#039;none&#039; );&lt;br /&gt;
&lt;br /&gt;
     // Give an element a 2px border&lt;br /&gt;
     dojo.style( &#039;my_element&#039;, &#039;borderWidth&#039;, &#039;2px&#039; );&lt;br /&gt;
&lt;br /&gt;
     // Change the background position of an element&lt;br /&gt;
     // (very practical when you are using CSS sprite to transform an element to another)&lt;br /&gt;
     dojo.style( &#039;my_element&#039;, &#039;backgroundPosition&#039;, &#039;-20px -50px&#039; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: you must always use dojo.style to modify CSS properties of HTML elements.&lt;br /&gt;
&lt;br /&gt;
Note²: if you have to modify several CSS properties of an element, or if you have some complex CSS transformation to do, you should consider using dojo.addClass/dojo.removeClass (see below).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;dojo CSS classes manipulation&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In many situation, a bunch of many small CSS property update can be replaced by a CSS class change (ie: you add a CSS class to your element instead of applying all modification manually).&lt;br /&gt;
&lt;br /&gt;
Advantages are:&lt;br /&gt;
* All your CSS stuff remains in your CSS file.&lt;br /&gt;
* You can add/remove a list of CSS modifications with a simple function and whithout error.&lt;br /&gt;
* You can test if you applied the stuff to an element with &amp;quot;dojo.hasClass&amp;quot; method.&lt;br /&gt;
&lt;br /&gt;
Example from &amp;quot;Reversi&amp;quot;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    // We add &amp;quot;possibleMove&amp;quot; to an element&lt;br /&gt;
    dojo.addClass( &#039;square_&#039;+x+&#039;_&#039;+y, &#039;possibleMove&#039; );&lt;br /&gt;
&lt;br /&gt;
    // In our CSS file, the class is defined as:&lt;br /&gt;
    .possibleMove {&lt;br /&gt;
      background-color: white;&lt;br /&gt;
      opacity: 0.2;&lt;br /&gt;
      filter:alpha(opacity=20); /* For IE8 and earlier */  &lt;br /&gt;
      cursor: pointer;  &lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
     // So we&#039;ve applied 4 CSS property change in one line of code.&lt;br /&gt;
&lt;br /&gt;
     // ... and when we need to check if a square is a possible move on client side:&lt;br /&gt;
     if( dojo.hasClass( &#039;square_&#039;+x+&#039;_&#039;+y, &#039;possibleMove&#039; ) )&lt;br /&gt;
     { ... }&lt;br /&gt;
&lt;br /&gt;
     // ... and if we want to remove all possible moves in one line of code (see &amp;quot;dojo.query&amp;quot; method):&lt;br /&gt;
     dojo.query( &#039;.possibleMove&#039; ).removeClass( &#039;possibleMove&#039; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Conclusion: we encourage you to use dojo.addClass, dojo.removeClass and dojo.hasClass to make your life easier :)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;dojo.query&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
With dojo.query, you can query a bunch of HTML elements with a single function, with a &amp;quot;CSS selector&amp;quot; style.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     // All elements with class &amp;quot;possibleMove&amp;quot;:&lt;br /&gt;
     var elements = dojo.query( &#039;.possibleMove&#039; );&lt;br /&gt;
&lt;br /&gt;
     // Count number of tokens (ie: elements with class &amp;quot;token&amp;quot;) on the board (ie: element with id &amp;quot;board&amp;quot;):&lt;br /&gt;
     dojo.query( &#039;#board .token&#039; ).length;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
But what is really cool with dojo.query is that you can combine it with almost all methods above.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     // Trigger a method when the mouse enter in any element with class &amp;quot;meeple&amp;quot;:&lt;br /&gt;
     dojo.query( &#039;.meeple&#039; ).connect( &#039;onmouseenter&#039;, this, &#039;myMethodToTrigger&#039; );&lt;br /&gt;
&lt;br /&gt;
     // Hide all meeples who are on the board&lt;br /&gt;
     dojo.query( &#039;#board .meeple&#039; ).style( &#039;display&#039;, &#039;none&#039; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;dojo.place&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
dojo.place is the best function to insert some HTML code somewhere in your game interface without breaking something. It is much better to use that &amp;quot;innerHTML=&#039;&#039;&amp;quot; method as soon as you must insert HTML tags and not only values.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     // Insert your HTML code as a child of a container element&lt;br /&gt;
     dojo.place( &amp;quot;&amp;lt;your html code&amp;gt;&amp;quot;, &amp;quot;your_container_element_id&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
     // Replace the container element with your new html&lt;br /&gt;
     dojo.place( &amp;quot;&amp;lt;your html code&amp;gt;&amp;quot;, &amp;quot;your_container_element_id&amp;quot;, &amp;quot;replace&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The third parameter of dojo.place can take various interesting value.&lt;br /&gt;
&lt;br /&gt;
values possibles :&lt;br /&gt;
&lt;br /&gt;
&amp;quot;replace&amp;quot; : (see description above).&lt;br /&gt;
&lt;br /&gt;
&amp;quot;first&amp;quot; : Places the node as a child of the reference node. The node is placed as the first child.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;last&amp;quot; : Places the node as a child of the reference node. The node is placed as the last child.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;before&amp;quot; : places the node right before the reference node.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;last (value by default) &amp;quot; : places the node right after the reference node.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;only&amp;quot; : replaces all children of the reference node with the node.&lt;br /&gt;
&lt;br /&gt;
positif integer : This parameter can be a positif integer. In this case, the node will be placed as a child of the reference node with this number (counting from 0). If the number is more than number of children, the node will be appended to the reference node making it the last child. &lt;br /&gt;
&lt;br /&gt;
See also full doc on dojo.place : [http://dojotoolkit.org/reference-guide/1.7/dojo/place.]&lt;br /&gt;
&lt;br /&gt;
Usually, when you want to insert some piece of HTML in your game interface, you should use &amp;quot;[[Game_layout:_view_and_template:_yourgamename.view.php_and_yourgamename_yourgamename.tpl#Javascript_templates|Javascript templates]]&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;addStyleToClass: function( cssClassName, cssProperty, propertyValue )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Same as dojo.style(), but for all the nodes set with the specified cssClassName&lt;br /&gt;
&lt;br /&gt;
=== Animations ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Dojo Animations&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
BGA animations is based on Dojo Animation ([http://dojotoolkit.org/documentation/tutorials/1.8/animation/ see tutorial here]).&lt;br /&gt;
&lt;br /&gt;
However, most of the time, you can just use methods below, which are built on top of Dojo Animation.&lt;br /&gt;
&lt;br /&gt;
Note: one interesting method from Dojo that could be useful from time to time is &amp;quot;Dojo.Animation&amp;quot;. It allows you to make any CSS property &amp;quot;slide&amp;quot; from one value to another.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.slideToObject( mobile_obj, target_obj, duration, delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You can use slideToObject to &amp;quot;slide&amp;quot; an element to a target position.&lt;br /&gt;
&lt;br /&gt;
Sliding element on the game area is the recommended and the most used way to animate your game interface. Using slides allow players to figure out what is happening on the game, as if they were playing with the real boardgame.&lt;br /&gt;
&lt;br /&gt;
The parameters are:&lt;br /&gt;
* mobile_obj: the ID of the object to move. This object must be &amp;quot;relative&amp;quot; or &amp;quot;absolute&amp;quot; positioned.&lt;br /&gt;
* target_obj: the ID of the target object. This object must be &amp;quot;relative&amp;quot; or &amp;quot;absolute&amp;quot; positioned. Note that it is not mandatory that mobile_obj and target_obj have the same size. If their size are different, the system slides the center of mobile_obj to the center of target_obj.&lt;br /&gt;
* duration: (optional) defines the duration in millisecond of the slide. The default is 500 milliseconds.&lt;br /&gt;
* delay: (optional). If you defines a delay, the slide will start only after this delay. This is particularly useful when you want to slide several object from the same position to the same position: you can give a 0ms delay to the first object, a 100ms delay to the second one, a 200ms delay to the third one, ... this way they won&#039;t be superposed during the slide.&lt;br /&gt;
&lt;br /&gt;
BE CAREFUL: The method returns an dojo.fx animation, so you can combine it with other animation if you want to. It means that you have to call the &amp;quot;play()&amp;quot; method, otherwise the animation WON&#039;T START.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   this.slideToObject( &amp;quot;some_token&amp;quot;, &amp;quot;some_place_on_board&amp;quot; ).play();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.slideToObjectPos( mobile_obj, target_obj, target_x, target_y, duration, delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This method does exactly the same as &amp;quot;slideToObject&amp;quot;, except than you can specify some (x,y) coordinates. This way, &amp;quot;mobile_obj&amp;quot; will slide to the specified x,y position relatively to &amp;quot;target_obj&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Example: slide a token to some place on the board, 10 pixels to the bottom:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   this.slideToObjectPos( &amp;quot;some_token&amp;quot;, &amp;quot;some_place_on_board&amp;quot;, 0, 10 ).play();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.slideTemporaryObject( mobile_obj_html, mobile_obj_parent, from, to, duration, delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This method is useful when you want to slide a temporary HTML object from one place to another. As this object does not exists before the animation and won&#039;t remain after, it could be complex to create this object (with dojo.place), to place it at its origin (with placeOnObject) to slide it (with slideToObject) and to make it disappear at the end.&lt;br /&gt;
&lt;br /&gt;
slideTemporaryObject does all of this for you:&lt;br /&gt;
* mobile_obj_html is a piece of HTML code that represent the object to slide.&lt;br /&gt;
* mobile_obj_parent is the ID of an HTML element of your interface that will be the parent of this temporary HTML object.&lt;br /&gt;
* from is the ID of the origin of the slide.&lt;br /&gt;
* to is the ID of the target of the slide.&lt;br /&gt;
* duration/delay works exactly like in &amp;quot;slideToObject&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
this.slideTemporaryObject( &#039;&amp;lt;div class=&amp;quot;token_icon&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;, &#039;tokens&#039;, &#039;my_origin_div&#039;, &#039;my_target_div&#039; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.slideToObjectAndDestroy: function( node, to, time, delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This method is a handy shortcut to slide an existing HTML object to some place then destroy it upon arrival. It can be used for example to move a victory token or a card from the board to the player panel to show that the player earns it, then destroy it when we don&#039;t need to keep it visible on the player panel.&lt;br /&gt;
&lt;br /&gt;
It works the same as this.slideToObject and takes the same arguments. &lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
this.slideToObjectAndDestroy( &amp;quot;some_token&amp;quot;, &amp;quot;some_place_on_board&amp;quot;, 1000, 0 );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.fadeOutAndDestroy( node, duration, delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This function fade out the target HTML node, then destroy it.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   this.fadeOutAndDestroy( &amp;quot;a_card_that_must_disappear&amp;quot; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
CAREFUL: the HTML node still exists until during few milliseconds, until the fadeOut has been completed.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Rotating elements&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You can check here [http://jimfulton.info/demos/dojo-animated-rotate.html an example of use] of Dojo to make an element rotate.&lt;br /&gt;
&lt;br /&gt;
This example combines &amp;quot;Dojo.Animation&amp;quot; method and a CSS3 property that allow you to rotate the element.&lt;br /&gt;
&lt;br /&gt;
IMPORTANT: to asses browser compatibility, you must select the CSS property to use just like in the example (see sourcecode below):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        var transform;&lt;br /&gt;
        dojo.forEach(&lt;br /&gt;
            [&#039;transform&#039;, &#039;WebkitTransform&#039;, &#039;msTransform&#039;,&lt;br /&gt;
             &#039;MozTransform&#039;, &#039;OTransform&#039;],&lt;br /&gt;
            function (name) {&lt;br /&gt;
                if (typeof dojo.body().style[name] != &#039;undefined&#039;) {&lt;br /&gt;
                    transform = name;&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        // ... and then use &amp;quot;transform&amp;quot; as the name of your CSS property for rotation&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Moving elements ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.placeOnObject( mobile_obj, target_obj )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
placeOnObject works exactly like &amp;quot;slideToObject&amp;quot;, except that the effect is immediate.&lt;br /&gt;
&lt;br /&gt;
This is not really an animation, but placeOnObject is frequently used before starting an animation.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  // (We just created an object &amp;quot;my_new_token&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
  // Place the new token on current player board&lt;br /&gt;
  this.placeOnObject( &amp;quot;my_new_token&amp;quot;, &amp;quot;overall_player_board_&amp;quot;+this.player_id );&lt;br /&gt;
  &lt;br /&gt;
  // Then slide it to its position on the board&lt;br /&gt;
  this.slideToObject( &amp;quot;my_new_token&amp;quot;, &amp;quot;a_place_on_board&amp;quot; ).play();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.placeOnObjectPos( mobile_obj, target_obj, target_x, target_y )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This method works exactly like placeOnObject, except than you can specify some (x,y) coordinates. This way, &amp;quot;mobile_obj&amp;quot; will be placed to the specified x,y position relatively to &amp;quot;target_obj&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.attachToNewParent( mobile_obj, target_obj )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
With this method, you change the HTML parent of &amp;quot;mobile_obj&amp;quot; element. &amp;quot;target_obj&amp;quot; is the new parent of this element. The beauty of &lt;br /&gt;
attachToNewParent is that the mobile_obj element DOES NOT MOVE during this process.&lt;br /&gt;
&lt;br /&gt;
Note: what happens is that the method calculate a relative position of mobile_obj to make sure it does not move after the HTML parent changes.&lt;br /&gt;
&lt;br /&gt;
Why using this method?&lt;br /&gt;
&lt;br /&gt;
Changing the HTML parent of an element can be useful for the following reasons:&lt;br /&gt;
* When the HTML parent moves, all its child are moving with them. If some game elements is no more linked with a parent HTML object, you may want to attach it to another place.&lt;br /&gt;
* The z_order (vertical order of display) depends on the position in the DOM, so you may need to change the parent of some game elements when they are moving in your game area.&lt;br /&gt;
&lt;br /&gt;
CAREFUL: this function destroys original object and places a clone onto a new parent, this will break all references to this HTML element (ex: dojo.connect).&lt;br /&gt;
&lt;br /&gt;
== Players input ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;dojo.connect&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Used to associate a player event with one of your notification method.&lt;br /&gt;
&lt;br /&gt;
Example: associate a click on an element (&amp;quot;my_element&amp;quot;) with one of our method (&amp;quot;onClickOnMyElement&amp;quot;):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
      dojo.connect( $(&#039;my_element&#039;), &#039;onclick&#039;, this, &#039;onClickOnMyElement&#039; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: this is the only possible correct way to associate a player input event to your code, and you must not use anything else.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.checkAction( &amp;quot;my_action_name&amp;quot; )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Usage: checkAction: function( action, nomessage )&lt;br /&gt;
&lt;br /&gt;
Check if player can do the specified action by taking into account:&lt;br /&gt;
* current game state&lt;br /&gt;
* interface locking (a player can&#039;t do any action if an action is already in progress)&lt;br /&gt;
&lt;br /&gt;
return true if action is authorized (ie: the action is listed as a &amp;quot;possibleaction&amp;quot; in current game state).&lt;br /&gt;
&lt;br /&gt;
return false and display an error message if not (display no message if nomessage parameter is true). The displayed error message could be either &amp;quot;This move is not allowed at this moment&amp;quot; or &amp;quot;An action is already in progress&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  function onClickOnGameElement( evt )&lt;br /&gt;
  {&lt;br /&gt;
     if( this.checkAction( &amp;quot;my_action&amp;quot; ) )&lt;br /&gt;
     {&lt;br /&gt;
        // Do the action&lt;br /&gt;
     }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.ajaxcall( url, parameters, obj_callback, callback, callback_error )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This method must be used to send a player input to the game server.&lt;br /&gt;
&lt;br /&gt;
* url: the url of the action to perform. For a game, it must be: &amp;quot;/&amp;lt;mygame&amp;gt;/&amp;lt;mygame&amp;gt;/myAction.html&amp;quot;&lt;br /&gt;
* parameters: an array of parameter to send to the game server. Note that &amp;quot;lock:true&amp;quot; must always be specified in this list of parameter in order the interface can be locked during the server call.&lt;br /&gt;
* obj_callback: must be set to &amp;quot;this&amp;quot;.&lt;br /&gt;
* callback: a function to trigger when the server returns and everything went fine.&lt;br /&gt;
* callback_error: (optional and rarely used) a function to trigger when the server returns an error.&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
this.ajaxcall( &#039;/mygame/mygame/myaction.html&#039;, { lock: true, &lt;br /&gt;
   arg1: myarg1, &lt;br /&gt;
   arg2: myarg2, &lt;br /&gt;
   ...&lt;br /&gt;
}, this, function( result ) {&lt;br /&gt;
   // Do some stuff after a successful call&lt;br /&gt;
} );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Restricted arguments names (please don&#039;t use them):&lt;br /&gt;
* &amp;quot;action&amp;quot;&lt;br /&gt;
* &amp;quot;module&amp;quot;&lt;br /&gt;
* &amp;quot;class&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.confirmationDialog()&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Display a confirmation dialog with a yes/no choice.&lt;br /&gt;
&lt;br /&gt;
We advice you to NOT use this function unless the player action is really critical and could ruins the game, because it slows down the game and upset players.&lt;br /&gt;
&lt;br /&gt;
Usage: this.confirmationDialog( &amp;quot;Question to displayed&amp;quot;, callback_function_if_click_on_yes );&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
this.confirmationDialog( _(&#039;Are you sure to use this bonus (points penalty at the end of the game) ?&#039;),&lt;br /&gt;
                         dojo.hitch( this, function() {&lt;br /&gt;
                           this.ajaxcall( &#039;/seasons/seasons/useBonus.html&#039;,&lt;br /&gt;
                                { id:bonus_id, lock:true }, this, function( result ) {} );&lt;br /&gt;
                        } ) ); &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; addEventToClass: function( cssClassName, eventName, functionName )&lt;br /&gt;
: Same as dojo.connect(), but for all the nodes set with the specified cssClassName&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.addActionButton( id, label, method, (opt)destination, (opt)blinking, (opt)color )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You can use this method to add an action button in the main action status bar.&lt;br /&gt;
&lt;br /&gt;
Arguments:&lt;br /&gt;
* id: an element ID that should be unique in your HTML DOM document.&lt;br /&gt;
* label: the text of the button. Should be translatable (use _() function).&lt;br /&gt;
* method: the name of your method that must be triggered when the player clicks on this button.&lt;br /&gt;
* destination (optional): deprecated, do not use this. Use &#039;&#039;&#039;null&#039;&#039;&#039; as value if you need to specify other arguments.&lt;br /&gt;
* blinking (optional): if set to &#039;&#039;&#039;true&#039;&#039;&#039;, the button is going blink to catch player&#039;s attention. Please don&#039;t abuse of blinking button.&lt;br /&gt;
* color: could be &#039;&#039;&#039;blue&#039;&#039;&#039; (default), &#039;&#039;&#039;red&#039;&#039;&#039; or &#039;&#039;&#039;gray&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
You should only use this method in your &amp;quot;onUpdateActionButtons&amp;quot; method. Usually, you use it like this (from Hears example):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        onUpdateActionButtons: function( stateName, args ) {&lt;br /&gt;
                      &lt;br /&gt;
            if (this.isCurrentPlayerActive()) {            &lt;br /&gt;
                switch( stateName ) {&lt;br /&gt;
                case &#039;giveCards&#039;:&lt;br /&gt;
                    this.addActionButton( &#039;giveCards_button&#039;, _(&#039;Give selected cards&#039;), &#039;onGiveCards&#039; ); &lt;br /&gt;
                    break;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        },   &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the example above, we are adding a &amp;quot;Give selected cards&amp;quot; button in the case we are on game state &amp;quot;giveCards&amp;quot;. When player clicks on this button, it triggers our &amp;quot;onGiveCards&amp;quot; method.&lt;br /&gt;
&lt;br /&gt;
Example using blinking red button:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     this.addActionButton( &#039;commit_button&#039;, _(&#039;Confirm&#039;), &#039;onConfirm&#039;, null, true, &#039;red&#039;); &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: at least in studio example above will make button huge, because it sets it display of blinking things to &#039;&#039;&#039;block&#039;&#039;&#039;, &lt;br /&gt;
if you don&#039;t like it you have to change css display value&lt;br /&gt;
of the button to inline-block (the id of the button is the first argument, i.e &#039;commit_button&#039; in example above)&lt;br /&gt;
&lt;br /&gt;
== Translations ==&lt;br /&gt;
&lt;br /&gt;
See [[Translations]]&lt;br /&gt;
&lt;br /&gt;
== Notifications ==&lt;br /&gt;
&lt;br /&gt;
When something happens on the server side, your game interface Javascript logic received a notification.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s how you can handle these notifications on the client side.&lt;br /&gt;
&lt;br /&gt;
=== Subscribe to notifications ===&lt;br /&gt;
&lt;br /&gt;
Your Javascript &amp;quot;setupNotifications&amp;quot; method is the place where you can subscribe to notifications from your PHP code.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s how you associate one of your Javascript method to a notification &amp;quot;playDisc&amp;quot; (from Reversi example):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   // In setupNotifications method:&lt;br /&gt;
   dojo.subscribe( &#039;playDisc&#039;, this, &amp;quot;notif_playDisc&amp;quot; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: the &amp;quot;playDisc&amp;quot; corresponds to the name of the notification you define it in your PHP code, in your &amp;quot;notifyAllPlayers&amp;quot; or &amp;quot;notifyPlayer&amp;quot; method.&lt;br /&gt;
&lt;br /&gt;
Then, you have to define your &amp;quot;notif_playDisc&amp;quot; method:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        notif_playDisc: function( notif )&lt;br /&gt;
        {&lt;br /&gt;
            // Remove current possible moves (makes the board more clear)&lt;br /&gt;
            dojo.query( &#039;.possibleMove&#039; ).removeClass( &#039;possibleMove&#039; );        &lt;br /&gt;
        &lt;br /&gt;
            this.addDiscOnBoard( notif.args.x, notif.args.y, notif.args.player_id );&lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In a notification handler like our &amp;quot;notif_playDisc&amp;quot; method, you can access to all notifications arguments with &amp;quot;notif.args&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    // If you did this on PHP side:&lt;br /&gt;
    self::notifyAllPlayers( &amp;quot;myNotification&amp;quot;, &#039;&#039;, array( &amp;quot;myArgument&amp;quot; =&amp;gt; 3 ) );&lt;br /&gt;
&lt;br /&gt;
    // On Javascript side, you can access the &amp;quot;myArgument&amp;quot; like this:&lt;br /&gt;
    notif_myNotification: function( notif )&lt;br /&gt;
    {&lt;br /&gt;
       alert( &amp;quot;myArgument = &amp;quot; + notif.args.myArgument );&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Synchronous notifications ===&lt;br /&gt;
&lt;br /&gt;
When several notifications are received by your game interface, these notifications are processed immediately, one after the other, in the same exact order they have been generated in your PHP game logic.&lt;br /&gt;
&lt;br /&gt;
However, sometimes, you need to give some time to the players to figure out what happened on the game before jumping to the next notification. Indeed, in many games, they are a lot of automatic actions, and the computer is going to resolve all these actions very fast if you don&#039;t tell it not to do so.&lt;br /&gt;
&lt;br /&gt;
As an example, for Reversi, when someone is playing a disc, we want to wait 500 milliseconds before doing anything else in order the opponent player can figure out what move has been played.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s how we do this, right after our subscription:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
       dojo.subscribe( &#039;playDisc&#039;, this, &amp;quot;notif_playDisc&amp;quot; );&lt;br /&gt;
       this.notifqueue.setSynchronous( &#039;playDisc&#039;, 500 );   // Wait 500 milliseconds after executing the playDisc handler&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Pre-defined notification types ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;tableWindow&#039;&#039;&#039; - This defines notification to display [[Game_interface_logic:_yourgamename.js#Scoring_dialogs|Scoring Dialogs]], see below.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;message&#039;&#039;&#039; - This defines notification that shows on players log and have no other effect&lt;br /&gt;
&lt;br /&gt;
   // You can call this on php side without doing anything on client side&lt;br /&gt;
    self::notifyAllPlayers( &#039;message&#039;, &#039;hello&#039;, array( ) );&lt;br /&gt;
&lt;br /&gt;
== Tooltips ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.addTooltip( nodeId, _( helpString ), _( actionString ), delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Add a simple text tooltip to the DOM node.&lt;br /&gt;
&lt;br /&gt;
Specify &#039;helpString&#039; to display some information about &amp;quot;what is this game element?&amp;quot;.&lt;br /&gt;
Specify &#039;actionString&#039; to display some information about &amp;quot;what happens when I click on this element?&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
You must specify both helpString and actionString. Most of the time, you use only one and specify a void string (&amp;quot;&amp;quot;) for the other one.&lt;br /&gt;
&lt;br /&gt;
Usually, _() must be used for the text to be marked for translation.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Delay&amp;quot; is an optional parameter. Usually, it is primarily used to specify a zero delay for some game element when the tooltip gives really important information for the game - but remember: no essential information must be placed in tooltips as they won&#039;t be displayed in some browser (see Guidelines).&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   this.addTooltip( &#039;cardcount&#039;, _(&#039;Number of cards in hand&#039;), &#039;&#039; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.addTooltipHtml( nodeId, html, delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Add an HTML tooltip to the DOM node (for more elaborate content such as presenting a bigger version of a card).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.addTooltipToClass( cssClass, _( helpString ), _( actionString ), delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Add a simple text tooltip to all the DOM nodes set with this cssClass. &lt;br /&gt;
&lt;br /&gt;
IMPORTANT: all concerned nodes must have IDs to get tooltips.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.addTooltipHtmlToClass( cssClass, html, delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Add an HTML tooltip to to all the DOM nodes set with this cssClass (for more elaborate content such as presenting a bigger version of a card).&lt;br /&gt;
&lt;br /&gt;
IMPORTANT: all concerned nodes must have IDs to get tooltips&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.removeTooltip( nodeId )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Remove a tooltip from the DOM node.&lt;br /&gt;
&lt;br /&gt;
== Dialogs, warning messages, confirmation dialogs, ... ==&lt;br /&gt;
&lt;br /&gt;
=== Warning messages ===&lt;br /&gt;
&lt;br /&gt;
Sometimes, there is something important that is happening on the game and you have to make sure all players get the message. Most of the time, the evolution of the game situation or the game log is enough, but sometimes you need something more visible.&lt;br /&gt;
&lt;br /&gt;
Ex: someone fulfill one of the end of the game condition, so this is the last turn.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.showMessage( msg, type )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
showMessage shows a message in a big rectangular area on the top of the screen of current player.&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;msg&amp;quot; is the string to display. It should be translated.&lt;br /&gt;
* &amp;quot;type&amp;quot; can be set to &amp;quot;info&amp;quot; or &amp;quot;error&amp;quot;. If set to &amp;quot;info&amp;quot;, the message will be an informative message on a white background. If set to &amp;quot;error&amp;quot;, the message will be an error message on a red background.&lt;br /&gt;
&lt;br /&gt;
Important: the normal way to inform players about the progression of the game is the game log. &amp;quot;showMessage&amp;quot; is intrusive and should not be used often.&lt;br /&gt;
&lt;br /&gt;
=== Confirmation dialog ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;confirmationDialog( message, yesHandler, noHandler )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When an important action with a lot of consequences is triggered by the player, you may want to propose a confirmation dialog.&lt;br /&gt;
&lt;br /&gt;
CAREFUL: the general guidelines of BGA is to AVOID the use of confirmation dialog. Confirmation dialogs slow down the game and bother players. The players knows that they have to pay attention about each move when they are playing online.&lt;br /&gt;
&lt;br /&gt;
The situation where you should use a confirmation dialog are the following:&lt;br /&gt;
* It must not happen very often during a game.&lt;br /&gt;
* It must be linked to an action that can really &amp;quot;kill a game&amp;quot; if the player do not pay attention.&lt;br /&gt;
* It must be something that can be done by mistake (ex: a link on the action status bar).&lt;br /&gt;
&lt;br /&gt;
How to display a confirmation dialog:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        this.confirmationDialog( _(&#039;Are you sure you want to bake the pie?&#039;), dojo.hitch( this, function() {&lt;br /&gt;
            this.bakeThePie();&lt;br /&gt;
        } ) ); &lt;br /&gt;
        return; // nothing should be called or done after calling this, all action must be done in the handler  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Multiple choice dialog ===&lt;br /&gt;
You can use this dialog to give user a choice with small amount of options:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        var keys = [1,5,10];&lt;br /&gt;
        this.multipleChoiceDialog(&lt;br /&gt;
          _(&#039;How many bugs to fix?&amp;quot;), keys, &lt;br /&gt;
            dojo.hitch(this, function(choice) {&lt;br /&gt;
                            var bugchoice = keys[choice];&lt;br /&gt;
                            console.log(&#039;dialog callback with &#039;+bugchoice);&lt;br /&gt;
                            this.ajaxcall( &#039;/mygame/mygame/fixBugs.html&#039;, { bugs: bugchoice}, this, function( result ) {} );                        }));&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Dialogs ===&lt;br /&gt;
&lt;br /&gt;
At first, you shouldn&#039;t use dialogs windows.&lt;br /&gt;
&lt;br /&gt;
BGA guidelines specify that all game elements should be displayed on the main screen. Players can eventually scroll down to see game elements they don&#039;t need to see anytime, and you may eventually create anchors to move between game area section. Of course dialogs windows are very practical, but the thing is: all players know how to scroll down, and not all players know how to show up your dialog window. In addition, when the dialog shows up, players can&#039;t access the other game components.&lt;br /&gt;
&lt;br /&gt;
Sometimes although, you need to display a dialog window. Here is how you do this:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  // Create the new dialog. You should store the handler in a member variable to access it later&lt;br /&gt;
  this.myDlg = new dijit.Dialog({ title: _(&amp;quot;my dialog title to translate&amp;quot;) });&lt;br /&gt;
  &lt;br /&gt;
  // Create the HTML of my dialog. &lt;br /&gt;
  // The best practice here is to use [[Game_layout:_view_and_template:_yourgamename.view.php_and_yourgamename_yourgamename.tpl#Javascript_templates|Javascript templates]]&lt;br /&gt;
  var html = this.format_block( &#039;jstpl_myDialogTemplate&#039;, { &lt;br /&gt;
                arg1: myArg1,&lt;br /&gt;
                arg2: myArg2,&lt;br /&gt;
                ...&lt;br /&gt;
            } );  &lt;br /&gt;
  &lt;br /&gt;
  // Show the dialog&lt;br /&gt;
  this.myDlg.attr(&amp;quot;content&amp;quot;, html );&lt;br /&gt;
  this.myDlg.show(); &lt;br /&gt;
  &lt;br /&gt;
  // Now that the dialog has been displayed, you can connect your method to some dialog elements&lt;br /&gt;
  // Example, a &amp;quot;close&amp;quot; button:&lt;br /&gt;
  dojo.connect( $(&#039;closeDlg&#039;), &#039;onclick&#039;, this, function(evt){&lt;br /&gt;
                evt.preventDefault();&lt;br /&gt;
                this.myDlg.hide();&lt;br /&gt;
            } );  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Tip: be careful with &amp;quot;hide()&amp;quot; method to close your dialog: the dialog and its content is not completely removed from the DOM. It can cause you problems if you try to display the same dialog several times. A good practice is to wrap all the content of your dialog in a &amp;lt;nowiki&amp;gt;&amp;lt;div id=&#039;myDlgContent&#039;&amp;gt;&amp;lt;/nowiki&amp;gt; div element, and to call &amp;quot;dojo.destroy(&#039;myDlgContent&#039;)&amp;quot; before displaying your dialog.&lt;br /&gt;
&lt;br /&gt;
=== Scoring dialogs ===&lt;br /&gt;
&lt;br /&gt;
Sometimes at the end of a round you want to display a big table that details the points wins in each section of the game.&lt;br /&gt;
&lt;br /&gt;
Example: in Hearts game, we display at the end of each round the number of &amp;quot;heart&amp;quot; cards collected by each player, the player who collected the Queen of Spades, and the total number of points loose by each player.&lt;br /&gt;
&lt;br /&gt;
Scoring dialogs are managed entirely on &#039;&#039;&#039;PHP side&#039;&#039;&#039;, but they are described here as their effects are visible only on client side.&lt;br /&gt;
&lt;br /&gt;
Displaying a scoring dialog is quite simple and is using a special notification type: &amp;quot;tableWindow&amp;quot;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  // on PHP side:&lt;br /&gt;
  $this-&amp;gt;notifyAllPlayers( &amp;quot;tableWindow&amp;quot;, &#039;&#039;, array(&lt;br /&gt;
            &amp;quot;id&amp;quot; =&amp;gt; &#039;finalScoring&#039;,&lt;br /&gt;
            &amp;quot;title&amp;quot; =&amp;gt; clienttranslate(&amp;quot;Title of the scoring dialog&amp;quot;),&lt;br /&gt;
            &amp;quot;table&amp;quot; =&amp;gt; $table&lt;br /&gt;
        ) ); &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;table&amp;quot; argument is a 2 dimensional PHP array that describe the table you want to display, line by line and column by column.&lt;br /&gt;
&lt;br /&gt;
Example: display an 3x3 array of strings&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   $table = array(&lt;br /&gt;
      array( &amp;quot;one&amp;quot;, &amp;quot;two&amp;quot;, &amp;quot;three&amp;quot; ),    // This is my first line&lt;br /&gt;
      array( &amp;quot;four&amp;quot;, &amp;quot;five&amp;quot;, &amp;quot;six&amp;quot; ),    // This is my second line&lt;br /&gt;
      array( &amp;quot;seven&amp;quot;, &amp;quot;height&amp;quot;, &amp;quot;nine&amp;quot; )    // This is my third line&lt;br /&gt;
   );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As you can see above, in each &amp;quot;cell&amp;quot; of your array you can display a simple string value. But you can also display a complex value with a template and associated arguments like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   $table = array(&lt;br /&gt;
      array( &amp;quot;one&amp;quot;, &amp;quot;two&amp;quot;, array( &amp;quot;str&amp;quot; =&amp;gt; &amp;quot;a string with an ${argument}&amp;quot;, &amp;quot;args&amp;quot; =&amp;gt; array( &#039;argument&#039; =&amp;gt; &#039;argument_value&#039; )  ) ),&lt;br /&gt;
      array( &amp;quot;four&amp;quot;, &amp;quot;five&amp;quot;, &amp;quot;six&amp;quot; ), &lt;br /&gt;
      array( &amp;quot;seven&amp;quot;, &amp;quot;height&amp;quot;, &amp;quot;nine&amp;quot; )&lt;br /&gt;
   );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is especially useful when you want to display player names with colors. Example from &amp;quot;Hearts&amp;quot;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        $firstRow = array( &#039;&#039; );&lt;br /&gt;
        foreach( $players as $player_id =&amp;gt; $player )&lt;br /&gt;
        {&lt;br /&gt;
            $firstRow[] = array( &#039;str&#039; =&amp;gt; &#039;${player_name}&#039;,&lt;br /&gt;
                                 &#039;args&#039; =&amp;gt; array( &#039;player_name&#039; =&amp;gt; $player[&#039;player_name&#039;] ),&lt;br /&gt;
                                 &#039;type&#039; =&amp;gt; &#039;header&#039;&lt;br /&gt;
                               );&lt;br /&gt;
        }&lt;br /&gt;
        $table[] = $firstRow;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also use three extra attributes in the parameter array for the notification:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   $this-&amp;gt;notifyAllPlayers( &amp;quot;tableWindow&amp;quot;, &#039;&#039;, array(&lt;br /&gt;
            &amp;quot;id&amp;quot; =&amp;gt; &#039;finalScoring&#039;,&lt;br /&gt;
            &amp;quot;title&amp;quot; =&amp;gt; clienttranslate(&amp;quot;Title of the scoring dialog&amp;quot;),&lt;br /&gt;
            &amp;quot;table&amp;quot; =&amp;gt; $table,&lt;br /&gt;
            &amp;quot;header&amp;quot; =&amp;gt; array(&#039;str&#039; =&amp;gt; clienttranslate(&#039;Table header with parameter ${number}&#039;),&lt;br /&gt;
                                 &#039;args&#039; =&amp;gt; array( &#039;number&#039; =&amp;gt; 3 ),&lt;br /&gt;
                               ),&lt;br /&gt;
            &amp;quot;footer&amp;quot; =&amp;gt; &#039;&amp;lt;div&amp;gt;Some footer&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
            &amp;quot;closing&amp;quot; =&amp;gt; clienttranslate( &amp;quot;Closing button label&amp;quot; )&lt;br /&gt;
        ) ); &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;header&#039;&#039;&#039;: the content for this parameter will display before the table (also, the html will be parsed and player names will be colored according to the current game colors). &lt;br /&gt;
*&#039;&#039;&#039;footer&#039;&#039;&#039;: the content for this parameter will display after the table (no parsing for coloring the player names)&lt;br /&gt;
*&#039;&#039;&#039;closing&#039;&#039;&#039;: if this parameter is used, a button will be displayed with this label at the bottom of the popup and will allow players to close it (more easily than by clicking the top right &#039;cross&#039; icon).&lt;br /&gt;
&lt;br /&gt;
=== Scoring animated display ===&lt;br /&gt;
&lt;br /&gt;
Sometimes (Terra Mystica final scoring for example), you may want to display a score value over an element to make the scoring easier to follow for the players.&lt;br /&gt;
You can do it with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   this.displayScoring( anchor_id, color, score );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Speech bubble ===&lt;br /&gt;
&lt;br /&gt;
For better interactivity in some games (Love Letter for example), you may use comic book style speech bubbles to express the players voices.&lt;br /&gt;
This is done with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   this.showBubble( anchor_id, text, delay, duration, custom_class )&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
delay in milliseconds is optional (default 0)&lt;br /&gt;
duration in milliseconds is optional (default 3000)&lt;br /&gt;
custom_class is optional, if you need to override the default bubble style&lt;br /&gt;
&lt;br /&gt;
== Update players score ==&lt;br /&gt;
&lt;br /&gt;
Increase a player score (with a positive or negative number):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  this.scoreCtrl[ player_id ].incValue( score_delta );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Set a player score to a specific value:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  this.scoreCtrl[ player_id ].setValue( new_score );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Players panels ==&lt;br /&gt;
&lt;br /&gt;
=== Adding stuff to player&#039;s panel ===&lt;br /&gt;
&lt;br /&gt;
At first, create a new &amp;quot;JS template&amp;quot; string in your template (tpl) file:&lt;br /&gt;
&lt;br /&gt;
(from Gomoku example)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
var jstpl_player_board = &#039;\&amp;lt;div class=&amp;quot;cp_board&amp;quot;&amp;gt;\&lt;br /&gt;
    &amp;lt;div id=&amp;quot;stoneicon_p${id}&amp;quot; class=&amp;quot;gmk_stoneicon gmk_stoneicon_${color}&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;span id=&amp;quot;stonecount_p${id}&amp;quot;&amp;gt;0&amp;lt;/span&amp;gt;\&lt;br /&gt;
&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then, you add this piece of code in your JS file to add this template to each player panel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
            // Setting up player boards&lt;br /&gt;
            for( var player_id in gamedatas.players )&lt;br /&gt;
            {&lt;br /&gt;
                var player = gamedatas.players[player_id];&lt;br /&gt;
                         &lt;br /&gt;
                // Setting up players boards if needed&lt;br /&gt;
                var player_board_div = $(&#039;player_board_&#039;+player_id);&lt;br /&gt;
                dojo.place( this.format_block(&#039;jstpl_player_board&#039;, player ), player_board_div );&lt;br /&gt;
            }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Note: the code above is of course from your &amp;quot;setup&amp;quot; function in your Javascript).&lt;br /&gt;
&lt;br /&gt;
Very often, you have to distinguish current player and others players. In this case, you just have to create another JS template (ex: jstpl_otherplayer_board) and use it when &amp;quot;player_id&amp;quot; is different than &amp;quot;this.player_id&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Player&#039;s panel disabling/enabling ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.disablePlayerPanel( player_id )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Disable given player panel (the panel background become gray).&lt;br /&gt;
&lt;br /&gt;
Usually, this is used to signal that this played passes, or will be inactive during a while.&lt;br /&gt;
&lt;br /&gt;
Note that the only effect of this is visual. There are no consequences on the behaviour of the panel itself.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.enablePlayerPanel( player_id )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Enable a player panel that has been disabled before.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.enableAllPlayerPanels()&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Enable all player panels that has been disabled before.&lt;br /&gt;
&lt;br /&gt;
== Image loading ==&lt;br /&gt;
&lt;br /&gt;
See also [[Game_art:_img_directory]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Be careful&#039;&#039;&#039;: by default, ALL images of your img directory are loaded on a player&#039;s browser when he loads the game. For this reason, don&#039;t let in your img directory images that are not useful, otherwise it&#039;s going to slowdown the game load.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;dontPreloadImage( image_file_name )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Using dontPreloadImage, you tell the interface to not preload a specific image in your img directory.&lt;br /&gt;
&lt;br /&gt;
Example of use:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
this.dontPreloadImage( &#039;cards.png&#039; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is particularly useful if for example you have 2 different themes for a game. To accelerate the loading of the game, you can specify to not preload images corresponding to the other theme.&lt;br /&gt;
&lt;br /&gt;
Another example of use: in &amp;quot;Gosu&amp;quot; game with Kamakor extension, you play with 5 sets of cards among 10 available. Cards images are organized by sets, and we only preload the images corresponding to the 5 current sets with &#039;&#039;&#039;ensureSpecificGameImageLoading( image_file_names_array )&#039;&#039;&#039;.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// By default, do not preload anything&lt;br /&gt;
this.dontPreloadImage( &#039;cards.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan1.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan2.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan3.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan4.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan5.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan6.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan7.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan8.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan9.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan10.png&#039; );&lt;br /&gt;
var to_preload = [];&lt;br /&gt;
for( i in this.gamedatas.clans )&lt;br /&gt;
{&lt;br /&gt;
	var clan_id = this.gamedatas.clans[i];&lt;br /&gt;
	to_preload.push( &#039;clan&#039;+clan_id+&#039;.png&#039; );&lt;br /&gt;
}&lt;br /&gt;
if( to_preload.length == 5 )&lt;br /&gt;
{&lt;br /&gt;
	this.ensureSpecificGameImageLoading( to_preload );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; You don&#039;t need to specify to not preload game box images (game_box.png, game_box75.png...) since they are not preloaded by default.&lt;br /&gt;
&lt;br /&gt;
== Other useful stuff ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;dojo.hitch&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
With dojo.hitch, you can create a callback function that will run with your game object context whatever happen.&lt;br /&gt;
&lt;br /&gt;
Typical example: display a BGA confirmation dialog with a callback function created with dojo.hitch:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        this.confirmationDialog( _(&#039;Are you sure you want to make this?&#039;), dojo.hitch( this, function() {&lt;br /&gt;
            this.ajaxcall( &#039;/mygame/mygame/makeThis.html&#039;, { lock:true }, this, function( result ) {} );&lt;br /&gt;
        } ) );   &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the example above, using dojo.hitch, we are sure that the &amp;quot;this&amp;quot; object will be set when the callback is called.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; updateCounters(counters)&lt;br /&gt;
: Useful for updating game counters in the player panel (such as resources). &lt;br /&gt;
: &#039;counters&#039; arg is an associative array [counter_name_value =&amp;gt; [ &#039;counter_name&#039; =&amp;gt; counter_name_value, &#039;counter_value&#039; =&amp;gt; counter_value_value], ... ]&lt;br /&gt;
: All counters must be referenced in this.gamedatas.counters and will be updated.&lt;br /&gt;
: DOM objects referenced by &#039;counter_name&#039; will have their innerHTML updated with &#039;counter_value&#039;.&lt;br /&gt;
&lt;br /&gt;
== BGA GUI components ==&lt;br /&gt;
&lt;br /&gt;
BGA framework provides some useful ready-to-use components for the game interface:&lt;br /&gt;
&lt;br /&gt;
[[Studio#BGA_Studio_game_components_reference]]&lt;br /&gt;
&lt;br /&gt;
Note that each time you are using an additional component, you must declare it at the top of your Javascript file in the list of modules used.&lt;br /&gt;
&lt;br /&gt;
Example if you are using &amp;quot;ebg.stock&amp;quot;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
define([&lt;br /&gt;
    &amp;quot;dojo&amp;quot;,&amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
    &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
    &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
    &amp;quot;ebg/stock&amp;quot;  /// &amp;lt;=== we are using ebg.stock module&lt;br /&gt;
],&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://sr.doc.boardgamearena.com/index.php?title=Game_interface_logic:_yourgamename.js&amp;diff=3028</id>
		<title>Game interface logic: yourgamename.js</title>
		<link rel="alternate" type="text/html" href="https://sr.doc.boardgamearena.com/index.php?title=Game_interface_logic:_yourgamename.js&amp;diff=3028"/>
		<updated>2018-05-15T10:00:21Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Dialogs, warning messages, confirmation dialogs, ... */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This is the main file for your game interface. Here you will define:&lt;br /&gt;
&lt;br /&gt;
* which actions on the page will generate calls to the server&lt;br /&gt;
* what happens when you get a notification for change from the server and how it will show in the browser. &lt;br /&gt;
&lt;br /&gt;
== File structure ==&lt;br /&gt;
&lt;br /&gt;
The details on how the file is structured is described directly with comments on the code skeleton provided to you.&lt;br /&gt;
&lt;br /&gt;
Basically, here&#039;s this structure:&lt;br /&gt;
* constructor: here you can define variable global to your whole interface.&lt;br /&gt;
* setup: this method is called when the page is refreshed, in order you can setup the game interface.&lt;br /&gt;
* onEnteringState: the method is called when entering in a new game state. This way you can customize the view for this game state.&lt;br /&gt;
* onLeavingState: the method is called when leaving a game state.&lt;br /&gt;
* onUpdateActionButtons: called when entering in a new state, in order you can add action buttons in status bar.&lt;br /&gt;
* (utility methods): at this place you can define your utility methods&lt;br /&gt;
* (player&#039;s actions): at this place you can write your handlers for player&#039;s action on the interface (ex: click on an item).&lt;br /&gt;
* setupNotifications: in this method you associate notifications with notification handlers. This way, for each game notification, you trigger a javascript method to handle it and update the game interface.&lt;br /&gt;
* (notification handlers): at this place you can define your notifications handlers.&lt;br /&gt;
&lt;br /&gt;
== General tips ==&lt;br /&gt;
&lt;br /&gt;
; this.player_id&lt;br /&gt;
: Id of the player on whose browser the code is running.&lt;br /&gt;
&lt;br /&gt;
; this.isSpectator&lt;br /&gt;
: Flag set to true if the user at the table is a spectator (not a player).&lt;br /&gt;
: Note: this is not a function, its a variable.&lt;br /&gt;
: Note: if you want to hide some element for spectators, you&#039;d better use [[Game_interface_stylesheet:_yourgamename.css#spectatorMode|CSS &#039;spectatorMode&#039; class]].&lt;br /&gt;
&lt;br /&gt;
; this.gamedatas&lt;br /&gt;
: Contains your initial set of datas to init the game, created at game start or game refresh (F5)&lt;br /&gt;
: You can update it as needed to keep an up to date reference of the game on the client side if you need it (most of the time you don&#039;t).&lt;br /&gt;
&lt;br /&gt;
; this.isCurrentPlayerActive()&lt;br /&gt;
: Returns true if the player on whose browser the code is running is currently active (it&#039;s his turn to play)&lt;br /&gt;
&lt;br /&gt;
; this.getActivePlayerId()&lt;br /&gt;
: Return the ID of active player, or null if we are not in a &amp;quot;activeplayer&amp;quot; type state.&lt;br /&gt;
&lt;br /&gt;
; this.getActivePlayers()&lt;br /&gt;
: Return an array with the IDs of players that are currently active (or an empty array if there is not).&lt;br /&gt;
&lt;br /&gt;
== Dojo framework ==&lt;br /&gt;
&lt;br /&gt;
BGA is using the [http://dojotoolkit.org/ Dojo Javascript framework].&lt;br /&gt;
&lt;br /&gt;
The Dojo framework allows us to do complex things easier, and the BGA framework is using Dojo framework a lot.&lt;br /&gt;
&lt;br /&gt;
To realize game although, you only need to use a few part of the Dojo framework. All the Dojo methods you need to use are describe on this page.&lt;br /&gt;
&lt;br /&gt;
For performance reason, when deploying a game the js code is minified using Shrinksafe. Some advanced syntax may not be compatible with this process. In particular:&lt;br /&gt;
* you should not use reserved keywords from the javascript language as variables&lt;br /&gt;
* you should not declare default argument values in function declaration, the following syntax is invalid for Shriksafe: function myFunc(requiredArg, optionalArg = &#039;defaultValue&#039;) {}&lt;br /&gt;
&lt;br /&gt;
== Access and manipulate the DOM ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;$(&#039;some_html_element_id&#039;)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The $() function is used to get some HTML element using its &amp;quot;id&amp;quot; attribute.&lt;br /&gt;
&lt;br /&gt;
Example 1: modify the content of a &amp;quot;span&amp;quot; element:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
In your HTML code:&lt;br /&gt;
   &amp;lt;span id=&amp;quot;a_value_in_the_game_interface&amp;quot;&amp;gt;1234&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In your Javascript code:&lt;br /&gt;
   $(&#039;a_value_in_the_game_interface&#039;).innerHTML = &amp;quot;9999&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: $() is the standard method to access some HTML element with BGA Framework. You must not use &amp;quot;getElementById&amp;quot; function.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;dojo.style&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
With dojo.style you can modify a CSS property of any HTML element of your interface.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     // Make an element disappear&lt;br /&gt;
     dojo.style( &#039;my_element&#039;, &#039;display&#039;, &#039;none&#039; );&lt;br /&gt;
&lt;br /&gt;
     // Give an element a 2px border&lt;br /&gt;
     dojo.style( &#039;my_element&#039;, &#039;borderWidth&#039;, &#039;2px&#039; );&lt;br /&gt;
&lt;br /&gt;
     // Change the background position of an element&lt;br /&gt;
     // (very practical when you are using CSS sprite to transform an element to another)&lt;br /&gt;
     dojo.style( &#039;my_element&#039;, &#039;backgroundPosition&#039;, &#039;-20px -50px&#039; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: you must always use dojo.style to modify CSS properties of HTML elements.&lt;br /&gt;
&lt;br /&gt;
Note²: if you have to modify several CSS properties of an element, or if you have some complex CSS transformation to do, you should consider using dojo.addClass/dojo.removeClass (see below).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;dojo CSS classes manipulation&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In many situation, a bunch of many small CSS property update can be replaced by a CSS class change (ie: you add a CSS class to your element instead of applying all modification manually).&lt;br /&gt;
&lt;br /&gt;
Advantages are:&lt;br /&gt;
* All your CSS stuff remains in your CSS file.&lt;br /&gt;
* You can add/remove a list of CSS modifications with a simple function and whithout error.&lt;br /&gt;
* You can test if you applied the stuff to an element with &amp;quot;dojo.hasClass&amp;quot; method.&lt;br /&gt;
&lt;br /&gt;
Example from &amp;quot;Reversi&amp;quot;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    // We add &amp;quot;possibleMove&amp;quot; to an element&lt;br /&gt;
    dojo.addClass( &#039;square_&#039;+x+&#039;_&#039;+y, &#039;possibleMove&#039; );&lt;br /&gt;
&lt;br /&gt;
    // In our CSS file, the class is defined as:&lt;br /&gt;
    .possibleMove {&lt;br /&gt;
      background-color: white;&lt;br /&gt;
      opacity: 0.2;&lt;br /&gt;
      filter:alpha(opacity=20); /* For IE8 and earlier */  &lt;br /&gt;
      cursor: pointer;  &lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
     // So we&#039;ve applied 4 CSS property change in one line of code.&lt;br /&gt;
&lt;br /&gt;
     // ... and when we need to check if a square is a possible move on client side:&lt;br /&gt;
     if( dojo.hasClass( &#039;square_&#039;+x+&#039;_&#039;+y, &#039;possibleMove&#039; ) )&lt;br /&gt;
     { ... }&lt;br /&gt;
&lt;br /&gt;
     // ... and if we want to remove all possible moves in one line of code (see &amp;quot;dojo.query&amp;quot; method):&lt;br /&gt;
     dojo.query( &#039;.possibleMove&#039; ).removeClass( &#039;possibleMove&#039; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Conclusion: we encourage you to use dojo.addClass, dojo.removeClass and dojo.hasClass to make your life easier :)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;dojo.query&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
With dojo.query, you can query a bunch of HTML elements with a single function, with a &amp;quot;CSS selector&amp;quot; style.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     // All elements with class &amp;quot;possibleMove&amp;quot;:&lt;br /&gt;
     var elements = dojo.query( &#039;.possibleMove&#039; );&lt;br /&gt;
&lt;br /&gt;
     // Count number of tokens (ie: elements with class &amp;quot;token&amp;quot;) on the board (ie: element with id &amp;quot;board&amp;quot;):&lt;br /&gt;
     dojo.query( &#039;#board .token&#039; ).length;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
But what is really cool with dojo.query is that you can combine it with almost all methods above.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     // Trigger a method when the mouse enter in any element with class &amp;quot;meeple&amp;quot;:&lt;br /&gt;
     dojo.query( &#039;.meeple&#039; ).connect( &#039;onmouseenter&#039;, this, &#039;myMethodToTrigger&#039; );&lt;br /&gt;
&lt;br /&gt;
     // Hide all meeples who are on the board&lt;br /&gt;
     dojo.query( &#039;#board .meeple&#039; ).style( &#039;display&#039;, &#039;none&#039; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;dojo.place&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
dojo.place is the best function to insert some HTML code somewhere in your game interface without breaking something. It is much better to use that &amp;quot;innerHTML=&#039;&#039;&amp;quot; method as soon as you must insert HTML tags and not only values.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     // Insert your HTML code as a child of a container element&lt;br /&gt;
     dojo.place( &amp;quot;&amp;lt;your html code&amp;gt;&amp;quot;, &amp;quot;your_container_element_id&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
     // Replace the container element with your new html&lt;br /&gt;
     dojo.place( &amp;quot;&amp;lt;your html code&amp;gt;&amp;quot;, &amp;quot;your_container_element_id&amp;quot;, &amp;quot;replace&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The third parameter of dojo.place can take various interesting value.&lt;br /&gt;
&lt;br /&gt;
values possibles :&lt;br /&gt;
&lt;br /&gt;
&amp;quot;replace&amp;quot; : (see description above).&lt;br /&gt;
&lt;br /&gt;
&amp;quot;first&amp;quot; : Places the node as a child of the reference node. The node is placed as the first child.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;last&amp;quot; : Places the node as a child of the reference node. The node is placed as the last child.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;before&amp;quot; : places the node right before the reference node.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;last (value by default) &amp;quot; : places the node right after the reference node.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;only&amp;quot; : replaces all children of the reference node with the node.&lt;br /&gt;
&lt;br /&gt;
positif integer : This parameter can be a positif integer. In this case, the node will be placed as a child of the reference node with this number (counting from 0). If the number is more than number of children, the node will be appended to the reference node making it the last child. &lt;br /&gt;
&lt;br /&gt;
See also full doc on dojo.place : [http://dojotoolkit.org/reference-guide/1.7/dojo/place.]&lt;br /&gt;
&lt;br /&gt;
Usually, when you want to insert some piece of HTML in your game interface, you should use &amp;quot;[[Game_layout:_view_and_template:_yourgamename.view.php_and_yourgamename_yourgamename.tpl#Javascript_templates|Javascript templates]]&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;addStyleToClass: function( cssClassName, cssProperty, propertyValue )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Same as dojo.style(), but for all the nodes set with the specified cssClassName&lt;br /&gt;
&lt;br /&gt;
=== Animations ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Dojo Animations&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
BGA animations is based on Dojo Animation ([http://dojotoolkit.org/documentation/tutorials/1.8/animation/ see tutorial here]).&lt;br /&gt;
&lt;br /&gt;
However, most of the time, you can just use methods below, which are built on top of Dojo Animation.&lt;br /&gt;
&lt;br /&gt;
Note: one interesting method from Dojo that could be useful from time to time is &amp;quot;Dojo.Animation&amp;quot;. It allows you to make any CSS property &amp;quot;slide&amp;quot; from one value to another.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.slideToObject( mobile_obj, target_obj, duration, delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You can use slideToObject to &amp;quot;slide&amp;quot; an element to a target position.&lt;br /&gt;
&lt;br /&gt;
Sliding element on the game area is the recommended and the most used way to animate your game interface. Using slides allow players to figure out what is happening on the game, as if they were playing with the real boardgame.&lt;br /&gt;
&lt;br /&gt;
The parameters are:&lt;br /&gt;
* mobile_obj: the ID of the object to move. This object must be &amp;quot;relative&amp;quot; or &amp;quot;absolute&amp;quot; positioned.&lt;br /&gt;
* target_obj: the ID of the target object. This object must be &amp;quot;relative&amp;quot; or &amp;quot;absolute&amp;quot; positioned. Note that it is not mandatory that mobile_obj and target_obj have the same size. If their size are different, the system slides the center of mobile_obj to the center of target_obj.&lt;br /&gt;
* duration: (optional) defines the duration in millisecond of the slide. The default is 500 milliseconds.&lt;br /&gt;
* delay: (optional). If you defines a delay, the slide will start only after this delay. This is particularly useful when you want to slide several object from the same position to the same position: you can give a 0ms delay to the first object, a 100ms delay to the second one, a 200ms delay to the third one, ... this way they won&#039;t be superposed during the slide.&lt;br /&gt;
&lt;br /&gt;
BE CAREFUL: The method returns an dojo.fx animation, so you can combine it with other animation if you want to. It means that you have to call the &amp;quot;play()&amp;quot; method, otherwise the animation WON&#039;T START.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   this.slideToObject( &amp;quot;some_token&amp;quot;, &amp;quot;some_place_on_board&amp;quot; ).play();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.slideToObjectPos( mobile_obj, target_obj, target_x, target_y, duration, delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This method does exactly the same as &amp;quot;slideToObject&amp;quot;, except than you can specify some (x,y) coordinates. This way, &amp;quot;mobile_obj&amp;quot; will slide to the specified x,y position relatively to &amp;quot;target_obj&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Example: slide a token to some place on the board, 10 pixels to the bottom:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   this.slideToObjectPos( &amp;quot;some_token&amp;quot;, &amp;quot;some_place_on_board&amp;quot;, 0, 10 ).play();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.slideTemporaryObject( mobile_obj_html, mobile_obj_parent, from, to, duration, delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This method is useful when you want to slide a temporary HTML object from one place to another. As this object does not exists before the animation and won&#039;t remain after, it could be complex to create this object (with dojo.place), to place it at its origin (with placeOnObject) to slide it (with slideToObject) and to make it disappear at the end.&lt;br /&gt;
&lt;br /&gt;
slideTemporaryObject does all of this for you:&lt;br /&gt;
* mobile_obj_html is a piece of HTML code that represent the object to slide.&lt;br /&gt;
* mobile_obj_parent is the ID of an HTML element of your interface that will be the parent of this temporary HTML object.&lt;br /&gt;
* from is the ID of the origin of the slide.&lt;br /&gt;
* to is the ID of the target of the slide.&lt;br /&gt;
* duration/delay works exactly like in &amp;quot;slideToObject&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
this.slideTemporaryObject( &#039;&amp;lt;div class=&amp;quot;token_icon&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;, &#039;tokens&#039;, &#039;my_origin_div&#039;, &#039;my_target_div&#039; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.slideToObjectAndDestroy: function( node, to, time, delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This method is a handy shortcut to slide an existing HTML object to some place then destroy it upon arrival. It can be used for example to move a victory token or a card from the board to the player panel to show that the player earns it, then destroy it when we don&#039;t need to keep it visible on the player panel.&lt;br /&gt;
&lt;br /&gt;
It works the same as this.slideToObject and takes the same arguments. &lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
this.slideToObjectAndDestroy( &amp;quot;some_token&amp;quot;, &amp;quot;some_place_on_board&amp;quot;, 1000, 0 );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.fadeOutAndDestroy( node, duration, delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This function fade out the target HTML node, then destroy it.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   this.fadeOutAndDestroy( &amp;quot;a_card_that_must_disappear&amp;quot; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
CAREFUL: the HTML node still exists until during few milliseconds, until the fadeOut has been completed.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Rotating elements&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You can check here [http://jimfulton.info/demos/dojo-animated-rotate.html an example of use] of Dojo to make an element rotate.&lt;br /&gt;
&lt;br /&gt;
This example combines &amp;quot;Dojo.Animation&amp;quot; method and a CSS3 property that allow you to rotate the element.&lt;br /&gt;
&lt;br /&gt;
IMPORTANT: to asses browser compatibility, you must select the CSS property to use just like in the example (see sourcecode below):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        var transform;&lt;br /&gt;
        dojo.forEach(&lt;br /&gt;
            [&#039;transform&#039;, &#039;WebkitTransform&#039;, &#039;msTransform&#039;,&lt;br /&gt;
             &#039;MozTransform&#039;, &#039;OTransform&#039;],&lt;br /&gt;
            function (name) {&lt;br /&gt;
                if (typeof dojo.body().style[name] != &#039;undefined&#039;) {&lt;br /&gt;
                    transform = name;&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        // ... and then use &amp;quot;transform&amp;quot; as the name of your CSS property for rotation&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Moving elements ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.placeOnObject( mobile_obj, target_obj )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
placeOnObject works exactly like &amp;quot;slideToObject&amp;quot;, except that the effect is immediate.&lt;br /&gt;
&lt;br /&gt;
This is not really an animation, but placeOnObject is frequently used before starting an animation.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  // (We just created an object &amp;quot;my_new_token&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
  // Place the new token on current player board&lt;br /&gt;
  this.placeOnObject( &amp;quot;my_new_token&amp;quot;, &amp;quot;overall_player_board_&amp;quot;+this.player_id );&lt;br /&gt;
  &lt;br /&gt;
  // Then slide it to its position on the board&lt;br /&gt;
  this.slideToObject( &amp;quot;my_new_token&amp;quot;, &amp;quot;a_place_on_board&amp;quot; ).play();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.placeOnObjectPos( mobile_obj, target_obj, target_x, target_y )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This method works exactly like placeOnObject, except than you can specify some (x,y) coordinates. This way, &amp;quot;mobile_obj&amp;quot; will be placed to the specified x,y position relatively to &amp;quot;target_obj&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.attachToNewParent( mobile_obj, target_obj )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
With this method, you change the HTML parent of &amp;quot;mobile_obj&amp;quot; element. &amp;quot;target_obj&amp;quot; is the new parent of this element. The beauty of &lt;br /&gt;
attachToNewParent is that the mobile_obj element DOES NOT MOVE during this process.&lt;br /&gt;
&lt;br /&gt;
Note: what happens is that the method calculate a relative position of mobile_obj to make sure it does not move after the HTML parent changes.&lt;br /&gt;
&lt;br /&gt;
Why using this method?&lt;br /&gt;
&lt;br /&gt;
Changing the HTML parent of an element can be useful for the following reasons:&lt;br /&gt;
* When the HTML parent moves, all its child are moving with them. If some game elements is no more linked with a parent HTML object, you may want to attach it to another place.&lt;br /&gt;
* The z_order (vertical order of display) depends on the position in the DOM, so you may need to change the parent of some game elements when they are moving in your game area.&lt;br /&gt;
&lt;br /&gt;
CAREFUL: this function destroys original object and places a clone onto a new parent, this will break all references to this HTML element (ex: dojo.connect).&lt;br /&gt;
&lt;br /&gt;
== Players input ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;dojo.connect&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Used to associate a player event with one of your notification method.&lt;br /&gt;
&lt;br /&gt;
Example: associate a click on an element (&amp;quot;my_element&amp;quot;) with one of our method (&amp;quot;onClickOnMyElement&amp;quot;):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
      dojo.connect( $(&#039;my_element&#039;), &#039;onclick&#039;, this, &#039;onClickOnMyElement&#039; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: this is the only possible correct way to associate a player input event to your code, and you must not use anything else.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.checkAction( &amp;quot;my_action_name&amp;quot; )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Usage: checkAction: function( action, nomessage )&lt;br /&gt;
&lt;br /&gt;
Check if player can do the specified action by taking into account:&lt;br /&gt;
* current game state&lt;br /&gt;
* interface locking (a player can&#039;t do any action if an action is already in progress)&lt;br /&gt;
&lt;br /&gt;
return true if action is authorized (ie: the action is listed as a &amp;quot;possibleaction&amp;quot; in current game state).&lt;br /&gt;
&lt;br /&gt;
return false and display an error message if not (display no message if nomessage parameter is true). The displayed error message could be either &amp;quot;This move is not allowed at this moment&amp;quot; or &amp;quot;An action is already in progress&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  function onClickOnGameElement( evt )&lt;br /&gt;
  {&lt;br /&gt;
     if( this.checkAction( &amp;quot;my_action&amp;quot; ) )&lt;br /&gt;
     {&lt;br /&gt;
        // Do the action&lt;br /&gt;
     }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.ajaxcall( url, parameters, obj_callback, callback, callback_error )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This method must be used to send a player input to the game server.&lt;br /&gt;
&lt;br /&gt;
* url: the url of the action to perform. For a game, it must be: &amp;quot;/&amp;lt;mygame&amp;gt;/&amp;lt;mygame&amp;gt;/myAction.html&amp;quot;&lt;br /&gt;
* parameters: an array of parameter to send to the game server. Note that &amp;quot;lock:true&amp;quot; must always be specified in this list of parameter in order the interface can be locked during the server call.&lt;br /&gt;
* obj_callback: must be set to &amp;quot;this&amp;quot;.&lt;br /&gt;
* callback: a function to trigger when the server returns and everything went fine.&lt;br /&gt;
* callback_error: (optional and rarely used) a function to trigger when the server returns an error.&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
this.ajaxcall( &#039;/mygame/mygame/myaction.html&#039;, { lock: true, &lt;br /&gt;
   arg1: myarg1, &lt;br /&gt;
   arg2: myarg2, &lt;br /&gt;
   ...&lt;br /&gt;
}, this, function( result ) {&lt;br /&gt;
   // Do some stuff after a successful call&lt;br /&gt;
} );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Restricted arguments names (please don&#039;t use them):&lt;br /&gt;
* &amp;quot;action&amp;quot;&lt;br /&gt;
* &amp;quot;module&amp;quot;&lt;br /&gt;
* &amp;quot;class&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.confirmationDialog()&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Display a confirmation dialog with a yes/no choice.&lt;br /&gt;
&lt;br /&gt;
We advice you to NOT use this function unless the player action is really critical and could ruins the game, because it slows down the game and upset players.&lt;br /&gt;
&lt;br /&gt;
Usage: this.confirmationDialog( &amp;quot;Question to displayed&amp;quot;, callback_function_if_click_on_yes );&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
this.confirmationDialog( _(&#039;Are you sure to use this bonus (points penalty at the end of the game) ?&#039;),&lt;br /&gt;
                         dojo.hitch( this, function() {&lt;br /&gt;
                           this.ajaxcall( &#039;/seasons/seasons/useBonus.html&#039;,&lt;br /&gt;
                                { id:bonus_id, lock:true }, this, function( result ) {} );&lt;br /&gt;
                        } ) ); &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; addEventToClass: function( cssClassName, eventName, functionName )&lt;br /&gt;
: Same as dojo.connect(), but for all the nodes set with the specified cssClassName&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.addActionButton( id, label, method, (opt)destination, (opt)blinking, (opt)color )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You can use this method to add an action button in the main action status bar.&lt;br /&gt;
&lt;br /&gt;
Arguments:&lt;br /&gt;
* id: an element ID that should be unique in your HTML DOM document.&lt;br /&gt;
* label: the text of the button. Should be translatable (use _() function).&lt;br /&gt;
* method: the name of your method that must be triggered when the player clicks on this button.&lt;br /&gt;
* destination (optional): deprecated, do not use this. Use &#039;&#039;&#039;null&#039;&#039;&#039; as value if you need to specify other arguments.&lt;br /&gt;
* blinking (optional): if set to &#039;&#039;&#039;true&#039;&#039;&#039;, the button is going blink to catch player&#039;s attention. Please don&#039;t abuse of blinking button.&lt;br /&gt;
* color: could be &#039;&#039;&#039;blue&#039;&#039;&#039; (default), &#039;&#039;&#039;red&#039;&#039;&#039; or &#039;&#039;&#039;gray&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
You should only use this method in your &amp;quot;onUpdateActionButtons&amp;quot; method. Usually, you use it like this (from Hears example):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        onUpdateActionButtons: function( stateName, args ) {&lt;br /&gt;
                      &lt;br /&gt;
            if (this.isCurrentPlayerActive()) {            &lt;br /&gt;
                switch( stateName ) {&lt;br /&gt;
                case &#039;giveCards&#039;:&lt;br /&gt;
                    this.addActionButton( &#039;giveCards_button&#039;, _(&#039;Give selected cards&#039;), &#039;onGiveCards&#039; ); &lt;br /&gt;
                    break;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        },   &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the example above, we are adding a &amp;quot;Give selected cards&amp;quot; button in the case we are on game state &amp;quot;giveCards&amp;quot;. When player clicks on this button, it triggers our &amp;quot;onGiveCards&amp;quot; method.&lt;br /&gt;
&lt;br /&gt;
Example using blinking red button:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     this.addActionButton( &#039;commit_button&#039;, _(&#039;Confirm&#039;), &#039;onConfirm&#039;, null, true, &#039;red&#039;); &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: at least in studio example above will make button huge, because it sets it display of blinking things to &#039;&#039;&#039;block&#039;&#039;&#039;, &lt;br /&gt;
if you don&#039;t like it you have to change css display value&lt;br /&gt;
of the button to inline-block (the id of the button is the first argument, i.e &#039;commit_button&#039; in example above)&lt;br /&gt;
&lt;br /&gt;
== Translations ==&lt;br /&gt;
&lt;br /&gt;
See [[Translations]]&lt;br /&gt;
&lt;br /&gt;
== Notifications ==&lt;br /&gt;
&lt;br /&gt;
When something happens on the server side, your game interface Javascript logic received a notification.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s how you can handle these notifications on the client side.&lt;br /&gt;
&lt;br /&gt;
=== Subscribe to notifications ===&lt;br /&gt;
&lt;br /&gt;
Your Javascript &amp;quot;setupNotifications&amp;quot; method is the place where you can subscribe to notifications from your PHP code.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s how you associate one of your Javascript method to a notification &amp;quot;playDisc&amp;quot; (from Reversi example):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   // In setupNotifications method:&lt;br /&gt;
   dojo.subscribe( &#039;playDisc&#039;, this, &amp;quot;notif_playDisc&amp;quot; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: the &amp;quot;playDisc&amp;quot; corresponds to the name of the notification you define it in your PHP code, in your &amp;quot;notifyAllPlayers&amp;quot; or &amp;quot;notifyPlayer&amp;quot; method.&lt;br /&gt;
&lt;br /&gt;
Then, you have to define your &amp;quot;notif_playDisc&amp;quot; method:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        notif_playDisc: function( notif )&lt;br /&gt;
        {&lt;br /&gt;
            // Remove current possible moves (makes the board more clear)&lt;br /&gt;
            dojo.query( &#039;.possibleMove&#039; ).removeClass( &#039;possibleMove&#039; );        &lt;br /&gt;
        &lt;br /&gt;
            this.addDiscOnBoard( notif.args.x, notif.args.y, notif.args.player_id );&lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In a notification handler like our &amp;quot;notif_playDisc&amp;quot; method, you can access to all notifications arguments with &amp;quot;notif.args&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    // If you did this on PHP side:&lt;br /&gt;
    self::notifyAllPlayers( &amp;quot;myNotification&amp;quot;, &#039;&#039;, array( &amp;quot;myArgument&amp;quot; =&amp;gt; 3 ) );&lt;br /&gt;
&lt;br /&gt;
    // On Javascript side, you can access the &amp;quot;myArgument&amp;quot; like this:&lt;br /&gt;
    notif_myNotification: function( notif )&lt;br /&gt;
    {&lt;br /&gt;
       alert( &amp;quot;myArgument = &amp;quot; + notif.args.myArgument );&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Synchronous notifications ===&lt;br /&gt;
&lt;br /&gt;
When several notifications are received by your game interface, these notifications are processed immediately, one after the other, in the same exact order they have been generated in your PHP game logic.&lt;br /&gt;
&lt;br /&gt;
However, sometimes, you need to give some time to the players to figure out what happened on the game before jumping to the next notification. Indeed, in many games, they are a lot of automatic actions, and the computer is going to resolve all these actions very fast if you don&#039;t tell it not to do so.&lt;br /&gt;
&lt;br /&gt;
As an example, for Reversi, when someone is playing a disc, we want to wait 500 milliseconds before doing anything else in order the opponent player can figure out what move has been played.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s how we do this, right after our subscription:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
       dojo.subscribe( &#039;playDisc&#039;, this, &amp;quot;notif_playDisc&amp;quot; );&lt;br /&gt;
       this.notifqueue.setSynchronous( &#039;playDisc&#039;, 500 );   // Wait 500 milliseconds after executing the playDisc handler&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Pre-defined notification types ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;tableWindow&#039;&#039;&#039; - This defines notification to display [[Game_interface_logic:_yourgamename.js#Scoring_dialogs|Scoring Dialogs]], see below.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;message&#039;&#039;&#039; - This defines notification that shows on players log and have no other effect&lt;br /&gt;
&lt;br /&gt;
   // You can call this on php side without doing anything on client side&lt;br /&gt;
    self::notifyAllPlayers( &#039;message&#039;, &#039;hello&#039;, array( ) );&lt;br /&gt;
&lt;br /&gt;
== Tooltips ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.addTooltip( nodeId, _( helpString ), _( actionString ), delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Add a simple text tooltip to the DOM node.&lt;br /&gt;
&lt;br /&gt;
Specify &#039;helpString&#039; to display some information about &amp;quot;what is this game element?&amp;quot;.&lt;br /&gt;
Specify &#039;actionString&#039; to display some information about &amp;quot;what happens when I click on this element?&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
You must specify both helpString and actionString. Most of the time, you use only one and specify a void string (&amp;quot;&amp;quot;) for the other one.&lt;br /&gt;
&lt;br /&gt;
Usually, _() must be used for the text to be marked for translation.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Delay&amp;quot; is an optional parameter. Usually, it is primarily used to specify a zero delay for some game element when the tooltip gives really important information for the game - but remember: no essential information must be placed in tooltips as they won&#039;t be displayed in some browser (see Guidelines).&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   this.addTooltip( &#039;cardcount&#039;, _(&#039;Number of cards in hand&#039;), &#039;&#039; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.addTooltipHtml( nodeId, html, delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Add an HTML tooltip to the DOM node (for more elaborate content such as presenting a bigger version of a card).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.addTooltipToClass( cssClass, _( helpString ), _( actionString ), delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Add a simple text tooltip to all the DOM nodes set with this cssClass. &lt;br /&gt;
&lt;br /&gt;
IMPORTANT: all concerned nodes must have IDs to get tooltips.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.addTooltipHtmlToClass( cssClass, html, delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Add an HTML tooltip to to all the DOM nodes set with this cssClass (for more elaborate content such as presenting a bigger version of a card).&lt;br /&gt;
&lt;br /&gt;
IMPORTANT: all concerned nodes must have IDs to get tooltips&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.removeTooltip( nodeId )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Remove a tooltip from the DOM node.&lt;br /&gt;
&lt;br /&gt;
== Dialogs, warning messages, confirmation dialogs, ... ==&lt;br /&gt;
&lt;br /&gt;
=== Warning messages ===&lt;br /&gt;
&lt;br /&gt;
Sometimes, there is something important that is happening on the game and you have to make sure all players get the message. Most of the time, the evolution of the game situation or the game log is enough, but sometimes you need something more visible.&lt;br /&gt;
&lt;br /&gt;
Ex: someone fulfill one of the end of the game condition, so this is the last turn.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.showMessage( msg, type )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
showMessage shows a message in a big rectangular area on the top of the screen of current player.&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;msg&amp;quot; is the string to display. It should be translated.&lt;br /&gt;
* &amp;quot;type&amp;quot; can be set to &amp;quot;info&amp;quot; or &amp;quot;error&amp;quot;. If set to &amp;quot;info&amp;quot;, the message will be an informative message on a white background. If set to &amp;quot;error&amp;quot;, the message will be an error message on a red background.&lt;br /&gt;
&lt;br /&gt;
Important: the normal way to inform players about the progression of the game is the game log. &amp;quot;showMessage&amp;quot; is intrusive and should not be used often.&lt;br /&gt;
&lt;br /&gt;
=== Confirmation dialog ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;confirmationDialog( message, yesHandler, noHandler )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When an important action with a lot of consequences is triggered by the player, you may want to propose a confirmation dialog.&lt;br /&gt;
&lt;br /&gt;
CAREFUL: the general guidelines of BGA is to AVOID the use of confirmation dialog. Confirmation dialogs slow down the game and bother players. The players knows that they have to pay attention about each move when they are playing online.&lt;br /&gt;
&lt;br /&gt;
The situation where you should use a confirmation dialog are the following:&lt;br /&gt;
* It must not happen very often during a game.&lt;br /&gt;
* It must be linked to an action that can really &amp;quot;kill a game&amp;quot; if the player do not pay attention.&lt;br /&gt;
* It must be something that can be done by mistake (ex: a link on the action status bar).&lt;br /&gt;
&lt;br /&gt;
How to display a confirmation dialog:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        this.confirmationDialog( _(&#039;Are you sure you want to bake the pie?&#039;), dojo.hitch( this, function() {&lt;br /&gt;
            this.bakeThePie();&lt;br /&gt;
        } ) ); &lt;br /&gt;
        return; // nothing should be called or done after calling this, all action must be done in the handler  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Multiple choice dialog ===&lt;br /&gt;
You can use this dialog to give user a choice with small amount of options:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        var keys = [1,5,10];&lt;br /&gt;
        this.multipleChoiceDialog(&lt;br /&gt;
          _(&#039;How many bugs to fix?&amp;quot;), keys, &lt;br /&gt;
            dojo.hitch(this, function(choice) {&lt;br /&gt;
                            var bugchoice = keys[choice];&lt;br /&gt;
                            console.log(&#039;dialog callback with &#039;+bugchoice);&lt;br /&gt;
                            this.ajaxcall( &#039;/mygame/mygame/fixBugs.html&#039;, { bugs: bugchoice}, this, function( result ) {} );                        }));&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Dialogs ===&lt;br /&gt;
&lt;br /&gt;
At first, you shouldn&#039;t use dialogs windows.&lt;br /&gt;
&lt;br /&gt;
BGA guidelines specify that all game elements should be displayed on the main screen. Players can eventually scroll down to see game elements they don&#039;t need to see anytime, and you may eventually create anchors to move between game area section. Of course dialogs windows are very practical, but the thing is: all players know how to scroll down, and not all players know how to show up your dialog window. In addition, when the dialog shows up, players can&#039;t access the other game components.&lt;br /&gt;
&lt;br /&gt;
Sometimes although, you need to display a dialog window. Here is how you do this:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  // Create the new dialog. You should store the handler in a member variable to access it later&lt;br /&gt;
  this.myDlg = new dijit.Dialog({ title: _(&amp;quot;my dialog title to translate&amp;quot;) });&lt;br /&gt;
  &lt;br /&gt;
  // Create the HTML of my dialog. &lt;br /&gt;
  // The best practice here is to use [[Game_layout:_view_and_template:_yourgamename.view.php_and_yourgamename_yourgamename.tpl#Javascript_templates|Javascript templates]]&lt;br /&gt;
  var html = this.format_block( &#039;jstpl_myDialogTemplate&#039;, { &lt;br /&gt;
                arg1: myArg1,&lt;br /&gt;
                arg2: myArg2,&lt;br /&gt;
                ...&lt;br /&gt;
            } );  &lt;br /&gt;
  &lt;br /&gt;
  // Show the dialog&lt;br /&gt;
  this.myDlg.attr(&amp;quot;content&amp;quot;, html );&lt;br /&gt;
  this.myDlg.show(); &lt;br /&gt;
  &lt;br /&gt;
  // Now that the dialog has been displayed, you can connect your method to some dialog elements&lt;br /&gt;
  // Example, a &amp;quot;close&amp;quot; button:&lt;br /&gt;
  dojo.connect( $(&#039;closeDlg&#039;), &#039;onclick&#039;, this, function(evt){&lt;br /&gt;
                evt.preventDefault();&lt;br /&gt;
                this.myDlg.hide();&lt;br /&gt;
            } );  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Tip: be careful with &amp;quot;hide()&amp;quot; method to close your dialog: the dialog and its content is not completely removed from the DOM. It can cause you problems if you try to display the same dialog several times. A good practice is to wrap all the content of your dialog in a &amp;lt;nowiki&amp;gt;&amp;lt;div id=&#039;myDlgContent&#039;&amp;gt;&amp;lt;/nowiki&amp;gt; div element, and to call &amp;quot;dojo.destroy(&#039;myDlgContent&#039;)&amp;quot; before displaying your dialog.&lt;br /&gt;
&lt;br /&gt;
=== Scoring dialogs ===&lt;br /&gt;
&lt;br /&gt;
Sometimes at the end of a round you want to display a big table that details the points wins in each section of the game.&lt;br /&gt;
&lt;br /&gt;
Example: in Hearts game, we display at the end of each round the number of &amp;quot;heart&amp;quot; cards collected by each player, the player who collected the Queen of Spades, and the total number of points loose by each player.&lt;br /&gt;
&lt;br /&gt;
Scoring dialogs are managed entirely on &#039;&#039;&#039;PHP side&#039;&#039;&#039;, but they are described here as their effects are visible only on client side.&lt;br /&gt;
&lt;br /&gt;
Displaying a scoring dialog is quite simple and is using a special notification type: &amp;quot;tableWindow&amp;quot;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  // on PHP side:&lt;br /&gt;
  $this-&amp;gt;notifyAllPlayers( &amp;quot;tableWindow&amp;quot;, &#039;&#039;, array(&lt;br /&gt;
            &amp;quot;id&amp;quot; =&amp;gt; &#039;finalScoring&#039;,&lt;br /&gt;
            &amp;quot;title&amp;quot; =&amp;gt; clienttranslate(&amp;quot;Title of the scoring dialog&amp;quot;),&lt;br /&gt;
            &amp;quot;table&amp;quot; =&amp;gt; $table&lt;br /&gt;
        ) ); &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;table&amp;quot; argument is a 2 dimensional PHP array that describe the table you want to display, line by line and column by column.&lt;br /&gt;
&lt;br /&gt;
Example: display an 3x3 array of strings&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   $table = array(&lt;br /&gt;
      array( &amp;quot;one&amp;quot;, &amp;quot;two&amp;quot;, &amp;quot;three&amp;quot; ),    // This is my first line&lt;br /&gt;
      array( &amp;quot;four&amp;quot;, &amp;quot;five&amp;quot;, &amp;quot;six&amp;quot; ),    // This is my second line&lt;br /&gt;
      array( &amp;quot;seven&amp;quot;, &amp;quot;height&amp;quot;, &amp;quot;nine&amp;quot; )    // This is my third line&lt;br /&gt;
   );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As you can see above, in each &amp;quot;cell&amp;quot; of your array you can display a simple string value. But you can also display a complex value with a template and associated arguments like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   $table = array(&lt;br /&gt;
      array( &amp;quot;one&amp;quot;, &amp;quot;two&amp;quot;, array( &amp;quot;str&amp;quot; =&amp;gt; &amp;quot;a string with an ${argument}&amp;quot;, &amp;quot;args&amp;quot; =&amp;gt; array( &#039;argument&#039; =&amp;gt; &#039;argument_value&#039; )  ) ),&lt;br /&gt;
      array( &amp;quot;four&amp;quot;, &amp;quot;five&amp;quot;, &amp;quot;six&amp;quot; ), &lt;br /&gt;
      array( &amp;quot;seven&amp;quot;, &amp;quot;height&amp;quot;, &amp;quot;nine&amp;quot; )&lt;br /&gt;
   );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is especially useful when you want to display player names with colors. Example from &amp;quot;Hearts&amp;quot;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        $firstRow = array( &#039;&#039; );&lt;br /&gt;
        foreach( $players as $player_id =&amp;gt; $player )&lt;br /&gt;
        {&lt;br /&gt;
            $firstRow[] = array( &#039;str&#039; =&amp;gt; &#039;${player_name}&#039;,&lt;br /&gt;
                                 &#039;args&#039; =&amp;gt; array( &#039;player_name&#039; =&amp;gt; $player[&#039;player_name&#039;] ),&lt;br /&gt;
                                 &#039;type&#039; =&amp;gt; &#039;header&#039;&lt;br /&gt;
                               );&lt;br /&gt;
        }&lt;br /&gt;
        $table[] = $firstRow;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also use three extra attributes in the parameter array for the notification:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   $this-&amp;gt;notifyAllPlayers( &amp;quot;tableWindow&amp;quot;, &#039;&#039;, array(&lt;br /&gt;
            &amp;quot;id&amp;quot; =&amp;gt; &#039;finalScoring&#039;,&lt;br /&gt;
            &amp;quot;title&amp;quot; =&amp;gt; clienttranslate(&amp;quot;Title of the scoring dialog&amp;quot;),&lt;br /&gt;
            &amp;quot;table&amp;quot; =&amp;gt; $table,&lt;br /&gt;
            &amp;quot;header&amp;quot; =&amp;gt; array(&#039;str&#039; =&amp;gt; clienttranslate(&#039;Table header with parameter ${number}&#039;),&lt;br /&gt;
                                 &#039;args&#039; =&amp;gt; array( &#039;number&#039; =&amp;gt; 3 ),&lt;br /&gt;
                               ),&lt;br /&gt;
            &amp;quot;footer&amp;quot; =&amp;gt; &#039;&amp;lt;div&amp;gt;Some footer&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
            &amp;quot;closing&amp;quot; =&amp;gt; clienttranslate( &amp;quot;Closing button label&amp;quot; )&lt;br /&gt;
        ) ); &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;header&#039;&#039;&#039;: the content for this parameter will display before the table (also, the html will be parsed and player names will be colored according to the current game colors). &lt;br /&gt;
*&#039;&#039;&#039;footer&#039;&#039;&#039;: the content for this parameter will display after the table (no parsing for coloring the player names)&lt;br /&gt;
*&#039;&#039;&#039;closing&#039;&#039;&#039;: if this parameter is used, a button will be displayed with this label at the bottom of the popup and will allow players to close it (more easily than by clicking the top right &#039;cross&#039; icon).&lt;br /&gt;
&lt;br /&gt;
=== Scoring animated display ===&lt;br /&gt;
&lt;br /&gt;
Sometimes (Terra Mystica final scoring for example), you may want to display a score value over an element to make the scoring easier to follow for the players.&lt;br /&gt;
You can do it with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   this.displayScoring( anchor_id, color, score );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Speech bubble ==&lt;br /&gt;
&lt;br /&gt;
For better interactivity in some games (Love Letter for example), you may use comic book style speech bubbles to express the players voices.&lt;br /&gt;
This is done with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   this.showBubble( anchor_id, text, delay, duration, custom_class )&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
delay in milliseconds is optional (default 0)&lt;br /&gt;
duration in milliseconds is optional (default 3000)&lt;br /&gt;
custom_class is optional, if you need to override the default bubble style&lt;br /&gt;
&lt;br /&gt;
== Update players score ==&lt;br /&gt;
&lt;br /&gt;
Increase a player score (with a positive or negative number):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  this.scoreCtrl[ player_id ].incValue( score_delta );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Set a player score to a specific value:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  this.scoreCtrl[ player_id ].setValue( new_score );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Players panels ==&lt;br /&gt;
&lt;br /&gt;
=== Adding stuff to player&#039;s panel ===&lt;br /&gt;
&lt;br /&gt;
At first, create a new &amp;quot;JS template&amp;quot; string in your template (tpl) file:&lt;br /&gt;
&lt;br /&gt;
(from Gomoku example)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
var jstpl_player_board = &#039;\&amp;lt;div class=&amp;quot;cp_board&amp;quot;&amp;gt;\&lt;br /&gt;
    &amp;lt;div id=&amp;quot;stoneicon_p${id}&amp;quot; class=&amp;quot;gmk_stoneicon gmk_stoneicon_${color}&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;span id=&amp;quot;stonecount_p${id}&amp;quot;&amp;gt;0&amp;lt;/span&amp;gt;\&lt;br /&gt;
&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then, you add this piece of code in your JS file to add this template to each player panel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
            // Setting up player boards&lt;br /&gt;
            for( var player_id in gamedatas.players )&lt;br /&gt;
            {&lt;br /&gt;
                var player = gamedatas.players[player_id];&lt;br /&gt;
                         &lt;br /&gt;
                // Setting up players boards if needed&lt;br /&gt;
                var player_board_div = $(&#039;player_board_&#039;+player_id);&lt;br /&gt;
                dojo.place( this.format_block(&#039;jstpl_player_board&#039;, player ), player_board_div );&lt;br /&gt;
            }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Note: the code above is of course from your &amp;quot;setup&amp;quot; function in your Javascript).&lt;br /&gt;
&lt;br /&gt;
Very often, you have to distinguish current player and others players. In this case, you just have to create another JS template (ex: jstpl_otherplayer_board) and use it when &amp;quot;player_id&amp;quot; is different than &amp;quot;this.player_id&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Player&#039;s panel disabling/enabling ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.disablePlayerPanel( player_id )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Disable given player panel (the panel background become gray).&lt;br /&gt;
&lt;br /&gt;
Usually, this is used to signal that this played passes, or will be inactive during a while.&lt;br /&gt;
&lt;br /&gt;
Note that the only effect of this is visual. There are no consequences on the behaviour of the panel itself.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.enablePlayerPanel( player_id )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Enable a player panel that has been disabled before.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.enableAllPlayerPanels()&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Enable all player panels that has been disabled before.&lt;br /&gt;
&lt;br /&gt;
== Image loading ==&lt;br /&gt;
&lt;br /&gt;
See also [[Game_art:_img_directory]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Be careful&#039;&#039;&#039;: by default, ALL images of your img directory are loaded on a player&#039;s browser when he loads the game. For this reason, don&#039;t let in your img directory images that are not useful, otherwise it&#039;s going to slowdown the game load.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;dontPreloadImage( image_file_name )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Using dontPreloadImage, you tell the interface to not preload a specific image in your img directory.&lt;br /&gt;
&lt;br /&gt;
Example of use:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
this.dontPreloadImage( &#039;cards.png&#039; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is particularly useful if for example you have 2 different themes for a game. To accelerate the loading of the game, you can specify to not preload images corresponding to the other theme.&lt;br /&gt;
&lt;br /&gt;
Another example of use: in &amp;quot;Gosu&amp;quot; game with Kamakor extension, you play with 5 sets of cards among 10 available. Cards images are organized by sets, and we only preload the images corresponding to the 5 current sets with &#039;&#039;&#039;ensureSpecificGameImageLoading( image_file_names_array )&#039;&#039;&#039;.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// By default, do not preload anything&lt;br /&gt;
this.dontPreloadImage( &#039;cards.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan1.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan2.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan3.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan4.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan5.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan6.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan7.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan8.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan9.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan10.png&#039; );&lt;br /&gt;
var to_preload = [];&lt;br /&gt;
for( i in this.gamedatas.clans )&lt;br /&gt;
{&lt;br /&gt;
	var clan_id = this.gamedatas.clans[i];&lt;br /&gt;
	to_preload.push( &#039;clan&#039;+clan_id+&#039;.png&#039; );&lt;br /&gt;
}&lt;br /&gt;
if( to_preload.length == 5 )&lt;br /&gt;
{&lt;br /&gt;
	this.ensureSpecificGameImageLoading( to_preload );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; You don&#039;t need to specify to not preload game box images (game_box.png, game_box75.png...) since they are not preloaded by default.&lt;br /&gt;
&lt;br /&gt;
== Other useful stuff ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;dojo.hitch&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
With dojo.hitch, you can create a callback function that will run with your game object context whatever happen.&lt;br /&gt;
&lt;br /&gt;
Typical example: display a BGA confirmation dialog with a callback function created with dojo.hitch:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        this.confirmationDialog( _(&#039;Are you sure you want to make this?&#039;), dojo.hitch( this, function() {&lt;br /&gt;
            this.ajaxcall( &#039;/mygame/mygame/makeThis.html&#039;, { lock:true }, this, function( result ) {} );&lt;br /&gt;
        } ) );   &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the example above, using dojo.hitch, we are sure that the &amp;quot;this&amp;quot; object will be set when the callback is called.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; updateCounters(counters)&lt;br /&gt;
: Useful for updating game counters in the player panel (such as resources). &lt;br /&gt;
: &#039;counters&#039; arg is an associative array [counter_name_value =&amp;gt; [ &#039;counter_name&#039; =&amp;gt; counter_name_value, &#039;counter_value&#039; =&amp;gt; counter_value_value], ... ]&lt;br /&gt;
: All counters must be referenced in this.gamedatas.counters and will be updated.&lt;br /&gt;
: DOM objects referenced by &#039;counter_name&#039; will have their innerHTML updated with &#039;counter_value&#039;.&lt;br /&gt;
&lt;br /&gt;
== BGA GUI components ==&lt;br /&gt;
&lt;br /&gt;
BGA framework provides some useful ready-to-use components for the game interface:&lt;br /&gt;
&lt;br /&gt;
[[Studio#BGA_Studio_game_components_reference]]&lt;br /&gt;
&lt;br /&gt;
Note that each time you are using an additional component, you must declare it at the top of your Javascript file in the list of modules used.&lt;br /&gt;
&lt;br /&gt;
Example if you are using &amp;quot;ebg.stock&amp;quot;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
define([&lt;br /&gt;
    &amp;quot;dojo&amp;quot;,&amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
    &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
    &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
    &amp;quot;ebg/stock&amp;quot;  /// &amp;lt;=== we are using ebg.stock module&lt;br /&gt;
],&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://sr.doc.boardgamearena.com/index.php?title=Gamehelptablut&amp;diff=3003</id>
		<title>Gamehelptablut</title>
		<link rel="alternate" type="text/html" href="https://sr.doc.boardgamearena.com/index.php?title=Gamehelptablut&amp;diff=3003"/>
		<updated>2018-04-27T10:21:50Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Captures */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Description =&lt;br /&gt;
Tablut is an abstract tactical game for 2 players.&lt;br /&gt;
&lt;br /&gt;
It is played on a 9 per 9 tiled board. There are 16 black pawns, called Muscovites, 8 white pawns, the Swedes, and a special white pawn, the Swedish king.&lt;br /&gt;
&lt;br /&gt;
Players take turns, moving a single pawn of their color each time.&lt;br /&gt;
&lt;br /&gt;
The initial setup looks like this:&lt;br /&gt;
&lt;br /&gt;
[[File:Tablut_board_screenshot.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Objective of the game =&lt;br /&gt;
For the player with the black pawns, the Muscovites, the goal is to make encircle the king in order to capture him.&lt;br /&gt;
&lt;br /&gt;
For the player with the white pawns, the Swedes, the goal his to bring the king in one of the four corners of the board.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Moves =&lt;br /&gt;
All pawns move like the tower in chess: horizontally or vertically of any number of tiles.&lt;br /&gt;
Only the king can stop inside the four corners of the board and the center tile.&lt;br /&gt;
&lt;br /&gt;
= Captures =&lt;br /&gt;
A pawn is captured, and hence removed from the board, when surrounded by 2 enemy pawns on opposite neighbour tiles :&lt;br /&gt;
&lt;br /&gt;
[[File:Tablut_soldier_capture.png]]&lt;br /&gt;
&lt;br /&gt;
However, a pawn willingly moving between 2 enemy pawns does not get captured.&lt;br /&gt;
&lt;br /&gt;
The king is special in regard to capture: 2 Muscovites are not enough to eliminate him,&lt;br /&gt;
he must be encircled on all his 4 neighbour tiles.&lt;br /&gt;
&lt;br /&gt;
The 4 corner tiles, the edge of the board (and for capturing the King, the center of the board) act like encircling pieces in regards to capture.&lt;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://sr.doc.boardgamearena.com/index.php?title=Gamehelptablut&amp;diff=3002</id>
		<title>Gamehelptablut</title>
		<link rel="alternate" type="text/html" href="https://sr.doc.boardgamearena.com/index.php?title=Gamehelptablut&amp;diff=3002"/>
		<updated>2018-04-27T10:19:08Z</updated>

		<summary type="html">&lt;p&gt;Een: Update rules to match scripted version&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Description =&lt;br /&gt;
Tablut is an abstract tactical game for 2 players.&lt;br /&gt;
&lt;br /&gt;
It is played on a 9 per 9 tiled board. There are 16 black pawns, called Muscovites, 8 white pawns, the Swedes, and a special white pawn, the Swedish king.&lt;br /&gt;
&lt;br /&gt;
Players take turns, moving a single pawn of their color each time.&lt;br /&gt;
&lt;br /&gt;
The initial setup looks like this:&lt;br /&gt;
&lt;br /&gt;
[[File:Tablut_board_screenshot.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Objective of the game =&lt;br /&gt;
For the player with the black pawns, the Muscovites, the goal is to make encircle the king in order to capture him.&lt;br /&gt;
&lt;br /&gt;
For the player with the white pawns, the Swedes, the goal his to bring the king in one of the four corners of the board.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Moves =&lt;br /&gt;
All pawns move like the tower in chess: horizontally or vertically of any number of tiles.&lt;br /&gt;
Only the king can stop inside the four corners of the board and the center tile.&lt;br /&gt;
&lt;br /&gt;
= Captures =&lt;br /&gt;
A pawn is captured, and hence removed from the board, when surrounded by 2 enemy pawns on opposite neighbour tiles :&lt;br /&gt;
&lt;br /&gt;
[[File:Tablut_soldier_capture.png]]&lt;br /&gt;
&lt;br /&gt;
However, a pawn willingly moving between 2 enemy pawns does not get captured.&lt;br /&gt;
&lt;br /&gt;
The king is special in regard to capture: 2 Muscovites are not enough to eliminate him,&lt;br /&gt;
he must be encircled on all his 4 neighbour tiles.&lt;br /&gt;
&lt;br /&gt;
For capture, the 4 corner tiles, the edge of the board (and for capturing the King, the center of the board) act like enemy pieces.&lt;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://sr.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=3001</id>
		<title>SandboxScripts</title>
		<link rel="alternate" type="text/html" href="https://sr.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=3001"/>
		<updated>2018-04-24T10:44:20Z</updated>

		<summary type="html">&lt;p&gt;Een: /* bga.getElementsArray( selector, (optional) fields ) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This is the reference of functions you can call from your Sandbox scripts.&lt;br /&gt;
&lt;br /&gt;
= Javascript =&lt;br /&gt;
&lt;br /&gt;
BGA Sandbox scripts are written in Javascript.&lt;br /&gt;
&lt;br /&gt;
Using Javascript, you can write scripts to automate moves for your Sandbox games &amp;amp; provide rules reinforcement.&lt;br /&gt;
&lt;br /&gt;
Important : in the opposite of the most common usage of Javascript, Sandbox scripts are executed &#039;&#039;&#039;on server side&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
= BGA API =&lt;br /&gt;
&lt;br /&gt;
To interact with your BGA Sandbox game, we provide you an API.&lt;br /&gt;
&lt;br /&gt;
With this API, you can get properties values of game elements from the current game situation, modify them and/or trigger the game actions (ex : move this element here, flip this card, and so on).&lt;br /&gt;
&lt;br /&gt;
= Quick start =&lt;br /&gt;
&lt;br /&gt;
== Hello World Script ==&lt;br /&gt;
&lt;br /&gt;
From Sandbox editor &amp;quot;interface view&amp;quot; tab, select an element, and access to its property (top right icon).&lt;br /&gt;
&lt;br /&gt;
Go to &amp;quot;Scripts (advanced)&amp;quot; section.&lt;br /&gt;
&lt;br /&gt;
In front of &amp;quot;When this element is clicked&amp;quot;, enter &amp;quot;onMyClick&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Close the window. Go to &amp;quot;script view&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Enter the following :&lt;br /&gt;
&lt;br /&gt;
 function onMyClick( element_id )&lt;br /&gt;
 {&lt;br /&gt;
    bga.log(&amp;quot;Hello world! You just clicked on element &amp;quot; + element_id + &amp;quot;. Congrats!&amp;quot;);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Save &amp;amp; publish your project, starts a test session, click on the previous element : your message appears in the log on the right!&lt;br /&gt;
&lt;br /&gt;
== Top useful tips ==&lt;br /&gt;
&lt;br /&gt;
* You don&#039;t have to save&amp;amp;publish from the Sandbox editor for each modification of your script : each time you save your script (control+S), the script used for all test sessions is updated. Note that the production version on BGA is of course NOT updated until you explicitly save&amp;amp;publish again your project.&lt;br /&gt;
&lt;br /&gt;
* Alternatively to bga.log(), you can use bga.exit( &amp;quot;my message&amp;quot; ) to debug your script. With bga.exit, the script execution immediately stops and all previous game changes are cancelled, so this is very practical to try and retry an action until your script is fine.&lt;br /&gt;
&lt;br /&gt;
* We advise you to develop first a full playable version of the game without the scripts, and THEN to script it.&lt;br /&gt;
&lt;br /&gt;
* On Board Game Arena, players have come to expect fully implemented games with all rules enforced. So even if it&#039;s technically possible not to script the full game and to implement the game only partially, in most cases we&#039;ll publish only fully scripted games :)&lt;br /&gt;
&lt;br /&gt;
= Functions you can use in your Sandbox scripts=&lt;br /&gt;
&lt;br /&gt;
== Debugging functions ==&lt;br /&gt;
&lt;br /&gt;
=== bga.trace( txt / obj ) ===&lt;br /&gt;
&lt;br /&gt;
Write something immediately in the BGA log (on the right of the screen).&lt;br /&gt;
&lt;br /&gt;
This is the most practical way to debug your script :)&lt;br /&gt;
&lt;br /&gt;
Important : bga.trace is for debugging purpose only and won&#039;t be displayed on production.&lt;br /&gt;
&lt;br /&gt;
Note : you can also pass an object in parameter. This will dump the content of this object in the log.&lt;br /&gt;
&lt;br /&gt;
Note : in the opposite of bga.log, bga.trace is NOT cancelled if the game action failed (after a call to bga.cancel or bga.error). This makes bga.trace very practical to debug a game action that failed, and for this reason you should probably NEVER use bga.log for debugging purpose.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  // Example : write &amp;quot;Hello world&amp;quot; in the log&lt;br /&gt;
  bga.trace( &amp;quot;Hello world&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Example : dump an associative array in the log&lt;br /&gt;
  bga.trace( { mykey: &#039;myvalue&#039;, another_key: &#039;another_value&#039; } );&lt;br /&gt;
&lt;br /&gt;
=== bga.exit( txt / obj ) ===&lt;br /&gt;
&lt;br /&gt;
Stop the script immediately, display the &amp;quot;txt&amp;quot; messages and cancel (ie : rollback) on every previous API call except bga.trace :&lt;br /&gt;
&lt;br /&gt;
ALL previous BGA api call are canceled and there will be no visible changes on the interface (ex : no moves, no visible property changes, ...). Only &amp;quot;bga.trace&amp;quot; API commands are kept so you can debug.&lt;br /&gt;
&lt;br /&gt;
bga.exit is very practical when you want to repeat a game action again and again to debug it : with a call to bga.exit at the end of your script, you make sure that your game situation will be kept unchanged after each test.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.exit( &amp;quot;My script is stopped by this call&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Example with dumping a javascript variable&lt;br /&gt;
  bga.exit( my_variable_to_dump );&lt;br /&gt;
&lt;br /&gt;
== Cancelling a game action ==&lt;br /&gt;
&lt;br /&gt;
=== bga.cancel( txt ) ===&lt;br /&gt;
&lt;br /&gt;
This is the function to use when a player is doing something against game rules.&lt;br /&gt;
&lt;br /&gt;
The text message in parameter will be displayed to this player as a &amp;quot;red message&amp;quot;, so he/she can understand the rule.&lt;br /&gt;
&lt;br /&gt;
All previous BGA api call are cancelled, and there will be no visible changes on the interface.&lt;br /&gt;
&lt;br /&gt;
   // Example :&lt;br /&gt;
   bga.cancel( _(&amp;quot;You cannot move this piece here&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
Note : most of the time, you should wrap your text inside a _() translation marker to make this string translatable.&lt;br /&gt;
&lt;br /&gt;
=== bga.error( text ) ===&lt;br /&gt;
&lt;br /&gt;
This is the function to use when some unexpected error happens in your script.&lt;br /&gt;
&lt;br /&gt;
The text message will be displayed to user, with mention &amp;quot;Unexpected error&amp;quot;. The player will be incited to fill a bug report. The purpose of the message is to help you to identify the bug.&lt;br /&gt;
&lt;br /&gt;
All previous BGA api call are cancelled, and there will be no visible changes on the interface.&lt;br /&gt;
&lt;br /&gt;
   // Example :&lt;br /&gt;
   if( card_picked === null )&lt;br /&gt;
   {&lt;br /&gt;
       bga.error( &amp;quot;Cannot find a card to pick !&amp;quot; );&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
Note : you should NEVER wrap text inside bga.error with _() translation marker, because unexpected error should not be translate (so you can eventually recognize them when reported by players in bug report).&lt;br /&gt;
&lt;br /&gt;
== Game log (history) ==&lt;br /&gt;
&lt;br /&gt;
=== bga.log( txt, (optional) args ) ===&lt;br /&gt;
&lt;br /&gt;
Write something in the BGA log on the right.&lt;br /&gt;
&lt;br /&gt;
  // Example : simple log&lt;br /&gt;
  bga.log( _(&amp;quot;A new round starts&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
You may add arguments to your log, like this :&lt;br /&gt;
&lt;br /&gt;
  // Example: log with argument to display a card name.&lt;br /&gt;
  //          In this example, variable &amp;quot;event_name&amp;quot; is specified afterwards.&lt;br /&gt;
  //          Note that using this, game translators only have to translate one &amp;quot;Event XXX is triggered&amp;quot; string for all possible events.&lt;br /&gt;
  bga.log( _(&amp;quot;Event ${event_name} is triggered&amp;quot;), {  event_name: _( &amp;quot;Armageddon&amp;quot; ) } ) );&lt;br /&gt;
&lt;br /&gt;
Note that argument &amp;quot;player_name&amp;quot; is ALWAYS pre-set with the name of the current player, so you can use it immediately.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.log( _(&amp;quot;${player_name} draw a card from the deck&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
=== bga.speechBubble( target, text, (optional) args, (optional) delay, (optional) duration, (optional) size ) ===&lt;br /&gt;
&lt;br /&gt;
Display a &amp;quot;speeck bubble&amp;quot;, attached to the specified target, containing the specified text.&lt;br /&gt;
&lt;br /&gt;
You can use &amp;quot;args&amp;quot; to customize text exactly like with bga.log.&lt;br /&gt;
&lt;br /&gt;
delay : milliseconds to wait before displaying the speech bubble (default : 0).&lt;br /&gt;
duration : how long to show the speech bubble in milliseconds (default : 3000).&lt;br /&gt;
size : size of the text in percent (default: 100)&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.speechBubble( _(&amp;quot;I play ${nbr} cards&amp;quot;), { nbr : 4 }, 0 );&lt;br /&gt;
  bga.speechBubble( _(&amp;quot;Good for you!&amp;quot;), { }, 2000 );&lt;br /&gt;
&lt;br /&gt;
== Get / search game elements and their properties ==&lt;br /&gt;
&lt;br /&gt;
=== bga.getElement( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Allow you to retrieve informations about one game element specified using &amp;quot;selector&amp;quot; argument.&lt;br /&gt;
&lt;br /&gt;
Return null if no element is found.&lt;br /&gt;
&lt;br /&gt;
Note : getElement throw an error if several elements matches the selector. If you want to retrieve several elements, you should use &amp;quot;getElements&amp;quot; instead of &amp;quot;getElement&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The following examples are showing all the possible use of bga.getElement :&lt;br /&gt;
&lt;br /&gt;
  // Basic example :&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve the ID of a game element using its name (&amp;quot;Deck&amp;quot;)&lt;br /&gt;
  var deck_id = bga.getElement( { name: &amp;quot;Deck&amp;quot; } );&lt;br /&gt;
  // Return : 1234  &lt;br /&gt;
&lt;br /&gt;
  // Examples using &amp;quot;field&amp;quot; parameter :&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve a specific property from a game element using its name (&amp;quot;Deck&amp;quot;)&lt;br /&gt;
  var deck_id = bga.getElement( { name: &amp;quot;Deck&amp;quot; }, &#039;x&#039; );&lt;br /&gt;
  // Return : 20&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve several properties from the previous element&lt;br /&gt;
  var deck_properties = bga.getElement( { name: &amp;quot;Deck&amp;quot; }, [&#039;name&#039;,&#039;id&#039;,&#039;parent&#039;, &#039;x&#039;,&#039;y&#039;,&#039;canShuffle&#039;] );&lt;br /&gt;
  // Return : { name:&#039;Deck&#039;, id:1234, parent:4321, x: 20, y:50, canShuffle: true }&lt;br /&gt;
  &lt;br /&gt;
  // Note : as you can see, getElement returns:&lt;br /&gt;
  //        _ the element ID by default, or&lt;br /&gt;
  //        _ a single value if you request a single field, or&lt;br /&gt;
  //        _ an object if you request several fields&lt;br /&gt;
&lt;br /&gt;
  // Examples using different &amp;quot;selector&amp;quot; paramter&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve an element name from its id&lt;br /&gt;
  var deck_name = bga.getElement( { id: 1234 }, [&#039;name&#039;] );&lt;br /&gt;
  // Return : &amp;quot;Deck&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  // Retrieve the last child element of another element&lt;br /&gt;
  // Here, we are requesting for elements who has element with ID=1234 (Deck) as their parent&lt;br /&gt;
  // Note the use of &amp;quot;limit:1&amp;quot; which allows us to retrieve only 1 element.&lt;br /&gt;
  var first_card_on_deck_id = bga.getElement( { parent: 1234, limit:1 } );&lt;br /&gt;
  //&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== bga.getElements( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Returns an object holding the properties of the elements matching the selector.&lt;br /&gt;
&lt;br /&gt;
  // Basic example: unselect all selected elements&lt;br /&gt;
  bga.removeStyle( bga.getElements( {tag: &#039;sbstyle_selected&#039;}), &#039;selected&#039; );&lt;br /&gt;
&lt;br /&gt;
=== bga.getElementsArray( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Returns an array of all elements matching the selector, holding the required properties.&lt;br /&gt;
&lt;br /&gt;
  // Basic example: get id of selected element&lt;br /&gt;
  var selected_tokens = bga.getElementsArray( {tag: &#039;sbstyle_selected&#039; } );&lt;br /&gt;
  var token_id = null;&lt;br /&gt;
  if (selected_tokens.length &amp;gt; 0) {&lt;br /&gt;
      token_id = selected_tokens[0];&lt;br /&gt;
  }&lt;br /&gt;
  return token_id;&lt;br /&gt;
&lt;br /&gt;
  // Classic example: get array of elements and iterate over it&lt;br /&gt;
  var all_cells = bga.getElementsArray( {tag: &#039;CELL&#039;}, [&#039;id&#039;,&#039;name&#039;,&#039;tags&#039;] );&lt;br /&gt;
  for (var i=0; i&amp;lt;all_cells.length; i++) {&lt;br /&gt;
     // ... process each cell ...&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Utility methods ==&lt;br /&gt;
&lt;br /&gt;
=== bga.isOn( element_id, parent_id ) ===&lt;br /&gt;
&lt;br /&gt;
Return true if &amp;quot;element_id&amp;quot; is a descendant of &amp;quot;parent_id&amp;quot; (ie : if element_id game element has been placed on parent_id game element).&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  if( bga.isOn( bga.getElementIfByName( &#039;Turn counter&#039; ), bga.getElementIfByName( &#039;Turn 6&#039; ) )&lt;br /&gt;
  {&lt;br /&gt;
     // Trigger game end&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Trigger most common game actions ==&lt;br /&gt;
&lt;br /&gt;
===moveElement( element_id, target_id )===&lt;br /&gt;
&lt;br /&gt;
Move element to specified target id.&lt;br /&gt;
&lt;br /&gt;
The exact destination of element depends on target &amp;quot;howToArrange&amp;quot; property (&amp;quot;How elements are arranged on it?&amp;quot; : spreaded/deck/...).&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.moveElement( bga.getElementIdByName( &#039;Turn counter&#039; ), bga.getElementIdByName( &#039;Turn 3&#039; ) );&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Other functions ==&lt;br /&gt;
&lt;br /&gt;
=== pause( milliseconds ) ===&lt;br /&gt;
&lt;br /&gt;
Pause the client interface during a specified number of milliseconds.&lt;br /&gt;
&lt;br /&gt;
If you do not use bga.pause, all Sandbox game actions are executed immediately and synchronously.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.log( &amp;quot;1&amp;quot; );    // Will be displayed immediately on the log&lt;br /&gt;
  bga.pause( 3000 ); // pause during 3 seconds&lt;br /&gt;
  bga.log( &amp;quot;2&amp;quot; );    // Will be displayed after the 3 second on the log&lt;br /&gt;
  bga.log( &amp;quot;3&amp;quot; );    // Will be displayed right after the previous one, without delay.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Tips : if you want to execute several consecutive &amp;quot;moveTo&amp;quot;, you should &amp;quot;bga.pause&amp;quot; between them, otherwise your element will move directly to the final destination.&lt;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://sr.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=2998</id>
		<title>SandboxScripts</title>
		<link rel="alternate" type="text/html" href="https://sr.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=2998"/>
		<updated>2018-04-23T14:57:39Z</updated>

		<summary type="html">&lt;p&gt;Een: /* bga.getElementsArray( selector, (optional) fields ) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This is the reference of functions you can call from your Sandbox scripts.&lt;br /&gt;
&lt;br /&gt;
= Javascript =&lt;br /&gt;
&lt;br /&gt;
BGA Sandbox scripts are written in Javascript.&lt;br /&gt;
&lt;br /&gt;
Using Javascript, you can write scripts to automate moves for your Sandbox games &amp;amp; provide rules reinforcement.&lt;br /&gt;
&lt;br /&gt;
Important : in the opposite of the most common usage of Javascript, Sandbox scripts are executed &#039;&#039;&#039;on server side&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
= BGA API =&lt;br /&gt;
&lt;br /&gt;
To interact with your BGA Sandbox game, we provide you an API.&lt;br /&gt;
&lt;br /&gt;
With this API, you can get properties values of game elements from the current game situation, modify them and/or trigger the game actions (ex : move this element here, flip this card, and so on).&lt;br /&gt;
&lt;br /&gt;
= Quick start =&lt;br /&gt;
&lt;br /&gt;
== Hello World Script ==&lt;br /&gt;
&lt;br /&gt;
From Sandbox editor &amp;quot;interface view&amp;quot; tab, select an element, and access to its property (top right icon).&lt;br /&gt;
&lt;br /&gt;
Go to &amp;quot;Scripts (advanced)&amp;quot; section.&lt;br /&gt;
&lt;br /&gt;
In front of &amp;quot;When this element is clicked&amp;quot;, enter &amp;quot;onMyClick&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Close the window. Go to &amp;quot;script view&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Enter the following :&lt;br /&gt;
&lt;br /&gt;
 function onMyClick( element_id )&lt;br /&gt;
 {&lt;br /&gt;
    bga.log(&amp;quot;Hello world! You just clicked on element &amp;quot; + element_id + &amp;quot;. Congrats!&amp;quot;);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Save &amp;amp; publish your project, starts a test session, click on the previous element : your message appears in the log on the right!&lt;br /&gt;
&lt;br /&gt;
== Top useful tips ==&lt;br /&gt;
&lt;br /&gt;
* You don&#039;t have to save&amp;amp;publish from the Sandbox editor for each modification of your script : each time you save your script (control+S), the script used for all test sessions is updated. Note that the production version on BGA is of course NOT updated until you explicitly save&amp;amp;publish again your project.&lt;br /&gt;
&lt;br /&gt;
* Alternatively to bga.log(), you can use bga.exit( &amp;quot;my message&amp;quot; ) to debug your script. With bga.exit, the script execution immediately stops and all previous game changes are cancelled, so this is very practical to try and retry an action until your script is fine.&lt;br /&gt;
&lt;br /&gt;
* We advise you to develop first a full playable version of the game without the scripts, and THEN to script it.&lt;br /&gt;
&lt;br /&gt;
* On Board Game Arena, players have come to expect fully implemented games with all rules enforced. So even if it&#039;s technically possible not to script the full game and to implement the game only partially, in most cases we&#039;ll publish only fully scripted games :)&lt;br /&gt;
&lt;br /&gt;
= Functions you can use in your Sandbox scripts=&lt;br /&gt;
&lt;br /&gt;
== Debugging functions ==&lt;br /&gt;
&lt;br /&gt;
=== bga.trace( txt / obj ) ===&lt;br /&gt;
&lt;br /&gt;
Write something immediately in the BGA log (on the right of the screen).&lt;br /&gt;
&lt;br /&gt;
This is the most practical way to debug your script :)&lt;br /&gt;
&lt;br /&gt;
Important : bga.trace is for debugging purpose only and won&#039;t be displayed on production.&lt;br /&gt;
&lt;br /&gt;
Note : you can also pass an object in parameter. This will dump the content of this object in the log.&lt;br /&gt;
&lt;br /&gt;
Note : in the opposite of bga.log, bga.trace is NOT cancelled if the game action failed (after a call to bga.cancel or bga.error). This makes bga.trace very practical to debug a game action that failed, and for this reason you should probably NEVER use bga.log for debugging purpose.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  // Example : write &amp;quot;Hello world&amp;quot; in the log&lt;br /&gt;
  bga.trace( &amp;quot;Hello world&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Example : dump an associative array in the log&lt;br /&gt;
  bga.trace( { mykey: &#039;myvalue&#039;, another_key: &#039;another_value&#039; } );&lt;br /&gt;
&lt;br /&gt;
=== bga.exit( txt / obj ) ===&lt;br /&gt;
&lt;br /&gt;
Stop the script immediately, display the &amp;quot;txt&amp;quot; messages and cancel (ie : rollback) on every previous API call except bga.trace :&lt;br /&gt;
&lt;br /&gt;
ALL previous BGA api call are canceled and there will be no visible changes on the interface (ex : no moves, no visible property changes, ...). Only &amp;quot;bga.trace&amp;quot; API commands are kept so you can debug.&lt;br /&gt;
&lt;br /&gt;
bga.exit is very practical when you want to repeat a game action again and again to debug it : with a call to bga.exit at the end of your script, you make sure that your game situation will be kept unchanged after each test.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.exit( &amp;quot;My script is stopped by this call&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Example with dumping a javascript variable&lt;br /&gt;
  bga.exit( my_variable_to_dump );&lt;br /&gt;
&lt;br /&gt;
== Cancelling a game action ==&lt;br /&gt;
&lt;br /&gt;
=== bga.cancel( txt ) ===&lt;br /&gt;
&lt;br /&gt;
This is the function to use when a player is doing something against game rules.&lt;br /&gt;
&lt;br /&gt;
The text message in parameter will be displayed to this player as a &amp;quot;red message&amp;quot;, so he/she can understand the rule.&lt;br /&gt;
&lt;br /&gt;
All previous BGA api call are cancelled, and there will be no visible changes on the interface.&lt;br /&gt;
&lt;br /&gt;
   // Example :&lt;br /&gt;
   bga.cancel( _(&amp;quot;You cannot move this piece here&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
Note : most of the time, you should wrap your text inside a _() translation marker to make this string translatable.&lt;br /&gt;
&lt;br /&gt;
=== bga.error( text ) ===&lt;br /&gt;
&lt;br /&gt;
This is the function to use when some unexpected error happens in your script.&lt;br /&gt;
&lt;br /&gt;
The text message will be displayed to user, with mention &amp;quot;Unexpected error&amp;quot;. The player will be incited to fill a bug report. The purpose of the message is to help you to identify the bug.&lt;br /&gt;
&lt;br /&gt;
All previous BGA api call are cancelled, and there will be no visible changes on the interface.&lt;br /&gt;
&lt;br /&gt;
   // Example :&lt;br /&gt;
   if( card_picked === null )&lt;br /&gt;
   {&lt;br /&gt;
       bga.error( &amp;quot;Cannot find a card to pick !&amp;quot; );&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
Note : you should NEVER wrap text inside bga.error with _() translation marker, because unexpected error should not be translate (so you can eventually recognize them when reported by players in bug report).&lt;br /&gt;
&lt;br /&gt;
== Game log (history) ==&lt;br /&gt;
&lt;br /&gt;
=== bga.log( txt, (optional) args ) ===&lt;br /&gt;
&lt;br /&gt;
Write something in the BGA log on the right.&lt;br /&gt;
&lt;br /&gt;
  // Example : simple log&lt;br /&gt;
  bga.log( _(&amp;quot;A new round starts&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
You may add arguments to your log, like this :&lt;br /&gt;
&lt;br /&gt;
  // Example: log with argument to display a card name.&lt;br /&gt;
  //          In this example, variable &amp;quot;event_name&amp;quot; is specified afterwards.&lt;br /&gt;
  //          Note that using this, game translators only have to translate one &amp;quot;Event XXX is triggered&amp;quot; string for all possible events.&lt;br /&gt;
  bga.log( _(&amp;quot;Event ${event_name} is triggered&amp;quot;), {  event_name: _( &amp;quot;Armageddon&amp;quot; ) } ) );&lt;br /&gt;
&lt;br /&gt;
Note that argument &amp;quot;player_name&amp;quot; is ALWAYS pre-set with the name of the current player, so you can use it immediately.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.log( _(&amp;quot;${player_name} draw a card from the deck&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
=== bga.speechBubble( target, text, (optional) args, (optional) delay, (optional) duration, (optional) size ) ===&lt;br /&gt;
&lt;br /&gt;
Display a &amp;quot;speeck bubble&amp;quot;, attached to the specified target, containing the specified text.&lt;br /&gt;
&lt;br /&gt;
You can use &amp;quot;args&amp;quot; to customize text exactly like with bga.log.&lt;br /&gt;
&lt;br /&gt;
delay : milliseconds to wait before displaying the speech bubble (default : 0).&lt;br /&gt;
duration : how long to show the speech bubble in milliseconds (default : 3000).&lt;br /&gt;
size : size of the text in percent (default: 100)&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.speechBubble( _(&amp;quot;I play ${nbr} cards&amp;quot;), { nbr : 4 }, 0 );&lt;br /&gt;
  bga.speechBubble( _(&amp;quot;Good for you!&amp;quot;), { }, 2000 );&lt;br /&gt;
&lt;br /&gt;
== Get / search game elements and their properties ==&lt;br /&gt;
&lt;br /&gt;
=== bga.getElement( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Allow you to retrieve informations about one game element specified using &amp;quot;selector&amp;quot; argument.&lt;br /&gt;
&lt;br /&gt;
Return null if no element is found.&lt;br /&gt;
&lt;br /&gt;
Note : getElement throw an error if several elements matches the selector. If you want to retrieve several elements, you should use &amp;quot;getElements&amp;quot; instead of &amp;quot;getElement&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The following examples are showing all the possible use of bga.getElement :&lt;br /&gt;
&lt;br /&gt;
  // Basic example :&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve the ID of a game element using its name (&amp;quot;Deck&amp;quot;)&lt;br /&gt;
  var deck_id = bga.getElement( { name: &amp;quot;Deck&amp;quot; } );&lt;br /&gt;
  // Return : 1234  &lt;br /&gt;
&lt;br /&gt;
  // Examples using &amp;quot;field&amp;quot; parameter :&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve a specific property from a game element using its name (&amp;quot;Deck&amp;quot;)&lt;br /&gt;
  var deck_id = bga.getElement( { name: &amp;quot;Deck&amp;quot; }, &#039;x&#039; );&lt;br /&gt;
  // Return : 20&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve several properties from the previous element&lt;br /&gt;
  var deck_properties = bga.getElement( { name: &amp;quot;Deck&amp;quot; }, [&#039;name&#039;,&#039;id&#039;,&#039;parent&#039;, &#039;x&#039;,&#039;y&#039;,&#039;canShuffle&#039;] );&lt;br /&gt;
  // Return : { name:&#039;Deck&#039;, id:1234, parent:4321, x: 20, y:50, canShuffle: true }&lt;br /&gt;
  &lt;br /&gt;
  // Note : as you can see, getElement returns:&lt;br /&gt;
  //        _ the element ID by default, or&lt;br /&gt;
  //        _ a single value if you request a single field, or&lt;br /&gt;
  //        _ an object if you request several fields&lt;br /&gt;
&lt;br /&gt;
  // Examples using different &amp;quot;selector&amp;quot; paramter&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve an element name from its id&lt;br /&gt;
  var deck_name = bga.getElement( { id: 1234 }, [&#039;name&#039;] );&lt;br /&gt;
  // Return : &amp;quot;Deck&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  // Retrieve the last child element of another element&lt;br /&gt;
  // Here, we are requesting for elements who has element with ID=1234 (Deck) as their parent&lt;br /&gt;
  // Note the use of &amp;quot;limit:1&amp;quot; which allows us to retrieve only 1 element.&lt;br /&gt;
  var first_card_on_deck_id = bga.getElement( { parent: 1234, limit:1 } );&lt;br /&gt;
  //&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== bga.getElements( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Returns an object holding the properties of the elements matching the selector.&lt;br /&gt;
&lt;br /&gt;
  // Basic example: unselect all selected elements&lt;br /&gt;
  bga.removeStyle( bga.getElements( {tag: &#039;sbstyle_selected&#039;}), &#039;selected&#039; );&lt;br /&gt;
&lt;br /&gt;
=== bga.getElementsArray( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Returns an array of all elements matching the selector, holding the required properties.&lt;br /&gt;
&lt;br /&gt;
  // Basic example: get id of selected element&lt;br /&gt;
  var selected_tokens = bga.getElementsArray( {tag: &#039;sbstyle_selected&#039; } );&lt;br /&gt;
  var token_id = null;&lt;br /&gt;
  if (selected_tokens.length &amp;gt; 0) {&lt;br /&gt;
      token_id = selected_tokens[0];&lt;br /&gt;
  }&lt;br /&gt;
  return token_id;&lt;br /&gt;
&lt;br /&gt;
  // Classic example: get array of elements and iterate over it&lt;br /&gt;
  var all_cells = bga.getElementsArray( {tag: &#039;CELL&#039;}, [&#039;id&#039;,&#039;name&#039;,&#039;tag&#039;] );&lt;br /&gt;
  for (var i=0; i&amp;lt;all_cells.length; i++) {&lt;br /&gt;
     // ... process each cell ...&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Utility methods ==&lt;br /&gt;
&lt;br /&gt;
=== bga.isOn( element_id, parent_id ) ===&lt;br /&gt;
&lt;br /&gt;
Return true if &amp;quot;element_id&amp;quot; is a descendant of &amp;quot;parent_id&amp;quot; (ie : if element_id game element has been placed on parent_id game element).&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  if( bga.isOn( bga.getElementIfByName( &#039;Turn counter&#039; ), bga.getElementIfByName( &#039;Turn 6&#039; ) )&lt;br /&gt;
  {&lt;br /&gt;
     // Trigger game end&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Trigger most common game actions ==&lt;br /&gt;
&lt;br /&gt;
===moveElement( element_id, target_id )===&lt;br /&gt;
&lt;br /&gt;
Move element to specified target id.&lt;br /&gt;
&lt;br /&gt;
The exact destination of element depends on target &amp;quot;howToArrange&amp;quot; property (&amp;quot;How elements are arranged on it?&amp;quot; : spreaded/deck/...).&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.moveElement( bga.getElementIdByName( &#039;Turn counter&#039; ), bga.getElementIdByName( &#039;Turn 3&#039; ) );&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Other functions ==&lt;br /&gt;
&lt;br /&gt;
=== pause( milliseconds ) ===&lt;br /&gt;
&lt;br /&gt;
Pause the client interface during a specified number of milliseconds.&lt;br /&gt;
&lt;br /&gt;
If you do not use bga.pause, all Sandbox game actions are executed immediately and synchronously.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.log( &amp;quot;1&amp;quot; );    // Will be displayed immediately on the log&lt;br /&gt;
  bga.pause( 3000 ); // pause during 3 seconds&lt;br /&gt;
  bga.log( &amp;quot;2&amp;quot; );    // Will be displayed after the 3 second on the log&lt;br /&gt;
  bga.log( &amp;quot;3&amp;quot; );    // Will be displayed right after the previous one, without delay.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Tips : if you want to execute several consecutive &amp;quot;moveTo&amp;quot;, you should &amp;quot;bga.pause&amp;quot; between them, otherwise your element will move directly to the final destination.&lt;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://sr.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=2997</id>
		<title>SandboxScripts</title>
		<link rel="alternate" type="text/html" href="https://sr.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=2997"/>
		<updated>2018-04-23T14:53:41Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Get / search game elements and their properties */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This is the reference of functions you can call from your Sandbox scripts.&lt;br /&gt;
&lt;br /&gt;
= Javascript =&lt;br /&gt;
&lt;br /&gt;
BGA Sandbox scripts are written in Javascript.&lt;br /&gt;
&lt;br /&gt;
Using Javascript, you can write scripts to automate moves for your Sandbox games &amp;amp; provide rules reinforcement.&lt;br /&gt;
&lt;br /&gt;
Important : in the opposite of the most common usage of Javascript, Sandbox scripts are executed &#039;&#039;&#039;on server side&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
= BGA API =&lt;br /&gt;
&lt;br /&gt;
To interact with your BGA Sandbox game, we provide you an API.&lt;br /&gt;
&lt;br /&gt;
With this API, you can get properties values of game elements from the current game situation, modify them and/or trigger the game actions (ex : move this element here, flip this card, and so on).&lt;br /&gt;
&lt;br /&gt;
= Quick start =&lt;br /&gt;
&lt;br /&gt;
== Hello World Script ==&lt;br /&gt;
&lt;br /&gt;
From Sandbox editor &amp;quot;interface view&amp;quot; tab, select an element, and access to its property (top right icon).&lt;br /&gt;
&lt;br /&gt;
Go to &amp;quot;Scripts (advanced)&amp;quot; section.&lt;br /&gt;
&lt;br /&gt;
In front of &amp;quot;When this element is clicked&amp;quot;, enter &amp;quot;onMyClick&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Close the window. Go to &amp;quot;script view&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Enter the following :&lt;br /&gt;
&lt;br /&gt;
 function onMyClick( element_id )&lt;br /&gt;
 {&lt;br /&gt;
    bga.log(&amp;quot;Hello world! You just clicked on element &amp;quot; + element_id + &amp;quot;. Congrats!&amp;quot;);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Save &amp;amp; publish your project, starts a test session, click on the previous element : your message appears in the log on the right!&lt;br /&gt;
&lt;br /&gt;
== Top useful tips ==&lt;br /&gt;
&lt;br /&gt;
* You don&#039;t have to save&amp;amp;publish from the Sandbox editor for each modification of your script : each time you save your script (control+S), the script used for all test sessions is updated. Note that the production version on BGA is of course NOT updated until you explicitly save&amp;amp;publish again your project.&lt;br /&gt;
&lt;br /&gt;
* Alternatively to bga.log(), you can use bga.exit( &amp;quot;my message&amp;quot; ) to debug your script. With bga.exit, the script execution immediately stops and all previous game changes are cancelled, so this is very practical to try and retry an action until your script is fine.&lt;br /&gt;
&lt;br /&gt;
* We advise you to develop first a full playable version of the game without the scripts, and THEN to script it.&lt;br /&gt;
&lt;br /&gt;
* On Board Game Arena, players have come to expect fully implemented games with all rules enforced. So even if it&#039;s technically possible not to script the full game and to implement the game only partially, in most cases we&#039;ll publish only fully scripted games :)&lt;br /&gt;
&lt;br /&gt;
= Functions you can use in your Sandbox scripts=&lt;br /&gt;
&lt;br /&gt;
== Debugging functions ==&lt;br /&gt;
&lt;br /&gt;
=== bga.trace( txt / obj ) ===&lt;br /&gt;
&lt;br /&gt;
Write something immediately in the BGA log (on the right of the screen).&lt;br /&gt;
&lt;br /&gt;
This is the most practical way to debug your script :)&lt;br /&gt;
&lt;br /&gt;
Important : bga.trace is for debugging purpose only and won&#039;t be displayed on production.&lt;br /&gt;
&lt;br /&gt;
Note : you can also pass an object in parameter. This will dump the content of this object in the log.&lt;br /&gt;
&lt;br /&gt;
Note : in the opposite of bga.log, bga.trace is NOT cancelled if the game action failed (after a call to bga.cancel or bga.error). This makes bga.trace very practical to debug a game action that failed, and for this reason you should probably NEVER use bga.log for debugging purpose.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  // Example : write &amp;quot;Hello world&amp;quot; in the log&lt;br /&gt;
  bga.trace( &amp;quot;Hello world&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Example : dump an associative array in the log&lt;br /&gt;
  bga.trace( { mykey: &#039;myvalue&#039;, another_key: &#039;another_value&#039; } );&lt;br /&gt;
&lt;br /&gt;
=== bga.exit( txt / obj ) ===&lt;br /&gt;
&lt;br /&gt;
Stop the script immediately, display the &amp;quot;txt&amp;quot; messages and cancel (ie : rollback) on every previous API call except bga.trace :&lt;br /&gt;
&lt;br /&gt;
ALL previous BGA api call are canceled and there will be no visible changes on the interface (ex : no moves, no visible property changes, ...). Only &amp;quot;bga.trace&amp;quot; API commands are kept so you can debug.&lt;br /&gt;
&lt;br /&gt;
bga.exit is very practical when you want to repeat a game action again and again to debug it : with a call to bga.exit at the end of your script, you make sure that your game situation will be kept unchanged after each test.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.exit( &amp;quot;My script is stopped by this call&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Example with dumping a javascript variable&lt;br /&gt;
  bga.exit( my_variable_to_dump );&lt;br /&gt;
&lt;br /&gt;
== Cancelling a game action ==&lt;br /&gt;
&lt;br /&gt;
=== bga.cancel( txt ) ===&lt;br /&gt;
&lt;br /&gt;
This is the function to use when a player is doing something against game rules.&lt;br /&gt;
&lt;br /&gt;
The text message in parameter will be displayed to this player as a &amp;quot;red message&amp;quot;, so he/she can understand the rule.&lt;br /&gt;
&lt;br /&gt;
All previous BGA api call are cancelled, and there will be no visible changes on the interface.&lt;br /&gt;
&lt;br /&gt;
   // Example :&lt;br /&gt;
   bga.cancel( _(&amp;quot;You cannot move this piece here&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
Note : most of the time, you should wrap your text inside a _() translation marker to make this string translatable.&lt;br /&gt;
&lt;br /&gt;
=== bga.error( text ) ===&lt;br /&gt;
&lt;br /&gt;
This is the function to use when some unexpected error happens in your script.&lt;br /&gt;
&lt;br /&gt;
The text message will be displayed to user, with mention &amp;quot;Unexpected error&amp;quot;. The player will be incited to fill a bug report. The purpose of the message is to help you to identify the bug.&lt;br /&gt;
&lt;br /&gt;
All previous BGA api call are cancelled, and there will be no visible changes on the interface.&lt;br /&gt;
&lt;br /&gt;
   // Example :&lt;br /&gt;
   if( card_picked === null )&lt;br /&gt;
   {&lt;br /&gt;
       bga.error( &amp;quot;Cannot find a card to pick !&amp;quot; );&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
Note : you should NEVER wrap text inside bga.error with _() translation marker, because unexpected error should not be translate (so you can eventually recognize them when reported by players in bug report).&lt;br /&gt;
&lt;br /&gt;
== Game log (history) ==&lt;br /&gt;
&lt;br /&gt;
=== bga.log( txt, (optional) args ) ===&lt;br /&gt;
&lt;br /&gt;
Write something in the BGA log on the right.&lt;br /&gt;
&lt;br /&gt;
  // Example : simple log&lt;br /&gt;
  bga.log( _(&amp;quot;A new round starts&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
You may add arguments to your log, like this :&lt;br /&gt;
&lt;br /&gt;
  // Example: log with argument to display a card name.&lt;br /&gt;
  //          In this example, variable &amp;quot;event_name&amp;quot; is specified afterwards.&lt;br /&gt;
  //          Note that using this, game translators only have to translate one &amp;quot;Event XXX is triggered&amp;quot; string for all possible events.&lt;br /&gt;
  bga.log( _(&amp;quot;Event ${event_name} is triggered&amp;quot;), {  event_name: _( &amp;quot;Armageddon&amp;quot; ) } ) );&lt;br /&gt;
&lt;br /&gt;
Note that argument &amp;quot;player_name&amp;quot; is ALWAYS pre-set with the name of the current player, so you can use it immediately.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.log( _(&amp;quot;${player_name} draw a card from the deck&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
=== bga.speechBubble( target, text, (optional) args, (optional) delay, (optional) duration, (optional) size ) ===&lt;br /&gt;
&lt;br /&gt;
Display a &amp;quot;speeck bubble&amp;quot;, attached to the specified target, containing the specified text.&lt;br /&gt;
&lt;br /&gt;
You can use &amp;quot;args&amp;quot; to customize text exactly like with bga.log.&lt;br /&gt;
&lt;br /&gt;
delay : milliseconds to wait before displaying the speech bubble (default : 0).&lt;br /&gt;
duration : how long to show the speech bubble in milliseconds (default : 3000).&lt;br /&gt;
size : size of the text in percent (default: 100)&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.speechBubble( _(&amp;quot;I play ${nbr} cards&amp;quot;), { nbr : 4 }, 0 );&lt;br /&gt;
  bga.speechBubble( _(&amp;quot;Good for you!&amp;quot;), { }, 2000 );&lt;br /&gt;
&lt;br /&gt;
== Get / search game elements and their properties ==&lt;br /&gt;
&lt;br /&gt;
=== bga.getElement( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Allow you to retrieve informations about one game element specified using &amp;quot;selector&amp;quot; argument.&lt;br /&gt;
&lt;br /&gt;
Return null if no element is found.&lt;br /&gt;
&lt;br /&gt;
Note : getElement throw an error if several elements matches the selector. If you want to retrieve several elements, you should use &amp;quot;getElements&amp;quot; instead of &amp;quot;getElement&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The following examples are showing all the possible use of bga.getElement :&lt;br /&gt;
&lt;br /&gt;
  // Basic example :&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve the ID of a game element using its name (&amp;quot;Deck&amp;quot;)&lt;br /&gt;
  var deck_id = bga.getElement( { name: &amp;quot;Deck&amp;quot; } );&lt;br /&gt;
  // Return : 1234  &lt;br /&gt;
&lt;br /&gt;
  // Examples using &amp;quot;field&amp;quot; parameter :&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve a specific property from a game element using its name (&amp;quot;Deck&amp;quot;)&lt;br /&gt;
  var deck_id = bga.getElement( { name: &amp;quot;Deck&amp;quot; }, &#039;x&#039; );&lt;br /&gt;
  // Return : 20&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve several properties from the previous element&lt;br /&gt;
  var deck_properties = bga.getElement( { name: &amp;quot;Deck&amp;quot; }, [&#039;name&#039;,&#039;id&#039;,&#039;parent&#039;, &#039;x&#039;,&#039;y&#039;,&#039;canShuffle&#039;] );&lt;br /&gt;
  // Return : { name:&#039;Deck&#039;, id:1234, parent:4321, x: 20, y:50, canShuffle: true }&lt;br /&gt;
  &lt;br /&gt;
  // Note : as you can see, getElement returns:&lt;br /&gt;
  //        _ the element ID by default, or&lt;br /&gt;
  //        _ a single value if you request a single field, or&lt;br /&gt;
  //        _ an object if you request several fields&lt;br /&gt;
&lt;br /&gt;
  // Examples using different &amp;quot;selector&amp;quot; paramter&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve an element name from its id&lt;br /&gt;
  var deck_name = bga.getElement( { id: 1234 }, [&#039;name&#039;] );&lt;br /&gt;
  // Return : &amp;quot;Deck&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  // Retrieve the last child element of another element&lt;br /&gt;
  // Here, we are requesting for elements who has element with ID=1234 (Deck) as their parent&lt;br /&gt;
  // Note the use of &amp;quot;limit:1&amp;quot; which allows us to retrieve only 1 element.&lt;br /&gt;
  var first_card_on_deck_id = bga.getElement( { parent: 1234, limit:1 } );&lt;br /&gt;
  //&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== bga.getElements( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Returns an object holding the properties of the elements matching the selector.&lt;br /&gt;
&lt;br /&gt;
  // Basic example: unselect all selected elements&lt;br /&gt;
  bga.removeStyle( bga.getElements( {tag: &#039;sbstyle_selected&#039;}), &#039;selected&#039; );&lt;br /&gt;
&lt;br /&gt;
=== bga.getElementsArray( selector, (optional) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Returns an array of all elements matching the selector, holding the required properties.&lt;br /&gt;
&lt;br /&gt;
  // Basic example: get id of selected element&lt;br /&gt;
  var selected_tokens = bga.getElementsArray( {tag: &#039;sbstyle_selected&#039; } );&lt;br /&gt;
  var token_id = null;&lt;br /&gt;
  if (selected_tokens.length &amp;gt; 0) {&lt;br /&gt;
      token_id = selected_tokens[0];&lt;br /&gt;
  }&lt;br /&gt;
  return token_id;&lt;br /&gt;
&lt;br /&gt;
== Utility methods ==&lt;br /&gt;
&lt;br /&gt;
=== bga.isOn( element_id, parent_id ) ===&lt;br /&gt;
&lt;br /&gt;
Return true if &amp;quot;element_id&amp;quot; is a descendant of &amp;quot;parent_id&amp;quot; (ie : if element_id game element has been placed on parent_id game element).&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  if( bga.isOn( bga.getElementIfByName( &#039;Turn counter&#039; ), bga.getElementIfByName( &#039;Turn 6&#039; ) )&lt;br /&gt;
  {&lt;br /&gt;
     // Trigger game end&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Trigger most common game actions ==&lt;br /&gt;
&lt;br /&gt;
===moveElement( element_id, target_id )===&lt;br /&gt;
&lt;br /&gt;
Move element to specified target id.&lt;br /&gt;
&lt;br /&gt;
The exact destination of element depends on target &amp;quot;howToArrange&amp;quot; property (&amp;quot;How elements are arranged on it?&amp;quot; : spreaded/deck/...).&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.moveElement( bga.getElementIdByName( &#039;Turn counter&#039; ), bga.getElementIdByName( &#039;Turn 3&#039; ) );&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Other functions ==&lt;br /&gt;
&lt;br /&gt;
=== pause( milliseconds ) ===&lt;br /&gt;
&lt;br /&gt;
Pause the client interface during a specified number of milliseconds.&lt;br /&gt;
&lt;br /&gt;
If you do not use bga.pause, all Sandbox game actions are executed immediately and synchronously.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.log( &amp;quot;1&amp;quot; );    // Will be displayed immediately on the log&lt;br /&gt;
  bga.pause( 3000 ); // pause during 3 seconds&lt;br /&gt;
  bga.log( &amp;quot;2&amp;quot; );    // Will be displayed after the 3 second on the log&lt;br /&gt;
  bga.log( &amp;quot;3&amp;quot; );    // Will be displayed right after the previous one, without delay.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Tips : if you want to execute several consecutive &amp;quot;moveTo&amp;quot;, you should &amp;quot;bga.pause&amp;quot; between them, otherwise your element will move directly to the final destination.&lt;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://sr.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=2996</id>
		<title>SandboxScripts</title>
		<link rel="alternate" type="text/html" href="https://sr.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=2996"/>
		<updated>2018-04-23T14:39:23Z</updated>

		<summary type="html">&lt;p&gt;Een: /* bga.getElement( selector, (optionnal) fields ) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This is the reference of functions you can call from your Sandbox scripts.&lt;br /&gt;
&lt;br /&gt;
= Javascript =&lt;br /&gt;
&lt;br /&gt;
BGA Sandbox scripts are written in Javascript.&lt;br /&gt;
&lt;br /&gt;
Using Javascript, you can write scripts to automate moves for your Sandbox games &amp;amp; provide rules reinforcement.&lt;br /&gt;
&lt;br /&gt;
Important : in the opposite of the most common usage of Javascript, Sandbox scripts are executed &#039;&#039;&#039;on server side&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
= BGA API =&lt;br /&gt;
&lt;br /&gt;
To interact with your BGA Sandbox game, we provide you an API.&lt;br /&gt;
&lt;br /&gt;
With this API, you can get properties values of game elements from the current game situation, modify them and/or trigger the game actions (ex : move this element here, flip this card, and so on).&lt;br /&gt;
&lt;br /&gt;
= Quick start =&lt;br /&gt;
&lt;br /&gt;
== Hello World Script ==&lt;br /&gt;
&lt;br /&gt;
From Sandbox editor &amp;quot;interface view&amp;quot; tab, select an element, and access to its property (top right icon).&lt;br /&gt;
&lt;br /&gt;
Go to &amp;quot;Scripts (advanced)&amp;quot; section.&lt;br /&gt;
&lt;br /&gt;
In front of &amp;quot;When this element is clicked&amp;quot;, enter &amp;quot;onMyClick&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Close the window. Go to &amp;quot;script view&amp;quot; tab.&lt;br /&gt;
&lt;br /&gt;
Enter the following :&lt;br /&gt;
&lt;br /&gt;
 function onMyClick( element_id )&lt;br /&gt;
 {&lt;br /&gt;
    bga.log(&amp;quot;Hello world! You just clicked on element &amp;quot; + element_id + &amp;quot;. Congrats!&amp;quot;);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Save &amp;amp; publish your project, starts a test session, click on the previous element : your message appears in the log on the right!&lt;br /&gt;
&lt;br /&gt;
== Top useful tips ==&lt;br /&gt;
&lt;br /&gt;
* You don&#039;t have to save&amp;amp;publish from the Sandbox editor for each modification of your script : each time you save your script (control+S), the script used for all test sessions is updated. Note that the production version on BGA is of course NOT updated until you explicitly save&amp;amp;publish again your project.&lt;br /&gt;
&lt;br /&gt;
* Alternatively to bga.log(), you can use bga.exit( &amp;quot;my message&amp;quot; ) to debug your script. With bga.exit, the script execution immediately stops and all previous game changes are cancelled, so this is very practical to try and retry an action until your script is fine.&lt;br /&gt;
&lt;br /&gt;
* We advise you to develop first a full playable version of the game without the scripts, and THEN to script it.&lt;br /&gt;
&lt;br /&gt;
* On Board Game Arena, players have come to expect fully implemented games with all rules enforced. So even if it&#039;s technically possible not to script the full game and to implement the game only partially, in most cases we&#039;ll publish only fully scripted games :)&lt;br /&gt;
&lt;br /&gt;
= Functions you can use in your Sandbox scripts=&lt;br /&gt;
&lt;br /&gt;
== Debugging functions ==&lt;br /&gt;
&lt;br /&gt;
=== bga.trace( txt / obj ) ===&lt;br /&gt;
&lt;br /&gt;
Write something immediately in the BGA log (on the right of the screen).&lt;br /&gt;
&lt;br /&gt;
This is the most practical way to debug your script :)&lt;br /&gt;
&lt;br /&gt;
Important : bga.trace is for debugging purpose only and won&#039;t be displayed on production.&lt;br /&gt;
&lt;br /&gt;
Note : you can also pass an object in parameter. This will dump the content of this object in the log.&lt;br /&gt;
&lt;br /&gt;
Note : in the opposite of bga.log, bga.trace is NOT cancelled if the game action failed (after a call to bga.cancel or bga.error). This makes bga.trace very practical to debug a game action that failed, and for this reason you should probably NEVER use bga.log for debugging purpose.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  // Example : write &amp;quot;Hello world&amp;quot; in the log&lt;br /&gt;
  bga.trace( &amp;quot;Hello world&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Example : dump an associative array in the log&lt;br /&gt;
  bga.trace( { mykey: &#039;myvalue&#039;, another_key: &#039;another_value&#039; } );&lt;br /&gt;
&lt;br /&gt;
=== bga.exit( txt / obj ) ===&lt;br /&gt;
&lt;br /&gt;
Stop the script immediately, display the &amp;quot;txt&amp;quot; messages and cancel (ie : rollback) on every previous API call except bga.trace :&lt;br /&gt;
&lt;br /&gt;
ALL previous BGA api call are canceled and there will be no visible changes on the interface (ex : no moves, no visible property changes, ...). Only &amp;quot;bga.trace&amp;quot; API commands are kept so you can debug.&lt;br /&gt;
&lt;br /&gt;
bga.exit is very practical when you want to repeat a game action again and again to debug it : with a call to bga.exit at the end of your script, you make sure that your game situation will be kept unchanged after each test.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.exit( &amp;quot;My script is stopped by this call&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Example with dumping a javascript variable&lt;br /&gt;
  bga.exit( my_variable_to_dump );&lt;br /&gt;
&lt;br /&gt;
== Cancelling a game action ==&lt;br /&gt;
&lt;br /&gt;
=== bga.cancel( txt ) ===&lt;br /&gt;
&lt;br /&gt;
This is the function to use when a player is doing something against game rules.&lt;br /&gt;
&lt;br /&gt;
The text message in parameter will be displayed to this player as a &amp;quot;red message&amp;quot;, so he/she can understand the rule.&lt;br /&gt;
&lt;br /&gt;
All previous BGA api call are cancelled, and there will be no visible changes on the interface.&lt;br /&gt;
&lt;br /&gt;
   // Example :&lt;br /&gt;
   bga.cancel( _(&amp;quot;You cannot move this piece here&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
Note : most of the time, you should wrap your text inside a _() translation marker to make this string translatable.&lt;br /&gt;
&lt;br /&gt;
=== bga.error( text ) ===&lt;br /&gt;
&lt;br /&gt;
This is the function to use when some unexpected error happens in your script.&lt;br /&gt;
&lt;br /&gt;
The text message will be displayed to user, with mention &amp;quot;Unexpected error&amp;quot;. The player will be incited to fill a bug report. The purpose of the message is to help you to identify the bug.&lt;br /&gt;
&lt;br /&gt;
All previous BGA api call are cancelled, and there will be no visible changes on the interface.&lt;br /&gt;
&lt;br /&gt;
   // Example :&lt;br /&gt;
   if( card_picked === null )&lt;br /&gt;
   {&lt;br /&gt;
       bga.error( &amp;quot;Cannot find a card to pick !&amp;quot; );&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
Note : you should NEVER wrap text inside bga.error with _() translation marker, because unexpected error should not be translate (so you can eventually recognize them when reported by players in bug report).&lt;br /&gt;
&lt;br /&gt;
== Game log (history) ==&lt;br /&gt;
&lt;br /&gt;
=== bga.log( txt, (optional) args ) ===&lt;br /&gt;
&lt;br /&gt;
Write something in the BGA log on the right.&lt;br /&gt;
&lt;br /&gt;
  // Example : simple log&lt;br /&gt;
  bga.log( _(&amp;quot;A new round starts&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
You may add arguments to your log, like this :&lt;br /&gt;
&lt;br /&gt;
  // Example: log with argument to display a card name.&lt;br /&gt;
  //          In this example, variable &amp;quot;event_name&amp;quot; is specified afterwards.&lt;br /&gt;
  //          Note that using this, game translators only have to translate one &amp;quot;Event XXX is triggered&amp;quot; string for all possible events.&lt;br /&gt;
  bga.log( _(&amp;quot;Event ${event_name} is triggered&amp;quot;), {  event_name: _( &amp;quot;Armageddon&amp;quot; ) } ) );&lt;br /&gt;
&lt;br /&gt;
Note that argument &amp;quot;player_name&amp;quot; is ALWAYS pre-set with the name of the current player, so you can use it immediately.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.log( _(&amp;quot;${player_name} draw a card from the deck&amp;quot;) );&lt;br /&gt;
&lt;br /&gt;
=== bga.speechBubble( target, text, (optional) args, (optional) delay, (optional) duration, (optional) size ) ===&lt;br /&gt;
&lt;br /&gt;
Display a &amp;quot;speeck bubble&amp;quot;, attached to the specified target, containing the specified text.&lt;br /&gt;
&lt;br /&gt;
You can use &amp;quot;args&amp;quot; to customize text exactly like with bga.log.&lt;br /&gt;
&lt;br /&gt;
delay : milliseconds to wait before displaying the speech bubble (default : 0).&lt;br /&gt;
duration : how long to show the speech bubble in milliseconds (default : 3000).&lt;br /&gt;
size : size of the text in percent (default: 100)&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.speechBubble( _(&amp;quot;I play ${nbr} cards&amp;quot;), { nbr : 4 }, 0 );&lt;br /&gt;
  bga.speechBubble( _(&amp;quot;Good for you!&amp;quot;), { }, 2000 );&lt;br /&gt;
&lt;br /&gt;
== Get / search game elements and their properties ==&lt;br /&gt;
&lt;br /&gt;
=== bga.getElement( selector, (optionnal) fields ) ===&lt;br /&gt;
&lt;br /&gt;
Allow you to retrieve informations about one game element specified using &amp;quot;selector&amp;quot; argument.&lt;br /&gt;
&lt;br /&gt;
Return null if no element is found.&lt;br /&gt;
&lt;br /&gt;
Note : getElement throw an error if several elements matches the selector. If you want to retrieve several elements, you should use &amp;quot;getElements&amp;quot; instead of &amp;quot;getElement&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The following examples are showing all the possible use of bga.getElement :&lt;br /&gt;
&lt;br /&gt;
  // Basic example :&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve the ID of a game element using its name (&amp;quot;Deck&amp;quot;)&lt;br /&gt;
  var deck_id = bga.getElement( { name: &amp;quot;Deck&amp;quot; } );&lt;br /&gt;
  // Return : 1234  &lt;br /&gt;
&lt;br /&gt;
  // Examples using &amp;quot;field&amp;quot; parameter :&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve a specific property from a game element using its name (&amp;quot;Deck&amp;quot;)&lt;br /&gt;
  var deck_id = bga.getElement( { name: &amp;quot;Deck&amp;quot; }, &#039;x&#039; );&lt;br /&gt;
  // Return : 20&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve several properties from the previous element&lt;br /&gt;
  var deck_properties = bga.getElement( { name: &amp;quot;Deck&amp;quot; }, [&#039;name&#039;,&#039;id&#039;,&#039;parent&#039;, &#039;x&#039;,&#039;y&#039;,&#039;canShuffle&#039;] );&lt;br /&gt;
  // Return : { name:&#039;Deck&#039;, id:1234, parent:4321, x: 20, y:50, canShuffle: true }&lt;br /&gt;
  &lt;br /&gt;
  // Note : as you can see, getElement returns:&lt;br /&gt;
  //        _ the element ID by default, or&lt;br /&gt;
  //        _ a single value if you request a single field, or&lt;br /&gt;
  //        _ an object if you request several fields&lt;br /&gt;
&lt;br /&gt;
  // Examples using different &amp;quot;selector&amp;quot; paramter&lt;br /&gt;
  &lt;br /&gt;
  // Retrieve an element name from its id&lt;br /&gt;
  var deck_name = bga.getElement( { id: 1234 }, [&#039;name&#039;] );&lt;br /&gt;
  // Return : &amp;quot;Deck&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  // Retrieve the last child element of another element&lt;br /&gt;
  // Here, we are requesting for elements who has element with ID=1234 (Deck) as their parent&lt;br /&gt;
  // Note the use of &amp;quot;limit:1&amp;quot; which allows us to retrieve only 1 element.&lt;br /&gt;
  var first_card_on_deck_id = bga.getElement( { parent: 1234, limit:1 } );&lt;br /&gt;
  //&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== bga.getElementById( id )===&lt;br /&gt;
&lt;br /&gt;
Get an object with all the properties of the element with specified ID.&lt;br /&gt;
&lt;br /&gt;
Throw an exception if the element does not exists.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===bga.getElementsByIds( ids )===&lt;br /&gt;
&lt;br /&gt;
Get all specified elements with an array of ids.&lt;br /&gt;
&lt;br /&gt;
Return an associative array (element_id =&amp;gt; element).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===bga.getElementsByParent( parent_id )===&lt;br /&gt;
&lt;br /&gt;
Get all children (ie : all elements contained) of the specified element_id.&lt;br /&gt;
&lt;br /&gt;
Ex : if you call getElementsByParent on a deck of cards, you&#039;ll get all cards.&lt;br /&gt;
&lt;br /&gt;
  // Example : Get all cards of a deck with name &amp;quot;mydeck&amp;quot;&lt;br /&gt;
  var cards = bga.getElementsByParent( bga.getElementByName( &#039;mydeck&#039; ) );&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===bga.getElementIdByName( name )===&lt;br /&gt;
&lt;br /&gt;
Get the ID of a Sandbox element from its name.&lt;br /&gt;
&lt;br /&gt;
Return null if there are no element with this name.&lt;br /&gt;
Throw an exception if there are more than 1 element with this name.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  var chess_square = bga.getElementIdByName( &#039;h3&#039; );&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===bga.getElementsIdsByName( name )===&lt;br /&gt;
&lt;br /&gt;
Get the IDs of all Sandbox elements with this name.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  var pawn_pieces_ids = bga.getElementsIdByName( &#039;pawn&#039; );&lt;br /&gt;
  &lt;br /&gt;
  // Result : [ 41, 42, 43, ... ]&lt;br /&gt;
&lt;br /&gt;
== Utility methods ==&lt;br /&gt;
&lt;br /&gt;
=== bga.isOn( element_id, parent_id ) ===&lt;br /&gt;
&lt;br /&gt;
Return true if &amp;quot;element_id&amp;quot; is a descendant of &amp;quot;parent_id&amp;quot; (ie : if element_id game element has been placed on parent_id game element).&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  if( bga.isOn( bga.getElementIfByName( &#039;Turn counter&#039; ), bga.getElementIfByName( &#039;Turn 6&#039; ) )&lt;br /&gt;
  {&lt;br /&gt;
     // Trigger game end&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
== Trigger most common game actions ==&lt;br /&gt;
&lt;br /&gt;
===moveElement( element_id, target_id )===&lt;br /&gt;
&lt;br /&gt;
Move element to specified target id.&lt;br /&gt;
&lt;br /&gt;
The exact destination of element depends on target &amp;quot;howToArrange&amp;quot; property (&amp;quot;How elements are arranged on it?&amp;quot; : spreaded/deck/...).&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.moveElement( bga.getElementIdByName( &#039;Turn counter&#039; ), bga.getElementIdByName( &#039;Turn 3&#039; ) );&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Other functions ==&lt;br /&gt;
&lt;br /&gt;
=== pause( milliseconds ) ===&lt;br /&gt;
&lt;br /&gt;
Pause the client interface during a specified number of milliseconds.&lt;br /&gt;
&lt;br /&gt;
If you do not use bga.pause, all Sandbox game actions are executed immediately and synchronously.&lt;br /&gt;
&lt;br /&gt;
  // Example :&lt;br /&gt;
  bga.log( &amp;quot;1&amp;quot; );    // Will be displayed immediately on the log&lt;br /&gt;
  bga.pause( 3000 ); // pause during 3 seconds&lt;br /&gt;
  bga.log( &amp;quot;2&amp;quot; );    // Will be displayed after the 3 second on the log&lt;br /&gt;
  bga.log( &amp;quot;3&amp;quot; );    // Will be displayed right after the previous one, without delay.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Tips : if you want to execute several consecutive &amp;quot;moveTo&amp;quot;, you should &amp;quot;bga.pause&amp;quot; between them, otherwise your element will move directly to the final destination.&lt;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://sr.doc.boardgamearena.com/index.php?title=Game_interface_logic:_yourgamename.js&amp;diff=2884</id>
		<title>Game interface logic: yourgamename.js</title>
		<link rel="alternate" type="text/html" href="https://sr.doc.boardgamearena.com/index.php?title=Game_interface_logic:_yourgamename.js&amp;diff=2884"/>
		<updated>2018-01-31T14:40:16Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Image loading */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This is the main file for your game interface. Here you will define:&lt;br /&gt;
&lt;br /&gt;
* which actions on the page will generate calls to the server&lt;br /&gt;
* what happens when you get a notification for change from the server and how it will show in the browser. &lt;br /&gt;
&lt;br /&gt;
== File structure ==&lt;br /&gt;
&lt;br /&gt;
The details on how the file is structured is described directly with comments on the code skeleton provided to you.&lt;br /&gt;
&lt;br /&gt;
Basically, here&#039;s this structure:&lt;br /&gt;
* constructor: here you can define variable global to your whole interface.&lt;br /&gt;
* setup: this method is called when the page is refreshed, in order you can setup the game interface.&lt;br /&gt;
* onEnteringState: the method is called when entering in a new game state. This way you can customize the view for this game state.&lt;br /&gt;
* onLeavingState: the method is called when leaving a game state.&lt;br /&gt;
* onUpdateActionButtons: called when entering in a new state, in order you can add action buttons in status bar.&lt;br /&gt;
* (utility methods): at this place you can define your utility methods&lt;br /&gt;
* (player&#039;s actions): at this place you can write your handlers for player&#039;s action on the interface (ex: click on an item).&lt;br /&gt;
* setupNotifications: in this method you associate notifications with notification handlers. This way, for each game notification, you trigger a javascript method to handle it and update the game interface.&lt;br /&gt;
* (notification handlers): at this place you can define your notifications handlers.&lt;br /&gt;
&lt;br /&gt;
== General tips ==&lt;br /&gt;
&lt;br /&gt;
; this.player_id&lt;br /&gt;
: Id of the player on whose browser the code is running.&lt;br /&gt;
&lt;br /&gt;
; this.isSpectator&lt;br /&gt;
: Flag set to true if the user at the table is a spectator (not a player).&lt;br /&gt;
: Note: this is not a function, its a variable.&lt;br /&gt;
: Note: if you want to hide some element for spectators, you&#039;d better use [[Game_interface_stylesheet:_yourgamename.css#spectatorMode|CSS &#039;spectatorMode&#039; class]].&lt;br /&gt;
&lt;br /&gt;
; this.gamedatas&lt;br /&gt;
: Contains your initial set of datas to init the game, created at game start or game refresh (F5)&lt;br /&gt;
: You can update it as needed to keep an up to date reference of the game on the client side if you need it (most of the time you don&#039;t).&lt;br /&gt;
&lt;br /&gt;
; this.isCurrentPlayerActive()&lt;br /&gt;
: Returns true if the player on whose browser the code is running is currently active (it&#039;s his turn to play)&lt;br /&gt;
&lt;br /&gt;
; this.getActivePlayerId()&lt;br /&gt;
: Return the ID of active player, or null if we are not in a &amp;quot;activeplayer&amp;quot; type state.&lt;br /&gt;
&lt;br /&gt;
; this.getActivePlayers()&lt;br /&gt;
: Return an array with the IDs of players that are currently active (or an empty array if there is not).&lt;br /&gt;
&lt;br /&gt;
== Dojo framework ==&lt;br /&gt;
&lt;br /&gt;
BGA is using the [http://dojotoolkit.org/ Dojo Javascript framework].&lt;br /&gt;
&lt;br /&gt;
The Dojo framework allows us to do complex things easier, and the BGA framework is using Dojo framework a lot.&lt;br /&gt;
&lt;br /&gt;
To realize game although, you only need to use a few part of the Dojo framework. All the Dojo methods you need to use are describe on this page.&lt;br /&gt;
&lt;br /&gt;
For performance reason, when deploying a game the js code is minified using Shrinksafe. Some advanced syntax may not be compatible with this process. In particular:&lt;br /&gt;
* you should not use reserved keywords from the javascript language as variables&lt;br /&gt;
* you should not declare default argument values in function declaration, the following syntax is invalid for Shriksafe: function myFunc(requiredArg, optionalArg = &#039;defaultValue&#039;) {}&lt;br /&gt;
&lt;br /&gt;
== Access and manipulate the DOM ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;$(&#039;some_html_element_id&#039;)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The $() function is used to get some HTML element using its &amp;quot;id&amp;quot; attribute.&lt;br /&gt;
&lt;br /&gt;
Example 1: modify the content of a &amp;quot;span&amp;quot; element:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
In your HTML code:&lt;br /&gt;
   &amp;lt;span id=&amp;quot;a_value_in_the_game_interface&amp;quot;&amp;gt;1234&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In your Javascript code:&lt;br /&gt;
   $(&#039;a_value_in_the_game_interface&#039;).innerHTML = &amp;quot;9999&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: $() is the standard method to access some HTML element with BGA Framework. You must not use &amp;quot;getElementById&amp;quot; function.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;dojo.style&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
With dojo.style you can modify a CSS property of any HTML element of your interface.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     // Make an element disappear&lt;br /&gt;
     dojo.style( &#039;my_element&#039;, &#039;display&#039;, &#039;none&#039; );&lt;br /&gt;
&lt;br /&gt;
     // Give an element a 2px border&lt;br /&gt;
     dojo.style( &#039;my_element&#039;, &#039;borderWidth&#039;, &#039;2px&#039; );&lt;br /&gt;
&lt;br /&gt;
     // Change the background position of an element&lt;br /&gt;
     // (very practical when you are using CSS sprite to transform an element to another)&lt;br /&gt;
     dojo.style( &#039;my_element&#039;, &#039;backgroundPosition&#039;, &#039;-20px -50px&#039; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: you must always use dojo.style to modify CSS properties of HTML elements.&lt;br /&gt;
&lt;br /&gt;
Note²: if you have to modify several CSS properties of an element, or if you have some complex CSS transformation to do, you should consider using dojo.addClass/dojo.removeClass (see below).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;dojo CSS classes manipulation&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In many situation, a bunch of many small CSS property update can be replaced by a CSS class change (ie: you add a CSS class to your element instead of applying all modification manually).&lt;br /&gt;
&lt;br /&gt;
Advantages are:&lt;br /&gt;
* All your CSS stuff remains in your CSS file.&lt;br /&gt;
* You can add/remove a list of CSS modifications with a simple function and whithout error.&lt;br /&gt;
* You can test if you applied the stuff to an element with &amp;quot;dojo.hasClass&amp;quot; method.&lt;br /&gt;
&lt;br /&gt;
Example from &amp;quot;Reversi&amp;quot;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    // We add &amp;quot;possibleMove&amp;quot; to an element&lt;br /&gt;
    dojo.addClass( &#039;square_&#039;+x+&#039;_&#039;+y, &#039;possibleMove&#039; );&lt;br /&gt;
&lt;br /&gt;
    // In our CSS file, the class is defined as:&lt;br /&gt;
    .possibleMove {&lt;br /&gt;
      background-color: white;&lt;br /&gt;
      opacity: 0.2;&lt;br /&gt;
      filter:alpha(opacity=20); /* For IE8 and earlier */  &lt;br /&gt;
      cursor: pointer;  &lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
     // So we&#039;ve applied 4 CSS property change in one line of code.&lt;br /&gt;
&lt;br /&gt;
     // ... and when we need to check if a square is a possible move on client side:&lt;br /&gt;
     if( dojo.hasClass( &#039;square_&#039;+x+&#039;_&#039;+y, &#039;possibleMove&#039; ) )&lt;br /&gt;
     { ... }&lt;br /&gt;
&lt;br /&gt;
     // ... and if we want to remove all possible moves in one line of code (see &amp;quot;dojo.query&amp;quot; method):&lt;br /&gt;
     dojo.query( &#039;.possibleMove&#039; ).removeClass( &#039;possibleMove&#039; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Conclusion: we encourage you to use dojo.addClass, dojo.removeClass and dojo.hasClass to make your life easier :)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;dojo.query&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
With dojo.query, you can query a bunch of HTML elements with a single function, with a &amp;quot;CSS selector&amp;quot; style.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     // All elements with class &amp;quot;possibleMove&amp;quot;:&lt;br /&gt;
     var elements = dojo.query( &#039;.possibleMove&#039; );&lt;br /&gt;
&lt;br /&gt;
     // Count number of tokens (ie: elements with class &amp;quot;token&amp;quot;) on the board (ie: element with id &amp;quot;board&amp;quot;):&lt;br /&gt;
     dojo.query( &#039;#board .token&#039; ).length;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
But what is really cool with dojo.query is that you can combine it with almost all methods above.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     // Trigger a method when the mouse enter in any element with class &amp;quot;meeple&amp;quot;:&lt;br /&gt;
     dojo.query( &#039;.meeple&#039; ).connect( &#039;onmouseenter&#039;, this, &#039;myMethodToTrigger&#039; );&lt;br /&gt;
&lt;br /&gt;
     // Hide all meeples who are on the board&lt;br /&gt;
     dojo.query( &#039;#board .meeple&#039; ).style( &#039;display&#039;, &#039;none&#039; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;dojo.place&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
dojo.place is the best function to insert some HTML code somewhere in your game interface without breaking something. It is much better to use that &amp;quot;innerHTML=&#039;&#039;&amp;quot; method as soon as you must insert HTML tags and not only values.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     // Insert your HTML code as a child of a container element&lt;br /&gt;
     dojo.place( &amp;quot;&amp;lt;your html code&amp;gt;&amp;quot;, &amp;quot;your_container_element_id&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
     // Replace the container element with your new html&lt;br /&gt;
     dojo.place( &amp;quot;&amp;lt;your html code&amp;gt;&amp;quot;, &amp;quot;your_container_element_id&amp;quot;, &amp;quot;replace&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The third parameter of dojo.place can take various interesting value.&lt;br /&gt;
&lt;br /&gt;
values possibles :&lt;br /&gt;
&lt;br /&gt;
&amp;quot;replace&amp;quot; : (see description above).&lt;br /&gt;
&lt;br /&gt;
&amp;quot;first&amp;quot; : Places the node as a child of the reference node. The node is placed as the first child.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;last&amp;quot; : Places the node as a child of the reference node. The node is placed as the last child.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;before&amp;quot; : places the node right before the reference node.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;last (value by default) &amp;quot; : places the node right after the reference node.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;only&amp;quot; : replaces all children of the reference node with the node.&lt;br /&gt;
&lt;br /&gt;
positif integer : This parameter can be a positif integer. In this case, the node will be placed as a child of the reference node with this number (counting from 0). If the number is more than number of children, the node will be appended to the reference node making it the last child. &lt;br /&gt;
&lt;br /&gt;
See also full doc on dojo.place : [http://dojotoolkit.org/reference-guide/1.7/dojo/place.]&lt;br /&gt;
&lt;br /&gt;
Usually, when you want to insert some piece of HTML in your game interface, you should use &amp;quot;[[Game_layout:_view_and_template:_yourgamename.view.php_and_yourgamename_yourgamename.tpl#Javascript_templates|Javascript templates]]&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;addStyleToClass: function( cssClassName, cssProperty, propertyValue )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Same as dojo.style(), but for all the nodes set with the specified cssClassName&lt;br /&gt;
&lt;br /&gt;
=== Animations ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Dojo Animations&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
BGA animations is based on Dojo Animation ([http://dojotoolkit.org/documentation/tutorials/1.8/animation/ see tutorial here]).&lt;br /&gt;
&lt;br /&gt;
However, most of the time, you can just use methods below, which are built on top of Dojo Animation.&lt;br /&gt;
&lt;br /&gt;
Note: one interesting method from Dojo that could be useful from time to time is &amp;quot;Dojo.Animation&amp;quot;. It allows you to make any CSS property &amp;quot;slide&amp;quot; from one value to another.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.slideToObject( mobile_obj, target_obj, duration, delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You can use slideToObject to &amp;quot;slide&amp;quot; an element to a target position.&lt;br /&gt;
&lt;br /&gt;
Sliding element on the game area is the recommended and the most used way to animate your game interface. Using slides allow players to figure out what is happening on the game, as if they were playing with the real boardgame.&lt;br /&gt;
&lt;br /&gt;
The parameters are:&lt;br /&gt;
* mobile_obj: the ID of the object to move. This object must be &amp;quot;relative&amp;quot; or &amp;quot;absolute&amp;quot; positioned.&lt;br /&gt;
* target_obj: the ID of the target object. This object must be &amp;quot;relative&amp;quot; or &amp;quot;absolute&amp;quot; positioned. Note that it is not mandatory that mobile_obj and target_obj have the same size. If their size are different, the system slides the center of mobile_obj to the center of target_obj.&lt;br /&gt;
* duration: (optional) defines the duration in millisecond of the slide. The default is 500 milliseconds.&lt;br /&gt;
* delay: (optional). If you defines a delay, the slide will start only after this delay. This is particularly useful when you want to slide several object from the same position to the same position: you can give a 0ms delay to the first object, a 100ms delay to the second one, a 200ms delay to the third one, ... this way they won&#039;t be superposed during the slide.&lt;br /&gt;
&lt;br /&gt;
BE CAREFUL: The method returns an dojo.fx animation, so you can combine it with other animation if you want to. It means that you have to call the &amp;quot;play()&amp;quot; method, otherwise the animation WON&#039;T START.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   this.slideToObject( &amp;quot;some_token&amp;quot;, &amp;quot;some_place_on_board&amp;quot; ).play();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.slideToObjectPos( mobile_obj, target_obj, target_x, target_y, duration, delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This method does exactly the same as &amp;quot;slideToObject&amp;quot;, except than you can specify some (x,y) coordinates. This way, &amp;quot;mobile_obj&amp;quot; will slide to the specified x,y position relatively to &amp;quot;target_obj&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Example: slide a token to some place on the board, 10 pixels to the bottom:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   this.slideToObjectPos( &amp;quot;some_token&amp;quot;, &amp;quot;some_place_on_board&amp;quot;, 0, 10 ).play();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.slideTemporaryObject( mobile_obj_html, mobile_obj_parent, from, to, duration, delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This method is useful when you want to slide a temporary HTML object from one place to another. As this object does not exists before the animation and won&#039;t remain after, it could be complex to create this object (with dojo.place), to place it at its origin (with placeOnObject) to slide it (with slideToObject) and to make it disappear at the end.&lt;br /&gt;
&lt;br /&gt;
slideTemporaryObject does all of this for you:&lt;br /&gt;
* mobile_obj_html is a piece of HTML code that represent the object to slide.&lt;br /&gt;
* mobile_obj_parent is the ID of an HTML element of your interface that will be the parent of this temporary HTML object.&lt;br /&gt;
* from is the ID of the origin of the slide.&lt;br /&gt;
* to is the ID of the target of the slide.&lt;br /&gt;
* duration/delay works exactly like in &amp;quot;slideToObject&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
this.slideTemporaryObject( &#039;&amp;lt;div class=&amp;quot;token_icon&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;, &#039;tokens&#039;, &#039;my_origin_div&#039;, &#039;my_target_div&#039; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.slideToObjectAndDestroy: function( node, to, time, delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This method is a handy shortcut to slide an existing HTML object to some place then destroy it upon arrival. It can be used for example to move a victory token or a card from the board to the player panel to show that the player earns it, then destroy it when we don&#039;t need to keep it visible on the player panel.&lt;br /&gt;
&lt;br /&gt;
It works the same as this.slideToObject and takes the same arguments. &lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
this.slideToObjectAndDestroy( &amp;quot;some_token&amp;quot;, &amp;quot;some_place_on_board&amp;quot;, 1000, 0 );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.fadeOutAndDestroy( node, duration, delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This function fade out the target HTML node, then destroy it.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   this.fadeOutAndDestroy( &amp;quot;a_card_that_must_disappear&amp;quot; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
CAREFUL: the HTML node still exists until during few milliseconds, until the fadeOut has been completed.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Rotating elements&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You can check here [http://jimfulton.info/demos/dojo-animated-rotate.html an example of use] of Dojo to make an element rotate.&lt;br /&gt;
&lt;br /&gt;
This example combines &amp;quot;Dojo.Animation&amp;quot; method and a CSS3 property that allow you to rotate the element.&lt;br /&gt;
&lt;br /&gt;
IMPORTANT: to asses browser compatibility, you must select the CSS property to use just like in the example (see sourcecode below):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        var transform;&lt;br /&gt;
        dojo.forEach(&lt;br /&gt;
            [&#039;transform&#039;, &#039;WebkitTransform&#039;, &#039;msTransform&#039;,&lt;br /&gt;
             &#039;MozTransform&#039;, &#039;OTransform&#039;],&lt;br /&gt;
            function (name) {&lt;br /&gt;
                if (typeof dojo.body().style[name] != &#039;undefined&#039;) {&lt;br /&gt;
                    transform = name;&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        // ... and then use &amp;quot;transform&amp;quot; as the name of your CSS property for rotation&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Moving elements ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.placeOnObject( mobile_obj, target_obj )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
placeOnObject works exactly like &amp;quot;slideToObject&amp;quot;, except that the effect is immediate.&lt;br /&gt;
&lt;br /&gt;
This is not really an animation, but placeOnObject is frequently used before starting an animation.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  // (We just created an object &amp;quot;my_new_token&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
  // Place the new token on current player board&lt;br /&gt;
  this.placeOnObject( &amp;quot;my_new_token&amp;quot;, &amp;quot;overall_player_board_&amp;quot;+this.player_id );&lt;br /&gt;
  &lt;br /&gt;
  // Then slide it to its position on the board&lt;br /&gt;
  this.slideToObject( &amp;quot;my_new_token&amp;quot;, &amp;quot;a_place_on_board&amp;quot; ).play();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.placeOnObjectPos( mobile_obj, target_obj, target_x, target_y )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This method works exactly like placeOnObject, except than you can specify some (x,y) coordinates. This way, &amp;quot;mobile_obj&amp;quot; will be placed to the specified x,y position relatively to &amp;quot;target_obj&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.attachToNewParent( mobile_obj, target_obj )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
With this method, you change the HTML parent of &amp;quot;mobile_obj&amp;quot; element. &amp;quot;target_obj&amp;quot; is the new parent of this element. The beauty of &lt;br /&gt;
attachToNewParent is that the mobile_obj element DOES NOT MOVE during this process.&lt;br /&gt;
&lt;br /&gt;
Note: what happens is that the method calculate a relative position of mobile_obj to make sure it does not move after the HTML parent changes.&lt;br /&gt;
&lt;br /&gt;
Why using this method?&lt;br /&gt;
&lt;br /&gt;
Changing the HTML parent of an element can be useful for the following reasons:&lt;br /&gt;
* When the HTML parent moves, all its child are moving with them. If some game elements is no more linked with a parent HTML object, you may want to attach it to another place.&lt;br /&gt;
* The z_order (vertical order of display) depends on the position in the DOM, so you may need to change the parent of some game elements when they are moving in your game area.&lt;br /&gt;
&lt;br /&gt;
CAREFUL: this function destroys original object and places a clone onto a new parent, this will break all references to this HTML element (ex: dojo.connect).&lt;br /&gt;
&lt;br /&gt;
== Players input ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;dojo.connect&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Used to associate a player event with one of your notification method.&lt;br /&gt;
&lt;br /&gt;
Example: associate a click on an element (&amp;quot;my_element&amp;quot;) with one of our method (&amp;quot;onClickOnMyElement&amp;quot;):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
      dojo.connect( $(&#039;my_element&#039;), &#039;onclick&#039;, this, &#039;onClickOnMyElement&#039; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: this is the only possible correct way to associate a player input event to your code, and you must not use anything else.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.checkAction( &amp;quot;my_action_name&amp;quot; )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Usage: checkAction: function( action, nomessage )&lt;br /&gt;
&lt;br /&gt;
Check if player can do the specified action by taking into account:&lt;br /&gt;
* current game state&lt;br /&gt;
* interface locking (a player can&#039;t do any action if an action is already in progress)&lt;br /&gt;
&lt;br /&gt;
return true if action is authorized (ie: the action is listed as a &amp;quot;possibleaction&amp;quot; in current game state).&lt;br /&gt;
&lt;br /&gt;
return false and display an error message if not (display no message if nomessage parameter is true). The displayed error message could be either &amp;quot;This move is not allowed at this moment&amp;quot; or &amp;quot;An action is already in progress&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  function onClickOnGameElement( evt )&lt;br /&gt;
  {&lt;br /&gt;
     if( this.checkAction( &amp;quot;my_action&amp;quot; ) )&lt;br /&gt;
     {&lt;br /&gt;
        // Do the action&lt;br /&gt;
     }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.ajaxcall( url, parameters, obj_callback, callback, callback_error )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This method must be used to send a player input to the game server.&lt;br /&gt;
&lt;br /&gt;
* url: the url of the action to perform. For a game, it must be: &amp;quot;/&amp;lt;mygame&amp;gt;/&amp;lt;mygame&amp;gt;/myAction.html&amp;quot;&lt;br /&gt;
* parameters: an array of parameter to send to the game server. Note that &amp;quot;lock:true&amp;quot; must always be specified in this list of parameter in order the interface can be locked during the server call.&lt;br /&gt;
* obj_callback: must be set to &amp;quot;this&amp;quot;.&lt;br /&gt;
* callback: a function to trigger when the server returns and everything went fine.&lt;br /&gt;
* callback_error: (optional and rarely used) a function to trigger when the server returns an error.&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
this.ajaxcall( &#039;/mygame/mygame/myaction.html&#039;, { lock: true, &lt;br /&gt;
   arg1: myarg1, &lt;br /&gt;
   arg2: myarg2, &lt;br /&gt;
   ...&lt;br /&gt;
}, this, function( result ) {&lt;br /&gt;
   // Do some stuff after a successful call&lt;br /&gt;
} );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Restricted arguments names (please don&#039;t use them):&lt;br /&gt;
* &amp;quot;action&amp;quot;&lt;br /&gt;
* &amp;quot;module&amp;quot;&lt;br /&gt;
* &amp;quot;class&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.confirmationDialog()&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Display a confirmation dialog with a yes/no choice.&lt;br /&gt;
&lt;br /&gt;
We advice you to NOT use this function unless the player action is really critical and could ruins the game, because it slows down the game and upset players.&lt;br /&gt;
&lt;br /&gt;
Usage: this.confirmationDialog( &amp;quot;Question to displayed&amp;quot;, callback_function_if_click_on_yes );&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
this.confirmationDialog( _(&#039;Are you sure to use this bonus (points penalty at the end of the game) ?&#039;),&lt;br /&gt;
                         dojo.hitch( this, function() {&lt;br /&gt;
                           this.ajaxcall( &#039;/seasons/seasons/useBonus.html&#039;,&lt;br /&gt;
                                { id:bonus_id, lock:true }, this, function( result ) {} );&lt;br /&gt;
                        } ) ); &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; addEventToClass: function( cssClassName, eventName, functionName )&lt;br /&gt;
: Same as dojo.connect(), but for all the nodes set with the specified cssClassName&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.addActionButton( id, label, method, (opt)destination, (opt)blinking, (opt)color )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You can use this method to add an action button in the main action status bar.&lt;br /&gt;
&lt;br /&gt;
Arguments:&lt;br /&gt;
* id: an element ID that should be unique in your HTML DOM document.&lt;br /&gt;
* label: the text of the button. Should be translatable (use _() function).&lt;br /&gt;
* method: the name of your method that must be triggered when the player clicks on this button.&lt;br /&gt;
* destination (optional): deprecated, do not use this. Use &#039;&#039;&#039;null&#039;&#039;&#039; as value if you need to specify other arguments.&lt;br /&gt;
* blinking (optional): if set to &#039;&#039;&#039;true&#039;&#039;&#039;, the button is going blink to catch player&#039;s attention. Please don&#039;t abuse of blinking button.&lt;br /&gt;
* color: could be &#039;&#039;&#039;blue&#039;&#039;&#039; (default), &#039;&#039;&#039;red&#039;&#039;&#039; or &#039;&#039;&#039;gray&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
You should only use this method in your &amp;quot;onUpdateActionButtons&amp;quot; method. Usually, you use it like this (from Hears example):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        onUpdateActionButtons: function( stateName, args ) {&lt;br /&gt;
                      &lt;br /&gt;
            if (this.isCurrentPlayerActive()) {            &lt;br /&gt;
                switch( stateName ) {&lt;br /&gt;
                case &#039;giveCards&#039;:&lt;br /&gt;
                    this.addActionButton( &#039;giveCards_button&#039;, _(&#039;Give selected cards&#039;), &#039;onGiveCards&#039; ); &lt;br /&gt;
                    break;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        },   &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the example above, we are adding a &amp;quot;Give selected cards&amp;quot; button in the case we are on game state &amp;quot;giveCards&amp;quot;. When player clicks on this button, it triggers our &amp;quot;onGiveCards&amp;quot; method.&lt;br /&gt;
&lt;br /&gt;
Example using blinking red button:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     this.addActionButton( &#039;commit_button&#039;, _(&#039;Confirm&#039;), &#039;onConfirm&#039;, null, true, &#039;red&#039;); &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: at least in studio example above will make button huge, because it sets it display of blinking things to &#039;&#039;&#039;block&#039;&#039;&#039;, &lt;br /&gt;
if you don&#039;t like it you have to change css display value&lt;br /&gt;
of the button to inline-block (the id of the button is the first argument, i.e &#039;commit_button&#039; in example above)&lt;br /&gt;
&lt;br /&gt;
== Translations ==&lt;br /&gt;
&lt;br /&gt;
See [[Translations]]&lt;br /&gt;
&lt;br /&gt;
== Notifications ==&lt;br /&gt;
&lt;br /&gt;
When something happens on the server side, your game interface Javascript logic received a notification.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s how you can handle these notifications on the client side.&lt;br /&gt;
&lt;br /&gt;
=== Subscribe to notifications ===&lt;br /&gt;
&lt;br /&gt;
Your Javascript &amp;quot;setupNotifications&amp;quot; method is the place where you can subscribe to notifications from your PHP code.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s how you associate one of your Javascript method to a notification &amp;quot;playDisc&amp;quot; (from Reversi example):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   // In setupNotifications method:&lt;br /&gt;
   dojo.subscribe( &#039;playDisc&#039;, this, &amp;quot;notif_playDisc&amp;quot; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: the &amp;quot;playDisc&amp;quot; corresponds to the name of the notification you define it in your PHP code, in your &amp;quot;notifyAllPlayers&amp;quot; or &amp;quot;notifyPlayer&amp;quot; method.&lt;br /&gt;
&lt;br /&gt;
Then, you have to define your &amp;quot;notif_playDisc&amp;quot; method:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        notif_playDisc: function( notif )&lt;br /&gt;
        {&lt;br /&gt;
            // Remove current possible moves (makes the board more clear)&lt;br /&gt;
            dojo.query( &#039;.possibleMove&#039; ).removeClass( &#039;possibleMove&#039; );        &lt;br /&gt;
        &lt;br /&gt;
            this.addDiscOnBoard( notif.args.x, notif.args.y, notif.args.player_id );&lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In a notification handler like our &amp;quot;notif_playDisc&amp;quot; method, you can access to all notifications arguments with &amp;quot;notif.args&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    // If you did this on PHP side:&lt;br /&gt;
    self::notifyAllPlayers( &amp;quot;myNotification&amp;quot;, &#039;&#039;, array( &amp;quot;myArgument&amp;quot; =&amp;gt; 3 ) );&lt;br /&gt;
&lt;br /&gt;
    // On Javascript side, you can access the &amp;quot;myArgument&amp;quot; like this:&lt;br /&gt;
    notif_myNotification: function( notif )&lt;br /&gt;
    {&lt;br /&gt;
       alert( &amp;quot;myArgument = &amp;quot; + notif.args.myArgument );&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Synchronous notifications ===&lt;br /&gt;
&lt;br /&gt;
When several notifications are received by your game interface, these notifications are processed immediately, one after the other, in the same exact order they have been generated in your PHP game logic.&lt;br /&gt;
&lt;br /&gt;
However, sometimes, you need to give some time to the players to figure out what happened on the game before jumping to the next notification. Indeed, in many games, they are a lot of automatic actions, and the computer is going to resolve all these actions very fast if you don&#039;t tell it not to do so.&lt;br /&gt;
&lt;br /&gt;
As an example, for Reversi, when someone is playing a disc, we want to wait 500 milliseconds before doing anything else in order the opponent player can figure out what move has been played.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s how we do this, right after our subscription:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
       dojo.subscribe( &#039;playDisc&#039;, this, &amp;quot;notif_playDisc&amp;quot; );&lt;br /&gt;
       this.notifqueue.setSynchronous( &#039;playDisc&#039;, 500 );   // Wait 500 milliseconds after executing the playDisc handler&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Pre-defined notification types ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;tableWindow&#039;&#039;&#039; - This defines notification to display [[Game_interface_logic:_yourgamename.js#Scoring_dialogs|Scoring Dialogs]], see below.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;message&#039;&#039;&#039; - This defines notification that shows on players log and have no other effect&lt;br /&gt;
&lt;br /&gt;
   // You can call this on php side without doing anything on client side&lt;br /&gt;
    self::notifyAllPlayers( &#039;message&#039;, &#039;hello&#039;, array( ) );&lt;br /&gt;
&lt;br /&gt;
== Tooltips ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.addTooltip( nodeId, _( helpString ), _( actionString ), delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Add a simple text tooltip to the DOM node.&lt;br /&gt;
&lt;br /&gt;
Specify &#039;helpString&#039; to display some information about &amp;quot;what is this game element?&amp;quot;.&lt;br /&gt;
Specify &#039;actionString&#039; to display some information about &amp;quot;what happens when I click on this element?&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
You must specify both helpString and actionString. Most of the time, you use only one and specify a void string (&amp;quot;&amp;quot;) for the other one.&lt;br /&gt;
&lt;br /&gt;
Usually, _() must be used for the text to be marked for translation.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Delay&amp;quot; is an optional parameter. Usually, it is primarily used to specify a zero delay for some game element when the tooltip gives really important information for the game - but remember: no essential information must be placed in tooltips as they won&#039;t be displayed in some browser (see Guidelines).&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   this.addTooltip( &#039;cardcount&#039;, _(&#039;Number of cards in hand&#039;), &#039;&#039; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.addTooltipHtml( nodeId, html, delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Add an HTML tooltip to the DOM node (for more elaborate content such as presenting a bigger version of a card).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.addTooltipToClass( cssClass, _( helpString ), _( actionString ), delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Add a simple text tooltip to all the DOM nodes set with this cssClass. &lt;br /&gt;
&lt;br /&gt;
IMPORTANT: all concerned nodes must have IDs to get tooltips.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.addTooltipHtmlToClass( cssClass, html, delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Add an HTML tooltip to to all the DOM nodes set with this cssClass (for more elaborate content such as presenting a bigger version of a card).&lt;br /&gt;
&lt;br /&gt;
IMPORTANT: all concerned nodes must have IDs to get tooltips&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.removeTooltip( nodeId )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Remove a tooltip from the DOM node.&lt;br /&gt;
&lt;br /&gt;
== Dialogs, warning messages, confirmation dialogs, ... ==&lt;br /&gt;
&lt;br /&gt;
=== Warning messages ===&lt;br /&gt;
&lt;br /&gt;
Sometimes, there is something important that is happening on the game and you have to make sure all players get the message. Most of the time, the evolution of the game situation or the game log is enough, but sometimes you need something more visible.&lt;br /&gt;
&lt;br /&gt;
Ex: someone fulfill one of the end of the game condition, so this is the last turn.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.showMessage( msg, type )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
showMessage shows a message in a big rectangular area on the top of the screen of current player.&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;msg&amp;quot; is the string to display. It should be translated.&lt;br /&gt;
* &amp;quot;type&amp;quot; can be set to &amp;quot;info&amp;quot; or &amp;quot;error&amp;quot;. If set to &amp;quot;info&amp;quot;, the message will be an informative message on a white background. If set to &amp;quot;error&amp;quot;, the message will be an error message on a red background.&lt;br /&gt;
&lt;br /&gt;
Important: the normal way to inform players about the progression of the game is the game log. &amp;quot;showMessage&amp;quot; is intrusive and should not be used often.&lt;br /&gt;
&lt;br /&gt;
=== Confirmation dialog ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;confirmationDialog( message, yesHandler, noHandler )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When an important action with a lot of consequences is triggered by the player, you may want to propose a confirmation dialog.&lt;br /&gt;
&lt;br /&gt;
CAREFUL: the general guidelines of BGA is to AVOID the use of confirmation dialog. Confirmation dialogs slow down the game and bother players. The players knows that they have to pay attention about each move when they are playing online.&lt;br /&gt;
&lt;br /&gt;
The situation where you should use a confirmation dialog are the following:&lt;br /&gt;
* It must not happen very often during a game.&lt;br /&gt;
* It must be linked to an action that can really &amp;quot;kill a game&amp;quot; if the player do not pay attention.&lt;br /&gt;
* It must be something that can be done by mistake (ex: a link on the action status bar).&lt;br /&gt;
&lt;br /&gt;
How to display a confirmation dialog:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        this.confirmationDialog( _(&#039;Are you sure you want to bake the pie?&#039;), dojo.hitch( this, function() {&lt;br /&gt;
            this.bakeThePie();&lt;br /&gt;
        } ) ); &lt;br /&gt;
        return; // nothing should be called or done after calling this, all action must be done in the handler  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Multiple choice dialog ===&lt;br /&gt;
You can use this dialog to give user a choice with small amount of options:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        var keys = [1,5,10];&lt;br /&gt;
        this.multipleChoiceDialog(&lt;br /&gt;
          _(&#039;How many bugs to fix?&amp;quot;), keys, &lt;br /&gt;
            dojo.hitch(this, function(choice) {&lt;br /&gt;
                            var bugchoice = keys[choice];&lt;br /&gt;
                            console.log(&#039;dialog callback with &#039;+bugchoice);&lt;br /&gt;
                            this.ajaxcall( &#039;/mygame/mygame/fixBugs.html&#039;, { bugs: bugchoice}, this, function( result ) {} );                        }));&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Dialogs ===&lt;br /&gt;
&lt;br /&gt;
At first, you shouldn&#039;t use dialogs windows.&lt;br /&gt;
&lt;br /&gt;
BGA guidelines specify that all game elements should be displayed on the main screen. Players can eventually scroll down to see game elements they don&#039;t need to see anytime, and you may eventually create anchors to move between game area section. Of course dialogs windows are very practical, but the thing is: all players know how to scroll down, and not all players know how to show up your dialog window. In addition, when the dialog shows up, players can&#039;t access the other game components.&lt;br /&gt;
&lt;br /&gt;
Sometimes although, you need to display a dialog window. Here is how you do this:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  // Create the new dialog. You should store the handler in a member variable to access it later&lt;br /&gt;
  this.myDlg = new dijit.Dialog({ title: _(&amp;quot;my dialog title to translate&amp;quot;) });&lt;br /&gt;
  &lt;br /&gt;
  // Create the HTML of my dialog. &lt;br /&gt;
  // The best practice here is to use [[Game_layout:_view_and_template:_yourgamename.view.php_and_yourgamename_yourgamename.tpl#Javascript_templates|Javascript templates]]&lt;br /&gt;
  var html = this.format_block( &#039;jstpl_myDialogTemplate&#039;, { &lt;br /&gt;
                arg1: myArg1,&lt;br /&gt;
                arg2: myArg2,&lt;br /&gt;
                ...&lt;br /&gt;
            } );  &lt;br /&gt;
  &lt;br /&gt;
  // Show the dialog&lt;br /&gt;
  this.myDlg.attr(&amp;quot;content&amp;quot;, html );&lt;br /&gt;
  this.myDlg.show(); &lt;br /&gt;
  &lt;br /&gt;
  // Now that the dialog has been displayed, you can connect your method to some dialog elements&lt;br /&gt;
  // Example, a &amp;quot;close&amp;quot; button:&lt;br /&gt;
  dojo.connect( $(&#039;closeDlg&#039;), &#039;onclick&#039;, this, function(evt){&lt;br /&gt;
                evt.preventDefault();&lt;br /&gt;
                this.myDlg.hide();&lt;br /&gt;
            } );  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Tip: be careful with &amp;quot;hide()&amp;quot; method to close your dialog: the dialog and its content is not completely removed from the DOM. It can cause you problems if you try to display the same dialog several times. A good practice is to wrap all the content of your dialog in a &amp;lt;nowiki&amp;gt;&amp;lt;div id=&#039;myDlgContent&#039;&amp;gt;&amp;lt;/nowiki&amp;gt; div element, and to call &amp;quot;dojo.destroy(&#039;myDlgContent&#039;)&amp;quot; before displaying your dialog.&lt;br /&gt;
&lt;br /&gt;
=== Scoring dialogs ===&lt;br /&gt;
&lt;br /&gt;
Sometimes at the end of a round you want to display a big table that details the points wins in each section of the game.&lt;br /&gt;
&lt;br /&gt;
Example: in Hearts game, we display at the end of each round the number of &amp;quot;heart&amp;quot; cards collected by each player, the player who collected the Queen of Spades, and the total number of points loose by each player.&lt;br /&gt;
&lt;br /&gt;
Scoring dialogs are managed entirely on &#039;&#039;&#039;PHP side&#039;&#039;&#039;, but they are described here as their effects are visible only on client side.&lt;br /&gt;
&lt;br /&gt;
Displaying a scoring dialog is quite simple and is using a special notification type: &amp;quot;tableWindow&amp;quot;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  // on PHP side:&lt;br /&gt;
  $this-&amp;gt;notifyAllPlayers( &amp;quot;tableWindow&amp;quot;, &#039;&#039;, array(&lt;br /&gt;
            &amp;quot;id&amp;quot; =&amp;gt; &#039;finalScoring&#039;,&lt;br /&gt;
            &amp;quot;title&amp;quot; =&amp;gt; clienttranslate(&amp;quot;Title of the scoring dialog&amp;quot;),&lt;br /&gt;
            &amp;quot;table&amp;quot; =&amp;gt; $table&lt;br /&gt;
        ) ); &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;table&amp;quot; argument is a 2 dimensional PHP array that describe the table you want to display, line by line and column by column.&lt;br /&gt;
&lt;br /&gt;
Example: display an 3x3 array of strings&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   $table = array(&lt;br /&gt;
      array( &amp;quot;one&amp;quot;, &amp;quot;two&amp;quot;, &amp;quot;three&amp;quot; ),    // This is my first line&lt;br /&gt;
      array( &amp;quot;four&amp;quot;, &amp;quot;five&amp;quot;, &amp;quot;six&amp;quot; ),    // This is my second line&lt;br /&gt;
      array( &amp;quot;seven&amp;quot;, &amp;quot;height&amp;quot;, &amp;quot;nine&amp;quot; )    // This is my third line&lt;br /&gt;
   );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As you can see above, in each &amp;quot;cell&amp;quot; of your array you can display a simple string value. But you can also display a complex value with a template and associated arguments like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   $table = array(&lt;br /&gt;
      array( &amp;quot;one&amp;quot;, &amp;quot;two&amp;quot;, array( &amp;quot;str&amp;quot; =&amp;gt; &amp;quot;a string with an ${argument}&amp;quot;, &amp;quot;args&amp;quot; =&amp;gt; array( &#039;argument&#039; =&amp;gt; &#039;argument_value&#039; )  ) ),&lt;br /&gt;
      array( &amp;quot;four&amp;quot;, &amp;quot;five&amp;quot;, &amp;quot;six&amp;quot; ), &lt;br /&gt;
      array( &amp;quot;seven&amp;quot;, &amp;quot;height&amp;quot;, &amp;quot;nine&amp;quot; )&lt;br /&gt;
   );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is especially useful when you want to display player names with colors. Example from &amp;quot;Hearts&amp;quot;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        $firstRow = array( &#039;&#039; );&lt;br /&gt;
        foreach( $players as $player_id =&amp;gt; $player )&lt;br /&gt;
        {&lt;br /&gt;
            $firstRow[] = array( &#039;str&#039; =&amp;gt; &#039;${player_name}&#039;,&lt;br /&gt;
                                 &#039;args&#039; =&amp;gt; array( &#039;player_name&#039; =&amp;gt; $player[&#039;player_name&#039;] ),&lt;br /&gt;
                                 &#039;type&#039; =&amp;gt; &#039;header&#039;&lt;br /&gt;
                               );&lt;br /&gt;
        }&lt;br /&gt;
        $table[] = $firstRow;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also use three extra attributes in the parameter array for the notification:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   $this-&amp;gt;notifyAllPlayers( &amp;quot;tableWindow&amp;quot;, &#039;&#039;, array(&lt;br /&gt;
            &amp;quot;id&amp;quot; =&amp;gt; &#039;finalScoring&#039;,&lt;br /&gt;
            &amp;quot;title&amp;quot; =&amp;gt; clienttranslate(&amp;quot;Title of the scoring dialog&amp;quot;),&lt;br /&gt;
            &amp;quot;table&amp;quot; =&amp;gt; $table,&lt;br /&gt;
            &amp;quot;header&amp;quot; =&amp;gt; array(&#039;str&#039; =&amp;gt; clienttranslate(&#039;Table header with parameter ${number}&#039;),&lt;br /&gt;
                                 &#039;args&#039; =&amp;gt; array( &#039;number&#039; =&amp;gt; 3 ),&lt;br /&gt;
                               ),&lt;br /&gt;
            &amp;quot;footer&amp;quot; =&amp;gt; &#039;&amp;lt;div&amp;gt;Some footer&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
            &amp;quot;closing&amp;quot; =&amp;gt; clienttranslate( &amp;quot;Closing button label&amp;quot; )&lt;br /&gt;
        ) ); &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;header&#039;&#039;&#039;: the content for this parameter will display before the table (also, the html will be parsed and player names will be colored according to the current game colors). &lt;br /&gt;
*&#039;&#039;&#039;footer&#039;&#039;&#039;: the content for this parameter will display after the table (no parsing for coloring the player names)&lt;br /&gt;
*&#039;&#039;&#039;closing&#039;&#039;&#039;: if this parameter is used, a button will be displayed with this label at the bottom of the popup and will allow players to close it (more easily than by clicking the top right &#039;cross&#039; icon).&lt;br /&gt;
&lt;br /&gt;
== Update players score ==&lt;br /&gt;
&lt;br /&gt;
Increase a player score (with a positive or negative number):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  this.scoreCtrl[ player_id ].incValue( score_delta );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Set a player score to a specific value:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  this.scoreCtrl[ player_id ].setValue( new_score );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Players panels ==&lt;br /&gt;
&lt;br /&gt;
=== Adding stuff to player&#039;s panel ===&lt;br /&gt;
&lt;br /&gt;
At first, create a new &amp;quot;JS template&amp;quot; string in your template (tpl) file:&lt;br /&gt;
&lt;br /&gt;
(from Gomoku example)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
var jstpl_player_board = &#039;\&amp;lt;div class=&amp;quot;cp_board&amp;quot;&amp;gt;\&lt;br /&gt;
    &amp;lt;div id=&amp;quot;stoneicon_p${id}&amp;quot; class=&amp;quot;gmk_stoneicon gmk_stoneicon_${color}&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;span id=&amp;quot;stonecount_p${id}&amp;quot;&amp;gt;0&amp;lt;/span&amp;gt;\&lt;br /&gt;
&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then, you add this piece of code in your JS file to add this template to each player panel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
            // Setting up player boards&lt;br /&gt;
            for( var player_id in gamedatas.players )&lt;br /&gt;
            {&lt;br /&gt;
                var player = gamedatas.players[player_id];&lt;br /&gt;
                         &lt;br /&gt;
                // Setting up players boards if needed&lt;br /&gt;
                var player_board_div = $(&#039;player_board_&#039;+player_id);&lt;br /&gt;
                dojo.place( this.format_block(&#039;jstpl_player_board&#039;, player ), player_board_div );&lt;br /&gt;
            }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Note: the code above is of course from your &amp;quot;setup&amp;quot; function in your Javascript).&lt;br /&gt;
&lt;br /&gt;
Very often, you have to distinguish current player and others players. In this case, you just have to create another JS template (ex: jstpl_otherplayer_board) and use it when &amp;quot;player_id&amp;quot; is different than &amp;quot;this.player_id&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Player&#039;s panel disabling/enabling ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.disablePlayerPanel( player_id )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Disable given player panel (the panel background become gray).&lt;br /&gt;
&lt;br /&gt;
Usually, this is used to signal that this played passes, or will be inactive during a while.&lt;br /&gt;
&lt;br /&gt;
Note that the only effect of this is visual. There are no consequences on the behaviour of the panel itself.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.enablePlayerPanel( player_id )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Enable a player panel that has been disabled before.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.enableAllPlayerPanels()&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Enable all player panels that has been disabled before.&lt;br /&gt;
&lt;br /&gt;
== Image loading ==&lt;br /&gt;
&lt;br /&gt;
See also [[Game_art:_img_directory]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Be careful&#039;&#039;&#039;: by default, ALL images of your img directory are loaded on a player&#039;s browser when he loads the game. For this reason, don&#039;t let in your img directory images that are not useful, otherwise it&#039;s going to slowdown the game load.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;dontPreloadImage( image_file_name )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Using dontPreloadImage, you tell the interface to not preload a specific image in your img directory.&lt;br /&gt;
&lt;br /&gt;
Example of use:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
this.dontPreloadImage( &#039;cards.png&#039; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is particularly useful if for example you have 2 different themes for a game. To accelerate the loading of the game, you can specify to not preload images corresponding to the other theme.&lt;br /&gt;
&lt;br /&gt;
Another example of use: in &amp;quot;Gosu&amp;quot; game with Kamakor extension, you play with 5 sets of cards among 10 available. Cards images are organized by sets, and we only preload the images corresponding to the 5 current sets with &#039;&#039;&#039;ensureSpecificGameImageLoading( image_file_names_array )&#039;&#039;&#039;.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// By default, do not preload anything&lt;br /&gt;
this.dontPreloadImage( &#039;cards.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan1.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan2.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan3.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan4.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan5.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan6.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan7.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan8.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan9.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan10.png&#039; );&lt;br /&gt;
var to_preload = [];&lt;br /&gt;
for( i in this.gamedatas.clans )&lt;br /&gt;
{&lt;br /&gt;
	var clan_id = this.gamedatas.clans[i];&lt;br /&gt;
	to_preload.push( &#039;clan&#039;+clan_id+&#039;.png&#039; );&lt;br /&gt;
}&lt;br /&gt;
if( to_preload.length == 5 )&lt;br /&gt;
{&lt;br /&gt;
	this.ensureSpecificGameImageLoading( to_preload );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; You don&#039;t need to specify to not preload game box images (game_box.png, game_box75.png...) since they are not preloaded by default.&lt;br /&gt;
&lt;br /&gt;
== Other useful stuff ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;dojo.hitch&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
With dojo.hitch, you can create a callback function that will run with your game object context whatever happen.&lt;br /&gt;
&lt;br /&gt;
Typical example: display a BGA confirmation dialog with a callback function created with dojo.hitch:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        this.confirmationDialog( _(&#039;Are you sure you want to make this?&#039;), dojo.hitch( this, function() {&lt;br /&gt;
            this.ajaxcall( &#039;/mygame/mygame/makeThis.html&#039;, { lock:true }, this, function( result ) {} );&lt;br /&gt;
        } ) );   &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the example above, using dojo.hitch, we are sure that the &amp;quot;this&amp;quot; object will be set when the callback is called.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; updateCounters(counters)&lt;br /&gt;
: Useful for updating game counters in the player panel (such as resources). &lt;br /&gt;
: &#039;counters&#039; arg is an associative array [counter_name_value =&amp;gt; [ &#039;counter_name&#039; =&amp;gt; counter_name_value, &#039;counter_value&#039; =&amp;gt; counter_value_value], ... ]&lt;br /&gt;
: All counters must be referenced in this.gamedatas.counters and will be updated.&lt;br /&gt;
: DOM objects referenced by &#039;counter_name&#039; will have their innerHTML updated with &#039;counter_value&#039;.&lt;br /&gt;
&lt;br /&gt;
== BGA GUI components ==&lt;br /&gt;
&lt;br /&gt;
BGA framework provides some useful ready-to-use components for the game interface:&lt;br /&gt;
&lt;br /&gt;
[[Studio#BGA_Studio_game_components_reference]]&lt;br /&gt;
&lt;br /&gt;
Note that each time you are using an additional component, you must declare it at the top of your Javascript file in the list of modules used.&lt;br /&gt;
&lt;br /&gt;
Example if you are using &amp;quot;ebg.stock&amp;quot;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
define([&lt;br /&gt;
    &amp;quot;dojo&amp;quot;,&amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
    &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
    &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
    &amp;quot;ebg/stock&amp;quot;  /// &amp;lt;=== we are using ebg.stock module&lt;br /&gt;
],&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://sr.doc.boardgamearena.com/index.php?title=Game_layout:_view_and_template:_yourgamename.view.php_and_yourgamename_yourgamename.tpl&amp;diff=2851</id>
		<title>Game layout: view and template: yourgamename.view.php and yourgamename yourgamename.tpl</title>
		<link rel="alternate" type="text/html" href="https://sr.doc.boardgamearena.com/index.php?title=Game_layout:_view_and_template:_yourgamename.view.php_and_yourgamename_yourgamename.tpl&amp;diff=2851"/>
		<updated>2018-01-14T09:29:07Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Javascript templates */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;These 2 files work together to provide the HTML layout of your game.&lt;br /&gt;
&lt;br /&gt;
Using these 2 files, you specify what HTML is rendered in your game client interface.&lt;br /&gt;
&lt;br /&gt;
In &amp;lt;yourgame.tpl&amp;gt;, you can directly write raw HTML that will be displayed by the browser.&lt;br /&gt;
&lt;br /&gt;
Example: extract of &amp;quot;hearts_hearts.tpl&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;myhand_wrap&amp;quot; class=&amp;quot;whiteblock&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;h3&amp;gt;{MY_HAND}&amp;lt;/h3&amp;gt;&lt;br /&gt;
    &amp;lt;div id=&amp;quot;myhand&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== WARNING ==&lt;br /&gt;
&lt;br /&gt;
Your view and your template are supposed to generate only the BASE layout of the game&lt;br /&gt;
&lt;br /&gt;
You shouldn&#039;t try to setup the current game situation in the view: this is the role of your Javascript code. Why? Because you&#039;ll have to write Javascript code to put game elements in place anyway, and you don&#039;t want to write it twice :)&lt;br /&gt;
&lt;br /&gt;
Example of things to generate in your view:&lt;br /&gt;
* The overall layout of your game interface (what is displayed where).&lt;br /&gt;
* The board and fixed elements on the board (ex: places for cards, squares, ...).&lt;br /&gt;
&lt;br /&gt;
Example of things that shouldn&#039;t be generate by your view:&lt;br /&gt;
* Game elements that come and go from the game area.&lt;br /&gt;
* Game elements that normally hidden from players (other players cards, cards in the deck).&lt;br /&gt;
&lt;br /&gt;
== phplib template system ==&lt;br /&gt;
&lt;br /&gt;
BGA is using the phplib template system, used for example in PHPbb forums.&lt;br /&gt;
&lt;br /&gt;
More details about how to use phplib template system here:&lt;br /&gt;
http://www.phpbuilder.com/columns/david20000512.php3&lt;br /&gt;
&lt;br /&gt;
== Variables ==&lt;br /&gt;
&lt;br /&gt;
In your template (&amp;quot;tpl&amp;quot;) file, you can use variables. Then in your view (&amp;quot;.view.php&amp;quot;) file, you fill these variables with value.&lt;br /&gt;
&lt;br /&gt;
In the example above, &amp;quot;{MY_HAND}&amp;quot; is a variable. As you can see, a variable is uppercase characters border by &amp;quot;{&amp;quot; and &amp;quot;}&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
To give a value to this variable in your view.php:&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   // Display a translated version of &amp;quot;My hand&amp;quot; at the place of the variable in the template&lt;br /&gt;
   $this-&amp;gt;tpl[&#039;MY_HAND&#039;] = self::_(&amp;quot;My hand&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
   // Display some raw HTML material at the place of the variable&lt;br /&gt;
   $this-&amp;gt;tpl[&#039;MY_HAND&#039;] = self::raw( &amp;quot;&amp;lt;div class=&#039;myhand_icon&#039;&amp;gt;&amp;lt;/div&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
WARNING: do not use a variable called {id} as it will interfere with action buttons.&lt;br /&gt;
&lt;br /&gt;
== Blocks ==&lt;br /&gt;
&lt;br /&gt;
Using &amp;quot;blocks&amp;quot;, you can repeat a piece of HTML from your template several time.&lt;br /&gt;
&lt;br /&gt;
You should use &amp;quot;blocks&amp;quot; everytime you have a block of HTML that you have to repeat a big number of time. For example, for Reversi, we have to generate 64 (8x8) squares:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(in reversi_reversi.tpl)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;board&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;!-- BEGIN square --&amp;gt;&lt;br /&gt;
        &amp;lt;div id=&amp;quot;square_{X}_{Y}&amp;quot; class=&amp;quot;square&amp;quot; style=&amp;quot;left: {LEFT}px; top: {TOP}px;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;!-- END square --&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
    &amp;lt;div id=&amp;quot;discs&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(in reversi.view.php)&lt;br /&gt;
&lt;br /&gt;
 $this-&amp;gt;page-&amp;gt;begin_block( &amp;quot;reversi_reversi&amp;quot;, &amp;quot;square&amp;quot; );&lt;br /&gt;
        &lt;br /&gt;
 $hor_scale = 64.8;&lt;br /&gt;
 $ver_scale = 64.4;&lt;br /&gt;
 for( $x=1; $x&amp;lt;=8; $x++ )&lt;br /&gt;
 {&lt;br /&gt;
    for( $y=1; $y&amp;lt;=8; $y++ )&lt;br /&gt;
    {&lt;br /&gt;
       $this-&amp;gt;page-&amp;gt;insert_block( &amp;quot;square&amp;quot;, array(&lt;br /&gt;
         &#039;X&#039; =&amp;gt; $x,&lt;br /&gt;
         &#039;Y&#039; =&amp;gt; $y,&lt;br /&gt;
         &#039;LEFT&#039; =&amp;gt; round( ($x-1)*$hor_scale+10 ),&lt;br /&gt;
         &#039;TOP&#039; =&amp;gt; round( ($y-1)*$ver_scale+7 )&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;
Explanations:&lt;br /&gt;
* You specify a block in your template file, using &amp;quot;BEGIN&amp;quot; and &amp;quot;END&amp;quot; keywords. In the example above, we are creating a block named &amp;quot;square&amp;quot;.&lt;br /&gt;
* In your view, you declare your block using &amp;quot;begin_block&amp;quot; method.&lt;br /&gt;
* Then, you can insert as many block as you want to, using &amp;quot;insert_block&amp;quot; method.&lt;br /&gt;
&lt;br /&gt;
The insert_block method takes 2 parameters:&lt;br /&gt;
* the name of the block to insert.&lt;br /&gt;
* an associative array you can use to assign values to template variables of this block. In the example above, there are 4 parameters in the block (X, Y, LEFT and TOP).&lt;br /&gt;
&lt;br /&gt;
== Nested blocks ==&lt;br /&gt;
&lt;br /&gt;
You can use nested blocks. In the example below, we are going to add a mini-board for each player of the game, with 4 card places on each of it:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(In template file)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- BEGIN player --&amp;gt;&lt;br /&gt;
    &amp;lt;div class=&amp;quot;miniboard&amp;quot; id=&amp;quot;miniboard_{PLAYER_ID}&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
        &amp;lt;div class=&amp;quot;card_places&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;!-- BEGIN card_place --&amp;gt;&lt;br /&gt;
            &amp;lt;div id=&amp;quot;card_place_{PLAYER_ID}_{PLACE_ID}&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;!-- END card_place --&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;!-- END player --&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
(In view file)&lt;br /&gt;
&lt;br /&gt;
$this-&amp;gt;page-&amp;gt;begin_block( &amp;quot;mygame_mygame.tpl&amp;quot;, &amp;quot;card_place&amp;quot; ); // Nested block must be declared first&lt;br /&gt;
$this-&amp;gt;page-&amp;gt;begin_block( &amp;quot;mygame_mygame.tpl&amp;quot;, &amp;quot;player&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
foreach( $players as $player_id =&amp;gt; $player )&lt;br /&gt;
{&lt;br /&gt;
    // Important: nested block must be reset here, otherwise the second player miniboard will&lt;br /&gt;
    //  have 8 card_place, the third will have 12 card_place, and so one...&lt;br /&gt;
    $this-&amp;gt;page-&amp;gt;reset_subblocks( &#039;card_place&#039; ); &lt;br /&gt;
&lt;br /&gt;
    for( $i=1; $i&amp;lt;=4; $i++ )&lt;br /&gt;
    {&lt;br /&gt;
       $this-&amp;gt;page-&amp;gt;insert_block( &amp;quot;card_place&amp;quot;, array( &lt;br /&gt;
             &#039;PLAYER_ID&#039; =&amp;gt; $player_id,&lt;br /&gt;
             &#039;PLACE_ID&#039; =&amp;gt; $i&lt;br /&gt;
       );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    $this-&amp;gt;page-&amp;gt;insert_block( &#039;player&#039;, array( &#039;PLAYER_ID&#039; =&amp;gt; $player_id );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Javascript templates ==&lt;br /&gt;
&lt;br /&gt;
For game elements that come and go from the game area, we suggest you to define a Javascript template.&lt;br /&gt;
&lt;br /&gt;
A Javascript template is defined in your template file like this:&lt;br /&gt;
&lt;br /&gt;
(Reversi Token from Reversi example):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Templates&lt;br /&gt;
&lt;br /&gt;
var jstpl_disc=&#039;&amp;lt;div class=&amp;quot;disc disccolor_${color}&amp;quot; id=&amp;quot;disc_${xy}&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: a section for javascript templates is already available at the end of your template skeleton file.&lt;br /&gt;
&lt;br /&gt;
Then, you can use this javascript template to insert this piece of HTML in your game interface, like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    dojo.place( this.format_block( &#039;jstpl_disc&#039;, {&lt;br /&gt;
           xy: x+&#039;&#039;+y,&lt;br /&gt;
           color: color&lt;br /&gt;
    } ) , &#039;discs&#039; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
WARNING: always use lowercase for substitution variables in your Javascript templates, in order to avoid collision with phplib template variables (in particular, do not use ${ID}).&lt;br /&gt;
&lt;br /&gt;
== How to access game information from .view.php? ==&lt;br /&gt;
&lt;br /&gt;
From your .view.php, you can access the following:&lt;br /&gt;
&lt;br /&gt;
=== Access current player id===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  global $g_user;&lt;br /&gt;
  $current_player_id = $g_user-&amp;gt;get_id();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Access game object ===&lt;br /&gt;
&lt;br /&gt;
In your view file, &amp;quot;$this-&amp;gt;game&amp;quot; contains an instance of your main game class.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   // Access to some game elements description described in your &amp;quot;material.inc.php&amp;quot;:&lt;br /&gt;
   $my_cards_types = $this-&amp;gt;game-&amp;gt;card_types;&lt;br /&gt;
&lt;br /&gt;
   // Access to any (public) method defined in my .game.php file:&lt;br /&gt;
   $result = $this-&amp;gt;game-&amp;gt;myMethod();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tips: displaying a nice button ==&lt;br /&gt;
&lt;br /&gt;
From time to time, you need to display a standard button in your interface. BGA framework provides you a standard button that you can use directly in your interface:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    &amp;lt;a href=&amp;quot;#&amp;quot; id=&amp;quot;my_button_id&amp;quot; class=&amp;quot;bgabutton bgabutton_blue&amp;quot;&amp;gt;&amp;lt;span&amp;gt;My blue button&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    &amp;lt;a href=&amp;quot;#&amp;quot; id=&amp;quot;my_button_id&amp;quot; class=&amp;quot;bgabutton bgabutton_gray&amp;quot;&amp;gt;&amp;lt;span&amp;gt;My gray button&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    &amp;lt;a href=&amp;quot;#&amp;quot; id=&amp;quot;my_button_id&amp;quot; class=&amp;quot;bgabutton bgabutton_red&amp;quot;&amp;gt;&amp;lt;span&amp;gt;My red button&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    &amp;lt;a href=&amp;quot;#&amp;quot; id=&amp;quot;my_button_id&amp;quot; class=&amp;quot;bgabutton bgabutton_red bgabutton_big&amp;quot;&amp;gt;&amp;lt;span&amp;gt;My big red button&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note: To see it in action, check for example a Coloretto game&lt;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://sr.doc.boardgamearena.com/index.php?title=Game_layout:_view_and_template:_yourgamename.view.php_and_yourgamename_yourgamename.tpl&amp;diff=2850</id>
		<title>Game layout: view and template: yourgamename.view.php and yourgamename yourgamename.tpl</title>
		<link rel="alternate" type="text/html" href="https://sr.doc.boardgamearena.com/index.php?title=Game_layout:_view_and_template:_yourgamename.view.php_and_yourgamename_yourgamename.tpl&amp;diff=2850"/>
		<updated>2018-01-14T09:28:45Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Javascript templates */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;These 2 files work together to provide the HTML layout of your game.&lt;br /&gt;
&lt;br /&gt;
Using these 2 files, you specify what HTML is rendered in your game client interface.&lt;br /&gt;
&lt;br /&gt;
In &amp;lt;yourgame.tpl&amp;gt;, you can directly write raw HTML that will be displayed by the browser.&lt;br /&gt;
&lt;br /&gt;
Example: extract of &amp;quot;hearts_hearts.tpl&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;myhand_wrap&amp;quot; class=&amp;quot;whiteblock&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;h3&amp;gt;{MY_HAND}&amp;lt;/h3&amp;gt;&lt;br /&gt;
    &amp;lt;div id=&amp;quot;myhand&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== WARNING ==&lt;br /&gt;
&lt;br /&gt;
Your view and your template are supposed to generate only the BASE layout of the game&lt;br /&gt;
&lt;br /&gt;
You shouldn&#039;t try to setup the current game situation in the view: this is the role of your Javascript code. Why? Because you&#039;ll have to write Javascript code to put game elements in place anyway, and you don&#039;t want to write it twice :)&lt;br /&gt;
&lt;br /&gt;
Example of things to generate in your view:&lt;br /&gt;
* The overall layout of your game interface (what is displayed where).&lt;br /&gt;
* The board and fixed elements on the board (ex: places for cards, squares, ...).&lt;br /&gt;
&lt;br /&gt;
Example of things that shouldn&#039;t be generate by your view:&lt;br /&gt;
* Game elements that come and go from the game area.&lt;br /&gt;
* Game elements that normally hidden from players (other players cards, cards in the deck).&lt;br /&gt;
&lt;br /&gt;
== phplib template system ==&lt;br /&gt;
&lt;br /&gt;
BGA is using the phplib template system, used for example in PHPbb forums.&lt;br /&gt;
&lt;br /&gt;
More details about how to use phplib template system here:&lt;br /&gt;
http://www.phpbuilder.com/columns/david20000512.php3&lt;br /&gt;
&lt;br /&gt;
== Variables ==&lt;br /&gt;
&lt;br /&gt;
In your template (&amp;quot;tpl&amp;quot;) file, you can use variables. Then in your view (&amp;quot;.view.php&amp;quot;) file, you fill these variables with value.&lt;br /&gt;
&lt;br /&gt;
In the example above, &amp;quot;{MY_HAND}&amp;quot; is a variable. As you can see, a variable is uppercase characters border by &amp;quot;{&amp;quot; and &amp;quot;}&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
To give a value to this variable in your view.php:&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   // Display a translated version of &amp;quot;My hand&amp;quot; at the place of the variable in the template&lt;br /&gt;
   $this-&amp;gt;tpl[&#039;MY_HAND&#039;] = self::_(&amp;quot;My hand&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
   // Display some raw HTML material at the place of the variable&lt;br /&gt;
   $this-&amp;gt;tpl[&#039;MY_HAND&#039;] = self::raw( &amp;quot;&amp;lt;div class=&#039;myhand_icon&#039;&amp;gt;&amp;lt;/div&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
WARNING: do not use a variable called {id} as it will interfere with action buttons.&lt;br /&gt;
&lt;br /&gt;
== Blocks ==&lt;br /&gt;
&lt;br /&gt;
Using &amp;quot;blocks&amp;quot;, you can repeat a piece of HTML from your template several time.&lt;br /&gt;
&lt;br /&gt;
You should use &amp;quot;blocks&amp;quot; everytime you have a block of HTML that you have to repeat a big number of time. For example, for Reversi, we have to generate 64 (8x8) squares:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(in reversi_reversi.tpl)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;board&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;!-- BEGIN square --&amp;gt;&lt;br /&gt;
        &amp;lt;div id=&amp;quot;square_{X}_{Y}&amp;quot; class=&amp;quot;square&amp;quot; style=&amp;quot;left: {LEFT}px; top: {TOP}px;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;!-- END square --&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
    &amp;lt;div id=&amp;quot;discs&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(in reversi.view.php)&lt;br /&gt;
&lt;br /&gt;
 $this-&amp;gt;page-&amp;gt;begin_block( &amp;quot;reversi_reversi&amp;quot;, &amp;quot;square&amp;quot; );&lt;br /&gt;
        &lt;br /&gt;
 $hor_scale = 64.8;&lt;br /&gt;
 $ver_scale = 64.4;&lt;br /&gt;
 for( $x=1; $x&amp;lt;=8; $x++ )&lt;br /&gt;
 {&lt;br /&gt;
    for( $y=1; $y&amp;lt;=8; $y++ )&lt;br /&gt;
    {&lt;br /&gt;
       $this-&amp;gt;page-&amp;gt;insert_block( &amp;quot;square&amp;quot;, array(&lt;br /&gt;
         &#039;X&#039; =&amp;gt; $x,&lt;br /&gt;
         &#039;Y&#039; =&amp;gt; $y,&lt;br /&gt;
         &#039;LEFT&#039; =&amp;gt; round( ($x-1)*$hor_scale+10 ),&lt;br /&gt;
         &#039;TOP&#039; =&amp;gt; round( ($y-1)*$ver_scale+7 )&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;
Explanations:&lt;br /&gt;
* You specify a block in your template file, using &amp;quot;BEGIN&amp;quot; and &amp;quot;END&amp;quot; keywords. In the example above, we are creating a block named &amp;quot;square&amp;quot;.&lt;br /&gt;
* In your view, you declare your block using &amp;quot;begin_block&amp;quot; method.&lt;br /&gt;
* Then, you can insert as many block as you want to, using &amp;quot;insert_block&amp;quot; method.&lt;br /&gt;
&lt;br /&gt;
The insert_block method takes 2 parameters:&lt;br /&gt;
* the name of the block to insert.&lt;br /&gt;
* an associative array you can use to assign values to template variables of this block. In the example above, there are 4 parameters in the block (X, Y, LEFT and TOP).&lt;br /&gt;
&lt;br /&gt;
== Nested blocks ==&lt;br /&gt;
&lt;br /&gt;
You can use nested blocks. In the example below, we are going to add a mini-board for each player of the game, with 4 card places on each of it:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(In template file)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- BEGIN player --&amp;gt;&lt;br /&gt;
    &amp;lt;div class=&amp;quot;miniboard&amp;quot; id=&amp;quot;miniboard_{PLAYER_ID}&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
        &amp;lt;div class=&amp;quot;card_places&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;!-- BEGIN card_place --&amp;gt;&lt;br /&gt;
            &amp;lt;div id=&amp;quot;card_place_{PLAYER_ID}_{PLACE_ID}&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;!-- END card_place --&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;!-- END player --&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
(In view file)&lt;br /&gt;
&lt;br /&gt;
$this-&amp;gt;page-&amp;gt;begin_block( &amp;quot;mygame_mygame.tpl&amp;quot;, &amp;quot;card_place&amp;quot; ); // Nested block must be declared first&lt;br /&gt;
$this-&amp;gt;page-&amp;gt;begin_block( &amp;quot;mygame_mygame.tpl&amp;quot;, &amp;quot;player&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
foreach( $players as $player_id =&amp;gt; $player )&lt;br /&gt;
{&lt;br /&gt;
    // Important: nested block must be reset here, otherwise the second player miniboard will&lt;br /&gt;
    //  have 8 card_place, the third will have 12 card_place, and so one...&lt;br /&gt;
    $this-&amp;gt;page-&amp;gt;reset_subblocks( &#039;card_place&#039; ); &lt;br /&gt;
&lt;br /&gt;
    for( $i=1; $i&amp;lt;=4; $i++ )&lt;br /&gt;
    {&lt;br /&gt;
       $this-&amp;gt;page-&amp;gt;insert_block( &amp;quot;card_place&amp;quot;, array( &lt;br /&gt;
             &#039;PLAYER_ID&#039; =&amp;gt; $player_id,&lt;br /&gt;
             &#039;PLACE_ID&#039; =&amp;gt; $i&lt;br /&gt;
       );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    $this-&amp;gt;page-&amp;gt;insert_block( &#039;player&#039;, array( &#039;PLAYER_ID&#039; =&amp;gt; $player_id );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Javascript templates ==&lt;br /&gt;
&lt;br /&gt;
For game elements that come and go from the game area, we suggest you to define a Javascript template.&lt;br /&gt;
&lt;br /&gt;
A Javascript template is defined in your template file like this:&lt;br /&gt;
&lt;br /&gt;
(Reversi Token from Reversi example):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Templates&lt;br /&gt;
&lt;br /&gt;
var jstpl_disc=&#039;&amp;lt;div class=&amp;quot;disc disccolor_${color}&amp;quot; id=&amp;quot;disc_${xy}&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: a section for javascript templates is already available at the end of your template skeleton file.&lt;br /&gt;
&lt;br /&gt;
Then, you can use this javascript template to insert this piece of HTML in your game interface, like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    dojo.place( this.format_block( &#039;jstpl_disc&#039;, {&lt;br /&gt;
           xy: x+&#039;&#039;+y,&lt;br /&gt;
           color: color&lt;br /&gt;
    } ) , &#039;discs&#039; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
WARNING: always use lowercase for substitution variables in your Javascript templates, in order to avoid collision with PhpLib template variables (in particular, do not use ${ID}).&lt;br /&gt;
&lt;br /&gt;
== How to access game information from .view.php? ==&lt;br /&gt;
&lt;br /&gt;
From your .view.php, you can access the following:&lt;br /&gt;
&lt;br /&gt;
=== Access current player id===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  global $g_user;&lt;br /&gt;
  $current_player_id = $g_user-&amp;gt;get_id();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Access game object ===&lt;br /&gt;
&lt;br /&gt;
In your view file, &amp;quot;$this-&amp;gt;game&amp;quot; contains an instance of your main game class.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   // Access to some game elements description described in your &amp;quot;material.inc.php&amp;quot;:&lt;br /&gt;
   $my_cards_types = $this-&amp;gt;game-&amp;gt;card_types;&lt;br /&gt;
&lt;br /&gt;
   // Access to any (public) method defined in my .game.php file:&lt;br /&gt;
   $result = $this-&amp;gt;game-&amp;gt;myMethod();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tips: displaying a nice button ==&lt;br /&gt;
&lt;br /&gt;
From time to time, you need to display a standard button in your interface. BGA framework provides you a standard button that you can use directly in your interface:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    &amp;lt;a href=&amp;quot;#&amp;quot; id=&amp;quot;my_button_id&amp;quot; class=&amp;quot;bgabutton bgabutton_blue&amp;quot;&amp;gt;&amp;lt;span&amp;gt;My blue button&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    &amp;lt;a href=&amp;quot;#&amp;quot; id=&amp;quot;my_button_id&amp;quot; class=&amp;quot;bgabutton bgabutton_gray&amp;quot;&amp;gt;&amp;lt;span&amp;gt;My gray button&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    &amp;lt;a href=&amp;quot;#&amp;quot; id=&amp;quot;my_button_id&amp;quot; class=&amp;quot;bgabutton bgabutton_red&amp;quot;&amp;gt;&amp;lt;span&amp;gt;My red button&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    &amp;lt;a href=&amp;quot;#&amp;quot; id=&amp;quot;my_button_id&amp;quot; class=&amp;quot;bgabutton bgabutton_red bgabutton_big&amp;quot;&amp;gt;&amp;lt;span&amp;gt;My big red button&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note: To see it in action, check for example a Coloretto game&lt;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
	<entry>
		<id>https://sr.doc.boardgamearena.com/index.php?title=Game_layout:_view_and_template:_yourgamename.view.php_and_yourgamename_yourgamename.tpl&amp;diff=2849</id>
		<title>Game layout: view and template: yourgamename.view.php and yourgamename yourgamename.tpl</title>
		<link rel="alternate" type="text/html" href="https://sr.doc.boardgamearena.com/index.php?title=Game_layout:_view_and_template:_yourgamename.view.php_and_yourgamename_yourgamename.tpl&amp;diff=2849"/>
		<updated>2018-01-14T09:27:42Z</updated>

		<summary type="html">&lt;p&gt;Een: /* Javascript templates */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;These 2 files work together to provide the HTML layout of your game.&lt;br /&gt;
&lt;br /&gt;
Using these 2 files, you specify what HTML is rendered in your game client interface.&lt;br /&gt;
&lt;br /&gt;
In &amp;lt;yourgame.tpl&amp;gt;, you can directly write raw HTML that will be displayed by the browser.&lt;br /&gt;
&lt;br /&gt;
Example: extract of &amp;quot;hearts_hearts.tpl&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;lt;div id=&amp;quot;myhand_wrap&amp;quot; class=&amp;quot;whiteblock&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;h3&amp;gt;{MY_HAND}&amp;lt;/h3&amp;gt;&lt;br /&gt;
    &amp;lt;div id=&amp;quot;myhand&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== WARNING ==&lt;br /&gt;
&lt;br /&gt;
Your view and your template are supposed to generate only the BASE layout of the game&lt;br /&gt;
&lt;br /&gt;
You shouldn&#039;t try to setup the current game situation in the view: this is the role of your Javascript code. Why? Because you&#039;ll have to write Javascript code to put game elements in place anyway, and you don&#039;t want to write it twice :)&lt;br /&gt;
&lt;br /&gt;
Example of things to generate in your view:&lt;br /&gt;
* The overall layout of your game interface (what is displayed where).&lt;br /&gt;
* The board and fixed elements on the board (ex: places for cards, squares, ...).&lt;br /&gt;
&lt;br /&gt;
Example of things that shouldn&#039;t be generate by your view:&lt;br /&gt;
* Game elements that come and go from the game area.&lt;br /&gt;
* Game elements that normally hidden from players (other players cards, cards in the deck).&lt;br /&gt;
&lt;br /&gt;
== phplib template system ==&lt;br /&gt;
&lt;br /&gt;
BGA is using the phplib template system, used for example in PHPbb forums.&lt;br /&gt;
&lt;br /&gt;
More details about how to use phplib template system here:&lt;br /&gt;
http://www.phpbuilder.com/columns/david20000512.php3&lt;br /&gt;
&lt;br /&gt;
== Variables ==&lt;br /&gt;
&lt;br /&gt;
In your template (&amp;quot;tpl&amp;quot;) file, you can use variables. Then in your view (&amp;quot;.view.php&amp;quot;) file, you fill these variables with value.&lt;br /&gt;
&lt;br /&gt;
In the example above, &amp;quot;{MY_HAND}&amp;quot; is a variable. As you can see, a variable is uppercase characters border by &amp;quot;{&amp;quot; and &amp;quot;}&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
To give a value to this variable in your view.php:&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   // Display a translated version of &amp;quot;My hand&amp;quot; at the place of the variable in the template&lt;br /&gt;
   $this-&amp;gt;tpl[&#039;MY_HAND&#039;] = self::_(&amp;quot;My hand&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
   // Display some raw HTML material at the place of the variable&lt;br /&gt;
   $this-&amp;gt;tpl[&#039;MY_HAND&#039;] = self::raw( &amp;quot;&amp;lt;div class=&#039;myhand_icon&#039;&amp;gt;&amp;lt;/div&amp;gt;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
WARNING: do not use a variable called {id} as it will interfere with action buttons.&lt;br /&gt;
&lt;br /&gt;
== Blocks ==&lt;br /&gt;
&lt;br /&gt;
Using &amp;quot;blocks&amp;quot;, you can repeat a piece of HTML from your template several time.&lt;br /&gt;
&lt;br /&gt;
You should use &amp;quot;blocks&amp;quot; everytime you have a block of HTML that you have to repeat a big number of time. For example, for Reversi, we have to generate 64 (8x8) squares:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(in reversi_reversi.tpl)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;board&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;!-- BEGIN square --&amp;gt;&lt;br /&gt;
        &amp;lt;div id=&amp;quot;square_{X}_{Y}&amp;quot; class=&amp;quot;square&amp;quot; style=&amp;quot;left: {LEFT}px; top: {TOP}px;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;!-- END square --&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
    &amp;lt;div id=&amp;quot;discs&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(in reversi.view.php)&lt;br /&gt;
&lt;br /&gt;
 $this-&amp;gt;page-&amp;gt;begin_block( &amp;quot;reversi_reversi&amp;quot;, &amp;quot;square&amp;quot; );&lt;br /&gt;
        &lt;br /&gt;
 $hor_scale = 64.8;&lt;br /&gt;
 $ver_scale = 64.4;&lt;br /&gt;
 for( $x=1; $x&amp;lt;=8; $x++ )&lt;br /&gt;
 {&lt;br /&gt;
    for( $y=1; $y&amp;lt;=8; $y++ )&lt;br /&gt;
    {&lt;br /&gt;
       $this-&amp;gt;page-&amp;gt;insert_block( &amp;quot;square&amp;quot;, array(&lt;br /&gt;
         &#039;X&#039; =&amp;gt; $x,&lt;br /&gt;
         &#039;Y&#039; =&amp;gt; $y,&lt;br /&gt;
         &#039;LEFT&#039; =&amp;gt; round( ($x-1)*$hor_scale+10 ),&lt;br /&gt;
         &#039;TOP&#039; =&amp;gt; round( ($y-1)*$ver_scale+7 )&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;
Explanations:&lt;br /&gt;
* You specify a block in your template file, using &amp;quot;BEGIN&amp;quot; and &amp;quot;END&amp;quot; keywords. In the example above, we are creating a block named &amp;quot;square&amp;quot;.&lt;br /&gt;
* In your view, you declare your block using &amp;quot;begin_block&amp;quot; method.&lt;br /&gt;
* Then, you can insert as many block as you want to, using &amp;quot;insert_block&amp;quot; method.&lt;br /&gt;
&lt;br /&gt;
The insert_block method takes 2 parameters:&lt;br /&gt;
* the name of the block to insert.&lt;br /&gt;
* an associative array you can use to assign values to template variables of this block. In the example above, there are 4 parameters in the block (X, Y, LEFT and TOP).&lt;br /&gt;
&lt;br /&gt;
== Nested blocks ==&lt;br /&gt;
&lt;br /&gt;
You can use nested blocks. In the example below, we are going to add a mini-board for each player of the game, with 4 card places on each of it:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(In template file)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- BEGIN player --&amp;gt;&lt;br /&gt;
    &amp;lt;div class=&amp;quot;miniboard&amp;quot; id=&amp;quot;miniboard_{PLAYER_ID}&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
        &amp;lt;div class=&amp;quot;card_places&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;!-- BEGIN card_place --&amp;gt;&lt;br /&gt;
            &amp;lt;div id=&amp;quot;card_place_{PLAYER_ID}_{PLACE_ID}&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;!-- END card_place --&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;!-- END player --&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
(In view file)&lt;br /&gt;
&lt;br /&gt;
$this-&amp;gt;page-&amp;gt;begin_block( &amp;quot;mygame_mygame.tpl&amp;quot;, &amp;quot;card_place&amp;quot; ); // Nested block must be declared first&lt;br /&gt;
$this-&amp;gt;page-&amp;gt;begin_block( &amp;quot;mygame_mygame.tpl&amp;quot;, &amp;quot;player&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
foreach( $players as $player_id =&amp;gt; $player )&lt;br /&gt;
{&lt;br /&gt;
    // Important: nested block must be reset here, otherwise the second player miniboard will&lt;br /&gt;
    //  have 8 card_place, the third will have 12 card_place, and so one...&lt;br /&gt;
    $this-&amp;gt;page-&amp;gt;reset_subblocks( &#039;card_place&#039; ); &lt;br /&gt;
&lt;br /&gt;
    for( $i=1; $i&amp;lt;=4; $i++ )&lt;br /&gt;
    {&lt;br /&gt;
       $this-&amp;gt;page-&amp;gt;insert_block( &amp;quot;card_place&amp;quot;, array( &lt;br /&gt;
             &#039;PLAYER_ID&#039; =&amp;gt; $player_id,&lt;br /&gt;
             &#039;PLACE_ID&#039; =&amp;gt; $i&lt;br /&gt;
       );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    $this-&amp;gt;page-&amp;gt;insert_block( &#039;player&#039;, array( &#039;PLAYER_ID&#039; =&amp;gt; $player_id );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Javascript templates ==&lt;br /&gt;
&lt;br /&gt;
For game elements that come and go from the game area, we suggest you to define a Javascript template.&lt;br /&gt;
&lt;br /&gt;
A Javascript template is defined in your template file like this:&lt;br /&gt;
&lt;br /&gt;
(Reversi Token from Reversi example):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Templates&lt;br /&gt;
&lt;br /&gt;
var jstpl_disc=&#039;&amp;lt;div class=&amp;quot;disc disccolor_${color}&amp;quot; id=&amp;quot;disc_${xy}&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: a section for javascript templates is already available at the end of your template skeleton file.&lt;br /&gt;
&lt;br /&gt;
Then, you can use this javascript template to insert this piece of HTML in your game interface, like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    dojo.place( this.format_block( &#039;jstpl_disc&#039;, {&lt;br /&gt;
           xy: x+&#039;&#039;+y,&lt;br /&gt;
           color: color&lt;br /&gt;
    } ) , &#039;discs&#039; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
WARNING: always use lowercase for substitution variables, in order to avoid collision with PhpLib template variables.&lt;br /&gt;
&lt;br /&gt;
== How to access game information from .view.php? ==&lt;br /&gt;
&lt;br /&gt;
From your .view.php, you can access the following:&lt;br /&gt;
&lt;br /&gt;
=== Access current player id===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  global $g_user;&lt;br /&gt;
  $current_player_id = $g_user-&amp;gt;get_id();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Access game object ===&lt;br /&gt;
&lt;br /&gt;
In your view file, &amp;quot;$this-&amp;gt;game&amp;quot; contains an instance of your main game class.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   // Access to some game elements description described in your &amp;quot;material.inc.php&amp;quot;:&lt;br /&gt;
   $my_cards_types = $this-&amp;gt;game-&amp;gt;card_types;&lt;br /&gt;
&lt;br /&gt;
   // Access to any (public) method defined in my .game.php file:&lt;br /&gt;
   $result = $this-&amp;gt;game-&amp;gt;myMethod();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tips: displaying a nice button ==&lt;br /&gt;
&lt;br /&gt;
From time to time, you need to display a standard button in your interface. BGA framework provides you a standard button that you can use directly in your interface:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    &amp;lt;a href=&amp;quot;#&amp;quot; id=&amp;quot;my_button_id&amp;quot; class=&amp;quot;bgabutton bgabutton_blue&amp;quot;&amp;gt;&amp;lt;span&amp;gt;My blue button&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    &amp;lt;a href=&amp;quot;#&amp;quot; id=&amp;quot;my_button_id&amp;quot; class=&amp;quot;bgabutton bgabutton_gray&amp;quot;&amp;gt;&amp;lt;span&amp;gt;My gray button&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    &amp;lt;a href=&amp;quot;#&amp;quot; id=&amp;quot;my_button_id&amp;quot; class=&amp;quot;bgabutton bgabutton_red&amp;quot;&amp;gt;&amp;lt;span&amp;gt;My red button&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    &amp;lt;a href=&amp;quot;#&amp;quot; id=&amp;quot;my_button_id&amp;quot; class=&amp;quot;bgabutton bgabutton_red bgabutton_big&amp;quot;&amp;gt;&amp;lt;span&amp;gt;My big red button&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note: To see it in action, check for example a Coloretto game&lt;/div&gt;</summary>
		<author><name>Een</name></author>
	</entry>
</feed>