<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://en.doc.boardgamearena.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=SwHawk</id>
	<title>Board Game Arena - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://en.doc.boardgamearena.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=SwHawk"/>
	<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/Special:Contributions/SwHawk"/>
	<updated>2026-10-18T07:10:29Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.39.0</generator>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Gamehelpcosmosempires&amp;diff=15534</id>
		<title>Gamehelpcosmosempires</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Gamehelpcosmosempires&amp;diff=15534"/>
		<updated>2022-12-13T17:07:24Z</updated>

		<summary type="html">&lt;p&gt;SwHawk: Added rule adaptations for 6+ players, and added further explanations to some parts&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The game is played with a single deck, from which 10 cards are drawn into the &amp;quot;build pool&amp;quot; where players can select and build cards from. Each card has a cost (on the left of the card, below the card&#039;s name), roll value (at the bottom of the card, inside the triangle) and production value (at the bottom of the card, inside the circle).&lt;br /&gt;
&lt;br /&gt;
==Objective==&lt;br /&gt;
The first player to reach a total production value (sum of production values from all of their card) of 30 (20 when playing with 7 or 8 players) starts the last turn. The last turn then proceeds up to the last player of the turn. The winner is then the player with the highest production value. If there is a tie, the player with the most credits wins. If there is still a tie, the player who played last is declared winner.&lt;br /&gt;
&lt;br /&gt;
==Player turn==&lt;br /&gt;
&lt;br /&gt;
===Production phase===&lt;br /&gt;
Except for each player&#039;s first turn, the active player starts their turn by rolling the two four sided dice and spending actions to adjust the total roll value (sum of the two dice, each action spent allows to adjust that total value by ± 1). Some cards will grant you this action for free each turn, once per card. Once the player confirms the roll value, each player around the table receives an amount of credits equal to the sum of the production value of the cards with that specific roll value that they own.&lt;br /&gt;
&lt;br /&gt;
===Main phase===&lt;br /&gt;
During this phase, the active player can spend their remaining actions to perform the following:&lt;br /&gt;
&lt;br /&gt;
* Buying a card from the build pool. A new card is then picked from the deck to replace it. The active player adds this card to their playing area. If the card grants an extra action (see below), the player can spend it immediately.&lt;br /&gt;
* Cycling a card from the build pool and get 2 credits. The selected card is put under the deck and a new one is picked to replace it.&lt;br /&gt;
&lt;br /&gt;
Some cards will grant you extra actions that can be performed each turn, once per card granting that extra action:&lt;br /&gt;
&lt;br /&gt;
* Buying a Mech card from the build pool without spending a regular action, but the player still has to pay for the credits,&lt;br /&gt;
* Cycling a card from the build pool without spending a regular action, but without getting 2 credits as well.&lt;br /&gt;
&lt;br /&gt;
You are not required to spend all of your actions before ending your turn.&lt;br /&gt;
&lt;br /&gt;
===End of turn===&lt;br /&gt;
Once a player has exhausted all of their actions or decided they don&#039;t want to spend them anymore, they reset their actions counter (for 6 players or less, each player gets 2 regular action per turn, for 7 or 8 players, each players has 3 regular actions per turn, plus any extra action granted by their card) and pass the dice to the next player.&lt;/div&gt;</summary>
		<author><name>SwHawk</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Game_interface_logic:_Game.js&amp;diff=15524</id>
		<title>Game interface logic: Game.js</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Game_interface_logic:_Game.js&amp;diff=15524"/>
		<updated>2022-12-12T10:18:49Z</updated>

		<summary type="html">&lt;p&gt;SwHawk: /* Actions */ added information for the callback_anycase parameter in ajaxcall&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Studio_Framework_Navigation}}&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&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 a change from the server and how it will show in the browser. &lt;br /&gt;
* Setup user interface&lt;br /&gt;
&lt;br /&gt;
== File structure ==&lt;br /&gt;
&lt;br /&gt;
The details of how the file is structured are described below with comments in the code skeleton provided to you.&lt;br /&gt;
&lt;br /&gt;
Here is the basic structure:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;constructor&#039;&#039;&#039;: here you can define global variables for your whole interface.&lt;br /&gt;
* &#039;&#039;&#039;setup&#039;&#039;&#039;: this method is called when the page is refreshed, and sets up the game interface.&lt;br /&gt;
* &#039;&#039;&#039;onEnteringState&#039;&#039;&#039;: this method is called when entering a new game state. You can use it to customize the view for each game state.&lt;br /&gt;
* &#039;&#039;&#039;onLeavingState&#039;&#039;&#039;: this method is called when leaving a game state.&lt;br /&gt;
* &#039;&#039;&#039;onUpdateActionButtons&#039;&#039;&#039;: called when entering a new state, in order to add action buttons to the status bar.&lt;br /&gt;
* &#039;&#039;(utility methods)&#039;&#039;: this is where you can define your utility methods.&lt;br /&gt;
* &#039;&#039;(player&#039;s actions)&#039;&#039;: this is where you can write your handlers for player actions on the interface (example: click on an item).&lt;br /&gt;
* &#039;&#039;&#039;setupNotifications&#039;&#039;&#039;: this method associates notifications with notification handlers. For each game notification, you can trigger a javascript method to handle it and update the game interface.&lt;br /&gt;
* &#039;&#039;(notification handlers)&#039;&#039;: this is where you define the notifications handlers associated with notifications in &#039;&#039;&#039;setupNotifications&#039;&#039;&#039;, above.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
More details:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;setup(gamedatas: object)            &#039;&#039;&#039;&lt;br /&gt;
This method must set up the game user interface according to current game situation specified in parameters.&lt;br /&gt;
The method is called each time the game interface is displayed to a player, ie:&lt;br /&gt;
&lt;br /&gt;
* when the game starts&lt;br /&gt;
* when a player opens a game in the browser later &lt;br /&gt;
* when a player refreshes the game page (F5)&lt;br /&gt;
* when player does a server side Undo&lt;br /&gt;
&lt;br /&gt;
&amp;quot;gamedatas&amp;quot; argument contains all data retrieved by your &amp;quot;getAllDatas&amp;quot; PHP method and some more.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;onEnteringState(stateName: string, args: { args: any } | null): void&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This method is called each time we enter a new game state.&lt;br /&gt;
You can use this method to perform some user interface changes at this moment.&lt;br /&gt;
To access state arguments passed via calling php arg* method use args?.args.&lt;br /&gt;
Typically you would do something only for active player, using this.isCurrentPlayerActive() check.&lt;br /&gt;
It is also called (for the current game state only) when doing a browser refresh (after the setup method is called).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Warning&#039;&#039;&#039;: for multipleactiveplayer states:&lt;br /&gt;
the active players are NOT active yet so you must use onUpdateActionButtons to perform the client side operation which depends on a player active/inactive status.&lt;br /&gt;
If you are doing initialization of some structures which do not depend on the active player, you can just replace (this.isCurrentPlayerActive()) with (!this.isSpectator) &lt;br /&gt;
for the main switch in that method.&lt;br /&gt;
&lt;br /&gt;
See more details in [[Your_game_state_machine:_states.inc.php#Difference_between_Single_active_and_Multi_active_states]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;onLeavingState(stateName: string): void&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This method is called each time we leave a game state.&lt;br /&gt;
You can use this method to perform some user interface changes at this point (i.e. cleanup).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;onUpdateActionButtons(stateName: string, args: object | null): void&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In this method you can manage &amp;quot;action buttons&amp;quot; that are displayed in the action status bar and highlight active UI elements.&lt;br /&gt;
To access state arguments passed via calling php arg* method use &#039;&#039;&#039;args&#039;&#039;&#039; parameter. Note: args can be null! For &#039;&#039;&#039;game&#039;&#039;&#039; states and when you don&#039;t supply state args function - it is null.&lt;br /&gt;
This method is called when the active or multiactive player changes. In a classic &amp;quot;activePlayer&amp;quot; state this method is called before the onEnteringState state.&lt;br /&gt;
In multipleactiveplayer state it is a mess. The sequencing of calls depends on whether you get into that state from transitions OR from reloading the whole game (i.e. F5).&lt;br /&gt;
&lt;br /&gt;
See more details in [[Your_game_state_machine:_states.inc.php#Difference_between_Single_active_and_Multi_active_states]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Dojo framework ==&lt;br /&gt;
&lt;br /&gt;
BGA uses the [http://dojotoolkit.org/ Dojo Javascript framework].&lt;br /&gt;
&lt;br /&gt;
The Dojo framework allows us to do complex things more easily. The BGA framework uses Dojo extensively.&lt;br /&gt;
&lt;br /&gt;
To implement a game, you only need to use a few parts of the Dojo framework. All the Dojo methods you need are described on this page.&lt;br /&gt;
&lt;br /&gt;
== Javascript minimization (after July 2020) ==&lt;br /&gt;
&lt;br /&gt;
For performance reasons, when deploying a game the javascript code is minimized using &#039;&#039;&#039;terser&#039;&#039;&#039; (https://github.com/terser/terser). This minifier works with modern javascript syntax. From your project &amp;quot;Manage game&amp;quot; page, you can now test a minified version of your javascript on the studio (and revert to the original).&lt;br /&gt;
&lt;br /&gt;
NB: it has been reported that there is an issue with this minifier and percentage values for opacity.&lt;br /&gt;
&lt;br /&gt;
== Accessing Players Information ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;player_id: number&#039;&#039;&#039;&lt;br /&gt;
id of the player who is looking at the game. The player may not be part of the game (i.e. spectator)&lt;br /&gt;
  if (notif.args.player_id == this.player_id) {&lt;br /&gt;
    ...&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;isSpectator: boolean&#039;&#039;&#039;&lt;br /&gt;
Flag set to true if the user at the table is a spectator (not a player).&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    if (this.isSpectator) {&lt;br /&gt;
        this.player_color = &#039;ffffff&#039;;&lt;br /&gt;
    } else {&lt;br /&gt;
        this.player_color = gamedatas.players[this.player_id].color;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: If you want to hide an element from spectators, you should use [[Game_interface_stylesheet:_yourgamename.css#spectatorMode|CSS &#039;spectatorMode&#039; class]].&lt;br /&gt;
&lt;br /&gt;
You may consider making a function like this, to detect if the game is in a read-only state (i.e. non-interactive):&lt;br /&gt;
  // Returns true for spectators, instant replay (during game), archive mode (after game end)&lt;br /&gt;
  isReadOnly: function () {&lt;br /&gt;
    return this.isSpectator || typeof g_replayFrom != &#039;undefined&#039; || g_archive_mode;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;gamedatas: object&#039;&#039;&#039;&lt;br /&gt;
Contains the initial set of data to init the game, created at game start or by 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, however most of the time this is unnecessary.&lt;br /&gt;
&lt;br /&gt;
Note: In hotseat mode, the framework does not keep this.gamedatas of hotseat players and shares the same set as the main player to store data.&lt;br /&gt;
&lt;br /&gt;
Note: be careful when you update this data structurally, many framework functions expect data to be certain way and they will break if they see something else.&lt;br /&gt;
&lt;br /&gt;
Typical example of accessing player&#039;s info&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
for (var player_id in this.gamedatas.players) { &lt;br /&gt;
    var playerInfo = this.gamedatas.players [player_id];&lt;br /&gt;
    var c = playerInfo.color;&lt;br /&gt;
    var name = playerInfo.name;&lt;br /&gt;
    // do something &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;isCurrentPlayerActive(): boolean&#039;&#039;&#039;&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). Note: see remarks above about usage of this function inside onEnteringState method.&lt;br /&gt;
  if (this.isCurrentPlayerActive()) {&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;getActivePlayerId(): number&#039;&#039;&#039;&lt;br /&gt;
Return the ID of the active player, or null if we are not in an &amp;quot;activeplayer&amp;quot; type state.&lt;br /&gt;
  if (this.player_id == this.getActivePlayerId()) ...&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;getActivePlayers(): number[]&#039;&#039;&#039;&lt;br /&gt;
Return an array with the IDs of players who are currently active (or an empty array if there are none).&lt;br /&gt;
&lt;br /&gt;
== Accessing and manipulating the DOM ==&lt;br /&gt;
&lt;br /&gt;
=== Element by Id ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;$(elementId: ElementOrId)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The $ function is used to get an HTML element using its &amp;quot;id&amp;quot; attribute.&lt;br /&gt;
&lt;br /&gt;
Example: modify the content of a &amp;quot;span&amp;quot; element:&lt;br /&gt;
&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;
&lt;br /&gt;
Note: It is safe to use if you don&#039;t know if variable is string (id of element) or element itself, i.e. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  foo: function(card) {&lt;br /&gt;
       card = $(card); // now its node, no need to write if (typeof card === &#039;string&#039;) ...&lt;br /&gt;
       // but its good idea to check for null here&lt;br /&gt;
       ...&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;getElementById(elementId: string)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Note: $() is the standard method to access some HTML element with the BGA Framework. You can use &#039;&#039;&#039;getElementById&#039;&#039;&#039; but a longer to type and less handy as it does not do some checks.&lt;br /&gt;
&lt;br /&gt;
=== Style ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;dojo.style(node: ElementOrId, styleName: string, styleValue: any): void&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
With dojo.style you can modify the CSS property of any HTML element in your interface.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&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 sprites 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: if you have to modify several CSS properties of an element, or if you have a complex CSS transformation to do, you should consider using dojo.addClass/dojo.removeClass (see below).&lt;br /&gt;
&lt;br /&gt;
You can also use object to set multiple values&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
dojo.setStyle(&amp;quot;thinger&amp;quot;, {&lt;br /&gt;
  &amp;quot;opacity&amp;quot;: 0.5,&lt;br /&gt;
  &amp;quot;border&amp;quot;: &amp;quot;3px solid black&amp;quot;,&lt;br /&gt;
  &amp;quot;height&amp;quot;: &amp;quot;300px&amp;quot;&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;addStyleToClass(cssClassName: string, styleName: string, styleValue: any):void&#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;
Equivalent of &lt;br /&gt;
  &lt;br /&gt;
  dojo.query(`.${aclass}`).style(styleName, styleValue)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
dojo.query(&amp;quot;#baz &amp;gt; div&amp;quot;).style({&lt;br /&gt;
  opacity:0.75,&lt;br /&gt;
  fontSize:&amp;quot;13pt&amp;quot;&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Vanila JS style&#039;&#039;&#039;&lt;br /&gt;
  $(&#039;my_element&#039;).style.display=&#039;none&#039;; // set&lt;br /&gt;
  var display = $(&#039;my_element&#039;).style.display; // get&lt;br /&gt;
  $(&#039;my_element&#039;).style.removeProperty(&#039;display&#039;); // remove&lt;br /&gt;
&lt;br /&gt;
=== Classes ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;dojo.addClass(node: ElementOrId, classes: string): void&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;dojo.removeClass(node: ElementOrId, classes: string): void&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;dojo.hasClass(node: ElementOrId, aclass: string): void&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;dojo.toggleClass(node: ElementOrId, aclass: string): void&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In many situations, many small CSS property updates can be replaced by a CSS class change (i.e., you add a CSS class to your element instead of applying all modifications 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 without error.&lt;br /&gt;
* You can test whether you applied the CSS to an element with the &#039;&#039;&#039;dojo.hasClass&#039;&#039;&#039; method.&lt;br /&gt;
&lt;br /&gt;
Example from &#039;&#039;Reversi&#039;&#039;:&lt;br /&gt;
&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 changes 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 the 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;
&lt;br /&gt;
&#039;&#039;&#039;Vanila JS classList&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This is the only exception where dojo versions are better&lt;br /&gt;
  // add class&lt;br /&gt;
  $(token_id).classList.addClass(&#039;possibleMove&#039;);&lt;br /&gt;
  // remove class&lt;br /&gt;
  $(token_id).classList.removeClass(&#039;possibleMove&#039;);&lt;br /&gt;
  // add 2 classes&lt;br /&gt;
  const myclasses = [&#039;a&#039;,&#039;b&#039;];&lt;br /&gt;
  $(token_id).classList.addClass(...myclasses);&lt;br /&gt;
  // add classes to query result&lt;br /&gt;
  document.querySelectorAll(&amp;quot;.hand .card&amp;quot;).forEach((node)=&amp;gt;node.classList.addClass(&#039;possibleMove&#039;));&lt;br /&gt;
&lt;br /&gt;
=== Attributes ===&lt;br /&gt;
&lt;br /&gt;
;dojo.attr&lt;br /&gt;
&lt;br /&gt;
With dojo.attr you can access or change the value of an attribute or property of any HTML element in your interface.&lt;br /&gt;
&lt;br /&gt;
Exemple:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     // Get the title of a node&lt;br /&gt;
     var title = dojo.attr( id, &#039;title&#039; );&lt;br /&gt;
     // Change the height of a node&lt;br /&gt;
     dojo.attr( &#039;img_growing_tree&#039;, &#039;height&#039;, 100 );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Vanila JS attr&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
   $(token).id=new_id; // set attr for &amp;quot;id&amp;quot;&lt;br /&gt;
   var id = $(token).id; // get&lt;br /&gt;
&lt;br /&gt;
=== Queries ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;dojo.query(cssSelector: string): Element[]&#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 (i.e., elements of class &amp;quot;token&amp;quot;) on the board (i.e., the 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;Vanila JS query&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
  var cards=document.querySelectorAll(&amp;quot;.hand .card&amp;quot;);// all cards in all hands&lt;br /&gt;
  var cards=$(&#039;hand&#039;).querySelectorAll(&amp;quot;.card&amp;quot;);// all cards in specific hand&lt;br /&gt;
  var card=document.querySelector(&amp;quot;.hand .card&amp;quot;);// first card or null if none (super handy)&lt;br /&gt;
&lt;br /&gt;
=== Creating and Destroying elements ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;dojo.empty(node: ElementOrId)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Remove all children of the node element&lt;br /&gt;
   dojo.empty(&#039;my_hand&#039;);&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;dojo.destroy(node: ElementOrId)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Remove the element&lt;br /&gt;
   dojo.destroy(&#039;my_token&#039;);&lt;br /&gt;
&lt;br /&gt;
   dojo.query(&amp;quot;.green&amp;quot;, mynode).forEach(dojo.destroy); // this remove all subnode of class green from mynode&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;dojo.create(tag: string, attributes?: obj, parent?: ElementOrId): Element&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Create element&lt;br /&gt;
&lt;br /&gt;
    dojo.create(&amp;quot;div&amp;quot;, { class: &amp;quot;yellow_arrow&amp;quot; }, parent); // this creates div with class yellow_array and places it in &amp;quot;parent&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.format_block(name: string, args: object): string&#039;&#039;&#039;&lt;br /&gt;
This bga function that takes global var from template file and substitute variables, typical use would be&lt;br /&gt;
&lt;br /&gt;
                var player = gamedatas.players[player_id];&lt;br /&gt;
                var div = this.format_block(&#039;jstpl_player_board&#039;, player ); // var jstpl_player_board = ... is defined in .tpl file &lt;br /&gt;
Note: result is trimmed&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.format_string(name: string, args: object): string&#039;&#039;&#039;&lt;br /&gt;
This bga function just substitute variables in a string, i.e.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     var div = this.format_string(&#039;&amp;lt;div color=&amp;quot;${player_color}&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;, {player_color: &#039;#ff0000&#039;} );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: result is trimmed&lt;br /&gt;
&lt;br /&gt;
Note: this can be replaced by using backquoted string now: &lt;br /&gt;
     const player_color =  &#039;#ff0000&#039;;&lt;br /&gt;
     const div = `&amp;lt;div color=&amp;quot;${player_color}&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;`;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.format_string_recursive&#039;&#039;&#039;&lt;br /&gt;
This bga function is similar to this.format_string but is capable of processing recursive argument structures and translations. It is used to format server notifications.&lt;br /&gt;
&lt;br /&gt;
TODO: find better place for these function docs&lt;br /&gt;
&lt;br /&gt;
=== Moving elements ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;dojo.place(node: string | Element, refNode: ElementOrId, pos?: string | number): Element&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
dojo.place is the best function to insert HTML code somewhere in your game interface without breaking something. It is much better to use than the &#039;&#039;&#039;innerHTML=&#039;&#039;&#039; method if you must insert HTML tags and not only values.&lt;br /&gt;
&lt;br /&gt;
node: &lt;br /&gt;
&lt;br /&gt;
Can be a String or a DOM node. If it is a string starting with “&amp;lt;”, it is assumed to be an HTML fragment, which will be created. Otherwise it is assumed to be an id of a DOM node.&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;div class=&#039;foo&#039;&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;, &amp;quot;your_container_element_id&amp;quot; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
pos:&lt;br /&gt;
&lt;br /&gt;
Optional argument. Can be a number or one of the following strings: “before”, “after”, “replace”, “only”, “first”, or “last”. If omitted, “last” is assumed. &lt;br /&gt;
&lt;br /&gt;
&amp;quot;replace&amp;quot;: Replace the container element with my_node element&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; (default): 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;after&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;
positive integer: This parameter can be a positive 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;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     // Replace all children of container with my_node &lt;br /&gt;
     dojo.place( $(&#039;my_node&#039;), &amp;quot;your_container_element_id&amp;quot;, &amp;quot;only&amp;quot; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See also full doc on dojo.place: [https://dojotoolkit.org/reference-guide/1.7/dojo/place.html]&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;
But you can also relocate elements like that. Note: it won&#039;t animate if you do that.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;placeOnObject(mobile_obj: ElementOrId, target_obj: ElementOrId): void&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
places mobile_obj on target_obj, set the absolute positions and centers the mobile_obj on target_obj,&lt;br /&gt;
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;placeOnObjectPos( mobile_obj: ElementOrId, target_obj: ElementOrId, target_x: number, target_y: number ): void&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This method works exactly like placeOnObject, except than you can specify some (x,y) coordinates (in px). This way, the center of &amp;quot;mobile_obj&amp;quot; will be placed to the specified x,y position relatively to the center of &amp;quot;target_obj&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note: the placement works differently from this.slideToObjectPos&#039;&#039;, since coordinates are calculated based on the center of objects.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.attachToNewParent(mobile_obj: ElementOrId, target_obj: ElementOrId): void&#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 without moving it. &lt;br /&gt;
&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;
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;
&#039;&#039;&#039;CAREFUL&#039;&#039;&#039;: 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;
If you need version that does not destroy the object but the same otherwise see [[BGA_Studio_Cookbook#Attach_to_new_parent_without_destroying_the_object]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Animations ==&lt;br /&gt;
&lt;br /&gt;
===Dojo Animations===&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;
Note 2: the slideTo methods are not compatible with CSS transform (scale, zoom, rotate...). If possible, avoid using CSS transform on nodes that are being slided. Eventually, the only possible solution to make these 2 compatible is to disable all CSS transform properties, use slideToObjectPos/placeOnObjectPos, and then apply them again.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Sliding===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;slideToObject(mobile_obj: string | Element, target_obj: string | Element, duration?: number, delay?: number): Animation&#039;&#039;&#039;&lt;br /&gt;
&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;
&lt;br /&gt;
&#039;&#039;&#039;slideToObjectPos(mobile_obj: string | Element, target_obj: string | Element, target_x: number, target_y: number, duration?: number, delay?: number ): Animation&#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 from the top:&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;
&lt;br /&gt;
&#039;&#039;&#039;slideTemporaryObject( mobile_obj_html: string, mobile_obj_parent: string | Element, from: string  | Element, to: string  | Element, duration?: number, delay?: number ): Animation&#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; ).play();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Destroy===&lt;br /&gt;
&#039;&#039;&#039;slideToObjectAndDestroy: function(mobile_obj: string | Element, target_obj: string | Element, duration?: number, delay?: number): void&#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, but it starts the animation. &lt;br /&gt;
&lt;br /&gt;
CAREFUL: Make sure nothing is creating the same object at the same time the animation is running, because this will cause some random disappearing effects&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;
&lt;br /&gt;
&#039;&#039;&#039;fadeOutAndDestroy( node: string | Element, duration?: number, delay?: number):void&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This function fade out the target node, then destroy it. Its starts the animation.&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.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;
Make sure nothing is creating same object at the same time as animation is running, because you will be some random dissapearing effects&lt;br /&gt;
&lt;br /&gt;
===Rotating elements===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This example combines &amp;quot;Dojo.Animation&amp;quot; method and a CSS property transform that allow you to rotate the element.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// node is Element we rotating&lt;br /&gt;
		    var animation = new dojo.Animation({&lt;br /&gt;
			    curve: [fromDegree, toDegree],&lt;br /&gt;
			    onAnimate: (v) =&amp;gt; {&lt;br /&gt;
				    node.style.transform = &#039;rotate(&#039; + v + &#039;deg)&#039;;&lt;br /&gt;
			    } &lt;br /&gt;
		    });&lt;br /&gt;
		    &lt;br /&gt;
		    animation.play();  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
BGA has its own interface to rotate&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;rotateTo(node: string | Element, degree: number): void&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
It starts the animation, and stored the rotation degree in the class, so next time you rotate object - it is additive.&lt;br /&gt;
There is no animation hooks in this one, if you need to change any parameters use dojo animation above.&lt;br /&gt;
&lt;br /&gt;
There is also &#039;&#039;&#039;rotateInstantTo&#039;&#039;&#039; with same signature which does not animate&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Animation Callbacks===&lt;br /&gt;
&lt;br /&gt;
If you wish to run some code only after an animation has completed you can do this by linking a callback method to &#039;onEnd&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
var animation_id = this.slideToObject( mobile_obj, target_obj, 500 );&lt;br /&gt;
dojo.connect(animation_id, &#039;onEnd&#039;, ()-&amp;gt;{&lt;br /&gt;
   // do something here&lt;br /&gt;
});&lt;br /&gt;
animation_id.play();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you wish to call a second animation after the first (rather than general code) then you can use a dojo animation chain (see tutorial referenced above).&lt;br /&gt;
&lt;br /&gt;
== Players input ==&lt;br /&gt;
&lt;br /&gt;
=== Connecting ===&lt;br /&gt;
&#039;&#039;&#039;dojo.connect(element: ElementOrId, event: string, context: object, method: eventHandler): any&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;dojo.connect(element: ElementOrId, event: string, hander: eventHandler): any&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Used to associate a player event with one of your notification methods.&lt;br /&gt;
&lt;br /&gt;
Example: associate a click on an element (&amp;quot;my_element&amp;quot;) with one of our methods (&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;
Same idea but base on query (i.e. all element of &#039;pet&#039; class)&lt;br /&gt;
      dojo.query(&amp;quot;.pet&amp;quot;).connect(&#039;onclick&#039;, this, &#039;onPet&#039;);&lt;br /&gt;
&lt;br /&gt;
Note: if you need to disconnect the handler you have to store handler returned from this method, i.e.&lt;br /&gt;
   &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    var handler = dojo.connect(...);&lt;br /&gt;
    ...&lt;br /&gt;
    dojo.disconnect(handler);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you don&#039;t store the handler - you have to destroy the object to disconnect it&lt;br /&gt;
&lt;br /&gt;
Typical function that implements the input handler will look like this&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
onPet: function(event) {&lt;br /&gt;
    var id = event.currentTarget.id;&lt;br /&gt;
    console.log(&#039;onPet &#039; + id);&lt;br /&gt;
    dojo.stopEvent(event);&lt;br /&gt;
    if (this.gamedatas.gamestate.name == &#039;playerTurnPet&#039;) {&lt;br /&gt;
          this.ajaxcallwrapper(&#039;playPet&#039;, {card: id});&lt;br /&gt;
    } else {&lt;br /&gt;
          this.showMoveUnauthorized();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;connect(element: ElementOrId, event: string, method: eventHandler): void&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Used to associate a player event with one of your notification methods.&lt;br /&gt;
&lt;br /&gt;
      this.connect( $(&#039;my_element&#039;), &#039;onclick&#039;, &#039;onClickOnMyElement&#039; );&lt;br /&gt;
&lt;br /&gt;
Or you can use an in-place handler&lt;br /&gt;
&lt;br /&gt;
      this.connect( $(&#039;my_element&#039;), &#039;onclick&#039;, (e) =&amp;gt; { console.log(&#039;boo&#039;); } );&lt;br /&gt;
&lt;br /&gt;
Note that this function stores the connection handler. That is the only real difference between &#039;&#039;&#039;this.connect&#039;&#039;&#039; and &#039;&#039;&#039;dojo.connect&#039;&#039;&#039;. If you plan to destroy the element you connected, you &#039;&#039;&#039;must&#039;&#039;&#039; call this.disconnect() to prevent memory leaks.&lt;br /&gt;
This function is mainly for permanent objects - if you just want to connect the temp object you should probably not use this method but use dojo.connect which won&#039;t require any clean-up.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;connectClass(cssClassName: string, event: string, method: eventHandler): void&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Same as connect(), but for all the nodes set with the specified cssClassName.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	this.connectClass(&#039;pet&#039;, &#039;onclick&#039;, &#039;onPet&#039;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;disconnect(element: ElementOrId, event: string): void&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Disconnect event handler (previously registered with this.connect or this.connectClass).&lt;br /&gt;
&lt;br /&gt;
   this.disconnect( $(&#039;my_element&#039;), &#039;onclick&#039;);&lt;br /&gt;
&lt;br /&gt;
Note: dynamic connect/disconnect is for advanced cases ONLY, you should always connect elements statically if possible, i.e. in setup() method.&lt;br /&gt;
&lt;br /&gt;
;disconnectAll() &lt;br /&gt;
&lt;br /&gt;
Disconnect all previously registed event handlers (registered via this.connect or this.connectClass)&lt;br /&gt;
&lt;br /&gt;
  this.disconnectAll();&lt;br /&gt;
&lt;br /&gt;
=== Actions ===&lt;br /&gt;
&#039;&#039;&#039;this.ajaxcall(url, parameters, obj_callback, callback, callback_anycase?, ajax_method?: string)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This method must be used to send a player input to the game server. &#039;&#039;&#039;It should not be triggered programmatically&#039;&#039;&#039;, especially not in loops, in callbacks, in notifications, or in onEnteringState/onUpdateActionButtons/onLeavingState, in order not to create race conditions or break replay game and tutorial features. It should be used only in reaction to a user action in the interface.&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. &lt;br /&gt;
** Note that &amp;quot;lock: true&amp;quot; must always be specified in this list of parameters in order the interface can be locked during the server call. Cannot use lock: false - to not lock it has to be undefined.&lt;br /&gt;
** Note: Restricted parameter 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;
* obj_callback: must be set to &amp;quot;this&amp;quot;.&lt;br /&gt;
* callback (non-optional but rarely used): a function to trigger when the server returns result and everything went fine (not used, as all data handling is done via notifications).&lt;br /&gt;
* callback_anycase: (optional) a function to trigger when the server returns ok OR error.  If no error this function is called with parameter value false. If an error occurred, the first parameter will be set to true, the second will contain the error message sent by the PHP back-end, and the third will contain an error code.&lt;br /&gt;
* ajax_method: (optional and rarely used) if you need to send large amounts of data (over 2048 bytes), you can set this parameter to &#039;post&#039; (all lower-case) to send a POST request as opposed to the default GET. This works, but was not officially documented, so only use if you really need to.&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;
}, this, (result)=&amp;gt;{} );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: to reduce the boilerplate code you can define your own wrapper, which will do checking, locking and allow to skip parameters, for example&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ajaxcallwrapper: function(action, args, handler) {&lt;br /&gt;
	if (!args) {&lt;br /&gt;
		args = {};&lt;br /&gt;
	}&lt;br /&gt;
	args.lock = true;&lt;br /&gt;
&lt;br /&gt;
	if (this.checkAction(action)) {&lt;br /&gt;
		this.ajaxcall(&amp;quot;/&amp;quot; + this.game_name + &amp;quot;/&amp;quot; + this.game_name + &amp;quot;/&amp;quot; + action + &amp;quot;.html&amp;quot;, args, this, (result) =&amp;gt; { }, handler);&lt;br /&gt;
	}&lt;br /&gt;
},&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This can be called like this which is a lot more compact&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   this.ajaxcallwrapper(&#039;playDraw&#039;);&lt;br /&gt;
   this.ajaxcallwrapper(&#039;playMove&#039;, {card: id})&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;checkAction(action: string, nomessage?: boolean): boolean &#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Check if player can do the specified action by taking into account:&lt;br /&gt;
* if interface is locked it will return false and show message &amp;quot;An action is already in progress&amp;quot;,  unless nomessage set to true &lt;br /&gt;
* if player is not active it will return false and show message &amp;quot;This is not your turn&amp;quot;, unless nomessage set to true &lt;br /&gt;
* if action is not in list in possible actions (defined by &amp;quot;possibleaction&amp;quot; in current game state) it will return false and show &amp;quot;This move is not authorized now&amp;quot; error (unconditionally).&lt;br /&gt;
* otherwise returns true&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  function onClickOnGameElement( evt )  {&lt;br /&gt;
     if( this.checkAction( &amp;quot;my_action&amp;quot; ) ) {&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;checkPossibleActions(action: string): boolean&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* this is independent of the player being active, so can be used instead of this.checkAction(). This is particularly useful for multiplayer states when the player is not active in a &#039;player may like to change their mind&#039; scenario. Unlike this.checkAction, this function does NOT take interface locking into account &lt;br /&gt;
&lt;br /&gt;
* if action is not in list in possible actions (defined by &amp;quot;possibleaction&amp;quot; in current game state) it will return false and show &amp;quot;This move is not authorized now&amp;quot; error (unconditionally).&lt;br /&gt;
* otherwise returns true&lt;br /&gt;
&lt;br /&gt;
  function onChangeMyMind( evt )  {&lt;br /&gt;
     if( this.checkPossibleActions( &amp;quot;my_action&amp;quot; ) ) {&lt;br /&gt;
        // Do the action&lt;br /&gt;
     }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;checkLock(nomessage?: boolean): boolean&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
When using &amp;quot;lock: true&amp;quot; in ajax call you can use this function to check if interface is in lock state (it will be locked during server call and notification processing).&lt;br /&gt;
This check can be used to block some other interactions which do not result in ajaxcall or if you want to suppress errors. Note: normally you only need to use this.checkAction(...), this is for advanced cases.&lt;br /&gt;
&lt;br /&gt;
It will also show error unless nomessage is set to true&lt;br /&gt;
&lt;br /&gt;
  function onChangeMyMind( evt )  {&lt;br /&gt;
     if( this.checkLock() ) {&lt;br /&gt;
        // Do the action&lt;br /&gt;
     }&lt;br /&gt;
  }&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;
&#039;&#039;&#039;dojo.subscribe(notif_type: string, callback_obj: Object, handler: string|handler)&#039;&#039;&#039;&lt;br /&gt;
* notif_type - notification type/name send by php server&lt;br /&gt;
* callback_obj - usually this&lt;br /&gt;
* handler - if string method of callback_obj with name name is called, when notification is called, with notification object as parameter (see below)&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;
   setupNotifications: function() {&lt;br /&gt;
      ...&lt;br /&gt;
      dojo.subscribe(&#039;playDisc&#039;, this, &amp;quot;notif_playDisc&amp;quot;);&lt;br /&gt;
   },&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;
     // Remove current possible moves (makes the board more clear)&lt;br /&gt;
     dojo.query( &#039;.possibleMove&#039; ).removeClass( &#039;possibleMove&#039; );          &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 all notifications arguments with &amp;quot;notif.args&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
PHP&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    $this-&amp;gt;notifyAllPlayers( &amp;quot;apples&amp;quot;, clienttranslate(&#039;player takes ${count} apples&#039;), [ &amp;quot;count&amp;quot; =&amp;gt; 3 ] );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
JavaScript&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    setupNotifications: function() {&lt;br /&gt;
       dojo.subscribe( &#039;apples&#039;, this, &#039;notif_apples&#039; );&lt;br /&gt;
    },&lt;br /&gt;
&lt;br /&gt;
    notif_apples: function(notif) {&lt;br /&gt;
      //You can access the &amp;quot;count&amp;quot; like this:&lt;br /&gt;
       alert(&amp;quot;count = &amp;quot; + notif.args.count);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The notification Object received by client ===&lt;br /&gt;
&lt;br /&gt;
When sending a notification on your PHP, the client side will receive an Object with the following attributes:&lt;br /&gt;
&lt;br /&gt;
* type - type of the notification (as passed by php function)&lt;br /&gt;
* log - the log string passed from php notification&lt;br /&gt;
* args - This is the arguments that you passed on your notification method on php&lt;br /&gt;
* bIsTableMsg - is true when you use [[Main_game_logic:_yourgamename.game.php#NotifyAllPlayers|NotifyAllPlayers]] method (false otherwise)&lt;br /&gt;
* channelorig - information about table ID (formatted as : &amp;quot;/table/t[TABLE_NUMBER]&amp;quot;)&lt;br /&gt;
* gamenameorig - name of the game&lt;br /&gt;
* move_id - ID of the move associated with the notification&lt;br /&gt;
* table_id - ID of the table (comes as string)&lt;br /&gt;
* time - UNIX GMT timestamp&lt;br /&gt;
* uid - unique identifier of the notification&lt;br /&gt;
* h - unknown&lt;br /&gt;
&lt;br /&gt;
&#039;&#039; Note that those information were inferred from observation on console log. If an Admin can confirm/correct (and remove this line), you&#039;re welcome :)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Ignoring notifications ===&lt;br /&gt;
Sometimes you need to ignore some notification on client side. You don&#039;t want them to be shown in game log and you don&#039;t want them to be handled.&lt;br /&gt;
&lt;br /&gt;
The most common use case is when a player gets private information. They will receive a specific notification (such as &amp;quot;You received Ace of Heart&amp;quot;), while other players would receive more generic notification (&amp;quot;Player received a card&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
In X.game.php&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        $this-&amp;gt;notifyAllPlayers(&amp;quot;dealCard&amp;quot;, clienttranslate(&#039;${player_name} received a card&#039;), [&lt;br /&gt;
            &#039;player_id&#039; =&amp;gt; $playerId,&lt;br /&gt;
            &#039;player_name&#039; =&amp;gt; $this-&amp;gt;getActivePlayerName()&lt;br /&gt;
        ]);&lt;br /&gt;
&lt;br /&gt;
        $this-&amp;gt;notifyPlayer($playerId, &amp;quot;dealCardPrivate&amp;quot;, clienttranslate(&#039;You received ${cardName}&#039;), [&lt;br /&gt;
            &amp;quot;type&amp;quot; =&amp;gt; $card[&amp;quot;type&amp;quot;],&lt;br /&gt;
            &amp;quot;cardName&amp;quot; =&amp;gt; $this-&amp;gt;getCardName($card[&amp;quot;type&amp;quot;])&lt;br /&gt;
        ]);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The problem with this approach is that the active player will receive two notifications:&lt;br /&gt;
* Player1 received a card&lt;br /&gt;
* You received Ace of Hearts&lt;br /&gt;
&lt;br /&gt;
Hence, notification ignoring.&lt;br /&gt;
&lt;br /&gt;
NOTE: You can think that it would be possible to send such notification to all players except active just by using notifyPlayer and it seems to work. The problem however is that table spectators would miss such notification and their user interface (and game log) wouldn&#039;t be updated. Since there is no way to send notification just to spectators, ignoring the notification (or &amp;quot;filtering&amp;quot;) is the only reasonable solution.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;setIgnoreNotificationCheck(notif_type: string, predicate: ((notif: Notif)=&amp;gt;boolean))&#039;&#039;&#039;&lt;br /&gt;
This method will set a check whether any of notifications of specific type should be ignored.&lt;br /&gt;
&lt;br /&gt;
The parameters are:&lt;br /&gt;
* notif_type: type of the notification &lt;br /&gt;
* predicate (notif =&amp;gt; boolean): a function that will receive notif object and will return true if this specific notification should be ignored&lt;br /&gt;
&lt;br /&gt;
Before dispatching any notification of this type, the framework will call predicate to check whether notification should be ignored, if it return true - the notification will be dispatched, i.e. logged or handled.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    this.notifqueue.setIgnoreNotificationCheck( &#039;dealCard&#039;, (notif) =&amp;gt; (notif.args.player_id == this.player_id) );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
IMPORTANT: Remember that this notification is ignored on the client side, but was still received by the client. Therefore it shouldn&#039;t contain any private information as cheaters can get it. In other words this is not a way to hide information.&lt;br /&gt;
&lt;br /&gt;
IMPORTANT: When a game is reloaded with F5 or when opening a turn based game, old notifications are replayed as history notification. They are used just to update the game log and are stripped of all arguments except player_id, i18n and any argument present in message. If you use and other argument in your predicate you should &#039;&#039;&#039;preserve&#039;&#039;&#039; it as explained [[Main_game_logic:_yourgamename.game.php#Notify_players|here]].&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, there 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;
&lt;br /&gt;
It is also possible to control the delay timing dynamically (e.g., using notification args). As an example, maybe your notification &#039;cardPlayed&#039; should pause for a different amount of time depending on the number or type of cards played.&lt;br /&gt;
&lt;br /&gt;
For this case, use &#039;&#039;&#039;setSynchronous&#039;&#039;&#039; without specifying the duration and use &#039;&#039;&#039;setSynchronousDuration&#039;&#039;&#039; within the notification callback.&lt;br /&gt;
&lt;br /&gt;
* NOTE: If you forget to invoke &#039;&#039;&#039;setSynchronousDuration&#039;&#039;&#039;, the game will remain paused forever!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
setupNotifications: function () {&lt;br /&gt;
    dojo.subscribe( &#039;cardPlayed&#039;, this, &#039;notif_cardPlayed&#039; );&lt;br /&gt;
    this.notifqueue.setSynchronous( &#039;cardPlayed&#039; ); // wait time is dynamic&lt;br /&gt;
    ...&lt;br /&gt;
},&lt;br /&gt;
&lt;br /&gt;
notif_cardPlayed: function (notif) {&lt;br /&gt;
    // MUST call setSynchronousDuration&lt;br /&gt;
&lt;br /&gt;
    // Example 1: From notification args (PHP)&lt;br /&gt;
    this.notifqueue.setSynchronousDuration(notif.args.duration);&lt;br /&gt;
    ...&lt;br /&gt;
&lt;br /&gt;
    // Or, example 2: Match the duration to a Dojo animation&lt;br /&gt;
    var anim = dojo.fx.combine([&lt;br /&gt;
        ...&lt;br /&gt;
    ]);&lt;br /&gt;
    anim.play();&lt;br /&gt;
    this.notifqueue.setSynchronousDuration(anim.duration);&lt;br /&gt;
},&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;WARNING: combining synchronous and ignored notifications&#039;&#039;&#039;&lt;br /&gt;
You must be careful when combining dynamic synchronous durations (as described above) with ignored notifications. If you have a conditionally ignored notification like this (see below section):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;this.notifqueue.setIgnoreNotificationCheck( &#039;myNotif&#039;, (notif) =&amp;gt; (notif.args.player_id == this.player_id) /* or any other condition */ )&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
then you CANNOT do&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;this.notifqueue.setSynchronous(&#039;myNotif&#039;);&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
as, when the ignored check passes, the notification handler, in which `this.notifqueue.setSychronousDuration` is called, is never called and so the duration is never set and interface locking results.&lt;br /&gt;
&lt;br /&gt;
The workaround is to set a &amp;quot;dummy&amp;quot; time:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;this.notifqueue.setSynchronous(&#039;myNotif&#039;, 5000);&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
whose value is irrelevant but must be large enough to cover the time before the notification handler is called. The large value never actually comes into play because the notification is either ignored, or the synchronous duration is reset to a sensible value inside the handler.&lt;br /&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 (technically any unhandled notification will do the same but its recommended to use this keyword for consistency)&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;, clienttranslate(&#039;hello&#039;), [] );&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;simplePause&#039;&#039;&#039; - This notification will just delay other notifications, maybe useful if you know you need some extra time for animation or something. Requires a time parameter.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    self::notifyAllPlayers( &#039;simplePause&#039;, &#039;&#039;, [ &#039;time&#039; =&amp;gt; 500] ); // time is in milliseconds&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: the following types are RESERVED by framework, do not use:&lt;br /&gt;
&lt;br /&gt;
gameStateChange gameStateChangePrivateArg gameStateMultipleActiveUpdate newActivePlayer playerstatus yourturnack clockalert tableInfosChanged playerEliminated tableDecision  archivewaitingdelay end_archivewaitingdelay replaywaitingdelay end_replaywaitingdelay replayinitialwaitingdelay end_replayinitialwaitingdelay aiPlayerWaitingDelay replay_has_ended updateSpectatorList  wouldlikethink updateReflexionTime undoRestorePoint resetInterfaceWithAllDatas zombieModeFail zombieModeFailWarning aiError skipTurnOfPlayer zombieBack allPlayersAreZombie gameResultNeutralized playerConcedeGame showTutorial showCursor showCursorClick skipTurnOfPlayerWarning  banFromTable resultsAvailable switchToTurnbased newPrivateState infomsg&lt;br /&gt;
&lt;br /&gt;
== Tooltips ==&lt;br /&gt;
=== Adding static tooltips ===&lt;br /&gt;
&#039;&#039;&#039;addTooltip( nodeId:string, helpStringTranslated: string, actionStringTranslated:string, delay?:number):void&#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;helpStringTranslated&#039; to display some information about &amp;quot;what is this game element?&amp;quot;.&lt;br /&gt;
Specify &#039;actionStringTranslated&#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 of the strings. You can only use one and specify an empty string (&#039;&#039;) for the other one.&lt;br /&gt;
&lt;br /&gt;
When you pass text directly function _() must be used for the text to be marked for translation! Except for empty string.&lt;br /&gt;
&lt;br /&gt;
Parameter &amp;quot;delay&amp;quot; is optional. 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 browsers (see [[BGA_Studio_Guidelines|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;
Note: this generates static tooltip and attaches to existing dom element, if you need to generate tooltip more dynamically you have to call that method every time information about object is updated or use completely different tehnique, see dynamic tooltips below.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;addTooltipHtml( nodeId: string, html: string, delay?:number ):void&#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;addTooltipToClass(cssClass: string, helpStringTranslated: string, actionStringTranslated: string, delay?:number ):void;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Add a simple text tooltip to all the DOM nodes set with this cssClass. See more details above for this.addTooltip.&lt;br /&gt;
     this.addTooltipToClass( &#039;meeple&#039;, _(&#039;This is A Meeple&#039;), _(&#039;Click to tickle&#039;) );&lt;br /&gt;
&lt;br /&gt;
IMPORTANT: all concerned nodes must exist and have IDs to get tooltips.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;addTooltipHtmlToClass(cssClass: string, html: string, delay?:number ):void)&#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 exist and have IDs to get tooltips.&lt;br /&gt;
&lt;br /&gt;
=== Removing static tooltips ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;removeTooltip( nodeId: string ):void&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Remove a tooltip from the DOM node with given id.&lt;br /&gt;
&lt;br /&gt;
=== Advanced tooltips ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;force tooltip to open&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
If you want to force tooltip to open in reaction to some other action, i.e. click you can do this&lt;br /&gt;
&lt;br /&gt;
   this.tooltips[id].open(id)&lt;br /&gt;
&lt;br /&gt;
where id is the id of the tooltip node where tooltip was installed.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;dynamic tooltips&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
See [[BGA_Studio_Cookbook#Dynamic_tooltips]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;tooltips on mobile&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Tooltips is very unreliable on mobile, it is recommended to implement some other method to obtaining same information,&lt;br /&gt;
such as simple click handler in dedicated &amp;quot;Help&amp;quot; mode or provide dedicated clickable areas such as corner of card.&lt;br /&gt;
&lt;br /&gt;
== Warning messages ==&lt;br /&gt;
&lt;br /&gt;
Sometimes, there is something important that is happening in 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 fulfills one of the end of the game conditions, so this is the last turn.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;showMessage(msg: string, type: string): void&#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 the current player, and it dissapears after few seconds (also it will be in the log in some cases).&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;, &amp;quot;error&amp;quot;, &amp;quot;only_to_log&amp;quot; or custom string. 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 and it will be added to log. If set to &amp;quot;only_to_log&amp;quot;, the message will be added to the game log but will not popup at the top of the screen.&lt;br /&gt;
If set to custom string, it will be transparent, to use custom type define &amp;quot;head_xxx&amp;quot; in css, where xxx is the type. For example if you want yellow warning, use &amp;quot;warning&amp;quot; as type and add this to css:&lt;br /&gt;
 .head_warning {&lt;br /&gt;
    background-color: #e6c66e;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Important: the normal way to inform players about the progression of the game is the game log. The &amp;quot;showMessage&amp;quot; is intrusive and should not be used often.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    notif_messageinfo: function(notif) {&lt;br /&gt;
	if (!g_archive_mode) {&lt;br /&gt;
        	var message = this.format_string_recursive(notif.log, notif.args);&lt;br /&gt;
		this.showMessage(_(&#039;Announcement:&#039;) + &amp;quot; &amp;quot; + message, &#039;info&#039;);		&lt;br /&gt;
         }&lt;br /&gt;
    },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Show message could be used on the client side to prevent user wrong moves before it is send to server.&lt;br /&gt;
Example from &#039;battleship&#039;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
onGrid: function(event) {&lt;br /&gt;
     if (checkIfPlayerTriesToFireOnThemselves(event)) {&lt;br /&gt;
        this.showMessage(_(&#039;This is your own board silly!&#039;), &#039;error&#039;);&lt;br /&gt;
        return;&lt;br /&gt;
     }&lt;br /&gt;
     ...&lt;br /&gt;
},&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;showMoveUnauthorized(): void&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Shows predefined user error that move is unauthorized now&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
onPet: function(event) {&lt;br /&gt;
     if (checkPet(event)==false) {&lt;br /&gt;
        this.showMoveUnauthorized();&lt;br /&gt;
        return;&lt;br /&gt;
     }&lt;br /&gt;
     ...&lt;br /&gt;
},&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Dialogs ==&lt;br /&gt;
&lt;br /&gt;
=== Confirmation dialog ===&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 guideline of BGA is to AVOID the use of confirmation dialogs. Confirmation dialogs slow down the game and bother players. The players know that they have to pay attention to each move when they are playing online.&lt;br /&gt;
&lt;br /&gt;
The situations 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 does 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;
&#039;&#039;&#039;confirmationDialog(message:string, yesHandler:(param:any)=&amp;gt;void, noHandler?:(param:any)=&amp;gt;void, param?: any): void&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* message - message will be shown to user, use _() to translate&lt;br /&gt;
* yesHandler - non-optional handler to be called on yes&lt;br /&gt;
* noHandler - optional handler to called on no&lt;br /&gt;
* param - if specified, it will be passed to both handlers&lt;br /&gt;
NOTE: this is async function, it does not return anything and you should not do anything after, you must do everything in handlers&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(_(&amp;quot;Are you sure you want to bake the pie?&amp;quot;), () =&amp;gt; {&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;
&lt;br /&gt;
You can use this dialog to give user a choice with small amount of options&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;multipleChoiceDialog(message: string, choices: string[], callback: (choice: number)=&amp;gt;void): void&#039;&#039;&#039;&lt;br /&gt;
* message - message will be shown to user, use _() to translate&lt;br /&gt;
* choices - array of choices&lt;br /&gt;
* callback - non-optional handler to be called on choice made, the choice parameter is the INDEX of the choice from the array of choices&lt;br /&gt;
&lt;br /&gt;
NOTE: this is async function, it does not return anything and you should not do anything after, you must do everything in handlers&lt;br /&gt;
NOTE: there is no cancel handler, so make sure you gave user a choice to get out of it&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    const keys = [&amp;quot;0&amp;quot;, &amp;quot;1&amp;quot;, &amp;quot;5&amp;quot;, &amp;quot;10&amp;quot;];&lt;br /&gt;
    this.multipleChoiceDialog(_(&amp;quot;How many bugs to fix?&amp;quot;), keys, (choice) =&amp;gt; {&lt;br /&gt;
      if (choice==0) return; // cancel operation, do not call server action&lt;br /&gt;
      var bugchoice = keys[choice]; // choice will be 0,1,2,3 here&lt;br /&gt;
      this.ajaxcallwrapper(&amp;quot;fixBugs&amp;quot;, { number: bugchoice });&lt;br /&gt;
    });&lt;br /&gt;
    return; // must return here&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Generic Dialogs ===&lt;br /&gt;
&lt;br /&gt;
As a general rule, 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;
  // Create the new dialog over the play zone. You should store the handler in a member variable to access it later&lt;br /&gt;
  this.myDlg = new ebg.popindialog();&lt;br /&gt;
  this.myDlg.create( &#039;myDialogUniqueId&#039; );&lt;br /&gt;
  this.myDlg.setTitle( _(&amp;quot;my dialog title to translate&amp;quot;) );&lt;br /&gt;
  this.myDlg.setMaxWidth( 500 ); // Optional&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.setContent( html ); // Must be set before calling show() so that the size of the content is defined before positioning the dialog&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, if you have an &amp;quot;OK&amp;quot; button in the HTML of your dialog:&lt;br /&gt;
  dojo.connect($(&#039;my_ok_button&#039;), &#039;onclick&#039;, this, (event) =&amp;gt; {&lt;br /&gt;
                event.preventDefault();&lt;br /&gt;
                this.myDlg.destroy();&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
If necessary, you can remove the default top right corner &#039;close&#039; icon, or replace the function called when it is clicked:&lt;br /&gt;
  // Removes the default close icon&lt;br /&gt;
  this.myDlg.hideCloseIcon();&lt;br /&gt;
&lt;br /&gt;
  // Replace the function call when it&#039;s clicked&lt;br /&gt;
  this.myDlg.replaceCloseCallback((event) =&amp;gt; { ... });&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 describes 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 = [&lt;br /&gt;
      [ &amp;quot;one&amp;quot;, &amp;quot;two&amp;quot;, &amp;quot;three&amp;quot; ],    // This is my first line&lt;br /&gt;
      [ &amp;quot;four&amp;quot;, &amp;quot;five&amp;quot;, &amp;quot;six&amp;quot; ],    // This is my second line&lt;br /&gt;
      [ &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 = [&lt;br /&gt;
      [ &amp;quot;one&amp;quot;, &amp;quot;two&amp;quot;, [ &amp;quot;str&amp;quot; =&amp;gt; clienttranslate(&amp;quot;a string with an ${argument}&amp;quot;), &amp;quot;args&amp;quot; =&amp;gt; [ &#039;argument&#039; =&amp;gt; &#039;argument_value&#039; ] ] ],&lt;br /&gt;
      [ &amp;quot;four&amp;quot;, &amp;quot;five&amp;quot;, &amp;quot;six&amp;quot; ], &lt;br /&gt;
      [ &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 = [ &#039;&#039; ];&lt;br /&gt;
        foreach( $players as $player_id =&amp;gt; $player )    {&lt;br /&gt;
            $cell = [ &#039;str&#039; =&amp;gt; &#039;${player_name}&#039;,&lt;br /&gt;
                      &#039;args&#039; =&amp;gt; [ &#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;
            $firstRow[] = $cell;&lt;br /&gt;
        }&lt;br /&gt;
        $table[] = $firstRow;&lt;br /&gt;
        ...&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;
* &#039;&#039;&#039;header&#039;&#039;&#039;: the content for this parameter displays 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 displays 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;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   $this-&amp;gt;notifyAllPlayers( &amp;quot;tableWindow&amp;quot;, &#039;&#039;, [&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; [&#039;str&#039; =&amp;gt; clienttranslate(&#039;Table header with parameter ${number}&#039;),&lt;br /&gt;
                                 &#039;args&#039; =&amp;gt; [ &#039;number&#039; =&amp;gt; 3 ],&lt;br /&gt;
                               ],&lt;br /&gt;
            &amp;quot;footer&amp;quot; =&amp;gt; &#039;&amp;lt;div class=&amp;quot;myfoot&amp;quot;&amp;gt;&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;
Note: currently id is not used - so you cannot access resulting div by id on js side&lt;br /&gt;
Note: any traslatable stirng have to be wrapped by clienttranslate() on top level OR it has to be recursive template. &lt;br /&gt;
&lt;br /&gt;
DO NOT DO THIS: &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   &amp;quot;footer&amp;quot; =&amp;gt; &#039;&amp;lt;div&amp;gt;&#039;.clienttranslate( &amp;quot;The end&amp;quot; ).&#039;&amp;lt;/div&amp;gt;&#039;, // this will not work for translations!!!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Scoring animated display ===&lt;br /&gt;
&lt;br /&gt;
Sometimes, you may want to display a score value over an element to make the scoring easier to follow for the players (Terra Mystica final scoring for example).&lt;br /&gt;
You can do it with:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;displayScoring(anchor_id:string, color:string, score:number|string, duration?:number, offset_x?:number, offset_y?: number): void&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;anchor_id&#039;&#039;&#039;: ID of the html element to place the animated score onto (without the &#039;#&#039;) &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;color&#039;&#039;&#039;: hexadecimal RGB representation of the color (should be the color of the scoring player), but without a leading &#039;#&#039;.  For instance, &#039;ff0000&#039; for red.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;score&#039;&#039;&#039;: numeric score to display, prefixed by a &#039;+&#039; or &#039;-&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;duration&#039;&#039;&#039;: animation duration in milliseconds (optional, default is 1000)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;offset_x&#039;&#039;&#039; and &#039;&#039;&#039;offset_y&#039;&#039;&#039;: if both offset_x and offset_y are defined and not null, apply the following offset (in pixels) to the scoring animation. &lt;br /&gt;
Note that the score is centered in the anchor, so the offsets might have to be negative if you calculate the position.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note: if you want to display successively each score, you can use &#039;&#039;this.notifqueue.setSynchronous()&#039;&#039; function.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    setupNotifications: function()   {&lt;br /&gt;
           dojo.subscribe( &#039;displayScoring&#039;, this, &amp;quot;notif_displayScoring&amp;quot; );&lt;br /&gt;
           ...&lt;br /&gt;
    }&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
    notif_displayScoring: function(notif) {&lt;br /&gt;
            const duration = notif.args.duration?notif.args.duration:1000;&lt;br /&gt;
            this.notifqueue.setSynchronous(&#039;displayScoring&#039;, duration );&lt;br /&gt;
	    this.displayScoring( notif.args.target, notif.args.color, notif.args.score, duration);&lt;br /&gt;
    },&lt;br /&gt;
&amp;lt;/pre&amp;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 showBubble:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;showBubble(anchor_id: string, text: string, delay?: number, duration?: number, custom_class?: string): void&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* anchor_id - where to attach the bubble&lt;br /&gt;
* text - what to put in bubble, can be html&lt;br /&gt;
* delay - delay in milliseconds (optional, default 0)&lt;br /&gt;
* duration -  duration of animation in milliseconds (optional, default 3000)&lt;br /&gt;
* custom_class - extra class to add to bubble (optional), if you need to override the default bubble style&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   this.showBubble(&#039;meeple_2&#039;, _(&#039;Hello&#039;), 0, 1000, &#039;pink_bubble&#039;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  notif_speechBubble(notif) {&lt;br /&gt;
    var html = this.format_string_recursive(notif.args.text, notif.args.args);&lt;br /&gt;
    this.showBubble(notif.args.target, html, notif.args.delay ?? 0, notif.args.duration ?? 1000);&lt;br /&gt;
  },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Warning&#039;&#039;&#039;: if your bubble could overlap other active elements of the interface (buttons in particular), as it stays in place even after disappearing, you should use a custom class to give it the style &amp;quot;pointer-events: none;&amp;quot; in order to intercept click events.&lt;br /&gt;
&lt;br /&gt;
Note: If you want this visually, but want to take complete control over this bubble and its animation (for example to make it permanent) you can just use div with &#039;discussion_bubble&#039; class on it, and content of div is what will be shown.&lt;br /&gt;
&lt;br /&gt;
== Translations ==&lt;br /&gt;
&lt;br /&gt;
See [[Translations]]&lt;br /&gt;
&lt;br /&gt;
== Players panels ==&lt;br /&gt;
&lt;br /&gt;
=== Update players score ===&lt;br /&gt;
&lt;br /&gt;
The column player_score from the player table is automatically loaded into this.scoreCtrl and therefore into the stars location on the player board. This occurs sometime after the game setup() function. However this score must be updated as the game progresses using notifications.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note: this.scoreCtrl[player_id] is object of class [[Counter]], you can use other counter API.&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;
Set a player score to a specific value with animation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  this.scoreCtrl[ player_id ].toValue( new_score );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Typical usage would be (that will process &#039;score&#039; notification):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        setupNotifications : function() {&lt;br /&gt;
              ...&lt;br /&gt;
             dojo.subscribe(&#039;score&#039;, this, &amp;quot;notif_score&amp;quot;);&lt;br /&gt;
        },&lt;br /&gt;
        notif_score: function(notif) {&lt;br /&gt;
            this.scoreCtrl[notif.args.player_id].setValue(notif.args.player_score);&lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&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;disablePlayerPanel(player_id: number):void&#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;enablePlayerPanel(player_id:number):void&#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;enableAllPlayerPanels():void&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Enable all player panels that has been disabled before.&lt;br /&gt;
&lt;br /&gt;
=== Player order ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;updatePlayerOrdering():void&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This function makes sure that player order in player&#039;s panel matches this.gamedatas.playerorder and its normally called by framework.&lt;br /&gt;
You can call it yoursel if you change this.gamedatas.playerorder from notification.&lt;br /&gt;
Also you can override this function to change defaults  OR insert a non-player panel [[BGA_Studio_Cookbook#Inserting_non-player_panel]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Counters ===&lt;br /&gt;
Note: there is bga component called  &amp;quot;ebg/counter&amp;quot; this API is not using it, these methods&lt;br /&gt;
below declared right in core game. If you need animation for counters use ebg/counter&lt;br /&gt;
&lt;br /&gt;
To use this API just create a counter dom element like this (class does not really matter)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 &amp;lt;div class=&amp;quot;counter&amp;quot; id=&amp;quot;bread&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
 &amp;lt;div class=&amp;quot;counter&amp;quot; id=&amp;quot;coin&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The &amp;quot;bread&amp;quot; will the counter name.&lt;br /&gt;
&lt;br /&gt;
The php code should send all &amp;quot;counters&amp;quot; data from getAllDatas() method like this&lt;br /&gt;
&lt;br /&gt;
game.php&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  protected function getAllDatas() {&lt;br /&gt;
    // (the key must match counter_name)&lt;br /&gt;
    $result[&#039;counters&#039;]=[&lt;br /&gt;
        &#039;bread&#039; =&amp;gt; [ &lt;br /&gt;
         &#039;counter_name&#039; =&amp;gt; &#039;bread&#039;, &lt;br /&gt;
         &#039;counter_value&#039; =&amp;gt; 3&lt;br /&gt;
         ], &lt;br /&gt;
        &#039;coin&#039; =&amp;gt; [&lt;br /&gt;
          &#039;counter_name&#039; =&amp;gt; &#039;coin&#039;, &lt;br /&gt;
          &#039;counter_value&#039; =&amp;gt; 5&lt;br /&gt;
        ]&lt;br /&gt;
   ];&lt;br /&gt;
   return $result;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;setCounter(counter_name:stirng, new_value: string | number): void&lt;br /&gt;
&lt;br /&gt;
updates the global this.gamedatas.counters and value of node $(counter_name)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  notif_counter: function(notif) { &lt;br /&gt;
    this.setCounter(notif.args.counter_name, notif.args.counter_value);&lt;br /&gt;
  },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;incCounter(counter_name:string, delta: number): void&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  notif_counter : function(notif) {&lt;br /&gt;
    this.incCounter(notif.args.counter_name, notif.args.inc);&lt;br /&gt;
  },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;updateCounters(counters: object): void&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Useful for updating game counters in the player panel (such as resources). &lt;br /&gt;
&#039;counters&#039; arg is map of counters (the key must match counter_name)&lt;br /&gt;
  {&lt;br /&gt;
    &#039;bread&#039;: { &lt;br /&gt;
         &#039;counter_name&#039; : &#039;bread&#039;, &lt;br /&gt;
         &#039;counter_value&#039; =&amp;gt; 3&lt;br /&gt;
    }, &lt;br /&gt;
    &#039;coin&#039;: { &lt;br /&gt;
         &#039;counter_name&#039; : &#039;coin&#039;, &lt;br /&gt;
         &#039;counter_value&#039; =&amp;gt; 5&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
All counters MUST be referenced in this.gamedatas.counters (means they should be send from php) 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;
Usually you call this from notification&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                        notif_counter : function(notif) {&lt;br /&gt;
                            this.updateCounters(notif.args.counters);&lt;br /&gt;
                        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&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;br /&gt;
&lt;br /&gt;
== BGA Buttons ==&lt;br /&gt;
&lt;br /&gt;
=== Basic Button ===&lt;br /&gt;
&#039;&#039;&#039;addActionButton( id: string, label: string, method: string | eventhandler, destination?: string, blinking?: boolean, color?:string): void&#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 (or other places).&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). Note: this can also be any html, such as &amp;quot;&amp;lt;div class=&#039;brick&#039;&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;, see example below on how to make image action buttons.&lt;br /&gt;
* method: the name of your method that must be triggered when the player clicks on this button (can be name of the method on game class or handler).&lt;br /&gt;
* destination (optional): id of parent on where to add button, ONLY use in rare cases if location is not action bar. 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 DO NOT abuse blinking button. If you need button to blink after some time passed add class &#039;blinking&#039; to the button later.&lt;br /&gt;
* color: could be &#039;&#039;&#039;blue&#039;&#039;&#039; (default), &#039;&#039;&#039;red&#039;&#039;&#039;,&#039;&#039;&#039;gray&#039;&#039;&#039; or &#039;&#039;&#039;none&#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:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        onUpdateActionButtons: function( stateName, args ) {                      &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;
                    this.addActionButton( &#039;pass_button&#039;, _(&#039;Pass&#039;), ()=&amp;gt;this.ajaxcallwrapper(&#039;pass&#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;button_confirm&#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;
If you want to call the handled with arguments, you can use arrow functions, like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     this.addActionButton( &#039;commit_button&#039;, _(&#039;Confirm&#039;), () =&amp;gt; this.onConfirm(this.selectedCardId), null, false, &#039;red&#039;); &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Image Button ===&lt;br /&gt;
&lt;br /&gt;
You can use the same method, but add extra class to a button to disable the padding and style it, i.e.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
this.addActionButton( &#039;button_brick&#039;, &#039;&amp;lt;div class=&amp;quot;brick&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;, ()=&amp;gt;{... on brick ...}, null, null, &#039;gray&#039;); &lt;br /&gt;
dojo.addClass(&#039;button_brick&#039;,&#039;bgaimagebutton&#039;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.bgaimagebutton {&lt;br /&gt;
  padding: 0px 12px;&lt;br /&gt;
  min-height: 28px;&lt;br /&gt;
  border: none;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you use this a lot, you can define a helper function, i.e.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * This method can be used instead of addActionButton, to add a button which is an image (i.e. resource). Can be useful when player&lt;br /&gt;
 * need to make a choice of resources or tokens.&lt;br /&gt;
 */&lt;br /&gt;
addImageActionButton: function(id, div, handler, bcolor, tooltip) {&lt;br /&gt;
	if (typeof bcolor == &amp;quot;undefined&amp;quot;) {&lt;br /&gt;
		bcolor = &amp;quot;gray&amp;quot;;&lt;br /&gt;
	}&lt;br /&gt;
	// this will actually make a transparent button id color = gray&lt;br /&gt;
	this.addActionButton(id, div, handler, null, false, bcolor);&lt;br /&gt;
	// remove border, for images it better without&lt;br /&gt;
	dojo.style(id, &amp;quot;border&amp;quot;, &amp;quot;none&amp;quot;);&lt;br /&gt;
	// but add shadow style (box-shadow, see css)&lt;br /&gt;
	dojo.addClass(id, &amp;quot;shadow bgaimagebutton&amp;quot;);&lt;br /&gt;
	// you can also add additional styles, such as background&lt;br /&gt;
	if (tooltip) {&lt;br /&gt;
		dojo.attr(id, &amp;quot;title&amp;quot;, tooltip);&lt;br /&gt;
	}&lt;br /&gt;
	return $(id);&lt;br /&gt;
},&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Disabling Button ===&lt;br /&gt;
&lt;br /&gt;
You can disable the &#039;&#039;&#039;bgabutton&#039;&#039;&#039; by adding the css class &#039;&#039;&#039;disabled&#039;&#039;&#039; in you js. The disabled button is still visible but is grey and not clickable.&lt;br /&gt;
For example in the &#039;&#039;&#039;onUpdateActionButtons&#039;&#039;&#039; : &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
this.addActionButton(&#039;play_button_id&#039;, _(&#039;Play 1 to 3 cards&#039;), &#039;playFunctionButton&#039;); &lt;br /&gt;
if (condition) {&lt;br /&gt;
  dojo.addClass(&#039;play_button_id&#039;, &#039;disabled&#039;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Custom Buttons ===&lt;br /&gt;
&lt;br /&gt;
You can create a custom button, but the BGA framework provides a standard button that requires only .css classes: &#039;&#039;&#039;bgabutton&#039;&#039;&#039; and &#039;&#039;&#039;bgabutton_${color}&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Examples:&#039;&#039;&#039;&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;
&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;
&#039;&#039;&#039;Note&#039;&#039;&#039;: To see it in action, check out &#039;&#039;Coloretto&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Button outside of action bar ===&lt;br /&gt;
&lt;br /&gt;
Use addActionButton() method with destination argument set&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
this.addActionButton( &#039;commit_button&#039;, _(&#039;Confirm&#039;), &#039;onConfirm&#039;, &#039;player_board&#039;, true, &#039;red&#039;); &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
in example above the button will be place on object with id &#039;player_board&#039;&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: string)&#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;
&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;
&#039;&#039;&#039;ensureSpecificGameImageLoading(list: string[])&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This is oppostive of dontPreloadImage - its ensure specific images is loaded. Note: only makes sense if preload list is empty, otherwise everything is loaded anyway&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;load specific images&#039;&#039;&#039;&lt;br /&gt;
All images that will be preloaded stored in g_img_preload. If you want to override it directly - there is no API, but you can do this in GAME constructor&lt;br /&gt;
&lt;br /&gt;
          g_img_preload = [&#039;tokens.png&#039;, &#039;trains.png&#039;, &#039;loc_plan.png&#039;, &#039;eng.png&#039;, &#039;eng-back.png&#039;];&lt;br /&gt;
&lt;br /&gt;
You can also set it to empty array and call ensureSpecificGameImageLoading() on specific images&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Sounds ==&lt;br /&gt;
&lt;br /&gt;
Add a custom sound and make it load with your interface:&lt;br /&gt;
&lt;br /&gt;
Add this in your template (.tpl) file:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;audio id=&amp;quot;audiosrc_&amp;lt;gamename&amp;gt;_&amp;lt;yoursoundname&amp;gt;&amp;quot; src=&amp;quot;{GAMETHEMEURL}img/&amp;lt;gamename&amp;gt;_&amp;lt;yoursoundname&amp;gt;.mp3&amp;quot; preload=&amp;quot;none&amp;quot; autobuffer&amp;gt;&amp;lt;/audio&amp;gt;&lt;br /&gt;
&amp;lt;audio id=&amp;quot;audiosrc_o_&amp;lt;gamename&amp;gt;_&amp;lt;yoursoundname&amp;gt;&amp;quot; src=&amp;quot;{GAMETHEMEURL}img/&amp;lt;gamename&amp;gt;_&amp;lt;yoursoundname&amp;gt;.ogg&amp;quot; preload=&amp;quot;none&amp;quot; autobuffer&amp;gt;&amp;lt;/audio&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: this is a requirement to provide both a mp3 and a ogg file with the names &amp;lt;code&amp;gt;&amp;lt;gamename&amp;gt;_&amp;lt;yoursoundname&amp;gt;[.ogg][.mp3]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Play the sound (from your .js file):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
playSound(&#039;&amp;lt;gamename&amp;gt;_&amp;lt;yoursoundname&amp;gt;&#039;);   // do not add &#039;this.&#039; - its a global function&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Disable the standard &amp;quot;move&amp;quot; sound for this move (to replace it with your custom sound):&lt;br /&gt;
&lt;br /&gt;
Add this to your notification handler:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
this.disableNextMoveSound();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: it only disable the sound for the next move.&lt;br /&gt;
&lt;br /&gt;
== Title bar and states ==&lt;br /&gt;
&lt;br /&gt;
=== Client states ===&lt;br /&gt;
&lt;br /&gt;
Client states is a way to simulate the state transition but without actually going&lt;br /&gt;
to server. It is usefull when you need to ask user multiple questions before you&lt;br /&gt;
send things to server&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;setClientState(newState: string, args: object)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
     this.setClientState(&amp;quot;client_playerPicksLocation&amp;quot;, {&lt;br /&gt;
                               descriptionmyturn : _(&amp;quot;${you} must select location&amp;quot;),&lt;br /&gt;
                           });&lt;br /&gt;
&lt;br /&gt;
For more information see [[BGA_Studio_Cookbook#Multi_Step_Interactions:_Select_Worker.2FPlace_Worker_-_Using_Client_States]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;restoreServerGameState()&#039;&#039;&#039;&lt;br /&gt;
If you are in client state it will restore the current server state (cheap undo)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.on_client_state&#039;&#039;&#039;&lt;br /&gt;
Boolean indicating that we are in client state&lt;br /&gt;
&lt;br /&gt;
=== Title bar ===&lt;br /&gt;
If you simply want to show something in title bar you can do it directly &lt;br /&gt;
     $(&#039;pagemaintitletext&#039;).innerHTML = text;&lt;br /&gt;
&lt;br /&gt;
This however will not work with parameters and will not draw You in color,&lt;br /&gt;
if you want to do proper args rendering use method below&lt;br /&gt;
&lt;br /&gt;
;&#039;&#039;&#039;removeActionButtons()&#039;&#039;&#039;&lt;br /&gt;
Removes all buttons from title bar&lt;br /&gt;
&lt;br /&gt;
;&#039;&#039;&#039;updatePageTitle()&#039;&#039;&#039;&lt;br /&gt;
:This function allows to update the current page title and turn description according to the game state arguments. If the current game state description this.gamedatas.gamestate.descriptionmyturn is modified before calling this function it allows to update the turn description without changing state. This will handle arguments substitutions properly.&lt;br /&gt;
&lt;br /&gt;
Note: this functional also will calls this.onUpdateActionButtons, if you want different buttons then state defaults, use method in example to replace them, if it becomes too clumsy use client states (see above)&lt;br /&gt;
&lt;br /&gt;
Example from Terra Mystica:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
onClickFavorTile: function( evt ) {&lt;br /&gt;
    ...&lt;br /&gt;
    if ( ... ) {&lt;br /&gt;
        this.gamedatas.gamestate.descriptionmyturn = _(&#039;Special action: &#039;) + _(&#039;Advance 1 space	on a Cult track&#039;);&lt;br /&gt;
        this.updatePageTitle();&lt;br /&gt;
        this.removeActionButtons();&lt;br /&gt;
        this.addActionButton( ... );&lt;br /&gt;
         ...&lt;br /&gt;
        return;&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;
== 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 ensure that the &amp;quot;this&amp;quot; object will be set when the callback is called.&lt;br /&gt;
&lt;br /&gt;
NOTE: In modern JS there are lambdas that eliminate need for that, the example above will look like this&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        this.confirmationDialog( _(&#039;Are you sure you want to make this?&#039;), () =&amp;gt; {&lt;br /&gt;
            this.ajaxcall( &#039;/mygame/mygame/makeThis.html&#039;, { lock:true }, this, (result) =&amp;gt; {} );&lt;br /&gt;
        } );   &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
;&#039;&#039;&#039;onScreenWidthChange()&#039;&#039;&#039;&lt;br /&gt;
:This function can be overridden in your game to manage some resizing on the client side when the browser window is resized. This function is also triggered at load time, so it can be used to adapt to the :viewport size at the start of the game too.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; this.bRealtime&lt;br /&gt;
: Return true if the game is in realtime. Note that having a distinct behavior in realtime and turn-based should be exceptional.&lt;br /&gt;
&lt;br /&gt;
; g_replayFrom&lt;br /&gt;
: Global contains reply number in live game, it is set to undefined (i.e. not set) when it is not a reply mode, so consequentially the good check is &#039;&#039;&#039;typeof g_replayFrom != &#039;undefined&#039;&#039;&#039;&#039; which returns true if the game is in replay mode &amp;lt;i&amp;gt;during the game&amp;lt;/i&amp;gt; (the game is ongoing but the user clicked &amp;quot;reply from this move&amp;quot; in the log)&lt;br /&gt;
&lt;br /&gt;
; g_archive_mode&lt;br /&gt;
: Returns true if the game is in archive mode &amp;lt;i&amp;gt;after the game&amp;lt;/i&amp;gt; (the game has ended)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; this.instantaneousMode&lt;br /&gt;
: Returns true during replay/archive mode if animations should be skipped. Only needed if you are doing custom animations. (The BGA-provided animation functions like &amp;lt;i&amp;gt;this.slideToObject()&amp;lt;/i&amp;gt; automatically handle instantaneous mode.)&lt;br /&gt;
: Technically, when you click &amp;quot;replay from move #20&amp;quot;, the system replays the game from the very beginning with moves 0 - 19 happening in instantaneous mode and moves 20+ happening in normal mode.&lt;br /&gt;
&lt;br /&gt;
; g_tutorialwritten&lt;br /&gt;
: Returns an object like the below if the game is in tutorial mode, or undefined otherwise. Tutorial mode is a special case of archive mode where comments have been added to a previous game to teach new players the rules.&lt;br /&gt;
    {&lt;br /&gt;
        author: &amp;quot;91577332&amp;quot;,&lt;br /&gt;
        id: &amp;quot;576&amp;quot;,&lt;br /&gt;
        mode: &amp;quot;view&amp;quot;&lt;br /&gt;
        status: &amp;quot;alpha&amp;quot;&lt;br /&gt;
        version_override: null&lt;br /&gt;
        viewer_id: &amp;quot;84554161&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;getBgaEnvironment(): string&#039;&#039;&#039;&lt;br /&gt;
: Returns &amp;quot;studio&amp;quot; for studio and &amp;quot;prod&amp;quot; for production environment (i.e. where games current runs). Only useful for debbugging hooks.&lt;br /&gt;
Note: alpha server is also &amp;quot;prod&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Studio]]&lt;/div&gt;</summary>
		<author><name>SwHawk</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=User:SwHawk/Create_Modular_Code&amp;diff=15447</id>
		<title>User:SwHawk/Create Modular Code</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=User:SwHawk/Create_Modular_Code&amp;diff=15447"/>
		<updated>2022-11-29T21:53:29Z</updated>

		<summary type="html">&lt;p&gt;SwHawk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{InfoBox|title=WIP|body=&#039;&#039;&#039;This article is a Work In Progress, please do not refer to it for production purposes&#039;&#039;&#039;}}&lt;br /&gt;
&lt;br /&gt;
This page will cover steps you can take as a BGA developer to make your code more modular and better organized. The way the framework is implemented makes the [[Main game logic: yourgamename.game.php|game logic]] and the [[Game interface logic: yourgamename.js|interface logic]] files very monolithic. While this is not a problem in itself, even simple to moderately complex game may require this files to be over 5k lines of code. Thus you can quickly become lost in all the functions you need to declare, where they are declared, and where they are called.&lt;br /&gt;
&lt;br /&gt;
But there are steps that you can follow to take advantage of PHP&#039;s Object Oriented Code and the dojo toolkit&#039;s AMD loader to organize your code in separate files. Let&#039;s see what&#039;s available:&lt;br /&gt;
&lt;br /&gt;
== Acknowledgements ==&lt;br /&gt;
&lt;br /&gt;
Writing this wiki article wouldn&#039;t have been possible without the help, work and insight of more experienced BGA developers:&lt;br /&gt;
* [https://boardgamearena.com/player?id=83846198 Tisaac]  (Discord user Tisaac Human Expert)&lt;br /&gt;
* [https://boardgamearena.com/player?id=85537631 bennygui] (Discord user bennygui)&lt;br /&gt;
* [https://boardgamearena.com/player?id=84125723 VictoriaLa] (Discord user VictoriaLa)&lt;br /&gt;
* Syarwin and [https://boardgamearena.com/player?id=84554161 quietmint] (for their Welcome To [https://github.com/Syarwin/bga-welcometo repository])&lt;br /&gt;
* [https://boardgamearena.com/player?id=84522426 Mogri] (Discord user Mogri)&lt;br /&gt;
* Discord user Tug Brice (Ice 9 Games)&lt;br /&gt;
&lt;br /&gt;
== Conventions ==&lt;br /&gt;
In the code blocks, code additions will be displayed in bold and green, and added comments will be displayed in bold and dark grey so that they stand out from the boilerplate code from a scratch project. Part in red should be aapted to reflect your project&#039;s structure.&lt;br /&gt;
&lt;br /&gt;
== On the PHP side ==&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt; vs &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; ===&lt;br /&gt;
Throughout this section, I&#039;ll make heavy use of PHP&#039;s &amp;lt;code&amp;gt;require_once&amp;lt;/code&amp;gt; control structure. Why am I using &amp;lt;code&amp;gt;require(_once)&amp;lt;/code&amp;gt; instead of &amp;lt;code&amp;gt;include_once&amp;lt;/code&amp;gt;? Because if an error exists in a PHP file that you try to &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt;, only a warning will be thrown, but the script will continue in spite of the error. Using &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; if the included file has an error, the script dies when the inclusion takes places, throwing a fatal error (&amp;lt;code&amp;gt;E_COMPILE_ERROR&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
That way, I&#039;m sure the classes, traits or interfaces I&#039;m including are syntax error free.&lt;br /&gt;
&lt;br /&gt;
=== Game logic methods ===&lt;br /&gt;
The way the framework is implemented, your game logic is gathered inside a class (&amp;lt;code&amp;gt;YourProjectName&amp;lt;/code&amp;gt;) extending the [[Table|&amp;lt;code&amp;gt;Table&amp;lt;/code&amp;gt; class]]. You define your methods there so that they may be called from other parts of the framework (as long as they&#039;re public methods obviously).&lt;br /&gt;
&lt;br /&gt;
But you can take advantage of [https://www.php.net/manual/en/language.oop5.traits.php PHP Traits]. In a nutshell, Traits are a collection of methods that can be reused in different classes, to avoid code duplication. Here we&#039;re not going to reuse them anywhere else than in the game class, but this little trick allows us to put methods definitions in other files, and in so doing to avoid monolithic code.&lt;br /&gt;
&lt;br /&gt;
Basically you create a Trait in th &amp;lt;code&amp;gt;/modules/&amp;lt;/code&amp;gt; directory, for instance:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/UtiltityFunctionsTrait.php]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;lt;?php&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;namespace YourProjectNamespace\Modules;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;trait UtilityFunctionsTrait {&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &#039;&#039;&#039;public function myFirstUtilityFunction($args)&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;{&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//Your code here&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;}&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Then you can include it in you project&#039;s &amp;lt;code&amp;gt;X.game.php&amp;lt;/code&amp;gt; file like so:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X_game.php]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;?php&lt;br /&gt;
  /**&lt;br /&gt;
   *------&lt;br /&gt;
   * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
   * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
   * &lt;br /&gt;
   * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
   * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
   * -----&lt;br /&gt;
   * &lt;br /&gt;
   * X.game.php&lt;br /&gt;
   *&lt;br /&gt;
   * This is the main file for your game logic.&lt;br /&gt;
   *&lt;br /&gt;
   * In this PHP file, you are going to defines the rules of the game.&lt;br /&gt;
   *&lt;br /&gt;
   */&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;require_once &#039;modules/UtilityFunctionsTrait.php&#039;; &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;   //Here we require the trait to be loaded when the class is loaded&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;use X\Modules\UtilityFunctionsTrait;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;                 //We import the trait to be used directly as UtilityFunctionsTraits,&#039;&#039;&#039;&lt;br /&gt;
                                                      &#039;&#039;&#039;//otherwise we would have to use the Fully qualified class name&#039;&#039;&#039;&lt;br /&gt;
                                                      &#039;&#039;&#039;//(YourProjectNamespace\Modules\UtilityFunctionsTrait)&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 class X extends Table&lt;br /&gt;
 {&lt;br /&gt;
 //...&lt;br /&gt;
 &lt;br /&gt;
 //////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
 //////////// Utility functions&lt;br /&gt;
 ////////////    &lt;br /&gt;
 &lt;br /&gt;
     /*&lt;br /&gt;
         In this space, you can put any utility methods useful for your game logic&lt;br /&gt;
     */&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;use UtilityFunctionsTrait;&#039;&#039;&#039;&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//Here we actually include the trait inside the class, making all the trait&#039;s methods&#039;&#039;&#039; &lt;br /&gt;
                                &#039;&#039;&#039;//available as class methods, keeping their visibility scope (so a private method&#039;&#039;&#039;&lt;br /&gt;
                                &#039;&#039;&#039;//is still private)&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Support classes ===&lt;br /&gt;
Basically, the same as traits, you put your classes definitions into files that live under the &amp;lt;code&amp;gt;/modules/&amp;lt;/code&amp;gt; directory (don&#039;t forget to namespace your classes), and then require them at the top of &amp;lt;code&amp;gt;X_game.php&amp;lt;/code&amp;gt;, and voilà, you&#039;re done&lt;br /&gt;
&lt;br /&gt;
=== Adding autoloader support ===&lt;br /&gt;
&lt;br /&gt;
==== Coding standards ====&lt;br /&gt;
Even for simple games, you might end up having a dozen of traits and support classes. You can require them all in your &amp;lt;code&amp;gt;X_game.php&amp;lt;/code&amp;gt;. Or you can use an autoloader, which will load the necessary classes and traits at runtime. There are two PSRs dealing with autloading standards (namely [https://www.php-fig.org/psr/psr-0 PSR-0] which is marked as deprecated and [https://www.php-fig.org/psr/psr-4 PSR-4]) which state that your namespaces should be a reflection of the directory structure of your project.&lt;br /&gt;
&lt;br /&gt;
Basically, when creating namespaces, you choose a namespace prefix. For example, you could use your BGA handle and the project name as a namespace prefix (would result in &amp;lt;code&amp;gt;\SwHawk\X&amp;lt;/code&amp;gt; in my case), and then the rest of the namespace would be the directory the file is in. I usually group classes and traits by the function they have in my project, so my &amp;lt;code&amp;gt;/modules/&amp;lt;/code&amp;gt; directory looks like that:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
modules/&lt;br /&gt;
    php/&lt;br /&gt;
        Factory/                      //Holds my factory classes&lt;br /&gt;
            AFactoryClass.php         //The namespace for this file would be \SwHawk\X\Factory, and the fully qualified class name would be \SwHawk\X\Factory\AFactoryClass&lt;br /&gt;
            ...&lt;br /&gt;
        Object/                       //Holds my support classes&lt;br /&gt;
            ObjectA.php               //The namespace for this file would be \SwHawk\X\Object, and the fully qualified class name would be \SwHawk\X\Object\ObjectA&lt;br /&gt;
            ...&lt;br /&gt;
        Traits/                       //Holds my traits&lt;br /&gt;
            UtilityFunctionsTrait.php //The namespace for this file would be \SwHawk\X\Traits, and the fully qualified class name would be \SwHawk\X\Traits\UtilityFunctionsTrait&lt;br /&gt;
            ...&lt;br /&gt;
        ...&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Autoloader function for development ====&lt;br /&gt;
While your project is under development, you usually create, move and remove classes as part of the development process. So you usually need an autoloading function that can handle a lot of flexibility. Basically once you import a class using the &amp;lt;code&amp;gt;use&amp;lt;/code&amp;gt; keyword, the autoloading function will determine which file to &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; using its fully qualified class name, and then &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt;. This function needs to be either defined or included at the top of &amp;lt;code&amp;gt;X_game.php&amp;lt;/code&amp;gt;. Such a function would have the following code (borrowed and adapted from [https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader-examples.md this repository]):&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;spl_autoload_register(function ($class) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// project-specific namespace prefix&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;, adapt to your needs&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;, remember that you must escape \ characters in double-quoted strings (hence the \\)&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$prefix = &#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;SwHawk\\X\\&amp;quot;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// base directory for the namespace prefix, this file would usually reside in the modules/php/includes/ directory, so the base directory for all my classes would be a level higher&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$base_dir = __DIR__ . &#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;&#039;&#039;&#039; &#039;/../&#039; &#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;gt;&#039;&#039;&#039;;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// does the class use the namespace prefix?&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$len = strlen($prefix);&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;if (strncmp($prefix, $class, $len) !== 0) {&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// no, move to the next registered autoloader&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;return;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// get the relative class name&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$relative_class = substr($class, $len);&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;// replace the namespace prefix with the base directory, replace namespace&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;// separators with directory separators in the relative class name, append&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;// with .php&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$file = $base_dir . str_replace(&#039;\\&#039;, &#039;/&#039;, $relative_class) . &#039;.php&#039;;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// if the file exists, require it&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;if (file_exists($file)) {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;require $file;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Autoloader function for production ====&lt;br /&gt;
Once you&#039;re moving your game to production, the autoloader function provided before isn&#039;t optimized. Once in production, the directory tree should not be modified, so you can change the earlier autoloader to a classmap based one. Basically, you build an associative array with the fully qualified classes names as keys and the filepath as the value. An example would look like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;spl_autoload_register(function ($class) {&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;static $classmap = array(&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:red&amp;gt;&amp;quot;SwHawk\\X\\&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;Factory\\AFactoryClass&amp;quot; =&amp;gt; __DIR__ . &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;&amp;quot;/../&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;Factory/AFactoryClass.php&amp;quot;,&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;);&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;if(array_key_exists($class)) {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;require $classmap[$class];&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;} else {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;return;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This autoloader is better suited to production since it won&#039;t use expensive calls like &amp;lt;code&amp;gt;file_exists($filename)&amp;lt;/code&amp;gt;. You can write the classmap by yourself, but it can be quite cumbersome, there is some tools like [https://github.com/hanneskod/classtools this project], or [https://github.com/gnugat/nomo-spaco this one], or even scripts detailed in this [https://stackoverflow.com/questions/22761554/how-to-get-all-class-names-inside-a-particular-namespace StackOverflow topic]&lt;br /&gt;
&lt;br /&gt;
== On the JS side ==&lt;br /&gt;
&lt;br /&gt;
BGA uses the dojo toolkit framework for most of its javascript code. Dojo comes with its own way of loading modules, which you can read about in more detail [https://dojotoolkit.org/documentation/tutorials/1.10/modules/ here] and [https://dojotoolkit.org/documentation/tutorials/1.10/modules_advanced/ here]. To put it simply, there are two ways you can go about this&lt;br /&gt;
&lt;br /&gt;
=== Write plain javascript ===&lt;br /&gt;
&lt;br /&gt;
==== Relying on the dojo toolkit ====&lt;br /&gt;
Should you wan to write plain javascript, you can easily do so. What you need to do is actually load the file like so in &amp;lt;code&amp;gt;X.js&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&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;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;g_gamethemeurl + &amp;quot;/modules/path/to/firstfile.js&amp;quot;,&amp;lt;/span&amp;gt;        &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;//The first file with your JS code&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;g_gamethemeurl + &amp;quot;/modules/path/to/secondfile.js&amp;quot;,&amp;lt;/span&amp;gt;       &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;//The second file with another part of your JS code&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
     ...&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
         constructor: function(){&lt;br /&gt;
             ...&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
According to the dojo toolkit documentation, you will then need to directly access what you defined in the files.&lt;br /&gt;
&lt;br /&gt;
==== Alternative method ====&lt;br /&gt;
&lt;br /&gt;
This section has mostly been written by [[User:Mogri|Mogri]].&lt;br /&gt;
&lt;br /&gt;
This approach lets you avoid Dojo and &amp;lt;tt&amp;gt;this&amp;lt;/tt&amp;gt; and allows more modern JS.&lt;br /&gt;
&lt;br /&gt;
First, you&#039;ll need to a a statement at the beginning of the &amp;lt;code&amp;gt;X.js&amp;lt;/code&amp;gt; file:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
 *------&lt;br /&gt;
 * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
 * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
 *&lt;br /&gt;
 * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
 * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
 * -----&lt;br /&gt;
 *&lt;br /&gt;
 * X.js&lt;br /&gt;
 *&lt;br /&gt;
 * X user interface script&lt;br /&gt;
 * &lt;br /&gt;
 * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&gt;
 &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;window.X = {};&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// X = your game, or you can use something more generic&amp;lt;/span&amp;gt;&#039;&#039;&#039;&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;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;g_gamethemeurl + &amp;quot;/modules/whatever.js&amp;quot;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
         constructor: function(){&lt;br /&gt;
             console.log(&#039;X constructor&#039;);&lt;br /&gt;
               &lt;br /&gt;
             // Here, you can init the global variables of your user interface&lt;br /&gt;
             // Example:&lt;br /&gt;
             // this.myGlobalValue = 0;&lt;br /&gt;
 &lt;br /&gt;
         },&lt;br /&gt;
         &lt;br /&gt;
         /*&lt;br /&gt;
             setup:&lt;br /&gt;
             &lt;br /&gt;
             This method must set up the game user interface according to current game situation specified&lt;br /&gt;
             in parameters.&lt;br /&gt;
             &lt;br /&gt;
             The method is called each time the game interface is displayed to a player, ie:&lt;br /&gt;
             _ when the game starts&lt;br /&gt;
             _ when a player refreshes the game page (F5)&lt;br /&gt;
             &lt;br /&gt;
             &amp;quot;gamedatas&amp;quot; argument contains all datas retrieved by your &amp;quot;getAllDatas&amp;quot; PHP method.&lt;br /&gt;
         */&lt;br /&gt;
        &lt;br /&gt;
         setup: function( gamedatas )&lt;br /&gt;
         {&lt;br /&gt;
             &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;X = Object.assign(this, X);&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// This will allow you to use X.method instead of this.method inside modules/whatever.js&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// the rest of your setup goes here&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
         },&lt;br /&gt;
     });&lt;br /&gt;
 });&lt;br /&gt;
&lt;br /&gt;
And then, in your &amp;lt;code&amp;gt;modules/whatever.js&amp;lt;/code&amp;gt; file:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/whatever.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;X = Object.assign(X, {&#039;&#039;&#039;&lt;br /&gt;
   &#039;&#039;&#039;MY_CONSTANT: 1,&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
   &#039;&#039;&#039;myFunction: (arg1, arg2) =&amp;gt; {&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;X.someFunction(X.MY_CONSTANT);&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;return arg1 + arg2;&#039;&#039;&#039;&lt;br /&gt;
   &#039;&#039;&#039;},&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
   &#039;&#039;&#039;someFunction: (x) =&amp;gt; _(&#039;The answer is: &#039;) + x,&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notes on this approach:&lt;br /&gt;
*Aside from setup and any framework-override functions, you can use arrow functions&lt;br /&gt;
*Always use X instead of &amp;lt;tt&amp;gt;this&amp;lt;/tt&amp;gt;&lt;br /&gt;
*As usual, you can use any number of modules this way&lt;br /&gt;
&lt;br /&gt;
=== Write an AMD module ===&lt;br /&gt;
You can take advantage of the toolkit&#039;s module system to declare dependencies between the differents files you&#039;ll be writing (modules in the toolkit&#039;s language). To be identified as modules, your Javascript files will need to have the following structure:&lt;br /&gt;
&lt;br /&gt;
==== Create a named new class ====&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/js/FirstModule.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;gt;&#039;&#039;&#039;define([&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo&amp;quot;,&amp;lt;/span&amp;gt;      &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Needed if you want to be able to use dojo methods such as dojo.place, etc.&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo/_base/declare&amp;quot;,&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;other dependencies...&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;],function(dojo, declare){&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;return declare(&amp;quot;className&amp;quot;,&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/*Parent classes that this class inherits, optional*/&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, {&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;&#039;&#039;&#039;/* static properties */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;let property1 = &amp;quot;value;&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;let property2 = 5;&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;constructor: function (args) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;&#039;&#039;&#039;/* instance properties */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;let property3 = 8;&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;let property4 = [ &amp;quot;arrayValue&amp;quot;, &amp;quot;arrayValue2&amp;quot; ]; &#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;method1: function (args) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;/* your code here */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
         &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;});&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then in the X.js file, you can use your newly created module like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&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;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/js/Firstmodule&amp;quot;,&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
     ...&lt;br /&gt;
     });&lt;br /&gt;
 });&lt;br /&gt;
&lt;br /&gt;
In your code, you can access your module&#039;s class and methods by doing so:&lt;br /&gt;
&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;let object = new className();&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;object.method1();&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;...&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This can lead to namespace collisions if you don&#039;t choose a namespace correctly, so you might want to take the same approach as described earlier for the PHP files for using a namespace.&lt;br /&gt;
&lt;br /&gt;
==== Create an anonymous class ====&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/js/SecondModule.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;gt;&#039;&#039;&#039;define([&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo&amp;quot;,&amp;lt;/span&amp;gt;      &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Needed if you want to be able to use dojo methods such as dojo.place, etc.&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo/_base/declare&amp;quot;,&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;other dependencies...&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;],function(dojo, declare){&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;return declare(&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/*Optional : parent classes that this class inherits, must be required in the array, and in the define callback arguments*/&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, {&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;&#039;&#039;&#039;/* static properties */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;let property1 = &amp;quot;value;&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;let property2 = 5;&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;constructor: function (args) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;&#039;&#039;&#039;/* instance properties */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;let property3 = 8;&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;let property4 = [ &amp;quot;arrayValue&amp;quot;, &amp;quot;arrayValue2&amp;quot; ]; &#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;method1: function (args) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;/* your code here */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
         &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;});&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then in the X.js file, you can use your newly created module like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&gt;
 &lt;br /&gt;
 define([&lt;br /&gt;
     &amp;quot;dojo&amp;quot;,&amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/js/SecondModule&amp;quot;,&#039;&#039;&#039;&amp;lt;/span&amp;gt;      &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//Has to be inserted in the third position as we&#039;ll&#039;&#039;&#039;&lt;br /&gt;
                                       &#039;&#039;&#039;//need an identifier later, and the other modules don&#039;t need it, see code in the preceding subsection.&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
     &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
 &lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, SecondModule&amp;lt;/span&amp;gt;  &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/* insert a reference here that you&#039;ll use throughout the JS file for this module */&amp;lt;/span&amp;gt;&#039;&#039;&#039;) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
     ...&lt;br /&gt;
     });&lt;br /&gt;
 });&lt;br /&gt;
&lt;br /&gt;
In your code, you can access your module&#039;s class and methods by doing so:&lt;br /&gt;
&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;let myObject = new SecondModule();&lt;br /&gt;
     &#039;&#039;&#039;let someValue = myObject.property3&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;myObject.method1();&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;...&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This can lead to namespace collisions if you don&#039;t choose a namespace correctly, so you might want to take the same approach as described earlier for the PHP files for using a namespace.&lt;br /&gt;
&lt;br /&gt;
==== Create a singleton object ====&lt;br /&gt;
&lt;br /&gt;
You can also create singleton objects by creating a module this way:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/js/singletonObject.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;define([&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo&amp;quot;,&amp;lt;/span&amp;gt;      &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Needed if you want to be able to use dojo methods such as dojo.place, etc.&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;], function (dojo) {&#039;&#039;&#039;&lt;br /&gt;
     &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;// Methods and variables defined in this part will not be available anywhere else than in this file&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;let privateVariable = &amp;quot;someValue&amp;quot;;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;let privateFunction = function (args) {&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//some code here&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;return {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;firstMethod: function (args) {&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;privateFunction(args);&#039;&#039;&#039;&lt;br /&gt;
             &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//some other code here&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;};&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To be used in the &amp;lt;code&amp;gt;X.js&amp;lt;/code&amp;gt; file, you must use the same method as in the [[#Create an anonymous class|previous section]]:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&gt;
 &lt;br /&gt;
 define([&lt;br /&gt;
     &amp;quot;dojo&amp;quot;,&amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&amp;quot;./modules/js/SecondModule&amp;quot;,&amp;lt;/span&amp;gt;         &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Has to be inserted in the third position as we&#039;ll need an identifier later, and the other modules don&#039;t need it&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&amp;quot;./modules/js/sigletonObject&amp;quot;,&amp;lt;/span&amp;gt;          &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//see code in the preceding subsection.&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
     &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/js/Firstmodule&amp;quot;,&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, SecondModule&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/* insert a reference here that you&#039;ll use throughout the JS file for this module */&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, singletonObject&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/* same here */&amp;lt;/span&amp;gt;&#039;&#039;&#039;) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
     ...&lt;br /&gt;
     });&lt;br /&gt;
 });&lt;br /&gt;
&lt;br /&gt;
Then you can access your code the same way as described in the [[#Create an anonymous class|previous section]]:&lt;br /&gt;
&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;singletonObject.firstMethod();&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;...&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Putting it all together ==&lt;br /&gt;
As you might have gathered reading this, much of your work will rely on the directory structure your project will follow.&lt;br /&gt;
&lt;br /&gt;
=== Recommended directory structure ===&lt;br /&gt;
&lt;br /&gt;
This is a recommendation, and in no way are you forced to follow it, but then you may have to adapt some of the code snippets shown below. All filenames should be self-explanatory, although there might be comments for some files.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
X/&lt;br /&gt;
  img/&lt;br /&gt;
    ...&lt;br /&gt;
  misc/&lt;br /&gt;
    ...&lt;br /&gt;
  modules/&lt;br /&gt;
    js/&lt;br /&gt;
      utility/&lt;br /&gt;
        FirstUtilityModule.js (defines a [[#Create a singleton object|singleton object]])&lt;br /&gt;
        SecondUtilityModule.js (defines an [[#Create an anonymous class|anonymous class]])&lt;br /&gt;
      notifications/&lt;br /&gt;
        FirstNotificationModule.js (defines a [[#Create a new named class|class with a name]])&lt;br /&gt;
      actions/&lt;br /&gt;
        FirstActionModule.js (plain JS code)&lt;br /&gt;
    php/&lt;br /&gt;
      includes/&lt;br /&gt;
        PNAutoloader.php (contains your autoloader, PN stands for ProjectName, and should be a trigram if possible)&lt;br /&gt;
        Other files to be included into files of the project. For instance splits from material.inc.php.&lt;br /&gt;
      Object/&lt;br /&gt;
         ObjectA.php&lt;br /&gt;
         ObjectB.php&lt;br /&gt;
      Traits/&lt;br /&gt;
         PlayerActions/&lt;br /&gt;
           PlayerActionsFunctionsTrait.php&lt;br /&gt;
         States/&lt;br /&gt;
           Actions/&lt;br /&gt;
             StateActionsFunctionsTrait.php&lt;br /&gt;
           Arguments/&lt;br /&gt;
             StateArgumentFunctionsTrait.php&lt;br /&gt;
         Utility/&lt;br /&gt;
           FirstUtilityFunctionsTrait.php&lt;br /&gt;
           SecondUtilityFunctionsTrait.php&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This directory tree is quite detailed, you&#039;re free to make arrangements with it to suit your project&#039;s requirements.&lt;br /&gt;
&lt;br /&gt;
=== Choosing a namespace prefix ===&lt;br /&gt;
&lt;br /&gt;
==== PHP ====&lt;br /&gt;
As stated earlier, in order to avoid collisions when importing your PHP Classes and Traits, you should define a namespace prefix. We&#039;ll use &amp;lt;code&amp;gt;Username\ProjectName&amp;lt;/code&amp;gt; throughout the remainder of this article.&lt;br /&gt;
&lt;br /&gt;
==== JS ====&lt;br /&gt;
As we&#039;ll create a named class, we should also use a namespace prefix for the JS module. We&#039;ll use &amp;lt;code&amp;gt;username.projectname&amp;lt;/code&amp;gt; throughout the remainder of this article&lt;br /&gt;
&lt;br /&gt;
=== Write the autoloader and include it in the game logic ===&lt;br /&gt;
Even though you may have a lot less PHP classes than stated here, you should really write an autoloader function, and since it&#039;s recommended for the production environment, you should proceed to write a [[#Autoloader function for production|classmap autoloader]] when your classes are pretty much stabilised.&lt;br /&gt;
&lt;br /&gt;
Then you need to include it in your X_game.php like so:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X_game.php]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;?php&lt;br /&gt;
  /**&lt;br /&gt;
   *------&lt;br /&gt;
   * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
   * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
   * &lt;br /&gt;
   * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
   * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
   * -----&lt;br /&gt;
   * &lt;br /&gt;
   * X.game.php&lt;br /&gt;
   *&lt;br /&gt;
   * This is the main file for your game logic.&lt;br /&gt;
   *&lt;br /&gt;
   * In this PHP file, you are going to defines the rules of the game.&lt;br /&gt;
   *&lt;br /&gt;
   */&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;require_once &#039;modules/php/includes/PNAutoloader.php&#039;;&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Here you&#039;ll write the use statements to import your classes and traits using the autoloader&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 class X extends Table&lt;br /&gt;
 {&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Here you can write the use statements to import your traits into the class, or put them in the relevant sections of the file&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Write your Javascript modules and include them ===&lt;br /&gt;
On the JS side of the code, you have multiple alternatives to choose from (see the [[#On the JS side|JS section]]), but all will require you to modify the &amp;lt;code&amp;gt;define&amp;lt;/code&amp;gt; statement at the beginning of the &amp;lt;code&amp;gt;X.js&amp;lt;/code&amp;gt; file. According to the directory structure shown above, the file would look like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&gt;
 &lt;br /&gt;
 define([&lt;br /&gt;
     &amp;quot;dojo&amp;quot;,&amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/js/utility/FirstUtilityModule&amp;quot;,&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;./modules/js/utility/SecondUtilityModule&amp;quot;,&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
     &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/js/actions/FirstActionModule.js&amp;quot;,&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;./modules/js/notifications/FirstNotificationModule&amp;quot;,&amp;lt;/span&amp;gt;&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare, &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;FirstUtilityModule, SecondUtilityModule&amp;lt;/span&amp;gt;&#039;&#039;&#039;) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
         constructor: function(){&lt;br /&gt;
            console.log(&#039;X constructor&#039;);&lt;br /&gt;
              &lt;br /&gt;
            // Here, you can init the global variables of your user interface&lt;br /&gt;
            // Example:&lt;br /&gt;
            // this.myGlobalValue = 0;&lt;br /&gt;
            &lt;br /&gt;
        },&lt;br /&gt;
        &lt;br /&gt;
        /*&lt;br /&gt;
            setup:&lt;br /&gt;
            &lt;br /&gt;
            This method must set up the game user interface according to current game situation specified&lt;br /&gt;
            in parameters.&lt;br /&gt;
            &lt;br /&gt;
            The method is called each time the game interface is displayed to a player, ie:&lt;br /&gt;
            _ when the game starts&lt;br /&gt;
            _ when a player refreshes the game page (F5)&lt;br /&gt;
            &lt;br /&gt;
            &amp;quot;gamedatas&amp;quot; argument contains all datas retrieved by your &amp;quot;getAllDatas&amp;quot; PHP method.&lt;br /&gt;
        */&lt;br /&gt;
        &lt;br /&gt;
        setup: function( gamedatas )&lt;br /&gt;
        {&lt;br /&gt;
            &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;FirstUtilityModule.myMethod();&#039;&#039;&#039;&lt;br /&gt;
            &#039;&#039;&#039;SecondUtilityModule.anotherMethod(gamedatas);&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
            &lt;br /&gt;
        },&lt;br /&gt;
        ...&lt;br /&gt;
        ///////////////////////////////////////////////////&lt;br /&gt;
        //// Reaction to cometD notifications&lt;br /&gt;
 &lt;br /&gt;
        /*&lt;br /&gt;
            setupNotifications:&lt;br /&gt;
            &lt;br /&gt;
            In this method, you associate each of your game notifications with your local method to handle it.&lt;br /&gt;
            &lt;br /&gt;
            Note: game notification names correspond to &amp;quot;notifyAllPlayers&amp;quot; and &amp;quot;notifyPlayer&amp;quot; calls in&lt;br /&gt;
                  your progressevolutiontechnologyswh.game.php file.&lt;br /&gt;
        &lt;br /&gt;
        */&lt;br /&gt;
        setupNotifications: function()&lt;br /&gt;
        {&lt;br /&gt;
            console.log( &#039;notifications subscriptions setup&#039; );&lt;br /&gt;
            &lt;br /&gt;
            // TODO: here, associate your game notifications with local methods&lt;br /&gt;
            &lt;br /&gt;
            // Example 1: standard notification handling&lt;br /&gt;
            // dojo.subscribe( &#039;cardPlayed&#039;, this, &amp;quot;notif_cardPlayed&amp;quot; );&lt;br /&gt;
            &lt;br /&gt;
            // Example 2: standard notification handling + tell the user interface to wait&lt;br /&gt;
            //            during 3 seconds after calling the method in order to let the players&lt;br /&gt;
            //            see what is happening in the game.&lt;br /&gt;
            // dojo.subscribe( &#039;cardPlayed&#039;, this, &amp;quot;notif_cardPlayed&amp;quot; );&lt;br /&gt;
            // this.notifqueue.setSynchronous( &#039;cardPlayed&#039;, 3000 );&lt;br /&gt;
            //&lt;br /&gt;
            // TODO: check module integration with dojo.subscribe&lt;br /&gt;
        },&lt;br /&gt;
     });&lt;br /&gt;
 });&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== See it in a real project ===&lt;br /&gt;
This method has been partially or totally applied on the following projects:&lt;br /&gt;
* [https://gitlab.swhawk.eu/silver/progressevolutiontechnologybga Progress: Evolution of Technology] by [[User:SwHawk|SwHawk]]&lt;br /&gt;
&lt;br /&gt;
If you have successfully applied this method in your project, feel free to add you project to the list by editing this section&lt;/div&gt;</summary>
		<author><name>SwHawk</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=User:SwHawk/Create_Modular_Code&amp;diff=15446</id>
		<title>User:SwHawk/Create Modular Code</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=User:SwHawk/Create_Modular_Code&amp;diff=15446"/>
		<updated>2022-11-29T21:50:49Z</updated>

		<summary type="html">&lt;p&gt;SwHawk: /* Alternative method */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{InfoBox|title=WIP|body=&#039;&#039;&#039;This article is a Work In Progress, please do not refer to it for production purposes&#039;&#039;&#039;}}&lt;br /&gt;
&lt;br /&gt;
This page will cover steps you can take as a BGA developer to make your code more modular and better organized. The way the framework is implemented makes the [[Main game logic: yourgamename.game.php|game logic]] and the [[Game interface logic: yourgamename.js|interface logic]] files very monolithic. While this is not a problem in itself, even simple to moderately complex game may require this files to be over 5k lines of code. Thus you can quickly become lost in all the functions you need to declare, where they are declared, and where they are called.&lt;br /&gt;
&lt;br /&gt;
But there are steps that you can follow to take advantage of PHP&#039;s Object Oriented Code and the dojo toolkit&#039;s AMD loader to organize your code in separate files. Let&#039;s see what&#039;s available:&lt;br /&gt;
&lt;br /&gt;
== Acknowledgements ==&lt;br /&gt;
&lt;br /&gt;
Writing this wiki article wouldn&#039;t have been possible without the help, work and insight of more experienced BGA developers:&lt;br /&gt;
* [https://boardgamearena.com/player?id=83846198 Tisaac]  (Discord user Tisaac Human Expert)&lt;br /&gt;
* [https://boardgamearena.com/player?id=85537631 bennygui] (Discord user bennygui)&lt;br /&gt;
* [https://boardgamearena.com/player?id=84125723 VictoriaLa] (Discord user VictoriaLa)&lt;br /&gt;
* Syarwin and [https://boardgamearena.com/player?id=84554161 quietmint] (for their Welcome To [https://github.com/Syarwin/bga-welcometo repository])&lt;br /&gt;
* [https://boardgamearena.com/player?id=84522426 Mogri] (Discord user Mogri)&lt;br /&gt;
&lt;br /&gt;
== Conventions ==&lt;br /&gt;
In the code blocks, code additions will be displayed in bold and green, and added comments will be displayed in bold and dark grey so that they stand out from the boilerplate code from a scratch project. Part in red should be aapted to reflect your project&#039;s structure.&lt;br /&gt;
&lt;br /&gt;
== On the PHP side ==&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt; vs &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; ===&lt;br /&gt;
Throughout this section, I&#039;ll make heavy use of PHP&#039;s &amp;lt;code&amp;gt;require_once&amp;lt;/code&amp;gt; control structure. Why am I using &amp;lt;code&amp;gt;require(_once)&amp;lt;/code&amp;gt; instead of &amp;lt;code&amp;gt;include_once&amp;lt;/code&amp;gt;? Because if an error exists in a PHP file that you try to &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt;, only a warning will be thrown, but the script will continue in spite of the error. Using &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; if the included file has an error, the script dies when the inclusion takes places, throwing a fatal error (&amp;lt;code&amp;gt;E_COMPILE_ERROR&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
That way, I&#039;m sure the classes, traits or interfaces I&#039;m including are syntax error free.&lt;br /&gt;
&lt;br /&gt;
=== Game logic methods ===&lt;br /&gt;
The way the framework is implemented, your game logic is gathered inside a class (&amp;lt;code&amp;gt;YourProjectName&amp;lt;/code&amp;gt;) extending the [[Table|&amp;lt;code&amp;gt;Table&amp;lt;/code&amp;gt; class]]. You define your methods there so that they may be called from other parts of the framework (as long as they&#039;re public methods obviously).&lt;br /&gt;
&lt;br /&gt;
But you can take advantage of [https://www.php.net/manual/en/language.oop5.traits.php PHP Traits]. In a nutshell, Traits are a collection of methods that can be reused in different classes, to avoid code duplication. Here we&#039;re not going to reuse them anywhere else than in the game class, but this little trick allows us to put methods definitions in other files, and in so doing to avoid monolithic code.&lt;br /&gt;
&lt;br /&gt;
Basically you create a Trait in th &amp;lt;code&amp;gt;/modules/&amp;lt;/code&amp;gt; directory, for instance:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/UtiltityFunctionsTrait.php]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;lt;?php&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;namespace YourProjectNamespace\Modules;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;trait UtilityFunctionsTrait {&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &#039;&#039;&#039;public function myFirstUtilityFunction($args)&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;{&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//Your code here&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;}&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Then you can include it in you project&#039;s &amp;lt;code&amp;gt;X.game.php&amp;lt;/code&amp;gt; file like so:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X_game.php]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;?php&lt;br /&gt;
  /**&lt;br /&gt;
   *------&lt;br /&gt;
   * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
   * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
   * &lt;br /&gt;
   * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
   * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
   * -----&lt;br /&gt;
   * &lt;br /&gt;
   * X.game.php&lt;br /&gt;
   *&lt;br /&gt;
   * This is the main file for your game logic.&lt;br /&gt;
   *&lt;br /&gt;
   * In this PHP file, you are going to defines the rules of the game.&lt;br /&gt;
   *&lt;br /&gt;
   */&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;require_once &#039;modules/UtilityFunctionsTrait.php&#039;; &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;   //Here we require the trait to be loaded when the class is loaded&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;use X\Modules\UtilityFunctionsTrait;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;                 //We import the trait to be used directly as UtilityFunctionsTraits,&#039;&#039;&#039;&lt;br /&gt;
                                                      &#039;&#039;&#039;//otherwise we would have to use the Fully qualified class name&#039;&#039;&#039;&lt;br /&gt;
                                                      &#039;&#039;&#039;//(YourProjectNamespace\Modules\UtilityFunctionsTrait)&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 class X extends Table&lt;br /&gt;
 {&lt;br /&gt;
 //...&lt;br /&gt;
 &lt;br /&gt;
 //////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
 //////////// Utility functions&lt;br /&gt;
 ////////////    &lt;br /&gt;
 &lt;br /&gt;
     /*&lt;br /&gt;
         In this space, you can put any utility methods useful for your game logic&lt;br /&gt;
     */&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;use UtilityFunctionsTrait;&#039;&#039;&#039;&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//Here we actually include the trait inside the class, making all the trait&#039;s methods&#039;&#039;&#039; &lt;br /&gt;
                                &#039;&#039;&#039;//available as class methods, keeping their visibility scope (so a private method&#039;&#039;&#039;&lt;br /&gt;
                                &#039;&#039;&#039;//is still private)&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Support classes ===&lt;br /&gt;
Basically, the same as traits, you put your classes definitions into files that live under the &amp;lt;code&amp;gt;/modules/&amp;lt;/code&amp;gt; directory (don&#039;t forget to namespace your classes), and then require them at the top of &amp;lt;code&amp;gt;X_game.php&amp;lt;/code&amp;gt;, and voilà, you&#039;re done&lt;br /&gt;
&lt;br /&gt;
=== Adding autoloader support ===&lt;br /&gt;
&lt;br /&gt;
==== Coding standards ====&lt;br /&gt;
Even for simple games, you might end up having a dozen of traits and support classes. You can require them all in your &amp;lt;code&amp;gt;X_game.php&amp;lt;/code&amp;gt;. Or you can use an autoloader, which will load the necessary classes and traits at runtime. There are two PSRs dealing with autloading standards (namely [https://www.php-fig.org/psr/psr-0 PSR-0] which is marked as deprecated and [https://www.php-fig.org/psr/psr-4 PSR-4]) which state that your namespaces should be a reflection of the directory structure of your project.&lt;br /&gt;
&lt;br /&gt;
Basically, when creating namespaces, you choose a namespace prefix. For example, you could use your BGA handle and the project name as a namespace prefix (would result in &amp;lt;code&amp;gt;\SwHawk\X&amp;lt;/code&amp;gt; in my case), and then the rest of the namespace would be the directory the file is in. I usually group classes and traits by the function they have in my project, so my &amp;lt;code&amp;gt;/modules/&amp;lt;/code&amp;gt; directory looks like that:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
modules/&lt;br /&gt;
    php/&lt;br /&gt;
        Factory/                      //Holds my factory classes&lt;br /&gt;
            AFactoryClass.php         //The namespace for this file would be \SwHawk\X\Factory, and the fully qualified class name would be \SwHawk\X\Factory\AFactoryClass&lt;br /&gt;
            ...&lt;br /&gt;
        Object/                       //Holds my support classes&lt;br /&gt;
            ObjectA.php               //The namespace for this file would be \SwHawk\X\Object, and the fully qualified class name would be \SwHawk\X\Object\ObjectA&lt;br /&gt;
            ...&lt;br /&gt;
        Traits/                       //Holds my traits&lt;br /&gt;
            UtilityFunctionsTrait.php //The namespace for this file would be \SwHawk\X\Traits, and the fully qualified class name would be \SwHawk\X\Traits\UtilityFunctionsTrait&lt;br /&gt;
            ...&lt;br /&gt;
        ...&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Autoloader function for development ====&lt;br /&gt;
While your project is under development, you usually create, move and remove classes as part of the development process. So you usually need an autoloading function that can handle a lot of flexibility. Basically once you import a class using the &amp;lt;code&amp;gt;use&amp;lt;/code&amp;gt; keyword, the autoloading function will determine which file to &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; using its fully qualified class name, and then &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt;. This function needs to be either defined or included at the top of &amp;lt;code&amp;gt;X_game.php&amp;lt;/code&amp;gt;. Such a function would have the following code (borrowed and adapted from [https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader-examples.md this repository]):&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;spl_autoload_register(function ($class) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// project-specific namespace prefix&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;, adapt to your needs&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;, remember that you must escape \ characters in double-quoted strings (hence the \\)&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$prefix = &#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;SwHawk\\X\\&amp;quot;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// base directory for the namespace prefix, this file would usually reside in the modules/php/includes/ directory, so the base directory for all my classes would be a level higher&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$base_dir = __DIR__ . &#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;&#039;&#039;&#039; &#039;/../&#039; &#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;gt;&#039;&#039;&#039;;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// does the class use the namespace prefix?&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$len = strlen($prefix);&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;if (strncmp($prefix, $class, $len) !== 0) {&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// no, move to the next registered autoloader&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;return;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// get the relative class name&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$relative_class = substr($class, $len);&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;// replace the namespace prefix with the base directory, replace namespace&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;// separators with directory separators in the relative class name, append&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;// with .php&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$file = $base_dir . str_replace(&#039;\\&#039;, &#039;/&#039;, $relative_class) . &#039;.php&#039;;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// if the file exists, require it&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;if (file_exists($file)) {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;require $file;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Autoloader function for production ====&lt;br /&gt;
Once you&#039;re moving your game to production, the autoloader function provided before isn&#039;t optimized. Once in production, the directory tree should not be modified, so you can change the earlier autoloader to a classmap based one. Basically, you build an associative array with the fully qualified classes names as keys and the filepath as the value. An example would look like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;spl_autoload_register(function ($class) {&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;static $classmap = array(&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:red&amp;gt;&amp;quot;SwHawk\\X\\&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;Factory\\AFactoryClass&amp;quot; =&amp;gt; __DIR__ . &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;&amp;quot;/../&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;Factory/AFactoryClass.php&amp;quot;,&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;);&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;if(array_key_exists($class)) {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;require $classmap[$class];&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;} else {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;return;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This autoloader is better suited to production since it won&#039;t use expensive calls like &amp;lt;code&amp;gt;file_exists($filename)&amp;lt;/code&amp;gt;. You can write the classmap by yourself, but it can be quite cumbersome, there is some tools like [https://github.com/hanneskod/classtools this project], or [https://github.com/gnugat/nomo-spaco this one], or even scripts detailed in this [https://stackoverflow.com/questions/22761554/how-to-get-all-class-names-inside-a-particular-namespace StackOverflow topic]&lt;br /&gt;
&lt;br /&gt;
== On the JS side ==&lt;br /&gt;
&lt;br /&gt;
BGA uses the dojo toolkit framework for most of its javascript code. Dojo comes with its own way of loading modules, which you can read about in more detail [https://dojotoolkit.org/documentation/tutorials/1.10/modules/ here] and [https://dojotoolkit.org/documentation/tutorials/1.10/modules_advanced/ here]. To put it simply, there are two ways you can go about this&lt;br /&gt;
&lt;br /&gt;
=== Write plain javascript ===&lt;br /&gt;
&lt;br /&gt;
==== Relying on the dojo toolkit ====&lt;br /&gt;
Should you wan to write plain javascript, you can easily do so. What you need to do is actually load the file like so in &amp;lt;code&amp;gt;X.js&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&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;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;g_gamethemeurl + &amp;quot;/modules/path/to/firstfile.js&amp;quot;,&amp;lt;/span&amp;gt;        &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;//The first file with your JS code&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;g_gamethemeurl + &amp;quot;/modules/path/to/secondfile.js&amp;quot;,&amp;lt;/span&amp;gt;       &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;//The second file with another part of your JS code&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
     ...&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
         constructor: function(){&lt;br /&gt;
             ...&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
According to the dojo toolkit documentation, you will then need to directly access what you defined in the files.&lt;br /&gt;
&lt;br /&gt;
==== Alternative method ====&lt;br /&gt;
&lt;br /&gt;
This section has mostly been written by [[User:Mogri|Mogri]].&lt;br /&gt;
&lt;br /&gt;
This approach lets you avoid Dojo and &amp;lt;tt&amp;gt;this&amp;lt;/tt&amp;gt; and allows more modern JS.&lt;br /&gt;
&lt;br /&gt;
First, you&#039;ll need to a a statement at the beginning of the &amp;lt;code&amp;gt;X.js&amp;lt;/code&amp;gt; file:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
 *------&lt;br /&gt;
 * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
 * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
 *&lt;br /&gt;
 * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
 * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
 * -----&lt;br /&gt;
 *&lt;br /&gt;
 * X.js&lt;br /&gt;
 *&lt;br /&gt;
 * X user interface script&lt;br /&gt;
 * &lt;br /&gt;
 * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&gt;
 &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;window.X = {};&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// X = your game, or you can use something more generic&amp;lt;/span&amp;gt;&#039;&#039;&#039;&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;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;g_gamethemeurl + &amp;quot;/modules/whatever.js&amp;quot;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
         constructor: function(){&lt;br /&gt;
             console.log(&#039;X constructor&#039;);&lt;br /&gt;
               &lt;br /&gt;
             // Here, you can init the global variables of your user interface&lt;br /&gt;
             // Example:&lt;br /&gt;
             // this.myGlobalValue = 0;&lt;br /&gt;
 &lt;br /&gt;
         },&lt;br /&gt;
         &lt;br /&gt;
         /*&lt;br /&gt;
             setup:&lt;br /&gt;
             &lt;br /&gt;
             This method must set up the game user interface according to current game situation specified&lt;br /&gt;
             in parameters.&lt;br /&gt;
             &lt;br /&gt;
             The method is called each time the game interface is displayed to a player, ie:&lt;br /&gt;
             _ when the game starts&lt;br /&gt;
             _ when a player refreshes the game page (F5)&lt;br /&gt;
             &lt;br /&gt;
             &amp;quot;gamedatas&amp;quot; argument contains all datas retrieved by your &amp;quot;getAllDatas&amp;quot; PHP method.&lt;br /&gt;
         */&lt;br /&gt;
        &lt;br /&gt;
         setup: function( gamedatas )&lt;br /&gt;
         {&lt;br /&gt;
             &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;X = Object.assign(this, X);&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// This will allow you to use X.method instead of this.method inside modules/whatever.js&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// the rest of your setup goes here&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
         },&lt;br /&gt;
     });&lt;br /&gt;
 });&lt;br /&gt;
&lt;br /&gt;
And then, in your &amp;lt;code&amp;gt;modules/whatever.js&amp;lt;/code&amp;gt; file:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/whatever.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;X = Object.assign(X, {&#039;&#039;&#039;&lt;br /&gt;
   &#039;&#039;&#039;MY_CONSTANT: 1,&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
   &#039;&#039;&#039;myFunction: (arg1, arg2) =&amp;gt; {&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;X.someFunction(X.MY_CONSTANT);&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;return arg1 + arg2;&#039;&#039;&#039;&lt;br /&gt;
   &#039;&#039;&#039;},&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
   &#039;&#039;&#039;someFunction: (x) =&amp;gt; _(&#039;The answer is: &#039;) + x,&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notes on this approach:&lt;br /&gt;
*Aside from setup and any framework-override functions, you can use arrow functions&lt;br /&gt;
*Always use X instead of &amp;lt;tt&amp;gt;this&amp;lt;/tt&amp;gt;&lt;br /&gt;
*As usual, you can use any number of modules this way&lt;br /&gt;
&lt;br /&gt;
=== Write an AMD module ===&lt;br /&gt;
You can take advantage of the toolkit&#039;s module system to declare dependencies between the differents files you&#039;ll be writing (modules in the toolkit&#039;s language). To be identified as modules, your Javascript files will need to have the following structure:&lt;br /&gt;
&lt;br /&gt;
==== Create a named new class ====&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/js/FirstModule.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;gt;&#039;&#039;&#039;define([&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo&amp;quot;,&amp;lt;/span&amp;gt;      &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Needed if you want to be able to use dojo methods such as dojo.place, etc.&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo/_base/declare&amp;quot;,&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;other dependencies...&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;],function(dojo, declare){&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;return declare(&amp;quot;className&amp;quot;,&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/*Parent classes that this class inherits, optional*/&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, {&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;&#039;&#039;&#039;/* static properties */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;let property1 = &amp;quot;value;&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;let property2 = 5;&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;constructor: function (args) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;&#039;&#039;&#039;/* instance properties */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;let property3 = 8;&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;let property4 = [ &amp;quot;arrayValue&amp;quot;, &amp;quot;arrayValue2&amp;quot; ]; &#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;method1: function (args) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;/* your code here */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
         &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;});&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then in the X.js file, you can use your newly created module like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&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;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/js/Firstmodule&amp;quot;,&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
     ...&lt;br /&gt;
     });&lt;br /&gt;
 });&lt;br /&gt;
&lt;br /&gt;
In your code, you can access your module&#039;s class and methods by doing so:&lt;br /&gt;
&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;let object = new className();&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;object.method1();&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;...&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This can lead to namespace collisions if you don&#039;t choose a namespace correctly, so you might want to take the same approach as described earlier for the PHP files for using a namespace.&lt;br /&gt;
&lt;br /&gt;
==== Create an anonymous class ====&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/js/SecondModule.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;gt;&#039;&#039;&#039;define([&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo&amp;quot;,&amp;lt;/span&amp;gt;      &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Needed if you want to be able to use dojo methods such as dojo.place, etc.&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo/_base/declare&amp;quot;,&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;other dependencies...&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;],function(dojo, declare){&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;return declare(&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/*Optional : parent classes that this class inherits, must be required in the array, and in the define callback arguments*/&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, {&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;&#039;&#039;&#039;/* static properties */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;let property1 = &amp;quot;value;&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;let property2 = 5;&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;constructor: function (args) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;&#039;&#039;&#039;/* instance properties */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;let property3 = 8;&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;let property4 = [ &amp;quot;arrayValue&amp;quot;, &amp;quot;arrayValue2&amp;quot; ]; &#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;method1: function (args) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;/* your code here */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
         &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;});&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then in the X.js file, you can use your newly created module like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&gt;
 &lt;br /&gt;
 define([&lt;br /&gt;
     &amp;quot;dojo&amp;quot;,&amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/js/SecondModule&amp;quot;,&#039;&#039;&#039;&amp;lt;/span&amp;gt;      &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//Has to be inserted in the third position as we&#039;ll&#039;&#039;&#039;&lt;br /&gt;
                                       &#039;&#039;&#039;//need an identifier later, and the other modules don&#039;t need it, see code in the preceding subsection.&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
     &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
 &lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, SecondModule&amp;lt;/span&amp;gt;  &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/* insert a reference here that you&#039;ll use throughout the JS file for this module */&amp;lt;/span&amp;gt;&#039;&#039;&#039;) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
     ...&lt;br /&gt;
     });&lt;br /&gt;
 });&lt;br /&gt;
&lt;br /&gt;
In your code, you can access your module&#039;s class and methods by doing so:&lt;br /&gt;
&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;let myObject = new SecondModule();&lt;br /&gt;
     &#039;&#039;&#039;let someValue = myObject.property3&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;myObject.method1();&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;...&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This can lead to namespace collisions if you don&#039;t choose a namespace correctly, so you might want to take the same approach as described earlier for the PHP files for using a namespace.&lt;br /&gt;
&lt;br /&gt;
==== Create a singleton object ====&lt;br /&gt;
&lt;br /&gt;
You can also create singleton objects by creating a module this way:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/js/singletonObject.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;define([&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo&amp;quot;,&amp;lt;/span&amp;gt;      &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Needed if you want to be able to use dojo methods such as dojo.place, etc.&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;], function (dojo) {&#039;&#039;&#039;&lt;br /&gt;
     &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;// Methods and variables defined in this part will not be available anywhere else than in this file&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;let privateVariable = &amp;quot;someValue&amp;quot;;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;let privateFunction = function (args) {&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//some code here&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;return {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;firstMethod: function (args) {&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;privateFunction(args);&#039;&#039;&#039;&lt;br /&gt;
             &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//some other code here&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;};&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To be used in the &amp;lt;code&amp;gt;X.js&amp;lt;/code&amp;gt; file, you must use the same method as in the [[#Create an anonymous class|previous section]]:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&gt;
 &lt;br /&gt;
 define([&lt;br /&gt;
     &amp;quot;dojo&amp;quot;,&amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&amp;quot;./modules/js/SecondModule&amp;quot;,&amp;lt;/span&amp;gt;         &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Has to be inserted in the third position as we&#039;ll need an identifier later, and the other modules don&#039;t need it&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&amp;quot;./modules/js/sigletonObject&amp;quot;,&amp;lt;/span&amp;gt;          &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//see code in the preceding subsection.&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
     &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/js/Firstmodule&amp;quot;,&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, SecondModule&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/* insert a reference here that you&#039;ll use throughout the JS file for this module */&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, singletonObject&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/* same here */&amp;lt;/span&amp;gt;&#039;&#039;&#039;) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
     ...&lt;br /&gt;
     });&lt;br /&gt;
 });&lt;br /&gt;
&lt;br /&gt;
Then you can access your code the same way as described in the [[#Create an anonymous class|previous section]]:&lt;br /&gt;
&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;singletonObject.firstMethod();&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;...&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Putting it all together ==&lt;br /&gt;
As you might have gathered reading this, much of your work will rely on the directory structure your project will follow.&lt;br /&gt;
&lt;br /&gt;
=== Recommended directory structure ===&lt;br /&gt;
&lt;br /&gt;
This is a recommendation, and in no way are you forced to follow it, but then you may have to adapt some of the code snippets shown below. All filenames should be self-explanatory, although there might be comments for some files.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
X/&lt;br /&gt;
  img/&lt;br /&gt;
    ...&lt;br /&gt;
  misc/&lt;br /&gt;
    ...&lt;br /&gt;
  modules/&lt;br /&gt;
    js/&lt;br /&gt;
      utility/&lt;br /&gt;
        FirstUtilityModule.js (defines a [[#Create a singleton object|singleton object]])&lt;br /&gt;
        SecondUtilityModule.js (defines an [[#Create an anonymous class|anonymous class]])&lt;br /&gt;
      notifications/&lt;br /&gt;
        FirstNotificationModule.js (defines a [[#Create a new named class|class with a name]])&lt;br /&gt;
      actions/&lt;br /&gt;
        FirstActionModule.js (plain JS code)&lt;br /&gt;
    php/&lt;br /&gt;
      includes/&lt;br /&gt;
        PNAutoloader.php (contains your autoloader, PN stands for ProjectName, and should be a trigram if possible)&lt;br /&gt;
        Other files to be included into files of the project. For instance splits from material.inc.php.&lt;br /&gt;
      Object/&lt;br /&gt;
         ObjectA.php&lt;br /&gt;
         ObjectB.php&lt;br /&gt;
      Traits/&lt;br /&gt;
         PlayerActions/&lt;br /&gt;
           PlayerActionsFunctionsTrait.php&lt;br /&gt;
         States/&lt;br /&gt;
           Actions/&lt;br /&gt;
             StateActionsFunctionsTrait.php&lt;br /&gt;
           Arguments/&lt;br /&gt;
             StateArgumentFunctionsTrait.php&lt;br /&gt;
         Utility/&lt;br /&gt;
           FirstUtilityFunctionsTrait.php&lt;br /&gt;
           SecondUtilityFunctionsTrait.php&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This directory tree is quite detailed, you&#039;re free to make arrangements with it to suit your project&#039;s requirements.&lt;br /&gt;
&lt;br /&gt;
=== Choosing a namespace prefix ===&lt;br /&gt;
&lt;br /&gt;
==== PHP ====&lt;br /&gt;
As stated earlier, in order to avoid collisions when importing your PHP Classes and Traits, you should define a namespace prefix. We&#039;ll use &amp;lt;code&amp;gt;Username\ProjectName&amp;lt;/code&amp;gt; throughout the remainder of this article.&lt;br /&gt;
&lt;br /&gt;
==== JS ====&lt;br /&gt;
As we&#039;ll create a named class, we should also use a namespace prefix for the JS module. We&#039;ll use &amp;lt;code&amp;gt;username.projectname&amp;lt;/code&amp;gt; throughout the remainder of this article&lt;br /&gt;
&lt;br /&gt;
=== Write the autoloader and include it in the game logic ===&lt;br /&gt;
Even though you may have a lot less PHP classes than stated here, you should really write an autoloader function, and since it&#039;s recommended for the production environment, you should proceed to write a [[#Autoloader function for production|classmap autoloader]] when your classes are pretty much stabilised.&lt;br /&gt;
&lt;br /&gt;
Then you need to include it in your X_game.php like so:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X_game.php]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;?php&lt;br /&gt;
  /**&lt;br /&gt;
   *------&lt;br /&gt;
   * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
   * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
   * &lt;br /&gt;
   * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
   * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
   * -----&lt;br /&gt;
   * &lt;br /&gt;
   * X.game.php&lt;br /&gt;
   *&lt;br /&gt;
   * This is the main file for your game logic.&lt;br /&gt;
   *&lt;br /&gt;
   * In this PHP file, you are going to defines the rules of the game.&lt;br /&gt;
   *&lt;br /&gt;
   */&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;require_once &#039;modules/php/includes/PNAutoloader.php&#039;;&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Here you&#039;ll write the use statements to import your classes and traits using the autoloader&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 class X extends Table&lt;br /&gt;
 {&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Here you can write the use statements to import your traits into the class, or put them in the relevant sections of the file&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Write your Javascript modules and include them ===&lt;br /&gt;
On the JS side of the code, you have multiple alternatives to choose from (see the [[#On the JS side|JS section]]), but all will require you to modify the &amp;lt;code&amp;gt;define&amp;lt;/code&amp;gt; statement at the beginning of the &amp;lt;code&amp;gt;X.js&amp;lt;/code&amp;gt; file. According to the directory structure shown above, the file would look like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&gt;
 &lt;br /&gt;
 define([&lt;br /&gt;
     &amp;quot;dojo&amp;quot;,&amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/js/utility/FirstUtilityModule&amp;quot;,&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;./modules/js/utility/SecondUtilityModule&amp;quot;,&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
     &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/js/actions/FirstActionModule.js&amp;quot;,&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;./modules/js/notifications/FirstNotificationModule&amp;quot;,&amp;lt;/span&amp;gt;&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare, &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;FirstUtilityModule, SecondUtilityModule&amp;lt;/span&amp;gt;&#039;&#039;&#039;) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
         constructor: function(){&lt;br /&gt;
            console.log(&#039;X constructor&#039;);&lt;br /&gt;
              &lt;br /&gt;
            // Here, you can init the global variables of your user interface&lt;br /&gt;
            // Example:&lt;br /&gt;
            // this.myGlobalValue = 0;&lt;br /&gt;
            &lt;br /&gt;
        },&lt;br /&gt;
        &lt;br /&gt;
        /*&lt;br /&gt;
            setup:&lt;br /&gt;
            &lt;br /&gt;
            This method must set up the game user interface according to current game situation specified&lt;br /&gt;
            in parameters.&lt;br /&gt;
            &lt;br /&gt;
            The method is called each time the game interface is displayed to a player, ie:&lt;br /&gt;
            _ when the game starts&lt;br /&gt;
            _ when a player refreshes the game page (F5)&lt;br /&gt;
            &lt;br /&gt;
            &amp;quot;gamedatas&amp;quot; argument contains all datas retrieved by your &amp;quot;getAllDatas&amp;quot; PHP method.&lt;br /&gt;
        */&lt;br /&gt;
        &lt;br /&gt;
        setup: function( gamedatas )&lt;br /&gt;
        {&lt;br /&gt;
            &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;FirstUtilityModule.myMethod();&#039;&#039;&#039;&lt;br /&gt;
            &#039;&#039;&#039;SecondUtilityModule.anotherMethod(gamedatas);&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
            &lt;br /&gt;
        },&lt;br /&gt;
        ...&lt;br /&gt;
        ///////////////////////////////////////////////////&lt;br /&gt;
        //// Reaction to cometD notifications&lt;br /&gt;
 &lt;br /&gt;
        /*&lt;br /&gt;
            setupNotifications:&lt;br /&gt;
            &lt;br /&gt;
            In this method, you associate each of your game notifications with your local method to handle it.&lt;br /&gt;
            &lt;br /&gt;
            Note: game notification names correspond to &amp;quot;notifyAllPlayers&amp;quot; and &amp;quot;notifyPlayer&amp;quot; calls in&lt;br /&gt;
                  your progressevolutiontechnologyswh.game.php file.&lt;br /&gt;
        &lt;br /&gt;
        */&lt;br /&gt;
        setupNotifications: function()&lt;br /&gt;
        {&lt;br /&gt;
            console.log( &#039;notifications subscriptions setup&#039; );&lt;br /&gt;
            &lt;br /&gt;
            // TODO: here, associate your game notifications with local methods&lt;br /&gt;
            &lt;br /&gt;
            // Example 1: standard notification handling&lt;br /&gt;
            // dojo.subscribe( &#039;cardPlayed&#039;, this, &amp;quot;notif_cardPlayed&amp;quot; );&lt;br /&gt;
            &lt;br /&gt;
            // Example 2: standard notification handling + tell the user interface to wait&lt;br /&gt;
            //            during 3 seconds after calling the method in order to let the players&lt;br /&gt;
            //            see what is happening in the game.&lt;br /&gt;
            // dojo.subscribe( &#039;cardPlayed&#039;, this, &amp;quot;notif_cardPlayed&amp;quot; );&lt;br /&gt;
            // this.notifqueue.setSynchronous( &#039;cardPlayed&#039;, 3000 );&lt;br /&gt;
            //&lt;br /&gt;
            // TODO: check module integration with dojo.subscribe&lt;br /&gt;
        },&lt;br /&gt;
     });&lt;br /&gt;
 });&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== See it in a real project ===&lt;br /&gt;
This method has been partially or totally applied on the following projects:&lt;br /&gt;
* [https://gitlab.swhawk.eu/silver/progressevolutiontechnologybga Progress: Evolution of Technology] by [[User:SwHawk|SwHawk]]&lt;br /&gt;
&lt;br /&gt;
If you have successfully applied this method in your project, feel free to add you project to the list by editing this section&lt;/div&gt;</summary>
		<author><name>SwHawk</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=User:SwHawk/Create_Modular_Code&amp;diff=15445</id>
		<title>User:SwHawk/Create Modular Code</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=User:SwHawk/Create_Modular_Code&amp;diff=15445"/>
		<updated>2022-11-29T21:50:25Z</updated>

		<summary type="html">&lt;p&gt;SwHawk: /* Relying on the dojo toolkit */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{InfoBox|title=WIP|body=&#039;&#039;&#039;This article is a Work In Progress, please do not refer to it for production purposes&#039;&#039;&#039;}}&lt;br /&gt;
&lt;br /&gt;
This page will cover steps you can take as a BGA developer to make your code more modular and better organized. The way the framework is implemented makes the [[Main game logic: yourgamename.game.php|game logic]] and the [[Game interface logic: yourgamename.js|interface logic]] files very monolithic. While this is not a problem in itself, even simple to moderately complex game may require this files to be over 5k lines of code. Thus you can quickly become lost in all the functions you need to declare, where they are declared, and where they are called.&lt;br /&gt;
&lt;br /&gt;
But there are steps that you can follow to take advantage of PHP&#039;s Object Oriented Code and the dojo toolkit&#039;s AMD loader to organize your code in separate files. Let&#039;s see what&#039;s available:&lt;br /&gt;
&lt;br /&gt;
== Acknowledgements ==&lt;br /&gt;
&lt;br /&gt;
Writing this wiki article wouldn&#039;t have been possible without the help, work and insight of more experienced BGA developers:&lt;br /&gt;
* [https://boardgamearena.com/player?id=83846198 Tisaac]  (Discord user Tisaac Human Expert)&lt;br /&gt;
* [https://boardgamearena.com/player?id=85537631 bennygui] (Discord user bennygui)&lt;br /&gt;
* [https://boardgamearena.com/player?id=84125723 VictoriaLa] (Discord user VictoriaLa)&lt;br /&gt;
* Syarwin and [https://boardgamearena.com/player?id=84554161 quietmint] (for their Welcome To [https://github.com/Syarwin/bga-welcometo repository])&lt;br /&gt;
* [https://boardgamearena.com/player?id=84522426 Mogri] (Discord user Mogri)&lt;br /&gt;
&lt;br /&gt;
== Conventions ==&lt;br /&gt;
In the code blocks, code additions will be displayed in bold and green, and added comments will be displayed in bold and dark grey so that they stand out from the boilerplate code from a scratch project. Part in red should be aapted to reflect your project&#039;s structure.&lt;br /&gt;
&lt;br /&gt;
== On the PHP side ==&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt; vs &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; ===&lt;br /&gt;
Throughout this section, I&#039;ll make heavy use of PHP&#039;s &amp;lt;code&amp;gt;require_once&amp;lt;/code&amp;gt; control structure. Why am I using &amp;lt;code&amp;gt;require(_once)&amp;lt;/code&amp;gt; instead of &amp;lt;code&amp;gt;include_once&amp;lt;/code&amp;gt;? Because if an error exists in a PHP file that you try to &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt;, only a warning will be thrown, but the script will continue in spite of the error. Using &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; if the included file has an error, the script dies when the inclusion takes places, throwing a fatal error (&amp;lt;code&amp;gt;E_COMPILE_ERROR&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
That way, I&#039;m sure the classes, traits or interfaces I&#039;m including are syntax error free.&lt;br /&gt;
&lt;br /&gt;
=== Game logic methods ===&lt;br /&gt;
The way the framework is implemented, your game logic is gathered inside a class (&amp;lt;code&amp;gt;YourProjectName&amp;lt;/code&amp;gt;) extending the [[Table|&amp;lt;code&amp;gt;Table&amp;lt;/code&amp;gt; class]]. You define your methods there so that they may be called from other parts of the framework (as long as they&#039;re public methods obviously).&lt;br /&gt;
&lt;br /&gt;
But you can take advantage of [https://www.php.net/manual/en/language.oop5.traits.php PHP Traits]. In a nutshell, Traits are a collection of methods that can be reused in different classes, to avoid code duplication. Here we&#039;re not going to reuse them anywhere else than in the game class, but this little trick allows us to put methods definitions in other files, and in so doing to avoid monolithic code.&lt;br /&gt;
&lt;br /&gt;
Basically you create a Trait in th &amp;lt;code&amp;gt;/modules/&amp;lt;/code&amp;gt; directory, for instance:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/UtiltityFunctionsTrait.php]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;lt;?php&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;namespace YourProjectNamespace\Modules;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;trait UtilityFunctionsTrait {&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &#039;&#039;&#039;public function myFirstUtilityFunction($args)&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;{&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//Your code here&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;}&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Then you can include it in you project&#039;s &amp;lt;code&amp;gt;X.game.php&amp;lt;/code&amp;gt; file like so:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X_game.php]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;?php&lt;br /&gt;
  /**&lt;br /&gt;
   *------&lt;br /&gt;
   * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
   * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
   * &lt;br /&gt;
   * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
   * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
   * -----&lt;br /&gt;
   * &lt;br /&gt;
   * X.game.php&lt;br /&gt;
   *&lt;br /&gt;
   * This is the main file for your game logic.&lt;br /&gt;
   *&lt;br /&gt;
   * In this PHP file, you are going to defines the rules of the game.&lt;br /&gt;
   *&lt;br /&gt;
   */&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;require_once &#039;modules/UtilityFunctionsTrait.php&#039;; &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;   //Here we require the trait to be loaded when the class is loaded&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;use X\Modules\UtilityFunctionsTrait;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;                 //We import the trait to be used directly as UtilityFunctionsTraits,&#039;&#039;&#039;&lt;br /&gt;
                                                      &#039;&#039;&#039;//otherwise we would have to use the Fully qualified class name&#039;&#039;&#039;&lt;br /&gt;
                                                      &#039;&#039;&#039;//(YourProjectNamespace\Modules\UtilityFunctionsTrait)&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 class X extends Table&lt;br /&gt;
 {&lt;br /&gt;
 //...&lt;br /&gt;
 &lt;br /&gt;
 //////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
 //////////// Utility functions&lt;br /&gt;
 ////////////    &lt;br /&gt;
 &lt;br /&gt;
     /*&lt;br /&gt;
         In this space, you can put any utility methods useful for your game logic&lt;br /&gt;
     */&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;use UtilityFunctionsTrait;&#039;&#039;&#039;&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//Here we actually include the trait inside the class, making all the trait&#039;s methods&#039;&#039;&#039; &lt;br /&gt;
                                &#039;&#039;&#039;//available as class methods, keeping their visibility scope (so a private method&#039;&#039;&#039;&lt;br /&gt;
                                &#039;&#039;&#039;//is still private)&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Support classes ===&lt;br /&gt;
Basically, the same as traits, you put your classes definitions into files that live under the &amp;lt;code&amp;gt;/modules/&amp;lt;/code&amp;gt; directory (don&#039;t forget to namespace your classes), and then require them at the top of &amp;lt;code&amp;gt;X_game.php&amp;lt;/code&amp;gt;, and voilà, you&#039;re done&lt;br /&gt;
&lt;br /&gt;
=== Adding autoloader support ===&lt;br /&gt;
&lt;br /&gt;
==== Coding standards ====&lt;br /&gt;
Even for simple games, you might end up having a dozen of traits and support classes. You can require them all in your &amp;lt;code&amp;gt;X_game.php&amp;lt;/code&amp;gt;. Or you can use an autoloader, which will load the necessary classes and traits at runtime. There are two PSRs dealing with autloading standards (namely [https://www.php-fig.org/psr/psr-0 PSR-0] which is marked as deprecated and [https://www.php-fig.org/psr/psr-4 PSR-4]) which state that your namespaces should be a reflection of the directory structure of your project.&lt;br /&gt;
&lt;br /&gt;
Basically, when creating namespaces, you choose a namespace prefix. For example, you could use your BGA handle and the project name as a namespace prefix (would result in &amp;lt;code&amp;gt;\SwHawk\X&amp;lt;/code&amp;gt; in my case), and then the rest of the namespace would be the directory the file is in. I usually group classes and traits by the function they have in my project, so my &amp;lt;code&amp;gt;/modules/&amp;lt;/code&amp;gt; directory looks like that:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
modules/&lt;br /&gt;
    php/&lt;br /&gt;
        Factory/                      //Holds my factory classes&lt;br /&gt;
            AFactoryClass.php         //The namespace for this file would be \SwHawk\X\Factory, and the fully qualified class name would be \SwHawk\X\Factory\AFactoryClass&lt;br /&gt;
            ...&lt;br /&gt;
        Object/                       //Holds my support classes&lt;br /&gt;
            ObjectA.php               //The namespace for this file would be \SwHawk\X\Object, and the fully qualified class name would be \SwHawk\X\Object\ObjectA&lt;br /&gt;
            ...&lt;br /&gt;
        Traits/                       //Holds my traits&lt;br /&gt;
            UtilityFunctionsTrait.php //The namespace for this file would be \SwHawk\X\Traits, and the fully qualified class name would be \SwHawk\X\Traits\UtilityFunctionsTrait&lt;br /&gt;
            ...&lt;br /&gt;
        ...&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Autoloader function for development ====&lt;br /&gt;
While your project is under development, you usually create, move and remove classes as part of the development process. So you usually need an autoloading function that can handle a lot of flexibility. Basically once you import a class using the &amp;lt;code&amp;gt;use&amp;lt;/code&amp;gt; keyword, the autoloading function will determine which file to &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; using its fully qualified class name, and then &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt;. This function needs to be either defined or included at the top of &amp;lt;code&amp;gt;X_game.php&amp;lt;/code&amp;gt;. Such a function would have the following code (borrowed and adapted from [https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader-examples.md this repository]):&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;spl_autoload_register(function ($class) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// project-specific namespace prefix&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;, adapt to your needs&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;, remember that you must escape \ characters in double-quoted strings (hence the \\)&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$prefix = &#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;SwHawk\\X\\&amp;quot;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// base directory for the namespace prefix, this file would usually reside in the modules/php/includes/ directory, so the base directory for all my classes would be a level higher&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$base_dir = __DIR__ . &#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;&#039;&#039;&#039; &#039;/../&#039; &#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;gt;&#039;&#039;&#039;;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// does the class use the namespace prefix?&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$len = strlen($prefix);&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;if (strncmp($prefix, $class, $len) !== 0) {&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// no, move to the next registered autoloader&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;return;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// get the relative class name&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$relative_class = substr($class, $len);&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;// replace the namespace prefix with the base directory, replace namespace&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;// separators with directory separators in the relative class name, append&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;// with .php&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$file = $base_dir . str_replace(&#039;\\&#039;, &#039;/&#039;, $relative_class) . &#039;.php&#039;;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// if the file exists, require it&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;if (file_exists($file)) {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;require $file;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Autoloader function for production ====&lt;br /&gt;
Once you&#039;re moving your game to production, the autoloader function provided before isn&#039;t optimized. Once in production, the directory tree should not be modified, so you can change the earlier autoloader to a classmap based one. Basically, you build an associative array with the fully qualified classes names as keys and the filepath as the value. An example would look like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;spl_autoload_register(function ($class) {&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;static $classmap = array(&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:red&amp;gt;&amp;quot;SwHawk\\X\\&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;Factory\\AFactoryClass&amp;quot; =&amp;gt; __DIR__ . &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;&amp;quot;/../&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;Factory/AFactoryClass.php&amp;quot;,&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;);&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;if(array_key_exists($class)) {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;require $classmap[$class];&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;} else {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;return;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This autoloader is better suited to production since it won&#039;t use expensive calls like &amp;lt;code&amp;gt;file_exists($filename)&amp;lt;/code&amp;gt;. You can write the classmap by yourself, but it can be quite cumbersome, there is some tools like [https://github.com/hanneskod/classtools this project], or [https://github.com/gnugat/nomo-spaco this one], or even scripts detailed in this [https://stackoverflow.com/questions/22761554/how-to-get-all-class-names-inside-a-particular-namespace StackOverflow topic]&lt;br /&gt;
&lt;br /&gt;
== On the JS side ==&lt;br /&gt;
&lt;br /&gt;
BGA uses the dojo toolkit framework for most of its javascript code. Dojo comes with its own way of loading modules, which you can read about in more detail [https://dojotoolkit.org/documentation/tutorials/1.10/modules/ here] and [https://dojotoolkit.org/documentation/tutorials/1.10/modules_advanced/ here]. To put it simply, there are two ways you can go about this&lt;br /&gt;
&lt;br /&gt;
=== Write plain javascript ===&lt;br /&gt;
&lt;br /&gt;
==== Relying on the dojo toolkit ====&lt;br /&gt;
Should you wan to write plain javascript, you can easily do so. What you need to do is actually load the file like so in &amp;lt;code&amp;gt;X.js&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&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;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;g_gamethemeurl + &amp;quot;/modules/path/to/firstfile.js&amp;quot;,&amp;lt;/span&amp;gt;        &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;//The first file with your JS code&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;g_gamethemeurl + &amp;quot;/modules/path/to/secondfile.js&amp;quot;,&amp;lt;/span&amp;gt;       &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;//The second file with another part of your JS code&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
     ...&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
         constructor: function(){&lt;br /&gt;
             ...&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
According to the dojo toolkit documentation, you will then need to directly access what you defined in the files.&lt;br /&gt;
&lt;br /&gt;
==== Alternative method ====&lt;br /&gt;
&lt;br /&gt;
This section has mostly been written by [[User:Mogri|Mogri]].&lt;br /&gt;
&lt;br /&gt;
This approach lets you avoid Dojo and &amp;lt;tt&amp;gt;this&amp;lt;/tt&amp;gt; and allows more modern JS.&lt;br /&gt;
&lt;br /&gt;
First, you&#039;ll need to a a statement at the beginning of the &amp;lt;code&amp;gt;X.js&amp;lt;/code&amp;gt; file:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
 *------&lt;br /&gt;
 * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
 * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
 *&lt;br /&gt;
 * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
 * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
 * -----&lt;br /&gt;
 *&lt;br /&gt;
 * X.js&lt;br /&gt;
 *&lt;br /&gt;
 * X user interface script&lt;br /&gt;
 * &lt;br /&gt;
 * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&gt;
 &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;window.X = {};&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// X = your game, or you can use something more generic&amp;lt;/span&amp;gt;&#039;&#039;&#039;&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;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/whatever.js&amp;quot;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
         constructor: function(){&lt;br /&gt;
             console.log(&#039;X constructor&#039;);&lt;br /&gt;
               &lt;br /&gt;
             // Here, you can init the global variables of your user interface&lt;br /&gt;
             // Example:&lt;br /&gt;
             // this.myGlobalValue = 0;&lt;br /&gt;
 &lt;br /&gt;
         },&lt;br /&gt;
         &lt;br /&gt;
         /*&lt;br /&gt;
             setup:&lt;br /&gt;
             &lt;br /&gt;
             This method must set up the game user interface according to current game situation specified&lt;br /&gt;
             in parameters.&lt;br /&gt;
             &lt;br /&gt;
             The method is called each time the game interface is displayed to a player, ie:&lt;br /&gt;
             _ when the game starts&lt;br /&gt;
             _ when a player refreshes the game page (F5)&lt;br /&gt;
             &lt;br /&gt;
             &amp;quot;gamedatas&amp;quot; argument contains all datas retrieved by your &amp;quot;getAllDatas&amp;quot; PHP method.&lt;br /&gt;
         */&lt;br /&gt;
        &lt;br /&gt;
         setup: function( gamedatas )&lt;br /&gt;
         {&lt;br /&gt;
             &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;X = Object.assign(this, X);&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// This will allow you to use X.method instead of this.method inside modules/whatever.js&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// the rest of your setup goes here&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
         },&lt;br /&gt;
     });&lt;br /&gt;
 });&lt;br /&gt;
&lt;br /&gt;
And then, in your &amp;lt;code&amp;gt;modules/whatever.js&amp;lt;/code&amp;gt; file:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/whatever.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;X = Object.assign(X, {&#039;&#039;&#039;&lt;br /&gt;
   &#039;&#039;&#039;MY_CONSTANT: 1,&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
   &#039;&#039;&#039;myFunction: (arg1, arg2) =&amp;gt; {&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;X.someFunction(X.MY_CONSTANT);&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;return arg1 + arg2;&#039;&#039;&#039;&lt;br /&gt;
   &#039;&#039;&#039;},&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
   &#039;&#039;&#039;someFunction: (x) =&amp;gt; _(&#039;The answer is: &#039;) + x,&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notes on this approach:&lt;br /&gt;
*Aside from setup and any framework-override functions, you can use arrow functions&lt;br /&gt;
*Always use X instead of &amp;lt;tt&amp;gt;this&amp;lt;/tt&amp;gt;&lt;br /&gt;
*As usual, you can use any number of modules this way&lt;br /&gt;
&lt;br /&gt;
=== Write an AMD module ===&lt;br /&gt;
You can take advantage of the toolkit&#039;s module system to declare dependencies between the differents files you&#039;ll be writing (modules in the toolkit&#039;s language). To be identified as modules, your Javascript files will need to have the following structure:&lt;br /&gt;
&lt;br /&gt;
==== Create a named new class ====&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/js/FirstModule.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;gt;&#039;&#039;&#039;define([&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo&amp;quot;,&amp;lt;/span&amp;gt;      &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Needed if you want to be able to use dojo methods such as dojo.place, etc.&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo/_base/declare&amp;quot;,&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;other dependencies...&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;],function(dojo, declare){&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;return declare(&amp;quot;className&amp;quot;,&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/*Parent classes that this class inherits, optional*/&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, {&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;&#039;&#039;&#039;/* static properties */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;let property1 = &amp;quot;value;&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;let property2 = 5;&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;constructor: function (args) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;&#039;&#039;&#039;/* instance properties */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;let property3 = 8;&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;let property4 = [ &amp;quot;arrayValue&amp;quot;, &amp;quot;arrayValue2&amp;quot; ]; &#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;method1: function (args) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;/* your code here */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
         &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;});&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then in the X.js file, you can use your newly created module like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&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;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/js/Firstmodule&amp;quot;,&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
     ...&lt;br /&gt;
     });&lt;br /&gt;
 });&lt;br /&gt;
&lt;br /&gt;
In your code, you can access your module&#039;s class and methods by doing so:&lt;br /&gt;
&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;let object = new className();&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;object.method1();&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;...&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This can lead to namespace collisions if you don&#039;t choose a namespace correctly, so you might want to take the same approach as described earlier for the PHP files for using a namespace.&lt;br /&gt;
&lt;br /&gt;
==== Create an anonymous class ====&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/js/SecondModule.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;gt;&#039;&#039;&#039;define([&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo&amp;quot;,&amp;lt;/span&amp;gt;      &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Needed if you want to be able to use dojo methods such as dojo.place, etc.&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo/_base/declare&amp;quot;,&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;other dependencies...&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;],function(dojo, declare){&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;return declare(&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/*Optional : parent classes that this class inherits, must be required in the array, and in the define callback arguments*/&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, {&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;&#039;&#039;&#039;/* static properties */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;let property1 = &amp;quot;value;&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;let property2 = 5;&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;constructor: function (args) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;&#039;&#039;&#039;/* instance properties */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;let property3 = 8;&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;let property4 = [ &amp;quot;arrayValue&amp;quot;, &amp;quot;arrayValue2&amp;quot; ]; &#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;method1: function (args) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;/* your code here */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
         &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;});&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then in the X.js file, you can use your newly created module like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&gt;
 &lt;br /&gt;
 define([&lt;br /&gt;
     &amp;quot;dojo&amp;quot;,&amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/js/SecondModule&amp;quot;,&#039;&#039;&#039;&amp;lt;/span&amp;gt;      &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//Has to be inserted in the third position as we&#039;ll&#039;&#039;&#039;&lt;br /&gt;
                                       &#039;&#039;&#039;//need an identifier later, and the other modules don&#039;t need it, see code in the preceding subsection.&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
     &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
 &lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, SecondModule&amp;lt;/span&amp;gt;  &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/* insert a reference here that you&#039;ll use throughout the JS file for this module */&amp;lt;/span&amp;gt;&#039;&#039;&#039;) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
     ...&lt;br /&gt;
     });&lt;br /&gt;
 });&lt;br /&gt;
&lt;br /&gt;
In your code, you can access your module&#039;s class and methods by doing so:&lt;br /&gt;
&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;let myObject = new SecondModule();&lt;br /&gt;
     &#039;&#039;&#039;let someValue = myObject.property3&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;myObject.method1();&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;...&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This can lead to namespace collisions if you don&#039;t choose a namespace correctly, so you might want to take the same approach as described earlier for the PHP files for using a namespace.&lt;br /&gt;
&lt;br /&gt;
==== Create a singleton object ====&lt;br /&gt;
&lt;br /&gt;
You can also create singleton objects by creating a module this way:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/js/singletonObject.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;define([&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo&amp;quot;,&amp;lt;/span&amp;gt;      &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Needed if you want to be able to use dojo methods such as dojo.place, etc.&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;], function (dojo) {&#039;&#039;&#039;&lt;br /&gt;
     &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;// Methods and variables defined in this part will not be available anywhere else than in this file&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;let privateVariable = &amp;quot;someValue&amp;quot;;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;let privateFunction = function (args) {&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//some code here&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;return {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;firstMethod: function (args) {&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;privateFunction(args);&#039;&#039;&#039;&lt;br /&gt;
             &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//some other code here&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;};&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To be used in the &amp;lt;code&amp;gt;X.js&amp;lt;/code&amp;gt; file, you must use the same method as in the [[#Create an anonymous class|previous section]]:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&gt;
 &lt;br /&gt;
 define([&lt;br /&gt;
     &amp;quot;dojo&amp;quot;,&amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&amp;quot;./modules/js/SecondModule&amp;quot;,&amp;lt;/span&amp;gt;         &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Has to be inserted in the third position as we&#039;ll need an identifier later, and the other modules don&#039;t need it&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&amp;quot;./modules/js/sigletonObject&amp;quot;,&amp;lt;/span&amp;gt;          &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//see code in the preceding subsection.&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
     &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/js/Firstmodule&amp;quot;,&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, SecondModule&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/* insert a reference here that you&#039;ll use throughout the JS file for this module */&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, singletonObject&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/* same here */&amp;lt;/span&amp;gt;&#039;&#039;&#039;) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
     ...&lt;br /&gt;
     });&lt;br /&gt;
 });&lt;br /&gt;
&lt;br /&gt;
Then you can access your code the same way as described in the [[#Create an anonymous class|previous section]]:&lt;br /&gt;
&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;singletonObject.firstMethod();&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;...&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Putting it all together ==&lt;br /&gt;
As you might have gathered reading this, much of your work will rely on the directory structure your project will follow.&lt;br /&gt;
&lt;br /&gt;
=== Recommended directory structure ===&lt;br /&gt;
&lt;br /&gt;
This is a recommendation, and in no way are you forced to follow it, but then you may have to adapt some of the code snippets shown below. All filenames should be self-explanatory, although there might be comments for some files.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
X/&lt;br /&gt;
  img/&lt;br /&gt;
    ...&lt;br /&gt;
  misc/&lt;br /&gt;
    ...&lt;br /&gt;
  modules/&lt;br /&gt;
    js/&lt;br /&gt;
      utility/&lt;br /&gt;
        FirstUtilityModule.js (defines a [[#Create a singleton object|singleton object]])&lt;br /&gt;
        SecondUtilityModule.js (defines an [[#Create an anonymous class|anonymous class]])&lt;br /&gt;
      notifications/&lt;br /&gt;
        FirstNotificationModule.js (defines a [[#Create a new named class|class with a name]])&lt;br /&gt;
      actions/&lt;br /&gt;
        FirstActionModule.js (plain JS code)&lt;br /&gt;
    php/&lt;br /&gt;
      includes/&lt;br /&gt;
        PNAutoloader.php (contains your autoloader, PN stands for ProjectName, and should be a trigram if possible)&lt;br /&gt;
        Other files to be included into files of the project. For instance splits from material.inc.php.&lt;br /&gt;
      Object/&lt;br /&gt;
         ObjectA.php&lt;br /&gt;
         ObjectB.php&lt;br /&gt;
      Traits/&lt;br /&gt;
         PlayerActions/&lt;br /&gt;
           PlayerActionsFunctionsTrait.php&lt;br /&gt;
         States/&lt;br /&gt;
           Actions/&lt;br /&gt;
             StateActionsFunctionsTrait.php&lt;br /&gt;
           Arguments/&lt;br /&gt;
             StateArgumentFunctionsTrait.php&lt;br /&gt;
         Utility/&lt;br /&gt;
           FirstUtilityFunctionsTrait.php&lt;br /&gt;
           SecondUtilityFunctionsTrait.php&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This directory tree is quite detailed, you&#039;re free to make arrangements with it to suit your project&#039;s requirements.&lt;br /&gt;
&lt;br /&gt;
=== Choosing a namespace prefix ===&lt;br /&gt;
&lt;br /&gt;
==== PHP ====&lt;br /&gt;
As stated earlier, in order to avoid collisions when importing your PHP Classes and Traits, you should define a namespace prefix. We&#039;ll use &amp;lt;code&amp;gt;Username\ProjectName&amp;lt;/code&amp;gt; throughout the remainder of this article.&lt;br /&gt;
&lt;br /&gt;
==== JS ====&lt;br /&gt;
As we&#039;ll create a named class, we should also use a namespace prefix for the JS module. We&#039;ll use &amp;lt;code&amp;gt;username.projectname&amp;lt;/code&amp;gt; throughout the remainder of this article&lt;br /&gt;
&lt;br /&gt;
=== Write the autoloader and include it in the game logic ===&lt;br /&gt;
Even though you may have a lot less PHP classes than stated here, you should really write an autoloader function, and since it&#039;s recommended for the production environment, you should proceed to write a [[#Autoloader function for production|classmap autoloader]] when your classes are pretty much stabilised.&lt;br /&gt;
&lt;br /&gt;
Then you need to include it in your X_game.php like so:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X_game.php]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;?php&lt;br /&gt;
  /**&lt;br /&gt;
   *------&lt;br /&gt;
   * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
   * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
   * &lt;br /&gt;
   * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
   * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
   * -----&lt;br /&gt;
   * &lt;br /&gt;
   * X.game.php&lt;br /&gt;
   *&lt;br /&gt;
   * This is the main file for your game logic.&lt;br /&gt;
   *&lt;br /&gt;
   * In this PHP file, you are going to defines the rules of the game.&lt;br /&gt;
   *&lt;br /&gt;
   */&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;require_once &#039;modules/php/includes/PNAutoloader.php&#039;;&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Here you&#039;ll write the use statements to import your classes and traits using the autoloader&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 class X extends Table&lt;br /&gt;
 {&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Here you can write the use statements to import your traits into the class, or put them in the relevant sections of the file&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Write your Javascript modules and include them ===&lt;br /&gt;
On the JS side of the code, you have multiple alternatives to choose from (see the [[#On the JS side|JS section]]), but all will require you to modify the &amp;lt;code&amp;gt;define&amp;lt;/code&amp;gt; statement at the beginning of the &amp;lt;code&amp;gt;X.js&amp;lt;/code&amp;gt; file. According to the directory structure shown above, the file would look like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&gt;
 &lt;br /&gt;
 define([&lt;br /&gt;
     &amp;quot;dojo&amp;quot;,&amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/js/utility/FirstUtilityModule&amp;quot;,&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;./modules/js/utility/SecondUtilityModule&amp;quot;,&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
     &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/js/actions/FirstActionModule.js&amp;quot;,&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;./modules/js/notifications/FirstNotificationModule&amp;quot;,&amp;lt;/span&amp;gt;&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare, &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;FirstUtilityModule, SecondUtilityModule&amp;lt;/span&amp;gt;&#039;&#039;&#039;) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
         constructor: function(){&lt;br /&gt;
            console.log(&#039;X constructor&#039;);&lt;br /&gt;
              &lt;br /&gt;
            // Here, you can init the global variables of your user interface&lt;br /&gt;
            // Example:&lt;br /&gt;
            // this.myGlobalValue = 0;&lt;br /&gt;
            &lt;br /&gt;
        },&lt;br /&gt;
        &lt;br /&gt;
        /*&lt;br /&gt;
            setup:&lt;br /&gt;
            &lt;br /&gt;
            This method must set up the game user interface according to current game situation specified&lt;br /&gt;
            in parameters.&lt;br /&gt;
            &lt;br /&gt;
            The method is called each time the game interface is displayed to a player, ie:&lt;br /&gt;
            _ when the game starts&lt;br /&gt;
            _ when a player refreshes the game page (F5)&lt;br /&gt;
            &lt;br /&gt;
            &amp;quot;gamedatas&amp;quot; argument contains all datas retrieved by your &amp;quot;getAllDatas&amp;quot; PHP method.&lt;br /&gt;
        */&lt;br /&gt;
        &lt;br /&gt;
        setup: function( gamedatas )&lt;br /&gt;
        {&lt;br /&gt;
            &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;FirstUtilityModule.myMethod();&#039;&#039;&#039;&lt;br /&gt;
            &#039;&#039;&#039;SecondUtilityModule.anotherMethod(gamedatas);&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
            &lt;br /&gt;
        },&lt;br /&gt;
        ...&lt;br /&gt;
        ///////////////////////////////////////////////////&lt;br /&gt;
        //// Reaction to cometD notifications&lt;br /&gt;
 &lt;br /&gt;
        /*&lt;br /&gt;
            setupNotifications:&lt;br /&gt;
            &lt;br /&gt;
            In this method, you associate each of your game notifications with your local method to handle it.&lt;br /&gt;
            &lt;br /&gt;
            Note: game notification names correspond to &amp;quot;notifyAllPlayers&amp;quot; and &amp;quot;notifyPlayer&amp;quot; calls in&lt;br /&gt;
                  your progressevolutiontechnologyswh.game.php file.&lt;br /&gt;
        &lt;br /&gt;
        */&lt;br /&gt;
        setupNotifications: function()&lt;br /&gt;
        {&lt;br /&gt;
            console.log( &#039;notifications subscriptions setup&#039; );&lt;br /&gt;
            &lt;br /&gt;
            // TODO: here, associate your game notifications with local methods&lt;br /&gt;
            &lt;br /&gt;
            // Example 1: standard notification handling&lt;br /&gt;
            // dojo.subscribe( &#039;cardPlayed&#039;, this, &amp;quot;notif_cardPlayed&amp;quot; );&lt;br /&gt;
            &lt;br /&gt;
            // Example 2: standard notification handling + tell the user interface to wait&lt;br /&gt;
            //            during 3 seconds after calling the method in order to let the players&lt;br /&gt;
            //            see what is happening in the game.&lt;br /&gt;
            // dojo.subscribe( &#039;cardPlayed&#039;, this, &amp;quot;notif_cardPlayed&amp;quot; );&lt;br /&gt;
            // this.notifqueue.setSynchronous( &#039;cardPlayed&#039;, 3000 );&lt;br /&gt;
            //&lt;br /&gt;
            // TODO: check module integration with dojo.subscribe&lt;br /&gt;
        },&lt;br /&gt;
     });&lt;br /&gt;
 });&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== See it in a real project ===&lt;br /&gt;
This method has been partially or totally applied on the following projects:&lt;br /&gt;
* [https://gitlab.swhawk.eu/silver/progressevolutiontechnologybga Progress: Evolution of Technology] by [[User:SwHawk|SwHawk]]&lt;br /&gt;
&lt;br /&gt;
If you have successfully applied this method in your project, feel free to add you project to the list by editing this section&lt;/div&gt;</summary>
		<author><name>SwHawk</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Help&amp;diff=15249</id>
		<title>Help</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Help&amp;diff=15249"/>
		<updated>2022-11-11T16:21:29Z</updated>

		<summary type="html">&lt;p&gt;SwHawk: Undo revision 15227 by Verdakanguruo (talk)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;An issue? A question?&lt;br /&gt;
&lt;br /&gt;
* [https://boardgamearena.com/#!faq Frequently asked questions] is the most complete source of help for BGA.&lt;br /&gt;
&lt;br /&gt;
* [https://forum.boardgamearena.com Forums] are also helpful to get information.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Games ==&lt;br /&gt;
Game names which are displayed in red still need game help/summaries written for them. So help out and write one for them by creating a new page for these games. To do so simply click on them below, this will direct you to a page creation page. &lt;br /&gt;
&lt;br /&gt;
Meanwhile, games being available in the alpha list does not warrant that it will go through the whole process and become available to the whole community. Consequently, it is kindly asked to refrain from publicising the alpha list, in order not to create unfounded expectations. Therefore, do not add any games to the alpha list.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table cellpadding=&amp;quot;0&amp;quot; cellspacing=&amp;quot;5&amp;quot; border=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td colspan=&amp;quot;4&amp;quot;&amp;gt;&#039;&#039;&#039;Available on BGA&#039;&#039;&#039;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&#039;&#039;&#039;Beta Games&#039;&#039;&#039;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&#039;&#039;&#039;Alpha Games&#039;&#039;&#039;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&#039;&#039;&#039;Removed from BGA&#039;&#039;&#039;&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td valign=&amp;quot;top&amp;quot;&amp;gt;&lt;br /&gt;
* [[Gamehelpthirteenclues|13 Clues]]&lt;br /&gt;
* [[Gamehelpsechsnimmt|6 nimmt!]]&lt;br /&gt;
* [[Gamehelpsevenwonders|7 Wonders]]&lt;br /&gt;
* [[Gamehelpsevenwondersarchitects|7 Wonders Architects]]&lt;br /&gt;
* [[Gamehelpsevenwondersduel|7 Wonders Duel]]&lt;br /&gt;
* [[Gamehelpeightmastersrevenge|8 Master&#039;s Revenge]]&lt;br /&gt;
* [[Gamehelpninetynineaddition|99 (addition card game)]]&lt;br /&gt;
* [[Gamehelpninetynine|99 (trick-taking card game)]]&lt;br /&gt;
* [[Gamehelpfeastforodin|A Feast for Odin]]&lt;br /&gt;
* [[Gamehelpfistfulofgold|A Fistful of Gold]]&lt;br /&gt;
* [[Gamehelpabalone|Abalone]]&lt;br /&gt;
* [[Gamehelpabandonallartichokes|Abandon All Artichokes]]&lt;br /&gt;
* [[Gamehelpabyss|Abyss]]&lt;br /&gt;
* [[Gamehelpagricola|Agricola]]&lt;br /&gt;
* [[Gamehelpalhambra|Alhambra]]&lt;br /&gt;
* [[Gamehelpalmadi|Almadi]]&lt;br /&gt;
* [[Gamehelpalveole|Alveole]]&lt;br /&gt;
* [[Gamehelpamyitis|Amyitis]]&lt;br /&gt;
* [[Gamehelpapocalypseazcc|Apocalypse at the Zoo of Carson City]]&lt;br /&gt;
* [[Gamehelparcticscavengers|Arctic Scavengers]]&lt;br /&gt;
* [[Gamehelparmadora|Armadöra]]&lt;br /&gt;
* [[Gamehelpartdecko|Art Decko]]&lt;br /&gt;
* [[Gamehelpassyria|Assyria]]&lt;br /&gt;
* [[Gamehelpautomobiles|Automobiles]]&lt;br /&gt;
* [[Gamehelpazul|Azul]]&lt;br /&gt;
* [[Gamehelpbabydinosaurrescue|Baby Dinosaur Rescue]]&lt;br /&gt;
* [[Gamehelpbackgammon|Backgammon]]&lt;br /&gt;
* [[Gamehelpbahamataxi|Bahama Taxi]]&lt;br /&gt;
* [[Gamehelpballoonpop|Balloon Pop!]]&lt;br /&gt;
* [[Gamehelpbandido|Bandido]]&lt;br /&gt;
* [[Gamehelpbang|BANG!]]&lt;br /&gt;
* [[Gamehelpbaolakiswahili|Bao la Kiswahili]]&lt;br /&gt;
* [[Gamehelpbarbu|Barbu]]&lt;br /&gt;
* [[Gamehelpbarenpark|Barenpark]]&lt;br /&gt;
* [[Gamehelpbarrage|Barrage]]&lt;br /&gt;
* [[Gamehelpbattleoflits|Battle of LITS]]&lt;br /&gt;
* [[Gamehelpbattlesheep|Battle Sheep]]&lt;br /&gt;
* [[Gamehelpbattleship|Battleships Pencil &amp;amp;amp; Paper]]&lt;br /&gt;
* [[Gamehelpbelote|Belote]]&lt;br /&gt;
* [[Gamehelpbetta|Betta]]&lt;br /&gt;
* [[Gamehelpbeyondthesun|Beyond the Sun]]&lt;br /&gt;
* [[Gamehelpbids|Bids]]&lt;br /&gt;
* [[Gamehelpbigmonster|Big Monster]]&lt;br /&gt;
* [[Gamehelpbigtimesoccer|Big Time Soccer]]&lt;br /&gt;
* [[Gamehelpbiyi|Biyi]]&lt;br /&gt;
* [[Gamehelpblaze|Blaze]]&lt;br /&gt;
* [[Gamehelpbloodrage|Blood Rage]]&lt;br /&gt;
* [[Gamehelpblooms|Blooms]]&lt;br /&gt;
* [[Gamehelpblueskies|Blue Skies]]&lt;br /&gt;
* [[Gamehelpbobail|Bobail]]&lt;br /&gt;
* [[Gamehelpbombay|Bombay]]&lt;br /&gt;
* [[Gamehelpboomerangaustralia|Boomerang: Australia]]&lt;br /&gt;
* [[Gamehelpboomerangeurope|Boomerang: Europe]]&lt;br /&gt;
* [[Gamehelpboomerangusa|Boomerang: USA]]&lt;br /&gt;
* [[Gamehelpbossquest|Boss Quest]]&lt;br /&gt;
* [[Gamehelpbreakthecode|Break the Code]]&lt;br /&gt;
* [[Gamehelpbriscola|Briscola]]&lt;br /&gt;
* [[Gamehelpbubbleepop|Bubblee Pop]]&lt;br /&gt;
* [[Gamehelpbug|Bug]]&lt;br /&gt;
* [[Gamehelpburglebros|Burgle Bros.]]&lt;br /&gt;
* [[Gamehelpbutterfly|Butterfly]]&lt;br /&gt;
* [[Gamehelpbuttons|Buttons]]&lt;br /&gt;
* [[Gamehelpcacao|Cacao]]&lt;br /&gt;
* [[Gamehelpcantstop|Can&#039;t Stop]]&lt;br /&gt;
* [[Gamehelpcantstopexpress|Can’t Stop Express]]&lt;br /&gt;
* [[Gamehelpcanosa|Canosa]]&lt;br /&gt;
* [[Gamehelpcaravan|Caravan]]&lt;br /&gt;
* [[Gamehelpcarcassonne|Carcassonne]]&lt;br /&gt;
* [[Gamehelpcarcassonnehuntersandgatherers|Carcassonne: Hunters &amp;amp;amp; Gatherers]]&lt;br /&gt;
* [[Gamehelpcardiceo|Cardiceo]]&lt;br /&gt;
* [[Gamehelpcaribbeanallfours|Caribbean All Fours]]&lt;br /&gt;
* [[Gamehelpcarnegie|Carnegie]]&lt;br /&gt;
* [[Gamehelpcatan|Catan]]&lt;br /&gt;
* [[Gamehelpcaylus|Caylus]]&lt;br /&gt;
* [[Gamehelpcelestia|Celestia]]&lt;br /&gt;
* [[Gamehelpcentury|Century]]&lt;br /&gt;
* [[Gamehelpcephalopod|Cephalopod]]&lt;br /&gt;
* [[Gamehelpchakra|Chakra]]&lt;br /&gt;
* [[Gamehelpcheckers|Checkers]]&lt;br /&gt;
* [[Gamehelpchess|Chess]]&lt;br /&gt;
* [[Gamehelpchinagold|China Gold]]&lt;br /&gt;
* [[Gamehelpchinesecheckers|Chinese Checkers]]&lt;br /&gt;
* [[Gamehelpchocolatefactory|Chocolate Factory]]&lt;br /&gt;
* [[Gamehelpchromino|Chromino]]&lt;br /&gt;
* [[Gamehelpcinco|Cinco]]&lt;br /&gt;
* [[Gamehelpcircleoflife|Circle of Life]]&lt;br /&gt;
* [[Gamehelpcityofthebigshoulders|City of the Big Shoulders]]&lt;br /&gt;
* [[Gamehelpclansofcaledonia|Clans of Caledonia]]&lt;br /&gt;
* [[Gamehelpclashofdecks|Clash of Decks]]&lt;br /&gt;
* [[Gamehelpcloudcity|Cloud City]]&lt;br /&gt;
* [[Gamehelpcodexnaturalis|CODEX Naturalis]]&lt;br /&gt;
* [[Gamehelpcoinche|Coinche]]&lt;br /&gt;
* [[Gamehelpcolorpop|Color Pop]]&lt;br /&gt;
* [[Gamehelpcoloretto|Coloretto]]&lt;br /&gt;
* [[Gamehelpcoltexpress|Colt Express]]&lt;br /&gt;
* [[Gamehelpconsonar|Con Sonar!]]&lt;br /&gt;
* [[Gamehelpconcept|Concept]]&lt;br /&gt;
* [[Gamehelpconnectfour|Connect Four]]&lt;br /&gt;
* [[Gamehelpconnectsix|Connect6]]&lt;br /&gt;
* [[Gamehelpconspiracy|Conspiracy]]&lt;br /&gt;
* [[Gamehelpcopenhagen|Copenhagen]]&lt;br /&gt;
* [[Gamehelpcoupcitystate|Coup]]&lt;br /&gt;
* [[Gamehelpcrazyfarmers|Crazy Farmers]]&lt;br /&gt;
* [[Gamehelpcribbage|Cribbage]]&lt;br /&gt;
* [[Gamehelpcrimezoom|Crime Zoom: A Dirty Objective]]&lt;br /&gt;
* [[Gamehelpcrusadersthywillbedone|Crusaders: Thy Will Be Done]]&lt;br /&gt;
* [[Gamehelpcubirds|CuBirds]]&lt;br /&gt;
* [[Gamehelpdarkagent|Dark Agent]]&lt;br /&gt;
* [[Gamehelpdetectivepoker|Detective Poker]]&lt;br /&gt;
* [[Gamehelpdeus|Deus]]&lt;br /&gt;
* [[Gamehelpdiablo|Diablo]]&lt;br /&gt;
* [[Gamehelpdiams|Diam&#039;s]]&lt;br /&gt;
  &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td valign=&amp;quot;top&amp;quot;&amp;gt;&lt;br /&gt;
* [[Gamehelpdiceforge|Dice Forge]]&lt;br /&gt;
* [[Gamehelpdicehospital|Dice Hospital]]&lt;br /&gt;
* [[Gamehelpdicesummoners|Dice Summoners]]&lt;br /&gt;
* [[Gamehelpdicedtomatoes|Diced Tomatoes]]&lt;br /&gt;
* [[Gamehelpdingosdreams|Dingo&#039;s Dreams]]&lt;br /&gt;
* [[Gamehelpdinosaurteaparty|Dinosaur Tea Party]]&lt;br /&gt;
* [[Gamehelpthroneandthegrail|District Noir]]&lt;br /&gt;
* [[Gamehelpdjambi|Djambi]]&lt;br /&gt;
* [[Gamehelpdodo|Dodo]]&lt;br /&gt;
* [[Gamehelpdownforce|Downforce]]&lt;br /&gt;
* [[Gamehelpdraftosaurus|Draftosaurus]]&lt;br /&gt;
* [[Gamehelpdragoncastle|Dragon Castle]]&lt;br /&gt;
* [[Gamehelpdragonkeeper|Dragon Keeper: The Dungeon]]&lt;br /&gt;
* [[Gamehelpdragonline|Dragon Line]]&lt;br /&gt;
* [[Gamehelpdragonheart|Dragonheart]]&lt;br /&gt;
* [[Gamehelpdragonwood|Dragonwood]]&lt;br /&gt;
* [[Gamehelpdungeonpetz|Dungeon Petz]]&lt;br /&gt;
* [[Gamehelpdungeonroll|Dungeon Roll]]&lt;br /&gt;
* [[Gamehelpdungeontwister|Dungeon Twister]]&lt;br /&gt;
* [[Gamehelpegocentricworld|Egocentric World]]&lt;br /&gt;
* [[Gamehelpelfenland|Elfenland]]&lt;br /&gt;
* [[Gamehelpelgrande|El Grande]]&lt;br /&gt;
* [[Gamehelpeminentdomain|Eminent Domain]]&lt;br /&gt;
* [[Gamehelpemdomicrocosm|Eminent Domain: Microcosm]]&lt;br /&gt;
* [[Gamehelpepizodiak|EpiZodiak]]&lt;br /&gt;
* [[Gamehelpakeruption|Eruption]]&lt;br /&gt;
* [[Gamehelpequinox|Equinox]]&lt;br /&gt;
* [[Gamehelpevl|EVL]]&lt;br /&gt;
* [[Gamehelpevogamenoname|Evo: The &amp;quot;Game no Name&amp;quot;]]&lt;br /&gt;
* [[Gamehelpnorthwestpassage|Expedition: Northwest Passage]]&lt;br /&gt;
* [[Gamehelpexplorationwarzone|Exploration: Warzone]]&lt;br /&gt;
* [[Gamehelpfactum|Factum]]&lt;br /&gt;
* [[Gamehelpfaifo|Fai-Fo]]&lt;br /&gt;
* [[Gamehelpfairytrails|Fairy Trails]]&lt;br /&gt;
* [[Gamehelpfarmclub|Farm Club]]&lt;br /&gt;
* [[Gamehelpfinity|Finity]]&lt;br /&gt;
* [[Gamehelpflamingpyramids|Flaming Pyramids]]&lt;br /&gt;
* [[Gamehelpfleet|Fleet]]&lt;br /&gt;
* [[Gamehelpflorenzacardgame|Florenza: The Card Game]]&lt;br /&gt;
* [[Gamehelpfluxx|Fluxx]]&lt;br /&gt;
* [[Gamehelpforex|For-Ex]]&lt;br /&gt;
* [[Gamehelpforsale|For Sale]]&lt;br /&gt;
* [[Gamehelpforbiddenisland|Forbidden Island]]&lt;br /&gt;
* [[Gamehelpfourcolorcards|Four Color Cards]]&lt;br /&gt;
* [[Gamehelpfractal|Fractal]]&lt;br /&gt;
* [[Gamehelpfrenchtarot|French Tarot]]&lt;br /&gt;
* [[Gamehelpfruitpicking|Fruit Picking]]&lt;br /&gt;
* [[Gamehelpgaia|Gaia]]&lt;br /&gt;
* [[Gamehelpgaiaproject|Gaia Project]]&lt;br /&gt;
* [[Gamehelpgearnpiston|Gear &amp;amp; Piston]]&lt;br /&gt;
* [[Gamehelpgetonboard|Get on Board: New York &amp;amp; London]]&lt;br /&gt;
* [[Gamehelpgetthemacguffin|Get the MacGuffin]]&lt;br /&gt;
* [[Gamehelpglow|Glow]]&lt;br /&gt;
* [[Gamehelpclassicgo|Go]]&lt;br /&gt;
* [[Gamehelpgonutsfordonuts|Go Nuts for Donuts]]&lt;br /&gt;
* [[Gamehelpgoldwest|Gold West]]&lt;br /&gt;
* [[Gamehelpgomoku|Gomoku]]&lt;br /&gt;
* [[Gamehelpgopher|Gopher]]&lt;br /&gt;
* [[Gamehelpgorami|GORami]]&lt;br /&gt;
* [[Gamehelpgosu|Gosu]]&lt;br /&gt;
* [[Gamehelpgrandbazaar|Grand Bazaar]]&lt;br /&gt;
* [[Gamehelpgreatwesterntrail|Great Western Trail]]&lt;br /&gt;
* [[Gamehelpgrosstarock|Grosstarock]]&lt;br /&gt;
* [[Gamehelpguildes|Guildes]]&lt;br /&gt;
* [[Gamehelpguile|Guile]]&lt;br /&gt;
* [[Gamehelpgyges|Gygès]]&lt;br /&gt;
* [[Gamehelphacktrick|Hack Trick]]&lt;br /&gt;
* [[Gamehelphadron|Hadron]]&lt;br /&gt;
* [[Gamehelphaggis|Haggis]]&lt;br /&gt;
* [[Gamehelphaiclue|Haiclue]]&lt;br /&gt;
* [[Gamehelphanabi|Hanabi]]&lt;br /&gt;
* [[Gamehelphandandfoot|Hand and Foot]]&lt;br /&gt;
* [[Gamehelphappycity|Happy City]]&lt;br /&gt;
* [[Gamehelphardback|Hardback]]&lt;br /&gt;
* [[Gamehelphawaii|Hawaii]]&lt;br /&gt;
* [[Gamehelphearts|Hearts]]&lt;br /&gt;
* [[Gamehelpheckinhounds|Heckin Hounds]]&lt;br /&gt;
* [[Gamehelpherd|Herd]]&lt;br /&gt;
* [[Gamehelpherooj|Herooj]]&lt;br /&gt;
* [[Gamehelpherrlof|Herrlof]]&lt;br /&gt;
* [[Gamehelphex|Hex]]&lt;br /&gt;
* [[Gamehelphive|Hive]]&lt;br /&gt;
* [[Gamehelphoarders|Hoarders]]&lt;br /&gt;
* [[Gamehelphomesteaders|Homesteaders]]&lt;br /&gt;
* [[Gamehelphomeworlds|Homeworlds]]&lt;br /&gt;
* [[Gamehelpescapefromthehiddencastle|HUGO]]&lt;br /&gt;
* [[Gamehelphungariantarokk|Hungarian Tarokk]]&lt;br /&gt;
* [[Gamehelphypnosia|Hypnosia]]&lt;br /&gt;
* [[Gamehelpiceandthesky|Ice and the Sky]]&lt;br /&gt;
* [[Gamehelpicecoldicehockey|Ice Cold Ice Hockey]]&lt;br /&gt;
* [[Gamehelpicebreaker|Icebreaker]]&lt;br /&gt;
* [[Gamehelpillustori|Illustori]]&lt;br /&gt;
* [[Gamehelpimhotep|Imhotep]]&lt;br /&gt;
* [[Gamehelpimpasse|Impasse]]&lt;br /&gt;
* [[Gamehelpintheyearofthedragon|In The Year of the Dragon]]&lt;br /&gt;
* [[Gamehelpincangold|Incan Gold]]&lt;br /&gt;
* [[Gamehelpinnovation|Innovation]]&lt;br /&gt;
* [[Gamehelpinsert|Insert]]&lt;br /&gt;
* [[Gamehelpisaac|Isaac]]&lt;br /&gt;
* [[Gamehelpiwari|Iwari]]&lt;br /&gt;
* [[Gamehelpjaipur|Jaipur]]&lt;br /&gt;
* [[Gamehelpjekyllvshide|Jekyll vs. Hyde]]&lt;br /&gt;
* [[Gamehelpjumpdrive|Jump Drive]]&lt;br /&gt;
* [[Gamehelpjumpgate|Jump Gate]]&lt;br /&gt;
* [[Gamehelpjustdesserts|Just Desserts]]&lt;br /&gt;
* [[Gamehelpjustone|Just One]]&lt;br /&gt;
* [[Gamehelpk2|K2]]&lt;br /&gt;
* [[Gamehelpkabaleo|Kabaleo]]&lt;br /&gt;
* [[Gamehelpkahuna|Kahuna]]&lt;br /&gt;
* [[Gamehelpkalah|Kalah]]&lt;br /&gt;
* [[Gamehelpkami|Kami]]&lt;br /&gt;
* [[Gamehelpkeyflower|Keyflower]]&lt;br /&gt;
* [[Gamehelpkhronos|Khronos]]&lt;br /&gt;
* [[Gamehelpkingofthepitch|King of the Pitch]]&lt;br /&gt;
* [[Gamehelpkingoftokyo|King of Tokyo]]&lt;br /&gt;
* [[Gamehelpkingdombuilder|Kingdom Builder]]&lt;br /&gt;
* [[Gamehelpkingdomino|Kingdomino]]&lt;br /&gt;
* [[Gamehelpklaverjassen|Klaverjassen]]&lt;br /&gt;
* [[Gamehelpkoikoi|Koi-Koi]]&lt;br /&gt;
  &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td valign=&amp;quot;top&amp;quot;&amp;gt;&lt;br /&gt;
* [[Gamehelpkoryo|Koryŏ]]&lt;br /&gt;
* [[Gamehelpkqj|KQJ]]&lt;br /&gt;
* [[Gamehelpkrosmasterarena|Krosmaster Arena]]&lt;br /&gt;
* [[Gamehelpkrosmasterblast|Krosmaster Blast]]&lt;br /&gt;
* [[Gamehelplagranja|La Granja]]&lt;br /&gt;
* [[Gamehelpladyandthetiger|Lady and the Tiger]]&lt;br /&gt;
* [[Gamehelplasvegan|Las Vegan]]&lt;br /&gt;
* [[Gamehelpledernierpeuple|Le Dernier Peuple]]&lt;br /&gt;
* [[Gamehelpinventors|Legendary Inventors]]&lt;br /&gt;
* [[Gamehelplettertycoon|Letter Tycoon]]&lt;br /&gt;
* [[Gamehelplewisclark|Lewis &amp;amp;amp; Clark]]&lt;br /&gt;
* [[Gamehelplibertalia|Libertalia]]&lt;br /&gt;
* [[Gamehelplinesofaction|Lines of Action]]&lt;br /&gt;
* [[Gamehelplinkage|Linkage]]&lt;br /&gt;
* [[Gamehelplittlefactory|Little Factory]]&lt;br /&gt;
* [[Gamehelplivingforest|Living Forest]]&lt;br /&gt;
* [[Gamehelplama|LLAMA]]&lt;br /&gt;
* [[Gamehelplocomomo|Loco Momo]]&lt;br /&gt;
* [[Gamehelplogger|Logger]]&lt;br /&gt;
* [[Gamehelplox|Lords of Xidit]]&lt;br /&gt;
* [[Gamehelplostcities|Lost Cities]]&lt;br /&gt;
* [[Gamehelplostexplorers|Lost Explorers]]&lt;br /&gt;
* [[Gamehelparnak|Lost Ruins of Arnak]]&lt;br /&gt;
* [[Gamehelploveletter|Love Letter]]&lt;br /&gt;
* [[Gamehelpluckynumbers|Lucky Numbers]]&lt;br /&gt;
* [[Gamehelpluxor|Luxor]]&lt;br /&gt;
* [[Gamehelpmachiavelli|Machiavelli]]&lt;br /&gt;
* [[Gamehelpmadeira|Madeira]]&lt;br /&gt;
* [[Gamehelpmammalath|Mammalath]]&lt;br /&gt;
* [[Gamehelpmapmaker|Mapmaker: The Gerrymandering Game]]&lt;br /&gt;
* [[Gamehelpmarcopolotwo|Marco Polo II: In the Service of the Khan]]&lt;br /&gt;
* [[Gamehelpmarrakech|Marrakech]]&lt;br /&gt;
* [[Gamehelpmarram|Marram]]&lt;br /&gt;
* [[Gamehelpmartiandice|Martian Dice]]&lt;br /&gt;
* [[Gamehelpmascarade|Mascarade]]&lt;br /&gt;
* [[Gamehelpmattock|Mattock]]&lt;br /&gt;
* [[Gamehelpmedina|Medina]]&lt;br /&gt;
* [[Gamehelpmeadow|Medo]]&lt;br /&gt;
* [[Gamehelpmetromania|Metromania]]&lt;br /&gt;
* [[Gamehelpmijnlieff|Mijnlieff]]&lt;br /&gt;
* [[Gamehelpmonsterfactory|Monster Factory]]&lt;br /&gt;
* [[Gamehelpmow|MOW]]&lt;br /&gt;
* [[Gamehelpmrjack|Mr. Jack]]&lt;br /&gt;
* [[Gamehelpmurusgallicus|Murus Gallicus]]&lt;br /&gt;
* [[Gamehelpmyshelfie|My Shelfie]]&lt;br /&gt;
* [[Gamehelpnangaparbat|Nanga Parbat]]&lt;br /&gt;
* [[Gamehelpnarabi|Narabi]]&lt;br /&gt;
* [[Gamehelpnautilus|Nautilus]]&lt;br /&gt;
* [[Gamehelpneutreeko|Neutreeko]]&lt;br /&gt;
* [[Gamehelpnewfrontiers|New Frontiers]]&lt;br /&gt;
* [[Gamehelpnextstation|Next Station: London]]&lt;br /&gt;
* [[Gamehelpniagara|Niagara]]&lt;br /&gt;
* [[Gamehelpnicodemus|Nicodemus]]&lt;br /&gt;
* [[Gamehelpnidavellir|Nidavellir]]&lt;br /&gt;
* [[Gamehelpaknile|Nile]]&lt;br /&gt;
* [[Gamehelpninemensmorris|Nine Men&#039;s Morris]]&lt;br /&gt;
* [[Gamehelpnippon|Nippon]]&lt;br /&gt;
* [[Gamehelpnothanks|No Thanks!]]&lt;br /&gt;
* [[Gamehelpnoah|Noah]]&lt;br /&gt;
* [[Gamehelpnoirkvi|Noir: Killer versus Inspector]]&lt;br /&gt;
* [[Gamehelpnotalone|Not Alone]]&lt;br /&gt;
* [[Gamehelpnumberdrop|Number Drop]]&lt;br /&gt;
* [[Gamehelpnxs|NXS]]&lt;br /&gt;
* [[Gamehelpofftherails|Off the Rails]]&lt;br /&gt;
* [[Gamehelpohhell|Oh Hell!]]&lt;br /&gt;
* [[Gamehelpohseven|Oh-Seven]]&lt;br /&gt;
* [[Gamehelponceuponaforest|Once Upon A Forest]]&lt;br /&gt;
* [[Gamehelpone|ONE]]&lt;br /&gt;
* [[Gamehelponitama|Onitama]]&lt;br /&gt;
* [[Gamehelporiflamme|Oriflamme]]&lt;br /&gt;
* [[Gamehelporigin|Origin]]&lt;br /&gt;
* [[Gamehelpoust|Oust]]&lt;br /&gt;
* [[Gamehelpoutlaws|Outlaws: Last Man Standing]]&lt;br /&gt;
* [[Gamehelppi|P.I.]]&lt;br /&gt;
* [[Gamehelppalace|Palace]]&lt;br /&gt;
* [[Gamehelppandemic|Pandemic]]&lt;br /&gt;
* [[Gamehelppapayoo|Papayoo]]&lt;br /&gt;
* [[Gamehelpparisconnection|Paris Connection]]&lt;br /&gt;
* [[Gamehelpparks|PARKS]]&lt;br /&gt;
* [[Gamehelppatchwork|Patchwork]]&lt;br /&gt;
* [[Gamehelppedro|Pedro]]&lt;br /&gt;
* [[Gamehelppenaltychallenge|Penalty Challenge]]&lt;br /&gt;
* [[Gamehelppennypress|Penny Press]]&lt;br /&gt;
* [[Gamehelppente|Pente]]&lt;br /&gt;
* [[Gamehelpdudo|Perudo]]&lt;br /&gt;
* [[Gamehelpphat|Phat]]&lt;br /&gt;
* [[Gamehelppingimus|Pingimus]]&lt;br /&gt;
* [[Gamehelppiratenkapern|Piraten kapern]]&lt;br /&gt;
* [[Gamehelppolis|Polis: Fight for Hegemony]]&lt;br /&gt;
* [[Gamehelppontedeldiavolo|Ponte del Diavolo]]&lt;br /&gt;
* [[Gamehelppotionexplosion|Potion Explosion]]&lt;br /&gt;
* [[Gamehelppuertorico|Puerto Rico]]&lt;br /&gt;
* [[Gamehelppylos|Pylos]]&lt;br /&gt;
* [[Gamehelppyramidpoker|Pyramid Poker]]&lt;br /&gt;
* [[Gamehelppyrga|Pyrga]]&lt;br /&gt;
* [[Gamehelpquantik|Quantik]]&lt;br /&gt;
* [[Gamehelpquantum|Quantum]]&lt;br /&gt;
* [[Gamehelpquarto|Quarto]]&lt;br /&gt;
* [[Gamehelpqueenskings|Queens and Kings... A Checkers Game]]&lt;br /&gt;
* [[Gamehelpquetzal|Quetzal]]&lt;br /&gt;
* [[Gamehelpquinque|Quinque]]&lt;br /&gt;
* [[Gamehelpquoridor|Quoridor]]&lt;br /&gt;
* [[Gamehelpraceforthegalaxy|Race for the Galaxy]]&lt;br /&gt;
* [[Gamehelprage|Rage]]&lt;br /&gt;
* [[Gamehelprailroadink|Railroad Ink]]&lt;br /&gt;
* [[Gamehelprailwaysoftheworld|Railways of the World]]&lt;br /&gt;
* [[Gamehelprainbow|Rainbow]]&lt;br /&gt;
* [[Gamehelprallymangt|Rallyman: GT]]&lt;br /&gt;
* [[Gamehelpredseven|Red7]]&lt;br /&gt;
* [[Gamehelpredstone|Redstone]]&lt;br /&gt;
* [[Gamehelpregicide|Regicide]]&lt;br /&gt;
* [[Gamehelpregidice|Regidice]]&lt;br /&gt;
* [[Gamehelprememberwhen|Remember When]]&lt;br /&gt;
* [[Gamehelpresarcana|Res Arcana]]&lt;br /&gt;
* [[Gamehelprestinpeace|Rest In Peace]]&lt;br /&gt;
* [[Gamehelpreversi|Reversi]]&lt;br /&gt;
* [[Gamehelprive|Rive]]&lt;br /&gt;
* [[Gamehelprollforthegalaxy|Roll for the Galaxy]]&lt;br /&gt;
* [[Gamehelprolledwest|Rolled West]]&lt;br /&gt;
* [[Gamehelprollandbump|Roll’n Bump]]&lt;br /&gt;
* [[Gamehelproppyakken|Roppyakken]]&lt;br /&gt;
* [[Gamehelprussianrailroads|Russian Railroads]]&lt;br /&gt;
  &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td valign=&amp;quot;top&amp;quot;&amp;gt;&lt;br /&gt;
* [[Gamehelpsaboteur|Saboteur]]&lt;br /&gt;
* [[Gamehelpsaintpetersburg|Saint Petersburg]]&lt;br /&gt;
* [[Gamehelpsaintpoker|Saint Poker]]&lt;br /&gt;
* [[Gamehelpsantorini|Santorini]]&lt;br /&gt;
* [[Gamehelpsapiens|Sapiens]]&lt;br /&gt;
* [[Gamehelpschroedingerscats|Schrodinger&#039;s Cats]]&lt;br /&gt;
* [[Gamehelpscopa|Scopa]]&lt;br /&gt;
* [[Gamehelpseasaltpaper|Sea Salt &amp;amp; Paper]]&lt;br /&gt;
* [[Gamehelpseasons|Seasons]]&lt;br /&gt;
* [[Gamehelpsecretmoon|Secret Moon]]&lt;br /&gt;
* [[Gamehelpsenet|Senet]]&lt;br /&gt;
* [[Gamehelpsenshi|Senshi]]&lt;br /&gt;
* [[Gamehelpshiftingstones|Shifting Stones]]&lt;br /&gt;
* [[Gamehelpsiam|Siam]]&lt;br /&gt;
* [[Gamehelpsignorie|Signorie]]&lt;br /&gt;
* [[Gamehelpsilo|Silo]]&lt;br /&gt;
* [[Gamehelpsimilo|Similo]]&lt;br /&gt;
* [[Gamehelpsimplicity|Simplicity]]&lt;br /&gt;
* [[Gamehelpskat|Skat]]&lt;br /&gt;
* [[Gamehelpskull|Skull]]&lt;br /&gt;
* [[Gamehelpsmallislands|Small Islands]]&lt;br /&gt;
* [[Gamehelpsobek|Sobek]]&lt;br /&gt;
* [[Gamehelpsobektwoplayers|Sobek 2 players]]&lt;br /&gt;
* [[Gamehelpsolarstorm|Solar Storm]]&lt;br /&gt;
* [[Gamehelpsolo|Solo]]&lt;br /&gt;
* [[Gamehelpsolowhist|Solo Whist]]&lt;br /&gt;
* [[Gamehelpsoluna|Soluna]]&lt;br /&gt;
* [[Gamehelpspacebase|Space Base]]&lt;br /&gt;
* [[Gamehelpspacestationphoenix|Space Station Phoenix]]&lt;br /&gt;
* [[Gamehelpspades|Spades]]&lt;br /&gt;
* [[Gamehelpsparts|Sparts]]&lt;br /&gt;
* [[Gamehelpsplendor|Splendor]]&lt;br /&gt;
* [[Gamehelpsplito|Splito]]&lt;br /&gt;
* [[Gamehelpspotit|Spot It (or Dobble)]]&lt;br /&gt;
* [[Gamehelpspyrium|Spyrium]]&lt;br /&gt;
* [[Gamehelpsquadro|Squadro]]&lt;br /&gt;
* [[Gamehelpstarfluxx|Star Fluxx]]&lt;br /&gt;
* [[Gamehelpsteamrollers|SteamRollers]]&lt;br /&gt;
* [[Gamehelpsteamworks|Steam Works]]&lt;br /&gt;
* [[Gamehelpstella|Stella: Dixit Universe]]&lt;br /&gt;
* [[Gamehelpstirfryeighteen|Stir Fry Eighteen]]&lt;br /&gt;
* [[Gamehelpstoneage|Stone Age]]&lt;br /&gt;
* [[Gamehelpsuperfantasybrawl|Super Fantasy Brawl]]&lt;br /&gt;
* [[Gamehelpsushigo|Sushi Go!]]&lt;br /&gt;
* [[Gamehelpsushigoparty|Sushi Go Party]]&lt;br /&gt;
* [[Gamehelptablut|Tablut]]&lt;br /&gt;
* [[Gamehelptakaraisland|Takara Island]]&lt;br /&gt;
* [[Gamehelptakenoko|Takenoko]]&lt;br /&gt;
* [[Gamehelptaluva|Taluva]]&lt;br /&gt;
* [[Gamehelptapestry|Tapestry]]&lt;br /&gt;
* [[Gamehelptargi|Targi]]&lt;br /&gt;
* [[Gamehelptashkalar|Tash-Kalar]]&lt;br /&gt;
* [[Gamehelpteatime|Tea Time]]&lt;br /&gt;
* [[Gamehelpteotihuacan|Teotihuacan: City of Gods]]&lt;br /&gt;
* [[Gamehelpterramystica|Terra Mystica]]&lt;br /&gt;
* [[Gamehelpthatslife|That&#039;s Life (or Verflixxt!)]]&lt;br /&gt;
* [[Gamehelpbattleforhill|The Battle for Hill 218]]&lt;br /&gt;
* [[Gamehelptheboss|The Boss]]&lt;br /&gt;
* [[Gamehelpthebuildersantiquity|The Builders: Antiquity]]&lt;br /&gt;
* [[Gamehelpthebuilders|The Builders: Middle Ages]]&lt;br /&gt;
* [[Gamehelpcastlesofburgundy|The Castles of Burgundy]]&lt;br /&gt;
* [[Gamehelpthecrew|The Crew]]&lt;br /&gt;
* [[Gamehelpthecrewdeepsea|The Crew: Mission Deep Sea]]&lt;br /&gt;
* [[Gamehelptheisleofcats|The Isle of Cats]]&lt;br /&gt;
* [[Gamehelpthejellymonsterlab|The Jelly Monster Lab]]&lt;br /&gt;
* [[Gamehelpkingsguild|The King&#039;s Guild]]&lt;br /&gt;
* [[Gamehelpcarrara|The Palaces of Carrara]]&lt;br /&gt;
* [[Gamehelpruhr|The Ruhr: A Story of Coal Trade]]&lt;br /&gt;
* [[Gamehelpmarcopolo|The Voyages of Marco Polo]]&lt;br /&gt;
* [[Gamehelpwerewolves|The Werewolves of Miller&#039;s Hollow]]&lt;br /&gt;
* [[Gamehelpthermopyles|Thermopyles]]&lt;br /&gt;
* [[Gamehelpthrive|Thrive]]&lt;br /&gt;
* [[Gamehelpthroughtheages|Through the Ages]]&lt;br /&gt;
* [[Gamehelpthroughtheagesnewstory|Through the Ages: A new Story of Civilization]]&lt;br /&gt;
* [[Gamehelpthurnandtaxis|Thurn and Taxis]]&lt;br /&gt;
* [[Gamehelptichu|Tichu]]&lt;br /&gt;
* [[Gamehelptickettoride|Ticket to Ride]]&lt;br /&gt;
* [[Gamehelptigriseuphrates|Tigris Euphrates]]&lt;br /&gt;
* [[Gamehelptiki|Tiki]]&lt;br /&gt;
* [[Gamehelptimemasters|Time Masters]]&lt;br /&gt;
* [[Gamehelptobago|Tobago]]&lt;br /&gt;
* [[Gamehelptock|Tock]]&lt;br /&gt;
* [[Gamehelptoeshambo|ToeShamBo]]&lt;br /&gt;
* [[Gamehelptokaido|Tokaido]]&lt;br /&gt;
* [[Gamehelptournay|Tournay]]&lt;br /&gt;
* [[Gamehelptranquility|Tranquility]]&lt;br /&gt;
* [[Gamehelptrektwelve|Trek 12]]&lt;br /&gt;
* [[Gamehelptrekkingtheworld|Trekking the World]]&lt;br /&gt;
* [[Gamehelptrickoftherails|Trick of the Rails]]&lt;br /&gt;
* [[Gamehelptroyes|Troyes]]&lt;br /&gt;
* [[Gamehelptroyesdice|Troyes Dice]]&lt;br /&gt;
* [[Gamehelptumbleweed|Tumbleweed]]&lt;br /&gt;
* [[Gamehelpturnthetide|Turn the tide]]&lt;br /&gt;
* [[Gamehelptwintinbots|Twin Tin Bots]]&lt;br /&gt;
* [[Gamehelptwinpalms|Twin Palms]]&lt;br /&gt;
* [[Gamehelptzolkin|Tzolk&#039;in]]&lt;br /&gt;
* [[Gamehelpultimaterailroads|Ultimate Railroads]]&lt;br /&gt;
* [[Gamehelpunclechestnuttablegype|Uncle Chestnut&#039;s Table Gype]]&lt;br /&gt;
* [[Gamehelpunconditionalsurrender|Unconditional Surrender! World War 2 in Europe]]&lt;br /&gt;
* [[Gamehelpunitedsquare|United Square]]&lt;br /&gt;
* [[Gamehelpuptown|Uptown]]&lt;br /&gt;
* [[Gamehelpvegetables|VEGEtables]]&lt;br /&gt;
* [[Gamehelpveggiegarden|Veggie Garden]]&lt;br /&gt;
* [[Gamehelpvektorace|VektoRace]]&lt;br /&gt;
* [[Gamehelpveletas|Veletas]]&lt;br /&gt;
* [[Gamehelpveronatwist|Verona Twist]]&lt;br /&gt;
* [[Gamehelpviamagica|Via Magica]]&lt;br /&gt;
* [[Gamehelpviticulture|Viticulture]]&lt;br /&gt;
* [[Gamehelpvultureculture|Vulture Culture]]&lt;br /&gt;
* [[Gamehelpwelcometo|Welcome To]]&lt;br /&gt;
* [[Gamehelpwelcometonewlasvegas|Welcome To New Las Vegas]]&lt;br /&gt;
* [[Gamehelpwhisttwentytwo|Whist 22]]&lt;br /&gt;
* [[Gamehelpwingspan|Wingspan]]&lt;br /&gt;
* [[Gamehelpwizard|Wizard]]&lt;br /&gt;
* [[Gamehelpxiangqi|Xiangqi]]&lt;br /&gt;
* [[Gamehelpyatzy|Yahtzee]]&lt;br /&gt;
* [[Gamehelpyinyang|Yin Yang]]&lt;br /&gt;
* [[Gamehelpyokai|Yokai]]&lt;br /&gt;
* [[Gamehelpyokohama|Yokohama]]&lt;br /&gt;
* [[Gamehelpzener|Zener]]&lt;br /&gt;
* [[Gamehelpzola|Zola]]&lt;br /&gt;
  &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td valign=&amp;quot;top&amp;quot;&amp;gt;&lt;br /&gt;
* [[Gamehelpartthief|Art Thief]]&lt;br /&gt;
* [[Gamehelpblackjack|Blackjack]]&lt;br /&gt;
* [[Gamehelpbuyword|BuyWord]]&lt;br /&gt;
* [[Gamehelpcapereurope|Caper: Europe]]&lt;br /&gt;
* [[Gamehelpcastlesofcaleira|Castles of Caleira]]&lt;br /&gt;
* [[Gamehelpcaverna|Caverna]]&lt;br /&gt;
* [[Gamehelpchicagoexpress|Chicago Express]]&lt;br /&gt;
* [[Gamehelpchimerastation|Chimera Station]]&lt;br /&gt;
* [[Gamehelpcommanderchess|Commander Chess]]&lt;br /&gt;
* [[Gamehelpcoupell|Coupell]]&lt;br /&gt;
* [[Gamehelpdicethemepark|Dice Theme Park]]&lt;br /&gt;
* [[Gamehelpdinnerinparis|Dinner in Paris]]&lt;br /&gt;
* [[Gamehelpdotsandboxes|Dots and Boxes]]&lt;br /&gt;
* [[Gamehelpdraftcider|Draft Cider]]&lt;br /&gt;
* [[Gamehelpdragonbridge|Dragon Bridge]]&lt;br /&gt;
* [[Gamehelpekonos|EKONOS]]&lt;br /&gt;
* [[Gamehelpflume|Flume]]&lt;br /&gt;
* [[Gamehelpfortheking|For the King (and Me)]]&lt;br /&gt;
* [[Gamehelpgangsta|Gangsta!]]&lt;br /&gt;
* [[Gamehelpgardennation|Garden Nation]]&lt;br /&gt;
* [[Gamehelpgeekoutmasters|Geek Out! Masters]]&lt;br /&gt;
* [[Gamehelpghostathome|Ghost at Home]]&lt;br /&gt;
* [[Gamehelpgofish|Go Fish]]&lt;br /&gt;
* [[Gamehelpgoodcopbadcop|Good Cop Bad Cop]]&lt;br /&gt;
* [[Gamehelphoola|Hoola]]&lt;br /&gt;
* [[Gamehelphydroracers|Hydroracers]]&lt;br /&gt;
* [[Gamehelpimtheboss|I&#039;m the Boss]]&lt;br /&gt;
* [[Gamehelpitsawonderfulworld|It’s a Wonderful World]]&lt;br /&gt;
* [[Gamehelpriichimahjong|Japanese (Riichi) Mahjong]]&lt;br /&gt;
* [[Gamehelpkingdoms|Kingdoms]]&lt;br /&gt;
* [[Gamehelpkmakici|Kmakici Family&#039;s Greatest Teatime]]&lt;br /&gt;
* [[Gamehelpkonane|Konane]]&lt;br /&gt;
* [[Gamehelpkrakenup|Kraken Up]]&lt;br /&gt;
* [[Gamehelpkulami|Kulami]]&lt;br /&gt;
* [[Gamehelpladyschoice|Lady’s Choice]]&lt;br /&gt;
* [[Gamehelplamarcheducrabe|La Marche Du Crabe]]&lt;br /&gt;
* [[Gamehelpheroesofhellas|Legends of Hellas]]&lt;br /&gt;
* [[Gamehelplifeline|Lifeline]]&lt;br /&gt;
* [[Gamehelplineae|Lineae]]&lt;br /&gt;
* [[Gamehelpliverpoolrummy|Liverpool (Cozy Oaks) Rummy]]&lt;br /&gt;
* [[Gamehelplookatthestars|Look at the Stars]]&lt;br /&gt;
* [[Gamehelpmegalomania|Megalomania]]&lt;br /&gt;
* [[Gamehelpmemoir|Memoir 44]]&lt;br /&gt;
* [[Gamehelpmercadodelisboaste|Mercado de Lisboa]]&lt;br /&gt;
* [[Gamehelpmeridians|Meridians]]&lt;br /&gt;
* [[Gamehelpminhwatu|Minhwatu]]&lt;br /&gt;
* [[Gamehelpmorocco|Morocco]]&lt;br /&gt;
* [[Gamehelpmycity|My City]]&lt;br /&gt;
* [[Gamehelpmyfirstcastlepanic|My First Castle Panic]]&lt;br /&gt;
* [[Gamehelpobsessiion|Obsession]]&lt;br /&gt;
* [[Gamehelppaniclab|Panic Lab]]&lt;br /&gt;
* [[Gamehelppiereighteen|Pier 18]]&lt;br /&gt;
* [[Gamehelppointsalad|Point Salad]]&lt;br /&gt;
* [[Gamehelppresident|President]]&lt;br /&gt;
* [[Gamehelppugsinmugs|Pugs in Mugs]]&lt;br /&gt;
* [[Gamehelpreflection|Reflection]]&lt;br /&gt;
* [[Gamehelprobotsateourpizza|Robots Ate Our Pizza]]&lt;br /&gt;
* [[Gamehelproomtwentyfive|Room 25]]&lt;br /&gt;
* [[Gamehelpsamarkand|Samarkand]]&lt;br /&gt;
* [[Gamehelpseikatsu|Seikatsu]]&lt;br /&gt;
* [[Gamehelpsensei|Sensei]]&lt;br /&gt;
* [[Gamehelpsevens|Sevens]]&lt;br /&gt;
* [[Gamehelpsheepboombah|Sheep Boom Bah]]&lt;br /&gt;
* [[Gamehelpsoulaween|Soulaween]]&lt;br /&gt;
* [[Gamehelpspaceempires|Space Empire: 4X]]&lt;br /&gt;
* [[Gamehelpstrands|Strands]]&lt;br /&gt;
* [[Gamehelptalon|Talon]]&lt;br /&gt;
* [[Gamehelpthemotherroad|The Mother Road: Route 66]]&lt;br /&gt;
* [[Gamehelptheninedomains|The Nine Domains]]&lt;br /&gt;
* [[Gamehelptictacmatch|Tic-Tac Matc#]]&lt;br /&gt;
* [[Gamehelptinnerstrail|Tinner&#039;s Trail]]&lt;br /&gt;
* [[Gamehelptinyfarms|Tiny Farms]]&lt;br /&gt;
* [[Gamehelptrusis|Trusis]]&lt;br /&gt;
* [[Gamehelptucano|Tucano]]&lt;br /&gt;
* [[Gamehelpvolfyirion|Volfyirion Guilds]]&lt;br /&gt;
* [[Gamehelpworldwidetennis|Worldwide Tennis]]&lt;br /&gt;
* [[Gamehelpyaniv|Yaniv]]&lt;br /&gt;
* [[Gamehelpyoxii|Yoxii]]&lt;br /&gt;
* [[Gamehelpzooloretto|Zooloretto]]&lt;br /&gt;
  &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td valign=&amp;quot;top&amp;quot;&amp;gt;&lt;br /&gt;
* [[Gamehelpfifteendays|15 Days]]&lt;br /&gt;
* [[Gamehelpbohnanza|Bohnanza]]&lt;br /&gt;
* [[Gamehelpboomeranglm|Boomerang]]&lt;br /&gt;
* [[Gamehelpcalypso|Calypso]]&lt;br /&gt;
* [[Gamehelpchampionsofmidgard|Champions of Midgard]]&lt;br /&gt;
* [[Gamehelpcicerabigia|Cicera Bigia]]&lt;br /&gt;
* [[Gamehelpcitadels|Citadels]]&lt;br /&gt;
* [[Gamehelpcoinage|Coin Age]]&lt;br /&gt;
* [[Gamehelpcosmosempires|Cosmos: Empires]]&lt;br /&gt;
* [[Gamehelpcrazyeights|Crazy Eights]]&lt;br /&gt;
* [[Gamehelpdaihasamishogi|Dai Hasami Shogi]]&lt;br /&gt;
* [[Gamehelpdurak|Durak]]&lt;br /&gt;
* [[Gamehelpginkgopolis|Ginkgopolis]]&lt;br /&gt;
* [[Gamehelpgravitysuperstar|Gravity Superstar]]&lt;br /&gt;
* [[Gamehelpguibole|Guibole]]&lt;br /&gt;
* [[Gamehelphats|Hats]]&lt;br /&gt;
* [[Gamehelpindianchief|Indian Chief]]&lt;br /&gt;
* [[Gamehelpmagicmaze|Magic Maze]]&lt;br /&gt;
* [[Gamehelpmahjong|Mahjong]]&lt;br /&gt;
* [[Gamehelpmanhattannewgame|Manhattan]]&lt;br /&gt;
* [[Gamehelpmantisfalls|Mantis Falls]]&lt;br /&gt;
* [[Gamehelpmartianchess|Martian Chess]]&lt;br /&gt;
* [[Gamehelpminnesotawhist|Minnesota Whist]]&lt;br /&gt;
* [[Gamehelpmu|Mu]]&lt;br /&gt;
* [[Gamehelpnainjaune|Nain Jaune]]&lt;br /&gt;
* [[Gamehelppinochle|Pinochle]]&lt;br /&gt;
* [[Gamehelpfixtheteleporter|Please Fix the Teleporter]]&lt;br /&gt;
* [[Gamehelptexasholdem|Poker Texas Hold&#039;em]]&lt;br /&gt;
* [[Gamehelpriftforce|Riftforce]]&lt;br /&gt;
* [[Gamehelpristiseiska|Ristiseiska]]&lt;br /&gt;
* [[Gamehelpschwimmen|Schwimmen]]&lt;br /&gt;
* [[Gamehelpninefivetwo|Sergeant Major]]&lt;br /&gt;
* [[Gamehelpsnekagon|Snekagon]]&lt;br /&gt;
* [[Gamehelpsnowtime|Snow Time]]&lt;br /&gt;
* [[Gamehelpspiritsoftheforest|Spirits of the Forest]]&lt;br /&gt;
* [[Gamehelptemplari|Templari]]&lt;br /&gt;
* [[Gamehelpthreespot|Three Spot]]&lt;br /&gt;
* [[Gamehelptrasteroslocoscrazyauctions|Trasteros Locos: Crazy Auctions]]&lt;br /&gt;
* [[Gamehelptroggu|Troggu]]&lt;br /&gt;
* [[Gamehelpwatergate|Watergate]]&lt;br /&gt;
* [[Gamehelpwazabi|Wazabi]]&lt;br /&gt;
* [[Gamehelpxanadu|Xanadu]]&lt;br /&gt;
* [[Gamehelpyspahan|Yspahan]]&lt;br /&gt;
  &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td valign=&amp;quot;top&amp;quot;&amp;gt;&lt;br /&gt;
* [[Gamehelpdominion|Dominion]]&lt;br /&gt;
* [[Gamehelpinjawara|INJAWARA]]&lt;br /&gt;
* [[Gamehelpharbour|Harbour]]&lt;br /&gt;
  &amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== About available games and their content ==&lt;br /&gt;
&lt;br /&gt;
Games are games and it&#039;s all up to publishers to make them relevant or accurate to history, or not.&lt;br /&gt;
&lt;br /&gt;
We&#039;re focusing on gameplay and rules. We&#039;re not history books, nor an accurate source for anything related to real things.&lt;br /&gt;
&lt;br /&gt;
BGA is against any bad behaviors on real people, and will never EVER join, talk or expose about anything about themes, history or politics.&lt;br /&gt;
&lt;br /&gt;
Also please note that they&#039;re also a source to motivate talks, reflexion, exchange and viewpoints about history and education anywhere else.&lt;br /&gt;
&lt;br /&gt;
We&#039;re a gaming platform, we welcome everyone and do efforts daily to make this place a nice place to play nice games with nice people.&lt;/div&gt;</summary>
		<author><name>SwHawk</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Help&amp;diff=15248</id>
		<title>Help</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Help&amp;diff=15248"/>
		<updated>2022-11-11T16:21:14Z</updated>

		<summary type="html">&lt;p&gt;SwHawk: Undo revision 15240 by Jenna Beasley (talk)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is supposed to be a fun place to play, why the fuck do you ruin it with your shit policies.&lt;br /&gt;
You fucking assholes are so entitled. What gives you the right to punish people for no reason? I didn&#039;t do anything wrong, no I won&#039;t click on that shitty &amp;quot;I&#039;ve read and understood the moderation, and I agree to not do this again.&amp;quot; and I&#039;ll never pay anything. There is litteralty nowhere to complain expect editing the page....... Fuck you all for this bullshit&lt;/div&gt;</summary>
		<author><name>SwHawk</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Help&amp;diff=15174</id>
		<title>Help</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Help&amp;diff=15174"/>
		<updated>2022-11-02T14:48:06Z</updated>

		<summary type="html">&lt;p&gt;SwHawk: /* Games */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;An issue? A question?&lt;br /&gt;
&lt;br /&gt;
* [https://boardgamearena.com/#!faq Frequently asked questions] is the most complete source of help for BGA.&lt;br /&gt;
&lt;br /&gt;
* [https://forum.boardgamearena.com Forums] are also helpful to get information.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Games ==&lt;br /&gt;
Game names which are displayed in red still need game help/summaries written for them. So help out and write one for them by creating a new page for these games. To do so simply click on them below, this will direct you to a page creation page. &lt;br /&gt;
&lt;br /&gt;
Meanwhile, games being available in the alpha list does not warrant that it will go through the whole process and become available to the whole community. Consequently, it is kindly asked to refrain from publicising the alpha list, in order not to create unfounded expectations. Therefore, do not add any games to the alpha list.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table cellpadding=&amp;quot;0&amp;quot; cellspacing=&amp;quot;5&amp;quot; border=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td colspan=&amp;quot;4&amp;quot;&amp;gt;&#039;&#039;&#039;Available on BGA&#039;&#039;&#039;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&#039;&#039;&#039;Beta Games&#039;&#039;&#039;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&#039;&#039;&#039;Alpha Games&#039;&#039;&#039;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;&#039;&#039;&#039;Removed from BGA&#039;&#039;&#039;&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td valign=&amp;quot;top&amp;quot;&amp;gt;&lt;br /&gt;
* [[Gamehelpthirteenclues|13 Clues]]&lt;br /&gt;
* [[Gamehelpsechsnimmt|6 nimmt!]]&lt;br /&gt;
* [[Gamehelpsevenwonders|7 Wonders]]&lt;br /&gt;
* [[Gamehelpsevenwondersarchitects|7 Wonders Architects]]&lt;br /&gt;
* [[Gamehelpsevenwondersduel|7 Wonders Duel]]&lt;br /&gt;
* [[Gamehelpeightmastersrevenge|8 Master&#039;s Revenge]]&lt;br /&gt;
* [[Gamehelpninetynineaddition|99 (addition card game)]]&lt;br /&gt;
* [[Gamehelpninetynine|99 (trick-taking card game)]]&lt;br /&gt;
* [[Gamehelpfeastforodin|A Feast for Odin]]&lt;br /&gt;
* [[Gamehelpfistfulofgold|A Fistful of Gold]]&lt;br /&gt;
* [[Gamehelpabalone|Abalone]]&lt;br /&gt;
* [[Gamehelpabandonallartichokes|Abandon All Artichokes]]&lt;br /&gt;
* [[Gamehelpabyss|Abyss]]&lt;br /&gt;
* [[Gamehelpagricola|Agricola]]&lt;br /&gt;
* [[Gamehelpalhambra|Alhambra]]&lt;br /&gt;
* [[Gamehelpalmadi|Almadi]]&lt;br /&gt;
* [[Gamehelpalveole|Alveole]]&lt;br /&gt;
* [[Gamehelpamyitis|Amyitis]]&lt;br /&gt;
* [[Gamehelpapocalypseazcc|Apocalypse at the Zoo of Carson City]]&lt;br /&gt;
* [[Gamehelparcticscavengers|Arctic Scavengers]]&lt;br /&gt;
* [[Gamehelparmadora|Armadöra]]&lt;br /&gt;
* [[Gamehelpartdecko|Art Decko]]&lt;br /&gt;
* [[Gamehelpassyria|Assyria]]&lt;br /&gt;
* [[Gamehelpautomobiles|Automobiles]]&lt;br /&gt;
* [[Gamehelpazul|Azul]]&lt;br /&gt;
* [[Gamehelpbabydinosaurrescue|Baby Dinosaur Rescue]]&lt;br /&gt;
* [[Gamehelpbackgammon|Backgammon]]&lt;br /&gt;
* [[Gamehelpbahamataxi|Bahama Taxi]]&lt;br /&gt;
* [[Gamehelpballoonpop|Balloon Pop!]]&lt;br /&gt;
* [[Gamehelpbandido|Bandido]]&lt;br /&gt;
* [[Gamehelpbang|BANG!]]&lt;br /&gt;
* [[Gamehelpbaolakiswahili|Bao la Kiswahili]]&lt;br /&gt;
* [[Gamehelpbarbu|Barbu]]&lt;br /&gt;
* [[Gamehelpbarenpark|Barenpark]]&lt;br /&gt;
* [[Gamehelpbarrage|Barrage]]&lt;br /&gt;
* [[Gamehelpbattleoflits|Battle of LITS]]&lt;br /&gt;
* [[Gamehelpbattlesheep|Battle Sheep]]&lt;br /&gt;
* [[Gamehelpbattleship|Battleships Pencil &amp;amp;amp; Paper]]&lt;br /&gt;
* [[Gamehelpbelote|Belote]]&lt;br /&gt;
* [[Gamehelpbetta|Betta]]&lt;br /&gt;
* [[Gamehelpbeyondthesun|Beyond the Sun]]&lt;br /&gt;
* [[Gamehelpbids|Bids]]&lt;br /&gt;
* [[Gamehelpbigmonster|Big Monster]]&lt;br /&gt;
* [[Gamehelpbigtimesoccer|Big Time Soccer]]&lt;br /&gt;
* [[Gamehelpbiyi|Biyi]]&lt;br /&gt;
* [[Gamehelpblaze|Blaze]]&lt;br /&gt;
* [[Gamehelpbloodrage|Blood Rage]]&lt;br /&gt;
* [[Gamehelpblooms|Blooms]]&lt;br /&gt;
* [[Gamehelpblueskies|Blue Skies]]&lt;br /&gt;
* [[Gamehelpbobail|Bobail]]&lt;br /&gt;
* [[Gamehelpbombay|Bombay]]&lt;br /&gt;
* [[Gamehelpboomerangaustralia|Boomerang: Australia]]&lt;br /&gt;
* [[Gamehelpboomerangeurope|Boomerang: Europe]]&lt;br /&gt;
* [[Gamehelpboomerangusa|Boomerang: USA]]&lt;br /&gt;
* [[Gamehelpbossquest|Boss Quest]]&lt;br /&gt;
* [[Gamehelpbreakthecode|Break the Code]]&lt;br /&gt;
* [[Gamehelpbriscola|Briscola]]&lt;br /&gt;
* [[Gamehelpbubbleepop|Bubblee Pop]]&lt;br /&gt;
* [[Gamehelpbug|Bug]]&lt;br /&gt;
* [[Gamehelpburglebros|Burgle Bros.]]&lt;br /&gt;
* [[Gamehelpbutterfly|Butterfly]]&lt;br /&gt;
* [[Gamehelpbuttons|Buttons]]&lt;br /&gt;
* [[Gamehelpcacao|Cacao]]&lt;br /&gt;
* [[Gamehelpcantstop|Can&#039;t Stop]]&lt;br /&gt;
* [[Gamehelpcantstopexpress|Can’t Stop Express]]&lt;br /&gt;
* [[Gamehelpcanosa|Canosa]]&lt;br /&gt;
* [[Gamehelpcaravan|Caravan]]&lt;br /&gt;
* [[Gamehelpcarcassonne|Carcassonne]]&lt;br /&gt;
* [[Gamehelpcarcassonnehuntersandgatherers|Carcassonne: Hunters &amp;amp;amp; Gatherers]]&lt;br /&gt;
* [[Gamehelpcardiceo|Cardiceo]]&lt;br /&gt;
* [[Gamehelpcaribbeanallfours|Caribbean All Fours]]&lt;br /&gt;
* [[Gamehelpcarnegie|Carnegie]]&lt;br /&gt;
* [[Gamehelpcatan|Catan]]&lt;br /&gt;
* [[Gamehelpcaylus|Caylus]]&lt;br /&gt;
* [[Gamehelpcelestia|Celestia]]&lt;br /&gt;
* [[Gamehelpcentury|Century]]&lt;br /&gt;
* [[Gamehelpcephalopod|Cephalopod]]&lt;br /&gt;
* [[Gamehelpchakra|Chakra]]&lt;br /&gt;
* [[Gamehelpcheckers|Checkers]]&lt;br /&gt;
* [[Gamehelpchess|Chess]]&lt;br /&gt;
* [[Gamehelpchinagold|China Gold]]&lt;br /&gt;
* [[Gamehelpchinesecheckers|Chinese Checkers]]&lt;br /&gt;
* [[Gamehelpchocolatefactory|Chocolate Factory]]&lt;br /&gt;
* [[Gamehelpchromino|Chromino]]&lt;br /&gt;
* [[Gamehelpcinco|Cinco]]&lt;br /&gt;
* [[Gamehelpcircleoflife|Circle of Life]]&lt;br /&gt;
* [[Gamehelpcityofthebigshoulders|City of the Big Shoulders]]&lt;br /&gt;
* [[Gamehelpclansofcaledonia|Clans of Caledonia]]&lt;br /&gt;
* [[Gamehelpclashofdecks|Clash of Decks]]&lt;br /&gt;
* [[Gamehelpcloudcity|Cloud City]]&lt;br /&gt;
* [[Gamehelpcodexnaturalis|CODEX Naturalis]]&lt;br /&gt;
* [[Gamehelpcoinche|Coinche]]&lt;br /&gt;
* [[Gamehelpcolorpop|Color Pop]]&lt;br /&gt;
* [[Gamehelpcoloretto|Coloretto]]&lt;br /&gt;
* [[Gamehelpcoltexpress|Colt Express]]&lt;br /&gt;
* [[Gamehelpconsonar|Con Sonar!]]&lt;br /&gt;
* [[Gamehelpconcept|Concept]]&lt;br /&gt;
* [[Gamehelpconnectfour|Connect Four]]&lt;br /&gt;
* [[Gamehelpconnectsix|Connect6]]&lt;br /&gt;
* [[Gamehelpconspiracy|Conspiracy]]&lt;br /&gt;
* [[Gamehelpcopenhagen|Copenhagen]]&lt;br /&gt;
* [[Gamehelpcoupcitystate|Coup]]&lt;br /&gt;
* [[Gamehelpcrazyfarmers|Crazy Farmers]]&lt;br /&gt;
* [[Gamehelpcribbage|Cribbage]]&lt;br /&gt;
* [[Gamehelpcrimezoom|Crime Zoom: A Dirty Objective]]&lt;br /&gt;
* [[Gamehelpcrusadersthywillbedone|Crusaders: Thy Will Be Done]]&lt;br /&gt;
* [[Gamehelpcubirds|CuBirds]]&lt;br /&gt;
* [[Gamehelpdarkagent|Dark Agent]]&lt;br /&gt;
* [[Gamehelpdetectivepoker|Detective Poker]]&lt;br /&gt;
* [[Gamehelpdeus|Deus]]&lt;br /&gt;
* [[Gamehelpdiablo|Diablo]]&lt;br /&gt;
* [[Gamehelpdiams|Diam&#039;s]]&lt;br /&gt;
  &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td valign=&amp;quot;top&amp;quot;&amp;gt;&lt;br /&gt;
* [[Gamehelpdiceforge|Dice Forge]]&lt;br /&gt;
* [[Gamehelpdicehospital|Dice Hospital]]&lt;br /&gt;
* [[Gamehelpdicesummoners|Dice Summoners]]&lt;br /&gt;
* [[Gamehelpdicedtomatoes|Diced Tomatoes]]&lt;br /&gt;
* [[Gamehelpdingosdreams|Dingo&#039;s Dreams]]&lt;br /&gt;
* [[Gamehelpdinosaurteaparty|Dinosaur Tea Party]]&lt;br /&gt;
* [[Gamehelpdjambi|Djambi]]&lt;br /&gt;
* [[Gamehelpdodo|Dodo]]&lt;br /&gt;
* [[Gamehelpdownforce|Downforce]]&lt;br /&gt;
* [[Gamehelpdraftosaurus|Draftosaurus]]&lt;br /&gt;
* [[Gamehelpdragoncastle|Dragon Castle]]&lt;br /&gt;
* [[Gamehelpdragonkeeper|Dragon Keeper: The Dungeon]]&lt;br /&gt;
* [[Gamehelpdragonline|Dragon Line]]&lt;br /&gt;
* [[Gamehelpdragonheart|Dragonheart]]&lt;br /&gt;
* [[Gamehelpdragonwood|Dragonwood]]&lt;br /&gt;
* [[Gamehelpdungeonpetz|Dungeon Petz]]&lt;br /&gt;
* [[Gamehelpdungeonroll|Dungeon Roll]]&lt;br /&gt;
* [[Gamehelpdungeontwister|Dungeon Twister]]&lt;br /&gt;
* [[Gamehelpegocentricworld|Egocentric World]]&lt;br /&gt;
* [[Gamehelpelfenland|Elfenland]]&lt;br /&gt;
* [[Gamehelpelgrande|El Grande]]&lt;br /&gt;
* [[Gamehelpeminentdomain|Eminent Domain]]&lt;br /&gt;
* [[Gamehelpemdomicrocosm|Eminent Domain: Microcosm]]&lt;br /&gt;
* [[Gamehelpepizodiak|EpiZodiak]]&lt;br /&gt;
* [[Gamehelpakeruption|Eruption]]&lt;br /&gt;
* [[Gamehelpequinox|Equinox]]&lt;br /&gt;
* [[Gamehelpevl|EVL]]&lt;br /&gt;
* [[Gamehelpevogamenoname|Evo: The &amp;quot;Game no Name&amp;quot;]]&lt;br /&gt;
* [[Gamehelpnorthwestpassage|Expedition: Northwest Passage]]&lt;br /&gt;
* [[Gamehelpexplorationwarzone|Exploration: Warzone]]&lt;br /&gt;
* [[Gamehelpfactum|Factum]]&lt;br /&gt;
* [[Gamehelpfaifo|Fai-Fo]]&lt;br /&gt;
* [[Gamehelpfarmclub|Farm Club]]&lt;br /&gt;
* [[Gamehelpfinity|Finity]]&lt;br /&gt;
* [[Gamehelpflamingpyramids|Flaming Pyramids]]&lt;br /&gt;
* [[Gamehelpfleet|Fleet]]&lt;br /&gt;
* [[Gamehelpflorenzacardgame|Florenza: The Card Game]]&lt;br /&gt;
* [[Gamehelpfluxx|Fluxx]]&lt;br /&gt;
* [[Gamehelpforex|For-Ex]]&lt;br /&gt;
* [[Gamehelpforsale|For Sale]]&lt;br /&gt;
* [[Gamehelpforbiddenisland|Forbidden Island]]&lt;br /&gt;
* [[Gamehelpfourcolorcards|Four Color Cards]]&lt;br /&gt;
* [[Gamehelpfractal|Fractal]]&lt;br /&gt;
* [[Gamehelpfrenchtarot|French Tarot]]&lt;br /&gt;
* [[Gamehelpfruitpicking|Fruit Picking]]&lt;br /&gt;
* [[Gamehelpgaia|Gaia]]&lt;br /&gt;
* [[Gamehelpgaiaproject|Gaia Project]]&lt;br /&gt;
* [[Gamehelpgearnpiston|Gear &amp;amp; Piston]]&lt;br /&gt;
* [[Gamehelpgetonboard|Get on Board: New York &amp;amp; London]]&lt;br /&gt;
* [[Gamehelpgetthemacguffin|Get the MacGuffin]]&lt;br /&gt;
* [[Gamehelpglow|Glow]]&lt;br /&gt;
* [[Gamehelpclassicgo|Go]]&lt;br /&gt;
* [[Gamehelpgonutsfordonuts|Go Nuts for Donuts]]&lt;br /&gt;
* [[Gamehelpgoldwest|Gold West]]&lt;br /&gt;
* [[Gamehelpgomoku|Gomoku]]&lt;br /&gt;
* [[Gamehelpgopher|Gopher]]&lt;br /&gt;
* [[Gamehelpgorami|GORami]]&lt;br /&gt;
* [[Gamehelpgosu|Gosu]]&lt;br /&gt;
* [[Gamehelpgrandbazaar|Grand Bazaar]]&lt;br /&gt;
* [[Gamehelpgreatwesterntrail|Great Western Trail]]&lt;br /&gt;
* [[Gamehelpgrosstarock|Grosstarock]]&lt;br /&gt;
* [[Gamehelpguildes|Guildes]]&lt;br /&gt;
* [[Gamehelpguile|Guile]]&lt;br /&gt;
* [[Gamehelpgyges|Gygès]]&lt;br /&gt;
* [[Gamehelphacktrick|Hack Trick]]&lt;br /&gt;
* [[Gamehelphadron|Hadron]]&lt;br /&gt;
* [[Gamehelphaggis|Haggis]]&lt;br /&gt;
* [[Gamehelphaiclue|Haiclue]]&lt;br /&gt;
* [[Gamehelphanabi|Hanabi]]&lt;br /&gt;
* [[Gamehelphandandfoot|Hand and Foot]]&lt;br /&gt;
* [[Gamehelphappycity|Happy City]]&lt;br /&gt;
* [[Gamehelphardback|Hardback]]&lt;br /&gt;
* [[Gamehelphawaii|Hawaii]]&lt;br /&gt;
* [[Gamehelphearts|Hearts]]&lt;br /&gt;
* [[Gamehelpheckinhounds|Heckin Hounds]]&lt;br /&gt;
* [[Gamehelpherd|Herd]]&lt;br /&gt;
* [[Gamehelpherooj|Herooj]]&lt;br /&gt;
* [[Gamehelpherrlof|Herrlof]]&lt;br /&gt;
* [[Gamehelphex|Hex]]&lt;br /&gt;
* [[Gamehelphive|Hive]]&lt;br /&gt;
* [[Gamehelphoarders|Hoarders]]&lt;br /&gt;
* [[Gamehelphomesteaders|Homesteaders]]&lt;br /&gt;
* [[Gamehelphomeworlds|Homeworlds]]&lt;br /&gt;
* [[Gamehelpescapefromthehiddencastle|HUGO]]&lt;br /&gt;
* [[Gamehelphungariantarokk|Hungarian Tarokk]]&lt;br /&gt;
* [[Gamehelphypnosia|Hypnosia]]&lt;br /&gt;
* [[Gamehelpiceandthesky|Ice and the Sky]]&lt;br /&gt;
* [[Gamehelpicecoldicehockey|Ice Cold Ice Hockey]]&lt;br /&gt;
* [[Gamehelpicebreaker|Icebreaker]]&lt;br /&gt;
* [[Gamehelpillustori|Illustori]]&lt;br /&gt;
* [[Gamehelpimhotep|Imhotep]]&lt;br /&gt;
* [[Gamehelpimpasse|Impasse]]&lt;br /&gt;
* [[Gamehelpintheyearofthedragon|In The Year of the Dragon]]&lt;br /&gt;
* [[Gamehelpincangold|Incan Gold]]&lt;br /&gt;
* [[Gamehelpinnovation|Innovation]]&lt;br /&gt;
* [[Gamehelpinsert|Insert]]&lt;br /&gt;
* [[Gamehelpisaac|Isaac]]&lt;br /&gt;
* [[Gamehelpiwari|Iwari]]&lt;br /&gt;
* [[Gamehelpjaipur|Jaipur]]&lt;br /&gt;
* [[Gamehelpjekyllvshide|Jekyll vs. Hyde]]&lt;br /&gt;
* [[Gamehelpjumpdrive|Jump Drive]]&lt;br /&gt;
* [[Gamehelpjumpgate|Jump Gate]]&lt;br /&gt;
* [[Gamehelpjustdesserts|Just Desserts]]&lt;br /&gt;
* [[Gamehelpjustone|Just One]]&lt;br /&gt;
* [[Gamehelpk2|K2]]&lt;br /&gt;
* [[Gamehelpkabaleo|Kabaleo]]&lt;br /&gt;
* [[Gamehelpkahuna|Kahuna]]&lt;br /&gt;
* [[Gamehelpkalah|Kalah]]&lt;br /&gt;
* [[Gamehelpkami|Kami]]&lt;br /&gt;
* [[Gamehelpkeyflower|Keyflower]]&lt;br /&gt;
* [[Gamehelpkhronos|Khronos]]&lt;br /&gt;
* [[Gamehelpkingofthepitch|King of the Pitch]]&lt;br /&gt;
* [[Gamehelpkingoftokyo|King of Tokyo]]&lt;br /&gt;
* [[Gamehelpkingdombuilder|Kingdom Builder]]&lt;br /&gt;
* [[Gamehelpkingdomino|Kingdomino]]&lt;br /&gt;
* [[Gamehelpklaverjassen|Klaverjassen]]&lt;br /&gt;
* [[Gamehelpkoikoi|Koi-Koi]]&lt;br /&gt;
  &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td valign=&amp;quot;top&amp;quot;&amp;gt;&lt;br /&gt;
* [[Gamehelpkoryo|Koryŏ]]&lt;br /&gt;
* [[Gamehelpkqj|KQJ]]&lt;br /&gt;
* [[Gamehelpkrosmasterarena|Krosmaster Arena]]&lt;br /&gt;
* [[Gamehelpkrosmasterblast|Krosmaster Blast]]&lt;br /&gt;
* [[Gamehelplagranja|La Granja]]&lt;br /&gt;
* [[Gamehelpladyandthetiger|Lady and the Tiger]]&lt;br /&gt;
* [[Gamehelplasvegan|Las Vegan]]&lt;br /&gt;
* [[Gamehelpledernierpeuple|Le Dernier Peuple]]&lt;br /&gt;
* [[Gamehelpinventors|Legendary Inventors]]&lt;br /&gt;
* [[Gamehelplettertycoon|Letter Tycoon]]&lt;br /&gt;
* [[Gamehelplewisclark|Lewis &amp;amp;amp; Clark]]&lt;br /&gt;
* [[Gamehelplibertalia|Libertalia]]&lt;br /&gt;
* [[Gamehelplinesofaction|Lines of Action]]&lt;br /&gt;
* [[Gamehelplinkage|Linkage]]&lt;br /&gt;
* [[Gamehelplittlefactory|Little Factory]]&lt;br /&gt;
* [[Gamehelplivingforest|Living Forest]]&lt;br /&gt;
* [[Gamehelplama|LLAMA]]&lt;br /&gt;
* [[Gamehelplocomomo|Loco Momo]]&lt;br /&gt;
* [[Gamehelplogger|Logger]]&lt;br /&gt;
* [[Gamehelplox|Lords of Xidit]]&lt;br /&gt;
* [[Gamehelplostcities|Lost Cities]]&lt;br /&gt;
* [[Gamehelplostexplorers|Lost Explorers]]&lt;br /&gt;
* [[Gamehelparnak|Lost Ruins of Arnak]]&lt;br /&gt;
* [[Gamehelploveletter|Love Letter]]&lt;br /&gt;
* [[Gamehelpluckynumbers|Lucky Numbers]]&lt;br /&gt;
* [[Gamehelpluxor|Luxor]]&lt;br /&gt;
* [[Gamehelpmachiavelli|Machiavelli]]&lt;br /&gt;
* [[Gamehelpmadeira|Madeira]]&lt;br /&gt;
* [[Gamehelpmammalath|Mammalath]]&lt;br /&gt;
* [[Gamehelpmapmaker|Mapmaker: The Gerrymandering Game]]&lt;br /&gt;
* [[Gamehelpmarcopolotwo|Marco Polo II: In the Service of the Khan]]&lt;br /&gt;
* [[Gamehelpmarrakech|Marrakech]]&lt;br /&gt;
* [[Gamehelpmarram|Marram]]&lt;br /&gt;
* [[Gamehelpmartiandice|Martian Dice]]&lt;br /&gt;
* [[Gamehelpmascarade|Mascarade]]&lt;br /&gt;
* [[Gamehelpmattock|Mattock]]&lt;br /&gt;
* [[Gamehelpmedina|Medina]]&lt;br /&gt;
* [[Gamehelpmeadow|Medo]]&lt;br /&gt;
* [[Gamehelpmetromania|Metromania]]&lt;br /&gt;
* [[Gamehelpmijnlieff|Mijnlieff]]&lt;br /&gt;
* [[Gamehelpmonsterfactory|Monster Factory]]&lt;br /&gt;
* [[Gamehelpmow|MOW]]&lt;br /&gt;
* [[Gamehelpmrjack|Mr. Jack]]&lt;br /&gt;
* [[Gamehelpmurusgallicus|Murus Gallicus]]&lt;br /&gt;
* [[Gamehelpmyshelfie|My Shelfie]]&lt;br /&gt;
* [[Gamehelpnangaparbat|Nanga Parbat]]&lt;br /&gt;
* [[Gamehelpnarabi|Narabi]]&lt;br /&gt;
* [[Gamehelpnautilus|Nautilus]]&lt;br /&gt;
* [[Gamehelpneutreeko|Neutreeko]]&lt;br /&gt;
* [[Gamehelpnewfrontiers|New Frontiers]]&lt;br /&gt;
* [[Gamehelpnextstation|Next Station: London]]&lt;br /&gt;
* [[Gamehelpniagara|Niagara]]&lt;br /&gt;
* [[Gamehelpnicodemus|Nicodemus]]&lt;br /&gt;
* [[Gamehelpnidavellir|Nidavellir]]&lt;br /&gt;
* [[Gamehelpaknile|Nile]]&lt;br /&gt;
* [[Gamehelpninemensmorris|Nine Men&#039;s Morris]]&lt;br /&gt;
* [[Gamehelpnippon|Nippon]]&lt;br /&gt;
* [[Gamehelpnothanks|No Thanks!]]&lt;br /&gt;
* [[Gamehelpnoah|Noah]]&lt;br /&gt;
* [[Gamehelpnoirkvi|Noir: Killer versus Inspector]]&lt;br /&gt;
* [[Gamehelpnotalone|Not Alone]]&lt;br /&gt;
* [[Gamehelpnumberdrop|Number Drop]]&lt;br /&gt;
* [[Gamehelpnxs|NXS]]&lt;br /&gt;
* [[Gamehelpofftherails|Off the Rails]]&lt;br /&gt;
* [[Gamehelpohhell|Oh Hell!]]&lt;br /&gt;
* [[Gamehelpohseven|Oh-Seven]]&lt;br /&gt;
* [[Gamehelponceuponaforest|Once Upon A Forest]]&lt;br /&gt;
* [[Gamehelpone|ONE]]&lt;br /&gt;
* [[Gamehelponitama|Onitama]]&lt;br /&gt;
* [[Gamehelporiflamme|Oriflamme]]&lt;br /&gt;
* [[Gamehelporigin|Origin]]&lt;br /&gt;
* [[Gamehelpoust|Oust]]&lt;br /&gt;
* [[Gamehelpoutlaws|Outlaws: Last Man Standing]]&lt;br /&gt;
* [[Gamehelppi|P.I.]]&lt;br /&gt;
* [[Gamehelppalace|Palace]]&lt;br /&gt;
* [[Gamehelppandemic|Pandemic]]&lt;br /&gt;
* [[Gamehelppapayoo|Papayoo]]&lt;br /&gt;
* [[Gamehelpparisconnection|Paris Connection]]&lt;br /&gt;
* [[Gamehelpparks|PARKS]]&lt;br /&gt;
* [[Gamehelppatchwork|Patchwork]]&lt;br /&gt;
* [[Gamehelppedro|Pedro]]&lt;br /&gt;
* [[Gamehelppenaltychallenge|Penalty Challenge]]&lt;br /&gt;
* [[Gamehelppennypress|Penny Press]]&lt;br /&gt;
* [[Gamehelppente|Pente]]&lt;br /&gt;
* [[Gamehelpdudo|Perudo]]&lt;br /&gt;
* [[Gamehelpphat|Phat]]&lt;br /&gt;
* [[Gamehelppingimus|Pingimus]]&lt;br /&gt;
* [[Gamehelppiratenkapern|Piraten kapern]]&lt;br /&gt;
* [[Gamehelppolis|Polis: Fight for Hegemony]]&lt;br /&gt;
* [[Gamehelppontedeldiavolo|Ponte del Diavolo]]&lt;br /&gt;
* [[Gamehelppotionexplosion|Potion Explosion]]&lt;br /&gt;
* [[Gamehelppuertorico|Puerto Rico]]&lt;br /&gt;
* [[Gamehelppylos|Pylos]]&lt;br /&gt;
* [[Gamehelppyramidpoker|Pyramid Poker]]&lt;br /&gt;
* [[Gamehelppyrga|Pyrga]]&lt;br /&gt;
* [[Gamehelpquantik|Quantik]]&lt;br /&gt;
* [[Gamehelpquantum|Quantum]]&lt;br /&gt;
* [[Gamehelpquarto|Quarto]]&lt;br /&gt;
* [[Gamehelpqueenskings|Queens and Kings... A Checkers Game]]&lt;br /&gt;
* [[Gamehelpquetzal|Quetzal]]&lt;br /&gt;
* [[Gamehelpquinque|Quinque]]&lt;br /&gt;
* [[Gamehelpquoridor|Quoridor]]&lt;br /&gt;
* [[Gamehelpraceforthegalaxy|Race for the Galaxy]]&lt;br /&gt;
* [[Gamehelprage|Rage]]&lt;br /&gt;
* [[Gamehelprailroadink|Railroad Ink]]&lt;br /&gt;
* [[Gamehelprailwaysoftheworld|Railways of the World]]&lt;br /&gt;
* [[Gamehelprainbow|Rainbow]]&lt;br /&gt;
* [[Gamehelprallymangt|Rallyman: GT]]&lt;br /&gt;
* [[Gamehelpredseven|Red7]]&lt;br /&gt;
* [[Gamehelpredstone|Redstone]]&lt;br /&gt;
* [[Gamehelpregicide|Regicide]]&lt;br /&gt;
* [[Gamehelpregidice|Regidice]]&lt;br /&gt;
* [[Gamehelprememberwhen|Remember When]]&lt;br /&gt;
* [[Gamehelpresarcana|Res Arcana]]&lt;br /&gt;
* [[Gamehelprestinpeace|Rest In Peace]]&lt;br /&gt;
* [[Gamehelpreversi|Reversi]]&lt;br /&gt;
* [[Gamehelprive|Rive]]&lt;br /&gt;
* [[Gamehelprollforthegalaxy|Roll for the Galaxy]]&lt;br /&gt;
* [[Gamehelprolledwest|Rolled West]]&lt;br /&gt;
* [[Gamehelprollandbump|Roll’n Bump]]&lt;br /&gt;
* [[Gamehelproppyakken|Roppyakken]]&lt;br /&gt;
* [[Gamehelprussianrailroads|Russian Railroads]]&lt;br /&gt;
  &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td valign=&amp;quot;top&amp;quot;&amp;gt;&lt;br /&gt;
* [[Gamehelpsaboteur|Saboteur]]&lt;br /&gt;
* [[Gamehelpsaintpetersburg|Saint Petersburg]]&lt;br /&gt;
* [[Gamehelpsaintpoker|Saint Poker]]&lt;br /&gt;
* [[Gamehelpsantorini|Santorini]]&lt;br /&gt;
* [[Gamehelpsapiens|Sapiens]]&lt;br /&gt;
* [[Gamehelpschroedingerscats|Schrodinger&#039;s Cats]]&lt;br /&gt;
* [[Gamehelpscopa|Scopa]]&lt;br /&gt;
* [[Gamehelpseasaltpaper|Sea Salt &amp;amp; Paper]]&lt;br /&gt;
* [[Gamehelpseasons|Seasons]]&lt;br /&gt;
* [[Gamehelpsecretmoon|Secret Moon]]&lt;br /&gt;
* [[Gamehelpsenet|Senet]]&lt;br /&gt;
* [[Gamehelpsenshi|Senshi]]&lt;br /&gt;
* [[Gamehelpshiftingstones|Shifting Stones]]&lt;br /&gt;
* [[Gamehelpsiam|Siam]]&lt;br /&gt;
* [[Gamehelpsignorie|Signorie]]&lt;br /&gt;
* [[Gamehelpsilo|Silo]]&lt;br /&gt;
* [[Gamehelpsimilo|Similo]]&lt;br /&gt;
* [[Gamehelpsimplicity|Simplicity]]&lt;br /&gt;
* [[Gamehelpskat|Skat]]&lt;br /&gt;
* [[Gamehelpskull|Skull]]&lt;br /&gt;
* [[Gamehelpsmallislands|Small Islands]]&lt;br /&gt;
* [[Gamehelpsobek|Sobek]]&lt;br /&gt;
* [[Gamehelpsobektwoplayers|Sobek 2 players]]&lt;br /&gt;
* [[Gamehelpsolarstorm|Solar Storm]]&lt;br /&gt;
* [[Gamehelpsolo|Solo]]&lt;br /&gt;
* [[Gamehelpsolowhist|Solo Whist]]&lt;br /&gt;
* [[Gamehelpsoluna|Soluna]]&lt;br /&gt;
* [[Gamehelpspacebase|Space Base]]&lt;br /&gt;
* [[Gamehelpspacestationphoenix|Space Station Phoenix]]&lt;br /&gt;
* [[Gamehelpspades|Spades]]&lt;br /&gt;
* [[Gamehelpsparts|Sparts]]&lt;br /&gt;
* [[Gamehelpsplendor|Splendor]]&lt;br /&gt;
* [[Gamehelpsplito|Splito]]&lt;br /&gt;
* [[Gamehelpspotit|Spot It (or Dobble)]]&lt;br /&gt;
* [[Gamehelpspyrium|Spyrium]]&lt;br /&gt;
* [[Gamehelpsquadro|Squadro]]&lt;br /&gt;
* [[Gamehelpstarfluxx|Star Fluxx]]&lt;br /&gt;
* [[Gamehelpsteamrollers|SteamRollers]]&lt;br /&gt;
* [[Gamehelpsteamworks|Steam Works]]&lt;br /&gt;
* [[Gamehelpstella|Stella: Dixit Universe]]&lt;br /&gt;
* [[Gamehelpstirfryeighteen|Stir Fry Eighteen]]&lt;br /&gt;
* [[Gamehelpstoneage|Stone Age]]&lt;br /&gt;
* [[Gamehelpsuperfantasybrawl|Super Fantasy Brawl]]&lt;br /&gt;
* [[Gamehelpsushigo|Sushi Go!]]&lt;br /&gt;
* [[Gamehelpsushigoparty|Sushi Go Party]]&lt;br /&gt;
* [[Gamehelptablut|Tablut]]&lt;br /&gt;
* [[Gamehelptakaraisland|Takara Island]]&lt;br /&gt;
* [[Gamehelptakenoko|Takenoko]]&lt;br /&gt;
* [[Gamehelptaluva|Taluva]]&lt;br /&gt;
* [[Gamehelptapestry|Tapestry]]&lt;br /&gt;
* [[Gamehelptargi|Targi]]&lt;br /&gt;
* [[Gamehelptashkalar|Tash-Kalar]]&lt;br /&gt;
* [[Gamehelpteatime|Tea Time]]&lt;br /&gt;
* [[Gamehelpteotihuacan|Teotihuacan: City of Gods]]&lt;br /&gt;
* [[Gamehelpterramystica|Terra Mystica]]&lt;br /&gt;
* [[Gamehelpthatslife|That&#039;s Life (or Verflixxt!)]]&lt;br /&gt;
* [[Gamehelpbattleforhill|The Battle for Hill 218]]&lt;br /&gt;
* [[Gamehelptheboss|The Boss]]&lt;br /&gt;
* [[Gamehelpthebuildersantiquity|The Builders: Antiquity]]&lt;br /&gt;
* [[Gamehelpthebuilders|The Builders: Middle Ages]]&lt;br /&gt;
* [[Gamehelpcastlesofburgundy|The Castles of Burgundy]]&lt;br /&gt;
* [[Gamehelpthecrew|The Crew]]&lt;br /&gt;
* [[Gamehelpthecrewdeepsea|The Crew: Mission Deep Sea]]&lt;br /&gt;
* [[Gamehelptheisleofcats|The Isle of Cats]]&lt;br /&gt;
* [[Gamehelpthejellymonsterlab|The Jelly Monster Lab]]&lt;br /&gt;
* [[Gamehelpkingsguild|The King&#039;s Guild]]&lt;br /&gt;
* [[Gamehelpcarrara|The Palaces of Carrara]]&lt;br /&gt;
* [[Gamehelpruhr|The Ruhr: A Story of Coal Trade]]&lt;br /&gt;
* [[Gamehelpmarcopolo|The Voyages of Marco Polo]]&lt;br /&gt;
* [[Gamehelpwerewolves|The Werewolves of Miller&#039;s Hollow]]&lt;br /&gt;
* [[Gamehelpthermopyles|Thermopyles]]&lt;br /&gt;
* [[Gamehelpthrive|Thrive]]&lt;br /&gt;
* [[Gamehelpthroughtheages|Through the Ages]]&lt;br /&gt;
* [[Gamehelpthroughtheagesnewstory|Through the Ages: A new Story of Civilization]]&lt;br /&gt;
* [[Gamehelpthurnandtaxis|Thurn and Taxis]]&lt;br /&gt;
* [[Gamehelptichu|Tichu]]&lt;br /&gt;
* [[Gamehelptickettoride|Ticket to Ride]]&lt;br /&gt;
* [[Gamehelptigriseuphrates|Tigris Euphrates]]&lt;br /&gt;
* [[Gamehelptiki|Tiki]]&lt;br /&gt;
* [[Gamehelptimemasters|Time Masters]]&lt;br /&gt;
* [[Gamehelptobago|Tobago]]&lt;br /&gt;
* [[Gamehelptock|Tock]]&lt;br /&gt;
* [[Gamehelptoeshambo|ToeShamBo]]&lt;br /&gt;
* [[Gamehelptokaido|Tokaido]]&lt;br /&gt;
* [[Gamehelptournay|Tournay]]&lt;br /&gt;
* [[Gamehelptranquility|Tranquility]]&lt;br /&gt;
* [[Gamehelptrektwelve|Trek 12]]&lt;br /&gt;
* [[Gamehelptrekkingtheworld|Trekking the World]]&lt;br /&gt;
* [[Gamehelptrickoftherails|Trick of the Rails]]&lt;br /&gt;
* [[Gamehelptroyes|Troyes]]&lt;br /&gt;
* [[Gamehelptroyesdice|Troyes Dice]]&lt;br /&gt;
* [[Gamehelptumbleweed|Tumbleweed]]&lt;br /&gt;
* [[Gamehelpturnthetide|Turn the tide]]&lt;br /&gt;
* [[Gamehelptwintinbots|Twin Tin Bots]]&lt;br /&gt;
* [[Gamehelptwinpalms|Twin Palms]]&lt;br /&gt;
* [[Gamehelptzolkin|Tzolk&#039;in]]&lt;br /&gt;
* [[Gamehelpultimaterailroads|Ultimate Railroads]]&lt;br /&gt;
* [[Gamehelpunclechestnuttablegype|Uncle Chestnut&#039;s Table Gype]]&lt;br /&gt;
* [[Gamehelpunconditionalsurrender|Unconditional Surrender! World War 2 in Europe]]&lt;br /&gt;
* [[Gamehelpunitedsquare|United Square]]&lt;br /&gt;
* [[Gamehelpuptown|Uptown]]&lt;br /&gt;
* [[Gamehelpvegetables|VEGEtables]]&lt;br /&gt;
* [[Gamehelpveggiegarden|Veggie Garden]]&lt;br /&gt;
* [[Gamehelpvektorace|VektoRace]]&lt;br /&gt;
* [[Gamehelpveletas|Veletas]]&lt;br /&gt;
* [[Gamehelpveronatwist|Verona Twist]]&lt;br /&gt;
* [[Gamehelpviamagica|Via Magica]]&lt;br /&gt;
* [[Gamehelpviticulture|Viticulture]]&lt;br /&gt;
* [[Gamehelpvultureculture|Vulture Culture]]&lt;br /&gt;
* [[Gamehelpwelcometo|Welcome To]]&lt;br /&gt;
* [[Gamehelpwelcometonewlasvegas|Welcome To New Las Vegas]]&lt;br /&gt;
* [[Gamehelpwhisttwentytwo|Whist 22]]&lt;br /&gt;
* [[Gamehelpwingspan|Wingspan]]&lt;br /&gt;
* [[Gamehelpwizard|Wizard]]&lt;br /&gt;
* [[Gamehelpxiangqi|Xiangqi]]&lt;br /&gt;
* [[Gamehelpyatzy|Yahtzee]]&lt;br /&gt;
* [[Gamehelpyinyang|Yin Yang]]&lt;br /&gt;
* [[Gamehelpyokai|Yokai]]&lt;br /&gt;
* [[Gamehelpyokohama|Yokohama]]&lt;br /&gt;
* [[Gamehelpzener|Zener]]&lt;br /&gt;
* [[Gamehelpzola|Zola]]&lt;br /&gt;
  &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td valign=&amp;quot;top&amp;quot;&amp;gt;&lt;br /&gt;
* [[Gamehelpartthief|Art Thief]]&lt;br /&gt;
* [[Gamehelpblackjack|Blackjack]]&lt;br /&gt;
* [[Gamehelpbuyword|BuyWord]]&lt;br /&gt;
* [[Gamehelpcastlesofcaleira|Castles of Caleira]]&lt;br /&gt;
* [[Gamehelpcaverna|Caverna]]&lt;br /&gt;
* [[Gamehelpchimerastation|Chimera Station]]&lt;br /&gt;
* [[Gamehelpcommanderchess|Commander Chess]]&lt;br /&gt;
* [[Gamehelpcoupell|Coupell]]&lt;br /&gt;
* [[Gamehelpdicethemepark|Dice Theme Park]]&lt;br /&gt;
* [[Gamehelpdinnerinparis|Dinner in Paris]]&lt;br /&gt;
* [[Gamehelpthroneandthegrail|District Noir]]&lt;br /&gt;
* [[Gamehelpdotsandboxes|Dots and Boxes]]&lt;br /&gt;
* [[Gamehelpdraftcider|Draft Cider]]&lt;br /&gt;
* [[Gamehelpdragonbridge|Dragon Bridge]]&lt;br /&gt;
* [[Gamehelpekonos|EKONOS]]&lt;br /&gt;
* [[Gamehelpfairytrails|Fairy Trails]]&lt;br /&gt;
* [[Gamehelpfortheking|For the King (and Me)]]&lt;br /&gt;
* [[Gamehelpgangsta|Gangsta!]]&lt;br /&gt;
* [[Gamehelpgardennation|Garden Nation]]&lt;br /&gt;
* [[Gamehelpgeekoutmasters|Geek Out! Masters]]&lt;br /&gt;
* [[Gamehelpghostathome|Ghost at Home]]&lt;br /&gt;
* [[Gamehelpgofish|Go Fish]]&lt;br /&gt;
* [[Gamehelpgoodcopbadcop|Good Cop Bad Cop]]&lt;br /&gt;
* [[Gamehelphoola|Hoola]]&lt;br /&gt;
* [[Gamehelphydroracers|Hydroracers]]&lt;br /&gt;
* [[Gamehelpimtheboss|I&#039;m the Boss]]&lt;br /&gt;
* [[Gamehelpitsawonderfulworld|It’s a Wonderful World]]&lt;br /&gt;
* [[Gamehelpriichimahjong|Japanese (Riichi) Mahjong]]&lt;br /&gt;
* [[Gamehelpkingdoms|Kingdoms]]&lt;br /&gt;
* [[Gamehelpkmakici|Kmakici Family&#039;s Greatest Teatime]]&lt;br /&gt;
* [[Gamehelpkonane|Konane]]&lt;br /&gt;
* [[Gamehelpkrakenup|Kraken Up]]&lt;br /&gt;
* [[Gamehelpkulami|Kulami]]&lt;br /&gt;
* [[Gamehelpladyschoice|Lady’s Choice]]&lt;br /&gt;
* [[Gamehelplamarcheducrabe|La Marche Du Crabe]]&lt;br /&gt;
* [[Gamehelpheroesofhellas|Legends of Hellas]]&lt;br /&gt;
* [[Gamehelplifeline|Lifeline]]&lt;br /&gt;
* [[Gamehelplineae|Lineae]]&lt;br /&gt;
* [[Gamehelpliverpoolrummy|Liverpool (Cozy Oaks) Rummy]]&lt;br /&gt;
* [[Gamehelplookatthestars|Look at the Stars]]&lt;br /&gt;
* [[Gamehelpmegalomania|Megalomania]]&lt;br /&gt;
* [[Gamehelpmemoir|Memoir 44]]&lt;br /&gt;
* [[Gamehelpmercadodelisboaste|Mercado de Lisboa]]&lt;br /&gt;
* [[Gamehelpmeridians|Meridians]]&lt;br /&gt;
* [[Gamehelpminhwatu|Minhwatu]]&lt;br /&gt;
* [[Gamehelpmorocco|Morocco]]&lt;br /&gt;
* [[Gamehelpmycity|My City]]&lt;br /&gt;
* [[Gamehelpobsessiion|Obsession]]&lt;br /&gt;
* [[Gamehelppaniclab|Panic Lab]]&lt;br /&gt;
* [[Gamehelppiereighteen|Pier 18]]&lt;br /&gt;
* [[Gamehelppointsalad|Point Salad]]&lt;br /&gt;
* [[Gamehelppresident|President]]&lt;br /&gt;
* [[Gamehelppugsinmugs|Pugs in Mugs]]&lt;br /&gt;
* [[Gamehelpreflection|Reflection]]&lt;br /&gt;
* [[Gamehelprobotsateourpizza|Robots Ate Our Pizza]]&lt;br /&gt;
* [[Gamehelproomtwentyfive|Room 25]]&lt;br /&gt;
* [[Gamehelpsamarkand|Samarkand]]&lt;br /&gt;
* [[Gamehelpseikatsu|Seikatsu]]&lt;br /&gt;
* [[Gamehelpsensei|Sensei]]&lt;br /&gt;
* [[Gamehelpsevens|Sevens]]&lt;br /&gt;
* [[Gamehelpsheepboombah|Sheep Boom Bah]]&lt;br /&gt;
* [[Gamehelpsoulaween|Soulaween]]&lt;br /&gt;
* [[Gamehelpspaceempires|Space Empire: 4X]]&lt;br /&gt;
* [[Gamehelpstrands|Strands]]&lt;br /&gt;
* [[Gamehelptalon|Talon]]&lt;br /&gt;
* [[Gamehelpthemotherroad|The Mother Road: Route 66]]&lt;br /&gt;
* [[Gamehelptheninedomains|The Nine Domains]]&lt;br /&gt;
* [[Gamehelptictacmatch|Tic-Tac Matc#]]&lt;br /&gt;
* [[Gamehelptinnerstrail|Tinner&#039;s Trail]]&lt;br /&gt;
* [[Gamehelptinyfarms|Tiny Farms]]&lt;br /&gt;
* [[Gamehelptrusis|Trusis]]&lt;br /&gt;
* [[Gamehelptucano|Tucano]]&lt;br /&gt;
* [[Gamehelpvolfyirion|Volfyirion Guilds]]&lt;br /&gt;
* [[Gamehelpworldwidetennis|Worldwide Tennis]]&lt;br /&gt;
* [[Gamehelpyaniv|Yaniv]]&lt;br /&gt;
* [[Gamehelpyoxii|Yoxii]]&lt;br /&gt;
* [[Gamehelpzooloretto|Zooloretto]]&lt;br /&gt;
  &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td valign=&amp;quot;top&amp;quot;&amp;gt;&lt;br /&gt;
* [[Gamehelpfifteendays|15 Days]]&lt;br /&gt;
* [[Gamehelpbohnanza|Bohnanza]]&lt;br /&gt;
* [[Gamehelpboomeranglm|Boomerang]]&lt;br /&gt;
* [[Gamehelpcalypso|Calypso]]&lt;br /&gt;
* [[Gamehelpchampionsofmidgard|Champions of Midgard]]&lt;br /&gt;
* [[Gamehelpchicagoexpress|Chicago Express]]&lt;br /&gt;
* [[Gamehelpcicerabigia|Cicera Bigia]]&lt;br /&gt;
* [[Gamehelpcitadels|Citadels]]&lt;br /&gt;
* [[Gamehelpcoinage|Coin Age]]&lt;br /&gt;
* [[Gamehelpcosmosempires|Cosmos: Empires]]&lt;br /&gt;
* [[Gamehelpcrazyeights|Crazy Eights]]&lt;br /&gt;
* [[Gamehelpdaihasamishogi|Dai Hasami Shogi]]&lt;br /&gt;
* [[Gamehelpdurak|Durak]]&lt;br /&gt;
* [[Gamehelpginkgopolis|Ginkgopolis]]&lt;br /&gt;
* [[Gamehelpgravitysuperstar|Gravity Superstar]]&lt;br /&gt;
* [[Gamehelpguibole|Guibole]]&lt;br /&gt;
* [[Gamehelphats|Hats]]&lt;br /&gt;
* [[Gamehelpindianchief|Indian Chief]]&lt;br /&gt;
* [[Gamehelpmagicmaze|Magic Maze]]&lt;br /&gt;
* [[Gamehelpmahjong|Mahjong]]&lt;br /&gt;
* [[Gamehelpmanhattannewgame|Manhattan]]&lt;br /&gt;
* [[Gamehelpmantisfalls|Mantis Falls]]&lt;br /&gt;
* [[Gamehelpmartianchess|Martian Chess]]&lt;br /&gt;
* [[Gamehelpminnesotawhist|Minnesota Whist]]&lt;br /&gt;
* [[Gamehelpmu|Mu]]&lt;br /&gt;
* [[Gamehelpmyfirstcastlepanic|My First Castle Panic]]&lt;br /&gt;
* [[Gamehelpnainjaune|Nain Jaune]]&lt;br /&gt;
* [[Gamehelppinochle|Pinochle]]&lt;br /&gt;
* [[Gamehelpfixtheteleporter|Please Fix the Teleporter]]&lt;br /&gt;
* [[Gamehelptexasholdem|Poker Texas Hold&#039;em]]&lt;br /&gt;
* [[Gamehelpriftforce|Riftforce]]&lt;br /&gt;
* [[Gamehelpristiseiska|Ristiseiska]]&lt;br /&gt;
* [[Gamehelpschwimmen|Schwimmen]]&lt;br /&gt;
* [[Gamehelpninefivetwo|Sergeant Major]]&lt;br /&gt;
* [[Gamehelpsnekagon|Snekagon]]&lt;br /&gt;
* [[Gamehelpsnowtime|Snow Time]]&lt;br /&gt;
* [[Gamehelpspiritsoftheforest|Spirits of the Forest]]&lt;br /&gt;
* [[Gamehelptemplari|Templari]]&lt;br /&gt;
* [[Gamehelpthreespot|Three Spot]]&lt;br /&gt;
* [[Gamehelptrasteroslocoscrazyauctions|Trasteros Locos: Crazy Auctions]]&lt;br /&gt;
* [[Gamehelptroggu|Troggu]]&lt;br /&gt;
* [[Gamehelpwatergate|Watergate]]&lt;br /&gt;
* [[Gamehelpwazabi|Wazabi]]&lt;br /&gt;
* [[Gamehelpxanadu|Xanadu]]&lt;br /&gt;
* [[Gamehelpyspahan|Yspahan]]&lt;br /&gt;
  &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td valign=&amp;quot;top&amp;quot;&amp;gt;&lt;br /&gt;
* [[Gamehelpdominion|Dominion]]&lt;br /&gt;
* [[Gamehelpinjawara|INJAWARA]]&lt;br /&gt;
* [[Gamehelpharbour|Harbour]]&lt;br /&gt;
  &amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== About available games and their content ==&lt;br /&gt;
&lt;br /&gt;
Games are games and it&#039;s all up to publishers to make them relevant or accurate to history, or not.&lt;br /&gt;
&lt;br /&gt;
We&#039;re focusing on gameplay and rules. We&#039;re not history books, nor an accurate source for anything related to real things.&lt;br /&gt;
&lt;br /&gt;
BGA is against any bad behaviors on real people, and will never EVER join, talk or expose about anything about themes, history or politics.&lt;br /&gt;
&lt;br /&gt;
Also please note that they&#039;re also a source to motivate talks, reflexion, exchange and viewpoints about history and education anywhere else.&lt;br /&gt;
&lt;br /&gt;
We&#039;re a gaming platform, we welcome everyone and do efforts daily to make this place a nice place to play nice games with nice people.&lt;/div&gt;</summary>
		<author><name>SwHawk</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Gamehelpcosmosempires&amp;diff=15173</id>
		<title>Gamehelpcosmosempires</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Gamehelpcosmosempires&amp;diff=15173"/>
		<updated>2022-11-02T14:41:10Z</updated>

		<summary type="html">&lt;p&gt;SwHawk: Created page with &amp;quot;The game is played with a single deck, from which 10 cards are drawn into the &amp;quot;build pool&amp;quot; where players can select and build cards from. Each card has a cost, roll value and...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The game is played with a single deck, from which 10 cards are drawn into the &amp;quot;build pool&amp;quot; where players can select and build cards from. Each card has a cost, roll value and production value.&lt;br /&gt;
&lt;br /&gt;
==Objective==&lt;br /&gt;
The first player to reach a total production value (sum of production values from all of their card) of 30 starts the last turn. The last turn then proceeds up to the last player of the turn. The winner is then the players with the highest production value.&lt;br /&gt;
&lt;br /&gt;
==Player turn==&lt;br /&gt;
&lt;br /&gt;
===Production phase===&lt;br /&gt;
Except for each player&#039;s first turn, the active player starts their turn by rolling the two four sided dice and spending actions to adjust the total roll value (sum of the two dice, each action spent allows to adjust that total value by +/- 1). Some cards will grant you this action for free each turn, once per card. Once the player confirms the roll value, each player around the table receives an amount of credits equal to the sum of the production value of the card with that specific roll value.&lt;br /&gt;
&lt;br /&gt;
===Main phase===&lt;br /&gt;
During this phase, the active player can spend their remaining actions to perform the following:&lt;br /&gt;
&lt;br /&gt;
* Buying a card from the build pool. A new card is then picked from the deck to replace it. The active player adds this card to their playing area,&lt;br /&gt;
* Cycling a card from the build pool and get 2 credits. The selected card is put under the deck and a new one is picked to replace it.&lt;br /&gt;
&lt;br /&gt;
Some cards will grant you extra actions that can be performed each turn, once per card granting that extra action:&lt;br /&gt;
&lt;br /&gt;
* Buying a Mech card from the build pool without spending a regular action, but the player still has to pay for the credits,&lt;br /&gt;
* Cycling a card from the build pool without spending a regular action, but without getting 2 credits as well.&lt;br /&gt;
&lt;br /&gt;
You are not required to spend all of your actions before ending your turn.&lt;br /&gt;
&lt;br /&gt;
===End of turn===&lt;br /&gt;
Once a player has exhausted all of their actions or decided they don&#039;t want to spend them anymore, they reset their actions counter (for 5 players or less, each player gets 2 regular action per turn, for 6+ players, each players has 3 regular actions per turn) and pass the dice to the next player&lt;/div&gt;</summary>
		<author><name>SwHawk</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Options_and_preferences:_gameoptions.json,_gamepreferences.json&amp;diff=15146</id>
		<title>Options and preferences: gameoptions.json, gamepreferences.json</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Options_and_preferences:_gameoptions.json,_gamepreferences.json&amp;diff=15146"/>
		<updated>2022-10-28T14:38:08Z</updated>

		<summary type="html">&lt;p&gt;SwHawk: /* Game Options */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Studio_Framework_Navigation}}&lt;br /&gt;
&lt;br /&gt;
In this file, you can define your game options (i.e. game variants) and user preferences.&lt;br /&gt;
   &lt;br /&gt;
Note: If your game has no variants or preferences, you don&#039;t have to modify this file.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;IMPORTANT:&#039;&#039;&#039; after you edited this file and syncronized to ftp folder you have to go to the control panel and press &amp;quot;Reload game options configuration&amp;quot; for your changes &#039;&#039;&#039;to take effect&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Make sure you understand difference between options and preferences:&lt;br /&gt;
* Game options - something usually in the rule book defined as &amp;quot;variant&amp;quot; (except for 2,3,X people - that is automatically handled - you can query it)&lt;br /&gt;
* User preferences - personal choices of each player only visible to that specific player - i.e. layout, either or not to prompt for action, either or not auto-opt in in some actions, etc&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Game Options ==&lt;br /&gt;
&lt;br /&gt;
Game options are selected by the table creator and usually correspond to game variants, for example if the game includes expansions or certain special rules.&lt;br /&gt;
&lt;br /&gt;
These variants are defined in gameoptions.inc.php as the $game_options variable:  &lt;br /&gt;
&lt;br /&gt;
  $game_options = [ // exactly named that&lt;br /&gt;
  // options start with 100&lt;br /&gt;
        100 =&amp;gt; [ /*option description array for option 100*/ ], &lt;br /&gt;
        101 =&amp;gt; [ /*option description array for option 101*/ ], &lt;br /&gt;
        // etc&lt;br /&gt;
  ];&lt;br /&gt;
&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 ([&lt;br /&gt;
                        ...&lt;br /&gt;
                        &amp;quot;my_game_variant&amp;quot; =&amp;gt; 100,&lt;br /&gt;
              ]);&lt;br /&gt;
&lt;br /&gt;
Numbers have to be exactly from 100 to 199 (there can be gaps).&lt;br /&gt;
&lt;br /&gt;
That is how you access them during runtime:&lt;br /&gt;
&lt;br /&gt;
    public function isSecondVariant() {&lt;br /&gt;
        return $this-&amp;gt;getGameStateValue(&#039;my_game_variant&#039;) == 2;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
Or this&lt;br /&gt;
    $this-&amp;gt;gamestate-&amp;gt;table_globals[100]&lt;br /&gt;
&lt;br /&gt;
The following are the parameters of option description array:&lt;br /&gt;
* &#039;&#039;&#039;name&#039;&#039;&#039; - &#039;&#039;&#039;mandatory&#039;&#039;&#039;. The name of the option visible for table creator. Value must be wrapped in totranslate function.&lt;br /&gt;
* &#039;&#039;&#039;values&#039;&#039;&#039; - &#039;&#039;&#039;mandatory&#039;&#039;&#039;. The array (map) of values with additional parameters per value.&lt;br /&gt;
** &#039;&#039;&#039;name&#039;&#039;&#039; - &#039;&#039;&#039;mandatory&#039;&#039;&#039;. String representation of the numeric value visible to table creator. Value must be wrapped in totranslate function.&lt;br /&gt;
** &#039;&#039;&#039;description&#039;&#039;&#039; - String description of this value to use when the name of the option is not self-explanatory. Displayed at the table under the option when this value is selected.&lt;br /&gt;
** &#039;&#039;&#039;tmdisplay&#039;&#039;&#039; - String representation of the option visible in the table description in the lobby. Usually if a variant values are On and Off (default), the tmdisplay would be same as description name when On, and nothing (empty string) when Off. (&#039;&#039;&#039;Warning&#039;&#039;&#039;: due to some caching, a change in tmdisplay may not be effective immediately in the studio, even after forcing a reload of gameoptions.inc.php.) &#039;&#039;&#039;Pro Tip:&#039;&#039;&#039; You can use this as a pre-game communication by adding fake options that just do nothing in the game but make it easier to find other player wanted the same game configuration (see the crew deep sea for example).&lt;br /&gt;
** &#039;&#039;&#039;nobeginner&#039;&#039;&#039; - Set to true if not recommended for beginners&lt;br /&gt;
** &#039;&#039;&#039;firstgameonly&#039;&#039;&#039; - Set to true if this option is recommended only for the first game (discovery option)&lt;br /&gt;
** &#039;&#039;&#039;beta&#039;&#039;&#039; - Set to true to indicate that this option is in &amp;quot;beta&amp;quot; development stage (there will be a warning for players starting the game)&lt;br /&gt;
** &#039;&#039;&#039;alpha&#039;&#039;&#039; - Set to true to indicate that this option is in &amp;quot;alpha&amp;quot; development stage (there will be a warning, and starting the game will be allowed only in training mode except for the developer)&lt;br /&gt;
** &#039;&#039;&#039;premium&#039;&#039;&#039; - Option can be only used by premium members&lt;br /&gt;
* &#039;&#039;&#039;default&#039;&#039;&#039; - indicates the default value to use for this option (optional, if not present the first value listed is the default)&lt;br /&gt;
* &#039;&#039;&#039;displaycondition&#039;&#039;&#039; - checks the conditions before displaying the option for selection. All conditions must be true for the option to display. Supported condition types:&lt;br /&gt;
** &#039;&#039;minplayers&#039;&#039; condition ensures at least this many players (Note: if your game works with a disjoint interval of player counts, you can supply an array of valid counts instead of a single value)&lt;br /&gt;
** &#039;&#039;maxplayers&#039;&#039; conditions ensure at most this many players&lt;br /&gt;
** &#039;&#039;otheroption&#039;&#039; condition ensures another option is set to this given values. &lt;br /&gt;
** &#039;&#039;otheroptionisnot&#039;&#039; conditions ensure another option is NOT set to this given values&lt;br /&gt;
* &#039;&#039;&#039;displayconditionoperand&#039;&#039;&#039; - can be &#039;and&#039; (this is the default) or &#039;or&#039;. Allows to change the behaviour to display the option if one of the conditions is true instead of all of them.&lt;br /&gt;
* &#039;&#039;&#039;startcondition&#039;&#039;&#039; - checks the conditions (on options VALUES) before starting the game. All conditions must be true for the game to start, otherwise players will get a red error message when attempting to begin the game. Supported condition types:&lt;br /&gt;
** &#039;&#039;minplayers&#039;&#039; condition ensures at least this many players (Note: if your game works with a disjoint interval of player counts, you can supply an array of valid counts instead of a single value)&lt;br /&gt;
** &#039;&#039;maxplayers&#039;&#039; conditions ensure at most this many players&lt;br /&gt;
** &#039;&#039;otheroption&#039;&#039; conditions ensure another option is set to this given values. That works the same as in &#039;&#039;&#039;displaycondition&#039;&#039;&#039;.&lt;br /&gt;
** &#039;&#039;otheroptionisnot&#039;&#039; conditions ensure another option is NOT set to this given value.  That works the same as in &#039;&#039;&#039;displaycondition&#039;&#039;&#039;.&lt;br /&gt;
*: For all these condition types, a &#039;&#039;gamestartonly&#039;&#039; boolean option can be added, if you have options that are exclusive. Setting this boolean to &#039;&#039;true&#039;&#039; will defer the evaluation of the startcondition to the game creation, instead of preventing the player to select options that are exclusive at all. See [[#gamestartonly|below]] for an example.&lt;br /&gt;
* &#039;&#039;&#039;notdisplayedmessage&#039;&#039;&#039; - if option is not suppose to be visible because of displaycondition but this is set, the text will be visible instead of combo drop down&lt;br /&gt;
&lt;br /&gt;
Common options for all tables (reserved range 200-299):&lt;br /&gt;
*201 (const GAMESTATE_RATING_MODE) - ELO OFF (aka Training mode), &lt;br /&gt;
*200 (const GAMESTATE_CLOCK_MODE) - game speed profile, array(0,1,2) - realtime (technically &amp;lt;10 realtime but you cannot define range in php), values &amp;gt;=10 - turn based (currently 10..21)&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 $game_options = array(&lt;br /&gt;
     100 =&amp;gt; array(&lt;br /&gt;
         &#039;name&#039; =&amp;gt; totranslate(&#039;my game option&#039;),&lt;br /&gt;
         &#039;values&#039; =&amp;gt; array(&lt;br /&gt;
             // A simple value for this option:&lt;br /&gt;
             1 =&amp;gt; array(&lt;br /&gt;
                 &#039;name&#039; =&amp;gt; totranslate(&#039;option 1&#039;)&lt;br /&gt;
             ),&lt;br /&gt;
&lt;br /&gt;
             // A simple value for this option.&lt;br /&gt;
             // If this value is chosen, the value of &amp;quot;tmdisplay&amp;quot; is displayed in the game lobby&lt;br /&gt;
             2 =&amp;gt; array(&lt;br /&gt;
                 &#039;name&#039; =&amp;gt; totranslate(&#039;option 2&#039;),&lt;br /&gt;
                 &#039;tmdisplay&#039; =&amp;gt; totranslate(&#039;option 2&#039;)&lt;br /&gt;
             ),&lt;br /&gt;
&lt;br /&gt;
             // Another value, with other options:&lt;br /&gt;
             //  beta=true =&amp;gt; this option is in beta version right now.&lt;br /&gt;
             //  nobeginner=true  =&amp;gt;  this option is not recommended for beginners&lt;br /&gt;
             3 =&amp;gt; array(&lt;br /&gt;
                 &#039;name&#039; =&amp;gt; totranslate(&#039;option 3&#039;),&lt;br /&gt;
                 &#039;beta&#039; =&amp;gt; true,&lt;br /&gt;
                 &#039;nobeginner&#039; =&amp;gt; true&lt;br /&gt;
             ),&lt;br /&gt;
         ),&lt;br /&gt;
         &#039;default&#039; =&amp;gt; 1&lt;br /&gt;
     ),&lt;br /&gt;
     &lt;br /&gt;
     101 =&amp;gt; array(&lt;br /&gt;
         &#039;name&#039; =&amp;gt; totranslate(&#039;Draft variant&#039;),&lt;br /&gt;
         &#039;values&#039; =&amp;gt; array(&lt;br /&gt;
             1 =&amp;gt; array(&lt;br /&gt;
                 &#039;name&#039; =&amp;gt; totranslate(&#039;No draft&#039;)&lt;br /&gt;
             ),&lt;br /&gt;
             2 =&amp;gt; array(&lt;br /&gt;
                 &#039;name&#039; =&amp;gt; totranslate(&#039;Draft&#039;),&lt;br /&gt;
                 &#039;tmdisplay&#039; =&amp;gt; totranslate(&#039;Draft&#039;),&lt;br /&gt;
                 &#039;premium&#039; =&amp;gt; true,&lt;br /&gt;
                 &#039;nobeginner&#039; =&amp;gt; true&lt;br /&gt;
             ),&lt;br /&gt;
         ),&lt;br /&gt;
         &#039;displaycondition&#039; =&amp;gt; array( &lt;br /&gt;
             // Note: do not display this option unless these conditions are met&lt;br /&gt;
             array(&lt;br /&gt;
                 &#039;type&#039; =&amp;gt; &#039;otheroption&#039;,&lt;br /&gt;
                 &#039;id&#039; =&amp;gt; 100, // Game specific option defined in the same array above&lt;br /&gt;
                 &#039;value&#039; =&amp;gt; array(2, 3, 4)&lt;br /&gt;
             ),&lt;br /&gt;
             // Note: do not display this option unless these conditions are met&lt;br /&gt;
            array( &#039;type&#039; =&amp;gt; &#039;otheroption&#039;, &lt;br /&gt;
                 &#039;id&#039; =&amp;gt; 201, // ELO OFF hardcoded framework option&lt;br /&gt;
                 &#039;value&#039; =&amp;gt; 1 // 1 if OFF&lt;br /&gt;
            )&lt;br /&gt;
         ),&lt;br /&gt;
&lt;br /&gt;
         &#039;startcondition&#039; =&amp;gt; array(&lt;br /&gt;
             1 =&amp;gt; array(),&lt;br /&gt;
             2 =&amp;gt; array(&lt;br /&gt;
                 array(&lt;br /&gt;
                     &#039;type&#039; =&amp;gt; &#039;maxplayers&#039;,&lt;br /&gt;
                     &#039;value&#039; =&amp;gt; 3,&lt;br /&gt;
                     &#039;message&#039; =&amp;gt; totranslate(&#039;Draft option is available for 3 players maximum.&#039;)&lt;br /&gt;
                 )&lt;br /&gt;
             ),&lt;br /&gt;
         ),&lt;br /&gt;
     ),&lt;br /&gt;
     &lt;br /&gt;
     102 =&amp;gt; array(&lt;br /&gt;
         &#039;name&#039; =&amp;gt; totranslate(&#039;Takeovers&#039;),&lt;br /&gt;
         &#039;values&#039; =&amp;gt; array(&lt;br /&gt;
             2 =&amp;gt; array(&lt;br /&gt;
                 &#039;name&#039; =&amp;gt; totranslate(&#039;No takeover&#039;)&lt;br /&gt;
             ),&lt;br /&gt;
             1 =&amp;gt; array(&lt;br /&gt;
                 &#039;name&#039; =&amp;gt; totranslate(&#039;Allow takeovers&#039;),&lt;br /&gt;
                 &#039;tmdisplay&#039; =&amp;gt; totranslate(&#039;Takeovers&#039;),&lt;br /&gt;
                 &#039;premium&#039; =&amp;gt; true,&lt;br /&gt;
                 &#039;nobeginner&#039; =&amp;gt; true&lt;br /&gt;
             ),&lt;br /&gt;
         ),&lt;br /&gt;
         &#039;displaycondition&#039; =&amp;gt; array( // Note: do not display this option unless these conditions are met&lt;br /&gt;
             array(&lt;br /&gt;
                 &#039;type&#039; =&amp;gt; &#039;otheroption&#039;,&lt;br /&gt;
                 &#039;id&#039; =&amp;gt; 100,&lt;br /&gt;
                 &#039;value&#039; =&amp;gt; array(3, 4)&lt;br /&gt;
             )&lt;br /&gt;
         ),&lt;br /&gt;
         &#039;startcondition&#039; =&amp;gt; array(&lt;br /&gt;
             2 =&amp;gt; array(),&lt;br /&gt;
             1 =&amp;gt; array(&lt;br /&gt;
                 array(&lt;br /&gt;
                     &#039;type&#039; =&amp;gt; &#039;maxplayers&#039;,&lt;br /&gt;
                     &#039;value&#039; =&amp;gt; 2,&lt;br /&gt;
                     &#039;message&#039; =&amp;gt; totranslate(&#039;Rebel vs Imperium Takeover Scenario is available for 2 players only.&#039;)&lt;br /&gt;
                 )&lt;br /&gt;
             ),&lt;br /&gt;
         ),&lt;br /&gt;
     )&lt;br /&gt;
 );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example of option that condition on ELO off&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$game_options = array(&lt;br /&gt;
&lt;br /&gt;
        100 =&amp;gt; array(&lt;br /&gt;
                &#039;name&#039; =&amp;gt; totranslate(&#039;Learning Game (No Research)&#039;),&lt;br /&gt;
                &#039;values&#039; =&amp;gt; array(&lt;br /&gt;
                        &lt;br /&gt;
                        1 =&amp;gt; array( &#039;name&#039; =&amp;gt; totranslate(&#039;Off&#039;), &#039;tmdisplay&#039; =&amp;gt; totranslate(&#039;&#039;) ),&lt;br /&gt;
                        2 =&amp;gt; array( &#039;name&#039; =&amp;gt; totranslate(&#039;On&#039;), &#039;tmdisplay&#039; =&amp;gt; totranslate(&#039;Learning Game&#039;) ),&lt;br /&gt;
                        &lt;br /&gt;
                ),&lt;br /&gt;
                &#039;displaycondition&#039; =&amp;gt; array(&lt;br /&gt;
                        // Note: do not display this option unless these conditions are met&lt;br /&gt;
                        array( &#039;type&#039; =&amp;gt; &#039;otheroption&#039;,&lt;br /&gt;
                                &#039;id&#039; =&amp;gt; 201, // ELO OFF hardcoded framework option&lt;br /&gt;
                                &#039;value&#039; =&amp;gt; 1, // 1 if OFF&lt;br /&gt;
&lt;br /&gt;
                        )&lt;br /&gt;
                ),&lt;br /&gt;
                &#039;notdisplayedmessage&#039; =&amp;gt; totranslate(&#039;Learning variant available only with ELO off&#039;)&lt;br /&gt;
                ),&lt;br /&gt;
&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example of condition that is only available for REALTIME game mode&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&#039;displaycondition&#039; =&amp;gt; array(&lt;br /&gt;
    // Note: do not display this option until these conditions are met - game speed is selected as realtime&lt;br /&gt;
    array( &#039;type&#039; =&amp;gt; &#039;otheroption&#039;, &#039;id&#039; =&amp;gt; GAMESTATE_CLOCK_MODE, &#039;value&#039; =&amp;gt; array(0,1,2) )&lt;br /&gt;
),&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example of using condition on your own option&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        102 =&amp;gt; array(&lt;br /&gt;
                &#039;name&#039; =&amp;gt; totranslate(&#039;Scenarios&#039;),&lt;br /&gt;
                &#039;values&#039; =&amp;gt; array(&lt;br /&gt;
                        1 =&amp;gt; array( &#039;name&#039; =&amp;gt; totranslate(&#039;Off&#039;),&lt;br /&gt;
                                &#039;nobeginner&#039; =&amp;gt; false  ),&lt;br /&gt;
                        2 =&amp;gt; array( &#039;name&#039; =&amp;gt; totranslate(&#039;On&#039;), &#039;tmdisplay&#039; =&amp;gt; totranslate(&#039;Scenarios&#039;),&lt;br /&gt;
                                &#039;nobeginner&#039; =&amp;gt; true  ),&lt;br /&gt;
                        &lt;br /&gt;
                ),&lt;br /&gt;
                &#039;displaycondition&#039; =&amp;gt; array(&lt;br /&gt;
                        // Note: do not display this option unless these conditions are met&lt;br /&gt;
                        array( &#039;type&#039; =&amp;gt; &#039;otheroptionisnot&#039;,&lt;br /&gt;
                                &#039;id&#039; =&amp;gt; 100, // learning variant&lt;br /&gt;
                                &#039;value&#039; =&amp;gt; 2, // 1 if OFF,2 is ON&lt;br /&gt;
                                &lt;br /&gt;
                        )&lt;br /&gt;
                ),&lt;br /&gt;
                &#039;notdisplayedmessage&#039; =&amp;gt; totranslate(&#039;Scenarios variant is not available if Learning variant is chosen&#039;)&lt;br /&gt;
        ),&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example of handling solo vs multiplayer options:&lt;br /&gt;
&lt;br /&gt;
&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;Board setup&#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;Mirror setup&#039; ),&lt;br /&gt;
                &#039;description&#039; =&amp;gt; totranslate( &#039;The starting player shuffles their 6 Farm Cards and randomly lays a card face up in each of the round spaces of their Fruit Island Board. The other players then lay their cards in exactly the same way, copying the order of the starting player.&#039; ),&lt;br /&gt;
                &#039;tmdisplay&#039; =&amp;gt; totranslate( &#039;Mirror setup&#039; ),&lt;br /&gt;
            ),&lt;br /&gt;
            2 =&amp;gt; array(&lt;br /&gt;
                &#039;name&#039; =&amp;gt; totranslate( &#039;Random setup&#039; ),&lt;br /&gt;
                &#039;description&#039; =&amp;gt; totranslate( &#039;Instead of every player copying the same card configuration as the starting player, every player shuffles their Farm Cards and lays down the cards randomly on their Fruit Island Board.&#039; ),&lt;br /&gt;
                &#039;tmdisplay&#039; =&amp;gt; totranslate( &#039;Random setup&#039; ),&lt;br /&gt;
            ),&lt;br /&gt;
        ),&lt;br /&gt;
        &#039;displaycondition&#039; =&amp;gt; array(&lt;br /&gt;
            // Note: only display for non-solo mode&lt;br /&gt;
            array(&lt;br /&gt;
                &#039;type&#039; =&amp;gt; &#039;minplayers&#039;,&lt;br /&gt;
                &#039;value&#039; =&amp;gt; array (2, 3, 4),&lt;br /&gt;
            ),&lt;br /&gt;
        ),&lt;br /&gt;
    ),&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    102 =&amp;gt; array(&lt;br /&gt;
        &#039;name&#039; =&amp;gt; totranslate(&#039;Solo difficulty&#039;),&lt;br /&gt;
        &#039;values&#039; =&amp;gt; array(&lt;br /&gt;
            0 =&amp;gt; array(&lt;br /&gt;
                &#039;name&#039; =&amp;gt; totranslate( &#039;Banan-apprentice&#039; ),&lt;br /&gt;
                &#039;description&#039; =&amp;gt; totranslate( &#039;Do not remove any seed before starting the game.&#039; ),&lt;br /&gt;
                &#039;tmdisplay&#039; =&amp;gt; totranslate( &#039;Banan-apprentice&#039; ),&lt;br /&gt;
            ),&lt;br /&gt;
            1 =&amp;gt; array(&lt;br /&gt;
                &#039;name&#039; =&amp;gt; totranslate( &#039;Pear to the Throne&#039; ),&lt;br /&gt;
                &#039;description&#039; =&amp;gt; totranslate( &#039;Remove 1 seed before starting the game.&#039; ),&lt;br /&gt;
                &#039;tmdisplay&#039; =&amp;gt; totranslate( &#039;Pear to the Throne&#039; ),&lt;br /&gt;
            )&lt;br /&gt;
        ),&lt;br /&gt;
        &#039;displaycondition&#039; =&amp;gt; array(&lt;br /&gt;
            // Note: only display for solo mode&lt;br /&gt;
            array(&lt;br /&gt;
                &#039;type&#039; =&amp;gt; &#039;maxplayers&#039;,&lt;br /&gt;
                &#039;value&#039; =&amp;gt; 1&lt;br /&gt;
            ),&lt;br /&gt;
        ),&lt;br /&gt;
    ),&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== displaycondition vs startcondition ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;displaycondition&amp;lt;/code&amp;gt; should be used when an option should not be present in the list under certain conditions.&lt;br /&gt;
&lt;br /&gt;
For example, displaying the option which is consistent with the player count.&lt;br /&gt;
&lt;br /&gt;
* 2 player maps: A B C D &lt;br /&gt;
* 3 player maps: E F G H&lt;br /&gt;
* 4 player maps: I J K L&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;startcondition&amp;lt;/code&amp;gt; should be used when a specific combination of option values is invalid, but the option itself still makes sense to show.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
* Player 1 faction: A, B, C, D, E, F, G&lt;br /&gt;
* Player 2 faction: A, B, C, D, E, F, G&lt;br /&gt;
* startcondition: both players can&#039;t be the same faction&lt;br /&gt;
&lt;br /&gt;
These options should both be displayed at all times, but there are some invalid configurations.&lt;br /&gt;
&lt;br /&gt;
==== gamestartonly ====&lt;br /&gt;
&lt;br /&gt;
On the table configuration page, it won&#039;t let you select a combination which is invalid according to &amp;lt;code&amp;gt;startcondition&amp;lt;/code&amp;gt;. Doing so will show a red warning, and will revert the option to the previous value. This means you could end up in a situation where you can&#039;t easily change between certain options (requiring you to set or unset options in a specific order).&lt;br /&gt;
&lt;br /&gt;
The consequence of the &amp;lt;code&amp;gt;gamestartonly&amp;lt;/code&amp;gt; flag is that the player _can_ select an invalid combination. However, when clicking &amp;quot;Start&amp;quot;, an invalid combination will produce an error.&lt;br /&gt;
&lt;br /&gt;
Probably the easiest way to see what the difference is is with an example.&lt;br /&gt;
&lt;br /&gt;
With a _Clans of Caledonia_ table:&lt;br /&gt;
* set to training mode&lt;br /&gt;
* set player count to 1&lt;br /&gt;
* try setting &amp;quot;Clan Auction&amp;quot; to one of the &amp;quot;On&amp;quot; options&lt;br /&gt;
* try starting the game, there&#039;s an error! Ie. &amp;lt;code&amp;gt;&amp;quot;gamestartonly&amp;quot; =&amp;gt; true&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then, with a _Sushi Go Party!_ table:&lt;br /&gt;
* set number of players to 7&lt;br /&gt;
* try setting &amp;quot;Sushi Go! / Sushi Go Party!&amp;quot; to &amp;quot;Sushi Go!&amp;quot;&lt;br /&gt;
* you can&#039;t set the option! Ie. &amp;lt;code&amp;gt;&amp;quot;gamestartonly&amp;quot; =&amp;gt; false&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In code:&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;Option name&#039;),&lt;br /&gt;
        &#039;values&#039; =&amp;gt; array( ... ),&lt;br /&gt;
        &#039;startcondition&#039; =&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;This option is available for 2 players only.&#039;),&lt;br /&gt;
                     &#039;gamestartonly&#039; =&amp;gt; true, // true = check only on gamestart, false = don&#039;t allow player to even select this combination&lt;br /&gt;
                 )&lt;br /&gt;
             ),&lt;br /&gt;
         ),&lt;br /&gt;
    ),&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 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;
These preferences appear in the three-line hamburger menu in the top corner of the bga menu.  &amp;quot;Display game logs&amp;quot; and Display tooltips&amp;quot; are baked-in by default, but you can extend this list as below. &lt;br /&gt;
&lt;br /&gt;
[[File:century_preferences_menu.PNG|400px|The user preferences menu for the game Century]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
&#039;&#039;These preferences are a good place to put accessibility options - as Century did for its Colorblind Support.&#039;&#039;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&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;Colorblind Support&#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;None&#039; ), &#039;cssPref&#039; =&amp;gt; &#039;colorblind_off&#039; ),&lt;br /&gt;
                        2 =&amp;gt; array( &#039;name&#039; =&amp;gt; totranslate( &#039;Numbers&#039; ), &#039;cssPref&#039; =&amp;gt; &#039;colorblind_on&#039; ),&lt;br /&gt;
                        3 =&amp;gt; array( &#039;name&#039; =&amp;gt; totranslate( &#039;Shapes&#039; ), &#039;cssPref&#039; =&amp;gt; &#039;colorblind_shapes&#039; )&lt;br /&gt;
                ),&lt;br /&gt;
                &#039;default&#039; =&amp;gt; 1&lt;br /&gt;
        ),&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There is two ways to check/apply this. In java Script&lt;br /&gt;
&lt;br /&gt;
  if (this.prefs[100].value == 2) ...&lt;br /&gt;
&lt;br /&gt;
This checks if preferences 100 has selected value 2.&lt;br /&gt;
&lt;br /&gt;
Second, if cssPref specified it will be applied to the &#039;&#039;&#039;&amp;lt;html&amp;gt;&#039;&#039;&#039; tag. So you can use different css styling for the preference. Note: it seems needed to set needReload to true for that class change to be effective.&lt;br /&gt;
&lt;br /&gt;
As user you have to select them from the Gear menu when game is started. On studio only user0 will have it actually working (bug?).&lt;br /&gt;
&lt;br /&gt;
The following are the parameters of preferences description array:&lt;br /&gt;
* &#039;&#039;&#039;name&#039;&#039;&#039; - &#039;&#039;&#039;mandatory&#039;&#039;&#039;. The name of the preference. Value will be automatically wrapped in totranslate if you don&#039;t.&lt;br /&gt;
* &#039;&#039;&#039;needReload&#039;&#039;&#039; - If set to true, the game interface will auto-reload after a change of the preference.&lt;br /&gt;
* &#039;&#039;&#039;values&#039;&#039;&#039; - &#039;&#039;&#039;mandatory&#039;&#039;&#039;. The array (map) of values with additional parameters per value.&lt;br /&gt;
** &#039;&#039;&#039;name&#039;&#039;&#039; - &#039;&#039;&#039;mandatory&#039;&#039;&#039;. String representation of the numeric value. Value will be automatically wrapped in totranslate if you don&#039;t.&lt;br /&gt;
** &#039;&#039;&#039;cssPref&#039;&#039;&#039; - CSS class to add to the &#039;&#039;&#039;&amp;lt;html&amp;gt;&#039;&#039;&#039; tag. Currently it is added or removed only after a reload (see needReload).&lt;br /&gt;
* &#039;&#039;&#039;default&#039;&#039;&#039; - Indicates the default value to use for this preference (optional, if not present the first value listed is the default).&lt;br /&gt;
&lt;br /&gt;
=== Listening for preference changes ===&lt;br /&gt;
&lt;br /&gt;
The BGA framework lacks any callback to notify your game when a user preference is changed (see [https://studio.boardgamearena.com/bug?id=36 proposal #36]), but you can create your own if you need to run some UI code in response to a preference change.&lt;br /&gt;
&lt;br /&gt;
; In ggg.js&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    setup: function (gamedatas) {&lt;br /&gt;
      // your setup code here ...&lt;br /&gt;
&lt;br /&gt;
      this.initPreferencesObserver();&lt;br /&gt;
    },&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
    initPreferencesObserver: function () {      &lt;br /&gt;
      // Call onPreferenceChange() when any value changes&lt;br /&gt;
      dojo.query(&#039;.preference_control&#039;).on(&#039;change&#039;, (e) =&amp;gt; {&lt;br /&gt;
        const match = e.target.id.match(/^preference_[cf]ontrol_(\d+)$/);&lt;br /&gt;
        if (!match) {&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        const pref = match[1];&lt;br /&gt;
        const newValue = e.target.value;&lt;br /&gt;
        this.prefs[pref].value = newValue;&lt;br /&gt;
        this.onPreferenceChange(pref, newValue);&lt;br /&gt;
      });&lt;br /&gt;
    },&lt;br /&gt;
    &lt;br /&gt;
    onPreferenceChange: function (prefId, prefValue) {&lt;br /&gt;
      console.log(&amp;quot;Preference changed&amp;quot;, prefId, prefValue);&lt;br /&gt;
      // your code here to handle the change&lt;br /&gt;
    },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Updating preference from code ===&lt;br /&gt;
The BGA framework lacks any method to update a user preference from the code (see [https://studio.boardgamearena.com/bug?id=36 proposal #36]), but you can create your own if you need to.&lt;br /&gt;
&lt;br /&gt;
; In ggg.js&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    updatePreference: function(prefId, newValue) {&lt;br /&gt;
        // Select preference value in control:&lt;br /&gt;
        dojo.query(&#039;#preference_control_&#039; + prefId + &#039; &amp;gt; option[value=&amp;quot;&#039; + newValue&lt;br /&gt;
        // Also select fontrol to fix a BGA framework bug:&lt;br /&gt;
            + &#039;&amp;quot;], #preference_fontrol_&#039; + prefId + &#039; &amp;gt; option[value=&amp;quot;&#039; + newValue&lt;br /&gt;
            + &#039;&amp;quot;]&#039;).forEach((value) =&amp;gt; dojo.attr(value, &#039;selected&#039;, true));&lt;br /&gt;
        // Generate change event on control to trigger callbacks:&lt;br /&gt;
        const newEvt = document.createEvent(&#039;HTMLEvents&#039;);&lt;br /&gt;
        newEvt.initEvent(&#039;change&#039;, false, true);&lt;br /&gt;
        $(&#039;preference_control_&#039; + prefId).dispatchEvent(newEvt);&lt;br /&gt;
    },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Accessing User Preferences on the server ===&lt;br /&gt;
PHP has a variable called $this-&amp;gt;player_preferences.&lt;br /&gt;
This contains a table of player preferences, ONLY accessible in setupNewGame().&lt;br /&gt;
You can use this to populate a table that you manage yourself.&lt;br /&gt;
You have to update the table when a player changes preference (and you have to hook up a listener and initiate an AJAX call out-of-turn).&lt;br /&gt;
Check the code of Agricola for details but this should work:&lt;br /&gt;
&lt;br /&gt;
; In dbmodel.sql&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE TABLE IF NOT EXISTS `user_preferences` (&lt;br /&gt;
  `player_id` int(10) NOT NULL,&lt;br /&gt;
  `pref_id` int(10) NOT NULL,&lt;br /&gt;
  `pref_value` int(10) NOT NULL,&lt;br /&gt;
  PRIMARY KEY (`player_id`, `pref_id`)&lt;br /&gt;
) ENGINE=InnoDB DEFAULT CHARSET=utf8;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; In ggg.game.php&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
protected function setupNewGame($players, $options = array())&lt;br /&gt;
{&lt;br /&gt;
// TODO: Save $this-&amp;gt;player_preferences: key is player_id, value is array with pref_id as key and pref_value as value&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; In ggg.js&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// use code for initPreferencesObserver from above example&lt;br /&gt;
&lt;br /&gt;
onPreferenceChange(prefId, prefValue) {&lt;br /&gt;
    prefId = parseInt(prefId);&lt;br /&gt;
    if (prefId === 101 /*TODO: You probably want to send only some preferences*/) {&lt;br /&gt;
        // TODO: Code your own action in ggg.action.php and send it prefId and prefValue&lt;br /&gt;
        //       The on the server side you can save it all in the user_preferences&lt;br /&gt;
        //       table you created above.&lt;br /&gt;
    }&lt;br /&gt;
},&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Studio]]&lt;/div&gt;</summary>
		<author><name>SwHawk</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Gamehelpsensei&amp;diff=15133</id>
		<title>Gamehelpsensei</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Gamehelpsensei&amp;diff=15133"/>
		<updated>2022-10-26T19:19:54Z</updated>

		<summary type="html">&lt;p&gt;SwHawk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;GOAL OF THE GAME&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To be the first player to bring his character to the opposite side of the board.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;PREPARATION&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
At the beginning of the game, players choose a version to play « Arashi » or « Sizukana », as explained below. The stones are placed in a line on two opposite edges on player&#039;s home row. Each player&#039;s character is placed on their middle stone.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;HOW TO PLAY&#039;&#039;&#039;&lt;br /&gt;
Each player has three choices on their turn. You must choose to perform at least one of the three following actions &#039;&#039;(in any order)&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
• move a stone of your color&lt;br /&gt;
&lt;br /&gt;
• move a second stone of your color or move the first stone again&lt;br /&gt;
&lt;br /&gt;
• move your character&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;MOVE STONES&#039;&#039;&#039;  -  The stones move horizontally or vertically without changing direction (it is forbidden to move a stone diagonally) . So, to move a stone horizontally and vertically, you need to use two actions. Only one stone can be placed on each square stone. A stone with a character on it cannot move. A stone is stopped by an opponent&#039;s stone.&lt;br /&gt;
&lt;br /&gt;
During each turn, a player can execute one or two movements of stones (the two movements can be made by the same stone). Movements may be made in any order. For instance, the movement of a character can be made between two movements of stones in one turn.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VERSION ARASHI or VERSION SHIZUKANA&#039;&#039;&#039;&lt;br /&gt;
   VERSION ARASHI - You can move your stones as many squares as you wish as long as the spaces are open (not blocked by your stones or your opponent&#039;s), but always in only one direction.&lt;br /&gt;
&lt;br /&gt;
   VERSION SHIZUKANA You can move your stones only one square.&lt;br /&gt;
&#039;&#039;NOTE: only one version is chosen for playing at the beginning of each game.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;MOVE your CHARACTER&#039;&#039;&#039;  -  A character can move between two stones of their color and the length of the movement is not limited. IF:&lt;br /&gt;
   The two stones are aligned along the same line horizontally, vertically or diagonally;&lt;br /&gt;
   AND&#039;&lt;br /&gt;
   there are no opponent&#039;s stones between their two stones.&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;&#039;UNFAIR GAME &#039;&#039;(ENDS THE GAME EARLY)&#039;&#039;&#039;&#039;&#039; - If a player blocks the game by creating a line that may not be crossed by the opponent&#039;s stones, then you may lose the game due to unfair game play if their opponent puts at least three stones in contact with the impassable line stones.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NORMAL END OF THE GAME&#039;&#039;  -  The first player to bring their character onto one of their own color stones located on the opponent&#039;s home row wins the game.  &lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&#039;&#039;&#039;VARIANT SHIZUKANA&#039;&#039;&#039;&#039;  -  Rules are the same. Only the placement of the stones changes at the beginning of the game. Each player has two stones on the opponent&#039;s start line.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;VARIANT ARASHI EXPERT&#039;&#039;&#039; (using on the opposite side of the board) The stones cannot move through or fall into the pits. However a player&#039;s character can move over the pits. In checking for UNFAIR GAME the pits are treated like uncrossable stones.&lt;/div&gt;</summary>
		<author><name>SwHawk</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=BGA_Studio_Cookbook&amp;diff=14564</id>
		<title>BGA Studio Cookbook</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=BGA_Studio_Cookbook&amp;diff=14564"/>
		<updated>2022-09-02T18:33:54Z</updated>

		<summary type="html">&lt;p&gt;SwHawk: /* Third way: rely on the transform argument of dojo.string.substitute */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
This page is collection of design and implementation recipes for BGA Studio framework.&lt;br /&gt;
For tooling and usage recipes see [[Tools and tips of BGA Studio]].&lt;br /&gt;
If you have your own recipes feel free to edit this page.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Visual Effects, Layout and Animation ==&lt;br /&gt;
&lt;br /&gt;
=== DOM manipulatons ===&lt;br /&gt;
&lt;br /&gt;
==== Create pieces dynamically (using template) ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg_ggg.tpl, ggg.js&lt;br /&gt;
&lt;br /&gt;
Note: this method is recommended by BGA guildlines&lt;br /&gt;
&lt;br /&gt;
Declared js template with variables in .tpl file, like this&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;
    // Javascript HTML templates&lt;br /&gt;
    var jstpl_ipiece = &#039;&amp;lt;div class=&amp;quot;${type} ${type}_${color} inlineblock&amp;quot; aria-label=&amp;quot;${name}&amp;quot; title=&amp;quot;${name}&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use it like this in .js file&lt;br /&gt;
  div = this.format_block(&#039;jstpl_ipiece&#039;, {&lt;br /&gt;
                                type : &#039;meeple&#039;,&lt;br /&gt;
                                color : &#039;ff0000&#039;,&lt;br /&gt;
                                name : &#039;Bob&#039;,&lt;br /&gt;
                            });&lt;br /&gt;
  &lt;br /&gt;
Then you do whatever you need to do with that div, this one specifically design to go to log entries, because it has embedded title (otherwise its a picture only) and no id.&lt;br /&gt;
&lt;br /&gt;
Note: you could have place this variable in js itself, but keeping it in .tpl allows you to have your js code be free of HTML. Normally it never happens but&lt;br /&gt;
it is good to strive for it.&lt;br /&gt;
Note: you can also use string concatenation, its less readable. You can also use dojo dom object creation api&#039;s but its brutally verbose and its more unreadable.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Create pieces dynamically (using string concatenation) ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
Note: Not recommended&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  div = &amp;quot;&amp;lt;div class=&#039;meeple &amp;quot;+color+&amp;quot;&#039;&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
==== Create all pieces statically ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg_ggg.tpl, ggg.css, ggg.view.php (optional) &lt;br /&gt;
&lt;br /&gt;
* Create ALL game pieces in html template (.tpl)&lt;br /&gt;
* ALL pieces should have unique id, and it should be meaningful, i.e. meeple_red_1&lt;br /&gt;
* Do not use inline styling&lt;br /&gt;
* Id of player&#039;s specific pieces should use some sort of &#039;color&#039; identification, since player id cannot be used in static layout, you can use english color name, hex 6 char value, or color &amp;quot;number&amp;quot; (1,2,3...)&lt;br /&gt;
* Pieces should have separated class for its color, type, etc, so it can be easily styled in groups. In example below you now can style all meeples, all red meeples or all red tokens, or all &amp;quot;first&amp;quot; meeples&lt;br /&gt;
&lt;br /&gt;
ggg.tpl:&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
  &amp;lt;div id=&amp;quot;home_red&amp;quot; class=&amp;quot;home_red home&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;div id=&amp;quot;meeple_red_1&amp;quot; class=&amp;quot;meeple red n1&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
     &amp;lt;div id=&amp;quot;meeple_red_2&amp;quot; class=&amp;quot;meeple red n2&amp;quot;&amp;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;
ggg.css:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.meeple {&lt;br /&gt;
	width: 32px;&lt;br /&gt;
	height: 39px;&lt;br /&gt;
	background-image: url(img/78_64_stand_meeples.png);&lt;br /&gt;
	background-size: 352px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.meeple.red {&lt;br /&gt;
	background-position: 30% 0%;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* There should be straight forward mapping between server id and js id (or 1:1)&lt;br /&gt;
* You place objects in different zones of the layout, and setup css to take care of layout&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.home .meeple{&lt;br /&gt;
   display: inline-block;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* If you need to have a temporary object that look like original you can use dojo.clone (and change id to some temp id)&lt;br /&gt;
* If there is lots of repetition or zone grid you can use template generator, but inject style declaration in css instead of inline style for flexibility&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
* If you use this model you cannot use premade js components such as Stock and Zone&lt;br /&gt;
* You have to use alternative methods of animation (slightly altered) since default method will leave object with inline style attributes which you don&#039;t need&lt;br /&gt;
&lt;br /&gt;
=== Logs ===&lt;br /&gt;
&lt;br /&gt;
==== Inject icon images in the log ====&lt;br /&gt;
&lt;br /&gt;
Here is an example of what was done for Terra Mystica which is simple and straightforward:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
//Define the proper message&lt;br /&gt;
		$message = clienttranslate(&#039;${player_name} gets ${power_income} via Structures&#039;);&lt;br /&gt;
		if ($price &amp;gt; 0) {&lt;br /&gt;
			self::DbQuery(&amp;quot;UPDATE player SET player_score = player_score - $price WHERE player_id = $player_id&amp;quot;);&lt;br /&gt;
			$message = clienttranslate(&#039;${player_name} pays ${vp_price} and gets ${power_income} via Structures&#039;);&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
// Notify&lt;br /&gt;
		self::notifyAllPlayers( &amp;quot;powerViaStructures&amp;quot;, $message, array(&lt;br /&gt;
			&#039;i18n&#039; =&amp;gt; array( ),&lt;br /&gt;
			&#039;player_id&#039; =&amp;gt; $player_id,&lt;br /&gt;
			&#039;player_name&#039; =&amp;gt; self::getUniqueValueFromDb( &amp;quot;SELECT player_name FROM player WHERE player_id = $player_id&amp;quot; ),&lt;br /&gt;
			&#039;power_tokens&#039; =&amp;gt; $power_tokens,&lt;br /&gt;
			&#039;vp_price&#039; =&amp;gt; self::getLogsVPAmount($price),&lt;br /&gt;
			&#039;power_income&#039; =&amp;gt; self::getLogsPowerAmount($power_income),&lt;br /&gt;
			&#039;newScore&#039; =&amp;gt; self::getUniqueValueFromDb( &amp;quot;SELECT player_score FROM player WHERE player_id = $player_id&amp;quot; ),&lt;br /&gt;
			&#039;counters&#039; =&amp;gt; $this-&amp;gt;getGameCounters(null),&lt;br /&gt;
		) );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With some functions to have the needed html added inside the substitution variable, such as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function getLogsPowerAmount( $amount ) {&lt;br /&gt;
		return &amp;quot;&amp;lt;div class=&#039;tmlogs_icon&#039; title=&#039;Power&#039;&amp;gt;&amp;lt;div class=&#039;power_amount&#039;&amp;gt;$amount&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: injecting html from php is not ideal but easy, if you want more clean solution, use method below but it is a lot more sophisticated.&lt;br /&gt;
&lt;br /&gt;
==== Inject images and styled html in the log ====&lt;br /&gt;
&lt;br /&gt;
{{InfoBox|title=Warning — Translation|maxWidth=500|topLeftColour=#c00|middleColour=#c00|bottomRightColour=#c00|body=&#039;&#039;&#039;In order to prevent interference with the translation process, keep in mind that you must only apply modifications to the args object, and not try to substitute the keys (the &amp;lt;code&amp;gt;${player_name}&amp;lt;/code&amp;gt; parts of your string) in the log string.&#039;&#039;&#039;}}&lt;br /&gt;
&lt;br /&gt;
So you want nice pictures in the game log. What do you do? The first idea that comes to mind is to send html from php in notifications (see method above). &lt;br /&gt;
&lt;br /&gt;
This is a bad idea for many reasons:&lt;br /&gt;
&lt;br /&gt;
* It&#039;s bad architecture. ui elements leak into the server, and now you have to manage the ui in multiple places.&lt;br /&gt;
* If you decided to change something in the ui in future version, replay logs for old games and tutorials may not work, since they use stored notifications.&lt;br /&gt;
* Log previews for old games become unreadable. (This is the log state before you enter the game replay, which is useful for troubleshooting and game analysis.)&lt;br /&gt;
* It&#039;s more data to transfer and store in the db.&lt;br /&gt;
* It&#039;s a nightmare for translators.&lt;br /&gt;
&lt;br /&gt;
So what else can you do? You can use client side log injection to intercept log arguments (which come from the server) and replace them with html on the client side. Here are three different method you can use to achieve this.&lt;br /&gt;
&lt;br /&gt;
===== First way : Override &amp;lt;code&amp;gt;this.format_string_recursive()&amp;lt;/code&amp;gt; method =====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, ggg.game.php&lt;br /&gt;
&lt;br /&gt;
I use this recipe for &#039;&#039;&#039;client side log injection&#039;&#039;&#039; to intercept log arguments (which come from the server) and replace them with html on the client side.&lt;br /&gt;
&lt;br /&gt;
[[File:clientloginjection.png|left]] &lt;br /&gt;
&lt;br /&gt;
ggg.js&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
        /** Override this function to inject html into log items. This is a built-in BGA method.  */&lt;br /&gt;
&lt;br /&gt;
        /* @Override */&lt;br /&gt;
        format_string_recursive : function format_string_recursive(log, args) {&lt;br /&gt;
            try {&lt;br /&gt;
                if (log &amp;amp;&amp;amp; args &amp;amp;&amp;amp; !args.processed) {&lt;br /&gt;
                    args.processed = true;&lt;br /&gt;
                    &lt;br /&gt;
&lt;br /&gt;
                    // list of special keys we want to replace with images&lt;br /&gt;
                    var keys = [&#039;place_name&#039;,&#039;token_name&#039;];&lt;br /&gt;
                    &lt;br /&gt;
                  &lt;br /&gt;
                    for ( var i in keys) {&lt;br /&gt;
                        var key = keys[i];&lt;br /&gt;
                        key in args &amp;amp;&amp;amp; args[key] = this.getTokenDiv(key, args);                            &lt;br /&gt;
&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            } catch (e) {&lt;br /&gt;
                console.error(log,args,&amp;quot;Exception thrown&amp;quot;, e.stack);&lt;br /&gt;
            }&lt;br /&gt;
            return this.inherited({callee: format_string_recursive}, arguments);&lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important:&#039;&#039;&#039; In the &#039;&#039;format_string_recursive&#039;&#039; method, the &#039;args&#039; parameter will only contain arguments passed to it from the notify method in ggg.game.php (see below).&lt;br /&gt;
&lt;br /&gt;
The &#039;log&#039; parameter is the actual string that is inserted into the logs. You can perform additional js string manipulation on it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        getTokenDiv : function(key, args) {&lt;br /&gt;
            // ... implement whatever html you want here, example from sharedcode.js&lt;br /&gt;
            var token_id = args[key];&lt;br /&gt;
            var item_type = getPart(token_id,0);&lt;br /&gt;
            var logid = &amp;quot;log&amp;quot; + (this.globalid++) + &amp;quot;_&amp;quot; + token_id;&lt;br /&gt;
            switch (item_type) {&lt;br /&gt;
                case &#039;wcube&#039;:&lt;br /&gt;
                    var tokenDiv = this.format_block(&#039;jstpl_resource_log&#039;, {&lt;br /&gt;
                        &amp;quot;id&amp;quot; : logid,&lt;br /&gt;
                        &amp;quot;type&amp;quot; : &amp;quot;wcube&amp;quot;,&lt;br /&gt;
                        &amp;quot;color&amp;quot; : getPart(token_id,1),&lt;br /&gt;
                    });&lt;br /&gt;
                    return tokenDiv;&lt;br /&gt;
             &lt;br /&gt;
                case &#039;meeple&#039;:&lt;br /&gt;
                    if ($(token_id)) {&lt;br /&gt;
                        var clone = dojo.clone($(token_id));&lt;br /&gt;
    &lt;br /&gt;
                        dojo.attr(clone, &amp;quot;id&amp;quot;, logid);&lt;br /&gt;
                        this.stripPosition(clone);&lt;br /&gt;
                        dojo.addClass(clone, &amp;quot;logitem&amp;quot;);&lt;br /&gt;
                        return clone.outerHTML;&lt;br /&gt;
                    }&lt;br /&gt;
                    break;&lt;br /&gt;
     &lt;br /&gt;
                default:&lt;br /&gt;
                    break;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            return &amp;quot;&#039;&amp;quot; + this.clienttranslate_string(this.getTokenName(token_id)) + &amp;quot;&#039;&amp;quot;;&lt;br /&gt;
       },&lt;br /&gt;
       getTokenName : function(key) {&lt;br /&gt;
           return this.gamedatas.token_types[key].name; // get name for the key, from static table for example&lt;br /&gt;
       },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that in this case the server simply injects token_id as a name, and the client substitutes it for the translated name or the picture.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ggg.game.php:&lt;br /&gt;
&lt;br /&gt;
           $this-&amp;gt;notifyAllPlayers(&#039;playerLog&#039;,clienttranslate(&#039;Game moves ${token_name}&#039;),[&#039;token_name&#039;=&amp;gt;$token_id]);&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important:&#039;&#039;&#039; As noted above, only arguments actually passed by this method are available to the args parameter received in the client-side &#039;&#039;format_string_recursive&#039;&#039; method.&lt;br /&gt;
&lt;br /&gt;
Sometimes it is the case that you want to pass arguments that are not actually included in the output message. For example, suppose we have a method like this:&lt;br /&gt;
&lt;br /&gt;
           $this-&amp;gt;notifyAllPlayers(&#039;tokenPlaced&#039;,clienttranslate(&#039;Player placed ${token_name}&#039;),array(&lt;br /&gt;
              &#039;token_name&#039; =&amp;gt; $token_id,&lt;br /&gt;
              &#039;zone_played&#039; =&amp;gt; $zone);&lt;br /&gt;
&lt;br /&gt;
This will output &amp;quot;Player placed ${token_name}&amp;quot; in the log, and if we subscribe to a notification method activated by the &amp;quot;tokenPlaced&amp;quot; event in the client-side code, that method can make use of the &#039;zone_played&#039; argument. &lt;br /&gt;
&lt;br /&gt;
Now if you want to make some really cool things with game log, most probably you would need more arguments than are included in log message. The problem with that,&lt;br /&gt;
it will work at first, but if you reload game using F5 or when the game loads in turn based mode, you will loose your additional parameters, why? Because when game reloads it does not actually send same notifications, it sends special &amp;quot;hitstorical_log&amp;quot; notification where all  parameters not listed in the message are removed. In example above, field zone_played would be removed from historical log as it is not included in message of the notification. You can till preserve specific arguments in historical log by adding special field preserve to notification arguments like this:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
           $this-&amp;gt;notifyAllPlayers(&#039;tokenPlaced&#039;,clienttranslate(&#039;Player placed ${token_name}&#039;),array(&lt;br /&gt;
              &#039;token_name&#039; =&amp;gt; $token_id,&lt;br /&gt;
              &#039;zone_played&#039; =&amp;gt; $zone,&lt;br /&gt;
              &#039;preserve&#039; =&amp;gt; [ &#039;zone_played&#039; ]&lt;br /&gt;
           );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now you can use zone_played in format_string_recursive even in historical logs.&lt;br /&gt;
&lt;br /&gt;
===== Second way: rely on the &amp;lt;code&amp;gt;:formatFunction&amp;lt;/code&amp;gt; option provided by &amp;lt;code&amp;gt;dojo.string.substitute&amp;lt;/code&amp;gt; =====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, ggg.game.php, ggg_ggg.tpl, ggg.css&lt;br /&gt;
&lt;br /&gt;
The above method will work in most of the cases, but if you use dotted keys such as &amp;lt;code&amp;gt;${card.name}&amp;lt;/code&amp;gt; (which is supported by the framework, for private state args), the key won&#039;t be substituted because the &amp;lt;code&amp;gt;key in arg&amp;lt;/code&amp;gt; test will fail. If so you need to rely either on this way, or the one after.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;WARNING:&#039;&#039;&#039; using this method on an already advanced project will require you to go through all your notifications to change keys !&lt;br /&gt;
&lt;br /&gt;
Under the hood, the &#039;&#039;&#039;this.format_string_recursive()&#039;&#039;&#039; function calls the &#039;&#039;&#039;dojo.string.substitute&#039;&#039;&#039; method which substitutes &amp;lt;code&amp;gt;${keys}&amp;lt;/code&amp;gt; with the value provided. If you take a look at the [https://dojotoolkit.org/reference-guide/1.7/dojo/string.html#substitute documentation] and [https://github.com/dojo/dojo/blob/c3ceb017cfa25b703f5662dc83d1c8aae9bc5d81/string.js#L163 source code] you can notice that the key can be suffixed with a colon (&amp;lt;code&amp;gt;:&amp;lt;/code&amp;gt;) followed by a function name. This will allow you to specify directly in the substitution string which keys need HTML injection.&lt;br /&gt;
&lt;br /&gt;
First of all, you need to define your formatting function in the ggg.js file:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[[ggg.js]]&lt;br /&gt;
        getTokenDiv : function(value, key) {&lt;br /&gt;
            //This is only an example implementation, you need to write your own.&lt;br /&gt;
            //The method should return HTML code&lt;br /&gt;
            switch (key) {&lt;br /&gt;
                case &#039;html_injected_argument1&#039;:&lt;br /&gt;
                    return this.format_block(&#039;jstpl_HTMLLogElement1&#039;,{value: value});&lt;br /&gt;
                case &#039;html_injected_argument2&#039;:&lt;br /&gt;
                    return this.format_block(&#039;jstpl_HTMLLogElement2&#039;,{value: value});&lt;br /&gt;
                ...&lt;br /&gt;
            }&lt;br /&gt;
       }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Obviously you need to define the appropriate templates in the ggg_ggg.tpl file:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[[ggg_ggg.tpl]]&lt;br /&gt;
let jstpl_HTMLLogElement1 = &#039;&amp;lt;div class=&amp;quot;log-element log-element-1-${value}&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
let jstpl_HTMLLogElement2 = &#039;&amp;lt;div class=&amp;quot;log-element log-element-2-${value}&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
And the appropriate classes in ggg.css.&lt;br /&gt;
&lt;br /&gt;
Then you need to add the &amp;lt;code&amp;gt;dojo/aspect&amp;lt;/code&amp;gt; module at the top of the ggg.js file:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[ggg.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 define([&lt;br /&gt;
     &amp;quot;dojo&amp;quot;, &amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&amp;quot;dojo/aspect&amp;quot;,&amp;lt;/span&amp;gt;                 //MUST BE IN THIRD POSITION&#039;&#039;&#039; (see [[#Including your own JavaScript module (II)|below]])&lt;br /&gt;
     &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
 ], function (dojo, declare, &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&#039;&#039;&#039;aspect&#039;&#039;&#039;&amp;lt;/span&amp;gt;) {&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
And you also need to add the following code in your &amp;lt;code&amp;gt;contructor&amp;lt;/code&amp;gt; method in the ggg.js:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[ggg.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
         constructor: function(){&lt;br /&gt;
             console.log(&#039;progressevolutiontechnologyswh constructor&#039;);&lt;br /&gt;
               &lt;br /&gt;
             // Here, you can init the global variables of your user interface&lt;br /&gt;
             // Example:&lt;br /&gt;
             // this.myGlobalValue = 0;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&#039;&#039;&#039;let gameObject = this;&#039;&#039;&#039;            //Needed as the this object in aspect.before will not refer to the game object in which the formatting function resides&lt;br /&gt;
             &#039;&#039;&#039;aspect.before(dojo.string, &amp;quot;substitute&amp;quot;, function(template, map, transform) {&#039;&#039;&#039;      //This allows you to modify the arguments of the dojo.string.substitute method before they&#039;re actually passed to it&lt;br /&gt;
                 &#039;&#039;&#039;return [template, map, transform, gameObject];&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now you&#039;re all set to inject HTML in your logs. To actually achieve this, you must specify the function name with the key like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[ggg.game.php]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 $this-&amp;gt;notifyAllPlayers(&amp;quot;notificationName&amp;quot;, clienttranslate(&amp;quot;This log message contains ${plainTextArgument} and the following will receive HTML injection: ${html_injected_argument1:getTokenDiv}&amp;quot;), [&lt;br /&gt;
     &amp;quot;plainTextArgument&amp;quot; =&amp;gt; &amp;quot;some plain text here&amp;quot;,&lt;br /&gt;
     &amp;quot;html_injected_argument1&amp;quot; =&amp;gt; &amp;quot;some value used by getTokenDiv&amp;quot;,&lt;br /&gt;
 ]);&lt;br /&gt;
&lt;br /&gt;
You&#039;re not limited writing only one function, you can write as many functions as you like, and have them each inject a specific type of HTML. You just need to specify the relevant function name after the column in the substitution key.&lt;br /&gt;
&lt;br /&gt;
===== Third way: rely on the &amp;lt;code&amp;gt;transform&amp;lt;/code&amp;gt; argument of &amp;lt;code&amp;gt;dojo.string.substitute&amp;lt;/code&amp;gt; =====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, ggg.game.php, ggg_ggg.tpl, ggg.css&lt;br /&gt;
&lt;br /&gt;
This method is also relying on the use of &amp;lt;code&amp;gt;dojo.string.substitute&amp;lt;/code&amp;gt; by the framework, and will use the &amp;lt;code&amp;gt;transform&amp;lt;/code&amp;gt; argument, which, accordting to [https://github.com/dojo/dojo/blob/c3ceb017cfa25b703f5662dc83d1c8aae9bc5d81/string.js#L163 source code] and [https://dojotoolkit.org/reference-guide/1.7/dojo/string.html#substitute documentation] will be run on all the messages going through dojo.string.substitute.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;WARNING:&#039;&#039;&#039; This method will be applied to all strings that go through dojo.string.substitute. As such you must take extra care not to substitute keys that may be used by the framework (i.e. ${id}). In order to do so, a good practise would be to prefix all keys that need substitution with a trigram of the game name.&lt;br /&gt;
&lt;br /&gt;
Since all the keys will be fed to the tranform function, by default, it must return the value, substituted or not per your needs. You can define the function like this in the ggg.js file:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[ggg.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
         getTokenDiv : function(value, key) {&lt;br /&gt;
             //This is only an example implementation, you need to write your own.&lt;br /&gt;
             //The method should return HTML code&lt;br /&gt;
             switch (key) {&lt;br /&gt;
                 case &#039;html_injected_argument1&#039;:&lt;br /&gt;
                     return this.format_block(&#039;jstpl_HTMLLogElement1&#039;,{value: value});&lt;br /&gt;
                 case &#039;html_injected_argument2&#039;:&lt;br /&gt;
                     return this.format_block(&#039;jstpl_HTMLLogElement2&#039;,{value: value});&lt;br /&gt;
                 ...&lt;br /&gt;
                 &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&#039;&#039;&#039;default:&#039;&#039;&#039;&lt;br /&gt;
                     &#039;&#039;&#039;return value;&#039;&#039;&#039;&amp;lt;/span&amp;gt;                  &#039;&#039;&#039;//Needed otherwise regular strings won&#039;t appear since since the value isn&#039;t returned by the function&#039;&#039;&#039;&lt;br /&gt;
             }&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
The templates must be defined in the ggg_ggg.tpl file and the corresponding CSS classes in the ggg.css file.&lt;br /&gt;
&lt;br /&gt;
You need to add the following code at the beginning of the ggg.js file:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[ggg.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 define([&lt;br /&gt;
     &amp;quot;dojo&amp;quot;, &amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&amp;quot;dojo/aspect&amp;quot;,&amp;lt;/span&amp;gt;                 //MUST BE IN THIRD POSITION&#039;&#039;&#039; (see [[#Including your own JavaScript module (II)|below]])&lt;br /&gt;
     &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
 ], function (dojo, declare, &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&#039;&#039;&#039;aspect&#039;&#039;&#039;&amp;lt;/span&amp;gt;) {&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
And the following code to the &amp;lt;code&amp;gt;constructor&amp;lt;/code&amp;gt; method in ggg.js:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[ggg.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
         constructor: function(){&lt;br /&gt;
             console.log(&#039;progressevolutiontechnologyswh constructor&#039;);&lt;br /&gt;
               &lt;br /&gt;
             // Here, you can init the global variables of your user interface&lt;br /&gt;
             // Example:&lt;br /&gt;
             // this.myGlobalValue = 0;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&#039;&#039;&#039;let transformFunction = dojo.hitch(this, &amp;quot;getTokenDiv&amp;quot;);&#039;&#039;&#039;            //Needed as the this object in aspect.before will not refer to the game object in which the formatting function resides&lt;br /&gt;
             &#039;&#039;&#039;aspect.before(dojo.string, &amp;quot;substitute&amp;quot;, function(template, map, transform) {&#039;&#039;&#039;&lt;br /&gt;
                 &#039;&#039;&#039;if (undefined === transform) {&#039;&#039;&#039;                                   //Check for a transform function presence, just in case&lt;br /&gt;
                     &#039;&#039;&#039;return [template, map, transformFunction];&#039;&#039;&#039;&lt;br /&gt;
                 &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then you&#039;re all set for log injection, no need to change anything on the PHP side.&lt;br /&gt;
&lt;br /&gt;
==== Processing logs on re-loading ====&lt;br /&gt;
&lt;br /&gt;
You rarely need to process logs when reloading, but if you want to do something fancy you may have to do it after logs are loaded. &lt;br /&gt;
Logs are loaded asyncronously so you have to listen for logs to be fully loaded.&lt;br /&gt;
Unfortunately there is no direct way of doing it so this is the hack.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Hack alert&#039;&#039;&#039; - this extends undocumented function and may be broken when framework is updated&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
			/*&lt;br /&gt;
  			* [Undocumented] Override BGA framework functions to call onLoadingLogsComplete when loading is done&lt;br /&gt;
                        @Override&lt;br /&gt;
   			*/&lt;br /&gt;
			setLoader: function(image_progress, logs_progress) {&lt;br /&gt;
				this.inherited(arguments); // required, this is &amp;quot;super()&amp;quot; call, do not remove&lt;br /&gt;
				//console.log(&amp;quot;loader&amp;quot;, image_progress, logs_progress)&lt;br /&gt;
				if (!this.isLoadingLogsComplete &amp;amp;&amp;amp; logs_progress &amp;gt;= 100) {&lt;br /&gt;
					this.isLoadingLogsComplete = true; // this is to prevent from calling this more then once&lt;br /&gt;
					this.onLoadingLogsComplete();&lt;br /&gt;
				}&lt;br /&gt;
			},&lt;br /&gt;
&lt;br /&gt;
			onLoadingLogsComplete: function() {&lt;br /&gt;
				console.log(&#039;Loading logs complete&#039;);&lt;br /&gt;
				// do something here&lt;br /&gt;
			},&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Player Panel ===&lt;br /&gt;
&lt;br /&gt;
==== Inserting non-player panel ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, ggg_ggg.tpl&lt;br /&gt;
&lt;br /&gt;
If you want to insert non-player panel on the right side (for example to hold extra preferences, zooming controls, etc)&lt;br /&gt;
&lt;br /&gt;
this can go pretty much anywhere in template it will be moved later&lt;br /&gt;
&lt;br /&gt;
ggg_ggg.tpl:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	&amp;lt;div class=&#039;player_board_config&#039; id=&amp;quot;player_board_config&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;!-- here is whatever you want, buttons just example --&amp;gt;&lt;br /&gt;
		&amp;lt;button id=&amp;quot;zoom-out&amp;quot; class=&amp;quot; fa fa-search-minus fa-2x config-control&amp;quot;&amp;gt;&amp;lt;/button&amp;gt;&lt;br /&gt;
		&amp;lt;button id=&amp;quot;zoom-in&amp;quot; class=&amp;quot; fa fa-search-plus fa-2x config-control&amp;quot;&amp;gt;&amp;lt;/button&amp;gt;&lt;br /&gt;
		&amp;lt;button id=&amp;quot;show-settings&amp;quot; class=&amp;quot;fa fa-cog fa-2x config-control &amp;quot;&amp;gt;&amp;lt;/button&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
some hackery required in js&lt;br /&gt;
&lt;br /&gt;
ggg.js:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* @Override */&lt;br /&gt;
	updatePlayerOrdering() {&lt;br /&gt;
		this.inherited(arguments);&lt;br /&gt;
		dojo.place(&#039;player_board_config&#039;, &#039;player_boards&#039;, &#039;first&#039;);&lt;br /&gt;
	},&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Images and Icons ===&lt;br /&gt;
&lt;br /&gt;
==== Accessing images from js ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
     // your game resources&lt;br /&gt;
     &lt;br /&gt;
     var my_img = &#039;&amp;lt;img src=&amp;quot;&#039;+g_gamethemeurl+&#039;img/cards.jpg&amp;quot;/&amp;gt;&#039;;&lt;br /&gt;
     &lt;br /&gt;
     // shared resources&lt;br /&gt;
     var my_help_img = &amp;quot;&amp;lt;img class=&#039;imgtext&#039; src=&#039;&amp;quot; + g_themeurl + &amp;quot;img/layout/help_click.png&#039; alt=&#039;action&#039; /&amp;gt; &amp;lt;span class=&#039;tooltiptext&#039;&amp;gt;&amp;quot; +&lt;br /&gt;
                    text + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== High-Definition Graphics ====&lt;br /&gt;
&lt;br /&gt;
Some users will have screens which can display text and images at a greater resolution than the usual 72 dpi, e.g. the &amp;quot;Retina&amp;quot; screens on the 5k iMac, all iPads, and high-DPI screens on laptops from many manufacturers. If you can get art assets at this size, they will make your game look extra beautiful. You &#039;&#039;could&#039;&#039; just use large graphics and scale them down, but that would increase the download time and bandwidth for users who can&#039;t display them. Instead, a good way is to prepare a separate graphics file at exactly twice the size you would use otherwise, and add &amp;quot;@2x&amp;quot; at the end of the filename, e.g. if pieces.png is 240x320, then pieces@2x.png is 480x640.&lt;br /&gt;
&lt;br /&gt;
There are two changes required in order to use the separate graphics files. First in your css, where you use a file, add a media query which overrides the original definition and uses the bigger version on devices which can display them. Ensuring that the &amp;quot;background-size&amp;quot; attribute is set means that the size of the displayed object doesn&#039;t change, but only is drawn at the improved dot pitch.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.piece {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    background-image: url(&#039;img/pieces.png&#039;);&lt;br /&gt;
    background-size:240px 320px;&lt;br /&gt;
    z-index: 10;&lt;br /&gt;
}&lt;br /&gt;
@media (-webkit-min-device-pixel-ratio: 2), (min-device-pixel-ratio: 2), (min-resolution: 192dpi)&lt;br /&gt;
{&lt;br /&gt;
    .piece {&lt;br /&gt;
        background-image: url(&#039;img/pieces@2x.png&#039;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Secondly, in your setup function in javascript, you must ensure than only the appropriate one version of the file gets pre-loaded (otherwise you more than waste the bandwidth saved by maintaining the standard-resolution file). Note that the media query is the same in both cases:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
            var isRetina = &amp;quot;(-webkit-min-device-pixel-ratio: 2), (min-device-pixel-ratio: 2), (min-resolution: 192dpi)&amp;quot;;&lt;br /&gt;
            if (window.matchMedia(isRetina).matches)&lt;br /&gt;
            {&lt;br /&gt;
                this.dontPreloadImage( &#039;pieces.png&#039; );&lt;br /&gt;
                this.dontPreloadImage( &#039;board.jpg&#039; );&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                this.dontPreloadImage( &#039;pieces@2x.png&#039; );&lt;br /&gt;
                this.dontPreloadImage( &#039;board@2x.jpg&#039; );&lt;br /&gt;
            }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using CSS to create different colors of game pieces if you have only white piece ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
background-color: #${color}; &lt;br /&gt;
background-blend-mode: multiply;&lt;br /&gt;
background-image: url( &#039;img/mypiece.png&#039;);&lt;br /&gt;
mask: url(&#039;img/mypiece.png&#039;);&lt;br /&gt;
-webkit-mask: url(&#039;img/mypiece.png&#039;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where ${color} - is color you want&lt;br /&gt;
&lt;br /&gt;
Note: piece has to be white (shades of gray). Sprite can be used too, just add add blackground-position as usuall.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Other Fluff ===&lt;br /&gt;
&lt;br /&gt;
==== Use thematic fonts ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.css&lt;br /&gt;
&lt;br /&gt;
Sometime game elements use specific fonts of text, if you want to match it up you can load some specific font (IMPORTANT: from some &#039;&#039;&#039;free font&#039;&#039;&#039; source. See notes below).&lt;br /&gt;
&lt;br /&gt;
[[File:Dragonline_font.png]]&lt;br /&gt;
&lt;br /&gt;
.css&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* latin-ext */&lt;br /&gt;
@font-face {&lt;br /&gt;
  font-family: &#039;Qwigley&#039;;&lt;br /&gt;
  font-style: normal;&lt;br /&gt;
  font-weight: 400;&lt;br /&gt;
  src: local(&#039;Qwigley&#039;), local(&#039;Qwigley-Regular&#039;), url(https://fonts.gstatic.com/s/qwigley/v6/2Dy1Unur1HJoklbsg4iPJ_Y6323mHUZFJMgTvxaG2iE.woff2) format(&#039;woff2&#039;);&lt;br /&gt;
  unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;&lt;br /&gt;
}&lt;br /&gt;
/* latin */&lt;br /&gt;
@font-face {&lt;br /&gt;
  font-family: &#039;Qwigley&#039;;&lt;br /&gt;
  font-style: normal;&lt;br /&gt;
  font-weight: normal;&lt;br /&gt;
  src: local(&#039;Qwigley&#039;), local(&#039;Qwigley-Regular&#039;), url(https://fonts.gstatic.com/s/qwigley/v6/gThgNuQB0o5ITpgpLi4Zpw.woff2) format(&#039;woff2&#039;);&lt;br /&gt;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;&lt;br /&gt;
}&lt;br /&gt;
@font-face {&lt;br /&gt;
  font-family: &#039;Qwigley&#039;;&lt;br /&gt;
  font-style: normal;&lt;br /&gt;
  font-weight: normal;&lt;br /&gt;
  src: local(&#039;Qwigley&#039;), local(&#039;Qwigley-Regular&#039;), url(http://ff.static.1001fonts.net/q/w/qwigley.regular.ttf) format(&#039;ttf&#039;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.zone_title {&lt;br /&gt;
	display: inline-block;&lt;br /&gt;
	position: absolute;&lt;br /&gt;
	font: italic 32px/32px &amp;quot;Qwigley&amp;quot;, cursive;	   &lt;br /&gt;
	height: 32px;&lt;br /&gt;
	width: auto;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NB:&#039;&#039;&#039; if you need to include a font that&#039;s not available online, an extra action will be needed from an admin. Please include the font file(s) in your img directory, and mention it to admins when requesting your game to be moved to alpha. &#039;&#039;&#039;Please remember that the font has to be free, and include a .txt with all appropriate license information about the font.&#039;&#039;&#039;&lt;br /&gt;
You can look for free fonts (for example) on https://fonts.google.com or https://www.fontsquirrel.com/)&lt;br /&gt;
&lt;br /&gt;
=== Use player color in template ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg_ggg.tpl, ggg.view.php&lt;br /&gt;
&lt;br /&gt;
.view.php:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    function build_page($viewArgs) {&lt;br /&gt;
        // Get players &amp;amp; players number&lt;br /&gt;
        $players = $this-&amp;gt;game-&amp;gt;loadPlayersBasicInfos();&lt;br /&gt;
        $players_nbr = count($players);&lt;br /&gt;
        /**&lt;br /&gt;
         * ********* Place your code below: ***********&lt;br /&gt;
         */&lt;br /&gt;
        &lt;br /&gt;
        // Set PCOLOR to the current player color hex&lt;br /&gt;
        global $g_user;&lt;br /&gt;
        $cplayer = $g_user-&amp;gt;get_id();&lt;br /&gt;
        if (array_key_exists($cplayer, $players)) { // may be not set if spectator&lt;br /&gt;
            $player_color = $players [$cplayer] [&#039;player_color&#039;];&lt;br /&gt;
        } else {&lt;br /&gt;
            $player_color = &#039;ffffff&#039;; // spectator&lt;br /&gt;
        }&lt;br /&gt;
        $this-&amp;gt;tpl [&#039;PCOLOR&#039;] = $player_color;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Scale to fit for big boards ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg_ggg.tpl, ggg.js&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Lets say you have huge game board, and lets say you want it to be 1400px wide. Besides the board there will be side bar which is 240 and trim. &lt;br /&gt;
My display is 1920 wide so it fits, but there is big chance other people won&#039;t have that width. What do you do?&lt;br /&gt;
&lt;br /&gt;
You have to decide:&lt;br /&gt;
* If board does not fit you want scale whole thing down, the best way is probably use viewport (see https://en.doc.boardgamearena.com/Your_game_mobile_version)&lt;br /&gt;
* You can leave the board as is and make sure it is scrollable horizonatally&lt;br /&gt;
* You add custom scale just for the board (can add user controls  - and hook to transform: scale())&lt;br /&gt;
&lt;br /&gt;
I tried to auto-scale but this just does work, too many variables - browser zoom, 3d mode, viewport, custom bga scaling, devicePixelRatio - all create some impossible coctail of zooming...&lt;br /&gt;
Here is scaling functing for custom user scaling&lt;br /&gt;
&lt;br /&gt;
ggg_ggg.tpl:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   &amp;lt;div id=&amp;quot;thething&amp;quot; class=&amp;quot;thething&amp;quot;&amp;gt;&lt;br /&gt;
            ... everything else you declare ...&lt;br /&gt;
   &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ggg.js:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    onZoomPlus: function() {&lt;br /&gt;
       this.my_zoom+=0.1;&lt;br /&gt;
       this.zoommy(&#039;thething&#039;,this.my_zoom);&lt;br /&gt;
    },&lt;br /&gt;
&lt;br /&gt;
    zoommy: function(node, zoom) {&lt;br /&gt;
                node=$(node);&lt;br /&gt;
		var width = 100 / zoom;&lt;br /&gt;
		node.style.transformOrigin = &amp;quot;0 0&amp;quot;;&lt;br /&gt;
		node.style.transform = &amp;quot;scale(&amp;quot; + zoom + &amp;quot;)&amp;quot;;&lt;br /&gt;
		node.style.width = width + &amp;quot;%&amp;quot;;&lt;br /&gt;
    },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Dynamic tooltips ===&lt;br /&gt;
&lt;br /&gt;
If you really need a dynamic tooltip you can use this technique. (Only use it if the static tooltips provided by the BGA framework are not sufficient.)&lt;br /&gt;
&lt;br /&gt;
            new dijit.Tooltip({&lt;br /&gt;
                connectId: [&amp;quot;divItemId&amp;quot;],&lt;br /&gt;
                getContent: function(matchedNode){&lt;br /&gt;
                    return &amp;quot;... calculated ...&amp;quot;; &lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is an out-of-the-box djit.Tooltip. It has a &#039;&#039;getContent&#039;&#039; method which is called dynamically.&lt;br /&gt;
&lt;br /&gt;
The string function return becomes the innerHTML of the tooltip, so it can be anything. In this example matchedNode is a dojo node representing dom object with id of &amp;quot;divItemId&amp;quot; but there are more parameters which I am not posting here which allows more sophisticated subnode queries (i.e. you can attach tooltip to all nodes with class or whatever).&lt;br /&gt;
&lt;br /&gt;
[https://dojotoolkit.org/reference-guide/1.10/dijit/Tooltip.html dijit.Tooltip]&lt;br /&gt;
&lt;br /&gt;
It&#039;s not part of the BGA API so use at your own risk.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Rendering text with players color and proper background ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        /* Implementation of proper colored You with background in case of white or light colors  */&lt;br /&gt;
 &lt;br /&gt;
        divYou: function() {&lt;br /&gt;
            var color = this.gamedatas.players[this.player_id].color;&lt;br /&gt;
            var color_bg = &amp;quot;&amp;quot;;&lt;br /&gt;
            if (this.gamedatas.players[this.player_id] &amp;amp;&amp;amp; this.gamedatas.players[this.player_id].color_back) {&lt;br /&gt;
                color_bg = &amp;quot;background-color:#&amp;quot; + this.gamedatas.players[this.player_id].color_back + &amp;quot;;&amp;quot;;&lt;br /&gt;
            }&lt;br /&gt;
            var you = &amp;quot;&amp;lt;span style=\&amp;quot;font-weight:bold;color:#&amp;quot; + color + &amp;quot;;&amp;quot; + color_bg + &amp;quot;\&amp;quot;&amp;gt;&amp;quot; + __(&amp;quot;lang_mainsite&amp;quot;, &amp;quot;You&amp;quot;) + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
            return you;&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
        /* Implementation of proper colored player name with background in case of white or light colors  */&lt;br /&gt;
&lt;br /&gt;
        divColoredPlayer: function(player_id) {&lt;br /&gt;
            var color = this.gamedatas.players[player_id].color;&lt;br /&gt;
            var color_bg = &amp;quot;&amp;quot;;&lt;br /&gt;
            if (this.gamedatas.players[player_id] &amp;amp;&amp;amp; this.gamedatas.players[player_id].color_back) {&lt;br /&gt;
                color_bg = &amp;quot;background-color:#&amp;quot; + this.gamedatas.players[player_id].color_back + &amp;quot;;&amp;quot;;&lt;br /&gt;
            }&lt;br /&gt;
            var div = &amp;quot;&amp;lt;span style=\&amp;quot;color:#&amp;quot; + color + &amp;quot;;&amp;quot; + color_bg + &amp;quot;\&amp;quot;&amp;gt;&amp;quot; + this.gamedatas.players[player_id].name + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
            return div;&lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Cool realistic shadow effect with CSS ===&lt;br /&gt;
&lt;br /&gt;
==== Rectangles and circles ====&lt;br /&gt;
&lt;br /&gt;
It is often nice to have a drop shadow around tiles and tokens, to separate them from the table visually. It is very easy to add a shadow to rectangular elements, just add this to your css:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.xxx-tile {&lt;br /&gt;
    box-shadow: 3px 3px 3px #000000a0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
box-shadow obeys &#039;&#039;&#039;border-radius&#039;&#039;&#039; of the element, so it will look good for rounded rectangles, and hence also circles (if border-radius is set appropriately).&lt;br /&gt;
&lt;br /&gt;
box-shadow also supports various other parameters and can be used to achieve effects such as glowing, borders, inner shadows etc. If you need to animate a box-shadow, you may be able to get better performance (avoiding redraws) if you attach the shadow to another element (possibly an ::after pseudo-element) and change only the &#039;&#039;&#039;opacity&#039;&#039;&#039; of that element.&lt;br /&gt;
&lt;br /&gt;
==== Irregular Shapes ====&lt;br /&gt;
&lt;br /&gt;
If you wish to make a shadow effect for game pieces that are not a rectangle, but your game pieces are drawn from rectangles in a PNG image, you can apply the shadow to the piece using any art package and save it inside the image. This usually will yield the best performance. Remember to account for the size of the shadow when you lay out images in the sprite sheet.&lt;br /&gt;
&lt;br /&gt;
However that sometimes will not be an option, for example if the image needs to be rotated while the shadow remains offset in the same direction. In this case, one option is to not use box-shadow but use filter, which is supported by recent major browsers.  This way, you can use the alpha channel of your element to drop a shadow.  This even work for transparent backgrounds, so that if you are using the &amp;quot;CSS-sprite&amp;quot; method, it will work!&lt;br /&gt;
&lt;br /&gt;
For instance:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.xxx-token {&lt;br /&gt;
    filter: drop-shadow(0px 0px 1px #000000);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beware that some browsers still do not always draw drop-shadow correctly. In particular, Safari frequently leaves bits of shadow behind when objects move around the screen. In Chrome, shadows sometimes flicker badly if another element is animating close by. Some of these correctness issues can be solved by adding &#039;&#039;&#039;isolation: isolate; will-change: filter;&#039;&#039;&#039; to affected elements, but this significantly affects redraw performance.&lt;br /&gt;
&lt;br /&gt;
Beware of performance issues - particularly on Safari (MacOS, iPhone and iPad). Keep in mind that drop-shadow are very GPU intensive. This becomes noticeable once you have about 40 components with drop-shadow filter. If that is your case, you can quite easily implement a user preference to disable shadows for users on slower machines:&lt;br /&gt;
&lt;br /&gt;
gameoptions.inc.php&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
100 =&amp;gt; array(&lt;br /&gt;
			&#039;name&#039; =&amp;gt; totranslate(&#039;Shadows&#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;Enabled&#039; ), &#039;cssPref&#039; =&amp;gt; &#039;&#039; ),&lt;br /&gt;
					2 =&amp;gt; array( &#039;name&#039; =&amp;gt; totranslate( &#039;Disabled&#039; ), &#039;cssPref&#039; =&amp;gt; &#039;no-shadow&#039; )&lt;br /&gt;
			)&lt;br /&gt;
	),&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[game].css&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.no-shadow * {&lt;br /&gt;
	filter: none !important; &lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Shadows with clip-path ====&lt;br /&gt;
&lt;br /&gt;
For some reason, a shadow will not work together with clip-path on one element. To use both clip-path (when for example using .svg to cut out cardboard components from your .jpg spritesheet) and drop-shadow, you need to wrap the element into another one, and apply drop-shadow to the outer one, and clip-path to the inner one.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;div class=&#039;my-token-wrap&#039;&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&#039;my-token&#039;&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;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.my-token-wrap {&lt;br /&gt;
    filter: drop-shadow(0px 0px 1px #000000);&lt;br /&gt;
}&lt;br /&gt;
.my-token-wrap .my-token {&lt;br /&gt;
    clip-path: url(#my-token-path);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Using the CSS classes from the state machine ===&lt;br /&gt;
&lt;br /&gt;
If you need to hide or show stuff depending on the state of your game, you can of course use javascript, but CSS is hand enough for that.  The #overall-content element does change class depending on the game state.  For instance, if you are in state &#039;&#039;playerTurn&#039;&#039;, it will have the class &#039;&#039;gamestate_playerTurn&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
So now, if you want to show the discard pile only during player turns, you may use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#discard_pile { display: none }&lt;br /&gt;
.gamestate_playerTurn #discard_pile { display: block }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This can be used if you want to change sizing of elements, position, layout or visual appearance.&lt;br /&gt;
&lt;br /&gt;
== Game Model and Database design ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Database for The euro game ===&lt;br /&gt;
Lets say we have a game with workers, dice, tokens, board, resources, money and vp. Workers and dice can be placed in various zones on the board, and you can get resources, money, tokens and vp in your home zone. Also tokens can be flipped or not flipped.&lt;br /&gt;
&lt;br /&gt;
[[File:Madeira board.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now lets try to map it, we have&lt;br /&gt;
* (meeple,zone)&lt;br /&gt;
* (die, zone, sideup)&lt;br /&gt;
* (resource cube/money token/vp token,player home zone)&lt;br /&gt;
* (token, player home zone, flip state)&lt;br /&gt;
We can notice that resource and money are uncountable, and don&#039;t need to be track individually so we can replace our mapping to&lt;br /&gt;
* (resource type/money,player home zone, count)&lt;br /&gt;
And vp stored already for us in player table, so we can remove it from that list.&lt;br /&gt;
&lt;br /&gt;
Now when we get to encode it we can see that everything can be encoded as (object,zone,state) form, where object and zone is string and state is integer. The resource mapping is slightly different semantically so you can go with two table, or counting using same table with state been used as count for resources.&lt;br /&gt;
&lt;br /&gt;
So the piece mapping for non-grid based games can be in most case represented by (string: token_key, string: token_location, int: token_state), example of such database schema can be found here: [https://github.com/elaskavaia/bga-sharedcode/blob/master/dbmodel.sql dbmodel.sql] and class implementing access to it here [https://github.com/elaskavaia/bga-sharedcode/blob/master/modules/tokens.php table.game.php].&lt;br /&gt;
&lt;br /&gt;
Variant 1: Minimalistic&lt;br /&gt;
&lt;br /&gt;
 CREATE TABLE IF NOT EXISTS `token` (&lt;br /&gt;
  `token_key` varchar(32) NOT NULL,&lt;br /&gt;
  `token_location` varchar(32) NOT NULL,&lt;br /&gt;
  `token_state` int(10),&lt;br /&gt;
  PRIMARY KEY (`token_key`)&lt;br /&gt;
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+token&lt;br /&gt;
! token_key&lt;br /&gt;
! token_location&lt;br /&gt;
! token_state&lt;br /&gt;
|-&lt;br /&gt;
|meeple_red_1&lt;br /&gt;
|home_red&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
|dice_black_2&lt;br /&gt;
|board_guard&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
|dice_green_1&lt;br /&gt;
|board_action_mayor&lt;br /&gt;
|3&lt;br /&gt;
|-&lt;br /&gt;
|bread&lt;br /&gt;
|home_red&lt;br /&gt;
|5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Now how we represent resource counters such as bread?&lt;br /&gt;
Using same table from we simply add special counter token for bread and use state to indicate the count. Note to keep first column unique we have to add player identification for that counter, i.e. ff0000 is red player.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+token&lt;br /&gt;
! token_key&lt;br /&gt;
! token_location&lt;br /&gt;
! token_state&lt;br /&gt;
|-&lt;br /&gt;
|bread_ff0000&lt;br /&gt;
|tableau_ff0000&lt;br /&gt;
|5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See php module for this table here https://github.com/elaskavaia/bga-sharedcode/blob/master/modules/tokens.php&lt;br /&gt;
&lt;br /&gt;
Variant 2: Additional resource table, resource count for each player id&lt;br /&gt;
&lt;br /&gt;
 CREATE TABLE IF NOT EXISTS `resource` (&lt;br /&gt;
  `player_id` int(10) unsigned NOT NULL,&lt;br /&gt;
  `resource_key` varchar(32) NOT NULL,&lt;br /&gt;
  `resource_count` int(10) signed NOT NULL,&lt;br /&gt;
  PRIMARY KEY (`player_id`,`resource_key`)&lt;br /&gt;
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;&lt;br /&gt;
&lt;br /&gt;
 ALTER TABLE resource ADD CONSTRAINT fk_player_id FOREIGN KEY (player_id) REFERENCES player(player_id);&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+resource&lt;br /&gt;
! player_id&lt;br /&gt;
! resource_key&lt;br /&gt;
! resource_count&lt;br /&gt;
|-&lt;br /&gt;
|123456&lt;br /&gt;
|bread&lt;br /&gt;
|5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Variant 3: More normalised&lt;br /&gt;
&lt;br /&gt;
This version is similar to &amp;quot;card&amp;quot; table from hearts tutorial, you can also use exact cards database schema and Deck implementation for most purposes (even you not dealing with cards). &lt;br /&gt;
&lt;br /&gt;
 CREATE TABLE IF NOT EXISTS `token` (&lt;br /&gt;
  `token_id` int(10) unsigned NOT NULL AUTO_INCREMENT,&lt;br /&gt;
  `token_type` varchar(16) NOT NULL,&lt;br /&gt;
  `token_arg` int(11) NOT NULL,&lt;br /&gt;
  `token_location` varchar(32) NOT NULL,&lt;br /&gt;
  `token_state` int(10),&lt;br /&gt;
  PRIMARY KEY (`token_id`)&lt;br /&gt;
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+token&lt;br /&gt;
! token_id&lt;br /&gt;
! token_type&lt;br /&gt;
! token_arg&lt;br /&gt;
! token_location&lt;br /&gt;
! token_state&lt;br /&gt;
|-&lt;br /&gt;
|22&lt;br /&gt;
|meeple&lt;br /&gt;
|123456&lt;br /&gt;
|home_123456&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
|23&lt;br /&gt;
|dice&lt;br /&gt;
|2&lt;br /&gt;
|board_guard&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
|26&lt;br /&gt;
|dice&lt;br /&gt;
|1&lt;br /&gt;
|board_action_mayor&lt;br /&gt;
|3&lt;br /&gt;
|-&lt;br /&gt;
|49&lt;br /&gt;
|bread&lt;br /&gt;
|0&lt;br /&gt;
|home_123456&lt;br /&gt;
|5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Advantages of this would be is a bit more straightforward to do some queries in db, disadvantage its hard to read (as you can compare with previous example, you&lt;br /&gt;
cannot just look at say, ah I know what it means). Another questionable advantage is it allows you to do id randomisation, so it hard to do crafted queries to &lt;br /&gt;
cheat, the down side of that you cannot understand it either, and handcraft db states for debugging or testing.&lt;br /&gt;
&lt;br /&gt;
=== Database for The card game ===&lt;br /&gt;
&lt;br /&gt;
Lets say you have a standard card game, player have hidden cards in hand, you can draw card from draw deck, play card on tableau and discard to discard pile.&lt;br /&gt;
We have to design database for such game.&lt;br /&gt;
&lt;br /&gt;
In real word to &amp;quot;save&amp;quot; the game we take a picture a play area, save cards from it, then put away draw deck, discard and hand of each player separately and mark it, also we will record current scoring (if any) and who&#039;s turn was it.&lt;br /&gt;
&lt;br /&gt;
* Framework handles state machine transition, so you don&#039;t have to worry about database design for that (i.e. who&#039;s turn it is, what phase of the game we are at, you still have to design it but part of state machine step)&lt;br /&gt;
* Also framework supports basic player information, color, order around the table, basic scoring, etc, so you don&#039;t have to worry about it either&lt;br /&gt;
* The only thing you need in our database is state of the &amp;quot;board&amp;quot;, which is &amp;quot;where each pieces is, and in what state&amp;quot;, or (position,rotation) pair.&lt;br /&gt;
&lt;br /&gt;
Lets see what we have for that:&lt;br /&gt;
* The card state is very simple, its usually &amp;quot;face up/face down&amp;quot;, &amp;quot;tapped/untapped&amp;quot;, &amp;quot;right side up/up side down&amp;quot;&lt;br /&gt;
* As position go we never need real coordinates x,y,z. We need to know what &amp;quot;zone&amp;quot; card was, and depending on the zone it may sometimes need an extra &amp;quot;z&amp;quot; or &amp;quot;x&amp;quot; as card order. The zone position usually static or irrelevant.&lt;br /&gt;
* So our model is: we have cards, which have some attributes, at any given point in time they belong to a &amp;quot;zone&amp;quot;, and can also have order and state&lt;br /&gt;
* Now for mapping we should consider what information changes and what information is static, later is always candidate for material file&lt;br /&gt;
* For dynamic information we should try to reduce amount of fields we need&lt;br /&gt;
**  we need at least a field for card, so its one&lt;br /&gt;
**  we need to know what zone cards belong to, its 2&lt;br /&gt;
**  and we have possibly few other fields, if you look closely at you game you may find out that most of the zone only need one attribute at a time, i.e. draw pile always have cards face down, hand always face up, also for hand and discard order does not matter at all (but for draw it does matter). So in majority of cases we can get away with one single extra integer field representing state or order&lt;br /&gt;
* In real database both card and zone will be integers as primary keys referring to additional tables, but in our case its total overkill, so they can be strings as easily&lt;br /&gt;
&lt;br /&gt;
Variant 1: Minimalistic&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE TABLE IF NOT EXISTS `card` (&lt;br /&gt;
  `card_key` varchar(32) unsigned NOT NULL,&lt;br /&gt;
  `card_location` varchar(32) NOT NULL,&lt;br /&gt;
  `card_state` int(11) NOT NULL,&lt;br /&gt;
  PRIMARY KEY (`card_id`)&lt;br /&gt;
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Variant 2: More normalised&lt;br /&gt;
&lt;br /&gt;
This version supported by Deck php class, so unless you want to rewrite db access layer go with this one&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE TABLE IF NOT EXISTS `card` (&lt;br /&gt;
  `card_id` int(10) unsigned NOT NULL AUTO_INCREMENT,&lt;br /&gt;
  `card_type` varchar(16) NOT NULL,&lt;br /&gt;
  `card_type_arg` int(11) NOT NULL,&lt;br /&gt;
  `card_location` varchar(16) NOT NULL,&lt;br /&gt;
  `card_location_arg` int(11) NOT NULL,&lt;br /&gt;
  PRIMARY KEY (`card_id`)&lt;br /&gt;
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: if you using this schema, some zones/locations have special semantic. The &#039;hand&#039; location is actually multiple locations - one per player, but player id is encoded as card_location_arg. If &#039;hand&#039; in your game is ordered, visible or can have some other card states, you cannot use hand location (replacement is hand_&amp;lt;player_id&amp;gt; or hand_&amp;lt;color_id&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
== Code Organization ==&lt;br /&gt;
&lt;br /&gt;
=== Including your own JavaScript module ===&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, modules/ggg_other.js&lt;br /&gt;
&lt;br /&gt;
* Create ggg_other.js in modules/ folder and sync&lt;br /&gt;
* Modify ggg.js to include it&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  define([ &amp;quot;dojo&amp;quot;, &amp;quot;dojo/_base/declare&amp;quot;, &amp;quot;ebg/core/gamegui&amp;quot;, &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
    // load my own module!!!&lt;br /&gt;
    g_gamethemeurl + &amp;quot;modules/ggg_other.js&amp;quot; ], function(dojo,&lt;br /&gt;
        declare) {&lt;br /&gt;
&lt;br /&gt;
=== Including your own JavaScript module (II) ===&lt;br /&gt;
&lt;br /&gt;
* Create ggg_other.js in modules/ folder and sync&lt;br /&gt;
&lt;br /&gt;
  define([], function () {&lt;br /&gt;
    return &amp;quot;value&amp;quot;;&lt;br /&gt;
  });&lt;br /&gt;
&lt;br /&gt;
* Modify ggg.js to include it&lt;br /&gt;
&lt;br /&gt;
  define([ &lt;br /&gt;
    &amp;quot;dojo&amp;quot;, &lt;br /&gt;
    &amp;quot;dojo/_base/declare&amp;quot;, &lt;br /&gt;
    &amp;quot;bgagame/modules/ggg_other&amp;quot;, &lt;br /&gt;
    &amp;quot;ebg/core/gamegui&amp;quot;, &lt;br /&gt;
    &amp;quot;ebg/counter&amp;quot;&lt;br /&gt;
  ], function(dojo, declare, other) {&lt;br /&gt;
  &lt;br /&gt;
  });&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
This is maybe a little bit more the idea of the AMD Loader than the first option, although the first option should work as well.&lt;br /&gt;
&lt;br /&gt;
A little explanation to this:&lt;br /&gt;
The define function loads all the modules listed in the array and calls the following function with these loaded modules as parameters.&lt;br /&gt;
By putting your module at the third position in the array it is passed as the third parameter to the function. Be aware that the modules are resolved by position only, not by name. So you can load the module &#039;&#039;&#039;ggg_other&#039;&#039;&#039; and pass it as a parameter with the name &#039;&#039;&#039;other&#039;&#039;&#039;. &#039;&#039;&#039;gamegui&#039;&#039;&#039; and &#039;&#039;&#039;counter&#039;&#039;&#039; are passed in as well, but when the parameters are not defined they are just skipped. Because these modules put their content into the global scope it does not matter and you can use them from there.&lt;br /&gt;
&lt;br /&gt;
In the example above the string &amp;quot;value&amp;quot; is passed for the parameter &#039;&#039;&#039;other&#039;&#039;&#039;, but the function in your module can return whatever you want. It can be an object, an array, something you declared with dojo.declare, you can return even functions. &lt;br /&gt;
Your module can load other modules. Just put them in the array at the beginning and pass them as parameters to your function.&lt;br /&gt;
The advantage of passing the values as parameter is that you do not need to put these values in the global scope, so they can&#039;t be collisions with values defined in other scripts or the BGA Framework.&lt;br /&gt;
&lt;br /&gt;
The dojo toolkit provides good documentation to all of its components, the complete documentation for the AMD-Loader is here:&lt;br /&gt;
https://dojotoolkit.org/documentation/tutorials/1.10/modules/index.html It should be still correct, even as it seems to be only for version 1.10&lt;br /&gt;
&lt;br /&gt;
=== Including your own PHP module ===&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.game.php, modules/ggg_other.php&lt;br /&gt;
&lt;br /&gt;
* Create ggg_other.php in modules/ folder and sync&lt;br /&gt;
* Modify ggg.game.php to include it&lt;br /&gt;
&lt;br /&gt;
 require_once (&#039;modules/ggg_other.php&#039;);&lt;br /&gt;
&lt;br /&gt;
=== Creating a test class to run PHP locally ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.game.php, stubs&lt;br /&gt;
For this you need stubs of other method you can use this for example&lt;br /&gt;
https://github.com/elaskavaia/bga-sharedcode/raw/master/misc/module/table/table.game.php&lt;br /&gt;
&lt;br /&gt;
Create another php files, i.e ggg_test.php&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
define(&amp;quot;APP_GAMEMODULE_PATH&amp;quot;, &amp;quot;misc/&amp;quot;); // include path to stubs, which defines &amp;quot;table.game.php&amp;quot; and other classes&lt;br /&gt;
require_once (&#039;eminentdomaine.game.php&#039;);&lt;br /&gt;
&lt;br /&gt;
class MyGameTest1 extends MyGame { // this is your game class defined in ggg.game.php&lt;br /&gt;
    function __construct() {&lt;br /&gt;
        parent::__construct();&lt;br /&gt;
        include &#039;../material.inc.php&#039;;// this is how this normally included, from constructor&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // override/stub methods here that access db and stuff&lt;br /&gt;
    function getGameStateValue($var) {&lt;br /&gt;
        if ($var == &#039;round&#039;)&lt;br /&gt;
            return 3;&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
$x = new MyGameTest1(); // instantiate your class&lt;br /&gt;
$p = $x-&amp;gt;getGameProgression(); // call one of the methods to test&lt;br /&gt;
if ($p != 50)&lt;br /&gt;
    echo &amp;quot;Test1: FAILED&amp;quot;;&lt;br /&gt;
else&lt;br /&gt;
    echo &amp;quot;Test1: PASSED&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Run from command line like&lt;br /&gt;
 php7 ggg_test.php&lt;br /&gt;
&lt;br /&gt;
If you do it this way - you can also use local php debugger (i.e. integrated with IDE or command line).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Avoiding code in dojo declare style ===&lt;br /&gt;
Dojo class declarations are rather bizzare and do not work with most IDEs.&lt;br /&gt;
If you want to write in plain JS with classes, you can stub all the dojo define/declare stuff&lt;br /&gt;
and hook your class into that, so the classes are outside of this mess.&lt;br /&gt;
&lt;br /&gt;
NOTE: this technique is for experienced developers, do not try it if you do not understand&lt;br /&gt;
the consequences.&lt;br /&gt;
&lt;br /&gt;
This is complete example of game .js class&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  // Testla is game name is has to be changed&lt;br /&gt;
class Testla {&lt;br /&gt;
	constructor(game) {&lt;br /&gt;
		console.log(&#039;game constructor&#039;);&lt;br /&gt;
		this.game = game;&lt;br /&gt;
		this.varfoo = new MyFoo(); // this example of class from custom module&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	setup(gamedatas) {&lt;br /&gt;
		console.log(&amp;quot;Starting game setup&amp;quot;, this.varfoo);&lt;br /&gt;
		this.gamedatas = gamedatas;&lt;br /&gt;
		this.dojo.create(&amp;quot;div&amp;quot;, { class: &#039;whiteblock&#039;, innerHTML: _(&amp;quot;hello&amp;quot;) }, &#039;thething&#039;);&lt;br /&gt;
		console.log(&amp;quot;Ending game setup&amp;quot;);&lt;br /&gt;
	};&lt;br /&gt;
	onEnteringState(stateName, args) {&lt;br /&gt;
		console.log(&#039;onEnteringState : &#039; + stateName, args);&lt;br /&gt;
		this.game.addActionButton(&#039;b1&#039;,_(&#039;Click Me&#039;), (e)=&amp;gt;this.onButtonClick(e));&lt;br /&gt;
	};&lt;br /&gt;
	onLeavingState(stateName) {&lt;br /&gt;
		console.log(&#039;onLeavingState : &#039; + stateName, args);&lt;br /&gt;
	};&lt;br /&gt;
	onUpdateActionButtons(stateName, args) {&lt;br /&gt;
		console.log(&#039;onUpdateActionButtons : &#039; + stateName, args);&lt;br /&gt;
	};&lt;br /&gt;
	onButtonClick(event) {&lt;br /&gt;
		console.log(&#039;onButtonClick&#039;,event);&lt;br /&gt;
	};&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&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;
	g_gamethemeurl + &#039;/modules/foo.js&#039; // custom module if needed&lt;br /&gt;
],&lt;br /&gt;
	function(dojo, declare) {&lt;br /&gt;
                // testla is game name is has to be changed&lt;br /&gt;
		return declare(&amp;quot;bgagame.testla&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
			constructor: function() {&lt;br /&gt;
				this.xapp = new Testla(this);&lt;br /&gt;
				this.xapp.dojo = dojo;&lt;br /&gt;
			},&lt;br /&gt;
			setup: function(gamedatas) {&lt;br /&gt;
				this.xapp.setup(gamedatas);&lt;br /&gt;
			},&lt;br /&gt;
			onEnteringState: function(stateName, args) {&lt;br /&gt;
				this.xapp.onEnteringState(stateName, args?.args);&lt;br /&gt;
			},&lt;br /&gt;
			onLeavingState: function(stateName) {&lt;br /&gt;
				this.xapp.onLeavingState(stateName, args);&lt;br /&gt;
			},&lt;br /&gt;
			onUpdateActionButtons: function(stateName, args) {&lt;br /&gt;
				this.xapp.onUpdateActionButtons(stateName, args);&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;
=== More readable JS: onEnteringState ===&lt;br /&gt;
&lt;br /&gt;
If you have a lot of states onEnteringState and friends become rather wild, you can do this trick to call some method dynamically.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
     onEnteringState: function(stateName, args) {&lt;br /&gt;
       console.log(&#039;Entering state: &#039; + stateName, args);&lt;br /&gt;
&lt;br /&gt;
       // Call appropriate method&lt;br /&gt;
       var methodName = &amp;quot;onEnteringState_&amp;quot; + stateName;&lt;br /&gt;
       if (this[methodName] !== undefined) {             &lt;br /&gt;
          console.log(&#039;Calling &#039; + methodName, args.args);&lt;br /&gt;
          this[methodName](args.args);&lt;br /&gt;
       }&lt;br /&gt;
     },&lt;br /&gt;
&lt;br /&gt;
     onEnteringState_playerTurn: function(args) { // this is args directly, not args.args &lt;br /&gt;
         // process&lt;br /&gt;
     },&lt;br /&gt;
&lt;br /&gt;
     onEnteringState_playerSomethingElse: function(args) { &lt;br /&gt;
         // process&lt;br /&gt;
     },&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: since its ignores the undefined functions you don&#039;t have define function for each state, but on the other hand you cannot make typos.&lt;br /&gt;
Same applies to onUpdateActionButtons except you pass &#039;args&#039; to method, not args.args, and for onLeavingState where you don&#039;t pass anything.&lt;br /&gt;
&lt;br /&gt;
=== Frameworks and Preprocessors ===&lt;br /&gt;
&lt;br /&gt;
* [[Using Vue]] - work-in-progress guide on using the modern framework Vue.js to create a game&lt;br /&gt;
* [[Using Typescript and Scss]] - How to auto-build Typescript and SCSS files to make your code cleaner&lt;br /&gt;
&lt;br /&gt;
== Assorted Stuff ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Out-of-turn actions: Un-pass ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, ggg.game.php, ggg.action.php, states.inc.php&lt;br /&gt;
&lt;br /&gt;
In multiplayer game sometimes players passes but than they think more and want to un-Pass and redo their choice. &lt;br /&gt;
To re-active a player who passes some trickery required.&lt;br /&gt;
&lt;br /&gt;
Define a special action that does that and hook it up.&lt;br /&gt;
&lt;br /&gt;
In states.inc.php add an action to mmultipleactiveplayer state to &amp;quot;unpass&amp;quot;, lets call it &amp;quot;actionCancel&amp;quot;&lt;br /&gt;
&lt;br /&gt;
In ggg.action.php add action hook&lt;br /&gt;
    public function actionCancel() {&lt;br /&gt;
        self::setAjaxMode();&lt;br /&gt;
        $this-&amp;gt;game-&amp;gt;actionCancel();&lt;br /&gt;
        self::ajaxResponse();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
In ggg.game.php add action handler&lt;br /&gt;
    function actionCancel() {&lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;checkPossibleAction(&#039;actionCancel&#039;);&lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;setPlayersMultiactive(array ($this-&amp;gt;getCurrentPlayerId() ), &#039;error&#039;, false);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
Finally to call this in client ggg.js you would do something like:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 onUpdateActionButtons:  function(stateName, args) {&lt;br /&gt;
   if (this.isCurrentPlayerActive()) { &lt;br /&gt;
     // ...&lt;br /&gt;
   } else if (!this.isSpectator) { // player is NOT active but not spectator&lt;br /&gt;
       switch (stateName) {&lt;br /&gt;
          case &#039;playerTurnMuliPlayerState&#039;:&lt;br /&gt;
		this.addActionButton(&#039;button_unpass&#039;, _(&#039;Oh no!&#039;), &#039;onUnpass&#039;);&lt;br /&gt;
		break;&lt;br /&gt;
	}&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
				&lt;br /&gt;
 onUnpass: function(e) {&lt;br /&gt;
    this.ajaxcall(&amp;quot;/&amp;quot; + this.game_name + &amp;quot;/&amp;quot; +  this.game_name + &amp;quot;/actionCancel.html&amp;quot;, {}, this); // no checkAction!&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Although be careful that if the turn comes back to the player while he is about to click cancel, the action buttons will be updated and the player will misclick which can be quite frustrating. To avoid this, move the cancel button to another position, like to the left of pagemaintitletext:&lt;br /&gt;
  dojo.place(&#039;button_unpass&#039;, &#039;pagemaintitletext&#039;, &#039;before&#039;);&lt;br /&gt;
Being out of the generalactions div, it won&#039;t be automatically destroyed like normal buttons, so you&#039;ll have to handle that yourself in onLeavingState. You might also want to change the button color to red (blue buttons for active player only, red buttons also for inactive players?)&lt;br /&gt;
&lt;br /&gt;
Note: same technique can be used to do other out-of-turn actions, such as re-arranging cards in hand, exchanging resources, etc (i.e. if permitted by rules, such as &amp;quot;at any time player can...&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
=== Multi Step Interactions: Select Worker/Place Worker - Using Selection ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
Simple way to implement something like that without extra states is to use &amp;quot;selection&amp;quot; mechanism. When user click on worker add some sort of class into that element i.e. &#039;selected&#039; (which also have to have some indication by css i.e. outline).&lt;br /&gt;
&lt;br /&gt;
Than user can click on placement zone, you can use dojo.query for &amp;quot;selected&amp;quot; element and use it along with zone id to send data to server. If proper worker is not selected yet can give a error message using this.showMessage(...) function.&lt;br /&gt;
&lt;br /&gt;
Extra code required to properly cleanup selection between states.&lt;br /&gt;
Also when you do that sometimes you want to change the state prompt, see below &#039;Change state prompt&#039;&lt;br /&gt;
&lt;br /&gt;
=== Multi Step Interactions: Select Worker/Place Worker - Using Client States ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
I don&#039;t think its documented feature but there is a way to do client-only states, which is absolutely wonderful for few reasons&lt;br /&gt;
* When player interaction is two step process, such as select worker, place worker, or place worker, pick one of two resources of your choice&lt;br /&gt;
* When multi-step process can result of impossible situation and has to be undone (by rules)&lt;br /&gt;
* When multi-step process is triggered from multiple states (such as you can do same thing as activated card action, pass action or main action)&lt;br /&gt;
&lt;br /&gt;
So lets do Select Worker/Place Worker&lt;br /&gt;
&lt;br /&gt;
Define your server state as usual, i.e. playerMainTurn -&amp;gt; &amp;quot;You must pick up a worker&amp;quot;.&lt;br /&gt;
Now define a client state, we only need &amp;quot;name&amp;quot; and &amp;quot;descriptionmyturn&amp;quot;, lets say &amp;quot;client_playerPicksLocation&amp;quot;. Always prefix names of client state with &amp;quot;client_&amp;quot; to avoid confusion. Now we have to do the following:&lt;br /&gt;
* Have a handler for onUpdateActionButtons for playerMainTurn to activate all possible workers he can pick&lt;br /&gt;
* When player clicks workers, remember the worker in one of the members of the main class, I usually use one called this.clientStateArgs.&lt;br /&gt;
* Transition to new client state&lt;br /&gt;
  onWorker: function(e) {&lt;br /&gt;
      var id = event.currentTarget.id;&lt;br /&gt;
      dojo.stopEvent(event);&lt;br /&gt;
      ... // do validity checks&lt;br /&gt;
      this.clientStateArgs.worker_id = id;&lt;br /&gt;
      this.setClientState(&amp;quot;client_playerPicksLocation&amp;quot;, {&lt;br /&gt;
                                descriptionmyturn : _(&amp;quot;${you} must select location&amp;quot;),&lt;br /&gt;
                            });&lt;br /&gt;
   }&lt;br /&gt;
* Have a handler for onUpdateActionButtons for client_playerPicksLocation to activate all possible locations this worker can go AND add Cancel button (see below)&lt;br /&gt;
* Have a location handler which will eventually send a server request, using stored this.clientStateArgs.worker_id as worker id&lt;br /&gt;
* The cancel button should call a method to restore server state, also if you doing it for more than one state you can add this universally using this.on_client_state check&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        if (this.isCurrentPlayerActive()) {&lt;br /&gt;
          if (this.on_client_state &amp;amp;&amp;amp; !$(&#039;button_cancel&#039;)) {&lt;br /&gt;
               this.addActionButton(&#039;button_cancel&#039;, _(&#039;Cancel&#039;), dojo.hitch(this, function() {&lt;br /&gt;
                                             this.restoreServerGameState();&lt;br /&gt;
               }));&lt;br /&gt;
          }&lt;br /&gt;
        } &lt;br /&gt;
Note: usually I call my own function call this.cancelLocalStateEffects() which will do more stuff first then call restoreServerGameState(), same function is usually needs to be called when server request has failed (i.e. invalid move)&lt;br /&gt;
&lt;br /&gt;
Note: If you need more than 2 steps, you may have to do client side animation to reflect the new state, which gets trickier because you have to undo that also on cancellation.&lt;br /&gt;
&lt;br /&gt;
Code is available here [https://github.com/elaskavaia/bga-sharedcode/blob/master/sharedcode.js sharedcode.js] (its using playerTurnPlayCubes and client_selectCubeLocation).&lt;br /&gt;
&lt;br /&gt;
=== Action Stack - Using Client States ===&lt;br /&gt;
&lt;br /&gt;
Action stack required where game is very complex and use triggered effects that can &amp;quot;stack&amp;quot;. It not always actual stack, it can be queue or random access&lt;br /&gt;
Examples:&lt;br /&gt;
* Magic the Gathering - classic card game where effects go on Stack, that allows to counter spell and counter spell of counter spell (not on bga - it just example of mechanics)&lt;br /&gt;
* Ultimate Railroads - action taking game where effects can be executed in any order&lt;br /&gt;
* Lewis and Clark - card game where actions executed as queue&lt;br /&gt;
&lt;br /&gt;
There is two ways of implementing it - on the server or the client.&lt;br /&gt;
For the server see article below.&lt;br /&gt;
The requirement for client side stack is all action can be undone, which means&lt;br /&gt;
* No dice rolls&lt;br /&gt;
* No card drawn&lt;br /&gt;
* No other players interaction&lt;br /&gt;
&lt;br /&gt;
No snippets are here, as this will be too complex but basically flow is:&lt;br /&gt;
* You have a action/effect stack (queue/list) as js object attached to &amp;quot;this&amp;quot;, i.e. this.unprocessed_actions&lt;br /&gt;
* When player plays a card, worker, etc, you read the effect of that card from the material file (client copy), and place into stack&lt;br /&gt;
* Then we call dispatch method which pulls the next action from the stack and change client state accordinly,i.e.  this.setClientState(&amp;quot;client_playerGainsCubes&amp;quot;)&lt;br /&gt;
* When players acts on it - the action is removed from the stack and added to &amp;quot;server action arguments&amp;quot; list, this is another object which be used to send ajax call, i.e. this.clientStateArgs&lt;br /&gt;
* If nothing left in stack we can submit the ajax call assembling parameters from collected arguments (that can include action name)&lt;br /&gt;
* This method allows cheap undo - by restoring server state you will wipe out all user actions (but if you need intermediate aninmation you have to handle it yourself)&lt;br /&gt;
&lt;br /&gt;
Code can be found in Ultimate Railroads game (but it is random access list - so it a bit complex) and Lewis and Clark (complexity - use can always deny part of any effect)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Action Stack - Using Server States ===&lt;br /&gt;
&lt;br /&gt;
See definition of Action Stack above.&lt;br /&gt;
&lt;br /&gt;
To implement you usually need another db table that has the following fields: index of effect - which is used for sorted access, type - which is essense of the effect (i.e. collect resource), some extra arguments (i.e. resource type and resource count), and usually owner of the effect (i.e. player id)&lt;br /&gt;
The flow is:&lt;br /&gt;
* There is some initial player state, where player can play card for example&lt;br /&gt;
* Player main action - pushes the card effect on stack, which also can cause triggered effects which also go on stack&lt;br /&gt;
* After action processing is finished switch to game state which is &amp;quot;dispatcher&amp;quot;&lt;br /&gt;
* Gispatcher pulls the top effect (whatever definition of the top is), changes the active player and changes the state to appropriate player state to collect response&lt;br /&gt;
* Player state knows about the stack and pulls arguments (argX) from the effect arguments of the db&lt;br /&gt;
* Player action should clear up the top effect, and can possibly add more effects, then switch to &amp;quot;dispatcher&amp;quot; state again&lt;br /&gt;
* If stack is empty, dispatcher can either pick next player itself or use another game state which responsible for picking next player&lt;br /&gt;
&lt;br /&gt;
Code can be found in Tapestry.&lt;br /&gt;
&lt;br /&gt;
=== Changing state prompt ===&lt;br /&gt;
&lt;br /&gt;
State prompt is message displayed for player which usually comes from state description.&lt;br /&gt;
Sometimes you want to change it without changing state (one way is change state but locally, see client states above).&lt;br /&gt;
&lt;br /&gt;
Simple way just change the html&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        setMainTitle: function(text) {&lt;br /&gt;
            $(&#039;pagemaintitletext&#039;).innerHTML = text;&lt;br /&gt;
        },&lt;br /&gt;
         // usage&lt;br /&gt;
        onMeeple: function(event) {&lt;br /&gt;
              //... &lt;br /&gt;
              this.setMainTitle(_(&#039;You must select where meeple is going&#039;));&lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This however will not work with parameters and will not draw You in color, if you want this its more sophisticated:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        setDescriptionOnMyTurn : function(text) {&lt;br /&gt;
            this.gamedatas.gamestate.descriptionmyturn = text;&lt;br /&gt;
            var tpl = dojo.clone(this.gamedatas.gamestate.args);&lt;br /&gt;
            if (tpl === null) {&lt;br /&gt;
                tpl = {};&lt;br /&gt;
            }&lt;br /&gt;
            var title = &amp;quot;&amp;quot;;&lt;br /&gt;
            if (this.isCurrentPlayerActive() &amp;amp;&amp;amp; text !== null) {&lt;br /&gt;
                tpl.you = this.divYou(); &lt;br /&gt;
            }&lt;br /&gt;
            title = this.format_string_recursive(text, tpl);&lt;br /&gt;
&lt;br /&gt;
            if (!title) {&lt;br /&gt;
                this.setMainTitle(&amp;quot;&amp;amp;nbsp;&amp;quot;);&lt;br /&gt;
            } else {&lt;br /&gt;
                this.setMainTitle(title);&lt;br /&gt;
            }&lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: this method uses &#039;&#039;&#039;setMainTitle&#039;&#039;&#039; defined above and &#039;&#039;&#039;divYou&#039;&#039;&#039; defined in another section of this wiki.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Adding Image buttons ===&lt;br /&gt;
&lt;br /&gt;
Its pretty trivial but just in case you need a working function:&lt;br /&gt;
&lt;br /&gt;
ggg.js:&lt;br /&gt;
&lt;br /&gt;
                addImageActionButton: function (id, div_html, handler) { // div_html is string not node&lt;br /&gt;
                    this.addActionButton(id, div_html, handler, &#039;&#039;, false, &#039;gray&#039;); &lt;br /&gt;
                    dojo.style(id, &amp;quot;border&amp;quot;, &amp;quot;none&amp;quot;); // remove ugly border&lt;br /&gt;
                    dojo.addClass(id, &amp;quot;bgaimagebutton&amp;quot;); // add css class to do more styling&lt;br /&gt;
                    return $(id); // return node for chaining&lt;br /&gt;
                },&lt;br /&gt;
&lt;br /&gt;
Example of usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    this.addImageActionButton(&#039;button_coin&#039;,&amp;quot;&amp;lt;div class=&#039;coin&#039;&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;, ()=&amp;gt;{ alert(&#039;Ha!&#039;); });&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Assigning Player Order ===&lt;br /&gt;
Normally when game starts there is &amp;quot;natural&amp;quot; player order assigned randomly.&lt;br /&gt;
&lt;br /&gt;
If you want to deliberatly assign player order at the start of the game (for example, in a game with teams options), you can do so by retrieving the initialization-only player attribute &#039;&#039;&#039;player_table_order&#039;&#039;&#039; and using it to assign values to &#039;&#039;&#039;player_no&#039;&#039;&#039; (which is normally assigned at the start of a game in the order in which players come to the table). (See [https://en.doc.boardgamearena.com/Game_database_model:_dbmodel.sql#The_player_table Game database model] for more details.)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Example:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                // Retrieve inital player order ([0=&amp;gt;playerId1, 1=&amp;gt;playerId2, ...])&lt;br /&gt;
		$playerInitialOrder = [];&lt;br /&gt;
		foreach ($players as $playerId =&amp;gt; $player) {&lt;br /&gt;
			$playerInitialOrder[$player[&#039;player_table_order&#039;]] = $playerId;&lt;br /&gt;
		}&lt;br /&gt;
		ksort($playerInitialOrder);&lt;br /&gt;
		$playerInitialOrder = array_flip(array_values($playerInitialOrder));&lt;br /&gt;
&lt;br /&gt;
		// Player order based on &#039;playerTeams&#039; option&lt;br /&gt;
		$playerOrder = [0, 1, 2, 3];&lt;br /&gt;
		switch (self::getGameStateValue(&#039;playerTeams&#039;)) {&lt;br /&gt;
			case self::TEAM_1_2:&lt;br /&gt;
				$playerOrder = [0, 2, 1, 3];&lt;br /&gt;
				break;&lt;br /&gt;
			case self::TEAM_1_4:&lt;br /&gt;
				$playerOrder = [0, 1, 3, 2];&lt;br /&gt;
				break;&lt;br /&gt;
			case self::TEAM_RANDOM:&lt;br /&gt;
				shuffle($playerOrder);&lt;br /&gt;
				break;&lt;br /&gt;
			default:&lt;br /&gt;
			case self::TEAM_1_3:&lt;br /&gt;
				// Default order&lt;br /&gt;
				break;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
                // Create players&lt;br /&gt;
		// Note: if you added some extra field on &amp;quot;player&amp;quot; table in the database (dbmodel.sql), you can initialize it there.&lt;br /&gt;
		$sql =&lt;br /&gt;
			&#039;INSERT INTO player (player_id, player_color, player_canal, player_name, player_avatar, player_no) VALUES &#039;;&lt;br /&gt;
		$values = [];&lt;br /&gt;
&lt;br /&gt;
		foreach ($players as $playerId =&amp;gt; $player) {&lt;br /&gt;
			$color = array_shift($default_colors);&lt;br /&gt;
			$values[] =&lt;br /&gt;
				&amp;quot;(&#039;&amp;quot; .&lt;br /&gt;
				$playerId .&lt;br /&gt;
				&amp;quot;&#039;,&#039;$color&#039;,&#039;&amp;quot; .&lt;br /&gt;
				$player[&#039;player_canal&#039;] .&lt;br /&gt;
				&amp;quot;&#039;,&#039;&amp;quot; .&lt;br /&gt;
				addslashes($player[&#039;player_name&#039;]) .&lt;br /&gt;
				&amp;quot;&#039;,&#039;&amp;quot; .&lt;br /&gt;
				addslashes($player[&#039;player_avatar&#039;]) .&lt;br /&gt;
				&amp;quot;&#039;,&#039;&amp;quot; .&lt;br /&gt;
				$playerOrder[$playerInitialOrder[$playerId]] .&lt;br /&gt;
				&amp;quot;&#039;)&amp;quot;;&lt;br /&gt;
		}&lt;br /&gt;
		$sql .= implode(&#039;,&#039;, $values);&lt;br /&gt;
		self::DbQuery($sql);&lt;br /&gt;
		self::reattributeColorsBasedOnPreferences(&lt;br /&gt;
			$players,&lt;br /&gt;
			$gameinfos[&#039;player_colors&#039;]&lt;br /&gt;
		);&lt;br /&gt;
		self::reloadPlayersBasicInfos();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Send different notifications to active player vs everybody else ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
Hack alert. This is a hack. We were hoping for proper solution by bga framework.&lt;br /&gt;
&lt;br /&gt;
This will allow you to send notification with two message one for specific player and one for everybody else including spectators.&lt;br /&gt;
Note that this does not split the data - all data must be shared.&lt;br /&gt;
&lt;br /&gt;
Add this to .js file (if you already overriding it merge obviously)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/** @Override */&lt;br /&gt;
format_string_recursive: function(log, args) {&lt;br /&gt;
   if (typeof args.log_others != &#039;undefined&#039; &amp;amp;&amp;amp; typeof args.player_id != &#039;undefined&#039; &amp;amp;&amp;amp; this.player_id != args.player_id)&lt;br /&gt;
	log = args.log_others;&lt;br /&gt;
   return this.inherited(arguments); // you must call this to call super &lt;br /&gt;
},&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example of usage (from eminentdomain)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    $this-&amp;gt;notifyAllPlayers(&#039;tokenMoved&#039;, &lt;br /&gt;
             clienttranslate(&#039;${player_name} adds +2 Colonies to ${place_name}&#039;), // notification with show for player with player_id&lt;br /&gt;
             [&#039;player_id&#039;=&amp;gt;$player_id, // this is mandatory&lt;br /&gt;
             &#039;log_others&#039;=&amp;gt;clienttranslate(&#039;${player_name} adds +2 Colonies to an unknown planet&#039;), // notification will show for others&lt;br /&gt;
              ...&lt;br /&gt;
             ]);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Send transient notifications without incrementing move ID ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.php&lt;br /&gt;
&lt;br /&gt;
Hack alert. This is a hack.&lt;br /&gt;
&lt;br /&gt;
Use this if you need to send some transient notification that should not create a new move ID. The notification should be idempotent -- it should have no practical effect on the game state and would be &#039;&#039;&#039;safe to drop&#039;&#039;&#039; (e.g., it would not matter if a player never received this notification). For example, in a co-op game you want all players to see a real-time preview of some action, before the active player commits their turn.&lt;br /&gt;
&lt;br /&gt;
Doing this mainly affects the instant replay &amp;amp; archive modes. During replay, the BGA framework automatically inserts a 1.5-second pause between each &amp;quot;move&amp;quot;. With this hack, your transient notifications are not considered to be a &amp;quot;move&amp;quot;, so no pause gets added.&lt;br /&gt;
&lt;br /&gt;
; In ggg.php&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$this-&amp;gt;not_a_move_notification = true; // note: do not increase the move counter&lt;br /&gt;
$this-&amp;gt;notifyAllPlayers(&#039;cardsPreview&#039;, &#039;&#039;, $args);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: you cannot have code that send notification or even changes state after this, and you cannot reset this variable back either because it only takes effect when you exit action handling function&lt;br /&gt;
&lt;br /&gt;
=== Ajax Call wrapper ===&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
The current ajaxcall is super vebose and prone to errors, I suggest using a helper function. It does a lot of stuff you must do anyways.&lt;br /&gt;
Most beginner mistakes come from missing part of this code (which is understandstandable - this is a huge snippet to clone every time).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	ajaxcallwrapper: function(action, args, handler) {&lt;br /&gt;
		if (!args) args = []; // this allows to skip args parameter for action which do not require them&lt;br /&gt;
			&lt;br /&gt;
		args.lock = true; // this allows to avoid rapid action clicking which can cause race condition on server&lt;br /&gt;
		if (this.checkAction(action)) { // this does all the proper check that player is active and action is declared&lt;br /&gt;
			this.ajaxcall(&amp;quot;/&amp;quot; + this.game_name + &amp;quot;/&amp;quot; + this.game_name + &amp;quot;/&amp;quot; + action + &amp;quot;.html&amp;quot;, args, // this is mandatory fluff &lt;br /&gt;
				this, (result) =&amp;gt; { },  // success result handler is empty - it is never needed&lt;br /&gt;
                                               handler); // this is real result handler - it called both on success and error, it has optional param  &amp;quot;is_error&amp;quot; - you rarely need it&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   this.ajaxcallwrapper(&#039;pass&#039;); // no args&lt;br /&gt;
   this.ajaxcallwrapper(&#039;playCard&#039;, {card: card_id}); // with args&lt;br /&gt;
   this.ajaxcallwrapper(&#039;playCard&#039;, {card: card_id}, (is_error)=&amp;gt;{if (!is_error) dojo.query(&amp;quot;.selected&amp;quot;).removeClass(&#039;selected&#039;);}) // with handler that cleans up &#039;selected&#039; class on success&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: this always will lock interface and always check for action, you can modify this method to do it optionally, i.e&lt;br /&gt;
  if (args.lock!==false) args.lock = true; else delete args.lock; // it does not work with false value - it has to be removed&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Custom error/exception handling in JavaScript ===&lt;br /&gt;
&lt;br /&gt;
; In ggg.php&lt;br /&gt;
We intentionally throw BgaUserException to rollback database transaction and cancel all changes. Note that any notifications are also cancelled!&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    function foo(bool $didConfirm = false): void&lt;br /&gt;
    {&lt;br /&gt;
        // do processing for the user&#039;s move&lt;br /&gt;
        // afterwards, you determine this move will end the game&lt;br /&gt;
        // so you want to rollback the transaction and require the user to confirm the move first&lt;br /&gt;
&lt;br /&gt;
        if ($gameIsEnding &amp;amp;&amp;amp; !$didConfirm) {&lt;br /&gt;
            throw new BgaUserException(&#039;!!!endGameWarning&#039;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; In ggg.js&lt;br /&gt;
We define a global variable at the top to store the last error code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  var lastErrorCode = null;&lt;br /&gt;
  return declare(&amp;quot;bgagame.ggg&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We override framework function showMessage to populate the last error code and suppress the red banner message and log message&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    /* @Override */&lt;br /&gt;
    showMessage: function (msg, type) {&lt;br /&gt;
      if (type == &amp;quot;error&amp;quot;) {&lt;br /&gt;
        lastErrorCode = msg.startsWith(&amp;quot;!!!&amp;quot;) ? msg.substring(3) : null;&lt;br /&gt;
        if (lastErrorCode) {&lt;br /&gt;
          return; // suppress red banner and log message&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      this.inherited(arguments);&lt;br /&gt;
    },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Since the framework calls showMessage before your ajaxcall error handler, you can deal with the error in-place:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    fooAction: function (didConfirm) {&lt;br /&gt;
      var data = {&lt;br /&gt;
        foo: &amp;quot;bar&amp;quot;,&lt;br /&gt;
        didConfirm: !!didConfirm,&lt;br /&gt;
      };&lt;br /&gt;
      this.ajaxcallwrapper(&amp;quot;fooAction&amp;quot;, data, function (error) {&lt;br /&gt;
        if (lastErrorCode == &amp;quot;endGameWarning&amp;quot;) {&lt;br /&gt;
          // your custom error handling goes here&lt;br /&gt;
          // for example, show a confirmation dialog and repeat the action with additional param&lt;br /&gt;
          this.confirmationDialog(&lt;br /&gt;
            _(&amp;quot;Doing the foo action now will end the game&amp;quot;),&lt;br /&gt;
            () =&amp;gt; {&lt;br /&gt;
              this.fooAction(true);&lt;br /&gt;
            }&lt;br /&gt;
          );&lt;br /&gt;
        }&lt;br /&gt;
      });&lt;br /&gt;
    },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Studio]]&lt;/div&gt;</summary>
		<author><name>SwHawk</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=BGA_Studio_Cookbook&amp;diff=14559</id>
		<title>BGA Studio Cookbook</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=BGA_Studio_Cookbook&amp;diff=14559"/>
		<updated>2022-09-02T05:10:44Z</updated>

		<summary type="html">&lt;p&gt;SwHawk: /* Third way: rely on the transform argument of dojo.string.substitute */ Fixed typo&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
This page is collection of design and implementation recipes for BGA Studio framework.&lt;br /&gt;
For tooling and usage recipes see [[Tools and tips of BGA Studio]].&lt;br /&gt;
If you have your own recipes feel free to edit this page.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Visual Effects, Layout and Animation ==&lt;br /&gt;
&lt;br /&gt;
=== DOM manipulatons ===&lt;br /&gt;
&lt;br /&gt;
==== Create pieces dynamically (using template) ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg_ggg.tpl, ggg.js&lt;br /&gt;
&lt;br /&gt;
Note: this method is recommended by BGA guildlines&lt;br /&gt;
&lt;br /&gt;
Declared js template with variables in .tpl file, like this&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;
    // Javascript HTML templates&lt;br /&gt;
    var jstpl_ipiece = &#039;&amp;lt;div class=&amp;quot;${type} ${type}_${color} inlineblock&amp;quot; aria-label=&amp;quot;${name}&amp;quot; title=&amp;quot;${name}&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use it like this in .js file&lt;br /&gt;
  div = this.format_block(&#039;jstpl_ipiece&#039;, {&lt;br /&gt;
                                type : &#039;meeple&#039;,&lt;br /&gt;
                                color : &#039;ff0000&#039;,&lt;br /&gt;
                                name : &#039;Bob&#039;,&lt;br /&gt;
                            });&lt;br /&gt;
  &lt;br /&gt;
Then you do whatever you need to do with that div, this one specifically design to go to log entries, because it has embedded title (otherwise its a picture only) and no id.&lt;br /&gt;
&lt;br /&gt;
Note: you could have place this variable in js itself, but keeping it in .tpl allows you to have your js code be free of HTML. Normally it never happens but&lt;br /&gt;
it is good to strive for it.&lt;br /&gt;
Note: you can also use string concatenation, its less readable. You can also use dojo dom object creation api&#039;s but its brutally verbose and its more unreadable.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Create pieces dynamically (using string concatenation) ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
Note: Not recommended&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  div = &amp;quot;&amp;lt;div class=&#039;meeple &amp;quot;+color+&amp;quot;&#039;&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
==== Create all pieces statically ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg_ggg.tpl, ggg.css, ggg.view.php (optional) &lt;br /&gt;
&lt;br /&gt;
* Create ALL game pieces in html template (.tpl)&lt;br /&gt;
* ALL pieces should have unique id, and it should be meaningful, i.e. meeple_red_1&lt;br /&gt;
* Do not use inline styling&lt;br /&gt;
* Id of player&#039;s specific pieces should use some sort of &#039;color&#039; identification, since player id cannot be used in static layout, you can use english color name, hex 6 char value, or color &amp;quot;number&amp;quot; (1,2,3...)&lt;br /&gt;
* Pieces should have separated class for its color, type, etc, so it can be easily styled in groups. In example below you now can style all meeples, all red meeples or all red tokens, or all &amp;quot;first&amp;quot; meeples&lt;br /&gt;
&lt;br /&gt;
ggg.tpl:&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
  &amp;lt;div id=&amp;quot;home_red&amp;quot; class=&amp;quot;home_red home&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;div id=&amp;quot;meeple_red_1&amp;quot; class=&amp;quot;meeple red n1&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
     &amp;lt;div id=&amp;quot;meeple_red_2&amp;quot; class=&amp;quot;meeple red n2&amp;quot;&amp;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;
ggg.css:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.meeple {&lt;br /&gt;
	width: 32px;&lt;br /&gt;
	height: 39px;&lt;br /&gt;
	background-image: url(img/78_64_stand_meeples.png);&lt;br /&gt;
	background-size: 352px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.meeple.red {&lt;br /&gt;
	background-position: 30% 0%;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* There should be straight forward mapping between server id and js id (or 1:1)&lt;br /&gt;
* You place objects in different zones of the layout, and setup css to take care of layout&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.home .meeple{&lt;br /&gt;
   display: inline-block;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* If you need to have a temporary object that look like original you can use dojo.clone (and change id to some temp id)&lt;br /&gt;
* If there is lots of repetition or zone grid you can use template generator, but inject style declaration in css instead of inline style for flexibility&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
* If you use this model you cannot use premade js components such as Stock and Zone&lt;br /&gt;
* You have to use alternative methods of animation (slightly altered) since default method will leave object with inline style attributes which you don&#039;t need&lt;br /&gt;
&lt;br /&gt;
=== Logs ===&lt;br /&gt;
&lt;br /&gt;
==== Inject icon images in the log ====&lt;br /&gt;
&lt;br /&gt;
Here is an example of what was done for Terra Mystica which is simple and straightforward:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
//Define the proper message&lt;br /&gt;
		$message = clienttranslate(&#039;${player_name} gets ${power_income} via Structures&#039;);&lt;br /&gt;
		if ($price &amp;gt; 0) {&lt;br /&gt;
			self::DbQuery(&amp;quot;UPDATE player SET player_score = player_score - $price WHERE player_id = $player_id&amp;quot;);&lt;br /&gt;
			$message = clienttranslate(&#039;${player_name} pays ${vp_price} and gets ${power_income} via Structures&#039;);&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
// Notify&lt;br /&gt;
		self::notifyAllPlayers( &amp;quot;powerViaStructures&amp;quot;, $message, array(&lt;br /&gt;
			&#039;i18n&#039; =&amp;gt; array( ),&lt;br /&gt;
			&#039;player_id&#039; =&amp;gt; $player_id,&lt;br /&gt;
			&#039;player_name&#039; =&amp;gt; self::getUniqueValueFromDb( &amp;quot;SELECT player_name FROM player WHERE player_id = $player_id&amp;quot; ),&lt;br /&gt;
			&#039;power_tokens&#039; =&amp;gt; $power_tokens,&lt;br /&gt;
			&#039;vp_price&#039; =&amp;gt; self::getLogsVPAmount($price),&lt;br /&gt;
			&#039;power_income&#039; =&amp;gt; self::getLogsPowerAmount($power_income),&lt;br /&gt;
			&#039;newScore&#039; =&amp;gt; self::getUniqueValueFromDb( &amp;quot;SELECT player_score FROM player WHERE player_id = $player_id&amp;quot; ),&lt;br /&gt;
			&#039;counters&#039; =&amp;gt; $this-&amp;gt;getGameCounters(null),&lt;br /&gt;
		) );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With some functions to have the needed html added inside the substitution variable, such as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function getLogsPowerAmount( $amount ) {&lt;br /&gt;
		return &amp;quot;&amp;lt;div class=&#039;tmlogs_icon&#039; title=&#039;Power&#039;&amp;gt;&amp;lt;div class=&#039;power_amount&#039;&amp;gt;$amount&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: injecting html from php is not ideal but easy, if you want more clean solution, use method below but it is a lot more sophisticated.&lt;br /&gt;
&lt;br /&gt;
==== Inject images and styled html in the log ====&lt;br /&gt;
&lt;br /&gt;
{{InfoBox|title=Warning — Translation|maxWidth=500|topLeftColour=#c00|middleColour=#c00|bottomRightColour=#c00|body=&#039;&#039;&#039;In order to prevent interference with the translation process, keep in mind that you must only apply modifications to the args object, and not try to substitute the keys (the &amp;lt;code&amp;gt;${player_name}&amp;lt;/code&amp;gt; parts of your string) in the log string.&#039;&#039;&#039;}}&lt;br /&gt;
&lt;br /&gt;
So you want nice pictures in the game log. What do you do? The first idea that comes to mind is to send html from php in notifications (see method above). &lt;br /&gt;
&lt;br /&gt;
This is a bad idea for many reasons:&lt;br /&gt;
&lt;br /&gt;
* It&#039;s bad architecture. ui elements leak into the server, and now you have to manage the ui in multiple places.&lt;br /&gt;
* If you decided to change something in the ui in future version, replay logs for old games and tutorials may not work, since they use stored notifications.&lt;br /&gt;
* Log previews for old games become unreadable. (This is the log state before you enter the game replay, which is useful for troubleshooting and game analysis.)&lt;br /&gt;
* It&#039;s more data to transfer and store in the db.&lt;br /&gt;
* It&#039;s a nightmare for translators.&lt;br /&gt;
&lt;br /&gt;
So what else can you do? You can use client side log injection to intercept log arguments (which come from the server) and replace them with html on the client side. Here are three different method you can use to achieve this.&lt;br /&gt;
&lt;br /&gt;
===== First way : Override &amp;lt;code&amp;gt;this.format_string_recursive()&amp;lt;/code&amp;gt; method =====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, ggg.game.php&lt;br /&gt;
&lt;br /&gt;
I use this recipe for &#039;&#039;&#039;client side log injection&#039;&#039;&#039; to intercept log arguments (which come from the server) and replace them with html on the client side.&lt;br /&gt;
&lt;br /&gt;
[[File:clientloginjection.png|left]] &lt;br /&gt;
&lt;br /&gt;
ggg.js&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
        /** Override this function to inject html into log items. This is a built-in BGA method.  */&lt;br /&gt;
&lt;br /&gt;
        /* @Override */&lt;br /&gt;
        format_string_recursive : function format_string_recursive(log, args) {&lt;br /&gt;
            try {&lt;br /&gt;
                if (log &amp;amp;&amp;amp; args &amp;amp;&amp;amp; !args.processed) {&lt;br /&gt;
                    args.processed = true;&lt;br /&gt;
                    &lt;br /&gt;
&lt;br /&gt;
                    // list of special keys we want to replace with images&lt;br /&gt;
                    var keys = [&#039;place_name&#039;,&#039;token_name&#039;];&lt;br /&gt;
                    &lt;br /&gt;
                  &lt;br /&gt;
                    for ( var i in keys) {&lt;br /&gt;
                        var key = keys[i];&lt;br /&gt;
                        key in args &amp;amp;&amp;amp; args[key] = this.getTokenDiv(key, args);                            &lt;br /&gt;
&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            } catch (e) {&lt;br /&gt;
                console.error(log,args,&amp;quot;Exception thrown&amp;quot;, e.stack);&lt;br /&gt;
            }&lt;br /&gt;
            return this.inherited({callee: format_string_recursive}, arguments);&lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important:&#039;&#039;&#039; In the &#039;&#039;format_string_recursive&#039;&#039; method, the &#039;args&#039; parameter will only contain arguments passed to it from the notify method in ggg.game.php (see below).&lt;br /&gt;
&lt;br /&gt;
The &#039;log&#039; parameter is the actual string that is inserted into the logs. You can perform additional js string manipulation on it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        getTokenDiv : function(key, args) {&lt;br /&gt;
            // ... implement whatever html you want here, example from sharedcode.js&lt;br /&gt;
            var token_id = args[key];&lt;br /&gt;
            var item_type = getPart(token_id,0);&lt;br /&gt;
            var logid = &amp;quot;log&amp;quot; + (this.globalid++) + &amp;quot;_&amp;quot; + token_id;&lt;br /&gt;
            switch (item_type) {&lt;br /&gt;
                case &#039;wcube&#039;:&lt;br /&gt;
                    var tokenDiv = this.format_block(&#039;jstpl_resource_log&#039;, {&lt;br /&gt;
                        &amp;quot;id&amp;quot; : logid,&lt;br /&gt;
                        &amp;quot;type&amp;quot; : &amp;quot;wcube&amp;quot;,&lt;br /&gt;
                        &amp;quot;color&amp;quot; : getPart(token_id,1),&lt;br /&gt;
                    });&lt;br /&gt;
                    return tokenDiv;&lt;br /&gt;
             &lt;br /&gt;
                case &#039;meeple&#039;:&lt;br /&gt;
                    if ($(token_id)) {&lt;br /&gt;
                        var clone = dojo.clone($(token_id));&lt;br /&gt;
    &lt;br /&gt;
                        dojo.attr(clone, &amp;quot;id&amp;quot;, logid);&lt;br /&gt;
                        this.stripPosition(clone);&lt;br /&gt;
                        dojo.addClass(clone, &amp;quot;logitem&amp;quot;);&lt;br /&gt;
                        return clone.outerHTML;&lt;br /&gt;
                    }&lt;br /&gt;
                    break;&lt;br /&gt;
     &lt;br /&gt;
                default:&lt;br /&gt;
                    break;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            return &amp;quot;&#039;&amp;quot; + this.clienttranslate_string(this.getTokenName(token_id)) + &amp;quot;&#039;&amp;quot;;&lt;br /&gt;
       },&lt;br /&gt;
       getTokenName : function(key) {&lt;br /&gt;
           return this.gamedatas.token_types[key].name; // get name for the key, from static table for example&lt;br /&gt;
       },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that in this case the server simply injects token_id as a name, and the client substitutes it for the translated name or the picture.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ggg.game.php:&lt;br /&gt;
&lt;br /&gt;
           $this-&amp;gt;notifyAllPlayers(&#039;playerLog&#039;,clienttranslate(&#039;Game moves ${token_name}&#039;),[&#039;token_name&#039;=&amp;gt;$token_id]);&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important:&#039;&#039;&#039; As noted above, only arguments actually passed by this method are available to the args parameter received in the client-side &#039;&#039;format_string_recursive&#039;&#039; method.&lt;br /&gt;
&lt;br /&gt;
Sometimes it is the case that you want to pass arguments that are not actually included in the output message. For example, suppose we have a method like this:&lt;br /&gt;
&lt;br /&gt;
           $this-&amp;gt;notifyAllPlayers(&#039;tokenPlaced&#039;,clienttranslate(&#039;Player placed ${token_name}&#039;),array(&lt;br /&gt;
              &#039;token_name&#039; =&amp;gt; $token_id,&lt;br /&gt;
              &#039;zone_played&#039; =&amp;gt; $zone);&lt;br /&gt;
&lt;br /&gt;
This will output &amp;quot;Player placed ${token_name}&amp;quot; in the log, and if we subscribe to a notification method activated by the &amp;quot;tokenPlaced&amp;quot; event in the client-side code, that method can make use of the &#039;zone_played&#039; argument. &lt;br /&gt;
&lt;br /&gt;
Now if you want to make some really cool things with game log, most probably you would need more arguments than are included in log message. The problem with that,&lt;br /&gt;
it will work at first, but if you reload game using F5 or when the game loads in turn based mode, you will loose your additional parameters, why? Because when game reloads it does not actually send same notifications, it sends special &amp;quot;hitstorical_log&amp;quot; notification where all  parameters not listed in the message are removed. In example above, field zone_played would be removed from historical log as it is not included in message of the notification. You can till preserve specific arguments in historical log by adding special field preserve to notification arguments like this:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
           $this-&amp;gt;notifyAllPlayers(&#039;tokenPlaced&#039;,clienttranslate(&#039;Player placed ${token_name}&#039;),array(&lt;br /&gt;
              &#039;token_name&#039; =&amp;gt; $token_id,&lt;br /&gt;
              &#039;zone_played&#039; =&amp;gt; $zone,&lt;br /&gt;
              &#039;preserve&#039; =&amp;gt; [ &#039;zone_played&#039; ]&lt;br /&gt;
           );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now you can use zone_played in format_string_recursive even in historical logs.&lt;br /&gt;
&lt;br /&gt;
===== Second way: rely on the &amp;lt;code&amp;gt;:formatFunction&amp;lt;/code&amp;gt; option provided by &amp;lt;code&amp;gt;dojo.string.substitute&amp;lt;/code&amp;gt; =====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, ggg.game.php, ggg_ggg.tpl, ggg.css&lt;br /&gt;
&lt;br /&gt;
The above method will work in most of the cases, but if you use dotted keys such as &amp;lt;code&amp;gt;${card.name}&amp;lt;/code&amp;gt; (which is supported by the framework, for private state args), the key won&#039;t be substituted because the &amp;lt;code&amp;gt;key in arg&amp;lt;/code&amp;gt; test will fail. If so you need to rely either on this way, or the one after.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;WARNING:&#039;&#039;&#039; using this method on an already advanced project will require you to go through all your notifications to change keys !&lt;br /&gt;
&lt;br /&gt;
Under the hood, the &#039;&#039;&#039;this.format_string_recursive()&#039;&#039;&#039; function calls the &#039;&#039;&#039;dojo.string.substitute&#039;&#039;&#039; method which substitutes &amp;lt;code&amp;gt;${keys}&amp;lt;/code&amp;gt; with the value provided. If you take a look at the [https://dojotoolkit.org/reference-guide/1.7/dojo/string.html#substitute documentation] and [https://github.com/dojo/dojo/blob/c3ceb017cfa25b703f5662dc83d1c8aae9bc5d81/string.js#L163 source code] you can notice that the key can be suffixed with a colon (&amp;lt;code&amp;gt;:&amp;lt;/code&amp;gt;) followed by a function name. This will allow you to specify directly in the substitution string which keys need HTML injection.&lt;br /&gt;
&lt;br /&gt;
First of all, you need to define your formatting function in the ggg.js file:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[[ggg.js]]&lt;br /&gt;
        getTokenDiv : function(value, key) {&lt;br /&gt;
            //This is only an example implementation, you need to write your own.&lt;br /&gt;
            //The method should return HTML code&lt;br /&gt;
            switch (key) {&lt;br /&gt;
                case &#039;html_injected_argument1&#039;:&lt;br /&gt;
                    return this.format_block(&#039;jstpl_HTMLLogElement1&#039;,{value: value});&lt;br /&gt;
                case &#039;html_injected_argument2&#039;:&lt;br /&gt;
                    return this.format_block(&#039;jstpl_HTMLLogElement2&#039;,{value: value});&lt;br /&gt;
                ...&lt;br /&gt;
            }&lt;br /&gt;
       }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Obviously you need to define the appropriate templates in the ggg_ggg.tpl file:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[[ggg_ggg.tpl]]&lt;br /&gt;
let jstpl_HTMLLogElement1 = &#039;&amp;lt;div class=&amp;quot;log-element log-element-1-${value}&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
let jstpl_HTMLLogElement2 = &#039;&amp;lt;div class=&amp;quot;log-element log-element-2-${value}&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
And the appropriate classes in ggg.css.&lt;br /&gt;
&lt;br /&gt;
Then you need to add the &amp;lt;code&amp;gt;dojo/aspect&amp;lt;/code&amp;gt; module at the top of the ggg.js file:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[ggg.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 define([&lt;br /&gt;
     &amp;quot;dojo&amp;quot;, &amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&amp;quot;dojo/aspect&amp;quot;,&amp;lt;/span&amp;gt;                 //MUST BE IN THIRD POSITION&#039;&#039;&#039; (see [[#Including your own JavaScript module (II)|below]])&lt;br /&gt;
     &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
 ], function (dojo, declare, &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&#039;&#039;&#039;aspect&#039;&#039;&#039;&amp;lt;/span&amp;gt;) {&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
And you also need to add the following code in your &amp;lt;code&amp;gt;contructor&amp;lt;/code&amp;gt; method in the ggg.js:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[ggg.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
         constructor: function(){&lt;br /&gt;
             console.log(&#039;progressevolutiontechnologyswh constructor&#039;);&lt;br /&gt;
               &lt;br /&gt;
             // Here, you can init the global variables of your user interface&lt;br /&gt;
             // Example:&lt;br /&gt;
             // this.myGlobalValue = 0;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&#039;&#039;&#039;let gameObject = this;&#039;&#039;&#039;            //Needed as the this object in aspect.before will not refer to the game object in which the formatting function resides&lt;br /&gt;
             &#039;&#039;&#039;aspect.before(dojo.string, &amp;quot;substitute&amp;quot;, function(template, map, transform) {&#039;&#039;&#039;      //This allows you to modify the arguments of the dojo.string.substitute method before they&#039;re actually passed to it&lt;br /&gt;
                 &#039;&#039;&#039;return [template, map, transform, gameObject];&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now you&#039;re all set to inject HTML in your logs. To actually achieve this, you must specify the function name with the key like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[ggg.game.php]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 $this-&amp;gt;notifyAllPlayers(&amp;quot;notificationName&amp;quot;, clienttranslate(&amp;quot;This log message contains ${plainTextArgument} and the following will receive HTML injection: ${html_injected_argument1:getTokenDiv}&amp;quot;), [&lt;br /&gt;
     &amp;quot;plainTextArgument&amp;quot; =&amp;gt; &amp;quot;some plain text here&amp;quot;,&lt;br /&gt;
     &amp;quot;html_injected_argument1&amp;quot; =&amp;gt; &amp;quot;some value used by getTokenDiv&amp;quot;,&lt;br /&gt;
 ]);&lt;br /&gt;
&lt;br /&gt;
You&#039;re not limited writing only one function, you can write as many functions as you like, and have them each inject a specific type of HTML. You just need to specify the relevant function name after the column in the substitution key.&lt;br /&gt;
&lt;br /&gt;
===== Third way: rely on the &amp;lt;code&amp;gt;transform&amp;lt;/code&amp;gt; argument of &amp;lt;code&amp;gt;dojo.string.substitute&amp;lt;/code&amp;gt; =====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, ggg.game.php, ggg_ggg.tpl, ggg.css&lt;br /&gt;
&lt;br /&gt;
This method is also relying on the use of &amp;lt;code&amp;gt;dojo.string.substitute&amp;lt;/code&amp;gt; by the framework, and will use the &amp;lt;code&amp;gt;transform&amp;lt;/code&amp;gt; argument, which, accordting to [https://github.com/dojo/dojo/blob/c3ceb017cfa25b703f5662dc83d1c8aae9bc5d81/string.js#L163 source code] and [https://dojotoolkit.org/reference-guide/1.7/dojo/string.html#substitute documentation] will be run on all the messages going through dojo.string.substitute.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;WARNING:&#039;&#039;&#039; As this method will be applied to all strings that go through dojo.string.substitute. As such you must take extra care not to substitute keys that may be used by the framework (i.e. ${id}). In order to do so, a good practise would be to prefix all keys that need substitution with a trigram of the game name.&lt;br /&gt;
&lt;br /&gt;
Since all the keys will be fed to the tranform function, by default, it must return the value, substituted or not per your needs. You can define the function like this in the ggg.js file:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[ggg.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
         getTokenDiv : function(value, key) {&lt;br /&gt;
             //This is only an example implementation, you need to write your own.&lt;br /&gt;
             //The method should return HTML code&lt;br /&gt;
             switch (key) {&lt;br /&gt;
                 case &#039;html_injected_argument1&#039;:&lt;br /&gt;
                     return this.format_block(&#039;jstpl_HTMLLogElement1&#039;,{value: value});&lt;br /&gt;
                 case &#039;html_injected_argument2&#039;:&lt;br /&gt;
                     return this.format_block(&#039;jstpl_HTMLLogElement2&#039;,{value: value});&lt;br /&gt;
                 ...&lt;br /&gt;
                 &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&#039;&#039;&#039;default:&#039;&#039;&#039;&lt;br /&gt;
                     &#039;&#039;&#039;return value;&#039;&#039;&#039;&amp;lt;/span&amp;gt;                  &#039;&#039;&#039;//Needed otherwise regular strings won&#039;t appear since since the value isn&#039;t returned by the function&#039;&#039;&#039;&lt;br /&gt;
             }&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
The templates must be defined in the ggg_ggg.tpl file and the corresponding CSS classes in the ggg.css file.&lt;br /&gt;
&lt;br /&gt;
You need to add the following code at the beginning of the ggg.js file:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[ggg.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 define([&lt;br /&gt;
     &amp;quot;dojo&amp;quot;, &amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&amp;quot;dojo/aspect&amp;quot;,&amp;lt;/span&amp;gt;                 //MUST BE IN THIRD POSITION&#039;&#039;&#039; (see [[#Including your own JavaScript module (II)|below]])&lt;br /&gt;
     &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
 ], function (dojo, declare, &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&#039;&#039;&#039;aspect&#039;&#039;&#039;&amp;lt;/span&amp;gt;) {&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
And the following code to the &amp;lt;code&amp;gt;constructor&amp;lt;/code&amp;gt; method in ggg.js:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[ggg.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
         constructor: function(){&lt;br /&gt;
             console.log(&#039;progressevolutiontechnologyswh constructor&#039;);&lt;br /&gt;
               &lt;br /&gt;
             // Here, you can init the global variables of your user interface&lt;br /&gt;
             // Example:&lt;br /&gt;
             // this.myGlobalValue = 0;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&#039;&#039;&#039;let transformFunction = dojo.hitch(this, &amp;quot;getTokenDiv&amp;quot;);&#039;&#039;&#039;            //Needed as the this object in aspect.before will not refer to the game object in which the formatting function resides&lt;br /&gt;
             &#039;&#039;&#039;aspect.before(dojo.string, &amp;quot;substitute&amp;quot;, function(template, map, transform) {&#039;&#039;&#039;&lt;br /&gt;
                 &#039;&#039;&#039;if (undefined === transform) {&#039;&#039;&#039;                                   //Check for a transform function presence, just in case&lt;br /&gt;
                     &#039;&#039;&#039;return [template, map, transformFunction];&#039;&#039;&#039;&lt;br /&gt;
                 &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then you&#039;re all set for log injection, no need to change anything on the PHP side.&lt;br /&gt;
&lt;br /&gt;
==== Processing logs on re-loading ====&lt;br /&gt;
&lt;br /&gt;
You rarely need to process logs when reloading, but if you want to do something fancy you may have to do it after logs are loaded. &lt;br /&gt;
Logs are loaded asyncronously so you have to listen for logs to be fully loaded.&lt;br /&gt;
Unfortunately there is no direct way of doing it so this is the hack.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Hack alert&#039;&#039;&#039; - this extends undocumented function and may be broken when framework is updated&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
			/*&lt;br /&gt;
  			* [Undocumented] Override BGA framework functions to call onLoadingLogsComplete when loading is done&lt;br /&gt;
                        @Override&lt;br /&gt;
   			*/&lt;br /&gt;
			setLoader: function(image_progress, logs_progress) {&lt;br /&gt;
				this.inherited(arguments); // required, this is &amp;quot;super()&amp;quot; call, do not remove&lt;br /&gt;
				//console.log(&amp;quot;loader&amp;quot;, image_progress, logs_progress)&lt;br /&gt;
				if (!this.isLoadingLogsComplete &amp;amp;&amp;amp; logs_progress &amp;gt;= 100) {&lt;br /&gt;
					this.isLoadingLogsComplete = true; // this is to prevent from calling this more then once&lt;br /&gt;
					this.onLoadingLogsComplete();&lt;br /&gt;
				}&lt;br /&gt;
			},&lt;br /&gt;
&lt;br /&gt;
			onLoadingLogsComplete: function() {&lt;br /&gt;
				console.log(&#039;Loading logs complete&#039;);&lt;br /&gt;
				// do something here&lt;br /&gt;
			},&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Player Panel ===&lt;br /&gt;
&lt;br /&gt;
==== Inserting non-player panel ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, ggg_ggg.tpl&lt;br /&gt;
&lt;br /&gt;
If you want to insert non-player panel on the right side (for example to hold extra preferences, zooming controls, etc)&lt;br /&gt;
&lt;br /&gt;
this can go pretty much anywhere in template it will be moved later&lt;br /&gt;
&lt;br /&gt;
ggg_ggg.tpl:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	&amp;lt;div class=&#039;player_board_config&#039; id=&amp;quot;player_board_config&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;!-- here is whatever you want, buttons just example --&amp;gt;&lt;br /&gt;
		&amp;lt;button id=&amp;quot;zoom-out&amp;quot; class=&amp;quot; fa fa-search-minus fa-2x config-control&amp;quot;&amp;gt;&amp;lt;/button&amp;gt;&lt;br /&gt;
		&amp;lt;button id=&amp;quot;zoom-in&amp;quot; class=&amp;quot; fa fa-search-plus fa-2x config-control&amp;quot;&amp;gt;&amp;lt;/button&amp;gt;&lt;br /&gt;
		&amp;lt;button id=&amp;quot;show-settings&amp;quot; class=&amp;quot;fa fa-cog fa-2x config-control &amp;quot;&amp;gt;&amp;lt;/button&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
some hackery required in js&lt;br /&gt;
&lt;br /&gt;
ggg.js:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* @Override */&lt;br /&gt;
	updatePlayerOrdering() {&lt;br /&gt;
		this.inherited(arguments);&lt;br /&gt;
		dojo.place(&#039;player_board_config&#039;, &#039;player_boards&#039;, &#039;first&#039;);&lt;br /&gt;
	},&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Images and Icons ===&lt;br /&gt;
&lt;br /&gt;
==== Accessing images from js ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
     // your game resources&lt;br /&gt;
     &lt;br /&gt;
     var my_img = &#039;&amp;lt;img src=&amp;quot;&#039;+g_gamethemeurl+&#039;img/cards.jpg&amp;quot;/&amp;gt;&#039;;&lt;br /&gt;
     &lt;br /&gt;
     // shared resources&lt;br /&gt;
     var my_help_img = &amp;quot;&amp;lt;img class=&#039;imgtext&#039; src=&#039;&amp;quot; + g_themeurl + &amp;quot;img/layout/help_click.png&#039; alt=&#039;action&#039; /&amp;gt; &amp;lt;span class=&#039;tooltiptext&#039;&amp;gt;&amp;quot; +&lt;br /&gt;
                    text + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== High-Definition Graphics ====&lt;br /&gt;
&lt;br /&gt;
Some users will have screens which can display text and images at a greater resolution than the usual 72 dpi, e.g. the &amp;quot;Retina&amp;quot; screens on the 5k iMac, all iPads, and high-DPI screens on laptops from many manufacturers. If you can get art assets at this size, they will make your game look extra beautiful. You &#039;&#039;could&#039;&#039; just use large graphics and scale them down, but that would increase the download time and bandwidth for users who can&#039;t display them. Instead, a good way is to prepare a separate graphics file at exactly twice the size you would use otherwise, and add &amp;quot;@2x&amp;quot; at the end of the filename, e.g. if pieces.png is 240x320, then pieces@2x.png is 480x640.&lt;br /&gt;
&lt;br /&gt;
There are two changes required in order to use the separate graphics files. First in your css, where you use a file, add a media query which overrides the original definition and uses the bigger version on devices which can display them. Ensuring that the &amp;quot;background-size&amp;quot; attribute is set means that the size of the displayed object doesn&#039;t change, but only is drawn at the improved dot pitch.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.piece {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    background-image: url(&#039;img/pieces.png&#039;);&lt;br /&gt;
    background-size:240px 320px;&lt;br /&gt;
    z-index: 10;&lt;br /&gt;
}&lt;br /&gt;
@media (-webkit-min-device-pixel-ratio: 2), (min-device-pixel-ratio: 2), (min-resolution: 192dpi)&lt;br /&gt;
{&lt;br /&gt;
    .piece {&lt;br /&gt;
        background-image: url(&#039;img/pieces@2x.png&#039;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Secondly, in your setup function in javascript, you must ensure than only the appropriate one version of the file gets pre-loaded (otherwise you more than waste the bandwidth saved by maintaining the standard-resolution file). Note that the media query is the same in both cases:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
            var isRetina = &amp;quot;(-webkit-min-device-pixel-ratio: 2), (min-device-pixel-ratio: 2), (min-resolution: 192dpi)&amp;quot;;&lt;br /&gt;
            if (window.matchMedia(isRetina).matches)&lt;br /&gt;
            {&lt;br /&gt;
                this.dontPreloadImage( &#039;pieces.png&#039; );&lt;br /&gt;
                this.dontPreloadImage( &#039;board.jpg&#039; );&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                this.dontPreloadImage( &#039;pieces@2x.png&#039; );&lt;br /&gt;
                this.dontPreloadImage( &#039;board@2x.jpg&#039; );&lt;br /&gt;
            }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using CSS to create different colors of game pieces if you have only white piece ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
background-color: #${color}; &lt;br /&gt;
background-blend-mode: multiply;&lt;br /&gt;
background-image: url( &#039;img/mypiece.png&#039;);&lt;br /&gt;
mask: url(&#039;img/mypiece.png&#039;);&lt;br /&gt;
-webkit-mask: url(&#039;img/mypiece.png&#039;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where ${color} - is color you want&lt;br /&gt;
&lt;br /&gt;
Note: piece has to be white (shades of gray). Sprite can be used too, just add add blackground-position as usuall.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Other Fluff ===&lt;br /&gt;
&lt;br /&gt;
==== Use thematic fonts ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.css&lt;br /&gt;
&lt;br /&gt;
Sometime game elements use specific fonts of text, if you want to match it up you can load some specific font (IMPORTANT: from some &#039;&#039;&#039;free font&#039;&#039;&#039; source. See notes below).&lt;br /&gt;
&lt;br /&gt;
[[File:Dragonline_font.png]]&lt;br /&gt;
&lt;br /&gt;
.css&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* latin-ext */&lt;br /&gt;
@font-face {&lt;br /&gt;
  font-family: &#039;Qwigley&#039;;&lt;br /&gt;
  font-style: normal;&lt;br /&gt;
  font-weight: 400;&lt;br /&gt;
  src: local(&#039;Qwigley&#039;), local(&#039;Qwigley-Regular&#039;), url(https://fonts.gstatic.com/s/qwigley/v6/2Dy1Unur1HJoklbsg4iPJ_Y6323mHUZFJMgTvxaG2iE.woff2) format(&#039;woff2&#039;);&lt;br /&gt;
  unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;&lt;br /&gt;
}&lt;br /&gt;
/* latin */&lt;br /&gt;
@font-face {&lt;br /&gt;
  font-family: &#039;Qwigley&#039;;&lt;br /&gt;
  font-style: normal;&lt;br /&gt;
  font-weight: normal;&lt;br /&gt;
  src: local(&#039;Qwigley&#039;), local(&#039;Qwigley-Regular&#039;), url(https://fonts.gstatic.com/s/qwigley/v6/gThgNuQB0o5ITpgpLi4Zpw.woff2) format(&#039;woff2&#039;);&lt;br /&gt;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;&lt;br /&gt;
}&lt;br /&gt;
@font-face {&lt;br /&gt;
  font-family: &#039;Qwigley&#039;;&lt;br /&gt;
  font-style: normal;&lt;br /&gt;
  font-weight: normal;&lt;br /&gt;
  src: local(&#039;Qwigley&#039;), local(&#039;Qwigley-Regular&#039;), url(http://ff.static.1001fonts.net/q/w/qwigley.regular.ttf) format(&#039;ttf&#039;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.zone_title {&lt;br /&gt;
	display: inline-block;&lt;br /&gt;
	position: absolute;&lt;br /&gt;
	font: italic 32px/32px &amp;quot;Qwigley&amp;quot;, cursive;	   &lt;br /&gt;
	height: 32px;&lt;br /&gt;
	width: auto;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NB:&#039;&#039;&#039; if you need to include a font that&#039;s not available online, an extra action will be needed from an admin. Please include the font file(s) in your img directory, and mention it to admins when requesting your game to be moved to alpha. &#039;&#039;&#039;Please remember that the font has to be free, and include a .txt with all appropriate license information about the font.&#039;&#039;&#039;&lt;br /&gt;
You can look for free fonts (for example) on https://fonts.google.com or https://www.fontsquirrel.com/)&lt;br /&gt;
&lt;br /&gt;
=== Use player color in template ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg_ggg.tpl, ggg.view.php&lt;br /&gt;
&lt;br /&gt;
.view.php:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    function build_page($viewArgs) {&lt;br /&gt;
        // Get players &amp;amp; players number&lt;br /&gt;
        $players = $this-&amp;gt;game-&amp;gt;loadPlayersBasicInfos();&lt;br /&gt;
        $players_nbr = count($players);&lt;br /&gt;
        /**&lt;br /&gt;
         * ********* Place your code below: ***********&lt;br /&gt;
         */&lt;br /&gt;
        &lt;br /&gt;
        // Set PCOLOR to the current player color hex&lt;br /&gt;
        global $g_user;&lt;br /&gt;
        $cplayer = $g_user-&amp;gt;get_id();&lt;br /&gt;
        if (array_key_exists($cplayer, $players)) { // may be not set if spectator&lt;br /&gt;
            $player_color = $players [$cplayer] [&#039;player_color&#039;];&lt;br /&gt;
        } else {&lt;br /&gt;
            $player_color = &#039;ffffff&#039;; // spectator&lt;br /&gt;
        }&lt;br /&gt;
        $this-&amp;gt;tpl [&#039;PCOLOR&#039;] = $player_color;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Scale to fit for big boards ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg_ggg.tpl, ggg.js&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Lets say you have huge game board, and lets say you want it to be 1400px wide. Besides the board there will be side bar which is 240 and trim. &lt;br /&gt;
My display is 1920 wide so it fits, but there is big chance other people won&#039;t have that width. What do you do?&lt;br /&gt;
&lt;br /&gt;
You have to decide:&lt;br /&gt;
* If board does not fit you want scale whole thing down, the best way is probably use viewport (see https://en.doc.boardgamearena.com/Your_game_mobile_version)&lt;br /&gt;
* You can leave the board as is and make sure it is scrollable horizonatally&lt;br /&gt;
* You add custom scale just for the board (can add user controls  - and hook to transform: scale())&lt;br /&gt;
&lt;br /&gt;
I tried to auto-scale but this just does work, too many variables - browser zoom, 3d mode, viewport, custom bga scaling, devicePixelRatio - all create some impossible coctail of zooming...&lt;br /&gt;
Here is scaling functing for custom user scaling&lt;br /&gt;
&lt;br /&gt;
ggg_ggg.tpl:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   &amp;lt;div id=&amp;quot;thething&amp;quot; class=&amp;quot;thething&amp;quot;&amp;gt;&lt;br /&gt;
            ... everything else you declare ...&lt;br /&gt;
   &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ggg.js:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    onZoomPlus: function() {&lt;br /&gt;
       this.my_zoom+=0.1;&lt;br /&gt;
       this.zoommy(&#039;thething&#039;,this.my_zoom);&lt;br /&gt;
    },&lt;br /&gt;
&lt;br /&gt;
    zoommy: function(node, zoom) {&lt;br /&gt;
                node=$(node);&lt;br /&gt;
		var width = 100 / zoom;&lt;br /&gt;
		node.style.transformOrigin = &amp;quot;0 0&amp;quot;;&lt;br /&gt;
		node.style.transform = &amp;quot;scale(&amp;quot; + zoom + &amp;quot;)&amp;quot;;&lt;br /&gt;
		node.style.width = width + &amp;quot;%&amp;quot;;&lt;br /&gt;
    },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Dynamic tooltips ===&lt;br /&gt;
&lt;br /&gt;
If you really need a dynamic tooltip you can use this technique. (Only use it if the static tooltips provided by the BGA framework are not sufficient.)&lt;br /&gt;
&lt;br /&gt;
            new dijit.Tooltip({&lt;br /&gt;
                connectId: [&amp;quot;divItemId&amp;quot;],&lt;br /&gt;
                getContent: function(matchedNode){&lt;br /&gt;
                    return &amp;quot;... calculated ...&amp;quot;; &lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is an out-of-the-box djit.Tooltip. It has a &#039;&#039;getContent&#039;&#039; method which is called dynamically.&lt;br /&gt;
&lt;br /&gt;
The string function return becomes the innerHTML of the tooltip, so it can be anything. In this example matchedNode is a dojo node representing dom object with id of &amp;quot;divItemId&amp;quot; but there are more parameters which I am not posting here which allows more sophisticated subnode queries (i.e. you can attach tooltip to all nodes with class or whatever).&lt;br /&gt;
&lt;br /&gt;
[https://dojotoolkit.org/reference-guide/1.10/dijit/Tooltip.html dijit.Tooltip]&lt;br /&gt;
&lt;br /&gt;
It&#039;s not part of the BGA API so use at your own risk.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Rendering text with players color and proper background ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        /* Implementation of proper colored You with background in case of white or light colors  */&lt;br /&gt;
 &lt;br /&gt;
        divYou: function() {&lt;br /&gt;
            var color = this.gamedatas.players[this.player_id].color;&lt;br /&gt;
            var color_bg = &amp;quot;&amp;quot;;&lt;br /&gt;
            if (this.gamedatas.players[this.player_id] &amp;amp;&amp;amp; this.gamedatas.players[this.player_id].color_back) {&lt;br /&gt;
                color_bg = &amp;quot;background-color:#&amp;quot; + this.gamedatas.players[this.player_id].color_back + &amp;quot;;&amp;quot;;&lt;br /&gt;
            }&lt;br /&gt;
            var you = &amp;quot;&amp;lt;span style=\&amp;quot;font-weight:bold;color:#&amp;quot; + color + &amp;quot;;&amp;quot; + color_bg + &amp;quot;\&amp;quot;&amp;gt;&amp;quot; + __(&amp;quot;lang_mainsite&amp;quot;, &amp;quot;You&amp;quot;) + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
            return you;&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
        /* Implementation of proper colored player name with background in case of white or light colors  */&lt;br /&gt;
&lt;br /&gt;
        divColoredPlayer: function(player_id) {&lt;br /&gt;
            var color = this.gamedatas.players[player_id].color;&lt;br /&gt;
            var color_bg = &amp;quot;&amp;quot;;&lt;br /&gt;
            if (this.gamedatas.players[player_id] &amp;amp;&amp;amp; this.gamedatas.players[player_id].color_back) {&lt;br /&gt;
                color_bg = &amp;quot;background-color:#&amp;quot; + this.gamedatas.players[player_id].color_back + &amp;quot;;&amp;quot;;&lt;br /&gt;
            }&lt;br /&gt;
            var div = &amp;quot;&amp;lt;span style=\&amp;quot;color:#&amp;quot; + color + &amp;quot;;&amp;quot; + color_bg + &amp;quot;\&amp;quot;&amp;gt;&amp;quot; + this.gamedatas.players[player_id].name + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
            return div;&lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Cool realistic shadow effect with CSS ===&lt;br /&gt;
&lt;br /&gt;
==== Rectangles and circles ====&lt;br /&gt;
&lt;br /&gt;
It is often nice to have a drop shadow around tiles and tokens, to separate them from the table visually. It is very easy to add a shadow to rectangular elements, just add this to your css:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.xxx-tile {&lt;br /&gt;
    box-shadow: 3px 3px 3px #000000a0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
box-shadow obeys &#039;&#039;&#039;border-radius&#039;&#039;&#039; of the element, so it will look good for rounded rectangles, and hence also circles (if border-radius is set appropriately).&lt;br /&gt;
&lt;br /&gt;
box-shadow also supports various other parameters and can be used to achieve effects such as glowing, borders, inner shadows etc. If you need to animate a box-shadow, you may be able to get better performance (avoiding redraws) if you attach the shadow to another element (possibly an ::after pseudo-element) and change only the &#039;&#039;&#039;opacity&#039;&#039;&#039; of that element.&lt;br /&gt;
&lt;br /&gt;
==== Irregular Shapes ====&lt;br /&gt;
&lt;br /&gt;
If you wish to make a shadow effect for game pieces that are not a rectangle, but your game pieces are drawn from rectangles in a PNG image, you can apply the shadow to the piece using any art package and save it inside the image. This usually will yield the best performance. Remember to account for the size of the shadow when you lay out images in the sprite sheet.&lt;br /&gt;
&lt;br /&gt;
However that sometimes will not be an option, for example if the image needs to be rotated while the shadow remains offset in the same direction. In this case, one option is to not use box-shadow but use filter, which is supported by recent major browsers.  This way, you can use the alpha channel of your element to drop a shadow.  This even work for transparent backgrounds, so that if you are using the &amp;quot;CSS-sprite&amp;quot; method, it will work!&lt;br /&gt;
&lt;br /&gt;
For instance:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.xxx-token {&lt;br /&gt;
    filter: drop-shadow(0px 0px 1px #000000);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beware that some browsers still do not always draw drop-shadow correctly. In particular, Safari frequently leaves bits of shadow behind when objects move around the screen. In Chrome, shadows sometimes flicker badly if another element is animating close by. Some of these correctness issues can be solved by adding &#039;&#039;&#039;isolation: isolate; will-change: filter;&#039;&#039;&#039; to affected elements, but this significantly affects redraw performance.&lt;br /&gt;
&lt;br /&gt;
Beware of performance issues - particularly on Safari (MacOS, iPhone and iPad). Keep in mind that drop-shadow are very GPU intensive. This becomes noticeable once you have about 40 components with drop-shadow filter. If that is your case, you can quite easily implement a user preference to disable shadows for users on slower machines:&lt;br /&gt;
&lt;br /&gt;
gameoptions.inc.php&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
100 =&amp;gt; array(&lt;br /&gt;
			&#039;name&#039; =&amp;gt; totranslate(&#039;Shadows&#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;Enabled&#039; ), &#039;cssPref&#039; =&amp;gt; &#039;&#039; ),&lt;br /&gt;
					2 =&amp;gt; array( &#039;name&#039; =&amp;gt; totranslate( &#039;Disabled&#039; ), &#039;cssPref&#039; =&amp;gt; &#039;no-shadow&#039; )&lt;br /&gt;
			)&lt;br /&gt;
	),&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[game].css&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.no-shadow * {&lt;br /&gt;
	filter: none !important; &lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Shadows with clip-path ====&lt;br /&gt;
&lt;br /&gt;
For some reason, a shadow will not work together with clip-path on one element. To use both clip-path (when for example using .svg to cut out cardboard components from your .jpg spritesheet) and drop-shadow, you need to wrap the element into another one, and apply drop-shadow to the outer one, and clip-path to the inner one.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;div class=&#039;my-token-wrap&#039;&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&#039;my-token&#039;&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;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.my-token-wrap {&lt;br /&gt;
    filter: drop-shadow(0px 0px 1px #000000);&lt;br /&gt;
}&lt;br /&gt;
.my-token-wrap .my-token {&lt;br /&gt;
    clip-path: url(#my-token-path);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Using the CSS classes from the state machine ===&lt;br /&gt;
&lt;br /&gt;
If you need to hide or show stuff depending on the state of your game, you can of course use javascript, but CSS is hand enough for that.  The #overall-content element does change class depending on the game state.  For instance, if you are in state &#039;&#039;playerTurn&#039;&#039;, it will have the class &#039;&#039;gamestate_playerTurn&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
So now, if you want to show the discard pile only during player turns, you may use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#discard_pile { display: none }&lt;br /&gt;
.gamestate_playerTurn #discard_pile { display: block }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This can be used if you want to change sizing of elements, position, layout or visual appearance.&lt;br /&gt;
&lt;br /&gt;
== Game Model and Database design ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Database for The euro game ===&lt;br /&gt;
Lets say we have a game with workers, dice, tokens, board, resources, money and vp. Workers and dice can be placed in various zones on the board, and you can get resources, money, tokens and vp in your home zone. Also tokens can be flipped or not flipped.&lt;br /&gt;
&lt;br /&gt;
[[File:Madeira board.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now lets try to map it, we have&lt;br /&gt;
* (meeple,zone)&lt;br /&gt;
* (die, zone, sideup)&lt;br /&gt;
* (resource cube/money token/vp token,player home zone)&lt;br /&gt;
* (token, player home zone, flip state)&lt;br /&gt;
We can notice that resource and money are uncountable, and don&#039;t need to be track individually so we can replace our mapping to&lt;br /&gt;
* (resource type/money,player home zone, count)&lt;br /&gt;
And vp stored already for us in player table, so we can remove it from that list.&lt;br /&gt;
&lt;br /&gt;
Now when we get to encode it we can see that everything can be encoded as (object,zone,state) form, where object and zone is string and state is integer. The resource mapping is slightly different semantically so you can go with two table, or counting using same table with state been used as count for resources.&lt;br /&gt;
&lt;br /&gt;
So the piece mapping for non-grid based games can be in most case represented by (string: token_key, string: token_location, int: token_state), example of such database schema can be found here: [https://github.com/elaskavaia/bga-sharedcode/blob/master/dbmodel.sql dbmodel.sql] and class implementing access to it here [https://github.com/elaskavaia/bga-sharedcode/blob/master/modules/tokens.php table.game.php].&lt;br /&gt;
&lt;br /&gt;
Variant 1: Minimalistic&lt;br /&gt;
&lt;br /&gt;
 CREATE TABLE IF NOT EXISTS `token` (&lt;br /&gt;
  `token_key` varchar(32) NOT NULL,&lt;br /&gt;
  `token_location` varchar(32) NOT NULL,&lt;br /&gt;
  `token_state` int(10),&lt;br /&gt;
  PRIMARY KEY (`token_key`)&lt;br /&gt;
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+token&lt;br /&gt;
! token_key&lt;br /&gt;
! token_location&lt;br /&gt;
! token_state&lt;br /&gt;
|-&lt;br /&gt;
|meeple_red_1&lt;br /&gt;
|home_red&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
|dice_black_2&lt;br /&gt;
|board_guard&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
|dice_green_1&lt;br /&gt;
|board_action_mayor&lt;br /&gt;
|3&lt;br /&gt;
|-&lt;br /&gt;
|bread&lt;br /&gt;
|home_red&lt;br /&gt;
|5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Now how we represent resource counters such as bread?&lt;br /&gt;
Using same table from we simply add special counter token for bread and use state to indicate the count. Note to keep first column unique we have to add player identification for that counter, i.e. ff0000 is red player.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+token&lt;br /&gt;
! token_key&lt;br /&gt;
! token_location&lt;br /&gt;
! token_state&lt;br /&gt;
|-&lt;br /&gt;
|bread_ff0000&lt;br /&gt;
|tableau_ff0000&lt;br /&gt;
|5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See php module for this table here https://github.com/elaskavaia/bga-sharedcode/blob/master/modules/tokens.php&lt;br /&gt;
&lt;br /&gt;
Variant 2: Additional resource table, resource count for each player id&lt;br /&gt;
&lt;br /&gt;
 CREATE TABLE IF NOT EXISTS `resource` (&lt;br /&gt;
  `player_id` int(10) unsigned NOT NULL,&lt;br /&gt;
  `resource_key` varchar(32) NOT NULL,&lt;br /&gt;
  `resource_count` int(10) signed NOT NULL,&lt;br /&gt;
  PRIMARY KEY (`player_id`,`resource_key`)&lt;br /&gt;
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;&lt;br /&gt;
&lt;br /&gt;
 ALTER TABLE resource ADD CONSTRAINT fk_player_id FOREIGN KEY (player_id) REFERENCES player(player_id);&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+resource&lt;br /&gt;
! player_id&lt;br /&gt;
! resource_key&lt;br /&gt;
! resource_count&lt;br /&gt;
|-&lt;br /&gt;
|123456&lt;br /&gt;
|bread&lt;br /&gt;
|5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Variant 3: More normalised&lt;br /&gt;
&lt;br /&gt;
This version is similar to &amp;quot;card&amp;quot; table from hearts tutorial, you can also use exact cards database schema and Deck implementation for most purposes (even you not dealing with cards). &lt;br /&gt;
&lt;br /&gt;
 CREATE TABLE IF NOT EXISTS `token` (&lt;br /&gt;
  `token_id` int(10) unsigned NOT NULL AUTO_INCREMENT,&lt;br /&gt;
  `token_type` varchar(16) NOT NULL,&lt;br /&gt;
  `token_arg` int(11) NOT NULL,&lt;br /&gt;
  `token_location` varchar(32) NOT NULL,&lt;br /&gt;
  `token_state` int(10),&lt;br /&gt;
  PRIMARY KEY (`token_id`)&lt;br /&gt;
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+token&lt;br /&gt;
! token_id&lt;br /&gt;
! token_type&lt;br /&gt;
! token_arg&lt;br /&gt;
! token_location&lt;br /&gt;
! token_state&lt;br /&gt;
|-&lt;br /&gt;
|22&lt;br /&gt;
|meeple&lt;br /&gt;
|123456&lt;br /&gt;
|home_123456&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
|23&lt;br /&gt;
|dice&lt;br /&gt;
|2&lt;br /&gt;
|board_guard&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
|26&lt;br /&gt;
|dice&lt;br /&gt;
|1&lt;br /&gt;
|board_action_mayor&lt;br /&gt;
|3&lt;br /&gt;
|-&lt;br /&gt;
|49&lt;br /&gt;
|bread&lt;br /&gt;
|0&lt;br /&gt;
|home_123456&lt;br /&gt;
|5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Advantages of this would be is a bit more straightforward to do some queries in db, disadvantage its hard to read (as you can compare with previous example, you&lt;br /&gt;
cannot just look at say, ah I know what it means). Another questionable advantage is it allows you to do id randomisation, so it hard to do crafted queries to &lt;br /&gt;
cheat, the down side of that you cannot understand it either, and handcraft db states for debugging or testing.&lt;br /&gt;
&lt;br /&gt;
=== Database for The card game ===&lt;br /&gt;
&lt;br /&gt;
Lets say you have a standard card game, player have hidden cards in hand, you can draw card from draw deck, play card on tableau and discard to discard pile.&lt;br /&gt;
We have to design database for such game.&lt;br /&gt;
&lt;br /&gt;
In real word to &amp;quot;save&amp;quot; the game we take a picture a play area, save cards from it, then put away draw deck, discard and hand of each player separately and mark it, also we will record current scoring (if any) and who&#039;s turn was it.&lt;br /&gt;
&lt;br /&gt;
* Framework handles state machine transition, so you don&#039;t have to worry about database design for that (i.e. who&#039;s turn it is, what phase of the game we are at, you still have to design it but part of state machine step)&lt;br /&gt;
* Also framework supports basic player information, color, order around the table, basic scoring, etc, so you don&#039;t have to worry about it either&lt;br /&gt;
* The only thing you need in our database is state of the &amp;quot;board&amp;quot;, which is &amp;quot;where each pieces is, and in what state&amp;quot;, or (position,rotation) pair.&lt;br /&gt;
&lt;br /&gt;
Lets see what we have for that:&lt;br /&gt;
* The card state is very simple, its usually &amp;quot;face up/face down&amp;quot;, &amp;quot;tapped/untapped&amp;quot;, &amp;quot;right side up/up side down&amp;quot;&lt;br /&gt;
* As position go we never need real coordinates x,y,z. We need to know what &amp;quot;zone&amp;quot; card was, and depending on the zone it may sometimes need an extra &amp;quot;z&amp;quot; or &amp;quot;x&amp;quot; as card order. The zone position usually static or irrelevant.&lt;br /&gt;
* So our model is: we have cards, which have some attributes, at any given point in time they belong to a &amp;quot;zone&amp;quot;, and can also have order and state&lt;br /&gt;
* Now for mapping we should consider what information changes and what information is static, later is always candidate for material file&lt;br /&gt;
* For dynamic information we should try to reduce amount of fields we need&lt;br /&gt;
**  we need at least a field for card, so its one&lt;br /&gt;
**  we need to know what zone cards belong to, its 2&lt;br /&gt;
**  and we have possibly few other fields, if you look closely at you game you may find out that most of the zone only need one attribute at a time, i.e. draw pile always have cards face down, hand always face up, also for hand and discard order does not matter at all (but for draw it does matter). So in majority of cases we can get away with one single extra integer field representing state or order&lt;br /&gt;
* In real database both card and zone will be integers as primary keys referring to additional tables, but in our case its total overkill, so they can be strings as easily&lt;br /&gt;
&lt;br /&gt;
Variant 1: Minimalistic&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE TABLE IF NOT EXISTS `card` (&lt;br /&gt;
  `card_key` varchar(32) unsigned NOT NULL,&lt;br /&gt;
  `card_location` varchar(32) NOT NULL,&lt;br /&gt;
  `card_state` int(11) NOT NULL,&lt;br /&gt;
  PRIMARY KEY (`card_id`)&lt;br /&gt;
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Variant 2: More normalised&lt;br /&gt;
&lt;br /&gt;
This version supported by Deck php class, so unless you want to rewrite db access layer go with this one&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE TABLE IF NOT EXISTS `card` (&lt;br /&gt;
  `card_id` int(10) unsigned NOT NULL AUTO_INCREMENT,&lt;br /&gt;
  `card_type` varchar(16) NOT NULL,&lt;br /&gt;
  `card_type_arg` int(11) NOT NULL,&lt;br /&gt;
  `card_location` varchar(16) NOT NULL,&lt;br /&gt;
  `card_location_arg` int(11) NOT NULL,&lt;br /&gt;
  PRIMARY KEY (`card_id`)&lt;br /&gt;
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: if you using this schema, some zones/locations have special semantic. The &#039;hand&#039; location is actually multiple locations - one per player, but player id is encoded as card_location_arg. If &#039;hand&#039; in your game is ordered, visible or can have some other card states, you cannot use hand location (replacement is hand_&amp;lt;player_id&amp;gt; or hand_&amp;lt;color_id&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
== Code Organization ==&lt;br /&gt;
&lt;br /&gt;
=== Including your own JavaScript module ===&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, modules/ggg_other.js&lt;br /&gt;
&lt;br /&gt;
* Create ggg_other.js in modules/ folder and sync&lt;br /&gt;
* Modify ggg.js to include it&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  define([ &amp;quot;dojo&amp;quot;, &amp;quot;dojo/_base/declare&amp;quot;, &amp;quot;ebg/core/gamegui&amp;quot;, &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
    // load my own module!!!&lt;br /&gt;
    g_gamethemeurl + &amp;quot;modules/ggg_other.js&amp;quot; ], function(dojo,&lt;br /&gt;
        declare) {&lt;br /&gt;
&lt;br /&gt;
=== Including your own JavaScript module (II) ===&lt;br /&gt;
&lt;br /&gt;
* Create ggg_other.js in modules/ folder and sync&lt;br /&gt;
&lt;br /&gt;
  define([], function () {&lt;br /&gt;
    return &amp;quot;value&amp;quot;;&lt;br /&gt;
  });&lt;br /&gt;
&lt;br /&gt;
* Modify ggg.js to include it&lt;br /&gt;
&lt;br /&gt;
  define([ &lt;br /&gt;
    &amp;quot;dojo&amp;quot;, &lt;br /&gt;
    &amp;quot;dojo/_base/declare&amp;quot;, &lt;br /&gt;
    &amp;quot;bgagame/modules/ggg_other&amp;quot;, &lt;br /&gt;
    &amp;quot;ebg/core/gamegui&amp;quot;, &lt;br /&gt;
    &amp;quot;ebg/counter&amp;quot;&lt;br /&gt;
  ], function(dojo, declare, other) {&lt;br /&gt;
  &lt;br /&gt;
  });&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
This is maybe a little bit more the idea of the AMD Loader than the first option, although the first option should work as well.&lt;br /&gt;
&lt;br /&gt;
A little explanation to this:&lt;br /&gt;
The define function loads all the modules listed in the array and calls the following function with these loaded modules as parameters.&lt;br /&gt;
By putting your module at the third position in the array it is passed as the third parameter to the function. Be aware that the modules are resolved by position only, not by name. So you can load the module &#039;&#039;&#039;ggg_other&#039;&#039;&#039; and pass it as a parameter with the name &#039;&#039;&#039;other&#039;&#039;&#039;. &#039;&#039;&#039;gamegui&#039;&#039;&#039; and &#039;&#039;&#039;counter&#039;&#039;&#039; are passed in as well, but when the parameters are not defined they are just skipped. Because these modules put their content into the global scope it does not matter and you can use them from there.&lt;br /&gt;
&lt;br /&gt;
In the example above the string &amp;quot;value&amp;quot; is passed for the parameter &#039;&#039;&#039;other&#039;&#039;&#039;, but the function in your module can return whatever you want. It can be an object, an array, something you declared with dojo.declare, you can return even functions. &lt;br /&gt;
Your module can load other modules. Just put them in the array at the beginning and pass them as parameters to your function.&lt;br /&gt;
The advantage of passing the values as parameter is that you do not need to put these values in the global scope, so they can&#039;t be collisions with values defined in other scripts or the BGA Framework.&lt;br /&gt;
&lt;br /&gt;
The dojo toolkit provides good documentation to all of its components, the complete documentation for the AMD-Loader is here:&lt;br /&gt;
https://dojotoolkit.org/documentation/tutorials/1.10/modules/index.html It should be still correct, even as it seems to be only for version 1.10&lt;br /&gt;
&lt;br /&gt;
=== Including your own PHP module ===&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.game.php, modules/ggg_other.php&lt;br /&gt;
&lt;br /&gt;
* Create ggg_other.php in modules/ folder and sync&lt;br /&gt;
* Modify ggg.game.php to include it&lt;br /&gt;
&lt;br /&gt;
 require_once (&#039;modules/ggg_other.php&#039;);&lt;br /&gt;
&lt;br /&gt;
=== Creating a test class to run PHP locally ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.game.php, stubs&lt;br /&gt;
For this you need stubs of other method you can use this for example&lt;br /&gt;
https://github.com/elaskavaia/bga-sharedcode/raw/master/misc/module/table/table.game.php&lt;br /&gt;
&lt;br /&gt;
Create another php files, i.e ggg_test.php&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
define(&amp;quot;APP_GAMEMODULE_PATH&amp;quot;, &amp;quot;misc/&amp;quot;); // include path to stubs, which defines &amp;quot;table.game.php&amp;quot; and other classes&lt;br /&gt;
require_once (&#039;eminentdomaine.game.php&#039;);&lt;br /&gt;
&lt;br /&gt;
class MyGameTest1 extends MyGame { // this is your game class defined in ggg.game.php&lt;br /&gt;
    function __construct() {&lt;br /&gt;
        parent::__construct();&lt;br /&gt;
        include &#039;../material.inc.php&#039;;// this is how this normally included, from constructor&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // override/stub methods here that access db and stuff&lt;br /&gt;
    function getGameStateValue($var) {&lt;br /&gt;
        if ($var == &#039;round&#039;)&lt;br /&gt;
            return 3;&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
$x = new MyGameTest1(); // instantiate your class&lt;br /&gt;
$p = $x-&amp;gt;getGameProgression(); // call one of the methods to test&lt;br /&gt;
if ($p != 50)&lt;br /&gt;
    echo &amp;quot;Test1: FAILED&amp;quot;;&lt;br /&gt;
else&lt;br /&gt;
    echo &amp;quot;Test1: PASSED&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Run from command line like&lt;br /&gt;
 php7 ggg_test.php&lt;br /&gt;
&lt;br /&gt;
If you do it this way - you can also use local php debugger (i.e. integrated with IDE or command line).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Avoiding code in dojo declare style ===&lt;br /&gt;
Dojo class declarations are rather bizzare and do not work with most IDEs.&lt;br /&gt;
If you want to write in plain JS with classes, you can stub all the dojo define/declare stuff&lt;br /&gt;
and hook your class into that, so the classes are outside of this mess.&lt;br /&gt;
&lt;br /&gt;
NOTE: this technique is for experienced developers, do not try it if you do not understand&lt;br /&gt;
the consequences.&lt;br /&gt;
&lt;br /&gt;
This is complete example of game .js class&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  // Testla is game name is has to be changed&lt;br /&gt;
class Testla {&lt;br /&gt;
	constructor(game) {&lt;br /&gt;
		console.log(&#039;game constructor&#039;);&lt;br /&gt;
		this.game = game;&lt;br /&gt;
		this.varfoo = new MyFoo(); // this example of class from custom module&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	setup(gamedatas) {&lt;br /&gt;
		console.log(&amp;quot;Starting game setup&amp;quot;, this.varfoo);&lt;br /&gt;
		this.gamedatas = gamedatas;&lt;br /&gt;
		this.dojo.create(&amp;quot;div&amp;quot;, { class: &#039;whiteblock&#039;, innerHTML: _(&amp;quot;hello&amp;quot;) }, &#039;thething&#039;);&lt;br /&gt;
		console.log(&amp;quot;Ending game setup&amp;quot;);&lt;br /&gt;
	};&lt;br /&gt;
	onEnteringState(stateName, args) {&lt;br /&gt;
		console.log(&#039;onEnteringState : &#039; + stateName, args);&lt;br /&gt;
		this.game.addActionButton(&#039;b1&#039;,_(&#039;Click Me&#039;), (e)=&amp;gt;this.onButtonClick(e));&lt;br /&gt;
	};&lt;br /&gt;
	onLeavingState(stateName) {&lt;br /&gt;
		console.log(&#039;onLeavingState : &#039; + stateName, args);&lt;br /&gt;
	};&lt;br /&gt;
	onUpdateActionButtons(stateName, args) {&lt;br /&gt;
		console.log(&#039;onUpdateActionButtons : &#039; + stateName, args);&lt;br /&gt;
	};&lt;br /&gt;
	onButtonClick(event) {&lt;br /&gt;
		console.log(&#039;onButtonClick&#039;,event);&lt;br /&gt;
	};&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&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;
	g_gamethemeurl + &#039;/modules/foo.js&#039; // custom module if needed&lt;br /&gt;
],&lt;br /&gt;
	function(dojo, declare) {&lt;br /&gt;
                // testla is game name is has to be changed&lt;br /&gt;
		return declare(&amp;quot;bgagame.testla&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
			constructor: function() {&lt;br /&gt;
				this.xapp = new Testla(this);&lt;br /&gt;
				this.xapp.dojo = dojo;&lt;br /&gt;
			},&lt;br /&gt;
			setup: function(gamedatas) {&lt;br /&gt;
				this.xapp.setup(gamedatas);&lt;br /&gt;
			},&lt;br /&gt;
			onEnteringState: function(stateName, args) {&lt;br /&gt;
				this.xapp.onEnteringState(stateName, args?.args);&lt;br /&gt;
			},&lt;br /&gt;
			onLeavingState: function(stateName) {&lt;br /&gt;
				this.xapp.onLeavingState(stateName, args);&lt;br /&gt;
			},&lt;br /&gt;
			onUpdateActionButtons: function(stateName, args) {&lt;br /&gt;
				this.xapp.onUpdateActionButtons(stateName, args);&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;
=== More readable JS: onEnteringState ===&lt;br /&gt;
&lt;br /&gt;
If you have a lot of states onEnteringState and friends become rather wild, you can do this trick to call some method dynamically.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
     onEnteringState: function(stateName, args) {&lt;br /&gt;
       console.log(&#039;Entering state: &#039; + stateName, args);&lt;br /&gt;
&lt;br /&gt;
       // Call appropriate method&lt;br /&gt;
       var methodName = &amp;quot;onEnteringState_&amp;quot; + stateName;&lt;br /&gt;
       if (this[methodName] !== undefined) {             &lt;br /&gt;
          console.log(&#039;Calling &#039; + methodName, args.args);&lt;br /&gt;
          this[methodName](args.args);&lt;br /&gt;
       }&lt;br /&gt;
     },&lt;br /&gt;
&lt;br /&gt;
     onEnteringState_playerTurn: function(args) { // this is args directly, not args.args &lt;br /&gt;
         // process&lt;br /&gt;
     },&lt;br /&gt;
&lt;br /&gt;
     onEnteringState_playerSomethingElse: function(args) { &lt;br /&gt;
         // process&lt;br /&gt;
     },&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: since its ignores the undefined functions you don&#039;t have define function for each state, but on the other hand you cannot make typos.&lt;br /&gt;
Same applies to onUpdateActionButtons except you pass &#039;args&#039; to method, not args.args, and for onLeavingState where you don&#039;t pass anything.&lt;br /&gt;
&lt;br /&gt;
=== Frameworks and Preprocessors ===&lt;br /&gt;
&lt;br /&gt;
* [[Using Vue]] - work-in-progress guide on using the modern framework Vue.js to create a game&lt;br /&gt;
* [[Using Typescript and Scss]] - How to auto-build Typescript and SCSS files to make your code cleaner&lt;br /&gt;
&lt;br /&gt;
== Assorted Stuff ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Out-of-turn actions: Un-pass ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, ggg.game.php, ggg.action.php, states.inc.php&lt;br /&gt;
&lt;br /&gt;
In multiplayer game sometimes players passes but than they think more and want to un-Pass and redo their choice. &lt;br /&gt;
To re-active a player who passes some trickery required.&lt;br /&gt;
&lt;br /&gt;
Define a special action that does that and hook it up.&lt;br /&gt;
&lt;br /&gt;
In states.inc.php add an action to mmultipleactiveplayer state to &amp;quot;unpass&amp;quot;, lets call it &amp;quot;actionCancel&amp;quot;&lt;br /&gt;
&lt;br /&gt;
In ggg.action.php add action hook&lt;br /&gt;
    public function actionCancel() {&lt;br /&gt;
        self::setAjaxMode();&lt;br /&gt;
        $this-&amp;gt;game-&amp;gt;actionCancel();&lt;br /&gt;
        self::ajaxResponse();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
In ggg.game.php add action handler&lt;br /&gt;
    function actionCancel() {&lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;checkPossibleAction(&#039;actionCancel&#039;);&lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;setPlayersMultiactive(array ($this-&amp;gt;getCurrentPlayerId() ), &#039;error&#039;, false);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
Finally to call this in client ggg.js you would do something like:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 onUpdateActionButtons:  function(stateName, args) {&lt;br /&gt;
   if (this.isCurrentPlayerActive()) { &lt;br /&gt;
     // ...&lt;br /&gt;
   } else if (!this.isSpectator) { // player is NOT active but not spectator&lt;br /&gt;
       switch (stateName) {&lt;br /&gt;
          case &#039;playerTurnMuliPlayerState&#039;:&lt;br /&gt;
		this.addActionButton(&#039;button_unpass&#039;, _(&#039;Oh no!&#039;), &#039;onUnpass&#039;);&lt;br /&gt;
		break;&lt;br /&gt;
	}&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
				&lt;br /&gt;
 onUnpass: function(e) {&lt;br /&gt;
    this.ajaxcall(&amp;quot;/&amp;quot; + this.game_name + &amp;quot;/&amp;quot; +  this.game_name + &amp;quot;/actionCancel.html&amp;quot;, {}, this); // no checkAction!&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Although be careful that if the turn comes back to the player while he is about to click cancel, the action buttons will be updated and the player will misclick which can be quite frustrating. To avoid this, move the cancel button to another position, like to the left of pagemaintitletext:&lt;br /&gt;
  dojo.place(&#039;button_unpass&#039;, &#039;pagemaintitletext&#039;, &#039;before&#039;);&lt;br /&gt;
Being out of the generalactions div, it won&#039;t be automatically destroyed like normal buttons, so you&#039;ll have to handle that yourself in onLeavingState. You might also want to change the button color to red (blue buttons for active player only, red buttons also for inactive players?)&lt;br /&gt;
&lt;br /&gt;
Note: same technique can be used to do other out-of-turn actions, such as re-arranging cards in hand, exchanging resources, etc (i.e. if permitted by rules, such as &amp;quot;at any time player can...&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
=== Multi Step Interactions: Select Worker/Place Worker - Using Selection ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
Simple way to implement something like that without extra states is to use &amp;quot;selection&amp;quot; mechanism. When user click on worker add some sort of class into that element i.e. &#039;selected&#039; (which also have to have some indication by css i.e. outline).&lt;br /&gt;
&lt;br /&gt;
Than user can click on placement zone, you can use dojo.query for &amp;quot;selected&amp;quot; element and use it along with zone id to send data to server. If proper worker is not selected yet can give a error message using this.showMessage(...) function.&lt;br /&gt;
&lt;br /&gt;
Extra code required to properly cleanup selection between states.&lt;br /&gt;
Also when you do that sometimes you want to change the state prompt, see below &#039;Change state prompt&#039;&lt;br /&gt;
&lt;br /&gt;
=== Multi Step Interactions: Select Worker/Place Worker - Using Client States ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
I don&#039;t think its documented feature but there is a way to do client-only states, which is absolutely wonderful for few reasons&lt;br /&gt;
* When player interaction is two step process, such as select worker, place worker, or place worker, pick one of two resources of your choice&lt;br /&gt;
* When multi-step process can result of impossible situation and has to be undone (by rules)&lt;br /&gt;
* When multi-step process is triggered from multiple states (such as you can do same thing as activated card action, pass action or main action)&lt;br /&gt;
&lt;br /&gt;
So lets do Select Worker/Place Worker&lt;br /&gt;
&lt;br /&gt;
Define your server state as usual, i.e. playerMainTurn -&amp;gt; &amp;quot;You must pick up a worker&amp;quot;.&lt;br /&gt;
Now define a client state, we only need &amp;quot;name&amp;quot; and &amp;quot;descriptionmyturn&amp;quot;, lets say &amp;quot;client_playerPicksLocation&amp;quot;. Always prefix names of client state with &amp;quot;client_&amp;quot; to avoid confusion. Now we have to do the following:&lt;br /&gt;
* Have a handler for onUpdateActionButtons for playerMainTurn to activate all possible workers he can pick&lt;br /&gt;
* When player clicks workers, remember the worker in one of the members of the main class, I usually use one called this.clientStateArgs.&lt;br /&gt;
* Transition to new client state&lt;br /&gt;
  onWorker: function(e) {&lt;br /&gt;
      var id = event.currentTarget.id;&lt;br /&gt;
      dojo.stopEvent(event);&lt;br /&gt;
      ... // do validity checks&lt;br /&gt;
      this.clientStateArgs.worker_id = id;&lt;br /&gt;
      this.setClientState(&amp;quot;client_playerPicksLocation&amp;quot;, {&lt;br /&gt;
                                descriptionmyturn : _(&amp;quot;${you} must select location&amp;quot;),&lt;br /&gt;
                            });&lt;br /&gt;
   }&lt;br /&gt;
* Have a handler for onUpdateActionButtons for client_playerPicksLocation to activate all possible locations this worker can go AND add Cancel button (see below)&lt;br /&gt;
* Have a location handler which will eventually send a server request, using stored this.clientStateArgs.worker_id as worker id&lt;br /&gt;
* The cancel button should call a method to restore server state, also if you doing it for more than one state you can add this universally using this.on_client_state check&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        if (this.isCurrentPlayerActive()) {&lt;br /&gt;
          if (this.on_client_state &amp;amp;&amp;amp; !$(&#039;button_cancel&#039;)) {&lt;br /&gt;
               this.addActionButton(&#039;button_cancel&#039;, _(&#039;Cancel&#039;), dojo.hitch(this, function() {&lt;br /&gt;
                                             this.restoreServerGameState();&lt;br /&gt;
               }));&lt;br /&gt;
          }&lt;br /&gt;
        } &lt;br /&gt;
Note: usually I call my own function call this.cancelLocalStateEffects() which will do more stuff first then call restoreServerGameState(), same function is usually needs to be called when server request has failed (i.e. invalid move)&lt;br /&gt;
&lt;br /&gt;
Note: If you need more than 2 steps, you may have to do client side animation to reflect the new state, which gets trickier because you have to undo that also on cancellation.&lt;br /&gt;
&lt;br /&gt;
Code is available here [https://github.com/elaskavaia/bga-sharedcode/blob/master/sharedcode.js sharedcode.js] (its using playerTurnPlayCubes and client_selectCubeLocation).&lt;br /&gt;
&lt;br /&gt;
=== Action Stack - Using Client States ===&lt;br /&gt;
&lt;br /&gt;
Action stack required where game is very complex and use triggered effects that can &amp;quot;stack&amp;quot;. It not always actual stack, it can be queue or random access&lt;br /&gt;
Examples:&lt;br /&gt;
* Magic the Gathering - classic card game where effects go on Stack, that allows to counter spell and counter spell of counter spell (not on bga - it just example of mechanics)&lt;br /&gt;
* Ultimate Railroads - action taking game where effects can be executed in any order&lt;br /&gt;
* Lewis and Clark - card game where actions executed as queue&lt;br /&gt;
&lt;br /&gt;
There is two ways of implementing it - on the server or the client.&lt;br /&gt;
For the server see article below.&lt;br /&gt;
The requirement for client side stack is all action can be undone, which means&lt;br /&gt;
* No dice rolls&lt;br /&gt;
* No card drawn&lt;br /&gt;
* No other players interaction&lt;br /&gt;
&lt;br /&gt;
No snippets are here, as this will be too complex but basically flow is:&lt;br /&gt;
* You have a action/effect stack (queue/list) as js object attached to &amp;quot;this&amp;quot;, i.e. this.unprocessed_actions&lt;br /&gt;
* When player plays a card, worker, etc, you read the effect of that card from the material file (client copy), and place into stack&lt;br /&gt;
* Then we call dispatch method which pulls the next action from the stack and change client state accordinly,i.e.  this.setClientState(&amp;quot;client_playerGainsCubes&amp;quot;)&lt;br /&gt;
* When players acts on it - the action is removed from the stack and added to &amp;quot;server action arguments&amp;quot; list, this is another object which be used to send ajax call, i.e. this.clientStateArgs&lt;br /&gt;
* If nothing left in stack we can submit the ajax call assembling parameters from collected arguments (that can include action name)&lt;br /&gt;
* This method allows cheap undo - by restoring server state you will wipe out all user actions (but if you need intermediate aninmation you have to handle it yourself)&lt;br /&gt;
&lt;br /&gt;
Code can be found in Ultimate Railroads game (but it is random access list - so it a bit complex) and Lewis and Clark (complexity - use can always deny part of any effect)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Action Stack - Using Server States ===&lt;br /&gt;
&lt;br /&gt;
See definition of Action Stack above.&lt;br /&gt;
&lt;br /&gt;
To implement you usually need another db table that has the following fields: index of effect - which is used for sorted access, type - which is essense of the effect (i.e. collect resource), some extra arguments (i.e. resource type and resource count), and usually owner of the effect (i.e. player id)&lt;br /&gt;
The flow is:&lt;br /&gt;
* There is some initial player state, where player can play card for example&lt;br /&gt;
* Player main action - pushes the card effect on stack, which also can cause triggered effects which also go on stack&lt;br /&gt;
* After action processing is finished switch to game state which is &amp;quot;dispatcher&amp;quot;&lt;br /&gt;
* Gispatcher pulls the top effect (whatever definition of the top is), changes the active player and changes the state to appropriate player state to collect response&lt;br /&gt;
* Player state knows about the stack and pulls arguments (argX) from the effect arguments of the db&lt;br /&gt;
* Player action should clear up the top effect, and can possibly add more effects, then switch to &amp;quot;dispatcher&amp;quot; state again&lt;br /&gt;
* If stack is empty, dispatcher can either pick next player itself or use another game state which responsible for picking next player&lt;br /&gt;
&lt;br /&gt;
Code can be found in Tapestry.&lt;br /&gt;
&lt;br /&gt;
=== Changing state prompt ===&lt;br /&gt;
&lt;br /&gt;
State prompt is message displayed for player which usually comes from state description.&lt;br /&gt;
Sometimes you want to change it without changing state (one way is change state but locally, see client states above).&lt;br /&gt;
&lt;br /&gt;
Simple way just change the html&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        setMainTitle: function(text) {&lt;br /&gt;
            $(&#039;pagemaintitletext&#039;).innerHTML = text;&lt;br /&gt;
        },&lt;br /&gt;
         // usage&lt;br /&gt;
        onMeeple: function(event) {&lt;br /&gt;
              //... &lt;br /&gt;
              this.setMainTitle(_(&#039;You must select where meeple is going&#039;));&lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This however will not work with parameters and will not draw You in color, if you want this its more sophisticated:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        setDescriptionOnMyTurn : function(text) {&lt;br /&gt;
            this.gamedatas.gamestate.descriptionmyturn = text;&lt;br /&gt;
            var tpl = dojo.clone(this.gamedatas.gamestate.args);&lt;br /&gt;
            if (tpl === null) {&lt;br /&gt;
                tpl = {};&lt;br /&gt;
            }&lt;br /&gt;
            var title = &amp;quot;&amp;quot;;&lt;br /&gt;
            if (this.isCurrentPlayerActive() &amp;amp;&amp;amp; text !== null) {&lt;br /&gt;
                tpl.you = this.divYou(); &lt;br /&gt;
            }&lt;br /&gt;
            title = this.format_string_recursive(text, tpl);&lt;br /&gt;
&lt;br /&gt;
            if (!title) {&lt;br /&gt;
                this.setMainTitle(&amp;quot;&amp;amp;nbsp;&amp;quot;);&lt;br /&gt;
            } else {&lt;br /&gt;
                this.setMainTitle(title);&lt;br /&gt;
            }&lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: this method uses &#039;&#039;&#039;setMainTitle&#039;&#039;&#039; defined above and &#039;&#039;&#039;divYou&#039;&#039;&#039; defined in another section of this wiki.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Adding Image buttons ===&lt;br /&gt;
&lt;br /&gt;
Its pretty trivial but just in case you need a working function:&lt;br /&gt;
&lt;br /&gt;
ggg.js:&lt;br /&gt;
&lt;br /&gt;
                addImageActionButton: function (id, div_html, handler) { // div_html is string not node&lt;br /&gt;
                    this.addActionButton(id, div_html, handler, &#039;&#039;, false, &#039;gray&#039;); &lt;br /&gt;
                    dojo.style(id, &amp;quot;border&amp;quot;, &amp;quot;none&amp;quot;); // remove ugly border&lt;br /&gt;
                    dojo.addClass(id, &amp;quot;bgaimagebutton&amp;quot;); // add css class to do more styling&lt;br /&gt;
                    return $(id); // return node for chaining&lt;br /&gt;
                },&lt;br /&gt;
&lt;br /&gt;
Example of usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    this.addImageActionButton(&#039;button_coin&#039;,&amp;quot;&amp;lt;div class=&#039;coin&#039;&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;, ()=&amp;gt;{ alert(&#039;Ha!&#039;); });&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Assigning Player Order ===&lt;br /&gt;
Normally when game starts there is &amp;quot;natural&amp;quot; player order assigned randomly.&lt;br /&gt;
&lt;br /&gt;
If you want to deliberatly assign player order at the start of the game (for example, in a game with teams options), you can do so by retrieving the initialization-only player attribute &#039;&#039;&#039;player_table_order&#039;&#039;&#039; and using it to assign values to &#039;&#039;&#039;player_no&#039;&#039;&#039; (which is normally assigned at the start of a game in the order in which players come to the table). (See [https://en.doc.boardgamearena.com/Game_database_model:_dbmodel.sql#The_player_table Game database model] for more details.)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Example:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                // Retrieve inital player order ([0=&amp;gt;playerId1, 1=&amp;gt;playerId2, ...])&lt;br /&gt;
		$playerInitialOrder = [];&lt;br /&gt;
		foreach ($players as $playerId =&amp;gt; $player) {&lt;br /&gt;
			$playerInitialOrder[$player[&#039;player_table_order&#039;]] = $playerId;&lt;br /&gt;
		}&lt;br /&gt;
		ksort($playerInitialOrder);&lt;br /&gt;
		$playerInitialOrder = array_flip(array_values($playerInitialOrder));&lt;br /&gt;
&lt;br /&gt;
		// Player order based on &#039;playerTeams&#039; option&lt;br /&gt;
		$playerOrder = [0, 1, 2, 3];&lt;br /&gt;
		switch (self::getGameStateValue(&#039;playerTeams&#039;)) {&lt;br /&gt;
			case self::TEAM_1_2:&lt;br /&gt;
				$playerOrder = [0, 2, 1, 3];&lt;br /&gt;
				break;&lt;br /&gt;
			case self::TEAM_1_4:&lt;br /&gt;
				$playerOrder = [0, 1, 3, 2];&lt;br /&gt;
				break;&lt;br /&gt;
			case self::TEAM_RANDOM:&lt;br /&gt;
				shuffle($playerOrder);&lt;br /&gt;
				break;&lt;br /&gt;
			default:&lt;br /&gt;
			case self::TEAM_1_3:&lt;br /&gt;
				// Default order&lt;br /&gt;
				break;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
                // Create players&lt;br /&gt;
		// Note: if you added some extra field on &amp;quot;player&amp;quot; table in the database (dbmodel.sql), you can initialize it there.&lt;br /&gt;
		$sql =&lt;br /&gt;
			&#039;INSERT INTO player (player_id, player_color, player_canal, player_name, player_avatar, player_no) VALUES &#039;;&lt;br /&gt;
		$values = [];&lt;br /&gt;
&lt;br /&gt;
		foreach ($players as $playerId =&amp;gt; $player) {&lt;br /&gt;
			$color = array_shift($default_colors);&lt;br /&gt;
			$values[] =&lt;br /&gt;
				&amp;quot;(&#039;&amp;quot; .&lt;br /&gt;
				$playerId .&lt;br /&gt;
				&amp;quot;&#039;,&#039;$color&#039;,&#039;&amp;quot; .&lt;br /&gt;
				$player[&#039;player_canal&#039;] .&lt;br /&gt;
				&amp;quot;&#039;,&#039;&amp;quot; .&lt;br /&gt;
				addslashes($player[&#039;player_name&#039;]) .&lt;br /&gt;
				&amp;quot;&#039;,&#039;&amp;quot; .&lt;br /&gt;
				addslashes($player[&#039;player_avatar&#039;]) .&lt;br /&gt;
				&amp;quot;&#039;,&#039;&amp;quot; .&lt;br /&gt;
				$playerOrder[$playerInitialOrder[$playerId]] .&lt;br /&gt;
				&amp;quot;&#039;)&amp;quot;;&lt;br /&gt;
		}&lt;br /&gt;
		$sql .= implode(&#039;,&#039;, $values);&lt;br /&gt;
		self::DbQuery($sql);&lt;br /&gt;
		self::reattributeColorsBasedOnPreferences(&lt;br /&gt;
			$players,&lt;br /&gt;
			$gameinfos[&#039;player_colors&#039;]&lt;br /&gt;
		);&lt;br /&gt;
		self::reloadPlayersBasicInfos();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Send different notifications to active player vs everybody else ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
Hack alert. This is a hack. We were hoping for proper solution by bga framework.&lt;br /&gt;
&lt;br /&gt;
This will allow you to send notification with two message one for specific player and one for everybody else including spectators.&lt;br /&gt;
Note that this does not split the data - all data must be shared.&lt;br /&gt;
&lt;br /&gt;
Add this to .js file (if you already overriding it merge obviously)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/** @Override */&lt;br /&gt;
format_string_recursive: function(log, args) {&lt;br /&gt;
   if (typeof args.log_others != &#039;undefined&#039; &amp;amp;&amp;amp; typeof args.player_id != &#039;undefined&#039; &amp;amp;&amp;amp; this.player_id != args.player_id)&lt;br /&gt;
	log = args.log_others;&lt;br /&gt;
   return this.inherited(arguments); // you must call this to call super &lt;br /&gt;
},&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example of usage (from eminentdomain)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    $this-&amp;gt;notifyAllPlayers(&#039;tokenMoved&#039;, &lt;br /&gt;
             clienttranslate(&#039;${player_name} adds +2 Colonies to ${place_name}&#039;), // notification with show for player with player_id&lt;br /&gt;
             [&#039;player_id&#039;=&amp;gt;$player_id, // this is mandatory&lt;br /&gt;
             &#039;log_others&#039;=&amp;gt;clienttranslate(&#039;${player_name} adds +2 Colonies to an unknown planet&#039;), // notification will show for others&lt;br /&gt;
              ...&lt;br /&gt;
             ]);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Send transient notifications without incrementing move ID ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.php&lt;br /&gt;
&lt;br /&gt;
Hack alert. This is a hack.&lt;br /&gt;
&lt;br /&gt;
Use this if you need to send some transient notification that should not create a new move ID. The notification should be idempotent -- it should have no practical effect on the game state and would be &#039;&#039;&#039;safe to drop&#039;&#039;&#039; (e.g., it would not matter if a player never received this notification). For example, in a co-op game you want all players to see a real-time preview of some action, before the active player commits their turn.&lt;br /&gt;
&lt;br /&gt;
Doing this mainly affects the instant replay &amp;amp; archive modes. During replay, the BGA framework automatically inserts a 1.5-second pause between each &amp;quot;move&amp;quot;. With this hack, your transient notifications are not considered to be a &amp;quot;move&amp;quot;, so no pause gets added.&lt;br /&gt;
&lt;br /&gt;
; In ggg.php&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$this-&amp;gt;not_a_move_notification = true; // note: do not increase the move counter&lt;br /&gt;
$this-&amp;gt;notifyAllPlayers(&#039;cardsPreview&#039;, &#039;&#039;, $args);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: you cannot have code that send notification or even changes state after this, and you cannot reset this variable back either because it only takes effect when you exit action handling function&lt;br /&gt;
&lt;br /&gt;
=== Ajax Call wrapper ===&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
The current ajaxcall is super vebose and prone to errors, I suggest using a helper function. It does a lot of stuff you must do anyways.&lt;br /&gt;
Most beginner mistakes come from missing part of this code (which is understandstandable - this is a huge snippet to clone every time).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	ajaxcallwrapper: function(action, args, handler) {&lt;br /&gt;
		if (!args) args = []; // this allows to skip args parameter for action which do not require them&lt;br /&gt;
			&lt;br /&gt;
		args.lock = true; // this allows to avoid rapid action clicking which can cause race condition on server&lt;br /&gt;
		if (this.checkAction(action)) { // this does all the proper check that player is active and action is declared&lt;br /&gt;
			this.ajaxcall(&amp;quot;/&amp;quot; + this.game_name + &amp;quot;/&amp;quot; + this.game_name + &amp;quot;/&amp;quot; + action + &amp;quot;.html&amp;quot;, args, // this is mandatory fluff &lt;br /&gt;
				this, (result) =&amp;gt; { },  // success result handler is empty - it is never needed&lt;br /&gt;
                                               handler); // this is real result handler - it called both on success and error, it has optional param  &amp;quot;is_error&amp;quot; - you rarely need it&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   this.ajaxcallwrapper(&#039;pass&#039;); // no args&lt;br /&gt;
   this.ajaxcallwrapper(&#039;playCard&#039;, {card: card_id}); // with args&lt;br /&gt;
   this.ajaxcallwrapper(&#039;playCard&#039;, {card: card_id}, (is_error)=&amp;gt;{if (!is_error) dojo.query(&amp;quot;.selected&amp;quot;).removeClass(&#039;selected&#039;);}) // with handler that cleans up &#039;selected&#039; class on success&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: this always will lock interface and always check for action, you can modify this method to do it optionally, i.e&lt;br /&gt;
  if (args.lock!==false) args.lock = true; else delete args.lock; // it does not work with false value - it has to be removed&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Custom error/exception handling in JavaScript ===&lt;br /&gt;
&lt;br /&gt;
; In ggg.php&lt;br /&gt;
We intentionally throw BgaUserException to rollback database transaction and cancel all changes. Note that any notifications are also cancelled!&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    function foo(bool $didConfirm = false): void&lt;br /&gt;
    {&lt;br /&gt;
        // do processing for the user&#039;s move&lt;br /&gt;
        // afterwards, you determine this move will end the game&lt;br /&gt;
        // so you want to rollback the transaction and require the user to confirm the move first&lt;br /&gt;
&lt;br /&gt;
        if ($gameIsEnding &amp;amp;&amp;amp; !$didConfirm) {&lt;br /&gt;
            throw new BgaUserException(&#039;!!!endGameWarning&#039;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; In ggg.js&lt;br /&gt;
We define a global variable at the top to store the last error code&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  var lastErrorCode = null;&lt;br /&gt;
  return declare(&amp;quot;bgagame.ggg&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We override framework function showMessage to populate the last error code and suppress the red banner message and log message&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    /* @Override */&lt;br /&gt;
    showMessage: function (msg, type) {&lt;br /&gt;
      if (type == &amp;quot;error&amp;quot;) {&lt;br /&gt;
        lastErrorCode = msg.startsWith(&amp;quot;!!!&amp;quot;) ? msg.substring(3) : null;&lt;br /&gt;
        if (lastErrorCode) {&lt;br /&gt;
          return; // suppress red banner and log message&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      this.inherited(arguments);&lt;br /&gt;
    },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Since the framework calls showMessage before your ajaxcall error handler, you can deal with the error in-place:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    fooAction: function (didConfirm) {&lt;br /&gt;
      var data = {&lt;br /&gt;
        foo: &amp;quot;bar&amp;quot;,&lt;br /&gt;
        didConfirm: !!didConfirm,&lt;br /&gt;
      };&lt;br /&gt;
      this.ajaxcallwrapper(&amp;quot;fooAction&amp;quot;, data, function (error) {&lt;br /&gt;
        if (lastErrorCode == &amp;quot;endGameWarning&amp;quot;) {&lt;br /&gt;
          // your custom error handling goes here&lt;br /&gt;
          // for example, show a confirmation dialog and repeat the action with additional param&lt;br /&gt;
          this.confirmationDialog(&lt;br /&gt;
            _(&amp;quot;Doing the foo action now will end the game&amp;quot;),&lt;br /&gt;
            () =&amp;gt; {&lt;br /&gt;
              this.fooAction(true);&lt;br /&gt;
            }&lt;br /&gt;
          );&lt;br /&gt;
        }&lt;br /&gt;
      });&lt;br /&gt;
    },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Studio]]&lt;/div&gt;</summary>
		<author><name>SwHawk</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=BGA_Studio_Cookbook&amp;diff=14392</id>
		<title>BGA Studio Cookbook</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=BGA_Studio_Cookbook&amp;diff=14392"/>
		<updated>2022-08-18T18:24:15Z</updated>

		<summary type="html">&lt;p&gt;SwHawk: /* Inject images and styled html in the log */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
This page is collection of design and implementation recipes for BGA Studio framework.&lt;br /&gt;
For tooling and usage recipes see [[Tools and tips of BGA Studio]].&lt;br /&gt;
If you have your own recipes feel free to edit this page.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Visual Effects, Layout and Animation ==&lt;br /&gt;
&lt;br /&gt;
=== DOM manipulatons ===&lt;br /&gt;
&lt;br /&gt;
==== Create pieces dynamically (using template) ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg_ggg.tpl, ggg.js&lt;br /&gt;
&lt;br /&gt;
Note: this method is recommended by BGA guildlines&lt;br /&gt;
&lt;br /&gt;
Declared js template with variables in .tpl file, like this&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;
    // Javascript HTML templates&lt;br /&gt;
    var jstpl_ipiece = &#039;&amp;lt;div class=&amp;quot;${type} ${type}_${color} inlineblock&amp;quot; aria-label=&amp;quot;${name}&amp;quot; title=&amp;quot;${name}&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use it like this in .js file&lt;br /&gt;
  div = this.format_block(&#039;jstpl_ipiece&#039;, {&lt;br /&gt;
                                type : &#039;meeple&#039;,&lt;br /&gt;
                                color : &#039;ff0000&#039;,&lt;br /&gt;
                                name : &#039;Bob&#039;,&lt;br /&gt;
                            });&lt;br /&gt;
  &lt;br /&gt;
Then you do whatever you need to do with that div, this one specifically design to go to log entries, because it has embedded title (otherwise its a picture only) and no id.&lt;br /&gt;
&lt;br /&gt;
Note: you could have place this variable in js itself, but keeping it in .tpl allows you to have your js code be free of HTML. Normally it never happens but&lt;br /&gt;
it is good to strive for it.&lt;br /&gt;
Note: you can also use string concatenation, its less readable. You can also use dojo dom object creation api&#039;s but its brutally verbose and its more unreadable.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Create pieces dynamically (using string concatenation) ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
Note: Not recommended&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  div = &amp;quot;&amp;lt;div class=&#039;meeple &amp;quot;+color+&amp;quot;&#039;&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
==== Create all pieces statically ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg_ggg.tpl, ggg.css, ggg.view.php (optional) &lt;br /&gt;
&lt;br /&gt;
* Create ALL game pieces in html template (.tpl)&lt;br /&gt;
* ALL pieces should have unique id, and it should be meaningful, i.e. meeple_red_1&lt;br /&gt;
* Do not use inline styling&lt;br /&gt;
* Id of player&#039;s specific pieces should use some sort of &#039;color&#039; identification, since player id cannot be used in static layout, you can use english color name, hex 6 char value, or color &amp;quot;number&amp;quot; (1,2,3...)&lt;br /&gt;
* Pieces should have separated class for its color, type, etc, so it can be easily styled in groups. In example below you now can style all meeples, all red meeples or all red tokens, or all &amp;quot;first&amp;quot; meeples&lt;br /&gt;
&lt;br /&gt;
ggg.tpl:&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
  &amp;lt;div id=&amp;quot;home_red&amp;quot; class=&amp;quot;home_red home&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;div id=&amp;quot;meeple_red_1&amp;quot; class=&amp;quot;meeple red n1&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
     &amp;lt;div id=&amp;quot;meeple_red_2&amp;quot; class=&amp;quot;meeple red n2&amp;quot;&amp;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;
ggg.css:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.meeple {&lt;br /&gt;
	width: 32px;&lt;br /&gt;
	height: 39px;&lt;br /&gt;
	background-image: url(img/78_64_stand_meeples.png);&lt;br /&gt;
	background-size: 352px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.meeple.red {&lt;br /&gt;
	background-position: 30% 0%;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* There should be straight forward mapping between server id and js id (or 1:1)&lt;br /&gt;
* You place objects in different zones of the layout, and setup css to take care of layout&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.home .meeple{&lt;br /&gt;
   display: inline-block;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* If you need to have a temporary object that look like original you can use dojo.clone (and change id to some temp id)&lt;br /&gt;
* If there is lots of repetition or zone grid you can use template generator, but inject style declaration in css instead of inline style for flexibility&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
* If you use this model you cannot use premade js components such as Stock and Zone&lt;br /&gt;
* You have to use alternative methods of animation (slightly altered) since default method will leave object with inline style attributes which you don&#039;t need&lt;br /&gt;
&lt;br /&gt;
=== Logs ===&lt;br /&gt;
&lt;br /&gt;
==== Inject icon images in the log ====&lt;br /&gt;
&lt;br /&gt;
Here is an example of what was done for Terra Mystica which is simple and straightforward:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
//Define the proper message&lt;br /&gt;
		$message = clienttranslate(&#039;${player_name} gets ${power_income} via Structures&#039;);&lt;br /&gt;
		if ($price &amp;gt; 0) {&lt;br /&gt;
			self::DbQuery(&amp;quot;UPDATE player SET player_score = player_score - $price WHERE player_id = $player_id&amp;quot;);&lt;br /&gt;
			$message = clienttranslate(&#039;${player_name} pays ${vp_price} and gets ${power_income} via Structures&#039;);&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
// Notify&lt;br /&gt;
		self::notifyAllPlayers( &amp;quot;powerViaStructures&amp;quot;, $message, array(&lt;br /&gt;
			&#039;i18n&#039; =&amp;gt; array( ),&lt;br /&gt;
			&#039;player_id&#039; =&amp;gt; $player_id,&lt;br /&gt;
			&#039;player_name&#039; =&amp;gt; self::getUniqueValueFromDb( &amp;quot;SELECT player_name FROM player WHERE player_id = $player_id&amp;quot; ),&lt;br /&gt;
			&#039;power_tokens&#039; =&amp;gt; $power_tokens,&lt;br /&gt;
			&#039;vp_price&#039; =&amp;gt; self::getLogsVPAmount($price),&lt;br /&gt;
			&#039;power_income&#039; =&amp;gt; self::getLogsPowerAmount($power_income),&lt;br /&gt;
			&#039;newScore&#039; =&amp;gt; self::getUniqueValueFromDb( &amp;quot;SELECT player_score FROM player WHERE player_id = $player_id&amp;quot; ),&lt;br /&gt;
			&#039;counters&#039; =&amp;gt; $this-&amp;gt;getGameCounters(null),&lt;br /&gt;
		) );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With some functions to have the needed html added inside the substitution variable, such as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function getLogsPowerAmount( $amount ) {&lt;br /&gt;
		return &amp;quot;&amp;lt;div class=&#039;tmlogs_icon&#039; title=&#039;Power&#039;&amp;gt;&amp;lt;div class=&#039;power_amount&#039;&amp;gt;$amount&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: injecting html from php is not ideal but easy, if you want more clean solution, use method below but it is a lot more sophisticated.&lt;br /&gt;
&lt;br /&gt;
==== Inject images and styled html in the log ====&lt;br /&gt;
&lt;br /&gt;
{{InfoBox|title=Warning — Translation|maxWidth=500|topLeftColour=#c00|middleColour=#c00|bottomRightColour=#c00|body=&#039;&#039;&#039;In order to prevent interference with the translation process, keep in mind that you must only apply modifications to the args object, and not try to substitute the keys (the &amp;lt;code&amp;gt;${player_name}&amp;lt;/code&amp;gt; parts of your string) in the log string.&#039;&#039;&#039;}}&lt;br /&gt;
&lt;br /&gt;
So you want nice pictures in the game log. What do you do? The first idea that comes to mind is to send html from php in notifications (see method above). &lt;br /&gt;
&lt;br /&gt;
This is a bad idea for many reasons:&lt;br /&gt;
&lt;br /&gt;
* It&#039;s bad architecture. ui elements leak into the server, and now you have to manage the ui in multiple places.&lt;br /&gt;
* If you decided to change something in the ui in future version, replay logs for old games and tutorials may not work, since they use stored notifications.&lt;br /&gt;
* Log previews for old games become unreadable. (This is the log state before you enter the game replay, which is useful for troubleshooting and game analysis.)&lt;br /&gt;
* It&#039;s more data to transfer and store in the db.&lt;br /&gt;
* It&#039;s a nightmare for translators.&lt;br /&gt;
&lt;br /&gt;
So what else can you do? You can use client side log injection to intercept log arguments (which come from the server) and replace them with html on the client side. Here are three different method you can use to achieve this.&lt;br /&gt;
&lt;br /&gt;
===== First way : Override &amp;lt;code&amp;gt;this.format_string_recursive()&amp;lt;/code&amp;gt; method =====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, ggg.game.php&lt;br /&gt;
&lt;br /&gt;
I use this recipe for &#039;&#039;&#039;client side log injection&#039;&#039;&#039; to intercept log arguments (which come from the server) and replace them with html on the client side.&lt;br /&gt;
&lt;br /&gt;
[[File:clientloginjection.png|left]] &lt;br /&gt;
&lt;br /&gt;
ggg.js&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
        /** Override this function to inject html into log items. This is a built-in BGA method.  */&lt;br /&gt;
&lt;br /&gt;
        /* @Override */&lt;br /&gt;
        format_string_recursive : function format_string_recursive(log, args) {&lt;br /&gt;
            try {&lt;br /&gt;
                if (log &amp;amp;&amp;amp; args &amp;amp;&amp;amp; !args.processed) {&lt;br /&gt;
                    args.processed = true;&lt;br /&gt;
                    &lt;br /&gt;
&lt;br /&gt;
                    // list of special keys we want to replace with images&lt;br /&gt;
                    var keys = [&#039;place_name&#039;,&#039;token_name&#039;];&lt;br /&gt;
                    &lt;br /&gt;
                  &lt;br /&gt;
                    for ( var i in keys) {&lt;br /&gt;
                        var key = keys[i];&lt;br /&gt;
                        key in args &amp;amp;&amp;amp; args[key] = this.getTokenDiv(key, args);                            &lt;br /&gt;
&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            } catch (e) {&lt;br /&gt;
                console.error(log,args,&amp;quot;Exception thrown&amp;quot;, e.stack);&lt;br /&gt;
            }&lt;br /&gt;
            return this.inherited({callee: format_string_recursive}, arguments);&lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important:&#039;&#039;&#039; In the &#039;&#039;format_string_recursive&#039;&#039; method, the &#039;args&#039; parameter will only contain arguments passed to it from the notify method in ggg.game.php (see below).&lt;br /&gt;
&lt;br /&gt;
The &#039;log&#039; parameter is the actual string that is inserted into the logs. You can perform additional js string manipulation on it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        getTokenDiv : function(key, args) {&lt;br /&gt;
            // ... implement whatever html you want here, example from sharedcode.js&lt;br /&gt;
            var token_id = args[key];&lt;br /&gt;
            var item_type = getPart(token_id,0);&lt;br /&gt;
            var logid = &amp;quot;log&amp;quot; + (this.globalid++) + &amp;quot;_&amp;quot; + token_id;&lt;br /&gt;
            switch (item_type) {&lt;br /&gt;
                case &#039;wcube&#039;:&lt;br /&gt;
                    var tokenDiv = this.format_block(&#039;jstpl_resource_log&#039;, {&lt;br /&gt;
                        &amp;quot;id&amp;quot; : logid,&lt;br /&gt;
                        &amp;quot;type&amp;quot; : &amp;quot;wcube&amp;quot;,&lt;br /&gt;
                        &amp;quot;color&amp;quot; : getPart(token_id,1),&lt;br /&gt;
                    });&lt;br /&gt;
                    return tokenDiv;&lt;br /&gt;
             &lt;br /&gt;
                case &#039;meeple&#039;:&lt;br /&gt;
                    if ($(token_id)) {&lt;br /&gt;
                        var clone = dojo.clone($(token_id));&lt;br /&gt;
    &lt;br /&gt;
                        dojo.attr(clone, &amp;quot;id&amp;quot;, logid);&lt;br /&gt;
                        this.stripPosition(clone);&lt;br /&gt;
                        dojo.addClass(clone, &amp;quot;logitem&amp;quot;);&lt;br /&gt;
                        return clone.outerHTML;&lt;br /&gt;
                    }&lt;br /&gt;
                    break;&lt;br /&gt;
     &lt;br /&gt;
                default:&lt;br /&gt;
                    break;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            return &amp;quot;&#039;&amp;quot; + this.clienttranslate_string(this.getTokenName(token_id)) + &amp;quot;&#039;&amp;quot;;&lt;br /&gt;
       },&lt;br /&gt;
       getTokenName : function(key) {&lt;br /&gt;
           return this.gamedatas.token_types[key].name; // get name for the key, from static table for example&lt;br /&gt;
       },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that in this case the server simply injects token_id as a name, and the client substitutes it for the translated name or the picture.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ggg.game.php:&lt;br /&gt;
&lt;br /&gt;
           $this-&amp;gt;notifyAllPlayers(&#039;playerLog&#039;,clienttranslate(&#039;Game moves ${token_name}&#039;),[&#039;token_name&#039;=&amp;gt;$token_id]);&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important:&#039;&#039;&#039; As noted above, only arguments actually passed by this method are available to the args parameter received in the client-side &#039;&#039;format_string_recursive&#039;&#039; method.&lt;br /&gt;
&lt;br /&gt;
Sometimes it is the case that you want to pass arguments that are not actually included in the output message. For example, suppose we have a method like this:&lt;br /&gt;
&lt;br /&gt;
           $this-&amp;gt;notifyAllPlayers(&#039;tokenPlaced&#039;,clienttranslate(&#039;Player placed ${token_name}&#039;),array(&lt;br /&gt;
              &#039;token_name&#039; =&amp;gt; $token_id,&lt;br /&gt;
              &#039;zone_played&#039; =&amp;gt; $zone);&lt;br /&gt;
&lt;br /&gt;
This will output &amp;quot;Player placed ${token_name}&amp;quot; in the log, and if we subscribe to a notification method activated by the &amp;quot;tokenPlaced&amp;quot; event in the client-side code, that method can make use of the &#039;zone_played&#039; argument. &lt;br /&gt;
&lt;br /&gt;
Now if you want to make some really cool things with game log, most probably you would need more arguments than are included in log message. The problem with that,&lt;br /&gt;
it will work at first, but if you reload game using F5 or when the game loads in turn based mode, you will loose your additional parameters, why? Because when game reloads it does not actually send same notifications, it sends special &amp;quot;hitstorical_log&amp;quot; notification where all  parameters not listed in the message are removed. In example above, field zone_played would be removed from historical log as it is not included in message of the notification. You can till preserve specific arguments in historical log by adding special field preserve to notification arguments like this:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
           $this-&amp;gt;notifyAllPlayers(&#039;tokenPlaced&#039;,clienttranslate(&#039;Player placed ${token_name}&#039;),array(&lt;br /&gt;
              &#039;token_name&#039; =&amp;gt; $token_id,&lt;br /&gt;
              &#039;zone_played&#039; =&amp;gt; $zone,&lt;br /&gt;
              &#039;preserve&#039; =&amp;gt; [ &#039;zone_played&#039; ]&lt;br /&gt;
           );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now you can use zone_played in format_string_recursive even in historical logs.&lt;br /&gt;
&lt;br /&gt;
===== Second way: rely on the &amp;lt;code&amp;gt;:formatFunction&amp;lt;/code&amp;gt; option provided by &amp;lt;code&amp;gt;dojo.string.substitute&amp;lt;/code&amp;gt; =====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, ggg.game.php, ggg_ggg.tpl, ggg.css&lt;br /&gt;
&lt;br /&gt;
The above method will work in most of the cases, but if you use dotted keys such as &amp;lt;code&amp;gt;${card.name}&amp;lt;/code&amp;gt; (which is supported by the framework, for private state args), the key won&#039;t be substituted because the &amp;lt;code&amp;gt;key in arg&amp;lt;/code&amp;gt; test will fail. If so you need to rely either on this way, or the one after.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;WARNING:&#039;&#039;&#039; using this method on an already advanced project will require you to go through all your notifications to change keys !&lt;br /&gt;
&lt;br /&gt;
Under the hood, the &#039;&#039;&#039;this.format_string_recursive()&#039;&#039;&#039; function calls the &#039;&#039;&#039;dojo.string.substitute&#039;&#039;&#039; method which substitutes &amp;lt;code&amp;gt;${keys}&amp;lt;/code&amp;gt; with the value provided. If you take a look at the [https://dojotoolkit.org/reference-guide/1.7/dojo/string.html#substitute documentation] and [https://github.com/dojo/dojo/blob/c3ceb017cfa25b703f5662dc83d1c8aae9bc5d81/string.js#L163 source code] you can notice that the key can be suffixed with a colon (&amp;lt;code&amp;gt;:&amp;lt;/code&amp;gt;) followed by a function name. This will allow you to specify directly in the substitution string which keys need HTML injection.&lt;br /&gt;
&lt;br /&gt;
First of all, you need to define your formatting function in the ggg.js file:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[[ggg.js]]&lt;br /&gt;
        getTokenDiv : function(value, key) {&lt;br /&gt;
            //This is only an example implementation, you need to write your own.&lt;br /&gt;
            //The method should return HTML code&lt;br /&gt;
            switch (key) {&lt;br /&gt;
                case &#039;html_injected_argument1&#039;:&lt;br /&gt;
                    return this.format_block(&#039;jstpl_HTMLLogElement1&#039;,{value: value});&lt;br /&gt;
                case &#039;html_injected_argument2&#039;:&lt;br /&gt;
                    return this.format_block(&#039;jstpl_HTMLLogElement2&#039;,{value: value});&lt;br /&gt;
                ...&lt;br /&gt;
            }&lt;br /&gt;
       }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Obviously you need to define the appropriate templates in the ggg_ggg.tpl file:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[[ggg_ggg.tpl]]&lt;br /&gt;
let jstpl_HTMLLogElement1 = &#039;&amp;lt;div class=&amp;quot;log-element log-element-1-${value}&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
let jstpl_HTMLLogElement2 = &#039;&amp;lt;div class=&amp;quot;log-element log-element-2-${value}&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
And the appropriate classes in ggg.css.&lt;br /&gt;
&lt;br /&gt;
Then you need to add the &amp;lt;code&amp;gt;dojo/aspect&amp;lt;/code&amp;gt; module at the top of the ggg.js file:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[ggg.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 define([&lt;br /&gt;
     &amp;quot;dojo&amp;quot;, &amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&amp;quot;dojo/aspect&amp;quot;,&amp;lt;/span&amp;gt;                 //MUST BE IN THIRD POSITION&#039;&#039;&#039; (see [[#Including your own JavaScript module (II)|below]])&lt;br /&gt;
     &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
 ], function (dojo, declare, &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&#039;&#039;&#039;aspect&#039;&#039;&#039;&amp;lt;/span&amp;gt;) {&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
And you also need to add the following code in your &amp;lt;code&amp;gt;contructor&amp;lt;/code&amp;gt; method in the ggg.js:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[ggg.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
         constructor: function(){&lt;br /&gt;
             console.log(&#039;progressevolutiontechnologyswh constructor&#039;);&lt;br /&gt;
               &lt;br /&gt;
             // Here, you can init the global variables of your user interface&lt;br /&gt;
             // Example:&lt;br /&gt;
             // this.myGlobalValue = 0;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&#039;&#039;&#039;let gameObject = this;&#039;&#039;&#039;            //Needed as the this object in aspect.before will not refer to the game object in which the formatting function resides&lt;br /&gt;
             &#039;&#039;&#039;aspect.before(dojo.string, &amp;quot;substitute&amp;quot;, function(template, map, transform) {&#039;&#039;&#039;      //This allows you to modify the arguments of the dojo.string.substitute method before they&#039;re actually passed to it&lt;br /&gt;
                 &#039;&#039;&#039;return [template, map, transform, gameObject];&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now you&#039;re all set to inject HTML in your logs. To actually achieve this, you must specify the function name with the key like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[ggg.game.php]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 $this-&amp;gt;notifyAllPlayers(&amp;quot;notificationName&amp;quot;, clienttranslate(&amp;quot;This log message contains ${plainTextArgument} and the following will receive HTML injection: ${html_injected_argument1:getTokenDiv}&amp;quot;), [&lt;br /&gt;
     &amp;quot;plainTextArgument&amp;quot; =&amp;gt; &amp;quot;some plain text here&amp;quot;,&lt;br /&gt;
     &amp;quot;html_injected_argument1&amp;quot; =&amp;gt; &amp;quot;some value used by getTokenDiv&amp;quot;,&lt;br /&gt;
 ]);&lt;br /&gt;
&lt;br /&gt;
You&#039;re not limited writing only one function, you can write as many functions as you like, and have them each inject a specific type of HTML. You just need to specify the relevant function name after the column in the substitution key.&lt;br /&gt;
&lt;br /&gt;
===== Third way: rely on the &amp;lt;code&amp;gt;transform&amp;lt;/code&amp;gt; argument of &amp;lt;code&amp;gt;dojo.string.substitute&amp;lt;/code&amp;gt; =====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, ggg.game.php, ggg_ggg.tpl, ggg.css&lt;br /&gt;
&lt;br /&gt;
This method is also relying on the use of &amp;lt;code&amp;gt;dojo.string.substitute&amp;lt;/code&amp;gt; by the framework, and will use the &amp;lt;code&amp;gt;transform&amp;lt;/code&amp;gt; argument, which, accordting to [https://github.com/dojo/dojo/blob/c3ceb017cfa25b703f5662dc83d1c8aae9bc5d81/string.js#L163 source code] and [https://dojotoolkit.org/reference-guide/1.7/dojo/string.html#substitute documentation] will be run on all the messages going through dojo.string.substitute.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;WARNING:&#039;&#039;&#039; As this method will be applied to all strings that go through dojo.string.substitute. As such you must take extra care not to substitute keys that may be used by the framework (i.e. ${id}). In order to do so, a good practise would be to prefix all keys that need substitution with a trigram of the game name.&lt;br /&gt;
&lt;br /&gt;
Since all the keys will be fed to the tranform function, by default, it must return the value, substituted or not per your needs. You can define the function like this in the ggg.js file:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[ggg.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
         getTokenDiv : function(value, key) {&lt;br /&gt;
             //This is only an example implementation, you need to write your own.&lt;br /&gt;
             //The method should return HTML code&lt;br /&gt;
             switch (key) {&lt;br /&gt;
                 case &#039;html_injected_argument1&#039;:&lt;br /&gt;
                     return this.format_block(&#039;jstpl_HTMLLogElement1&#039;,{value: value});&lt;br /&gt;
                 case &#039;html_injected_argument2&#039;:&lt;br /&gt;
                     return this.format_block(&#039;jstpl_HTMLLogElement2&#039;,{value: value});&lt;br /&gt;
                 ...&lt;br /&gt;
                 &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&#039;&#039;&#039;default:&#039;&#039;&#039;&lt;br /&gt;
                     &#039;&#039;&#039;return value;&#039;&#039;&#039;&amp;lt;/span&amp;gt;                  &#039;&#039;&#039;//Needed otherwise regular strings won&#039;t appear since since the value isn&#039;t returned by the function&#039;&#039;&#039;&lt;br /&gt;
             }&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
The templates must be defined in the ggg_ggg.tpl file and the corresponding CSS classes in the ggg.css file.&lt;br /&gt;
&lt;br /&gt;
You need to add the following code at the beginning of the ggg.js file:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[ggg.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 define([&lt;br /&gt;
     &amp;quot;dojo&amp;quot;, &amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&amp;quot;dojo/aspect&amp;quot;,&amp;lt;/span&amp;gt;                 //MUST BE IN THIRD POSITION&#039;&#039;&#039; (see [[#Including your own JavaScript module (II)|below]])&lt;br /&gt;
     &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
 ], function (dojo, declare, &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&#039;&#039;&#039;aspect&#039;&#039;&#039;&amp;lt;/span&amp;gt;) {&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
And the following code to the &amp;lt;code&amp;gt;constructor&amp;lt;/code&amp;gt; method in ggg.js:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[ggg.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
         constructor: function(){&lt;br /&gt;
             console.log(&#039;progressevolutiontechnologyswh constructor&#039;);&lt;br /&gt;
               &lt;br /&gt;
             // Here, you can init the global variables of your user interface&lt;br /&gt;
             // Example:&lt;br /&gt;
             // this.myGlobalValue = 0;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&#039;&#039;&#039;let transformFunction = dojo.hitch(this, &amp;quot;getTokenDiv&amp;quot;);&#039;&#039;&#039;            //Needed as the this object in aspect.before will not refer to the game object in which the formatting function resides&lt;br /&gt;
             &#039;&#039;&#039;aspect.before(dojo.string, &amp;quot;substitute&amp;quot;, function(template, map, transform) {&#039;&#039;&#039;&lt;br /&gt;
                 &#039;&#039;&#039;if (undefined === transform) {&#039;&#039;&#039;                                   //Check for a transform function presence, just in case&lt;br /&gt;
                     &#039;&#039;&#039;return [template, map, transform];&#039;&#039;&#039;&lt;br /&gt;
                 &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then you&#039;re all set for log injection, no need to change anything on the PHP side.&lt;br /&gt;
&lt;br /&gt;
==== Processing logs on re-loading ====&lt;br /&gt;
&lt;br /&gt;
You rarely need to process logs when reloading, but if you want to do something fancy you may have to do it after logs are loaded. &lt;br /&gt;
Logs are loaded asyncronously so you have to listen for logs to be fully loaded.&lt;br /&gt;
Unfortunately there is no direct way of doing it so this is the hack.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Hack alert&#039;&#039;&#039; - this extends undocumented function and may be broken when framework is updated&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
			/*&lt;br /&gt;
  			* [Undocumented] Override BGA framework functions to call onLoadingLogsComplete when loading is done&lt;br /&gt;
                        @Override&lt;br /&gt;
   			*/&lt;br /&gt;
			setLoader: function(image_progress, logs_progress) {&lt;br /&gt;
				this.inherited(arguments); // required, this is &amp;quot;super()&amp;quot; call, do not remove&lt;br /&gt;
				//console.log(&amp;quot;loader&amp;quot;, image_progress, logs_progress)&lt;br /&gt;
				if (!this.isLoadingLogsComplete &amp;amp;&amp;amp; logs_progress &amp;gt;= 100) {&lt;br /&gt;
					this.isLoadingLogsComplete = true; // this is to prevent from calling this more then once&lt;br /&gt;
					this.onLoadingLogsComplete();&lt;br /&gt;
				}&lt;br /&gt;
			},&lt;br /&gt;
&lt;br /&gt;
			onLoadingLogsComplete: function() {&lt;br /&gt;
				console.log(&#039;Loading logs complete&#039;);&lt;br /&gt;
				// do something here&lt;br /&gt;
			},&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Player Panel ===&lt;br /&gt;
&lt;br /&gt;
==== Inserting non-player panel ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, ggg_ggg.tpl&lt;br /&gt;
&lt;br /&gt;
If you want to insert non-player panel on the right side (for example to hold extra preferences, zooming controls, etc)&lt;br /&gt;
&lt;br /&gt;
this can go pretty much anywhere in template it will be moved later&lt;br /&gt;
&lt;br /&gt;
ggg_ggg.tpl:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	&amp;lt;div class=&#039;player_board_config&#039; id=&amp;quot;player_board_config&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;!-- here is whatever you want, buttons just example --&amp;gt;&lt;br /&gt;
		&amp;lt;button id=&amp;quot;zoom-out&amp;quot; class=&amp;quot; fa fa-search-minus fa-2x config-control&amp;quot;&amp;gt;&amp;lt;/button&amp;gt;&lt;br /&gt;
		&amp;lt;button id=&amp;quot;zoom-in&amp;quot; class=&amp;quot; fa fa-search-plus fa-2x config-control&amp;quot;&amp;gt;&amp;lt;/button&amp;gt;&lt;br /&gt;
		&amp;lt;button id=&amp;quot;show-settings&amp;quot; class=&amp;quot;fa fa-cog fa-2x config-control &amp;quot;&amp;gt;&amp;lt;/button&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
some hackery required in js&lt;br /&gt;
&lt;br /&gt;
ggg.js:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* @Override */&lt;br /&gt;
	updatePlayerOrdering() {&lt;br /&gt;
		this.inherited(arguments);&lt;br /&gt;
		dojo.place(&#039;player_board_config&#039;, &#039;player_boards&#039;, &#039;first&#039;);&lt;br /&gt;
	},&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Images and Icons ===&lt;br /&gt;
&lt;br /&gt;
==== Accessing images from js ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
     // your game resources&lt;br /&gt;
     &lt;br /&gt;
     var my_img = &#039;&amp;lt;img src=&amp;quot;&#039;+g_gamethemeurl+&#039;img/cards.jpg&amp;quot;/&amp;gt;&#039;;&lt;br /&gt;
     &lt;br /&gt;
     // shared resources&lt;br /&gt;
     var my_help_img = &amp;quot;&amp;lt;img class=&#039;imgtext&#039; src=&#039;&amp;quot; + g_themeurl + &amp;quot;img/layout/help_click.png&#039; alt=&#039;action&#039; /&amp;gt; &amp;lt;span class=&#039;tooltiptext&#039;&amp;gt;&amp;quot; +&lt;br /&gt;
                    text + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== High-Definition Graphics ====&lt;br /&gt;
&lt;br /&gt;
Some users will have screens which can display text and images at a greater resolution than the usual 72 dpi, e.g. the &amp;quot;Retina&amp;quot; screens on the 5k iMac, all iPads, and high-DPI screens on laptops from many manufacturers. If you can get art assets at this size, they will make your game look extra beautiful. You &#039;&#039;could&#039;&#039; just use large graphics and scale them down, but that would increase the download time and bandwidth for users who can&#039;t display them. Instead, a good way is to prepare a separate graphics file at exactly twice the size you would use otherwise, and add &amp;quot;@2x&amp;quot; at the end of the filename, e.g. if pieces.png is 240x320, then pieces@2x.png is 480x640.&lt;br /&gt;
&lt;br /&gt;
There are two changes required in order to use the separate graphics files. First in your css, where you use a file, add a media query which overrides the original definition and uses the bigger version on devices which can display them. Ensuring that the &amp;quot;background-size&amp;quot; attribute is set means that the size of the displayed object doesn&#039;t change, but only is drawn at the improved dot pitch.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.piece {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    background-image: url(&#039;img/pieces.png&#039;);&lt;br /&gt;
    background-size:240px 320px;&lt;br /&gt;
    z-index: 10;&lt;br /&gt;
}&lt;br /&gt;
@media (-webkit-min-device-pixel-ratio: 2), (min-device-pixel-ratio: 2), (min-resolution: 192dpi)&lt;br /&gt;
{&lt;br /&gt;
    .piece {&lt;br /&gt;
        background-image: url(&#039;img/pieces@2x.png&#039;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Secondly, in your setup function in javascript, you must ensure than only the appropriate one version of the file gets pre-loaded (otherwise you more than waste the bandwidth saved by maintaining the standard-resolution file). Note that the media query is the same in both cases:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
            var isRetina = &amp;quot;(-webkit-min-device-pixel-ratio: 2), (min-device-pixel-ratio: 2), (min-resolution: 192dpi)&amp;quot;;&lt;br /&gt;
            if (window.matchMedia(isRetina).matches)&lt;br /&gt;
            {&lt;br /&gt;
                this.dontPreloadImage( &#039;pieces.png&#039; );&lt;br /&gt;
                this.dontPreloadImage( &#039;board.jpg&#039; );&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                this.dontPreloadImage( &#039;pieces@2x.png&#039; );&lt;br /&gt;
                this.dontPreloadImage( &#039;board@2x.jpg&#039; );&lt;br /&gt;
            }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using CSS to create different colors of game pieces if you have only white piece ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
background-color: #${color}; &lt;br /&gt;
background-blend-mode: multiply;&lt;br /&gt;
background-image: url( &#039;img/mypiece.png&#039;);&lt;br /&gt;
mask: url(&#039;img/mypiece.png&#039;);&lt;br /&gt;
-webkit-mask: url(&#039;img/mypiece.png&#039;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where ${color} - is color you want&lt;br /&gt;
&lt;br /&gt;
Note: piece has to be white (shades of gray). Sprite can be used too, just add add blackground-position as usuall.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Other Fluff ===&lt;br /&gt;
&lt;br /&gt;
==== Use thematic fonts ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.css&lt;br /&gt;
&lt;br /&gt;
Sometime game elements use specific fonts of text, if you want to match it up you can load some specific font (IMPORTANT: from some &#039;&#039;&#039;free font&#039;&#039;&#039; source. See notes below).&lt;br /&gt;
&lt;br /&gt;
[[File:Dragonline_font.png]]&lt;br /&gt;
&lt;br /&gt;
.css&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* latin-ext */&lt;br /&gt;
@font-face {&lt;br /&gt;
  font-family: &#039;Qwigley&#039;;&lt;br /&gt;
  font-style: normal;&lt;br /&gt;
  font-weight: 400;&lt;br /&gt;
  src: local(&#039;Qwigley&#039;), local(&#039;Qwigley-Regular&#039;), url(https://fonts.gstatic.com/s/qwigley/v6/2Dy1Unur1HJoklbsg4iPJ_Y6323mHUZFJMgTvxaG2iE.woff2) format(&#039;woff2&#039;);&lt;br /&gt;
  unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;&lt;br /&gt;
}&lt;br /&gt;
/* latin */&lt;br /&gt;
@font-face {&lt;br /&gt;
  font-family: &#039;Qwigley&#039;;&lt;br /&gt;
  font-style: normal;&lt;br /&gt;
  font-weight: normal;&lt;br /&gt;
  src: local(&#039;Qwigley&#039;), local(&#039;Qwigley-Regular&#039;), url(https://fonts.gstatic.com/s/qwigley/v6/gThgNuQB0o5ITpgpLi4Zpw.woff2) format(&#039;woff2&#039;);&lt;br /&gt;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;&lt;br /&gt;
}&lt;br /&gt;
@font-face {&lt;br /&gt;
  font-family: &#039;Qwigley&#039;;&lt;br /&gt;
  font-style: normal;&lt;br /&gt;
  font-weight: normal;&lt;br /&gt;
  src: local(&#039;Qwigley&#039;), local(&#039;Qwigley-Regular&#039;), url(http://ff.static.1001fonts.net/q/w/qwigley.regular.ttf) format(&#039;ttf&#039;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.zone_title {&lt;br /&gt;
	display: inline-block;&lt;br /&gt;
	position: absolute;&lt;br /&gt;
	font: italic 32px/32px &amp;quot;Qwigley&amp;quot;, cursive;	   &lt;br /&gt;
	height: 32px;&lt;br /&gt;
	width: auto;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NB:&#039;&#039;&#039; if you need to include a font that&#039;s not available online, an extra action will be needed from an admin. Please include the font file(s) in your img directory, and mention it to admins when requesting your game to be moved to alpha. &#039;&#039;&#039;Please remember that the font has to be free, and include a .txt with all appropriate license information about the font.&#039;&#039;&#039;&lt;br /&gt;
You can look for free fonts (for example) on https://fonts.google.com or https://www.fontsquirrel.com/)&lt;br /&gt;
&lt;br /&gt;
=== Use player color in template ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg_ggg.tpl, ggg.view.php&lt;br /&gt;
&lt;br /&gt;
.view.php:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    function build_page($viewArgs) {&lt;br /&gt;
        // Get players &amp;amp; players number&lt;br /&gt;
        $players = $this-&amp;gt;game-&amp;gt;loadPlayersBasicInfos();&lt;br /&gt;
        $players_nbr = count($players);&lt;br /&gt;
        /**&lt;br /&gt;
         * ********* Place your code below: ***********&lt;br /&gt;
         */&lt;br /&gt;
        &lt;br /&gt;
        // Set PCOLOR to the current player color hex&lt;br /&gt;
        global $g_user;&lt;br /&gt;
        $cplayer = $g_user-&amp;gt;get_id();&lt;br /&gt;
        if (array_key_exists($cplayer, $players)) { // may be not set if spectator&lt;br /&gt;
            $player_color = $players [$cplayer] [&#039;player_color&#039;];&lt;br /&gt;
        } else {&lt;br /&gt;
            $player_color = &#039;ffffff&#039;; // spectator&lt;br /&gt;
        }&lt;br /&gt;
        $this-&amp;gt;tpl [&#039;PCOLOR&#039;] = $player_color;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Scale to fit for big boards ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg_ggg.tpl, ggg.js&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Lets say you have huge game board, and lets say you want it to be 1400px wide. Besides the board there will be side bar which is 240 and trim. &lt;br /&gt;
My display is 1920 wide so it fits, but there is big chance other people won&#039;t have that width. What do you do?&lt;br /&gt;
&lt;br /&gt;
You have to decide:&lt;br /&gt;
* If board does not fit you want scale whole thing down, the best way is probably use viewport (see https://en.doc.boardgamearena.com/Your_game_mobile_version)&lt;br /&gt;
* You can leave the board as is and make sure it is scrollable horizonatally&lt;br /&gt;
* You add custom scale just for the board (can add user controls  - and hook to transform: scale())&lt;br /&gt;
&lt;br /&gt;
I tried to auto-scale but this just does work, too many variables - browser zoom, 3d mode, viewport, custom bga scaling, devicePixelRatio - all create some impossible coctail of zooming...&lt;br /&gt;
Here is scaling functing for custom user scaling&lt;br /&gt;
&lt;br /&gt;
ggg_ggg.tpl:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   &amp;lt;div id=&amp;quot;thething&amp;quot; class=&amp;quot;thething&amp;quot;&amp;gt;&lt;br /&gt;
            ... everything else you declare ...&lt;br /&gt;
   &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ggg.js:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    onZoomPlus: function() {&lt;br /&gt;
       this.my_zoom+=0.1;&lt;br /&gt;
       this.zoommy(&#039;thething&#039;,this.my_zoom);&lt;br /&gt;
    },&lt;br /&gt;
&lt;br /&gt;
    zoommy: function(node, zoom) {&lt;br /&gt;
                node=$(node);&lt;br /&gt;
		var width = 100 / zoom;&lt;br /&gt;
		node.style.transformOrigin = &amp;quot;0 0&amp;quot;;&lt;br /&gt;
		node.style.transform = &amp;quot;scale(&amp;quot; + zoom + &amp;quot;)&amp;quot;;&lt;br /&gt;
		node.style.width = width + &amp;quot;%&amp;quot;;&lt;br /&gt;
    },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Dynamic tooltips ===&lt;br /&gt;
&lt;br /&gt;
If you really need a dynamic tooltip you can use this technique. (Only use it if the static tooltips provided by the BGA framework are not sufficient.)&lt;br /&gt;
&lt;br /&gt;
            new dijit.Tooltip({&lt;br /&gt;
                connectId: [&amp;quot;divItemId&amp;quot;],&lt;br /&gt;
                getContent: function(matchedNode){&lt;br /&gt;
                    return &amp;quot;... calculated ...&amp;quot;; &lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is an out-of-the-box djit.Tooltip. It has a &#039;&#039;getContent&#039;&#039; method which is called dynamically.&lt;br /&gt;
&lt;br /&gt;
The string function return becomes the innerHTML of the tooltip, so it can be anything. In this example matchedNode is a dojo node representing dom object with id of &amp;quot;divItemId&amp;quot; but there are more parameters which I am not posting here which allows more sophisticated subnode queries (i.e. you can attach tooltip to all nodes with class or whatever).&lt;br /&gt;
&lt;br /&gt;
[https://dojotoolkit.org/reference-guide/1.10/dijit/Tooltip.html dijit.Tooltip]&lt;br /&gt;
&lt;br /&gt;
It&#039;s not part of the BGA API so use at your own risk.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Rendering text with players color and proper background ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
This example actually writes &amp;quot;You&amp;quot; but you can replace this with player name as easily, drop translating function in this case&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        /* Implementation of proper colored You with background in case of white or light colors  */&lt;br /&gt;
 &lt;br /&gt;
        divYou : function() {&lt;br /&gt;
            var color = this.gamedatas.players[this.player_id].color;&lt;br /&gt;
            var color_bg = &amp;quot;&amp;quot;;&lt;br /&gt;
            if (this.gamedatas.players[this.player_id] &amp;amp;&amp;amp; this.gamedatas.players[this.player_id].color_back) {&lt;br /&gt;
                color_bg = &amp;quot;background-color:#&amp;quot; + this.gamedatas.players[this.player_id].color_back + &amp;quot;;&amp;quot;;&lt;br /&gt;
            }&lt;br /&gt;
            var you = &amp;quot;&amp;lt;span style=\&amp;quot;font-weight:bold;color:#&amp;quot; + color + &amp;quot;;&amp;quot; + color_bg + &amp;quot;\&amp;quot;&amp;gt;&amp;quot; + __(&amp;quot;lang_mainsite&amp;quot;, &amp;quot;You&amp;quot;) + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
            return you;&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Cool realistic shadow effect with CSS ===&lt;br /&gt;
&lt;br /&gt;
==== Rectangles and circles ====&lt;br /&gt;
&lt;br /&gt;
It is often nice to have a drop shadow around tiles and tokens, to separate them from the table visually. It is very easy to add a shadow to rectangular elements, just add this to your css:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.xxx-tile {&lt;br /&gt;
    box-shadow: 3px 3px 3px #000000a0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
box-shadow obeys &#039;&#039;&#039;border-radius&#039;&#039;&#039; of the element, so it will look good for rounded rectangles, and hence also circles (if border-radius is set appropriately).&lt;br /&gt;
&lt;br /&gt;
box-shadow also supports various other parameters and can be used to achieve effects such as glowing, borders, inner shadows etc. If you need to animate a box-shadow, you may be able to get better performance (avoiding redraws) if you attach the shadow to another element (possibly an ::after pseudo-element) and change only the &#039;&#039;&#039;opacity&#039;&#039;&#039; of that element.&lt;br /&gt;
&lt;br /&gt;
==== Irregular Shapes ====&lt;br /&gt;
&lt;br /&gt;
If you wish to make a shadow effect for game pieces that are not a rectangle, but your game pieces are drawn from rectangles in a PNG image, you can apply the shadow to the piece using any art package and save it inside the image. This usually will yield the best performance. Remember to account for the size of the shadow when you lay out images in the sprite sheet.&lt;br /&gt;
&lt;br /&gt;
However that sometimes will not be an option, for example if the image needs to be rotated while the shadow remains offset in the same direction. In this case, one option is to not use box-shadow but use filter, which is supported by recent major browsers.  This way, you can use the alpha channel of your element to drop a shadow.  This even work for transparent backgrounds, so that if you are using the &amp;quot;CSS-sprite&amp;quot; method, it will work!&lt;br /&gt;
&lt;br /&gt;
For instance:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.xxx-token {&lt;br /&gt;
    filter: drop-shadow(0px 0px 1px #000000);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beware that some browsers still do not always draw drop-shadow correctly. In particular, Safari frequently leaves bits of shadow behind when objects move around the screen. In Chrome, shadows sometimes flicker badly if another element is animating close by. Some of these correctness issues can be solved by adding &#039;&#039;&#039;isolation: isolate; will-change: filter;&#039;&#039;&#039; to affected elements, but this significantly affects redraw performance.&lt;br /&gt;
&lt;br /&gt;
Beware of performance issues - particularly on Safari (MacOS, iPhone and iPad). Keep in mind that drop-shadow are very GPU intensive. This becomes noticeable once you have about 40 components with drop-shadow filter. If that is your case, you can quite easily implement a user preference to disable shadows for users on slower machines:&lt;br /&gt;
&lt;br /&gt;
gameoptions.inc.php&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
100 =&amp;gt; array(&lt;br /&gt;
			&#039;name&#039; =&amp;gt; totranslate(&#039;Shadows&#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;Enabled&#039; ), &#039;cssPref&#039; =&amp;gt; &#039;&#039; ),&lt;br /&gt;
					2 =&amp;gt; array( &#039;name&#039; =&amp;gt; totranslate( &#039;Disabled&#039; ), &#039;cssPref&#039; =&amp;gt; &#039;no-shadow&#039; )&lt;br /&gt;
			)&lt;br /&gt;
	),&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[game].css&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.no-shadow * {&lt;br /&gt;
	filter: none !important; &lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Shadows with clip-path ====&lt;br /&gt;
&lt;br /&gt;
For some reason, a shadow will not work together with clip-path on one element. To use both clip-path (when for example using .svg to cut out cardboard components from your .jpg spritesheet) and drop-shadow, you need to wrap the element into another one, and apply drop-shadow to the outer one, and clip-path to the inner one.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;div class=&#039;my-token-wrap&#039;&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&#039;my-token&#039;&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;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.my-token-wrap {&lt;br /&gt;
    filter: drop-shadow(0px 0px 1px #000000);&lt;br /&gt;
}&lt;br /&gt;
.my-token-wrap .my-token {&lt;br /&gt;
    clip-path: url(#my-token-path);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Using the CSS classes from the state machine ===&lt;br /&gt;
&lt;br /&gt;
If you need to hide or show stuff depending on the state of your game, you can of course use javascript, but CSS is hand enough for that.  The #overall-content element does change class depending on the game state.  For instance, if you are in state &#039;&#039;playerTurn&#039;&#039;, it will have the class &#039;&#039;gamestate_playerTurn&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
So now, if you want to show the discard pile only during player turns, you may use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#discard_pile { display: none }&lt;br /&gt;
.gamestate_playerTurn #discard_pile { display: block }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This can be used if you want to change sizing of elements, position, layout or visual appearance.&lt;br /&gt;
&lt;br /&gt;
== Game Model and Database design ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Database for The euro game ===&lt;br /&gt;
Lets say we have a game with workers, dice, tokens, board, resources, money and vp. Workers and dice can be placed in various zones on the board, and you can get resources, money, tokens and vp in your home zone. Also tokens can be flipped or not flipped.&lt;br /&gt;
&lt;br /&gt;
[[File:Madeira board.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now lets try to map it, we have&lt;br /&gt;
* (meeple,zone)&lt;br /&gt;
* (die, zone, sideup)&lt;br /&gt;
* (resource cube/money token/vp token,player home zone)&lt;br /&gt;
* (token, player home zone, flip state)&lt;br /&gt;
We can notice that resource and money are uncountable, and don&#039;t need to be track individually so we can replace our mapping to&lt;br /&gt;
* (resource type/money,player home zone, count)&lt;br /&gt;
And vp stored already for us in player table, so we can remove it from that list.&lt;br /&gt;
&lt;br /&gt;
Now when we get to encode it we can see that everything can be encoded as (object,zone,state) form, where object and zone is string and state is integer. The resource mapping is slightly different semantically so you can go with two table, or counting using same table with state been used as count for resources.&lt;br /&gt;
&lt;br /&gt;
So the piece mapping for non-grid based games can be in most case represented by (string: token_key, string: token_location, int: token_state), example of such database schema can be found here: [https://github.com/elaskavaia/bga-sharedcode/blob/master/dbmodel.sql dbmodel.sql] and class implementing access to it here [https://github.com/elaskavaia/bga-sharedcode/blob/master/modules/tokens.php table.game.php].&lt;br /&gt;
&lt;br /&gt;
Variant 1: Minimalistic&lt;br /&gt;
&lt;br /&gt;
 CREATE TABLE IF NOT EXISTS `token` (&lt;br /&gt;
  `token_key` varchar(32) NOT NULL,&lt;br /&gt;
  `token_location` varchar(32) NOT NULL,&lt;br /&gt;
  `token_state` int(10),&lt;br /&gt;
  PRIMARY KEY (`token_key`)&lt;br /&gt;
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+token&lt;br /&gt;
! token_key&lt;br /&gt;
! token_location&lt;br /&gt;
! token_state&lt;br /&gt;
|-&lt;br /&gt;
|meeple_red_1&lt;br /&gt;
|home_red&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
|dice_black_2&lt;br /&gt;
|board_guard&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
|dice_green_1&lt;br /&gt;
|board_action_mayor&lt;br /&gt;
|3&lt;br /&gt;
|-&lt;br /&gt;
|bread&lt;br /&gt;
|home_red&lt;br /&gt;
|5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Now how we represent resource counters such as bread?&lt;br /&gt;
Using same table from we simply add special counter token for bread and use state to indicate the count. Note to keep first column unique we have to add player identification for that counter, i.e. ff0000 is red player.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+token&lt;br /&gt;
! token_key&lt;br /&gt;
! token_location&lt;br /&gt;
! token_state&lt;br /&gt;
|-&lt;br /&gt;
|bread_ff0000&lt;br /&gt;
|tableau_ff0000&lt;br /&gt;
|5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See php module for this table here https://github.com/elaskavaia/bga-sharedcode/blob/master/modules/tokens.php&lt;br /&gt;
&lt;br /&gt;
Variant 2: Additional resource table, resource count for each player id&lt;br /&gt;
&lt;br /&gt;
 CREATE TABLE IF NOT EXISTS `resource` (&lt;br /&gt;
  `player_id` int(10) unsigned NOT NULL,&lt;br /&gt;
  `resource_key` varchar(32) NOT NULL,&lt;br /&gt;
  `resource_count` int(10) signed NOT NULL,&lt;br /&gt;
  PRIMARY KEY (`player_id`,`resource_key`)&lt;br /&gt;
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;&lt;br /&gt;
&lt;br /&gt;
 ALTER TABLE resource ADD CONSTRAINT fk_player_id FOREIGN KEY (player_id) REFERENCES player(player_id);&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+resource&lt;br /&gt;
! player_id&lt;br /&gt;
! resource_key&lt;br /&gt;
! resource_count&lt;br /&gt;
|-&lt;br /&gt;
|123456&lt;br /&gt;
|bread&lt;br /&gt;
|5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Variant 3: More normalised&lt;br /&gt;
&lt;br /&gt;
This version is similar to &amp;quot;card&amp;quot; table from hearts tutorial, you can also use exact cards database schema and Deck implementation for most purposes (even you not dealing with cards). &lt;br /&gt;
&lt;br /&gt;
 CREATE TABLE IF NOT EXISTS `token` (&lt;br /&gt;
  `token_id` int(10) unsigned NOT NULL AUTO_INCREMENT,&lt;br /&gt;
  `token_type` varchar(16) NOT NULL,&lt;br /&gt;
  `token_arg` int(11) NOT NULL,&lt;br /&gt;
  `token_location` varchar(32) NOT NULL,&lt;br /&gt;
  `token_state` int(10),&lt;br /&gt;
  PRIMARY KEY (`token_id`)&lt;br /&gt;
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+token&lt;br /&gt;
! token_id&lt;br /&gt;
! token_type&lt;br /&gt;
! token_arg&lt;br /&gt;
! token_location&lt;br /&gt;
! token_state&lt;br /&gt;
|-&lt;br /&gt;
|22&lt;br /&gt;
|meeple&lt;br /&gt;
|123456&lt;br /&gt;
|home_123456&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
|23&lt;br /&gt;
|dice&lt;br /&gt;
|2&lt;br /&gt;
|board_guard&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
|26&lt;br /&gt;
|dice&lt;br /&gt;
|1&lt;br /&gt;
|board_action_mayor&lt;br /&gt;
|3&lt;br /&gt;
|-&lt;br /&gt;
|49&lt;br /&gt;
|bread&lt;br /&gt;
|0&lt;br /&gt;
|home_123456&lt;br /&gt;
|5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Advantages of this would be is a bit more straightforward to do some queries in db, disadvantage its hard to read (as you can compare with previous example, you&lt;br /&gt;
cannot just look at say, ah I know what it means). Another questionable advantage is it allows you to do id randomisation, so it hard to do crafted queries to &lt;br /&gt;
cheat, the down side of that you cannot understand it either, and handcraft db states for debugging or testing.&lt;br /&gt;
&lt;br /&gt;
=== Database for The card game ===&lt;br /&gt;
&lt;br /&gt;
Lets say you have a standard card game, player have hidden cards in hand, you can draw card from draw deck, play card on tableau and discard to discard pile.&lt;br /&gt;
We have to design database for such game.&lt;br /&gt;
&lt;br /&gt;
In real word to &amp;quot;save&amp;quot; the game we take a picture a play area, save cards from it, then put away draw deck, discard and hand of each player separately and mark it, also we will record current scoring (if any) and who&#039;s turn was it.&lt;br /&gt;
&lt;br /&gt;
* Framework handles state machine transition, so you don&#039;t have to worry about database design for that (i.e. who&#039;s turn it is, what phase of the game we are at, you still have to design it but part of state machine step)&lt;br /&gt;
* Also framework supports basic player information, color, order around the table, basic scoring, etc, so you don&#039;t have to worry about it either&lt;br /&gt;
* The only thing you need in our database is state of the &amp;quot;board&amp;quot;, which is &amp;quot;where each pieces is, and in what state&amp;quot;, or (position,rotation) pair.&lt;br /&gt;
&lt;br /&gt;
Lets see what we have for that:&lt;br /&gt;
* The card state is very simple, its usually &amp;quot;face up/face down&amp;quot;, &amp;quot;tapped/untapped&amp;quot;, &amp;quot;right side up/up side down&amp;quot;&lt;br /&gt;
* As position go we never need real coordinates x,y,z. We need to know what &amp;quot;zone&amp;quot; card was, and depending on the zone it may sometimes need an extra &amp;quot;z&amp;quot; or &amp;quot;x&amp;quot; as card order. The zone position usually static or irrelevant.&lt;br /&gt;
* So our model is: we have cards, which have some attributes, at any given point in time they belong to a &amp;quot;zone&amp;quot;, and can also have order and state&lt;br /&gt;
* Now for mapping we should consider what information changes and what information is static, later is always candidate for material file&lt;br /&gt;
* For dynamic information we should try to reduce amount of fields we need&lt;br /&gt;
**  we need at least a field for card, so its one&lt;br /&gt;
**  we need to know what zone cards belong to, its 2&lt;br /&gt;
**  and we have possibly few other fields, if you look closely at you game you may find out that most of the zone only need one attribute at a time, i.e. draw pile always have cards face down, hand always face up, also for hand and discard order does not matter at all (but for draw it does matter). So in majority of cases we can get away with one single extra integer field representing state or order&lt;br /&gt;
* In real database both card and zone will be integers as primary keys referring to additional tables, but in our case its total overkill, so they can be strings as easily&lt;br /&gt;
&lt;br /&gt;
Variant 1: Minimalistic&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE TABLE IF NOT EXISTS `card` (&lt;br /&gt;
  `card_key` varchar(32) unsigned NOT NULL,&lt;br /&gt;
  `card_location` varchar(32) NOT NULL,&lt;br /&gt;
  `card_state` int(11) NOT NULL,&lt;br /&gt;
  PRIMARY KEY (`card_id`)&lt;br /&gt;
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Variant 2: More normalised&lt;br /&gt;
&lt;br /&gt;
This version supported by Deck php class, so unless you want to rewrite db access layer go with this one&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE TABLE IF NOT EXISTS `card` (&lt;br /&gt;
  `card_id` int(10) unsigned NOT NULL AUTO_INCREMENT,&lt;br /&gt;
  `card_type` varchar(16) NOT NULL,&lt;br /&gt;
  `card_type_arg` int(11) NOT NULL,&lt;br /&gt;
  `card_location` varchar(16) NOT NULL,&lt;br /&gt;
  `card_location_arg` int(11) NOT NULL,&lt;br /&gt;
  PRIMARY KEY (`card_id`)&lt;br /&gt;
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: if you using this schema, some zones/locations have special semantic. The &#039;hand&#039; location is actually multiple locations - one per player, but player id is encoded as card_location_arg. If &#039;hand&#039; in your game is ordered, visible or can have some other card states, you cannot use hand location (replacement is hand_&amp;lt;player_id&amp;gt; or hand_&amp;lt;color_id&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
== Code Organization ==&lt;br /&gt;
&lt;br /&gt;
=== Including your own JavaScript module ===&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, modules/ggg_other.js&lt;br /&gt;
&lt;br /&gt;
* Create ggg_other.js in modules/ folder and sync&lt;br /&gt;
* Modify ggg.js to include it&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  define([ &amp;quot;dojo&amp;quot;, &amp;quot;dojo/_base/declare&amp;quot;, &amp;quot;ebg/core/gamegui&amp;quot;, &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
    // load my own module!!!&lt;br /&gt;
    g_gamethemeurl + &amp;quot;modules/ggg_other.js&amp;quot; ], function(dojo,&lt;br /&gt;
        declare) {&lt;br /&gt;
&lt;br /&gt;
=== Including your own JavaScript module (II) ===&lt;br /&gt;
&lt;br /&gt;
* Create ggg_other.js in modules/ folder and sync&lt;br /&gt;
&lt;br /&gt;
  define([], function () {&lt;br /&gt;
    return &amp;quot;value&amp;quot;;&lt;br /&gt;
  });&lt;br /&gt;
&lt;br /&gt;
* Modify ggg.js to include it&lt;br /&gt;
&lt;br /&gt;
  define([ &lt;br /&gt;
    &amp;quot;dojo&amp;quot;, &lt;br /&gt;
    &amp;quot;dojo/_base/declare&amp;quot;, &lt;br /&gt;
    &amp;quot;bgagame/modules/ggg_other&amp;quot;, &lt;br /&gt;
    &amp;quot;ebg/core/gamegui&amp;quot;, &lt;br /&gt;
    &amp;quot;ebg/counter&amp;quot;&lt;br /&gt;
  ], function(dojo, declare, other) {&lt;br /&gt;
  &lt;br /&gt;
  });&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
This is maybe a little bit more the idea of the AMD Loader than the first option, although the first option should work as well.&lt;br /&gt;
&lt;br /&gt;
A little explanation to this:&lt;br /&gt;
The define function loads all the modules listed in the array and calls the following function with these loaded modules as parameters.&lt;br /&gt;
By putting your module at the third position in the array it is passed as the third parameter to the function. Be aware that the modules are resolved by position only, not by name. So you can load the module &#039;&#039;&#039;ggg_other&#039;&#039;&#039; and pass it as a parameter with the name &#039;&#039;&#039;other&#039;&#039;&#039;. &#039;&#039;&#039;gamegui&#039;&#039;&#039; and &#039;&#039;&#039;counter&#039;&#039;&#039; are passed in as well, but when the parameters are not defined they are just skipped. Because these modules put their content into the global scope it does not matter and you can use them from there.&lt;br /&gt;
&lt;br /&gt;
In the example above the string &amp;quot;value&amp;quot; is passed for the parameter &#039;&#039;&#039;other&#039;&#039;&#039;, but the function in your module can return whatever you want. It can be an object, an array, something you declared with dojo.declare, you can return even functions. &lt;br /&gt;
Your module can load other modules. Just put them in the array at the beginning and pass them as parameters to your function.&lt;br /&gt;
The advantage of passing the values as parameter is that you do not need to put these values in the global scope, so they can&#039;t be collisions with values defined in other scripts or the BGA Framework.&lt;br /&gt;
&lt;br /&gt;
The dojo toolkit provides good documentation to all of its components, the complete documentation for the AMD-Loader is here:&lt;br /&gt;
https://dojotoolkit.org/documentation/tutorials/1.10/modules/index.html It should be still correct, even as it seems to be only for version 1.10&lt;br /&gt;
&lt;br /&gt;
=== Including your own PHP module ===&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.game.php, modules/ggg_other.php&lt;br /&gt;
&lt;br /&gt;
* Create ggg_other.php in modules/ folder and sync&lt;br /&gt;
* Modify ggg.game.php to include it&lt;br /&gt;
&lt;br /&gt;
 require_once (&#039;modules/ggg_other.php&#039;);&lt;br /&gt;
&lt;br /&gt;
=== Creating a test class to run PHP locally ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.game.php, stubs&lt;br /&gt;
For this you need stubs of other method you can use this for example&lt;br /&gt;
https://github.com/elaskavaia/bga-sharedcode/raw/master/misc/module/table/table.game.php&lt;br /&gt;
&lt;br /&gt;
Create another php files, i.e ggg_test.php&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
define(&amp;quot;APP_GAMEMODULE_PATH&amp;quot;, &amp;quot;misc/&amp;quot;); // include path to stubs, which defines &amp;quot;table.game.php&amp;quot; and other classes&lt;br /&gt;
require_once (&#039;eminentdomaine.game.php&#039;);&lt;br /&gt;
&lt;br /&gt;
class MyGameTest1 extends MyGame { // this is your game class defined in ggg.game.php&lt;br /&gt;
    function __construct() {&lt;br /&gt;
        parent::__construct();&lt;br /&gt;
        include &#039;../material.inc.php&#039;;// this is how this normally included, from constructor&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // override/stub methods here that access db and stuff&lt;br /&gt;
    function getGameStateValue($var) {&lt;br /&gt;
        if ($var == &#039;round&#039;)&lt;br /&gt;
            return 3;&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
$x = new MyGameTest1(); // instantiate your class&lt;br /&gt;
$p = $x-&amp;gt;getGameProgression(); // call one of the methods to test&lt;br /&gt;
if ($p != 50)&lt;br /&gt;
    echo &amp;quot;Test1: FAILED&amp;quot;;&lt;br /&gt;
else&lt;br /&gt;
    echo &amp;quot;Test1: PASSED&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Run from command line like&lt;br /&gt;
 php7 ggg_test.php&lt;br /&gt;
&lt;br /&gt;
If you do it this way - you can also use local php debugger (i.e. integrated with IDE or command line).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Avoiding code in dojo declare style ===&lt;br /&gt;
Dojo class declarations are rather bizzare and do not work with most IDEs.&lt;br /&gt;
If you want to write in plain JS with classes, you can stub all the dojo define/declare stuff&lt;br /&gt;
and hook your class into that, so the classes are outside of this mess.&lt;br /&gt;
&lt;br /&gt;
NOTE: this technique is for experienced developers, do not try it if you do not understand&lt;br /&gt;
the consequences.&lt;br /&gt;
&lt;br /&gt;
This is complete example of game .js class&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  // Testla is game name is has to be changed&lt;br /&gt;
class Testla {&lt;br /&gt;
	constructor(game) {&lt;br /&gt;
		console.log(&#039;game constructor&#039;);&lt;br /&gt;
		this.game = game;&lt;br /&gt;
		this.varfoo = new MyFoo(); // this example of class from custom module&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	setup(gamedatas) {&lt;br /&gt;
		console.log(&amp;quot;Starting game setup&amp;quot;, this.varfoo);&lt;br /&gt;
		this.gamedatas = gamedatas;&lt;br /&gt;
		this.dojo.create(&amp;quot;div&amp;quot;, { class: &#039;whiteblock&#039;, innerHTML: _(&amp;quot;hello&amp;quot;) }, &#039;thething&#039;);&lt;br /&gt;
		console.log(&amp;quot;Ending game setup&amp;quot;);&lt;br /&gt;
	};&lt;br /&gt;
	onEnteringState(stateName, args) {&lt;br /&gt;
		console.log(&#039;onEnteringState : &#039; + stateName, args);&lt;br /&gt;
		this.game.addActionButton(&#039;b1&#039;,_(&#039;Click Me&#039;), (e)=&amp;gt;this.onButtonClick(e));&lt;br /&gt;
	};&lt;br /&gt;
	onLeavingState(stateName) {&lt;br /&gt;
		console.log(&#039;onLeavingState : &#039; + stateName, args);&lt;br /&gt;
	};&lt;br /&gt;
	onUpdateActionButtons(stateName, args) {&lt;br /&gt;
		console.log(&#039;onUpdateActionButtons : &#039; + stateName, args);&lt;br /&gt;
	};&lt;br /&gt;
	onButtonClick(event) {&lt;br /&gt;
		console.log(&#039;onButtonClick&#039;,event);&lt;br /&gt;
	};&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&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;
	g_gamethemeurl + &#039;/modules/foo.js&#039; // custom module if needed&lt;br /&gt;
],&lt;br /&gt;
	function(dojo, declare) {&lt;br /&gt;
                // testla is game name is has to be changed&lt;br /&gt;
		return declare(&amp;quot;bgagame.testla&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
			constructor: function() {&lt;br /&gt;
				this.xapp = new Testla(this);&lt;br /&gt;
				this.xapp.dojo = dojo;&lt;br /&gt;
			},&lt;br /&gt;
			setup: function(gamedatas) {&lt;br /&gt;
				this.xapp.setup(gamedatas);&lt;br /&gt;
			},&lt;br /&gt;
			onEnteringState: function(stateName, args) {&lt;br /&gt;
				this.xapp.onEnteringState(stateName, args.args);&lt;br /&gt;
			},&lt;br /&gt;
			onLeavingState: function(stateName) {&lt;br /&gt;
				this.xapp.onLeavingState(stateName, args);&lt;br /&gt;
			},&lt;br /&gt;
			onUpdateActionButtons: function(stateName, args) {&lt;br /&gt;
				this.xapp.onUpdateActionButtons(stateName, args);&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;
=== More readable JS: onEnteringState ===&lt;br /&gt;
&lt;br /&gt;
If you have a lot of states onEnteringState and friends become rather wild, you can do this trick to call some method dynamically.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
     onEnteringState: function(stateName, args) {&lt;br /&gt;
       console.log(&#039;Entering state: &#039; + stateName, args);&lt;br /&gt;
&lt;br /&gt;
       // Call appropriate method&lt;br /&gt;
       var methodName = &amp;quot;onEnteringState_&amp;quot; + stateName;&lt;br /&gt;
       if (this[methodName] !== undefined) {             &lt;br /&gt;
          console.log(&#039;Calling &#039; + methodName, args.args);&lt;br /&gt;
          this[methodName](args.args);&lt;br /&gt;
       }&lt;br /&gt;
     },&lt;br /&gt;
&lt;br /&gt;
     onEnteringState_playerTurn: function(args) { // this is args directly, not args.args &lt;br /&gt;
         // process&lt;br /&gt;
     },&lt;br /&gt;
&lt;br /&gt;
     onEnteringState_playerSomethingElse: function(args) { &lt;br /&gt;
         // process&lt;br /&gt;
     },&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: since its ignores the undefined functions you don&#039;t have define function for each state, but on the other hand you cannot make typos.&lt;br /&gt;
Same applies to onUpdateActionButtons except you pass &#039;args&#039; to method, not args.args, and for onLeavingState where you don&#039;t pass anything.&lt;br /&gt;
&lt;br /&gt;
=== Frameworks and Preprocessors ===&lt;br /&gt;
&lt;br /&gt;
* [[Using Vue]] - work-in-progress guide on using the modern framework Vue.js to create a game&lt;br /&gt;
* [[Using Typescript and Scss]] - How to auto-build Typescript and SCSS files to make your code cleaner&lt;br /&gt;
&lt;br /&gt;
== Assorted Stuff ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Out-of-turn actions: Un-pass ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, ggg.game.php, ggg.action.php, states.inc.php&lt;br /&gt;
&lt;br /&gt;
In multiplayer game sometimes players passes but than they think more and want to un-Pass and redo their choice. &lt;br /&gt;
To re-active a player who passes some trickery required.&lt;br /&gt;
&lt;br /&gt;
Define a special action that does that and hook it up.&lt;br /&gt;
&lt;br /&gt;
In states.inc.php add an action to mmultipleactiveplayer state to &amp;quot;unpass&amp;quot;, lets call it &amp;quot;actionCancel&amp;quot;&lt;br /&gt;
&lt;br /&gt;
In ggg.action.php add action hook&lt;br /&gt;
    public function actionCancel() {&lt;br /&gt;
        self::setAjaxMode();&lt;br /&gt;
        $this-&amp;gt;game-&amp;gt;actionCancel();&lt;br /&gt;
        self::ajaxResponse();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
In ggg.game.php add action handler&lt;br /&gt;
    function actionCancel() {&lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;checkPossibleAction(&#039;actionCancel&#039;);&lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;setPlayersMultiactive(array ($this-&amp;gt;getCurrentPlayerId() ), &#039;error&#039;, false);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
Finally to call this in client ggg.js you would do something like:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 onUpdateActionButtons:  function(stateName, args) {&lt;br /&gt;
   if (this.isCurrentPlayerActive()) { &lt;br /&gt;
     // ...&lt;br /&gt;
   } else if (!this.isSpectator) { // player is NOT active but not spectator&lt;br /&gt;
       switch (stateName) {&lt;br /&gt;
          case &#039;playerTurnMuliPlayerState&#039;:&lt;br /&gt;
		this.addActionButton(&#039;button_unpass&#039;, _(&#039;Oh no!&#039;), &#039;onUnpass&#039;);&lt;br /&gt;
		break;&lt;br /&gt;
	}&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
				&lt;br /&gt;
 onUnpass: function(e) {&lt;br /&gt;
    this.ajaxcall(&amp;quot;/&amp;quot; + this.game_name + &amp;quot;/&amp;quot; +  this.game_name + &amp;quot;/actionCancel.html&amp;quot;, {}, this); // no checkAction!&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Although be careful that if the turn comes back to the player while he is about to click cancel, the action buttons will be updated and the player will misclick which can be quite frustrating. To avoid this, move the cancel button to another position, like to the left of pagemaintitletext:&lt;br /&gt;
  dojo.place(&#039;button_unpass&#039;, &#039;pagemaintitletext&#039;, &#039;before&#039;);&lt;br /&gt;
Being out of the generalactions div, it won&#039;t be automatically destroyed like normal buttons, so you&#039;ll have to handle that yourself in onLeavingState. You might also want to change the button color to red (blue buttons for active player only, red buttons also for inactive players?)&lt;br /&gt;
&lt;br /&gt;
Note: same technique can be used to do other out-of-turn actions, such as re-arranging cards in hand, exchanging resources, etc (i.e. if permitted by rules, such as &amp;quot;at any time player can...&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
=== Multi Step Interactions: Select Worker/Place Worker - Using Selection ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
Simple way to implement something like that without extra states is to use &amp;quot;selection&amp;quot; mechanism. When user click on worker add some sort of class into that element i.e. &#039;selected&#039; (which also have to have some indication by css i.e. outline).&lt;br /&gt;
&lt;br /&gt;
Than user can click on placement zone, you can use dojo.query for &amp;quot;selected&amp;quot; element and use it along with zone id to send data to server. If proper worker is not selected yet can give a error message using this.showMessage(...) function.&lt;br /&gt;
&lt;br /&gt;
Extra code required to properly cleanup selection between states.&lt;br /&gt;
Also when you do that sometimes you want to change the state prompt, see below &#039;Change state prompt&#039;&lt;br /&gt;
&lt;br /&gt;
=== Multi Step Interactions: Select Worker/Place Worker - Using Client States ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
I don&#039;t think its documented feature but there is a way to do client-only states, which is absolutely wonderful for few reasons&lt;br /&gt;
* When player interaction is two step process, such as select worker, place worker, or place worker, pick one of two resources of your choice&lt;br /&gt;
* When multi-step process can result of impossible situation and has to be undone (by rules)&lt;br /&gt;
* When multi-step process is triggered from multiple states (such as you can do same thing as activated card action, pass action or main action)&lt;br /&gt;
&lt;br /&gt;
So lets do Select Worker/Place Worker&lt;br /&gt;
&lt;br /&gt;
Define your server state as usual, i.e. playerMainTurn -&amp;gt; &amp;quot;You must pick up a worker&amp;quot;.&lt;br /&gt;
Now define a client state, we only need &amp;quot;name&amp;quot; and &amp;quot;descriptionmyturn&amp;quot;, lets say &amp;quot;client_playerPicksLocation&amp;quot;. Always prefix names of client state with &amp;quot;client_&amp;quot; to avoid confusion. Now we have to do the following:&lt;br /&gt;
* Have a handler for onUpdateActionButtons for playerMainTurn to activate all possible workers he can pick&lt;br /&gt;
* When player clicks workers, remember the worker in one of the members of the main class, I usually use one called this.clientStateArgs.&lt;br /&gt;
* Transition to new client state&lt;br /&gt;
  onWorker: function(e) {&lt;br /&gt;
      var id = event.currentTarget.id;&lt;br /&gt;
      dojo.stopEvent(event);&lt;br /&gt;
      ... // do validity checks&lt;br /&gt;
      this.clientStateArgs.worker_id = id;&lt;br /&gt;
      this.setClientState(&amp;quot;client_playerPicksLocation&amp;quot;, {&lt;br /&gt;
                                descriptionmyturn : _(&amp;quot;${you} must select location&amp;quot;),&lt;br /&gt;
                            });&lt;br /&gt;
   }&lt;br /&gt;
* Have a handler for onUpdateActionButtons for client_playerPicksLocation to activate all possible locations this worker can go AND add Cancel button (see below)&lt;br /&gt;
* Have a location handler which will eventually send a server request, using stored this.clientStateArgs.worker_id as worker id&lt;br /&gt;
* The cancel button should call a method to restore server state, also if you doing it for more than one state you can add this universally using this.on_client_state check&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        if (this.isCurrentPlayerActive()) {&lt;br /&gt;
          if (this.on_client_state &amp;amp;&amp;amp; !$(&#039;button_cancel&#039;)) {&lt;br /&gt;
               this.addActionButton(&#039;button_cancel&#039;, _(&#039;Cancel&#039;), dojo.hitch(this, function() {&lt;br /&gt;
                                             this.restoreServerGameState();&lt;br /&gt;
               }));&lt;br /&gt;
          }&lt;br /&gt;
        } &lt;br /&gt;
Note: usually I call my own function call this.cancelLocalStateEffects() which will do more stuff first then call restoreServerGameState(), same function is usually needs to be called when server request has failed (i.e. invalid move)&lt;br /&gt;
&lt;br /&gt;
Note: If you need more than 2 steps, you may have to do client side animation to reflect the new state, which gets trickier because you have to undo that also on cancellation.&lt;br /&gt;
&lt;br /&gt;
Code is available here [https://github.com/elaskavaia/bga-sharedcode/blob/master/sharedcode.js sharedcode.js] (its using playerTurnPlayCubes and client_selectCubeLocation).&lt;br /&gt;
&lt;br /&gt;
=== Action Stack - Using Client States ===&lt;br /&gt;
&lt;br /&gt;
Action stack required where game is very complex and use triggered effects that can &amp;quot;stack&amp;quot;. It not always actual stack, it can be queue or random access&lt;br /&gt;
Examples:&lt;br /&gt;
* Magic the Gathering - classic card game where effects go on Stack, that allows to counter spell and counter spell of counter spell (not on bga - it just example of mechanics)&lt;br /&gt;
* Ultimate Railroads - action taking game where effects can be executed in any order&lt;br /&gt;
* Lewis and Clark - card game where actions executed as queue&lt;br /&gt;
&lt;br /&gt;
There is two ways of implementing it - on the server or the client.&lt;br /&gt;
For the server see article below.&lt;br /&gt;
The requirement for client side stack is all action can be undone, which means&lt;br /&gt;
* No dice rolls&lt;br /&gt;
* No card drawn&lt;br /&gt;
* No other players interaction&lt;br /&gt;
&lt;br /&gt;
No snippets are here, as this will be too complex but basically flow is:&lt;br /&gt;
* You have a action/effect stack (queue/list) as js object attached to &amp;quot;this&amp;quot;, i.e. this.unprocessed_actions&lt;br /&gt;
* When player plays a card, worker, etc, you read the effect of that card from the material file (client copy), and place into stack&lt;br /&gt;
* Then we call dispatch method which pulls the next action from the stack and change client state accordinly,i.e.  this.setClientState(&amp;quot;client_playerGainsCubes&amp;quot;)&lt;br /&gt;
* When players acts on it - the action is removed from the stack and added to &amp;quot;server action arguments&amp;quot; list, this is another object which be used to send ajax call, i.e. this.clientStateArgs&lt;br /&gt;
* If nothing left in stack we can submit the ajax call assembling parameters from collected arguments (that can include action name)&lt;br /&gt;
* This method allows cheap undo - by restoring server state you will wipe out all user actions (but if you need intermediate aninmation you have to handle it yourself)&lt;br /&gt;
&lt;br /&gt;
Code can be found in Ultimate Railroads game (but it is random access list - so it a bit complex) and Lewis and Clark (complexity - use can always deny part of any effect)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Action Stack - Using Server States ===&lt;br /&gt;
&lt;br /&gt;
See definition of Action Stack above.&lt;br /&gt;
&lt;br /&gt;
To implement you usually need another db table that has the following fields: index of effect - which is used for sorted access, type - which is essense of the effect (i.e. collect resource), some extra arguments (i.e. resource type and resource count), and usually owner of the effect (i.e. player id)&lt;br /&gt;
The flow is:&lt;br /&gt;
* There is some initial player state, where player can play card for example&lt;br /&gt;
* Player main action - pushes the card effect on stack, which also can cause triggered effects which also go on stack&lt;br /&gt;
* After action processing is finished switch to game state which is &amp;quot;dispatcher&amp;quot;&lt;br /&gt;
* Gispatcher pulls the top effect (whatever definition of the top is), changes the active player and changes the state to appropriate player state to collect response&lt;br /&gt;
* Player state knows about the stack and pulls arguments (argX) from the effect arguments of the db&lt;br /&gt;
* Player action should clear up the top effect, and can possibly add more effects, then switch to &amp;quot;dispatcher&amp;quot; state again&lt;br /&gt;
* If stack is empty, dispatcher can either pick next player itself or use another game state which responsible for picking next player&lt;br /&gt;
&lt;br /&gt;
Code can be found in Tapestry.&lt;br /&gt;
&lt;br /&gt;
=== Changing state prompt ===&lt;br /&gt;
&lt;br /&gt;
State prompt is message displayed for player which usually comes from state description.&lt;br /&gt;
Sometimes you want to change it without changing state (one way is change state but locally, see client states above).&lt;br /&gt;
&lt;br /&gt;
Simple way just change the html&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        setMainTitle: function(text) {&lt;br /&gt;
            $(&#039;pagemaintitletext&#039;).innerHTML = text;&lt;br /&gt;
        },&lt;br /&gt;
         // usage&lt;br /&gt;
        onMeeple: function(event) {&lt;br /&gt;
              //... &lt;br /&gt;
              this.setMainTitle(_(&#039;You must select where meeple is going&#039;));&lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This however will not work with parameters and will not draw You in color, if you want this its more sophisticated:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        setDescriptionOnMyTurn : function(text) {&lt;br /&gt;
            this.gamedatas.gamestate.descriptionmyturn = text;&lt;br /&gt;
            var tpl = dojo.clone(this.gamedatas.gamestate.args);&lt;br /&gt;
            if (tpl === null) {&lt;br /&gt;
                tpl = {};&lt;br /&gt;
            }&lt;br /&gt;
            var title = &amp;quot;&amp;quot;;&lt;br /&gt;
            if (this.isCurrentPlayerActive() &amp;amp;&amp;amp; text !== null) {&lt;br /&gt;
                tpl.you = this.divYou(); &lt;br /&gt;
            }&lt;br /&gt;
            title = this.format_string_recursive(text, tpl);&lt;br /&gt;
&lt;br /&gt;
            if (!title) {&lt;br /&gt;
                this.setMainTitle(&amp;quot;&amp;amp;nbsp;&amp;quot;);&lt;br /&gt;
            } else {&lt;br /&gt;
                this.setMainTitle(title);&lt;br /&gt;
            }&lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: this method uses &#039;&#039;&#039;setMainTitle&#039;&#039;&#039; defined above and &#039;&#039;&#039;divYou&#039;&#039;&#039; defined in another section of this wiki.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Adding Image buttons ===&lt;br /&gt;
&lt;br /&gt;
Its pretty trivial but just in case you need a working function:&lt;br /&gt;
&lt;br /&gt;
ggg.js:&lt;br /&gt;
&lt;br /&gt;
                addImageActionButton: function (id, div_html, handler) { // div_html is string not node&lt;br /&gt;
                    this.addActionButton(id, div_html, handler, &#039;&#039;, false, &#039;gray&#039;); &lt;br /&gt;
                    dojo.style(id, &amp;quot;border&amp;quot;, &amp;quot;none&amp;quot;); // remove ugly border&lt;br /&gt;
                    dojo.addClass(id, &amp;quot;bgaimagebutton&amp;quot;); // add css class to do more styling&lt;br /&gt;
                    return $(id); // return node for chaining&lt;br /&gt;
                },&lt;br /&gt;
&lt;br /&gt;
Example of usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    this.addImageActionButton(&#039;button_coin&#039;,&amp;quot;&amp;lt;div class=&#039;coin&#039;&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;, ()=&amp;gt;{ alert(&#039;Ha!&#039;); });&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Assigning Player Order ===&lt;br /&gt;
Normally when game starts there is &amp;quot;natural&amp;quot; player order assigned randomly.&lt;br /&gt;
&lt;br /&gt;
If you want to deliberatly assign player order at the start of the game (for example, in a game with teams options), you can do so by retrieving the initialization-only player attribute &#039;&#039;&#039;player_table_order&#039;&#039;&#039; and using it to assign values to &#039;&#039;&#039;player_no&#039;&#039;&#039; (which is normally assigned at the start of a game in the order in which players come to the table). (See [https://en.doc.boardgamearena.com/Game_database_model:_dbmodel.sql#The_player_table Game database model] for more details.)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Example:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                // Retrieve inital player order ([0=&amp;gt;playerId1, 1=&amp;gt;playerId2, ...])&lt;br /&gt;
		$playerInitialOrder = [];&lt;br /&gt;
		foreach ($players as $playerId =&amp;gt; $player) {&lt;br /&gt;
			$playerInitialOrder[$player[&#039;player_table_order&#039;]] = $playerId;&lt;br /&gt;
		}&lt;br /&gt;
		ksort($playerInitialOrder);&lt;br /&gt;
		$playerInitialOrder = array_flip(array_values($playerInitialOrder));&lt;br /&gt;
&lt;br /&gt;
		// Player order based on &#039;playerTeams&#039; option&lt;br /&gt;
		$playerOrder = [0, 1, 2, 3];&lt;br /&gt;
		switch (self::getGameStateValue(&#039;playerTeams&#039;)) {&lt;br /&gt;
			case self::TEAM_1_2:&lt;br /&gt;
				$playerOrder = [0, 2, 1, 3];&lt;br /&gt;
				break;&lt;br /&gt;
			case self::TEAM_1_4:&lt;br /&gt;
				$playerOrder = [0, 1, 3, 2];&lt;br /&gt;
				break;&lt;br /&gt;
			case self::TEAM_RANDOM:&lt;br /&gt;
				shuffle($playerOrder);&lt;br /&gt;
				break;&lt;br /&gt;
			default:&lt;br /&gt;
			case self::TEAM_1_3:&lt;br /&gt;
				// Default order&lt;br /&gt;
				break;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
                // Create players&lt;br /&gt;
		// Note: if you added some extra field on &amp;quot;player&amp;quot; table in the database (dbmodel.sql), you can initialize it there.&lt;br /&gt;
		$sql =&lt;br /&gt;
			&#039;INSERT INTO player (player_id, player_color, player_canal, player_name, player_avatar, player_no) VALUES &#039;;&lt;br /&gt;
		$values = [];&lt;br /&gt;
&lt;br /&gt;
		foreach ($players as $playerId =&amp;gt; $player) {&lt;br /&gt;
			$color = array_shift($default_colors);&lt;br /&gt;
			$values[] =&lt;br /&gt;
				&amp;quot;(&#039;&amp;quot; .&lt;br /&gt;
				$playerId .&lt;br /&gt;
				&amp;quot;&#039;,&#039;$color&#039;,&#039;&amp;quot; .&lt;br /&gt;
				$player[&#039;player_canal&#039;] .&lt;br /&gt;
				&amp;quot;&#039;,&#039;&amp;quot; .&lt;br /&gt;
				addslashes($player[&#039;player_name&#039;]) .&lt;br /&gt;
				&amp;quot;&#039;,&#039;&amp;quot; .&lt;br /&gt;
				addslashes($player[&#039;player_avatar&#039;]) .&lt;br /&gt;
				&amp;quot;&#039;,&#039;&amp;quot; .&lt;br /&gt;
				$playerOrder[$playerInitialOrder[$playerId]] .&lt;br /&gt;
				&amp;quot;&#039;)&amp;quot;;&lt;br /&gt;
		}&lt;br /&gt;
		$sql .= implode(&#039;,&#039;, $values);&lt;br /&gt;
		self::DbQuery($sql);&lt;br /&gt;
		self::reattributeColorsBasedOnPreferences(&lt;br /&gt;
			$players,&lt;br /&gt;
			$gameinfos[&#039;player_colors&#039;]&lt;br /&gt;
		);&lt;br /&gt;
		self::reloadPlayersBasicInfos();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Send different notifications to active player vs everybody else ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
Hack alert. This is a hack. We were hoping for proper solution by bga framework.&lt;br /&gt;
&lt;br /&gt;
This will allow you to send notification with two message one for specific player and one for everybody else including spectators.&lt;br /&gt;
Note that this does not split the data - all data must be shared.&lt;br /&gt;
&lt;br /&gt;
Add this to .js file (if you already overriding it merge obviously)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/** @Override */&lt;br /&gt;
format_string_recursive: function(log, args) {&lt;br /&gt;
   if (typeof args.log_others != &#039;undefined&#039; &amp;amp;&amp;amp; typeof args.player_id != &#039;undefined&#039; &amp;amp;&amp;amp; this.player_id != args.player_id)&lt;br /&gt;
	log = args.log_others;&lt;br /&gt;
   return this.inherited(arguments); // you must call this to call super &lt;br /&gt;
},&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example of usage (from eminentdomain)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    $this-&amp;gt;notifyAllPlayers(&#039;tokenMoved&#039;, &lt;br /&gt;
             clienttranslate(&#039;${player_name} adds +2 Colonies to ${place_name}&#039;), // notification with show for player with player_id&lt;br /&gt;
             [&#039;player_id&#039;=&amp;gt;$player_id, // this is mandatory&lt;br /&gt;
             &#039;log_others&#039;=&amp;gt;clienttranslate(&#039;${player_name} adds +2 Colonies to an unknown planet&#039;), // notification will show for others&lt;br /&gt;
              ...&lt;br /&gt;
             ]);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Send transient notifications without incrementing move ID ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.php&lt;br /&gt;
&lt;br /&gt;
Hack alert. This is a hack.&lt;br /&gt;
&lt;br /&gt;
Use this if you need to send some transient notification that should not create a new move ID. The notification should be idempotent -- it should have no practical effect on the game state and would be &#039;&#039;&#039;safe to drop&#039;&#039;&#039; (e.g., it would not matter if a player never received this notification). For example, in a co-op game you want all players to see a real-time preview of some action, before the active player commits their turn.&lt;br /&gt;
&lt;br /&gt;
Doing this mainly affects the instant replay &amp;amp; archive modes. During replay, the BGA framework automatically inserts a 1.5-second pause between each &amp;quot;move&amp;quot;. With this hack, your transient notifications are not considered to be a &amp;quot;move&amp;quot;, so no pause gets added.&lt;br /&gt;
&lt;br /&gt;
; In ggg.php&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$this-&amp;gt;not_a_move_notification = true; // note: do not increase the move counter&lt;br /&gt;
$this-&amp;gt;notifyAllPlayers(&#039;cardsPreview&#039;, &#039;&#039;, $args);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: you cannot have code that send notification or even changes state after this, and you cannot reset this variable back either because it only takes effect when you exit action handling function&lt;br /&gt;
&lt;br /&gt;
=== Ajax Call wrapper ===&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
The current ajaxcall is super vebose and prone to errors, I suggest using a helper function. It does a lot of stuff you must do anyways.&lt;br /&gt;
Most beginner mistakes come from missing part of this code (which is understandstandable - this is a huge snippet to clone every time).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	ajaxcallwrapper: function(action, args, handler) {&lt;br /&gt;
		if (!args) args = []; // this allows to skip args parameter for action which do not require them&lt;br /&gt;
			&lt;br /&gt;
		args.lock = true; // this allows to avoid rapid action clicking which can cause race condition on server&lt;br /&gt;
		if (this.checkAction(action)) { // this does all the proper check that player is active and action is declared&lt;br /&gt;
			this.ajaxcall(&amp;quot;/&amp;quot; + this.game_name + &amp;quot;/&amp;quot; + this.game_name + &amp;quot;/&amp;quot; + action + &amp;quot;.html&amp;quot;, args, // this is mandatory fluff &lt;br /&gt;
				this, (result) =&amp;gt; { },  // success result handler is empty - it is never needed&lt;br /&gt;
                                               handler); // this is real result handler - it called both on success and error, it has optional param  &amp;quot;is_error&amp;quot; - you rarely need it&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   this.ajaxcallwrapper(&#039;pass&#039;); // no args&lt;br /&gt;
   this.ajaxcallwrapper(&#039;playCard&#039;, {card: card_id}); // with args&lt;br /&gt;
   this.ajaxcallwrapper(&#039;playCard&#039;, {card: card_id}, (is_error)=&amp;gt;{if (!is_error) dojo.query(&amp;quot;.selected&amp;quot;).removeClass(&#039;selected&#039;);}) // with handler that cleans up &#039;selected&#039; class on success&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: this always will lock interface and always check for action, you can modify this method to do it optionally, i.e&lt;br /&gt;
  if (args.lock!==false) args.lock = true; else delete args.lock; // it does not work with false value - it has to be removed&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Studio]]&lt;/div&gt;</summary>
		<author><name>SwHawk</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=BGA_Studio_Cookbook&amp;diff=14391</id>
		<title>BGA Studio Cookbook</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=BGA_Studio_Cookbook&amp;diff=14391"/>
		<updated>2022-08-18T18:22:25Z</updated>

		<summary type="html">&lt;p&gt;SwHawk: /* Inject images and styled html in the log */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
This page is collection of design and implementation recipes for BGA Studio framework.&lt;br /&gt;
For tooling and usage recipes see [[Tools and tips of BGA Studio]].&lt;br /&gt;
If you have your own recipes feel free to edit this page.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Visual Effects, Layout and Animation ==&lt;br /&gt;
&lt;br /&gt;
=== DOM manipulatons ===&lt;br /&gt;
&lt;br /&gt;
==== Create pieces dynamically (using template) ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg_ggg.tpl, ggg.js&lt;br /&gt;
&lt;br /&gt;
Note: this method is recommended by BGA guildlines&lt;br /&gt;
&lt;br /&gt;
Declared js template with variables in .tpl file, like this&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;
    // Javascript HTML templates&lt;br /&gt;
    var jstpl_ipiece = &#039;&amp;lt;div class=&amp;quot;${type} ${type}_${color} inlineblock&amp;quot; aria-label=&amp;quot;${name}&amp;quot; title=&amp;quot;${name}&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use it like this in .js file&lt;br /&gt;
  div = this.format_block(&#039;jstpl_ipiece&#039;, {&lt;br /&gt;
                                type : &#039;meeple&#039;,&lt;br /&gt;
                                color : &#039;ff0000&#039;,&lt;br /&gt;
                                name : &#039;Bob&#039;,&lt;br /&gt;
                            });&lt;br /&gt;
  &lt;br /&gt;
Then you do whatever you need to do with that div, this one specifically design to go to log entries, because it has embedded title (otherwise its a picture only) and no id.&lt;br /&gt;
&lt;br /&gt;
Note: you could have place this variable in js itself, but keeping it in .tpl allows you to have your js code be free of HTML. Normally it never happens but&lt;br /&gt;
it is good to strive for it.&lt;br /&gt;
Note: you can also use string concatenation, its less readable. You can also use dojo dom object creation api&#039;s but its brutally verbose and its more unreadable.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Create pieces dynamically (using string concatenation) ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
Note: Not recommended&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  div = &amp;quot;&amp;lt;div class=&#039;meeple &amp;quot;+color+&amp;quot;&#039;&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
==== Create all pieces statically ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg_ggg.tpl, ggg.css, ggg.view.php (optional) &lt;br /&gt;
&lt;br /&gt;
* Create ALL game pieces in html template (.tpl)&lt;br /&gt;
* ALL pieces should have unique id, and it should be meaningful, i.e. meeple_red_1&lt;br /&gt;
* Do not use inline styling&lt;br /&gt;
* Id of player&#039;s specific pieces should use some sort of &#039;color&#039; identification, since player id cannot be used in static layout, you can use english color name, hex 6 char value, or color &amp;quot;number&amp;quot; (1,2,3...)&lt;br /&gt;
* Pieces should have separated class for its color, type, etc, so it can be easily styled in groups. In example below you now can style all meeples, all red meeples or all red tokens, or all &amp;quot;first&amp;quot; meeples&lt;br /&gt;
&lt;br /&gt;
ggg.tpl:&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
  &amp;lt;div id=&amp;quot;home_red&amp;quot; class=&amp;quot;home_red home&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;div id=&amp;quot;meeple_red_1&amp;quot; class=&amp;quot;meeple red n1&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
     &amp;lt;div id=&amp;quot;meeple_red_2&amp;quot; class=&amp;quot;meeple red n2&amp;quot;&amp;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;
ggg.css:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.meeple {&lt;br /&gt;
	width: 32px;&lt;br /&gt;
	height: 39px;&lt;br /&gt;
	background-image: url(img/78_64_stand_meeples.png);&lt;br /&gt;
	background-size: 352px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.meeple.red {&lt;br /&gt;
	background-position: 30% 0%;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* There should be straight forward mapping between server id and js id (or 1:1)&lt;br /&gt;
* You place objects in different zones of the layout, and setup css to take care of layout&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.home .meeple{&lt;br /&gt;
   display: inline-block;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* If you need to have a temporary object that look like original you can use dojo.clone (and change id to some temp id)&lt;br /&gt;
* If there is lots of repetition or zone grid you can use template generator, but inject style declaration in css instead of inline style for flexibility&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
* If you use this model you cannot use premade js components such as Stock and Zone&lt;br /&gt;
* You have to use alternative methods of animation (slightly altered) since default method will leave object with inline style attributes which you don&#039;t need&lt;br /&gt;
&lt;br /&gt;
=== Logs ===&lt;br /&gt;
&lt;br /&gt;
==== Inject icon images in the log ====&lt;br /&gt;
&lt;br /&gt;
Here is an example of what was done for Terra Mystica which is simple and straightforward:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
//Define the proper message&lt;br /&gt;
		$message = clienttranslate(&#039;${player_name} gets ${power_income} via Structures&#039;);&lt;br /&gt;
		if ($price &amp;gt; 0) {&lt;br /&gt;
			self::DbQuery(&amp;quot;UPDATE player SET player_score = player_score - $price WHERE player_id = $player_id&amp;quot;);&lt;br /&gt;
			$message = clienttranslate(&#039;${player_name} pays ${vp_price} and gets ${power_income} via Structures&#039;);&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
// Notify&lt;br /&gt;
		self::notifyAllPlayers( &amp;quot;powerViaStructures&amp;quot;, $message, array(&lt;br /&gt;
			&#039;i18n&#039; =&amp;gt; array( ),&lt;br /&gt;
			&#039;player_id&#039; =&amp;gt; $player_id,&lt;br /&gt;
			&#039;player_name&#039; =&amp;gt; self::getUniqueValueFromDb( &amp;quot;SELECT player_name FROM player WHERE player_id = $player_id&amp;quot; ),&lt;br /&gt;
			&#039;power_tokens&#039; =&amp;gt; $power_tokens,&lt;br /&gt;
			&#039;vp_price&#039; =&amp;gt; self::getLogsVPAmount($price),&lt;br /&gt;
			&#039;power_income&#039; =&amp;gt; self::getLogsPowerAmount($power_income),&lt;br /&gt;
			&#039;newScore&#039; =&amp;gt; self::getUniqueValueFromDb( &amp;quot;SELECT player_score FROM player WHERE player_id = $player_id&amp;quot; ),&lt;br /&gt;
			&#039;counters&#039; =&amp;gt; $this-&amp;gt;getGameCounters(null),&lt;br /&gt;
		) );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With some functions to have the needed html added inside the substitution variable, such as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function getLogsPowerAmount( $amount ) {&lt;br /&gt;
		return &amp;quot;&amp;lt;div class=&#039;tmlogs_icon&#039; title=&#039;Power&#039;&amp;gt;&amp;lt;div class=&#039;power_amount&#039;&amp;gt;$amount&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: injecting html from php is not ideal but easy, if you want more clean solution, use method below but it is a lot more sophisticated.&lt;br /&gt;
&lt;br /&gt;
==== Inject images and styled html in the log ====&lt;br /&gt;
&lt;br /&gt;
{{InfoBox|title=Warning &amp;amp;emdash; Translation|maxWidth=500|topLeftColour=#c00|middleColour=#c00|bottomRightColour=#c00|body=&#039;&#039;&#039;In order to prevent interference with the translation process, keep in mind that you must only apply modifications to the args object, and not try to substitute the keys (the &amp;lt;code&amp;gt;${player_name}&amp;lt;/code&amp;gt; parts of your string) in the log string.&#039;&#039;&#039;}}&lt;br /&gt;
&lt;br /&gt;
So you want nice pictures in the game log. What do you do? The first idea that comes to mind is to send html from php in notifications (see method above). &lt;br /&gt;
&lt;br /&gt;
This is a bad idea for many reasons:&lt;br /&gt;
&lt;br /&gt;
* It&#039;s bad architecture. ui elements leak into the server, and now you have to manage the ui in multiple places.&lt;br /&gt;
* If you decided to change something in the ui in future version, replay logs for old games and tutorials may not work, since they use stored notifications.&lt;br /&gt;
* Log previews for old games become unreadable. (This is the log state before you enter the game replay, which is useful for troubleshooting and game analysis.)&lt;br /&gt;
* It&#039;s more data to transfer and store in the db.&lt;br /&gt;
* It&#039;s a nightmare for translators.&lt;br /&gt;
&lt;br /&gt;
So what else can you do? You can use client side log injection to intercept log arguments (which come from the server) and replace them with html on the client side. Here are three different method you can use to achieve this.&lt;br /&gt;
&lt;br /&gt;
===== First way : Override &amp;lt;code&amp;gt;this.format_string_recursive()&amp;lt;/code&amp;gt; method =====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, ggg.game.php&lt;br /&gt;
&lt;br /&gt;
I use this recipe for &#039;&#039;&#039;client side log injection&#039;&#039;&#039; to intercept log arguments (which come from the server) and replace them with html on the client side.&lt;br /&gt;
&lt;br /&gt;
[[File:clientloginjection.png|left]] &lt;br /&gt;
&lt;br /&gt;
ggg.js&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
        /** Override this function to inject html into log items. This is a built-in BGA method.  */&lt;br /&gt;
&lt;br /&gt;
        /* @Override */&lt;br /&gt;
        format_string_recursive : function format_string_recursive(log, args) {&lt;br /&gt;
            try {&lt;br /&gt;
                if (log &amp;amp;&amp;amp; args &amp;amp;&amp;amp; !args.processed) {&lt;br /&gt;
                    args.processed = true;&lt;br /&gt;
                    &lt;br /&gt;
&lt;br /&gt;
                    // list of special keys we want to replace with images&lt;br /&gt;
                    var keys = [&#039;place_name&#039;,&#039;token_name&#039;];&lt;br /&gt;
                    &lt;br /&gt;
                  &lt;br /&gt;
                    for ( var i in keys) {&lt;br /&gt;
                        var key = keys[i];&lt;br /&gt;
                        key in args &amp;amp;&amp;amp; args[key] = this.getTokenDiv(key, args);                            &lt;br /&gt;
&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            } catch (e) {&lt;br /&gt;
                console.error(log,args,&amp;quot;Exception thrown&amp;quot;, e.stack);&lt;br /&gt;
            }&lt;br /&gt;
            return this.inherited({callee: format_string_recursive}, arguments);&lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important:&#039;&#039;&#039; In the &#039;&#039;format_string_recursive&#039;&#039; method, the &#039;args&#039; parameter will only contain arguments passed to it from the notify method in ggg.game.php (see below).&lt;br /&gt;
&lt;br /&gt;
The &#039;log&#039; parameter is the actual string that is inserted into the logs. You can perform additional js string manipulation on it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        getTokenDiv : function(key, args) {&lt;br /&gt;
            // ... implement whatever html you want here, example from sharedcode.js&lt;br /&gt;
            var token_id = args[key];&lt;br /&gt;
            var item_type = getPart(token_id,0);&lt;br /&gt;
            var logid = &amp;quot;log&amp;quot; + (this.globalid++) + &amp;quot;_&amp;quot; + token_id;&lt;br /&gt;
            switch (item_type) {&lt;br /&gt;
                case &#039;wcube&#039;:&lt;br /&gt;
                    var tokenDiv = this.format_block(&#039;jstpl_resource_log&#039;, {&lt;br /&gt;
                        &amp;quot;id&amp;quot; : logid,&lt;br /&gt;
                        &amp;quot;type&amp;quot; : &amp;quot;wcube&amp;quot;,&lt;br /&gt;
                        &amp;quot;color&amp;quot; : getPart(token_id,1),&lt;br /&gt;
                    });&lt;br /&gt;
                    return tokenDiv;&lt;br /&gt;
             &lt;br /&gt;
                case &#039;meeple&#039;:&lt;br /&gt;
                    if ($(token_id)) {&lt;br /&gt;
                        var clone = dojo.clone($(token_id));&lt;br /&gt;
    &lt;br /&gt;
                        dojo.attr(clone, &amp;quot;id&amp;quot;, logid);&lt;br /&gt;
                        this.stripPosition(clone);&lt;br /&gt;
                        dojo.addClass(clone, &amp;quot;logitem&amp;quot;);&lt;br /&gt;
                        return clone.outerHTML;&lt;br /&gt;
                    }&lt;br /&gt;
                    break;&lt;br /&gt;
     &lt;br /&gt;
                default:&lt;br /&gt;
                    break;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            return &amp;quot;&#039;&amp;quot; + this.clienttranslate_string(this.getTokenName(token_id)) + &amp;quot;&#039;&amp;quot;;&lt;br /&gt;
       },&lt;br /&gt;
       getTokenName : function(key) {&lt;br /&gt;
           return this.gamedatas.token_types[key].name; // get name for the key, from static table for example&lt;br /&gt;
       },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that in this case the server simply injects token_id as a name, and the client substitutes it for the translated name or the picture.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ggg.game.php:&lt;br /&gt;
&lt;br /&gt;
           $this-&amp;gt;notifyAllPlayers(&#039;playerLog&#039;,clienttranslate(&#039;Game moves ${token_name}&#039;),[&#039;token_name&#039;=&amp;gt;$token_id]);&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important:&#039;&#039;&#039; As noted above, only arguments actually passed by this method are available to the args parameter received in the client-side &#039;&#039;format_string_recursive&#039;&#039; method.&lt;br /&gt;
&lt;br /&gt;
Sometimes it is the case that you want to pass arguments that are not actually included in the output message. For example, suppose we have a method like this:&lt;br /&gt;
&lt;br /&gt;
           $this-&amp;gt;notifyAllPlayers(&#039;tokenPlaced&#039;,clienttranslate(&#039;Player placed ${token_name}&#039;),array(&lt;br /&gt;
              &#039;token_name&#039; =&amp;gt; $token_id,&lt;br /&gt;
              &#039;zone_played&#039; =&amp;gt; $zone);&lt;br /&gt;
&lt;br /&gt;
This will output &amp;quot;Player placed ${token_name}&amp;quot; in the log, and if we subscribe to a notification method activated by the &amp;quot;tokenPlaced&amp;quot; event in the client-side code, that method can make use of the &#039;zone_played&#039; argument. &lt;br /&gt;
&lt;br /&gt;
Now if you want to make some really cool things with game log, most probably you would need more arguments than are included in log message. The problem with that,&lt;br /&gt;
it will work at first, but if you reload game using F5 or when the game loads in turn based mode, you will loose your additional parameters, why? Because when game reloads it does not actually send same notifications, it sends special &amp;quot;hitstorical_log&amp;quot; notification where all  parameters not listed in the message are removed. In example above, field zone_played would be removed from historical log as it is not included in message of the notification. You can till preserve specific arguments in historical log by adding special field preserve to notification arguments like this:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
           $this-&amp;gt;notifyAllPlayers(&#039;tokenPlaced&#039;,clienttranslate(&#039;Player placed ${token_name}&#039;),array(&lt;br /&gt;
              &#039;token_name&#039; =&amp;gt; $token_id,&lt;br /&gt;
              &#039;zone_played&#039; =&amp;gt; $zone,&lt;br /&gt;
              &#039;preserve&#039; =&amp;gt; [ &#039;zone_played&#039; ]&lt;br /&gt;
           );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now you can use zone_played in format_string_recursive even in historical logs.&lt;br /&gt;
&lt;br /&gt;
===== Second way: rely on the &amp;lt;code&amp;gt;:formatFunction&amp;lt;/code&amp;gt; option provided by &amp;lt;code&amp;gt;dojo.string.substitute&amp;lt;/code&amp;gt; =====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, ggg.game.php, ggg_ggg.tpl, ggg.css&lt;br /&gt;
&lt;br /&gt;
The above method will work in most of the cases, but if you use dotted keys such as &amp;lt;code&amp;gt;${card.name}&amp;lt;/code&amp;gt; (which is supported by the framework, for private state args), the key won&#039;t be substituted because the &amp;lt;code&amp;gt;key in arg&amp;lt;/code&amp;gt; test will fail. If so you need to rely either on this way, or the one after.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;WARNING:&#039;&#039;&#039; using this method on an already advanced project will require you to go through all your notifications to change keys !&lt;br /&gt;
&lt;br /&gt;
Under the hood, the &#039;&#039;&#039;this.format_string_recursive()&#039;&#039;&#039; function calls the &#039;&#039;&#039;dojo.string.substitute&#039;&#039;&#039; method which substitutes &amp;lt;code&amp;gt;${keys}&amp;lt;/code&amp;gt; with the value provided. If you take a look at the [https://dojotoolkit.org/reference-guide/1.7/dojo/string.html#substitute documentation] and [https://github.com/dojo/dojo/blob/c3ceb017cfa25b703f5662dc83d1c8aae9bc5d81/string.js#L163 source code] you can notice that the key can be suffixed with a colon (&amp;lt;code&amp;gt;:&amp;lt;/code&amp;gt;) followed by a function name. This will allow you to specify directly in the substitution string which keys need HTML injection.&lt;br /&gt;
&lt;br /&gt;
First of all, you need to define your formatting function in the ggg.js file:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[[ggg.js]]&lt;br /&gt;
        getTokenDiv : function(value, key) {&lt;br /&gt;
            //This is only an example implementation, you need to write your own.&lt;br /&gt;
            //The method should return HTML code&lt;br /&gt;
            switch (key) {&lt;br /&gt;
                case &#039;html_injected_argument1&#039;:&lt;br /&gt;
                    return this.format_block(&#039;jstpl_HTMLLogElement1&#039;,{value: value});&lt;br /&gt;
                case &#039;html_injected_argument2&#039;:&lt;br /&gt;
                    return this.format_block(&#039;jstpl_HTMLLogElement2&#039;,{value: value});&lt;br /&gt;
                ...&lt;br /&gt;
            }&lt;br /&gt;
       }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Obviously you need to define the appropriate templates in the ggg_ggg.tpl file:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[[ggg_ggg.tpl]]&lt;br /&gt;
let jstpl_HTMLLogElement1 = &#039;&amp;lt;div class=&amp;quot;log-element log-element-1-${value}&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
let jstpl_HTMLLogElement2 = &#039;&amp;lt;div class=&amp;quot;log-element log-element-2-${value}&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
And the appropriate classes in ggg.css.&lt;br /&gt;
&lt;br /&gt;
Then you need to add the &amp;lt;code&amp;gt;dojo/aspect&amp;lt;/code&amp;gt; module at the top of the ggg.js file:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[ggg.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 define([&lt;br /&gt;
     &amp;quot;dojo&amp;quot;, &amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&amp;quot;dojo/aspect&amp;quot;,&amp;lt;/span&amp;gt;                 //MUST BE IN THIRD POSITION&#039;&#039;&#039; (see [[#Including your own JavaScript module (II)|below]])&lt;br /&gt;
     &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
 ], function (dojo, declare, &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&#039;&#039;&#039;aspect&#039;&#039;&#039;&amp;lt;/span&amp;gt;) {&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
And you also need to add the following code in your &amp;lt;code&amp;gt;contructor&amp;lt;/code&amp;gt; method in the ggg.js:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[ggg.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
         constructor: function(){&lt;br /&gt;
             console.log(&#039;progressevolutiontechnologyswh constructor&#039;);&lt;br /&gt;
               &lt;br /&gt;
             // Here, you can init the global variables of your user interface&lt;br /&gt;
             // Example:&lt;br /&gt;
             // this.myGlobalValue = 0;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&#039;&#039;&#039;let gameObject = this;&#039;&#039;&#039;            //Needed as the this object in aspect.before will not refer to the game object in which the formatting function resides&lt;br /&gt;
             &#039;&#039;&#039;aspect.before(dojo.string, &amp;quot;substitute&amp;quot;, function(template, map, transform) {&#039;&#039;&#039;      //This allows you to modify the arguments of the dojo.string.substitute method before they&#039;re actually passed to it&lt;br /&gt;
                 &#039;&#039;&#039;return [template, map, transform, gameObject];&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now you&#039;re all set to inject HTML in your logs. To actually achieve this, you must specify the function name with the key like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[ggg.game.php]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 $this-&amp;gt;notifyAllPlayers(&amp;quot;notificationName&amp;quot;, clienttranslate(&amp;quot;This log message contains ${plainTextArgument} and the following will receive HTML injection: ${html_injected_argument1:getTokenDiv}&amp;quot;), [&lt;br /&gt;
     &amp;quot;plainTextArgument&amp;quot; =&amp;gt; &amp;quot;some plain text here&amp;quot;,&lt;br /&gt;
     &amp;quot;html_injected_argument1&amp;quot; =&amp;gt; &amp;quot;some value used by getTokenDiv&amp;quot;,&lt;br /&gt;
 ]);&lt;br /&gt;
&lt;br /&gt;
You&#039;re not limited writing only one function, you can write as many functions as you like, and have them each inject a specific type of HTML. You just need to specify the relevant function name after the column in the substitution key.&lt;br /&gt;
&lt;br /&gt;
===== Third way: rely on the &amp;lt;code&amp;gt;transform&amp;lt;/code&amp;gt; argument of &amp;lt;code&amp;gt;dojo.string.substitute&amp;lt;/code&amp;gt; =====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, ggg.game.php, ggg_ggg.tpl, ggg.css&lt;br /&gt;
&lt;br /&gt;
This method is also relying on the use of &amp;lt;code&amp;gt;dojo.string.substitute&amp;lt;/code&amp;gt; by the framework, and will use the &amp;lt;code&amp;gt;transform&amp;lt;/code&amp;gt; argument, which, accordting to [https://github.com/dojo/dojo/blob/c3ceb017cfa25b703f5662dc83d1c8aae9bc5d81/string.js#L163 source code] and [https://dojotoolkit.org/reference-guide/1.7/dojo/string.html#substitute documentation] will be run on all the messages going through dojo.string.substitute.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;WARNING:&#039;&#039;&#039; As this method will be applied to all strings that go through dojo.string.substitute. As such you must take extra care not to substitute keys that may be used by the framework (i.e. ${id}). In order to do so, a good practise would be to prefix all keys that need substitution with a trigram of the game name.&lt;br /&gt;
&lt;br /&gt;
Since all the keys will be fed to the tranform function, by default, it must return the value, substituted or not per your needs. You can define the function like this in the ggg.js file:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[ggg.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
         getTokenDiv : function(value, key) {&lt;br /&gt;
             //This is only an example implementation, you need to write your own.&lt;br /&gt;
             //The method should return HTML code&lt;br /&gt;
             switch (key) {&lt;br /&gt;
                 case &#039;html_injected_argument1&#039;:&lt;br /&gt;
                     return this.format_block(&#039;jstpl_HTMLLogElement1&#039;,{value: value});&lt;br /&gt;
                 case &#039;html_injected_argument2&#039;:&lt;br /&gt;
                     return this.format_block(&#039;jstpl_HTMLLogElement2&#039;,{value: value});&lt;br /&gt;
                 ...&lt;br /&gt;
                 &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&#039;&#039;&#039;default:&#039;&#039;&#039;&lt;br /&gt;
                     &#039;&#039;&#039;return value;&#039;&#039;&#039;&amp;lt;/span&amp;gt;                  &#039;&#039;&#039;//Needed otherwise regular strings won&#039;t appear since since the value isn&#039;t returned by the function&#039;&#039;&#039;&lt;br /&gt;
             }&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
The templates must be defined in the ggg_ggg.tpl file and the corresponding CSS classes in the ggg.css file.&lt;br /&gt;
&lt;br /&gt;
You need to add the following code at the beginning of the ggg.js file:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[ggg.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 define([&lt;br /&gt;
     &amp;quot;dojo&amp;quot;, &amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&amp;quot;dojo/aspect&amp;quot;,&amp;lt;/span&amp;gt;                 //MUST BE IN THIRD POSITION&#039;&#039;&#039; (see [[#Including your own JavaScript module (II)|below]])&lt;br /&gt;
     &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
 ], function (dojo, declare, &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&#039;&#039;&#039;aspect&#039;&#039;&#039;&amp;lt;/span&amp;gt;) {&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
And the following code to the &amp;lt;code&amp;gt;constructor&amp;lt;/code&amp;gt; method in ggg.js:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[ggg.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
         constructor: function(){&lt;br /&gt;
             console.log(&#039;progressevolutiontechnologyswh constructor&#039;);&lt;br /&gt;
               &lt;br /&gt;
             // Here, you can init the global variables of your user interface&lt;br /&gt;
             // Example:&lt;br /&gt;
             // this.myGlobalValue = 0;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&#039;&#039;&#039;let transformFunction = dojo.hitch(this, &amp;quot;getTokenDiv&amp;quot;);&#039;&#039;&#039;            //Needed as the this object in aspect.before will not refer to the game object in which the formatting function resides&lt;br /&gt;
             &#039;&#039;&#039;aspect.before(dojo.string, &amp;quot;substitute&amp;quot;, function(template, map, transform) {&#039;&#039;&#039;&lt;br /&gt;
                 &#039;&#039;&#039;if (undefined === transform) {&#039;&#039;&#039;                                   //Check for a transform function presence, just in case&lt;br /&gt;
                     &#039;&#039;&#039;return [template, map, transform];&#039;&#039;&#039;&lt;br /&gt;
                 &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then you&#039;re all set for log injection, no need to change anything on the PHP side.&lt;br /&gt;
&lt;br /&gt;
==== Processing logs on re-loading ====&lt;br /&gt;
&lt;br /&gt;
You rarely need to process logs when reloading, but if you want to do something fancy you may have to do it after logs are loaded. &lt;br /&gt;
Logs are loaded asyncronously so you have to listen for logs to be fully loaded.&lt;br /&gt;
Unfortunately there is no direct way of doing it so this is the hack.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Hack alert&#039;&#039;&#039; - this extends undocumented function and may be broken when framework is updated&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
			/*&lt;br /&gt;
  			* [Undocumented] Override BGA framework functions to call onLoadingLogsComplete when loading is done&lt;br /&gt;
                        @Override&lt;br /&gt;
   			*/&lt;br /&gt;
			setLoader: function(image_progress, logs_progress) {&lt;br /&gt;
				this.inherited(arguments); // required, this is &amp;quot;super()&amp;quot; call, do not remove&lt;br /&gt;
				//console.log(&amp;quot;loader&amp;quot;, image_progress, logs_progress)&lt;br /&gt;
				if (!this.isLoadingLogsComplete &amp;amp;&amp;amp; logs_progress &amp;gt;= 100) {&lt;br /&gt;
					this.isLoadingLogsComplete = true; // this is to prevent from calling this more then once&lt;br /&gt;
					this.onLoadingLogsComplete();&lt;br /&gt;
				}&lt;br /&gt;
			},&lt;br /&gt;
&lt;br /&gt;
			onLoadingLogsComplete: function() {&lt;br /&gt;
				console.log(&#039;Loading logs complete&#039;);&lt;br /&gt;
				// do something here&lt;br /&gt;
			},&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Player Panel ===&lt;br /&gt;
&lt;br /&gt;
==== Inserting non-player panel ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, ggg_ggg.tpl&lt;br /&gt;
&lt;br /&gt;
If you want to insert non-player panel on the right side (for example to hold extra preferences, zooming controls, etc)&lt;br /&gt;
&lt;br /&gt;
this can go pretty much anywhere in template it will be moved later&lt;br /&gt;
&lt;br /&gt;
ggg_ggg.tpl:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	&amp;lt;div class=&#039;player_board_config&#039; id=&amp;quot;player_board_config&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;!-- here is whatever you want, buttons just example --&amp;gt;&lt;br /&gt;
		&amp;lt;button id=&amp;quot;zoom-out&amp;quot; class=&amp;quot; fa fa-search-minus fa-2x config-control&amp;quot;&amp;gt;&amp;lt;/button&amp;gt;&lt;br /&gt;
		&amp;lt;button id=&amp;quot;zoom-in&amp;quot; class=&amp;quot; fa fa-search-plus fa-2x config-control&amp;quot;&amp;gt;&amp;lt;/button&amp;gt;&lt;br /&gt;
		&amp;lt;button id=&amp;quot;show-settings&amp;quot; class=&amp;quot;fa fa-cog fa-2x config-control &amp;quot;&amp;gt;&amp;lt;/button&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
some hackery required in js&lt;br /&gt;
&lt;br /&gt;
ggg.js:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* @Override */&lt;br /&gt;
	updatePlayerOrdering() {&lt;br /&gt;
		this.inherited(arguments);&lt;br /&gt;
		dojo.place(&#039;player_board_config&#039;, &#039;player_boards&#039;, &#039;first&#039;);&lt;br /&gt;
	},&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Images and Icons ===&lt;br /&gt;
&lt;br /&gt;
==== Accessing images from js ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
     // your game resources&lt;br /&gt;
     &lt;br /&gt;
     var my_img = &#039;&amp;lt;img src=&amp;quot;&#039;+g_gamethemeurl+&#039;img/cards.jpg&amp;quot;/&amp;gt;&#039;;&lt;br /&gt;
     &lt;br /&gt;
     // shared resources&lt;br /&gt;
     var my_help_img = &amp;quot;&amp;lt;img class=&#039;imgtext&#039; src=&#039;&amp;quot; + g_themeurl + &amp;quot;img/layout/help_click.png&#039; alt=&#039;action&#039; /&amp;gt; &amp;lt;span class=&#039;tooltiptext&#039;&amp;gt;&amp;quot; +&lt;br /&gt;
                    text + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== High-Definition Graphics ====&lt;br /&gt;
&lt;br /&gt;
Some users will have screens which can display text and images at a greater resolution than the usual 72 dpi, e.g. the &amp;quot;Retina&amp;quot; screens on the 5k iMac, all iPads, and high-DPI screens on laptops from many manufacturers. If you can get art assets at this size, they will make your game look extra beautiful. You &#039;&#039;could&#039;&#039; just use large graphics and scale them down, but that would increase the download time and bandwidth for users who can&#039;t display them. Instead, a good way is to prepare a separate graphics file at exactly twice the size you would use otherwise, and add &amp;quot;@2x&amp;quot; at the end of the filename, e.g. if pieces.png is 240x320, then pieces@2x.png is 480x640.&lt;br /&gt;
&lt;br /&gt;
There are two changes required in order to use the separate graphics files. First in your css, where you use a file, add a media query which overrides the original definition and uses the bigger version on devices which can display them. Ensuring that the &amp;quot;background-size&amp;quot; attribute is set means that the size of the displayed object doesn&#039;t change, but only is drawn at the improved dot pitch.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.piece {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    background-image: url(&#039;img/pieces.png&#039;);&lt;br /&gt;
    background-size:240px 320px;&lt;br /&gt;
    z-index: 10;&lt;br /&gt;
}&lt;br /&gt;
@media (-webkit-min-device-pixel-ratio: 2), (min-device-pixel-ratio: 2), (min-resolution: 192dpi)&lt;br /&gt;
{&lt;br /&gt;
    .piece {&lt;br /&gt;
        background-image: url(&#039;img/pieces@2x.png&#039;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Secondly, in your setup function in javascript, you must ensure than only the appropriate one version of the file gets pre-loaded (otherwise you more than waste the bandwidth saved by maintaining the standard-resolution file). Note that the media query is the same in both cases:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
            var isRetina = &amp;quot;(-webkit-min-device-pixel-ratio: 2), (min-device-pixel-ratio: 2), (min-resolution: 192dpi)&amp;quot;;&lt;br /&gt;
            if (window.matchMedia(isRetina).matches)&lt;br /&gt;
            {&lt;br /&gt;
                this.dontPreloadImage( &#039;pieces.png&#039; );&lt;br /&gt;
                this.dontPreloadImage( &#039;board.jpg&#039; );&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                this.dontPreloadImage( &#039;pieces@2x.png&#039; );&lt;br /&gt;
                this.dontPreloadImage( &#039;board@2x.jpg&#039; );&lt;br /&gt;
            }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using CSS to create different colors of game pieces if you have only white piece ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
background-color: #${color}; &lt;br /&gt;
background-blend-mode: multiply;&lt;br /&gt;
background-image: url( &#039;img/mypiece.png&#039;);&lt;br /&gt;
mask: url(&#039;img/mypiece.png&#039;);&lt;br /&gt;
-webkit-mask: url(&#039;img/mypiece.png&#039;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where ${color} - is color you want&lt;br /&gt;
&lt;br /&gt;
Note: piece has to be white (shades of gray). Sprite can be used too, just add add blackground-position as usuall.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Other Fluff ===&lt;br /&gt;
&lt;br /&gt;
==== Use thematic fonts ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.css&lt;br /&gt;
&lt;br /&gt;
Sometime game elements use specific fonts of text, if you want to match it up you can load some specific font (IMPORTANT: from some &#039;&#039;&#039;free font&#039;&#039;&#039; source. See notes below).&lt;br /&gt;
&lt;br /&gt;
[[File:Dragonline_font.png]]&lt;br /&gt;
&lt;br /&gt;
.css&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* latin-ext */&lt;br /&gt;
@font-face {&lt;br /&gt;
  font-family: &#039;Qwigley&#039;;&lt;br /&gt;
  font-style: normal;&lt;br /&gt;
  font-weight: 400;&lt;br /&gt;
  src: local(&#039;Qwigley&#039;), local(&#039;Qwigley-Regular&#039;), url(https://fonts.gstatic.com/s/qwigley/v6/2Dy1Unur1HJoklbsg4iPJ_Y6323mHUZFJMgTvxaG2iE.woff2) format(&#039;woff2&#039;);&lt;br /&gt;
  unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;&lt;br /&gt;
}&lt;br /&gt;
/* latin */&lt;br /&gt;
@font-face {&lt;br /&gt;
  font-family: &#039;Qwigley&#039;;&lt;br /&gt;
  font-style: normal;&lt;br /&gt;
  font-weight: normal;&lt;br /&gt;
  src: local(&#039;Qwigley&#039;), local(&#039;Qwigley-Regular&#039;), url(https://fonts.gstatic.com/s/qwigley/v6/gThgNuQB0o5ITpgpLi4Zpw.woff2) format(&#039;woff2&#039;);&lt;br /&gt;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;&lt;br /&gt;
}&lt;br /&gt;
@font-face {&lt;br /&gt;
  font-family: &#039;Qwigley&#039;;&lt;br /&gt;
  font-style: normal;&lt;br /&gt;
  font-weight: normal;&lt;br /&gt;
  src: local(&#039;Qwigley&#039;), local(&#039;Qwigley-Regular&#039;), url(http://ff.static.1001fonts.net/q/w/qwigley.regular.ttf) format(&#039;ttf&#039;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.zone_title {&lt;br /&gt;
	display: inline-block;&lt;br /&gt;
	position: absolute;&lt;br /&gt;
	font: italic 32px/32px &amp;quot;Qwigley&amp;quot;, cursive;	   &lt;br /&gt;
	height: 32px;&lt;br /&gt;
	width: auto;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NB:&#039;&#039;&#039; if you need to include a font that&#039;s not available online, an extra action will be needed from an admin. Please include the font file(s) in your img directory, and mention it to admins when requesting your game to be moved to alpha. &#039;&#039;&#039;Please remember that the font has to be free, and include a .txt with all appropriate license information about the font.&#039;&#039;&#039;&lt;br /&gt;
You can look for free fonts (for example) on https://fonts.google.com or https://www.fontsquirrel.com/)&lt;br /&gt;
&lt;br /&gt;
=== Use player color in template ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg_ggg.tpl, ggg.view.php&lt;br /&gt;
&lt;br /&gt;
.view.php:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    function build_page($viewArgs) {&lt;br /&gt;
        // Get players &amp;amp; players number&lt;br /&gt;
        $players = $this-&amp;gt;game-&amp;gt;loadPlayersBasicInfos();&lt;br /&gt;
        $players_nbr = count($players);&lt;br /&gt;
        /**&lt;br /&gt;
         * ********* Place your code below: ***********&lt;br /&gt;
         */&lt;br /&gt;
        &lt;br /&gt;
        // Set PCOLOR to the current player color hex&lt;br /&gt;
        global $g_user;&lt;br /&gt;
        $cplayer = $g_user-&amp;gt;get_id();&lt;br /&gt;
        if (array_key_exists($cplayer, $players)) { // may be not set if spectator&lt;br /&gt;
            $player_color = $players [$cplayer] [&#039;player_color&#039;];&lt;br /&gt;
        } else {&lt;br /&gt;
            $player_color = &#039;ffffff&#039;; // spectator&lt;br /&gt;
        }&lt;br /&gt;
        $this-&amp;gt;tpl [&#039;PCOLOR&#039;] = $player_color;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Scale to fit for big boards ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg_ggg.tpl, ggg.js&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Lets say you have huge game board, and lets say you want it to be 1400px wide. Besides the board there will be side bar which is 240 and trim. &lt;br /&gt;
My display is 1920 wide so it fits, but there is big chance other people won&#039;t have that width. What do you do?&lt;br /&gt;
&lt;br /&gt;
You have to decide:&lt;br /&gt;
* If board does not fit you want scale whole thing down, the best way is probably use viewport (see https://en.doc.boardgamearena.com/Your_game_mobile_version)&lt;br /&gt;
* You can leave the board as is and make sure it is scrollable horizonatally&lt;br /&gt;
* You add custom scale just for the board (can add user controls  - and hook to transform: scale())&lt;br /&gt;
&lt;br /&gt;
I tried to auto-scale but this just does work, too many variables - browser zoom, 3d mode, viewport, custom bga scaling, devicePixelRatio - all create some impossible coctail of zooming...&lt;br /&gt;
Here is scaling functing for custom user scaling&lt;br /&gt;
&lt;br /&gt;
ggg_ggg.tpl:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   &amp;lt;div id=&amp;quot;thething&amp;quot; class=&amp;quot;thething&amp;quot;&amp;gt;&lt;br /&gt;
            ... everything else you declare ...&lt;br /&gt;
   &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ggg.js:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    onZoomPlus: function() {&lt;br /&gt;
       this.my_zoom+=0.1;&lt;br /&gt;
       this.zoommy(&#039;thething&#039;,this.my_zoom);&lt;br /&gt;
    },&lt;br /&gt;
&lt;br /&gt;
    zoommy: function(node, zoom) {&lt;br /&gt;
                node=$(node);&lt;br /&gt;
		var width = 100 / zoom;&lt;br /&gt;
		node.style.transformOrigin = &amp;quot;0 0&amp;quot;;&lt;br /&gt;
		node.style.transform = &amp;quot;scale(&amp;quot; + zoom + &amp;quot;)&amp;quot;;&lt;br /&gt;
		node.style.width = width + &amp;quot;%&amp;quot;;&lt;br /&gt;
    },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Dynamic tooltips ===&lt;br /&gt;
&lt;br /&gt;
If you really need a dynamic tooltip you can use this technique. (Only use it if the static tooltips provided by the BGA framework are not sufficient.)&lt;br /&gt;
&lt;br /&gt;
            new dijit.Tooltip({&lt;br /&gt;
                connectId: [&amp;quot;divItemId&amp;quot;],&lt;br /&gt;
                getContent: function(matchedNode){&lt;br /&gt;
                    return &amp;quot;... calculated ...&amp;quot;; &lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is an out-of-the-box djit.Tooltip. It has a &#039;&#039;getContent&#039;&#039; method which is called dynamically.&lt;br /&gt;
&lt;br /&gt;
The string function return becomes the innerHTML of the tooltip, so it can be anything. In this example matchedNode is a dojo node representing dom object with id of &amp;quot;divItemId&amp;quot; but there are more parameters which I am not posting here which allows more sophisticated subnode queries (i.e. you can attach tooltip to all nodes with class or whatever).&lt;br /&gt;
&lt;br /&gt;
[https://dojotoolkit.org/reference-guide/1.10/dijit/Tooltip.html dijit.Tooltip]&lt;br /&gt;
&lt;br /&gt;
It&#039;s not part of the BGA API so use at your own risk.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Rendering text with players color and proper background ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
This example actually writes &amp;quot;You&amp;quot; but you can replace this with player name as easily, drop translating function in this case&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        /* Implementation of proper colored You with background in case of white or light colors  */&lt;br /&gt;
 &lt;br /&gt;
        divYou : function() {&lt;br /&gt;
            var color = this.gamedatas.players[this.player_id].color;&lt;br /&gt;
            var color_bg = &amp;quot;&amp;quot;;&lt;br /&gt;
            if (this.gamedatas.players[this.player_id] &amp;amp;&amp;amp; this.gamedatas.players[this.player_id].color_back) {&lt;br /&gt;
                color_bg = &amp;quot;background-color:#&amp;quot; + this.gamedatas.players[this.player_id].color_back + &amp;quot;;&amp;quot;;&lt;br /&gt;
            }&lt;br /&gt;
            var you = &amp;quot;&amp;lt;span style=\&amp;quot;font-weight:bold;color:#&amp;quot; + color + &amp;quot;;&amp;quot; + color_bg + &amp;quot;\&amp;quot;&amp;gt;&amp;quot; + __(&amp;quot;lang_mainsite&amp;quot;, &amp;quot;You&amp;quot;) + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
            return you;&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Cool realistic shadow effect with CSS ===&lt;br /&gt;
&lt;br /&gt;
==== Rectangles and circles ====&lt;br /&gt;
&lt;br /&gt;
It is often nice to have a drop shadow around tiles and tokens, to separate them from the table visually. It is very easy to add a shadow to rectangular elements, just add this to your css:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.xxx-tile {&lt;br /&gt;
    box-shadow: 3px 3px 3px #000000a0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
box-shadow obeys &#039;&#039;&#039;border-radius&#039;&#039;&#039; of the element, so it will look good for rounded rectangles, and hence also circles (if border-radius is set appropriately).&lt;br /&gt;
&lt;br /&gt;
box-shadow also supports various other parameters and can be used to achieve effects such as glowing, borders, inner shadows etc. If you need to animate a box-shadow, you may be able to get better performance (avoiding redraws) if you attach the shadow to another element (possibly an ::after pseudo-element) and change only the &#039;&#039;&#039;opacity&#039;&#039;&#039; of that element.&lt;br /&gt;
&lt;br /&gt;
==== Irregular Shapes ====&lt;br /&gt;
&lt;br /&gt;
If you wish to make a shadow effect for game pieces that are not a rectangle, but your game pieces are drawn from rectangles in a PNG image, you can apply the shadow to the piece using any art package and save it inside the image. This usually will yield the best performance. Remember to account for the size of the shadow when you lay out images in the sprite sheet.&lt;br /&gt;
&lt;br /&gt;
However that sometimes will not be an option, for example if the image needs to be rotated while the shadow remains offset in the same direction. In this case, one option is to not use box-shadow but use filter, which is supported by recent major browsers.  This way, you can use the alpha channel of your element to drop a shadow.  This even work for transparent backgrounds, so that if you are using the &amp;quot;CSS-sprite&amp;quot; method, it will work!&lt;br /&gt;
&lt;br /&gt;
For instance:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.xxx-token {&lt;br /&gt;
    filter: drop-shadow(0px 0px 1px #000000);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beware that some browsers still do not always draw drop-shadow correctly. In particular, Safari frequently leaves bits of shadow behind when objects move around the screen. In Chrome, shadows sometimes flicker badly if another element is animating close by. Some of these correctness issues can be solved by adding &#039;&#039;&#039;isolation: isolate; will-change: filter;&#039;&#039;&#039; to affected elements, but this significantly affects redraw performance.&lt;br /&gt;
&lt;br /&gt;
Beware of performance issues - particularly on Safari (MacOS, iPhone and iPad). Keep in mind that drop-shadow are very GPU intensive. This becomes noticeable once you have about 40 components with drop-shadow filter. If that is your case, you can quite easily implement a user preference to disable shadows for users on slower machines:&lt;br /&gt;
&lt;br /&gt;
gameoptions.inc.php&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
100 =&amp;gt; array(&lt;br /&gt;
			&#039;name&#039; =&amp;gt; totranslate(&#039;Shadows&#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;Enabled&#039; ), &#039;cssPref&#039; =&amp;gt; &#039;&#039; ),&lt;br /&gt;
					2 =&amp;gt; array( &#039;name&#039; =&amp;gt; totranslate( &#039;Disabled&#039; ), &#039;cssPref&#039; =&amp;gt; &#039;no-shadow&#039; )&lt;br /&gt;
			)&lt;br /&gt;
	),&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[game].css&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.no-shadow * {&lt;br /&gt;
	filter: none !important; &lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Shadows with clip-path ====&lt;br /&gt;
&lt;br /&gt;
For some reason, a shadow will not work together with clip-path on one element. To use both clip-path (when for example using .svg to cut out cardboard components from your .jpg spritesheet) and drop-shadow, you need to wrap the element into another one, and apply drop-shadow to the outer one, and clip-path to the inner one.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;div class=&#039;my-token-wrap&#039;&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&#039;my-token&#039;&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;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.my-token-wrap {&lt;br /&gt;
    filter: drop-shadow(0px 0px 1px #000000);&lt;br /&gt;
}&lt;br /&gt;
.my-token-wrap .my-token {&lt;br /&gt;
    clip-path: url(#my-token-path);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Using the CSS classes from the state machine ===&lt;br /&gt;
&lt;br /&gt;
If you need to hide or show stuff depending on the state of your game, you can of course use javascript, but CSS is hand enough for that.  The #overall-content element does change class depending on the game state.  For instance, if you are in state &#039;&#039;playerTurn&#039;&#039;, it will have the class &#039;&#039;gamestate_playerTurn&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
So now, if you want to show the discard pile only during player turns, you may use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#discard_pile { display: none }&lt;br /&gt;
.gamestate_playerTurn #discard_pile { display: block }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This can be used if you want to change sizing of elements, position, layout or visual appearance.&lt;br /&gt;
&lt;br /&gt;
== Game Model and Database design ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Database for The euro game ===&lt;br /&gt;
Lets say we have a game with workers, dice, tokens, board, resources, money and vp. Workers and dice can be placed in various zones on the board, and you can get resources, money, tokens and vp in your home zone. Also tokens can be flipped or not flipped.&lt;br /&gt;
&lt;br /&gt;
[[File:Madeira board.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now lets try to map it, we have&lt;br /&gt;
* (meeple,zone)&lt;br /&gt;
* (die, zone, sideup)&lt;br /&gt;
* (resource cube/money token/vp token,player home zone)&lt;br /&gt;
* (token, player home zone, flip state)&lt;br /&gt;
We can notice that resource and money are uncountable, and don&#039;t need to be track individually so we can replace our mapping to&lt;br /&gt;
* (resource type/money,player home zone, count)&lt;br /&gt;
And vp stored already for us in player table, so we can remove it from that list.&lt;br /&gt;
&lt;br /&gt;
Now when we get to encode it we can see that everything can be encoded as (object,zone,state) form, where object and zone is string and state is integer. The resource mapping is slightly different semantically so you can go with two table, or counting using same table with state been used as count for resources.&lt;br /&gt;
&lt;br /&gt;
So the piece mapping for non-grid based games can be in most case represented by (string: token_key, string: token_location, int: token_state), example of such database schema can be found here: [https://github.com/elaskavaia/bga-sharedcode/blob/master/dbmodel.sql dbmodel.sql] and class implementing access to it here [https://github.com/elaskavaia/bga-sharedcode/blob/master/modules/tokens.php table.game.php].&lt;br /&gt;
&lt;br /&gt;
Variant 1: Minimalistic&lt;br /&gt;
&lt;br /&gt;
 CREATE TABLE IF NOT EXISTS `token` (&lt;br /&gt;
  `token_key` varchar(32) NOT NULL,&lt;br /&gt;
  `token_location` varchar(32) NOT NULL,&lt;br /&gt;
  `token_state` int(10),&lt;br /&gt;
  PRIMARY KEY (`token_key`)&lt;br /&gt;
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+token&lt;br /&gt;
! token_key&lt;br /&gt;
! token_location&lt;br /&gt;
! token_state&lt;br /&gt;
|-&lt;br /&gt;
|meeple_red_1&lt;br /&gt;
|home_red&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
|dice_black_2&lt;br /&gt;
|board_guard&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
|dice_green_1&lt;br /&gt;
|board_action_mayor&lt;br /&gt;
|3&lt;br /&gt;
|-&lt;br /&gt;
|bread&lt;br /&gt;
|home_red&lt;br /&gt;
|5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Now how we represent resource counters such as bread?&lt;br /&gt;
Using same table from we simply add special counter token for bread and use state to indicate the count. Note to keep first column unique we have to add player identification for that counter, i.e. ff0000 is red player.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+token&lt;br /&gt;
! token_key&lt;br /&gt;
! token_location&lt;br /&gt;
! token_state&lt;br /&gt;
|-&lt;br /&gt;
|bread_ff0000&lt;br /&gt;
|tableau_ff0000&lt;br /&gt;
|5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See php module for this table here https://github.com/elaskavaia/bga-sharedcode/blob/master/modules/tokens.php&lt;br /&gt;
&lt;br /&gt;
Variant 2: Additional resource table, resource count for each player id&lt;br /&gt;
&lt;br /&gt;
 CREATE TABLE IF NOT EXISTS `resource` (&lt;br /&gt;
  `player_id` int(10) unsigned NOT NULL,&lt;br /&gt;
  `resource_key` varchar(32) NOT NULL,&lt;br /&gt;
  `resource_count` int(10) signed NOT NULL,&lt;br /&gt;
  PRIMARY KEY (`player_id`,`resource_key`)&lt;br /&gt;
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;&lt;br /&gt;
&lt;br /&gt;
 ALTER TABLE resource ADD CONSTRAINT fk_player_id FOREIGN KEY (player_id) REFERENCES player(player_id);&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+resource&lt;br /&gt;
! player_id&lt;br /&gt;
! resource_key&lt;br /&gt;
! resource_count&lt;br /&gt;
|-&lt;br /&gt;
|123456&lt;br /&gt;
|bread&lt;br /&gt;
|5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Variant 3: More normalised&lt;br /&gt;
&lt;br /&gt;
This version is similar to &amp;quot;card&amp;quot; table from hearts tutorial, you can also use exact cards database schema and Deck implementation for most purposes (even you not dealing with cards). &lt;br /&gt;
&lt;br /&gt;
 CREATE TABLE IF NOT EXISTS `token` (&lt;br /&gt;
  `token_id` int(10) unsigned NOT NULL AUTO_INCREMENT,&lt;br /&gt;
  `token_type` varchar(16) NOT NULL,&lt;br /&gt;
  `token_arg` int(11) NOT NULL,&lt;br /&gt;
  `token_location` varchar(32) NOT NULL,&lt;br /&gt;
  `token_state` int(10),&lt;br /&gt;
  PRIMARY KEY (`token_id`)&lt;br /&gt;
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+token&lt;br /&gt;
! token_id&lt;br /&gt;
! token_type&lt;br /&gt;
! token_arg&lt;br /&gt;
! token_location&lt;br /&gt;
! token_state&lt;br /&gt;
|-&lt;br /&gt;
|22&lt;br /&gt;
|meeple&lt;br /&gt;
|123456&lt;br /&gt;
|home_123456&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
|23&lt;br /&gt;
|dice&lt;br /&gt;
|2&lt;br /&gt;
|board_guard&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
|26&lt;br /&gt;
|dice&lt;br /&gt;
|1&lt;br /&gt;
|board_action_mayor&lt;br /&gt;
|3&lt;br /&gt;
|-&lt;br /&gt;
|49&lt;br /&gt;
|bread&lt;br /&gt;
|0&lt;br /&gt;
|home_123456&lt;br /&gt;
|5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Advantages of this would be is a bit more straightforward to do some queries in db, disadvantage its hard to read (as you can compare with previous example, you&lt;br /&gt;
cannot just look at say, ah I know what it means). Another questionable advantage is it allows you to do id randomisation, so it hard to do crafted queries to &lt;br /&gt;
cheat, the down side of that you cannot understand it either, and handcraft db states for debugging or testing.&lt;br /&gt;
&lt;br /&gt;
=== Database for The card game ===&lt;br /&gt;
&lt;br /&gt;
Lets say you have a standard card game, player have hidden cards in hand, you can draw card from draw deck, play card on tableau and discard to discard pile.&lt;br /&gt;
We have to design database for such game.&lt;br /&gt;
&lt;br /&gt;
In real word to &amp;quot;save&amp;quot; the game we take a picture a play area, save cards from it, then put away draw deck, discard and hand of each player separately and mark it, also we will record current scoring (if any) and who&#039;s turn was it.&lt;br /&gt;
&lt;br /&gt;
* Framework handles state machine transition, so you don&#039;t have to worry about database design for that (i.e. who&#039;s turn it is, what phase of the game we are at, you still have to design it but part of state machine step)&lt;br /&gt;
* Also framework supports basic player information, color, order around the table, basic scoring, etc, so you don&#039;t have to worry about it either&lt;br /&gt;
* The only thing you need in our database is state of the &amp;quot;board&amp;quot;, which is &amp;quot;where each pieces is, and in what state&amp;quot;, or (position,rotation) pair.&lt;br /&gt;
&lt;br /&gt;
Lets see what we have for that:&lt;br /&gt;
* The card state is very simple, its usually &amp;quot;face up/face down&amp;quot;, &amp;quot;tapped/untapped&amp;quot;, &amp;quot;right side up/up side down&amp;quot;&lt;br /&gt;
* As position go we never need real coordinates x,y,z. We need to know what &amp;quot;zone&amp;quot; card was, and depending on the zone it may sometimes need an extra &amp;quot;z&amp;quot; or &amp;quot;x&amp;quot; as card order. The zone position usually static or irrelevant.&lt;br /&gt;
* So our model is: we have cards, which have some attributes, at any given point in time they belong to a &amp;quot;zone&amp;quot;, and can also have order and state&lt;br /&gt;
* Now for mapping we should consider what information changes and what information is static, later is always candidate for material file&lt;br /&gt;
* For dynamic information we should try to reduce amount of fields we need&lt;br /&gt;
**  we need at least a field for card, so its one&lt;br /&gt;
**  we need to know what zone cards belong to, its 2&lt;br /&gt;
**  and we have possibly few other fields, if you look closely at you game you may find out that most of the zone only need one attribute at a time, i.e. draw pile always have cards face down, hand always face up, also for hand and discard order does not matter at all (but for draw it does matter). So in majority of cases we can get away with one single extra integer field representing state or order&lt;br /&gt;
* In real database both card and zone will be integers as primary keys referring to additional tables, but in our case its total overkill, so they can be strings as easily&lt;br /&gt;
&lt;br /&gt;
Variant 1: Minimalistic&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE TABLE IF NOT EXISTS `card` (&lt;br /&gt;
  `card_key` varchar(32) unsigned NOT NULL,&lt;br /&gt;
  `card_location` varchar(32) NOT NULL,&lt;br /&gt;
  `card_state` int(11) NOT NULL,&lt;br /&gt;
  PRIMARY KEY (`card_id`)&lt;br /&gt;
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Variant 2: More normalised&lt;br /&gt;
&lt;br /&gt;
This version supported by Deck php class, so unless you want to rewrite db access layer go with this one&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE TABLE IF NOT EXISTS `card` (&lt;br /&gt;
  `card_id` int(10) unsigned NOT NULL AUTO_INCREMENT,&lt;br /&gt;
  `card_type` varchar(16) NOT NULL,&lt;br /&gt;
  `card_type_arg` int(11) NOT NULL,&lt;br /&gt;
  `card_location` varchar(16) NOT NULL,&lt;br /&gt;
  `card_location_arg` int(11) NOT NULL,&lt;br /&gt;
  PRIMARY KEY (`card_id`)&lt;br /&gt;
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: if you using this schema, some zones/locations have special semantic. The &#039;hand&#039; location is actually multiple locations - one per player, but player id is encoded as card_location_arg. If &#039;hand&#039; in your game is ordered, visible or can have some other card states, you cannot use hand location (replacement is hand_&amp;lt;player_id&amp;gt; or hand_&amp;lt;color_id&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
== Code Organization ==&lt;br /&gt;
&lt;br /&gt;
=== Including your own JavaScript module ===&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, modules/ggg_other.js&lt;br /&gt;
&lt;br /&gt;
* Create ggg_other.js in modules/ folder and sync&lt;br /&gt;
* Modify ggg.js to include it&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  define([ &amp;quot;dojo&amp;quot;, &amp;quot;dojo/_base/declare&amp;quot;, &amp;quot;ebg/core/gamegui&amp;quot;, &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
    // load my own module!!!&lt;br /&gt;
    g_gamethemeurl + &amp;quot;modules/ggg_other.js&amp;quot; ], function(dojo,&lt;br /&gt;
        declare) {&lt;br /&gt;
&lt;br /&gt;
=== Including your own JavaScript module (II) ===&lt;br /&gt;
&lt;br /&gt;
* Create ggg_other.js in modules/ folder and sync&lt;br /&gt;
&lt;br /&gt;
  define([], function () {&lt;br /&gt;
    return &amp;quot;value&amp;quot;;&lt;br /&gt;
  });&lt;br /&gt;
&lt;br /&gt;
* Modify ggg.js to include it&lt;br /&gt;
&lt;br /&gt;
  define([ &lt;br /&gt;
    &amp;quot;dojo&amp;quot;, &lt;br /&gt;
    &amp;quot;dojo/_base/declare&amp;quot;, &lt;br /&gt;
    &amp;quot;bgagame/modules/ggg_other&amp;quot;, &lt;br /&gt;
    &amp;quot;ebg/core/gamegui&amp;quot;, &lt;br /&gt;
    &amp;quot;ebg/counter&amp;quot;&lt;br /&gt;
  ], function(dojo, declare, other) {&lt;br /&gt;
  &lt;br /&gt;
  });&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
This is maybe a little bit more the idea of the AMD Loader than the first option, although the first option should work as well.&lt;br /&gt;
&lt;br /&gt;
A little explanation to this:&lt;br /&gt;
The define function loads all the modules listed in the array and calls the following function with these loaded modules as parameters.&lt;br /&gt;
By putting your module at the third position in the array it is passed as the third parameter to the function. Be aware that the modules are resolved by position only, not by name. So you can load the module &#039;&#039;&#039;ggg_other&#039;&#039;&#039; and pass it as a parameter with the name &#039;&#039;&#039;other&#039;&#039;&#039;. &#039;&#039;&#039;gamegui&#039;&#039;&#039; and &#039;&#039;&#039;counter&#039;&#039;&#039; are passed in as well, but when the parameters are not defined they are just skipped. Because these modules put their content into the global scope it does not matter and you can use them from there.&lt;br /&gt;
&lt;br /&gt;
In the example above the string &amp;quot;value&amp;quot; is passed for the parameter &#039;&#039;&#039;other&#039;&#039;&#039;, but the function in your module can return whatever you want. It can be an object, an array, something you declared with dojo.declare, you can return even functions. &lt;br /&gt;
Your module can load other modules. Just put them in the array at the beginning and pass them as parameters to your function.&lt;br /&gt;
The advantage of passing the values as parameter is that you do not need to put these values in the global scope, so they can&#039;t be collisions with values defined in other scripts or the BGA Framework.&lt;br /&gt;
&lt;br /&gt;
The dojo toolkit provides good documentation to all of its components, the complete documentation for the AMD-Loader is here:&lt;br /&gt;
https://dojotoolkit.org/documentation/tutorials/1.10/modules/index.html It should be still correct, even as it seems to be only for version 1.10&lt;br /&gt;
&lt;br /&gt;
=== Including your own PHP module ===&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.game.php, modules/ggg_other.php&lt;br /&gt;
&lt;br /&gt;
* Create ggg_other.php in modules/ folder and sync&lt;br /&gt;
* Modify ggg.game.php to include it&lt;br /&gt;
&lt;br /&gt;
 require_once (&#039;modules/ggg_other.php&#039;);&lt;br /&gt;
&lt;br /&gt;
=== Creating a test class to run PHP locally ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.game.php, stubs&lt;br /&gt;
For this you need stubs of other method you can use this for example&lt;br /&gt;
https://github.com/elaskavaia/bga-sharedcode/raw/master/misc/module/table/table.game.php&lt;br /&gt;
&lt;br /&gt;
Create another php files, i.e ggg_test.php&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
define(&amp;quot;APP_GAMEMODULE_PATH&amp;quot;, &amp;quot;misc/&amp;quot;); // include path to stubs, which defines &amp;quot;table.game.php&amp;quot; and other classes&lt;br /&gt;
require_once (&#039;eminentdomaine.game.php&#039;);&lt;br /&gt;
&lt;br /&gt;
class MyGameTest1 extends MyGame { // this is your game class defined in ggg.game.php&lt;br /&gt;
    function __construct() {&lt;br /&gt;
        parent::__construct();&lt;br /&gt;
        include &#039;../material.inc.php&#039;;// this is how this normally included, from constructor&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // override/stub methods here that access db and stuff&lt;br /&gt;
    function getGameStateValue($var) {&lt;br /&gt;
        if ($var == &#039;round&#039;)&lt;br /&gt;
            return 3;&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
$x = new MyGameTest1(); // instantiate your class&lt;br /&gt;
$p = $x-&amp;gt;getGameProgression(); // call one of the methods to test&lt;br /&gt;
if ($p != 50)&lt;br /&gt;
    echo &amp;quot;Test1: FAILED&amp;quot;;&lt;br /&gt;
else&lt;br /&gt;
    echo &amp;quot;Test1: PASSED&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Run from command line like&lt;br /&gt;
 php7 ggg_test.php&lt;br /&gt;
&lt;br /&gt;
If you do it this way - you can also use local php debugger (i.e. integrated with IDE or command line).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Avoiding code in dojo declare style ===&lt;br /&gt;
Dojo class declarations are rather bizzare and do not work with most IDEs.&lt;br /&gt;
If you want to write in plain JS with classes, you can stub all the dojo define/declare stuff&lt;br /&gt;
and hook your class into that, so the classes are outside of this mess.&lt;br /&gt;
&lt;br /&gt;
NOTE: this technique is for experienced developers, do not try it if you do not understand&lt;br /&gt;
the consequences.&lt;br /&gt;
&lt;br /&gt;
This is complete example of game .js class&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  // Testla is game name is has to be changed&lt;br /&gt;
class Testla {&lt;br /&gt;
	constructor(game) {&lt;br /&gt;
		console.log(&#039;game constructor&#039;);&lt;br /&gt;
		this.game = game;&lt;br /&gt;
		this.varfoo = new MyFoo(); // this example of class from custom module&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	setup(gamedatas) {&lt;br /&gt;
		console.log(&amp;quot;Starting game setup&amp;quot;, this.varfoo);&lt;br /&gt;
		this.gamedatas = gamedatas;&lt;br /&gt;
		this.dojo.create(&amp;quot;div&amp;quot;, { class: &#039;whiteblock&#039;, innerHTML: _(&amp;quot;hello&amp;quot;) }, &#039;thething&#039;);&lt;br /&gt;
		console.log(&amp;quot;Ending game setup&amp;quot;);&lt;br /&gt;
	};&lt;br /&gt;
	onEnteringState(stateName, args) {&lt;br /&gt;
		console.log(&#039;onEnteringState : &#039; + stateName, args);&lt;br /&gt;
		this.game.addActionButton(&#039;b1&#039;,_(&#039;Click Me&#039;), (e)=&amp;gt;this.onButtonClick(e));&lt;br /&gt;
	};&lt;br /&gt;
	onLeavingState(stateName) {&lt;br /&gt;
		console.log(&#039;onLeavingState : &#039; + stateName, args);&lt;br /&gt;
	};&lt;br /&gt;
	onUpdateActionButtons(stateName, args) {&lt;br /&gt;
		console.log(&#039;onUpdateActionButtons : &#039; + stateName, args);&lt;br /&gt;
	};&lt;br /&gt;
	onButtonClick(event) {&lt;br /&gt;
		console.log(&#039;onButtonClick&#039;,event);&lt;br /&gt;
	};&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&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;
	g_gamethemeurl + &#039;/modules/foo.js&#039; // custom module if needed&lt;br /&gt;
],&lt;br /&gt;
	function(dojo, declare) {&lt;br /&gt;
                // testla is game name is has to be changed&lt;br /&gt;
		return declare(&amp;quot;bgagame.testla&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
			constructor: function() {&lt;br /&gt;
				this.xapp = new Testla(this);&lt;br /&gt;
				this.xapp.dojo = dojo;&lt;br /&gt;
			},&lt;br /&gt;
			setup: function(gamedatas) {&lt;br /&gt;
				this.xapp.setup(gamedatas);&lt;br /&gt;
			},&lt;br /&gt;
			onEnteringState: function(stateName, args) {&lt;br /&gt;
				this.xapp.onEnteringState(stateName, args.args);&lt;br /&gt;
			},&lt;br /&gt;
			onLeavingState: function(stateName) {&lt;br /&gt;
				this.xapp.onLeavingState(stateName, args);&lt;br /&gt;
			},&lt;br /&gt;
			onUpdateActionButtons: function(stateName, args) {&lt;br /&gt;
				this.xapp.onUpdateActionButtons(stateName, args);&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;
=== More readable JS: onEnteringState ===&lt;br /&gt;
&lt;br /&gt;
If you have a lot of states onEnteringState and friends become rather wild, you can do this trick to call some method dynamically.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
     onEnteringState: function(stateName, args) {&lt;br /&gt;
       console.log(&#039;Entering state: &#039; + stateName, args);&lt;br /&gt;
&lt;br /&gt;
       // Call appropriate method&lt;br /&gt;
       var methodName = &amp;quot;onEnteringState_&amp;quot; + stateName;&lt;br /&gt;
       if (this[methodName] !== undefined) {             &lt;br /&gt;
          console.log(&#039;Calling &#039; + methodName, args.args);&lt;br /&gt;
          this[methodName](args.args);&lt;br /&gt;
       }&lt;br /&gt;
     },&lt;br /&gt;
&lt;br /&gt;
     onEnteringState_playerTurn: function(args) { // this is args directly, not args.args &lt;br /&gt;
         // process&lt;br /&gt;
     },&lt;br /&gt;
&lt;br /&gt;
     onEnteringState_playerSomethingElse: function(args) { &lt;br /&gt;
         // process&lt;br /&gt;
     },&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: since its ignores the undefined functions you don&#039;t have define function for each state, but on the other hand you cannot make typos.&lt;br /&gt;
Same applies to onUpdateActionButtons except you pass &#039;args&#039; to method, not args.args, and for onLeavingState where you don&#039;t pass anything.&lt;br /&gt;
&lt;br /&gt;
=== Frameworks and Preprocessors ===&lt;br /&gt;
&lt;br /&gt;
* [[Using Vue]] - work-in-progress guide on using the modern framework Vue.js to create a game&lt;br /&gt;
* [[Using Typescript and Scss]] - How to auto-build Typescript and SCSS files to make your code cleaner&lt;br /&gt;
&lt;br /&gt;
== Assorted Stuff ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Out-of-turn actions: Un-pass ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, ggg.game.php, ggg.action.php, states.inc.php&lt;br /&gt;
&lt;br /&gt;
In multiplayer game sometimes players passes but than they think more and want to un-Pass and redo their choice. &lt;br /&gt;
To re-active a player who passes some trickery required.&lt;br /&gt;
&lt;br /&gt;
Define a special action that does that and hook it up.&lt;br /&gt;
&lt;br /&gt;
In states.inc.php add an action to mmultipleactiveplayer state to &amp;quot;unpass&amp;quot;, lets call it &amp;quot;actionCancel&amp;quot;&lt;br /&gt;
&lt;br /&gt;
In ggg.action.php add action hook&lt;br /&gt;
    public function actionCancel() {&lt;br /&gt;
        self::setAjaxMode();&lt;br /&gt;
        $this-&amp;gt;game-&amp;gt;actionCancel();&lt;br /&gt;
        self::ajaxResponse();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
In ggg.game.php add action handler&lt;br /&gt;
    function actionCancel() {&lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;checkPossibleAction(&#039;actionCancel&#039;);&lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;setPlayersMultiactive(array ($this-&amp;gt;getCurrentPlayerId() ), &#039;error&#039;, false);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
Finally to call this in client ggg.js you would do something like:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 onUpdateActionButtons:  function(stateName, args) {&lt;br /&gt;
   if (this.isCurrentPlayerActive()) { &lt;br /&gt;
     // ...&lt;br /&gt;
   } else if (!this.isSpectator) { // player is NOT active but not spectator&lt;br /&gt;
       switch (stateName) {&lt;br /&gt;
          case &#039;playerTurnMuliPlayerState&#039;:&lt;br /&gt;
		this.addActionButton(&#039;button_unpass&#039;, _(&#039;Oh no!&#039;), &#039;onUnpass&#039;);&lt;br /&gt;
		break;&lt;br /&gt;
	}&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
				&lt;br /&gt;
 onUnpass: function(e) {&lt;br /&gt;
    this.ajaxcall(&amp;quot;/&amp;quot; + this.game_name + &amp;quot;/&amp;quot; +  this.game_name + &amp;quot;/actionCancel.html&amp;quot;, {}, this); // no checkAction!&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Although be careful that if the turn comes back to the player while he is about to click cancel, the action buttons will be updated and the player will misclick which can be quite frustrating. To avoid this, move the cancel button to another position, like to the left of pagemaintitletext:&lt;br /&gt;
  dojo.place(&#039;button_unpass&#039;, &#039;pagemaintitletext&#039;, &#039;before&#039;);&lt;br /&gt;
Being out of the generalactions div, it won&#039;t be automatically destroyed like normal buttons, so you&#039;ll have to handle that yourself in onLeavingState. You might also want to change the button color to red (blue buttons for active player only, red buttons also for inactive players?)&lt;br /&gt;
&lt;br /&gt;
Note: same technique can be used to do other out-of-turn actions, such as re-arranging cards in hand, exchanging resources, etc (i.e. if permitted by rules, such as &amp;quot;at any time player can...&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
=== Multi Step Interactions: Select Worker/Place Worker - Using Selection ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
Simple way to implement something like that without extra states is to use &amp;quot;selection&amp;quot; mechanism. When user click on worker add some sort of class into that element i.e. &#039;selected&#039; (which also have to have some indication by css i.e. outline).&lt;br /&gt;
&lt;br /&gt;
Than user can click on placement zone, you can use dojo.query for &amp;quot;selected&amp;quot; element and use it along with zone id to send data to server. If proper worker is not selected yet can give a error message using this.showMessage(...) function.&lt;br /&gt;
&lt;br /&gt;
Extra code required to properly cleanup selection between states.&lt;br /&gt;
Also when you do that sometimes you want to change the state prompt, see below &#039;Change state prompt&#039;&lt;br /&gt;
&lt;br /&gt;
=== Multi Step Interactions: Select Worker/Place Worker - Using Client States ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
I don&#039;t think its documented feature but there is a way to do client-only states, which is absolutely wonderful for few reasons&lt;br /&gt;
* When player interaction is two step process, such as select worker, place worker, or place worker, pick one of two resources of your choice&lt;br /&gt;
* When multi-step process can result of impossible situation and has to be undone (by rules)&lt;br /&gt;
* When multi-step process is triggered from multiple states (such as you can do same thing as activated card action, pass action or main action)&lt;br /&gt;
&lt;br /&gt;
So lets do Select Worker/Place Worker&lt;br /&gt;
&lt;br /&gt;
Define your server state as usual, i.e. playerMainTurn -&amp;gt; &amp;quot;You must pick up a worker&amp;quot;.&lt;br /&gt;
Now define a client state, we only need &amp;quot;name&amp;quot; and &amp;quot;descriptionmyturn&amp;quot;, lets say &amp;quot;client_playerPicksLocation&amp;quot;. Always prefix names of client state with &amp;quot;client_&amp;quot; to avoid confusion. Now we have to do the following:&lt;br /&gt;
* Have a handler for onUpdateActionButtons for playerMainTurn to activate all possible workers he can pick&lt;br /&gt;
* When player clicks workers, remember the worker in one of the members of the main class, I usually use one called this.clientStateArgs.&lt;br /&gt;
* Transition to new client state&lt;br /&gt;
  onWorker: function(e) {&lt;br /&gt;
      var id = event.currentTarget.id;&lt;br /&gt;
      dojo.stopEvent(event);&lt;br /&gt;
      ... // do validity checks&lt;br /&gt;
      this.clientStateArgs.worker_id = id;&lt;br /&gt;
      this.setClientState(&amp;quot;client_playerPicksLocation&amp;quot;, {&lt;br /&gt;
                                descriptionmyturn : _(&amp;quot;${you} must select location&amp;quot;),&lt;br /&gt;
                            });&lt;br /&gt;
   }&lt;br /&gt;
* Have a handler for onUpdateActionButtons for client_playerPicksLocation to activate all possible locations this worker can go AND add Cancel button (see below)&lt;br /&gt;
* Have a location handler which will eventually send a server request, using stored this.clientStateArgs.worker_id as worker id&lt;br /&gt;
* The cancel button should call a method to restore server state, also if you doing it for more than one state you can add this universally using this.on_client_state check&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        if (this.isCurrentPlayerActive()) {&lt;br /&gt;
          if (this.on_client_state &amp;amp;&amp;amp; !$(&#039;button_cancel&#039;)) {&lt;br /&gt;
               this.addActionButton(&#039;button_cancel&#039;, _(&#039;Cancel&#039;), dojo.hitch(this, function() {&lt;br /&gt;
                                             this.restoreServerGameState();&lt;br /&gt;
               }));&lt;br /&gt;
          }&lt;br /&gt;
        } &lt;br /&gt;
Note: usually I call my own function call this.cancelLocalStateEffects() which will do more stuff first then call restoreServerGameState(), same function is usually needs to be called when server request has failed (i.e. invalid move)&lt;br /&gt;
&lt;br /&gt;
Note: If you need more than 2 steps, you may have to do client side animation to reflect the new state, which gets trickier because you have to undo that also on cancellation.&lt;br /&gt;
&lt;br /&gt;
Code is available here [https://github.com/elaskavaia/bga-sharedcode/blob/master/sharedcode.js sharedcode.js] (its using playerTurnPlayCubes and client_selectCubeLocation).&lt;br /&gt;
&lt;br /&gt;
=== Action Stack - Using Client States ===&lt;br /&gt;
&lt;br /&gt;
Action stack required where game is very complex and use triggered effects that can &amp;quot;stack&amp;quot;. It not always actual stack, it can be queue or random access&lt;br /&gt;
Examples:&lt;br /&gt;
* Magic the Gathering - classic card game where effects go on Stack, that allows to counter spell and counter spell of counter spell (not on bga - it just example of mechanics)&lt;br /&gt;
* Ultimate Railroads - action taking game where effects can be executed in any order&lt;br /&gt;
* Lewis and Clark - card game where actions executed as queue&lt;br /&gt;
&lt;br /&gt;
There is two ways of implementing it - on the server or the client.&lt;br /&gt;
For the server see article below.&lt;br /&gt;
The requirement for client side stack is all action can be undone, which means&lt;br /&gt;
* No dice rolls&lt;br /&gt;
* No card drawn&lt;br /&gt;
* No other players interaction&lt;br /&gt;
&lt;br /&gt;
No snippets are here, as this will be too complex but basically flow is:&lt;br /&gt;
* You have a action/effect stack (queue/list) as js object attached to &amp;quot;this&amp;quot;, i.e. this.unprocessed_actions&lt;br /&gt;
* When player plays a card, worker, etc, you read the effect of that card from the material file (client copy), and place into stack&lt;br /&gt;
* Then we call dispatch method which pulls the next action from the stack and change client state accordinly,i.e.  this.setClientState(&amp;quot;client_playerGainsCubes&amp;quot;)&lt;br /&gt;
* When players acts on it - the action is removed from the stack and added to &amp;quot;server action arguments&amp;quot; list, this is another object which be used to send ajax call, i.e. this.clientStateArgs&lt;br /&gt;
* If nothing left in stack we can submit the ajax call assembling parameters from collected arguments (that can include action name)&lt;br /&gt;
* This method allows cheap undo - by restoring server state you will wipe out all user actions (but if you need intermediate aninmation you have to handle it yourself)&lt;br /&gt;
&lt;br /&gt;
Code can be found in Ultimate Railroads game (but it is random access list - so it a bit complex) and Lewis and Clark (complexity - use can always deny part of any effect)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Action Stack - Using Server States ===&lt;br /&gt;
&lt;br /&gt;
See definition of Action Stack above.&lt;br /&gt;
&lt;br /&gt;
To implement you usually need another db table that has the following fields: index of effect - which is used for sorted access, type - which is essense of the effect (i.e. collect resource), some extra arguments (i.e. resource type and resource count), and usually owner of the effect (i.e. player id)&lt;br /&gt;
The flow is:&lt;br /&gt;
* There is some initial player state, where player can play card for example&lt;br /&gt;
* Player main action - pushes the card effect on stack, which also can cause triggered effects which also go on stack&lt;br /&gt;
* After action processing is finished switch to game state which is &amp;quot;dispatcher&amp;quot;&lt;br /&gt;
* Gispatcher pulls the top effect (whatever definition of the top is), changes the active player and changes the state to appropriate player state to collect response&lt;br /&gt;
* Player state knows about the stack and pulls arguments (argX) from the effect arguments of the db&lt;br /&gt;
* Player action should clear up the top effect, and can possibly add more effects, then switch to &amp;quot;dispatcher&amp;quot; state again&lt;br /&gt;
* If stack is empty, dispatcher can either pick next player itself or use another game state which responsible for picking next player&lt;br /&gt;
&lt;br /&gt;
Code can be found in Tapestry.&lt;br /&gt;
&lt;br /&gt;
=== Changing state prompt ===&lt;br /&gt;
&lt;br /&gt;
State prompt is message displayed for player which usually comes from state description.&lt;br /&gt;
Sometimes you want to change it without changing state (one way is change state but locally, see client states above).&lt;br /&gt;
&lt;br /&gt;
Simple way just change the html&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        setMainTitle: function(text) {&lt;br /&gt;
            $(&#039;pagemaintitletext&#039;).innerHTML = text;&lt;br /&gt;
        },&lt;br /&gt;
         // usage&lt;br /&gt;
        onMeeple: function(event) {&lt;br /&gt;
              //... &lt;br /&gt;
              this.setMainTitle(_(&#039;You must select where meeple is going&#039;));&lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This however will not work with parameters and will not draw You in color, if you want this its more sophisticated:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        setDescriptionOnMyTurn : function(text) {&lt;br /&gt;
            this.gamedatas.gamestate.descriptionmyturn = text;&lt;br /&gt;
            var tpl = dojo.clone(this.gamedatas.gamestate.args);&lt;br /&gt;
            if (tpl === null) {&lt;br /&gt;
                tpl = {};&lt;br /&gt;
            }&lt;br /&gt;
            var title = &amp;quot;&amp;quot;;&lt;br /&gt;
            if (this.isCurrentPlayerActive() &amp;amp;&amp;amp; text !== null) {&lt;br /&gt;
                tpl.you = this.divYou(); &lt;br /&gt;
            }&lt;br /&gt;
            title = this.format_string_recursive(text, tpl);&lt;br /&gt;
&lt;br /&gt;
            if (!title) {&lt;br /&gt;
                this.setMainTitle(&amp;quot;&amp;amp;nbsp;&amp;quot;);&lt;br /&gt;
            } else {&lt;br /&gt;
                this.setMainTitle(title);&lt;br /&gt;
            }&lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: this method uses &#039;&#039;&#039;setMainTitle&#039;&#039;&#039; defined above and &#039;&#039;&#039;divYou&#039;&#039;&#039; defined in another section of this wiki.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Adding Image buttons ===&lt;br /&gt;
&lt;br /&gt;
Its pretty trivial but just in case you need a working function:&lt;br /&gt;
&lt;br /&gt;
ggg.js:&lt;br /&gt;
&lt;br /&gt;
                addImageActionButton: function (id, div_html, handler) { // div_html is string not node&lt;br /&gt;
                    this.addActionButton(id, div_html, handler, &#039;&#039;, false, &#039;gray&#039;); &lt;br /&gt;
                    dojo.style(id, &amp;quot;border&amp;quot;, &amp;quot;none&amp;quot;); // remove ugly border&lt;br /&gt;
                    dojo.addClass(id, &amp;quot;bgaimagebutton&amp;quot;); // add css class to do more styling&lt;br /&gt;
                    return $(id); // return node for chaining&lt;br /&gt;
                },&lt;br /&gt;
&lt;br /&gt;
Example of usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    this.addImageActionButton(&#039;button_coin&#039;,&amp;quot;&amp;lt;div class=&#039;coin&#039;&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;, ()=&amp;gt;{ alert(&#039;Ha!&#039;); });&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Assigning Player Order ===&lt;br /&gt;
Normally when game starts there is &amp;quot;natural&amp;quot; player order assigned randomly.&lt;br /&gt;
&lt;br /&gt;
If you want to deliberatly assign player order at the start of the game (for example, in a game with teams options), you can do so by retrieving the initialization-only player attribute &#039;&#039;&#039;player_table_order&#039;&#039;&#039; and using it to assign values to &#039;&#039;&#039;player_no&#039;&#039;&#039; (which is normally assigned at the start of a game in the order in which players come to the table). (See [https://en.doc.boardgamearena.com/Game_database_model:_dbmodel.sql#The_player_table Game database model] for more details.)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Example:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                // Retrieve inital player order ([0=&amp;gt;playerId1, 1=&amp;gt;playerId2, ...])&lt;br /&gt;
		$playerInitialOrder = [];&lt;br /&gt;
		foreach ($players as $playerId =&amp;gt; $player) {&lt;br /&gt;
			$playerInitialOrder[$player[&#039;player_table_order&#039;]] = $playerId;&lt;br /&gt;
		}&lt;br /&gt;
		ksort($playerInitialOrder);&lt;br /&gt;
		$playerInitialOrder = array_flip(array_values($playerInitialOrder));&lt;br /&gt;
&lt;br /&gt;
		// Player order based on &#039;playerTeams&#039; option&lt;br /&gt;
		$playerOrder = [0, 1, 2, 3];&lt;br /&gt;
		switch (self::getGameStateValue(&#039;playerTeams&#039;)) {&lt;br /&gt;
			case self::TEAM_1_2:&lt;br /&gt;
				$playerOrder = [0, 2, 1, 3];&lt;br /&gt;
				break;&lt;br /&gt;
			case self::TEAM_1_4:&lt;br /&gt;
				$playerOrder = [0, 1, 3, 2];&lt;br /&gt;
				break;&lt;br /&gt;
			case self::TEAM_RANDOM:&lt;br /&gt;
				shuffle($playerOrder);&lt;br /&gt;
				break;&lt;br /&gt;
			default:&lt;br /&gt;
			case self::TEAM_1_3:&lt;br /&gt;
				// Default order&lt;br /&gt;
				break;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
                // Create players&lt;br /&gt;
		// Note: if you added some extra field on &amp;quot;player&amp;quot; table in the database (dbmodel.sql), you can initialize it there.&lt;br /&gt;
		$sql =&lt;br /&gt;
			&#039;INSERT INTO player (player_id, player_color, player_canal, player_name, player_avatar, player_no) VALUES &#039;;&lt;br /&gt;
		$values = [];&lt;br /&gt;
&lt;br /&gt;
		foreach ($players as $playerId =&amp;gt; $player) {&lt;br /&gt;
			$color = array_shift($default_colors);&lt;br /&gt;
			$values[] =&lt;br /&gt;
				&amp;quot;(&#039;&amp;quot; .&lt;br /&gt;
				$playerId .&lt;br /&gt;
				&amp;quot;&#039;,&#039;$color&#039;,&#039;&amp;quot; .&lt;br /&gt;
				$player[&#039;player_canal&#039;] .&lt;br /&gt;
				&amp;quot;&#039;,&#039;&amp;quot; .&lt;br /&gt;
				addslashes($player[&#039;player_name&#039;]) .&lt;br /&gt;
				&amp;quot;&#039;,&#039;&amp;quot; .&lt;br /&gt;
				addslashes($player[&#039;player_avatar&#039;]) .&lt;br /&gt;
				&amp;quot;&#039;,&#039;&amp;quot; .&lt;br /&gt;
				$playerOrder[$playerInitialOrder[$playerId]] .&lt;br /&gt;
				&amp;quot;&#039;)&amp;quot;;&lt;br /&gt;
		}&lt;br /&gt;
		$sql .= implode(&#039;,&#039;, $values);&lt;br /&gt;
		self::DbQuery($sql);&lt;br /&gt;
		self::reattributeColorsBasedOnPreferences(&lt;br /&gt;
			$players,&lt;br /&gt;
			$gameinfos[&#039;player_colors&#039;]&lt;br /&gt;
		);&lt;br /&gt;
		self::reloadPlayersBasicInfos();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Send different notifications to active player vs everybody else ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
Hack alert. This is a hack. We were hoping for proper solution by bga framework.&lt;br /&gt;
&lt;br /&gt;
This will allow you to send notification with two message one for specific player and one for everybody else including spectators.&lt;br /&gt;
Note that this does not split the data - all data must be shared.&lt;br /&gt;
&lt;br /&gt;
Add this to .js file (if you already overriding it merge obviously)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/** @Override */&lt;br /&gt;
format_string_recursive: function(log, args) {&lt;br /&gt;
   if (typeof args.log_others != &#039;undefined&#039; &amp;amp;&amp;amp; typeof args.player_id != &#039;undefined&#039; &amp;amp;&amp;amp; this.player_id != args.player_id)&lt;br /&gt;
	log = args.log_others;&lt;br /&gt;
   return this.inherited(arguments); // you must call this to call super &lt;br /&gt;
},&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example of usage (from eminentdomain)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    $this-&amp;gt;notifyAllPlayers(&#039;tokenMoved&#039;, &lt;br /&gt;
             clienttranslate(&#039;${player_name} adds +2 Colonies to ${place_name}&#039;), // notification with show for player with player_id&lt;br /&gt;
             [&#039;player_id&#039;=&amp;gt;$player_id, // this is mandatory&lt;br /&gt;
             &#039;log_others&#039;=&amp;gt;clienttranslate(&#039;${player_name} adds +2 Colonies to an unknown planet&#039;), // notification will show for others&lt;br /&gt;
              ...&lt;br /&gt;
             ]);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Send transient notifications without incrementing move ID ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.php&lt;br /&gt;
&lt;br /&gt;
Hack alert. This is a hack.&lt;br /&gt;
&lt;br /&gt;
Use this if you need to send some transient notification that should not create a new move ID. The notification should be idempotent -- it should have no practical effect on the game state and would be &#039;&#039;&#039;safe to drop&#039;&#039;&#039; (e.g., it would not matter if a player never received this notification). For example, in a co-op game you want all players to see a real-time preview of some action, before the active player commits their turn.&lt;br /&gt;
&lt;br /&gt;
Doing this mainly affects the instant replay &amp;amp; archive modes. During replay, the BGA framework automatically inserts a 1.5-second pause between each &amp;quot;move&amp;quot;. With this hack, your transient notifications are not considered to be a &amp;quot;move&amp;quot;, so no pause gets added.&lt;br /&gt;
&lt;br /&gt;
; In ggg.php&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$this-&amp;gt;not_a_move_notification = true; // note: do not increase the move counter&lt;br /&gt;
$this-&amp;gt;notifyAllPlayers(&#039;cardsPreview&#039;, &#039;&#039;, $args);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: you cannot have code that send notification or even changes state after this, and you cannot reset this variable back either because it only takes effect when you exit action handling function&lt;br /&gt;
&lt;br /&gt;
=== Ajax Call wrapper ===&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
The current ajaxcall is super vebose and prone to errors, I suggest using a helper function. It does a lot of stuff you must do anyways.&lt;br /&gt;
Most beginner mistakes come from missing part of this code (which is understandstandable - this is a huge snippet to clone every time).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	ajaxcallwrapper: function(action, args, handler) {&lt;br /&gt;
		if (!args) args = []; // this allows to skip args parameter for action which do not require them&lt;br /&gt;
			&lt;br /&gt;
		args.lock = true; // this allows to avoid rapid action clicking which can cause race condition on server&lt;br /&gt;
		if (this.checkAction(action)) { // this does all the proper check that player is active and action is declared&lt;br /&gt;
			this.ajaxcall(&amp;quot;/&amp;quot; + this.game_name + &amp;quot;/&amp;quot; + this.game_name + &amp;quot;/&amp;quot; + action + &amp;quot;.html&amp;quot;, args, // this is mandatory fluff &lt;br /&gt;
				this, (result) =&amp;gt; { },  // success result handler is empty - it is never needed&lt;br /&gt;
                                               handler); // this is real result handler - it called both on success and error, it has optional param  &amp;quot;is_error&amp;quot; - you rarely need it&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   this.ajaxcallwrapper(&#039;pass&#039;); // no args&lt;br /&gt;
   this.ajaxcallwrapper(&#039;playCard&#039;, {card: card_id}); // with args&lt;br /&gt;
   this.ajaxcallwrapper(&#039;playCard&#039;, {card: card_id}, (is_error)=&amp;gt;{if (!is_error) dojo.query(&amp;quot;.selected&amp;quot;).removeClass(&#039;selected&#039;);}) // with handler that cleans up &#039;selected&#039; class on success&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: this always will lock interface and always check for action, you can modify this method to do it optionally, i.e&lt;br /&gt;
  if (args.lock!==false) args.lock = true; else delete args.lock; // it does not work with false value - it has to be removed&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Studio]]&lt;/div&gt;</summary>
		<author><name>SwHawk</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=BGA_Studio_Cookbook&amp;diff=14217</id>
		<title>BGA Studio Cookbook</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=BGA_Studio_Cookbook&amp;diff=14217"/>
		<updated>2022-07-31T21:11:39Z</updated>

		<summary type="html">&lt;p&gt;SwHawk: /* Third way: rely on the transform argument of dojo.string.substitute */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
This page is collection of design and implementation recipes for BGA Studio framework.&lt;br /&gt;
For tooling and usage recipes see [[Tools and tips of BGA Studio]].&lt;br /&gt;
If you have your own recipes feel free to edit this page.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Visual Effects, Layout and Animation ==&lt;br /&gt;
&lt;br /&gt;
=== DOM manipulatons ===&lt;br /&gt;
&lt;br /&gt;
==== Create pieces dynamically (using template) ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg_ggg.tpl, ggg.js&lt;br /&gt;
&lt;br /&gt;
Note: this method is recommended by BGA guildlines&lt;br /&gt;
&lt;br /&gt;
Declared js template with variables in .tpl file, like this&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;
    // Javascript HTML templates&lt;br /&gt;
    var jstpl_ipiece = &#039;&amp;lt;div class=&amp;quot;${type} ${type}_${color} inlineblock&amp;quot; aria-label=&amp;quot;${name}&amp;quot; title=&amp;quot;${name}&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use it like this in .js file&lt;br /&gt;
  div = this.format_block(&#039;jstpl_ipiece&#039;, {&lt;br /&gt;
                                type : &#039;meeple&#039;,&lt;br /&gt;
                                color : &#039;ff0000&#039;,&lt;br /&gt;
                                name : &#039;Bob&#039;,&lt;br /&gt;
                            });&lt;br /&gt;
  &lt;br /&gt;
Then you do whatever you need to do with that div, this one specifically design to go to log entries, because it has embedded title (otherwise its a picture only) and no id.&lt;br /&gt;
&lt;br /&gt;
Note: you could have place this variable in js itself, but keeping it in .tpl allows you to have your js code be free of HTML. Normally it never happens but&lt;br /&gt;
it is good to strive for it.&lt;br /&gt;
Note: you can also use string concatenation, its less readable. You can also use dojo dom object creation api&#039;s but its brutally verbose and its more unreadable.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Create pieces dynamically (using string concatenation) ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
Note: Not recommended&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  div = &amp;quot;&amp;lt;div class=&#039;meeple &amp;quot;+color+&amp;quot;&#039;&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
==== Create all pieces statically ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg_ggg.tpl, ggg.css, ggg.view.php (optional) &lt;br /&gt;
&lt;br /&gt;
* Create ALL game pieces in html template (.tpl)&lt;br /&gt;
* ALL pieces should have unique id, and it should be meaningful, i.e. meeple_red_1&lt;br /&gt;
* Do not use inline styling&lt;br /&gt;
* Id of player&#039;s specific pieces should use some sort of &#039;color&#039; identification, since player id cannot be used in static layout, you can use english color name, hex 6 char value, or color &amp;quot;number&amp;quot; (1,2,3...)&lt;br /&gt;
* Pieces should have separated class for its color, type, etc, so it can be easily styled in groups. In example below you now can style all meeples, all red meeples or all red tokens, or all &amp;quot;first&amp;quot; meeples&lt;br /&gt;
&lt;br /&gt;
ggg.tpl:&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
  &amp;lt;div id=&amp;quot;home_red&amp;quot; class=&amp;quot;home_red home&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;div id=&amp;quot;meeple_red_1&amp;quot; class=&amp;quot;meeple red n1&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
     &amp;lt;div id=&amp;quot;meeple_red_2&amp;quot; class=&amp;quot;meeple red n2&amp;quot;&amp;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;
ggg.css:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.meeple {&lt;br /&gt;
	width: 32px;&lt;br /&gt;
	height: 39px;&lt;br /&gt;
	background-image: url(img/78_64_stand_meeples.png);&lt;br /&gt;
	background-size: 352px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.meeple.red {&lt;br /&gt;
	background-position: 30% 0%;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* There should be straight forward mapping between server id and js id (or 1:1)&lt;br /&gt;
* You place objects in different zones of the layout, and setup css to take care of layout&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.home .meeple{&lt;br /&gt;
   display: inline-block;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* If you need to have a temporary object that look like original you can use dojo.clone (and change id to some temp id)&lt;br /&gt;
* If there is lots of repetition or zone grid you can use template generator, but inject style declaration in css instead of inline style for flexibility&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
* If you use this model you cannot use premade js components such as Stock and Zone&lt;br /&gt;
* You have to use alternative methods of animation (slightly altered) since default method will leave object with inline style attributes which you don&#039;t need&lt;br /&gt;
&lt;br /&gt;
=== Logs ===&lt;br /&gt;
&lt;br /&gt;
==== Inject icon images in the log ====&lt;br /&gt;
&lt;br /&gt;
Here is an example of what was done for Terra Mystica which is simple and straightforward:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
//Define the proper message&lt;br /&gt;
		$message = clienttranslate(&#039;${player_name} gets ${power_income} via Structures&#039;);&lt;br /&gt;
		if ($price &amp;gt; 0) {&lt;br /&gt;
			self::DbQuery(&amp;quot;UPDATE player SET player_score = player_score - $price WHERE player_id = $player_id&amp;quot;);&lt;br /&gt;
			$message = clienttranslate(&#039;${player_name} pays ${vp_price} and gets ${power_income} via Structures&#039;);&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
// Notify&lt;br /&gt;
		self::notifyAllPlayers( &amp;quot;powerViaStructures&amp;quot;, $message, array(&lt;br /&gt;
			&#039;i18n&#039; =&amp;gt; array( ),&lt;br /&gt;
			&#039;player_id&#039; =&amp;gt; $player_id,&lt;br /&gt;
			&#039;player_name&#039; =&amp;gt; self::getUniqueValueFromDb( &amp;quot;SELECT player_name FROM player WHERE player_id = $player_id&amp;quot; ),&lt;br /&gt;
			&#039;power_tokens&#039; =&amp;gt; $power_tokens,&lt;br /&gt;
			&#039;vp_price&#039; =&amp;gt; self::getLogsVPAmount($price),&lt;br /&gt;
			&#039;power_income&#039; =&amp;gt; self::getLogsPowerAmount($power_income),&lt;br /&gt;
			&#039;newScore&#039; =&amp;gt; self::getUniqueValueFromDb( &amp;quot;SELECT player_score FROM player WHERE player_id = $player_id&amp;quot; ),&lt;br /&gt;
			&#039;counters&#039; =&amp;gt; $this-&amp;gt;getGameCounters(null),&lt;br /&gt;
		) );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With some functions to have the needed html added inside the substitution variable, such as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function getLogsPowerAmount( $amount ) {&lt;br /&gt;
		return &amp;quot;&amp;lt;div class=&#039;tmlogs_icon&#039; title=&#039;Power&#039;&amp;gt;&amp;lt;div class=&#039;power_amount&#039;&amp;gt;$amount&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: injecting html from php is not ideal but easy, if you want more clean solution, use method below but it is a lot more sophisticated.&lt;br /&gt;
&lt;br /&gt;
==== Inject images and styled html in the log ====&lt;br /&gt;
&lt;br /&gt;
So you want nice pictures in the game log. What do you do? The first idea that comes to mind is to send html from php in notifications (see method above). &lt;br /&gt;
&lt;br /&gt;
This is a bad idea for many reasons:&lt;br /&gt;
&lt;br /&gt;
* It&#039;s bad architecture. ui elements leak into the server, and now you have to manage the ui in multiple places.&lt;br /&gt;
* If you decided to change something in the ui in future version, replay logs for old games and tutorials may not work, since they use stored notifications.&lt;br /&gt;
* Log previews for old games become unreadable. (This is the log state before you enter the game replay, which is useful for troubleshooting and game analysis.)&lt;br /&gt;
* It&#039;s more data to transfer and store in the db.&lt;br /&gt;
* It&#039;s a nightmare for translators.&lt;br /&gt;
&lt;br /&gt;
So what else can you do? You can use client side log injection to intercept log arguments (which come from the server) and replace them with html on the client side. Here are three different method you can use to achieve this.&lt;br /&gt;
&lt;br /&gt;
===== First way : Override &amp;lt;code&amp;gt;this.format_string_recursive()&amp;lt;/code&amp;gt; method =====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, ggg.game.php&lt;br /&gt;
&lt;br /&gt;
I use this recipe for &#039;&#039;&#039;client side log injection&#039;&#039;&#039; to intercept log arguments (which come from the server) and replace them with html on the client side.&lt;br /&gt;
&lt;br /&gt;
[[File:clientloginjection.png|left]] &lt;br /&gt;
&lt;br /&gt;
ggg.js&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
        /** Override this function to inject html into log items. This is a built-in BGA method.  */&lt;br /&gt;
&lt;br /&gt;
        /* @Override */&lt;br /&gt;
        format_string_recursive : function format_string_recursive(log, args) {&lt;br /&gt;
            try {&lt;br /&gt;
                if (log &amp;amp;&amp;amp; args &amp;amp;&amp;amp; !args.processed) {&lt;br /&gt;
                    args.processed = true;&lt;br /&gt;
                    &lt;br /&gt;
&lt;br /&gt;
                    // list of special keys we want to replace with images&lt;br /&gt;
                    var keys = [&#039;place_name&#039;,&#039;token_name&#039;];&lt;br /&gt;
                    &lt;br /&gt;
                  &lt;br /&gt;
                    for ( var i in keys) {&lt;br /&gt;
                        var key = keys[i];&lt;br /&gt;
                        key in args &amp;amp;&amp;amp; args[key] = this.getTokenDiv(key, args);                            &lt;br /&gt;
&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            } catch (e) {&lt;br /&gt;
                console.error(log,args,&amp;quot;Exception thrown&amp;quot;, e.stack);&lt;br /&gt;
            }&lt;br /&gt;
            return this.inherited({callee: format_string_recursive}, arguments);&lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important:&#039;&#039;&#039; In the &#039;&#039;format_string_recursive&#039;&#039; method, the &#039;args&#039; parameter will only contain arguments passed to it from the notify method in ggg.game.php (see below).&lt;br /&gt;
&lt;br /&gt;
The &#039;log&#039; parameter is the actual string that is inserted into the logs. You can perform additional js string manipulation on it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        getTokenDiv : function(key, args) {&lt;br /&gt;
            // ... implement whatever html you want here, example from sharedcode.js&lt;br /&gt;
            var token_id = args[key];&lt;br /&gt;
            var item_type = getPart(token_id,0);&lt;br /&gt;
            var logid = &amp;quot;log&amp;quot; + (this.globalid++) + &amp;quot;_&amp;quot; + token_id;&lt;br /&gt;
            switch (item_type) {&lt;br /&gt;
                case &#039;wcube&#039;:&lt;br /&gt;
                    var tokenDiv = this.format_block(&#039;jstpl_resource_log&#039;, {&lt;br /&gt;
                        &amp;quot;id&amp;quot; : logid,&lt;br /&gt;
                        &amp;quot;type&amp;quot; : &amp;quot;wcube&amp;quot;,&lt;br /&gt;
                        &amp;quot;color&amp;quot; : getPart(token_id,1),&lt;br /&gt;
                    });&lt;br /&gt;
                    return tokenDiv;&lt;br /&gt;
             &lt;br /&gt;
                case &#039;meeple&#039;:&lt;br /&gt;
                    if ($(token_id)) {&lt;br /&gt;
                        var clone = dojo.clone($(token_id));&lt;br /&gt;
    &lt;br /&gt;
                        dojo.attr(clone, &amp;quot;id&amp;quot;, logid);&lt;br /&gt;
                        this.stripPosition(clone);&lt;br /&gt;
                        dojo.addClass(clone, &amp;quot;logitem&amp;quot;);&lt;br /&gt;
                        return clone.outerHTML;&lt;br /&gt;
                    }&lt;br /&gt;
                    break;&lt;br /&gt;
     &lt;br /&gt;
                default:&lt;br /&gt;
                    break;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            return &amp;quot;&#039;&amp;quot; + this.clienttranslate_string(this.getTokenName(token_id)) + &amp;quot;&#039;&amp;quot;;&lt;br /&gt;
       },&lt;br /&gt;
       getTokenName : function(key) {&lt;br /&gt;
           return this.gamedatas.token_types[key].name; // get name for the key, from static table for example&lt;br /&gt;
       },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that in this case the server simply injects token_id as a name, and the client substitutes it for the translated name or the picture.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ggg.game.php:&lt;br /&gt;
&lt;br /&gt;
           $this-&amp;gt;notifyAllPlayers(&#039;playerLog&#039;,clienttranslate(&#039;Game moves ${token_name}&#039;),[&#039;token_name&#039;=&amp;gt;$token_id]);&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important:&#039;&#039;&#039; As noted above, only arguments actually passed by this method are available to the args parameter received in the client-side &#039;&#039;format_string_recursive&#039;&#039; method.&lt;br /&gt;
&lt;br /&gt;
Sometimes it is the case that you want to pass arguments that are not actually included in the output message. For example, suppose we have a method like this:&lt;br /&gt;
&lt;br /&gt;
           $this-&amp;gt;notifyAllPlayers(&#039;tokenPlaced&#039;,clienttranslate(&#039;Player placed ${token_name}&#039;),array(&lt;br /&gt;
              &#039;token_name&#039; =&amp;gt; $token_id,&lt;br /&gt;
              &#039;zone_played&#039; =&amp;gt; $zone);&lt;br /&gt;
&lt;br /&gt;
This will output &amp;quot;Player placed ${token_name}&amp;quot; in the log, and if we subscribe to a notification method activated by the &amp;quot;tokenPlaced&amp;quot; event in the client-side code, that method can make use of the &#039;zone_played&#039; argument. &lt;br /&gt;
&lt;br /&gt;
Now if you want to make some really cool things with game log, most probably you would need more arguments than are included in log message. The problem with that,&lt;br /&gt;
it will work at first, but if you reload game using F5 or when the game loads in turn based mode, you will loose your additional parameters, why? Because when game reloads it does not actually send same notifications, it sends special &amp;quot;hitstorical_log&amp;quot; notification where all  parameters not listed in the message are removed. In example above, field zone_played would be removed from historical log as it is not included in message of the notification. You can till preserve specific arguments in historical log by adding special field preserve to notification arguments like this:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
           $this-&amp;gt;notifyAllPlayers(&#039;tokenPlaced&#039;,clienttranslate(&#039;Player placed ${token_name}&#039;),array(&lt;br /&gt;
              &#039;token_name&#039; =&amp;gt; $token_id,&lt;br /&gt;
              &#039;zone_played&#039; =&amp;gt; $zone,&lt;br /&gt;
              &#039;preserve&#039; =&amp;gt; [ &#039;zone_played&#039; ]&lt;br /&gt;
           );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now you can use zone_played in format_string_recursive even in historical logs.&lt;br /&gt;
&lt;br /&gt;
===== Second way: rely on the &amp;lt;code&amp;gt;:formatFunction&amp;lt;/code&amp;gt; option provided by &amp;lt;code&amp;gt;dojo.string.substitute&amp;lt;/code&amp;gt; =====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, ggg.game.php, ggg_ggg.tpl, ggg.css&lt;br /&gt;
&lt;br /&gt;
The above method will work in most of the cases, but if you use dotted keys such as &amp;lt;code&amp;gt;${card.name}&amp;lt;/code&amp;gt; (which is supported by the framework, for private state args), the key won&#039;t be substituted because the &amp;lt;code&amp;gt;key in arg&amp;lt;/code&amp;gt; test will fail. If so you need to rely either on this way, or the one after.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;WARNING:&#039;&#039;&#039; using this method on an already advanced project will require you to go through all your notifications to change keys !&lt;br /&gt;
&lt;br /&gt;
Under the hood, the &#039;&#039;&#039;this.format_string_recursive()&#039;&#039;&#039; function calls the &#039;&#039;&#039;dojo.string.substitute&#039;&#039;&#039; method which substitutes &amp;lt;code&amp;gt;${keys}&amp;lt;/code&amp;gt; with the value provided. If you take a look at the [https://dojotoolkit.org/reference-guide/1.7/dojo/string.html#substitute documentation] and [https://github.com/dojo/dojo/blob/c3ceb017cfa25b703f5662dc83d1c8aae9bc5d81/string.js#L163 source code] you can notice that the key can be suffixed with a colon (&amp;lt;code&amp;gt;:&amp;lt;/code&amp;gt;) followed by a function name. This will allow you to specify directly in the substitution string which keys need HTML injection.&lt;br /&gt;
&lt;br /&gt;
First of all, you need to define your formatting function in the ggg.js file:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[[ggg.js]]&lt;br /&gt;
        getTokenDiv : function(value, key) {&lt;br /&gt;
            //This is only an example implementation, you need to write your own.&lt;br /&gt;
            //The method should return HTML code&lt;br /&gt;
            switch (key) {&lt;br /&gt;
                case &#039;html_injected_argument1&#039;:&lt;br /&gt;
                    return this.format_block(&#039;jstpl_HTMLLogElement1&#039;,{value: value});&lt;br /&gt;
                case &#039;html_injected_argument2&#039;:&lt;br /&gt;
                    return this.format_block(&#039;jstpl_HTMLLogElement2&#039;,{value: value});&lt;br /&gt;
                ...&lt;br /&gt;
            }&lt;br /&gt;
       }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Obviously you need to define the appropriate templates in the ggg_ggg.tpl file:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[[ggg_ggg.tpl]]&lt;br /&gt;
let jstpl_HTMLLogElement1 = &#039;&amp;lt;div class=&amp;quot;log-element log-element-1-${value}&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
let jstpl_HTMLLogElement2 = &#039;&amp;lt;div class=&amp;quot;log-element log-element-2-${value}&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
And the appropriate classes in ggg.css.&lt;br /&gt;
&lt;br /&gt;
Then you need to add the &amp;lt;code&amp;gt;dojo/aspect&amp;lt;/code&amp;gt; module at the top of the ggg.js file:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[ggg.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 define([&lt;br /&gt;
     &amp;quot;dojo&amp;quot;, &amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&amp;quot;dojo/aspect&amp;quot;,&amp;lt;/span&amp;gt;                 //MUST BE IN THIRD POSITION&#039;&#039;&#039; (see [[#Including your own JavaScript module (II)|below]])&lt;br /&gt;
     &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
 ], function (dojo, declare, &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&#039;&#039;&#039;aspect&#039;&#039;&#039;&amp;lt;/span&amp;gt;) {&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
And you also need to add the following code in your &amp;lt;code&amp;gt;contructor&amp;lt;/code&amp;gt; method in the ggg.js:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[ggg.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
         constructor: function(){&lt;br /&gt;
             console.log(&#039;progressevolutiontechnologyswh constructor&#039;);&lt;br /&gt;
               &lt;br /&gt;
             // Here, you can init the global variables of your user interface&lt;br /&gt;
             // Example:&lt;br /&gt;
             // this.myGlobalValue = 0;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&#039;&#039;&#039;let gameObject = this;&#039;&#039;&#039;            //Needed as the this object in aspect.before will not refer to the game object in which the formatting function resides&lt;br /&gt;
             &#039;&#039;&#039;aspect.before(dojo.string, &amp;quot;substitute&amp;quot;, function(template, map, transform) {&#039;&#039;&#039;      //This allows you to modify the arguments of the dojo.string.substitute method before they&#039;re actually passed to it&lt;br /&gt;
                 &#039;&#039;&#039;return [template, map, transform, gameObject];&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now you&#039;re all set to inject HTML in your logs. To actually achieve this, you must specify the function name with the key like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[ggg.game.php]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 $this-&amp;gt;notifyAllPlayers(&amp;quot;notificationName&amp;quot;, clienttranslate(&amp;quot;This log message contains ${plainTextArgument} and the following will receive HTML injection: ${html_injected_argument1:getTokenDiv}&amp;quot;), [&lt;br /&gt;
     &amp;quot;plainTextArgument&amp;quot; =&amp;gt; &amp;quot;some plain text here&amp;quot;,&lt;br /&gt;
     &amp;quot;html_injected_argument1&amp;quot; =&amp;gt; &amp;quot;some value used by getTokenDiv&amp;quot;,&lt;br /&gt;
 ]);&lt;br /&gt;
&lt;br /&gt;
You&#039;re not limited writing only one function, you can write as many functions as you like, and have them each inject a specific type of HTML. You just need to specify the relevant function name after the column in the substitution key.&lt;br /&gt;
&lt;br /&gt;
===== Third way: rely on the &amp;lt;code&amp;gt;transform&amp;lt;/code&amp;gt; argument of &amp;lt;code&amp;gt;dojo.string.substitute&amp;lt;/code&amp;gt; =====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, ggg.game.php, ggg_ggg.tpl, ggg.css&lt;br /&gt;
&lt;br /&gt;
This method is also relying on the use of &amp;lt;code&amp;gt;dojo.string.substitute&amp;lt;/code&amp;gt; by the framework, and will use the &amp;lt;code&amp;gt;transform&amp;lt;/code&amp;gt; argument, which, accordting to [https://github.com/dojo/dojo/blob/c3ceb017cfa25b703f5662dc83d1c8aae9bc5d81/string.js#L163 source code] and [https://dojotoolkit.org/reference-guide/1.7/dojo/string.html#substitute documentation] will be run on all the messages going through dojo.string.substitute.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;WARNING:&#039;&#039;&#039; As this method will be applied to all strings that go through dojo.string.substitute. As such you must take extra care not to substitute keys that may be used by the framework (i.e. ${id}). In order to do so, a good practise would be to prefix all keys that need substitution with a trigram of the game name.&lt;br /&gt;
&lt;br /&gt;
Since all the keys will be fed to the tranform function, by default, it must return the value, substituted or not per your needs. You can define the function like this in the ggg.js file:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[ggg.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
         getTokenDiv : function(value, key) {&lt;br /&gt;
             //This is only an example implementation, you need to write your own.&lt;br /&gt;
             //The method should return HTML code&lt;br /&gt;
             switch (key) {&lt;br /&gt;
                 case &#039;html_injected_argument1&#039;:&lt;br /&gt;
                     return this.format_block(&#039;jstpl_HTMLLogElement1&#039;,{value: value});&lt;br /&gt;
                 case &#039;html_injected_argument2&#039;:&lt;br /&gt;
                     return this.format_block(&#039;jstpl_HTMLLogElement2&#039;,{value: value});&lt;br /&gt;
                 ...&lt;br /&gt;
                 &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&#039;&#039;&#039;default:&#039;&#039;&#039;&lt;br /&gt;
                     &#039;&#039;&#039;return value;&#039;&#039;&#039;&amp;lt;/span&amp;gt;                  &#039;&#039;&#039;//Needed otherwise regular strings won&#039;t appear since since the value isn&#039;t returned by the function&#039;&#039;&#039;&lt;br /&gt;
             }&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
The templates must be defined in the ggg_ggg.tpl file and the corresponding CSS classes in the ggg.css file.&lt;br /&gt;
&lt;br /&gt;
You need to add the following code at the beginning of the ggg.js file:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[ggg.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 define([&lt;br /&gt;
     &amp;quot;dojo&amp;quot;, &amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&amp;quot;dojo/aspect&amp;quot;,&amp;lt;/span&amp;gt;                 //MUST BE IN THIRD POSITION&#039;&#039;&#039; (see [[#Including your own JavaScript module (II)|below]])&lt;br /&gt;
     &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
 ], function (dojo, declare, &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&#039;&#039;&#039;aspect&#039;&#039;&#039;&amp;lt;/span&amp;gt;) {&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
And the following code to the &amp;lt;code&amp;gt;constructor&amp;lt;/code&amp;gt; method in ggg.js:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[ggg.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
         constructor: function(){&lt;br /&gt;
             console.log(&#039;progressevolutiontechnologyswh constructor&#039;);&lt;br /&gt;
               &lt;br /&gt;
             // Here, you can init the global variables of your user interface&lt;br /&gt;
             // Example:&lt;br /&gt;
             // this.myGlobalValue = 0;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&#039;&#039;&#039;let transformFunction = dojo.hitch(this, &amp;quot;getTokenDiv&amp;quot;);&#039;&#039;&#039;            //Needed as the this object in aspect.before will not refer to the game object in which the formatting function resides&lt;br /&gt;
             &#039;&#039;&#039;aspect.before(dojo.string, &amp;quot;substitute&amp;quot;, function(template, map, transform) {&#039;&#039;&#039;&lt;br /&gt;
                 &#039;&#039;&#039;if (undefined === transform) {&#039;&#039;&#039;                                   //Check for a transform function presence, just in case&lt;br /&gt;
                     &#039;&#039;&#039;return [template, map, transform];&#039;&#039;&#039;&lt;br /&gt;
                 &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then you&#039;re all set for log injection, no need to change anything on the PHP side.&lt;br /&gt;
&lt;br /&gt;
==== Processing logs on re-loading ====&lt;br /&gt;
&lt;br /&gt;
You rarely need to process logs when reloading, but if you want to do something fancy you may have to do it after logs are loaded. &lt;br /&gt;
Logs are loaded asyncronously so you have to listen for logs to be fully loaded.&lt;br /&gt;
Unfortunately there is no direct way of doing it so this is the hack.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Hack alert&#039;&#039;&#039; - this extends undocumented function and may be broken when framework is updated&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
			/*&lt;br /&gt;
  			* [Undocumented] Override BGA framework functions to call onLoadingLogsComplete when loading is done&lt;br /&gt;
                        @Override&lt;br /&gt;
   			*/&lt;br /&gt;
			setLoader: function(image_progress, logs_progress) {&lt;br /&gt;
				this.inherited(arguments); // required, this is &amp;quot;super()&amp;quot; call, do not remove&lt;br /&gt;
				//console.log(&amp;quot;loader&amp;quot;, image_progress, logs_progress)&lt;br /&gt;
				if (!this.isLoadingLogsComplete &amp;amp;&amp;amp; logs_progress &amp;gt;= 100) {&lt;br /&gt;
					this.isLoadingLogsComplete = true; // this is to prevent from calling this more then once&lt;br /&gt;
					this.onLoadingLogsComplete();&lt;br /&gt;
				}&lt;br /&gt;
			},&lt;br /&gt;
&lt;br /&gt;
			onLoadingLogsComplete: function() {&lt;br /&gt;
				console.log(&#039;Loading logs complete&#039;);&lt;br /&gt;
				// do something here&lt;br /&gt;
			},&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Player Panel ===&lt;br /&gt;
&lt;br /&gt;
==== Inserting non-player panel ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, ggg_ggg.tpl&lt;br /&gt;
&lt;br /&gt;
If you want to insert non-player panel on the right side (for example to hold extra preferences, zooming controls, etc)&lt;br /&gt;
&lt;br /&gt;
this can go pretty much anywhere in template it will be moved later&lt;br /&gt;
&lt;br /&gt;
ggg_ggg.tpl:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	&amp;lt;div class=&#039;player_board_config&#039; id=&amp;quot;player_board_config&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;!-- here is whatever you want, buttons just example --&amp;gt;&lt;br /&gt;
		&amp;lt;button id=&amp;quot;zoom-out&amp;quot; class=&amp;quot; fa fa-search-minus fa-2x config-control&amp;quot;&amp;gt;&amp;lt;/button&amp;gt;&lt;br /&gt;
		&amp;lt;button id=&amp;quot;zoom-in&amp;quot; class=&amp;quot; fa fa-search-plus fa-2x config-control&amp;quot;&amp;gt;&amp;lt;/button&amp;gt;&lt;br /&gt;
		&amp;lt;button id=&amp;quot;show-settings&amp;quot; class=&amp;quot;fa fa-cog fa-2x config-control &amp;quot;&amp;gt;&amp;lt;/button&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
some hackery required in js&lt;br /&gt;
&lt;br /&gt;
ggg.js:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* @Override */&lt;br /&gt;
	updatePlayerOrdering() {&lt;br /&gt;
		this.inherited(arguments);&lt;br /&gt;
		dojo.place(&#039;player_board_config&#039;, &#039;player_boards&#039;, &#039;first&#039;);&lt;br /&gt;
	},&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Images and Icons ===&lt;br /&gt;
&lt;br /&gt;
==== Accessing images from js ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
     // your game resources&lt;br /&gt;
     &lt;br /&gt;
     var my_img = &#039;&amp;lt;img src=&amp;quot;&#039;+g_gamethemeurl+&#039;img/cards.jpg&amp;quot;/&amp;gt;&#039;;&lt;br /&gt;
     &lt;br /&gt;
     // shared resources&lt;br /&gt;
     var my_help_img = &amp;quot;&amp;lt;img class=&#039;imgtext&#039; src=&#039;&amp;quot; + g_themeurl + &amp;quot;img/layout/help_click.png&#039; alt=&#039;action&#039; /&amp;gt; &amp;lt;span class=&#039;tooltiptext&#039;&amp;gt;&amp;quot; +&lt;br /&gt;
                    text + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== High-Definition Graphics ====&lt;br /&gt;
&lt;br /&gt;
Some users will have screens which can display text and images at a greater resolution than the usual 72 dpi, e.g. the &amp;quot;Retina&amp;quot; screens on the 5k iMac, all iPads, and high-DPI screens on laptops from many manufacturers. If you can get art assets at this size, they will make your game look extra beautiful. You &#039;&#039;could&#039;&#039; just use large graphics and scale them down, but that would increase the download time and bandwidth for users who can&#039;t display them. Instead, a good way is to prepare a separate graphics file at exactly twice the size you would use otherwise, and add &amp;quot;@2x&amp;quot; at the end of the filename, e.g. if pieces.png is 240x320, then pieces@2x.png is 480x640.&lt;br /&gt;
&lt;br /&gt;
There are two changes required in order to use the separate graphics files. First in your css, where you use a file, add a media query which overrides the original definition and uses the bigger version on devices which can display them. Ensuring that the &amp;quot;background-size&amp;quot; attribute is set means that the size of the displayed object doesn&#039;t change, but only is drawn at the improved dot pitch.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.piece {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    background-image: url(&#039;img/pieces.png&#039;);&lt;br /&gt;
    background-size:240px 320px;&lt;br /&gt;
    z-index: 10;&lt;br /&gt;
}&lt;br /&gt;
@media (-webkit-min-device-pixel-ratio: 2), (min-device-pixel-ratio: 2), (min-resolution: 192dpi)&lt;br /&gt;
{&lt;br /&gt;
    .piece {&lt;br /&gt;
        background-image: url(&#039;img/pieces@2x.png&#039;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Secondly, in your setup function in javascript, you must ensure than only the appropriate one version of the file gets pre-loaded (otherwise you more than waste the bandwidth saved by maintaining the standard-resolution file). Note that the media query is the same in both cases:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
            var isRetina = &amp;quot;(-webkit-min-device-pixel-ratio: 2), (min-device-pixel-ratio: 2), (min-resolution: 192dpi)&amp;quot;;&lt;br /&gt;
            if (window.matchMedia(isRetina).matches)&lt;br /&gt;
            {&lt;br /&gt;
                this.dontPreloadImage( &#039;pieces.png&#039; );&lt;br /&gt;
                this.dontPreloadImage( &#039;board.jpg&#039; );&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                this.dontPreloadImage( &#039;pieces@2x.png&#039; );&lt;br /&gt;
                this.dontPreloadImage( &#039;board@2x.jpg&#039; );&lt;br /&gt;
            }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using CSS to create different colors of game pieces if you have only white piece ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
background-color: #${color}; &lt;br /&gt;
background-blend-mode: multiply;&lt;br /&gt;
background-image: url( &#039;img/mypiece.png&#039;);&lt;br /&gt;
mask: url(&#039;img/mypiece.png&#039;);&lt;br /&gt;
-webkit-mask: url(&#039;img/mypiece.png&#039;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where ${color} - is color you want&lt;br /&gt;
&lt;br /&gt;
Note: piece has to be white (shades of gray). Sprite can be used too, just add add blackground-position as usuall.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Other Fluff ===&lt;br /&gt;
&lt;br /&gt;
==== Use thematic fonts ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.css&lt;br /&gt;
&lt;br /&gt;
Sometime game elements use specific fonts of text, if you want to match it up you can load some specific font (IMPORTANT: from some &#039;&#039;&#039;free font&#039;&#039;&#039; source. See notes below).&lt;br /&gt;
&lt;br /&gt;
[[File:Dragonline_font.png]]&lt;br /&gt;
&lt;br /&gt;
.css&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* latin-ext */&lt;br /&gt;
@font-face {&lt;br /&gt;
  font-family: &#039;Qwigley&#039;;&lt;br /&gt;
  font-style: normal;&lt;br /&gt;
  font-weight: 400;&lt;br /&gt;
  src: local(&#039;Qwigley&#039;), local(&#039;Qwigley-Regular&#039;), url(https://fonts.gstatic.com/s/qwigley/v6/2Dy1Unur1HJoklbsg4iPJ_Y6323mHUZFJMgTvxaG2iE.woff2) format(&#039;woff2&#039;);&lt;br /&gt;
  unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;&lt;br /&gt;
}&lt;br /&gt;
/* latin */&lt;br /&gt;
@font-face {&lt;br /&gt;
  font-family: &#039;Qwigley&#039;;&lt;br /&gt;
  font-style: normal;&lt;br /&gt;
  font-weight: normal;&lt;br /&gt;
  src: local(&#039;Qwigley&#039;), local(&#039;Qwigley-Regular&#039;), url(https://fonts.gstatic.com/s/qwigley/v6/gThgNuQB0o5ITpgpLi4Zpw.woff2) format(&#039;woff2&#039;);&lt;br /&gt;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;&lt;br /&gt;
}&lt;br /&gt;
@font-face {&lt;br /&gt;
  font-family: &#039;Qwigley&#039;;&lt;br /&gt;
  font-style: normal;&lt;br /&gt;
  font-weight: normal;&lt;br /&gt;
  src: local(&#039;Qwigley&#039;), local(&#039;Qwigley-Regular&#039;), url(http://ff.static.1001fonts.net/q/w/qwigley.regular.ttf) format(&#039;ttf&#039;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.zone_title {&lt;br /&gt;
	display: inline-block;&lt;br /&gt;
	position: absolute;&lt;br /&gt;
	font: italic 32px/32px &amp;quot;Qwigley&amp;quot;, cursive;	   &lt;br /&gt;
	height: 32px;&lt;br /&gt;
	width: auto;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NB:&#039;&#039;&#039; if you need to include a font that&#039;s not available online, an extra action will be needed from an admin. Please include the font file(s) in your img directory, and mention it to admins when requesting your game to be moved to alpha. &#039;&#039;&#039;Please remember that the font has to be free, and include a .txt with all appropriate license information about the font.&#039;&#039;&#039;&lt;br /&gt;
You can look for free fonts (for example) on https://fonts.google.com or https://www.fontsquirrel.com/)&lt;br /&gt;
&lt;br /&gt;
=== Use player color in template ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg_ggg.tpl, ggg.view.php&lt;br /&gt;
&lt;br /&gt;
.view.php:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    function build_page($viewArgs) {&lt;br /&gt;
        // Get players &amp;amp; players number&lt;br /&gt;
        $players = $this-&amp;gt;game-&amp;gt;loadPlayersBasicInfos();&lt;br /&gt;
        $players_nbr = count($players);&lt;br /&gt;
        /**&lt;br /&gt;
         * ********* Place your code below: ***********&lt;br /&gt;
         */&lt;br /&gt;
        &lt;br /&gt;
        // Set PCOLOR to the current player color hex&lt;br /&gt;
        global $g_user;&lt;br /&gt;
        $cplayer = $g_user-&amp;gt;get_id();&lt;br /&gt;
        if (array_key_exists($cplayer, $players)) { // may be not set if spectator&lt;br /&gt;
            $player_color = $players [$cplayer] [&#039;player_color&#039;];&lt;br /&gt;
        } else {&lt;br /&gt;
            $player_color = &#039;ffffff&#039;; // spectator&lt;br /&gt;
        }&lt;br /&gt;
        $this-&amp;gt;tpl [&#039;PCOLOR&#039;] = $player_color;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Scale to fit for big boards ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg_ggg.tpl, ggg.js&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Lets say you have huge game board, and lets say you want it to be 1400px wide. Besides the board there will be side bar which is 240 and trim. &lt;br /&gt;
My display is 1920 wide so it fits, but there is big chance other people won&#039;t have that width. What do you do?&lt;br /&gt;
&lt;br /&gt;
You have to decide:&lt;br /&gt;
* If board does not fit you want scale whole thing down, the best way is probably use viewport (see https://en.doc.boardgamearena.com/Your_game_mobile_version)&lt;br /&gt;
* You can leave the board as is and make sure it is scrollable horizonatally&lt;br /&gt;
* You add custom scale just for the board (can add user controls  - and hook to transform: scale())&lt;br /&gt;
&lt;br /&gt;
I tried to auto-scale but this just does work, too many variables - browser zoom, 3d mode, viewport, custom bga scaling, devicePixelRatio - all create some impossible coctail of zooming...&lt;br /&gt;
Here is scaling functing for custom user scaling&lt;br /&gt;
&lt;br /&gt;
ggg_ggg.tpl:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   &amp;lt;div id=&amp;quot;thething&amp;quot; class=&amp;quot;thething&amp;quot;&amp;gt;&lt;br /&gt;
            ... everything else you declare ...&lt;br /&gt;
   &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ggg.js:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    onZoomPlus: function() {&lt;br /&gt;
       this.my_zoom+=0.1;&lt;br /&gt;
       this.zoommy(&#039;thething&#039;,this.my_zoom);&lt;br /&gt;
    },&lt;br /&gt;
&lt;br /&gt;
    zoommy: function(node, zoom) {&lt;br /&gt;
                node=$(node);&lt;br /&gt;
		var width = 100 / zoom;&lt;br /&gt;
		node.style.transformOrigin = &amp;quot;0 0&amp;quot;;&lt;br /&gt;
		node.style.transform = &amp;quot;scale(&amp;quot; + zoom + &amp;quot;)&amp;quot;;&lt;br /&gt;
		node.style.width = width + &amp;quot;%&amp;quot;;&lt;br /&gt;
    },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Dynamic tooltips ===&lt;br /&gt;
&lt;br /&gt;
If you really need a dynamic tooltip you can use this technique. (Only use it if the static tooltips provided by the BGA framework are not sufficient.)&lt;br /&gt;
&lt;br /&gt;
            new dijit.Tooltip({&lt;br /&gt;
                connectId: [&amp;quot;divItemId&amp;quot;],&lt;br /&gt;
                getContent: function(matchedNode){&lt;br /&gt;
                    return &amp;quot;... calculated ...&amp;quot;; &lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is an out-of-the-box djit.Tooltip. It has a &#039;&#039;getContent&#039;&#039; method which is called dynamically.&lt;br /&gt;
&lt;br /&gt;
The string function return becomes the innerHTML of the tooltip, so it can be anything. In this example matchedNode is a dojo node representing dom object with id of &amp;quot;divItemId&amp;quot; but there are more parameters which I am not posting here which allows more sophisticated subnode queries (i.e. you can attach tooltip to all nodes with class or whatever).&lt;br /&gt;
&lt;br /&gt;
[https://dojotoolkit.org/reference-guide/1.10/dijit/Tooltip.html dijit.Tooltip]&lt;br /&gt;
&lt;br /&gt;
It&#039;s not part of the BGA API so use at your own risk.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Rendering text with players color and proper background ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
This example actually writes &amp;quot;You&amp;quot; but you can replace this with player name as easily, drop translating function in this case&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        /* Implementation of proper colored You with background in case of white or light colors  */&lt;br /&gt;
 &lt;br /&gt;
        divYou : function() {&lt;br /&gt;
            var color = this.gamedatas.players[this.player_id].color;&lt;br /&gt;
            var color_bg = &amp;quot;&amp;quot;;&lt;br /&gt;
            if (this.gamedatas.players[this.player_id] &amp;amp;&amp;amp; this.gamedatas.players[this.player_id].color_back) {&lt;br /&gt;
                color_bg = &amp;quot;background-color:#&amp;quot; + this.gamedatas.players[this.player_id].color_back + &amp;quot;;&amp;quot;;&lt;br /&gt;
            }&lt;br /&gt;
            var you = &amp;quot;&amp;lt;span style=\&amp;quot;font-weight:bold;color:#&amp;quot; + color + &amp;quot;;&amp;quot; + color_bg + &amp;quot;\&amp;quot;&amp;gt;&amp;quot; + __(&amp;quot;lang_mainsite&amp;quot;, &amp;quot;You&amp;quot;) + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
            return you;&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Cool realistic shadow effect with CSS ===&lt;br /&gt;
&lt;br /&gt;
==== Rectangles and circles ====&lt;br /&gt;
&lt;br /&gt;
It is often nice to have a drop shadow around tiles and tokens, to separate them from the table visually. It is very easy to add a shadow to rectangular elements, just add this to your css:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.xxx-tile {&lt;br /&gt;
    box-shadow: 3px 3px 3px #000000a0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
box-shadow obeys &#039;&#039;&#039;border-radius&#039;&#039;&#039; of the element, so it will look good for rounded rectangles, and hence also circles (if border-radius is set appropriately).&lt;br /&gt;
&lt;br /&gt;
box-shadow also supports various other parameters and can be used to achieve effects such as glowing, borders, inner shadows etc. If you need to animate a box-shadow, you may be able to get better performance (avoiding redraws) if you attach the shadow to another element (possibly an ::after pseudo-element) and change only the &#039;&#039;&#039;opacity&#039;&#039;&#039; of that element.&lt;br /&gt;
&lt;br /&gt;
==== Irregular Shapes ====&lt;br /&gt;
&lt;br /&gt;
If you wish to make a shadow effect for game pieces that are not a rectangle, but your game pieces are drawn from rectangles in a PNG image, you can apply the shadow to the piece using any art package and save it inside the image. This usually will yield the best performance. Remember to account for the size of the shadow when you lay out images in the sprite sheet.&lt;br /&gt;
&lt;br /&gt;
However that sometimes will not be an option, for example if the image needs to be rotated while the shadow remains offset in the same direction. In this case, one option is to not use box-shadow but use filter, which is supported by recent major browsers.  This way, you can use the alpha channel of your element to drop a shadow.  This even work for transparent backgrounds, so that if you are using the &amp;quot;CSS-sprite&amp;quot; method, it will work!&lt;br /&gt;
&lt;br /&gt;
For instance:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.xxx-token {&lt;br /&gt;
    filter: drop-shadow(0px 0px 1px #000000);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beware that some browsers still do not always draw drop-shadow correctly. In particular, Safari frequently leaves bits of shadow behind when objects move around the screen. In Chrome, shadows sometimes flicker badly if another element is animating close by. Some of these correctness issues can be solved by adding &#039;&#039;&#039;isolation: isolate; will-change: filter;&#039;&#039;&#039; to affected elements, but this significantly affects redraw performance.&lt;br /&gt;
&lt;br /&gt;
Beware of performance issues - particularly on Safari (MacOS, iPhone and iPad). Keep in mind that drop-shadow are very GPU intensive. This becomes noticeable once you have about 40 components with drop-shadow filter. If that is your case, you can quite easily implement a user preference to disable shadows for users on slower machines:&lt;br /&gt;
&lt;br /&gt;
gameoptions.inc.php&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
100 =&amp;gt; array(&lt;br /&gt;
			&#039;name&#039; =&amp;gt; totranslate(&#039;Shadows&#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;Enabled&#039; ), &#039;cssPref&#039; =&amp;gt; &#039;&#039; ),&lt;br /&gt;
					2 =&amp;gt; array( &#039;name&#039; =&amp;gt; totranslate( &#039;Disabled&#039; ), &#039;cssPref&#039; =&amp;gt; &#039;no-shadow&#039; )&lt;br /&gt;
			)&lt;br /&gt;
	),&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[game].css&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.no-shadow * {&lt;br /&gt;
	filter: none !important; &lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Shadows with clip-path ====&lt;br /&gt;
&lt;br /&gt;
For some reason, a shadow will not work together with clip-path on one element. To use both clip-path (when for example using .svg to cut out cardboard components from your .jpg spritesheet) and drop-shadow, you need to wrap the element into another one, and apply drop-shadow to the outer one, and clip-path to the inner one.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;div class=&#039;my-token-wrap&#039;&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&#039;my-token&#039;&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;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.my-token-wrap {&lt;br /&gt;
    filter: drop-shadow(0px 0px 1px #000000);&lt;br /&gt;
}&lt;br /&gt;
.my-token-wrap .my-token {&lt;br /&gt;
    clip-path: url(#my-token-path);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Using the CSS classes from the state machine ===&lt;br /&gt;
&lt;br /&gt;
If you need to hide or show stuff depending on the state of your game, you can of course use javascript, but CSS is hand enough for that.  The #overall-content element does change class depending on the game state.  For instance, if you are in state &#039;&#039;playerTurn&#039;&#039;, it will have the class &#039;&#039;gamestate_playerTurn&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
So now, if you want to show the discard pile only during player turns, you may use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#discard_pile { display: none }&lt;br /&gt;
.gamestate_playerTurn #discard_pile { display: block }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This can be used if you want to change sizing of elements, position, layout or visual appearance.&lt;br /&gt;
&lt;br /&gt;
== Game Model and Database design ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Database for The euro game ===&lt;br /&gt;
Lets say we have a game with workers, dice, tokens, board, resources, money and vp. Workers and dice can be placed in various zones on the board, and you can get resources, money, tokens and vp in your home zone. Also tokens can be flipped or not flipped.&lt;br /&gt;
&lt;br /&gt;
[[File:Madeira board.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now lets try to map it, we have&lt;br /&gt;
* (meeple,zone)&lt;br /&gt;
* (die, zone, sideup)&lt;br /&gt;
* (resource cube/money token/vp token,player home zone)&lt;br /&gt;
* (token, player home zone, flip state)&lt;br /&gt;
We can notice that resource and money are uncountable, and don&#039;t need to be track individually so we can replace our mapping to&lt;br /&gt;
* (resource type/money,player home zone, count)&lt;br /&gt;
And vp stored already for us in player table, so we can remove it from that list.&lt;br /&gt;
&lt;br /&gt;
Now when we get to encode it we can see that everything can be encoded as (object,zone,state) form, where object and zone is string and state is integer. The resource mapping is slightly different semantically so you can go with two table, or counting using same table with state been used as count for resources.&lt;br /&gt;
&lt;br /&gt;
So the piece mapping for non-grid based games can be in most case represented by (string: token_key, string: token_location, int: token_state), example of such database schema can be found here: [https://github.com/elaskavaia/bga-sharedcode/blob/master/dbmodel.sql dbmodel.sql] and class implementing access to it here [https://github.com/elaskavaia/bga-sharedcode/blob/master/modules/tokens.php table.game.php].&lt;br /&gt;
&lt;br /&gt;
Variant 1: Minimalistic&lt;br /&gt;
&lt;br /&gt;
 CREATE TABLE IF NOT EXISTS `token` (&lt;br /&gt;
  `token_key` varchar(32) NOT NULL,&lt;br /&gt;
  `token_location` varchar(32) NOT NULL,&lt;br /&gt;
  `token_state` int(10),&lt;br /&gt;
  PRIMARY KEY (`token_key`)&lt;br /&gt;
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+token&lt;br /&gt;
! token_key&lt;br /&gt;
! token_location&lt;br /&gt;
! token_state&lt;br /&gt;
|-&lt;br /&gt;
|meeple_red_1&lt;br /&gt;
|home_red&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
|dice_black_2&lt;br /&gt;
|board_guard&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
|dice_green_1&lt;br /&gt;
|board_action_mayor&lt;br /&gt;
|3&lt;br /&gt;
|-&lt;br /&gt;
|bread&lt;br /&gt;
|home_red&lt;br /&gt;
|5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Now how we represent resource counters such as bread?&lt;br /&gt;
Using same table from we simply add special counter token for bread and use state to indicate the count. Note to keep first column unique we have to add player identification for that counter, i.e. ff0000 is red player.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+token&lt;br /&gt;
! token_key&lt;br /&gt;
! token_location&lt;br /&gt;
! token_state&lt;br /&gt;
|-&lt;br /&gt;
|bread_ff0000&lt;br /&gt;
|tableau_ff0000&lt;br /&gt;
|5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See php module for this table here https://github.com/elaskavaia/bga-sharedcode/blob/master/modules/tokens.php&lt;br /&gt;
&lt;br /&gt;
Variant 2: Additional resource table, resource count for each player id&lt;br /&gt;
&lt;br /&gt;
 CREATE TABLE IF NOT EXISTS `resource` (&lt;br /&gt;
  `player_id` int(10) unsigned NOT NULL,&lt;br /&gt;
  `resource_key` varchar(32) NOT NULL,&lt;br /&gt;
  `resource_count` int(10) signed NOT NULL,&lt;br /&gt;
  PRIMARY KEY (`player_id`,`resource_key`)&lt;br /&gt;
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;&lt;br /&gt;
&lt;br /&gt;
 ALTER TABLE resource ADD CONSTRAINT fk_player_id FOREIGN KEY (player_id) REFERENCES player(player_id);&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+resource&lt;br /&gt;
! player_id&lt;br /&gt;
! resource_key&lt;br /&gt;
! resource_count&lt;br /&gt;
|-&lt;br /&gt;
|123456&lt;br /&gt;
|bread&lt;br /&gt;
|5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Variant 3: More normalised&lt;br /&gt;
&lt;br /&gt;
This version is similar to &amp;quot;card&amp;quot; table from hearts tutorial, you can also use exact cards database schema and Deck implementation for most purposes (even you not dealing with cards). &lt;br /&gt;
&lt;br /&gt;
 CREATE TABLE IF NOT EXISTS `token` (&lt;br /&gt;
  `token_id` int(10) unsigned NOT NULL AUTO_INCREMENT,&lt;br /&gt;
  `token_type` varchar(16) NOT NULL,&lt;br /&gt;
  `token_arg` int(11) NOT NULL,&lt;br /&gt;
  `token_location` varchar(32) NOT NULL,&lt;br /&gt;
  `token_state` int(10),&lt;br /&gt;
  PRIMARY KEY (`token_id`)&lt;br /&gt;
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+token&lt;br /&gt;
! token_id&lt;br /&gt;
! token_type&lt;br /&gt;
! token_arg&lt;br /&gt;
! token_location&lt;br /&gt;
! token_state&lt;br /&gt;
|-&lt;br /&gt;
|22&lt;br /&gt;
|meeple&lt;br /&gt;
|123456&lt;br /&gt;
|home_123456&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
|23&lt;br /&gt;
|dice&lt;br /&gt;
|2&lt;br /&gt;
|board_guard&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
|26&lt;br /&gt;
|dice&lt;br /&gt;
|1&lt;br /&gt;
|board_action_mayor&lt;br /&gt;
|3&lt;br /&gt;
|-&lt;br /&gt;
|49&lt;br /&gt;
|bread&lt;br /&gt;
|0&lt;br /&gt;
|home_123456&lt;br /&gt;
|5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Advantages of this would be is a bit more straightforward to do some queries in db, disadvantage its hard to read (as you can compare with previous example, you&lt;br /&gt;
cannot just look at say, ah I know what it means). Another questionable advantage is it allows you to do id randomisation, so it hard to do crafted queries to &lt;br /&gt;
cheat, the down side of that you cannot understand it either, and handcraft db states for debugging or testing.&lt;br /&gt;
&lt;br /&gt;
=== Database for The card game ===&lt;br /&gt;
&lt;br /&gt;
Lets say you have a standard card game, player have hidden cards in hand, you can draw card from draw deck, play card on tableau and discard to discard pile.&lt;br /&gt;
We have to design database for such game.&lt;br /&gt;
&lt;br /&gt;
In real word to &amp;quot;save&amp;quot; the game we take a picture a play area, save cards from it, then put away draw deck, discard and hand of each player separately and mark it, also we will record current scoring (if any) and who&#039;s turn was it.&lt;br /&gt;
&lt;br /&gt;
* Framework handles state machine transition, so you don&#039;t have to worry about database design for that (i.e. who&#039;s turn it is, what phase of the game we are at, you still have to design it but part of state machine step)&lt;br /&gt;
* Also framework supports basic player information, color, order around the table, basic scoring, etc, so you don&#039;t have to worry about it either&lt;br /&gt;
* The only thing you need in our database is state of the &amp;quot;board&amp;quot;, which is &amp;quot;where each pieces is, and in what state&amp;quot;, or (position,rotation) pair.&lt;br /&gt;
&lt;br /&gt;
Lets see what we have for that:&lt;br /&gt;
* The card state is very simple, its usually &amp;quot;face up/face down&amp;quot;, &amp;quot;tapped/untapped&amp;quot;, &amp;quot;right side up/up side down&amp;quot;&lt;br /&gt;
* As position go we never need real coordinates x,y,z. We need to know what &amp;quot;zone&amp;quot; card was, and depending on the zone it may sometimes need an extra &amp;quot;z&amp;quot; or &amp;quot;x&amp;quot; as card order. The zone position usually static or irrelevant.&lt;br /&gt;
* So our model is: we have cards, which have some attributes, at any given point in time they belong to a &amp;quot;zone&amp;quot;, and can also have order and state&lt;br /&gt;
* Now for mapping we should consider what information changes and what information is static, later is always candidate for material file&lt;br /&gt;
* For dynamic information we should try to reduce amount of fields we need&lt;br /&gt;
**  we need at least a field for card, so its one&lt;br /&gt;
**  we need to know what zone cards belong to, its 2&lt;br /&gt;
**  and we have possibly few other fields, if you look closely at you game you may find out that most of the zone only need one attribute at a time, i.e. draw pile always have cards face down, hand always face up, also for hand and discard order does not matter at all (but for draw it does matter). So in majority of cases we can get away with one single extra integer field representing state or order&lt;br /&gt;
* In real database both card and zone will be integers as primary keys referring to additional tables, but in our case its total overkill, so they can be strings as easily&lt;br /&gt;
&lt;br /&gt;
Variant 1: Minimalistic&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE TABLE IF NOT EXISTS `card` (&lt;br /&gt;
  `card_key` varchar(32) unsigned NOT NULL,&lt;br /&gt;
  `card_location` varchar(32) NOT NULL,&lt;br /&gt;
  `card_state` int(11) NOT NULL,&lt;br /&gt;
  PRIMARY KEY (`card_id`)&lt;br /&gt;
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Variant 2: More normalised&lt;br /&gt;
&lt;br /&gt;
This version supported by Deck php class, so unless you want to rewrite db access layer go with this one&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE TABLE IF NOT EXISTS `card` (&lt;br /&gt;
  `card_id` int(10) unsigned NOT NULL AUTO_INCREMENT,&lt;br /&gt;
  `card_type` varchar(16) NOT NULL,&lt;br /&gt;
  `card_type_arg` int(11) NOT NULL,&lt;br /&gt;
  `card_location` varchar(16) NOT NULL,&lt;br /&gt;
  `card_location_arg` int(11) NOT NULL,&lt;br /&gt;
  PRIMARY KEY (`card_id`)&lt;br /&gt;
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: if you using this schema, some zones/locations have special semantic. The &#039;hand&#039; location is actually multiple locations - one per player, but player id is encoded as card_location_arg. If &#039;hand&#039; in your game is ordered, visible or can have some other card states, you cannot use hand location (replacement is hand_&amp;lt;player_id&amp;gt; or hand_&amp;lt;color_id&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
== Code Organization ==&lt;br /&gt;
&lt;br /&gt;
=== Including your own JavaScript module ===&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, modules/ggg_other.js&lt;br /&gt;
&lt;br /&gt;
* Create ggg_other.js in modules/ folder and sync&lt;br /&gt;
* Modify ggg.js to include it&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  define([ &amp;quot;dojo&amp;quot;, &amp;quot;dojo/_base/declare&amp;quot;, &amp;quot;ebg/core/gamegui&amp;quot;, &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
    // load my own module!!!&lt;br /&gt;
    g_gamethemeurl + &amp;quot;modules/ggg_other.js&amp;quot; ], function(dojo,&lt;br /&gt;
        declare) {&lt;br /&gt;
&lt;br /&gt;
=== Including your own JavaScript module (II) ===&lt;br /&gt;
&lt;br /&gt;
* Create ggg_other.js in modules/ folder and sync&lt;br /&gt;
&lt;br /&gt;
  define([], function () {&lt;br /&gt;
    return &amp;quot;value&amp;quot;;&lt;br /&gt;
  });&lt;br /&gt;
&lt;br /&gt;
* Modify ggg.js to include it&lt;br /&gt;
&lt;br /&gt;
  define([ &lt;br /&gt;
    &amp;quot;dojo&amp;quot;, &lt;br /&gt;
    &amp;quot;dojo/_base/declare&amp;quot;, &lt;br /&gt;
    &amp;quot;bgagame/modules/ggg_other&amp;quot;, &lt;br /&gt;
    &amp;quot;ebg/core/gamegui&amp;quot;, &lt;br /&gt;
    &amp;quot;ebg/counter&amp;quot;&lt;br /&gt;
  ], function(dojo, declare, other) {&lt;br /&gt;
  &lt;br /&gt;
  });&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
This is maybe a little bit more the idea of the AMD Loader than the first option, although the first option should work as well.&lt;br /&gt;
&lt;br /&gt;
A little explanation to this:&lt;br /&gt;
The define function loads all the modules listed in the array and calls the following function with these loaded modules as parameters.&lt;br /&gt;
By putting your module at the third position in the array it is passed as the third parameter to the function. Be aware that the modules are resolved by position only, not by name. So you can load the module &#039;&#039;&#039;ggg_other&#039;&#039;&#039; and pass it as a parameter with the name &#039;&#039;&#039;other&#039;&#039;&#039;. &#039;&#039;&#039;gamegui&#039;&#039;&#039; and &#039;&#039;&#039;counter&#039;&#039;&#039; are passed in as well, but when the parameters are not defined they are just skipped. Because these modules put their content into the global scope it does not matter and you can use them from there.&lt;br /&gt;
&lt;br /&gt;
In the example above the string &amp;quot;value&amp;quot; is passed for the parameter &#039;&#039;&#039;other&#039;&#039;&#039;, but the function in your module can return whatever you want. It can be an object, an array, something you declared with dojo.declare, you can return even functions. &lt;br /&gt;
Your module can load other modules. Just put them in the array at the beginning and pass them as parameters to your function.&lt;br /&gt;
The advantage of passing the values as parameter is that you do not need to put these values in the global scope, so they can&#039;t be collisions with values defined in other scripts or the BGA Framework.&lt;br /&gt;
&lt;br /&gt;
The dojo toolkit provides good documentation to all of its components, the complete documentation for the AMD-Loader is here:&lt;br /&gt;
https://dojotoolkit.org/documentation/tutorials/1.10/modules/index.html It should be still correct, even as it seems to be only for version 1.10&lt;br /&gt;
&lt;br /&gt;
=== Including your own PHP module ===&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.game.php, modules/ggg_other.php&lt;br /&gt;
&lt;br /&gt;
* Create ggg_other.php in modules/ folder and sync&lt;br /&gt;
* Modify ggg.game.php to include it&lt;br /&gt;
&lt;br /&gt;
 require_once (&#039;modules/ggg_other.php&#039;);&lt;br /&gt;
&lt;br /&gt;
=== Creating a test class to run PHP locally ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.game.php, stubs&lt;br /&gt;
For this you need stubs of other method you can use this for example&lt;br /&gt;
https://github.com/elaskavaia/bga-sharedcode/raw/master/misc/module/table/table.game.php&lt;br /&gt;
&lt;br /&gt;
Create another php files, i.e ggg_test.php&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
define(&amp;quot;APP_GAMEMODULE_PATH&amp;quot;, &amp;quot;misc/&amp;quot;); // include path to stubs, which defines &amp;quot;table.game.php&amp;quot; and other classes&lt;br /&gt;
require_once (&#039;eminentdomaine.game.php&#039;);&lt;br /&gt;
&lt;br /&gt;
class MyGameTest1 extends MyGame { // this is your game class defined in ggg.game.php&lt;br /&gt;
    function __construct() {&lt;br /&gt;
        parent::__construct();&lt;br /&gt;
        include &#039;../material.inc.php&#039;;// this is how this normally included, from constructor&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // override/stub methods here that access db and stuff&lt;br /&gt;
    function getGameStateValue($var) {&lt;br /&gt;
        if ($var == &#039;round&#039;)&lt;br /&gt;
            return 3;&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
$x = new MyGameTest1(); // instantiate your class&lt;br /&gt;
$p = $x-&amp;gt;getGameProgression(); // call one of the methods to test&lt;br /&gt;
if ($p != 50)&lt;br /&gt;
    echo &amp;quot;Test1: FAILED&amp;quot;;&lt;br /&gt;
else&lt;br /&gt;
    echo &amp;quot;Test1: PASSED&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Run from command line like&lt;br /&gt;
 php7 ggg_test.php&lt;br /&gt;
&lt;br /&gt;
If you do it this way - you can also use local php debugger (i.e. integrated with IDE or command line).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Avoiding code in dojo declare style ===&lt;br /&gt;
Dojo class declarations are rather bizzare and do not work with most IDEs.&lt;br /&gt;
If you want to write in plain JS with classes, you can stub all the dojo define/declare stuff&lt;br /&gt;
and hook your class into that, so the classes are outside of this mess.&lt;br /&gt;
&lt;br /&gt;
NOTE: this technique is for experienced developers, do not try it if you do not understand&lt;br /&gt;
the consequences.&lt;br /&gt;
&lt;br /&gt;
This is complete example of game .js class&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  // Testla is game name is has to be changed&lt;br /&gt;
class Testla {&lt;br /&gt;
	constructor(game) {&lt;br /&gt;
		console.log(&#039;game constructor&#039;);&lt;br /&gt;
		this.game = game;&lt;br /&gt;
		this.varfoo = new MyFoo(); // this example of class from custom module&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	setup(gamedatas) {&lt;br /&gt;
		console.log(&amp;quot;Starting game setup&amp;quot;, this.varfoo);&lt;br /&gt;
		this.gamedatas = gamedatas;&lt;br /&gt;
		this.dojo.create(&amp;quot;div&amp;quot;, { class: &#039;whiteblock&#039;, innerHTML: _(&amp;quot;hello&amp;quot;) }, &#039;thething&#039;);&lt;br /&gt;
		console.log(&amp;quot;Ending game setup&amp;quot;);&lt;br /&gt;
	};&lt;br /&gt;
	onEnteringState(stateName, args) {&lt;br /&gt;
		console.log(&#039;onEnteringState : &#039; + stateName, args);&lt;br /&gt;
		this.game.addActionButton(&#039;b1&#039;,_(&#039;Click Me&#039;), (e)=&amp;gt;this.onButtonClick(e));&lt;br /&gt;
	};&lt;br /&gt;
	onLeavingState(stateName) {&lt;br /&gt;
		console.log(&#039;onLeavingState : &#039; + stateName, args);&lt;br /&gt;
	};&lt;br /&gt;
	onUpdateActionButtons(stateName, args) {&lt;br /&gt;
		console.log(&#039;onUpdateActionButtons : &#039; + stateName, args);&lt;br /&gt;
	};&lt;br /&gt;
	onButtonClick(event) {&lt;br /&gt;
		console.log(&#039;onButtonClick&#039;,event);&lt;br /&gt;
	};&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&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;
	g_gamethemeurl + &#039;/modules/foo.js&#039; // custom module if needed&lt;br /&gt;
],&lt;br /&gt;
	function(dojo, declare) {&lt;br /&gt;
                // testla is game name is has to be changed&lt;br /&gt;
		return declare(&amp;quot;bgagame.testla&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
			constructor: function() {&lt;br /&gt;
				this.xapp = new Testla(this);&lt;br /&gt;
				this.xapp.dojo = dojo;&lt;br /&gt;
			},&lt;br /&gt;
			setup: function(gamedatas) {&lt;br /&gt;
				this.xapp.setup(gamedatas);&lt;br /&gt;
			},&lt;br /&gt;
			onEnteringState: function(stateName, args) {&lt;br /&gt;
				this.xapp.onEnteringState(stateName, args.args);&lt;br /&gt;
			},&lt;br /&gt;
			onLeavingState: function(stateName) {&lt;br /&gt;
				this.xapp.onLeavingState(stateName, args);&lt;br /&gt;
			},&lt;br /&gt;
			onUpdateActionButtons: function(stateName, args) {&lt;br /&gt;
				this.xapp.onUpdateActionButtons(stateName, args);&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;
=== More readable JS: onEnteringState ===&lt;br /&gt;
&lt;br /&gt;
If you have a lot of states onEnteringState and friends become rather wild, you can do this trick to call some method dynamically.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
     onEnteringState: function(stateName, args) {&lt;br /&gt;
       console.log(&#039;Entering state: &#039; + stateName, args);&lt;br /&gt;
&lt;br /&gt;
       // Call appropriate method&lt;br /&gt;
       var methodName = &amp;quot;onEnteringState_&amp;quot; + stateName;&lt;br /&gt;
       if (this[methodName] !== undefined) {             &lt;br /&gt;
          console.log(&#039;Calling &#039; + methodName, args.args);&lt;br /&gt;
          this[methodName](args.args);&lt;br /&gt;
       }&lt;br /&gt;
     },&lt;br /&gt;
&lt;br /&gt;
     onEnteringState_playerTurn: function(args) { // this is args directly, not args.args &lt;br /&gt;
         // process&lt;br /&gt;
     },&lt;br /&gt;
&lt;br /&gt;
     onEnteringState_playerSomethingElse: function(args) { &lt;br /&gt;
         // process&lt;br /&gt;
     },&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: since its ignores the undefined functions you don&#039;t have define function for each state, but on the other hand you cannot make typos.&lt;br /&gt;
Same applies to onUpdateActionButtons except you pass &#039;args&#039; to method, not args.args, and for onLeavingState where you don&#039;t pass anything.&lt;br /&gt;
&lt;br /&gt;
=== Frameworks and Preprocessors ===&lt;br /&gt;
&lt;br /&gt;
* [[Using Vue]] - work-in-progress guide on using the modern framework Vue.js to create a game&lt;br /&gt;
* [[Using Typescript and Scss]] - How to auto-build Typescript and SCSS files to make your code cleaner&lt;br /&gt;
&lt;br /&gt;
== Assorted Stuff ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Out-of-turn actions: Un-pass ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, ggg.game.php, ggg.action.php, states.inc.php&lt;br /&gt;
&lt;br /&gt;
In multiplayer game sometimes players passes but than they think more and want to un-Pass and redo their choice. &lt;br /&gt;
To re-active a player who passes some trickery required.&lt;br /&gt;
&lt;br /&gt;
Define a special action that does that and hook it up.&lt;br /&gt;
&lt;br /&gt;
In states.inc.php add an action to mmultipleactiveplayer state to &amp;quot;unpass&amp;quot;, lets call it &amp;quot;actionCancel&amp;quot;&lt;br /&gt;
&lt;br /&gt;
In ggg.action.php add action hook&lt;br /&gt;
    public function actionCancel() {&lt;br /&gt;
        self::setAjaxMode();&lt;br /&gt;
        $this-&amp;gt;game-&amp;gt;actionCancel();&lt;br /&gt;
        self::ajaxResponse();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
In ggg.game.php add action handler&lt;br /&gt;
    function actionCancel() {&lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;checkPossibleAction(&#039;actionCancel&#039;);&lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;setPlayersMultiactive(array ($this-&amp;gt;getCurrentPlayerId() ), &#039;error&#039;, false);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
Finally to call this in client ggg.js you would do something like:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 onUpdateActionButtons:  function(stateName, args) {&lt;br /&gt;
   if (this.isCurrentPlayerActive()) { &lt;br /&gt;
     // ...&lt;br /&gt;
   } else if (!this.isSpectator) { // player is NOT active but not spectator&lt;br /&gt;
       switch (stateName) {&lt;br /&gt;
          case &#039;playerTurnMuliPlayerState&#039;:&lt;br /&gt;
		this.addActionButton(&#039;button_unpass&#039;, _(&#039;Oh no!&#039;), &#039;onUnpass&#039;);&lt;br /&gt;
		break;&lt;br /&gt;
	}&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
				&lt;br /&gt;
 onUnpass: function(e) {&lt;br /&gt;
    this.ajaxcall(&amp;quot;/&amp;quot; + this.game_name + &amp;quot;/&amp;quot; +  this.game_name + &amp;quot;/actionCancel.html&amp;quot;, {}, this); // no checkAction!&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Although be careful that if the turn comes back to the player while he is about to click cancel, the action buttons will be updated and the player will misclick which can be quite frustrating. To avoid this, move the cancel button to another position, like to the left of pagemaintitletext:&lt;br /&gt;
  dojo.place(&#039;button_unpass&#039;, &#039;pagemaintitletext&#039;, &#039;before&#039;);&lt;br /&gt;
Being out of the generalactions div, it won&#039;t be automatically destroyed like normal buttons, so you&#039;ll have to handle that yourself in onLeavingState. You might also want to change the button color to red (blue buttons for active player only, red buttons also for inactive players?)&lt;br /&gt;
&lt;br /&gt;
Note: same technique can be used to do other out-of-turn actions, such as re-arranging cards in hand, exchanging resources, etc (i.e. if permitted by rules, such as &amp;quot;at any time player can...&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
=== Multi Step Interactions: Select Worker/Place Worker - Using Selection ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
Simple way to implement something like that without extra states is to use &amp;quot;selection&amp;quot; mechanism. When user click on worker add some sort of class into that element i.e. &#039;selected&#039; (which also have to have some indication by css i.e. outline).&lt;br /&gt;
&lt;br /&gt;
Than user can click on placement zone, you can use dojo.query for &amp;quot;selected&amp;quot; element and use it along with zone id to send data to server. If proper worker is not selected yet can give a error message using this.showMessage(...) function.&lt;br /&gt;
&lt;br /&gt;
Extra code required to properly cleanup selection between states.&lt;br /&gt;
Also when you do that sometimes you want to change the state prompt, see below &#039;Change state prompt&#039;&lt;br /&gt;
&lt;br /&gt;
=== Multi Step Interactions: Select Worker/Place Worker - Using Client States ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
I don&#039;t think its documented feature but there is a way to do client-only states, which is absolutely wonderful for few reasons&lt;br /&gt;
* When player interaction is two step process, such as select worker, place worker, or place worker, pick one of two resources of your choice&lt;br /&gt;
* When multi-step process can result of impossible situation and has to be undone (by rules)&lt;br /&gt;
* When multi-step process is triggered from multiple states (such as you can do same thing as activated card action, pass action or main action)&lt;br /&gt;
&lt;br /&gt;
So lets do Select Worker/Place Worker&lt;br /&gt;
&lt;br /&gt;
Define your server state as usual, i.e. playerMainTurn -&amp;gt; &amp;quot;You must pick up a worker&amp;quot;.&lt;br /&gt;
Now define a client state, we only need &amp;quot;name&amp;quot; and &amp;quot;descriptionmyturn&amp;quot;, lets say &amp;quot;client_playerPicksLocation&amp;quot;. Always prefix names of client state with &amp;quot;client_&amp;quot; to avoid confusion. Now we have to do the following:&lt;br /&gt;
* Have a handler for onUpdateActionButtons for playerMainTurn to activate all possible workers he can pick&lt;br /&gt;
* When player clicks workers, remember the worker in one of the members of the main class, I usually use one called this.clientStateArgs.&lt;br /&gt;
* Transition to new client state&lt;br /&gt;
  onWorker: function(e) {&lt;br /&gt;
      var id = event.currentTarget.id;&lt;br /&gt;
      dojo.stopEvent(event);&lt;br /&gt;
      ... // do validity checks&lt;br /&gt;
      this.clientStateArgs.worker_id = id;&lt;br /&gt;
      this.setClientState(&amp;quot;client_playerPicksLocation&amp;quot;, {&lt;br /&gt;
                                descriptionmyturn : _(&amp;quot;${you} must select location&amp;quot;),&lt;br /&gt;
                            });&lt;br /&gt;
   }&lt;br /&gt;
* Have a handler for onUpdateActionButtons for client_playerPicksLocation to activate all possible locations this worker can go AND add Cancel button (see below)&lt;br /&gt;
* Have a location handler which will eventually send a server request, using stored this.clientStateArgs.worker_id as worker id&lt;br /&gt;
* The cancel button should call a method to restore server state, also if you doing it for more than one state you can add this universally using this.on_client_state check&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        if (this.isCurrentPlayerActive()) {&lt;br /&gt;
          if (this.on_client_state &amp;amp;&amp;amp; !$(&#039;button_cancel&#039;)) {&lt;br /&gt;
               this.addActionButton(&#039;button_cancel&#039;, _(&#039;Cancel&#039;), dojo.hitch(this, function() {&lt;br /&gt;
                                             this.restoreServerGameState();&lt;br /&gt;
               }));&lt;br /&gt;
          }&lt;br /&gt;
        } &lt;br /&gt;
Note: usually I call my own function call this.cancelLocalStateEffects() which will do more stuff first then call restoreServerGameState(), same function is usually needs to be called when server request has failed (i.e. invalid move)&lt;br /&gt;
&lt;br /&gt;
Note: If you need more than 2 steps, you may have to do client side animation to reflect the new state, which gets trickier because you have to undo that also on cancellation.&lt;br /&gt;
&lt;br /&gt;
Code is available here [https://github.com/elaskavaia/bga-sharedcode/blob/master/sharedcode.js sharedcode.js] (its using playerTurnPlayCubes and client_selectCubeLocation).&lt;br /&gt;
&lt;br /&gt;
=== Action Stack - Using Client States ===&lt;br /&gt;
&lt;br /&gt;
Action stack required where game is very complex and use triggered effects that can &amp;quot;stack&amp;quot;. It not always actual stack, it can be queue or random access&lt;br /&gt;
Examples:&lt;br /&gt;
* Magic the Gathering - classic card game where effects go on Stack, that allows to counter spell and counter spell of counter spell (not on bga - it just example of mechanics)&lt;br /&gt;
* Ultimate Railroads - action taking game where effects can be executed in any order&lt;br /&gt;
* Lewis and Clark - card game where actions executed as queue&lt;br /&gt;
&lt;br /&gt;
There is two ways of implementing it - on the server or the client.&lt;br /&gt;
For the server see article below.&lt;br /&gt;
The requirement for client side stack is all action can be undone, which means&lt;br /&gt;
* No dice rolls&lt;br /&gt;
* No card drawn&lt;br /&gt;
* No other players interaction&lt;br /&gt;
&lt;br /&gt;
No snippets are here, as this will be too complex but basically flow is:&lt;br /&gt;
* You have a action/effect stack (queue/list) as js object attached to &amp;quot;this&amp;quot;, i.e. this.unprocessed_actions&lt;br /&gt;
* When player plays a card, worker, etc, you read the effect of that card from the material file (client copy), and place into stack&lt;br /&gt;
* Then we call dispatch method which pulls the next action from the stack and change client state accordinly,i.e.  this.setClientState(&amp;quot;client_playerGainsCubes&amp;quot;)&lt;br /&gt;
* When players acts on it - the action is removed from the stack and added to &amp;quot;server action arguments&amp;quot; list, this is another object which be used to send ajax call, i.e. this.clientStateArgs&lt;br /&gt;
* If nothing left in stack we can submit the ajax call assembling parameters from collected arguments (that can include action name)&lt;br /&gt;
* This method allows cheap undo - by restoring server state you will wipe out all user actions (but if you need intermediate aninmation you have to handle it yourself)&lt;br /&gt;
&lt;br /&gt;
Code can be found in Ultimate Railroads game (but it is random access list - so it a bit complex) and Lewis and Clark (complexity - use can always deny part of any effect)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Action Stack - Using Server States ===&lt;br /&gt;
&lt;br /&gt;
See definition of Action Stack above.&lt;br /&gt;
&lt;br /&gt;
To implement you usually need another db table that has the following fields: index of effect - which is used for sorted access, type - which is essense of the effect (i.e. collect resource), some extra arguments (i.e. resource type and resource count), and usually owner of the effect (i.e. player id)&lt;br /&gt;
The flow is:&lt;br /&gt;
* There is some initial player state, where player can play card for example&lt;br /&gt;
* Player main action - pushes the card effect on stack, which also can cause triggered effects which also go on stack&lt;br /&gt;
* After action processing is finished switch to game state which is &amp;quot;dispatcher&amp;quot;&lt;br /&gt;
* Gispatcher pulls the top effect (whatever definition of the top is), changes the active player and changes the state to appropriate player state to collect response&lt;br /&gt;
* Player state knows about the stack and pulls arguments (argX) from the effect arguments of the db&lt;br /&gt;
* Player action should clear up the top effect, and can possibly add more effects, then switch to &amp;quot;dispatcher&amp;quot; state again&lt;br /&gt;
* If stack is empty, dispatcher can either pick next player itself or use another game state which responsible for picking next player&lt;br /&gt;
&lt;br /&gt;
Code can be found in Tapestry.&lt;br /&gt;
&lt;br /&gt;
=== Changing state prompt ===&lt;br /&gt;
&lt;br /&gt;
State prompt is message displayed for player which usually comes from state description.&lt;br /&gt;
Sometimes you want to change it without changing state (one way is change state but locally, see client states above).&lt;br /&gt;
&lt;br /&gt;
Simple way just change the html&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        setMainTitle: function(text) {&lt;br /&gt;
            $(&#039;pagemaintitletext&#039;).innerHTML = text;&lt;br /&gt;
        },&lt;br /&gt;
         // usage&lt;br /&gt;
        onMeeple: function(event) {&lt;br /&gt;
              //... &lt;br /&gt;
              this.setMainTitle(_(&#039;You must select where meeple is going&#039;));&lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This however will not work with parameters and will not draw You in color, if you want this its more sophisticated:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        setDescriptionOnMyTurn : function(text) {&lt;br /&gt;
            this.gamedatas.gamestate.descriptionmyturn = text;&lt;br /&gt;
            var tpl = dojo.clone(this.gamedatas.gamestate.args);&lt;br /&gt;
            if (tpl === null) {&lt;br /&gt;
                tpl = {};&lt;br /&gt;
            }&lt;br /&gt;
            var title = &amp;quot;&amp;quot;;&lt;br /&gt;
            if (this.isCurrentPlayerActive() &amp;amp;&amp;amp; text !== null) {&lt;br /&gt;
                tpl.you = this.divYou(); &lt;br /&gt;
            }&lt;br /&gt;
            title = this.format_string_recursive(text, tpl);&lt;br /&gt;
&lt;br /&gt;
            if (!title) {&lt;br /&gt;
                this.setMainTitle(&amp;quot;&amp;amp;nbsp;&amp;quot;);&lt;br /&gt;
            } else {&lt;br /&gt;
                this.setMainTitle(title);&lt;br /&gt;
            }&lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: this method uses &#039;&#039;&#039;setMainTitle&#039;&#039;&#039; defined above and &#039;&#039;&#039;divYou&#039;&#039;&#039; defined in another section of this wiki.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Adding Image buttons ===&lt;br /&gt;
&lt;br /&gt;
Its pretty trivial but just in case you need a working function:&lt;br /&gt;
&lt;br /&gt;
ggg.js:&lt;br /&gt;
&lt;br /&gt;
                addImageActionButton: function (id, div_html, handler) { // div_html is string not node&lt;br /&gt;
                    this.addActionButton(id, div_html, handler, &#039;&#039;, false, &#039;gray&#039;); &lt;br /&gt;
                    dojo.style(id, &amp;quot;border&amp;quot;, &amp;quot;none&amp;quot;); // remove ugly border&lt;br /&gt;
                    dojo.addClass(id, &amp;quot;bgaimagebutton&amp;quot;); // add css class to do more styling&lt;br /&gt;
                    return $(id); // return node for chaining&lt;br /&gt;
                },&lt;br /&gt;
&lt;br /&gt;
Example of usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    this.addImageActionButton(&#039;button_coin&#039;,&amp;quot;&amp;lt;div class=&#039;coin&#039;&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;, ()=&amp;gt;{ alert(&#039;Ha!&#039;); });&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Assigning Player Order ===&lt;br /&gt;
Normally when game starts there is &amp;quot;natural&amp;quot; player order assigned randomly.&lt;br /&gt;
&lt;br /&gt;
If you want to deliberatly assign player order at the start of the game (for example, in a game with teams options), you can do so by retrieving the initialization-only player attribute &#039;&#039;&#039;player_table_order&#039;&#039;&#039; and using it to assign values to &#039;&#039;&#039;player_no&#039;&#039;&#039; (which is normally assigned at the start of a game in the order in which players come to the table). (See [https://en.doc.boardgamearena.com/Game_database_model:_dbmodel.sql#The_player_table Game database model] for more details.)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Example:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                // Retrieve inital player order ([0=&amp;gt;playerId1, 1=&amp;gt;playerId2, ...])&lt;br /&gt;
		$playerInitialOrder = [];&lt;br /&gt;
		foreach ($players as $playerId =&amp;gt; $player) {&lt;br /&gt;
			$playerInitialOrder[$player[&#039;player_table_order&#039;]] = $playerId;&lt;br /&gt;
		}&lt;br /&gt;
		ksort($playerInitialOrder);&lt;br /&gt;
		$playerInitialOrder = array_flip(array_values($playerInitialOrder));&lt;br /&gt;
&lt;br /&gt;
		// Player order based on &#039;playerTeams&#039; option&lt;br /&gt;
		$playerOrder = [0, 1, 2, 3];&lt;br /&gt;
		switch (self::getGameStateValue(&#039;playerTeams&#039;)) {&lt;br /&gt;
			case self::TEAM_1_2:&lt;br /&gt;
				$playerOrder = [0, 2, 1, 3];&lt;br /&gt;
				break;&lt;br /&gt;
			case self::TEAM_1_4:&lt;br /&gt;
				$playerOrder = [0, 1, 3, 2];&lt;br /&gt;
				break;&lt;br /&gt;
			case self::TEAM_RANDOM:&lt;br /&gt;
				shuffle($playerOrder);&lt;br /&gt;
				break;&lt;br /&gt;
			default:&lt;br /&gt;
			case self::TEAM_1_3:&lt;br /&gt;
				// Default order&lt;br /&gt;
				break;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
                // Create players&lt;br /&gt;
		// Note: if you added some extra field on &amp;quot;player&amp;quot; table in the database (dbmodel.sql), you can initialize it there.&lt;br /&gt;
		$sql =&lt;br /&gt;
			&#039;INSERT INTO player (player_id, player_color, player_canal, player_name, player_avatar, player_no) VALUES &#039;;&lt;br /&gt;
		$values = [];&lt;br /&gt;
&lt;br /&gt;
		foreach ($players as $playerId =&amp;gt; $player) {&lt;br /&gt;
			$color = array_shift($default_colors);&lt;br /&gt;
			$values[] =&lt;br /&gt;
				&amp;quot;(&#039;&amp;quot; .&lt;br /&gt;
				$playerId .&lt;br /&gt;
				&amp;quot;&#039;,&#039;$color&#039;,&#039;&amp;quot; .&lt;br /&gt;
				$player[&#039;player_canal&#039;] .&lt;br /&gt;
				&amp;quot;&#039;,&#039;&amp;quot; .&lt;br /&gt;
				addslashes($player[&#039;player_name&#039;]) .&lt;br /&gt;
				&amp;quot;&#039;,&#039;&amp;quot; .&lt;br /&gt;
				addslashes($player[&#039;player_avatar&#039;]) .&lt;br /&gt;
				&amp;quot;&#039;,&#039;&amp;quot; .&lt;br /&gt;
				$playerOrder[$playerInitialOrder[$playerId]] .&lt;br /&gt;
				&amp;quot;&#039;)&amp;quot;;&lt;br /&gt;
		}&lt;br /&gt;
		$sql .= implode(&#039;,&#039;, $values);&lt;br /&gt;
		self::DbQuery($sql);&lt;br /&gt;
		self::reattributeColorsBasedOnPreferences(&lt;br /&gt;
			$players,&lt;br /&gt;
			$gameinfos[&#039;player_colors&#039;]&lt;br /&gt;
		);&lt;br /&gt;
		self::reloadPlayersBasicInfos();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Send different notifications to active player vs everybody else ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
Hack alert. This is a hack. We were hoping for proper solution by bga framework.&lt;br /&gt;
&lt;br /&gt;
This will allow you to send notification with two message one for specific player and one for everybody else including spectators.&lt;br /&gt;
Note that this does not split the data - all data must be shared.&lt;br /&gt;
&lt;br /&gt;
Add this to .js file (if you already overriding it merge obviously)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/** @Override */&lt;br /&gt;
format_string_recursive: function(log, args) {&lt;br /&gt;
   if (typeof args.log_others != &#039;undefined&#039; &amp;amp;&amp;amp; typeof args.player_id != &#039;undefined&#039; &amp;amp;&amp;amp; this.player_id != args.player_id)&lt;br /&gt;
	log = args.log_others;&lt;br /&gt;
   return this.inherited(arguments); // you must call this to call super &lt;br /&gt;
},&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example of usage (from eminentdomain)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    $this-&amp;gt;notifyAllPlayers(&#039;tokenMoved&#039;, &lt;br /&gt;
             clienttranslate(&#039;${player_name} adds +2 Colonies to ${place_name}&#039;), // notification with show for player with player_id&lt;br /&gt;
             [&#039;player_id&#039;=&amp;gt;$player_id, // this is mandatory&lt;br /&gt;
             &#039;log_others&#039;=&amp;gt;clienttranslate(&#039;${player_name} adds +2 Colonies to an unknown planet&#039;), // notification will show for others&lt;br /&gt;
              ...&lt;br /&gt;
             ]);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Send transient notifications without incrementing move ID ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.php&lt;br /&gt;
&lt;br /&gt;
Hack alert. This is a hack.&lt;br /&gt;
&lt;br /&gt;
Use this if you need to send some transient notification that should not create a new move ID. The notification should be idempotent -- it should have no practical effect on the game state and would be &#039;&#039;&#039;safe to drop&#039;&#039;&#039; (e.g., it would not matter if a player never received this notification). For example, in a co-op game you want all players to see a real-time preview of some action, before the active player commits their turn.&lt;br /&gt;
&lt;br /&gt;
Doing this mainly affects the instant replay &amp;amp; archive modes. During replay, the BGA framework automatically inserts a 1.5-second pause between each &amp;quot;move&amp;quot;. With this hack, your transient notifications are not considered to be a &amp;quot;move&amp;quot;, so no pause gets added.&lt;br /&gt;
&lt;br /&gt;
; In ggg.php&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$this-&amp;gt;not_a_move_notification = true; // note: do not increase the move counter&lt;br /&gt;
$this-&amp;gt;notifyAllPlayers(&#039;cardsPreview&#039;, &#039;&#039;, $args);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: you cannot have code that send notification or even changes state after this, and you cannot reset this variable back either because it only takes effect when you exit action handling function&lt;br /&gt;
&lt;br /&gt;
=== Ajax Call wrapper ===&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
The current ajaxcall is super vebose and prone to errors, I suggest using a helper function. It does a lot of stuff you must do anyways.&lt;br /&gt;
Most beginner mistakes come from missing part of this code (which is understandstandable - this is a huge snippet to clone every time).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	ajaxcallwrapper: function(action, args, handler) {&lt;br /&gt;
		if (!args) args = []; // this allows to skip args parameter for action which do not require them&lt;br /&gt;
			&lt;br /&gt;
		args.lock = true; // this allows to avoid rapid action clicking which can cause race condition on server&lt;br /&gt;
		if (this.checkAction(action)) { // this does all the proper check that player is active and action is declared&lt;br /&gt;
			this.ajaxcall(&amp;quot;/&amp;quot; + this.game_name + &amp;quot;/&amp;quot; + this.game_name + &amp;quot;/&amp;quot; + action + &amp;quot;.html&amp;quot;, args, // this is mandatory fluff &lt;br /&gt;
				this, (result) =&amp;gt; { },  // success result handler is empty - it is never needed&lt;br /&gt;
                                               handler); // this is real result handler - it called both on success and error, it has optional param  &amp;quot;is_error&amp;quot; - you rarely need it&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   this.ajaxcallwrapper(&#039;pass&#039;); // no args&lt;br /&gt;
   this.ajaxcallwrapper(&#039;playCard&#039;, {card: card_id}); // with args&lt;br /&gt;
   this.ajaxcallwrapper(&#039;playCard&#039;, {card: card_id}, (is_error)=&amp;gt;{if (!is_error) dojo.query(&amp;quot;.selected&amp;quot;).removeClass(&#039;selected&#039;);}) // with handler that cleans up &#039;selected&#039; class on success&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: this always will lock interface and always check for action, you can modify this method to do it optionally, i.e&lt;br /&gt;
  if (args.lock!==false) args.lock = true; else delete args.lock; // it does not work with false value - it has to be removed&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Studio]]&lt;/div&gt;</summary>
		<author><name>SwHawk</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=BGA_Studio_Cookbook&amp;diff=14216</id>
		<title>BGA Studio Cookbook</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=BGA_Studio_Cookbook&amp;diff=14216"/>
		<updated>2022-07-31T21:07:31Z</updated>

		<summary type="html">&lt;p&gt;SwHawk: /* Second way: rely on the :formatFunction option provided by dojo.string.substitute */ typo&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
This page is collection of design and implementation recipes for BGA Studio framework.&lt;br /&gt;
For tooling and usage recipes see [[Tools and tips of BGA Studio]].&lt;br /&gt;
If you have your own recipes feel free to edit this page.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Visual Effects, Layout and Animation ==&lt;br /&gt;
&lt;br /&gt;
=== DOM manipulatons ===&lt;br /&gt;
&lt;br /&gt;
==== Create pieces dynamically (using template) ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg_ggg.tpl, ggg.js&lt;br /&gt;
&lt;br /&gt;
Note: this method is recommended by BGA guildlines&lt;br /&gt;
&lt;br /&gt;
Declared js template with variables in .tpl file, like this&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;
    // Javascript HTML templates&lt;br /&gt;
    var jstpl_ipiece = &#039;&amp;lt;div class=&amp;quot;${type} ${type}_${color} inlineblock&amp;quot; aria-label=&amp;quot;${name}&amp;quot; title=&amp;quot;${name}&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use it like this in .js file&lt;br /&gt;
  div = this.format_block(&#039;jstpl_ipiece&#039;, {&lt;br /&gt;
                                type : &#039;meeple&#039;,&lt;br /&gt;
                                color : &#039;ff0000&#039;,&lt;br /&gt;
                                name : &#039;Bob&#039;,&lt;br /&gt;
                            });&lt;br /&gt;
  &lt;br /&gt;
Then you do whatever you need to do with that div, this one specifically design to go to log entries, because it has embedded title (otherwise its a picture only) and no id.&lt;br /&gt;
&lt;br /&gt;
Note: you could have place this variable in js itself, but keeping it in .tpl allows you to have your js code be free of HTML. Normally it never happens but&lt;br /&gt;
it is good to strive for it.&lt;br /&gt;
Note: you can also use string concatenation, its less readable. You can also use dojo dom object creation api&#039;s but its brutally verbose and its more unreadable.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Create pieces dynamically (using string concatenation) ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
Note: Not recommended&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  div = &amp;quot;&amp;lt;div class=&#039;meeple &amp;quot;+color+&amp;quot;&#039;&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
==== Create all pieces statically ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg_ggg.tpl, ggg.css, ggg.view.php (optional) &lt;br /&gt;
&lt;br /&gt;
* Create ALL game pieces in html template (.tpl)&lt;br /&gt;
* ALL pieces should have unique id, and it should be meaningful, i.e. meeple_red_1&lt;br /&gt;
* Do not use inline styling&lt;br /&gt;
* Id of player&#039;s specific pieces should use some sort of &#039;color&#039; identification, since player id cannot be used in static layout, you can use english color name, hex 6 char value, or color &amp;quot;number&amp;quot; (1,2,3...)&lt;br /&gt;
* Pieces should have separated class for its color, type, etc, so it can be easily styled in groups. In example below you now can style all meeples, all red meeples or all red tokens, or all &amp;quot;first&amp;quot; meeples&lt;br /&gt;
&lt;br /&gt;
ggg.tpl:&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
  &amp;lt;div id=&amp;quot;home_red&amp;quot; class=&amp;quot;home_red home&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;div id=&amp;quot;meeple_red_1&amp;quot; class=&amp;quot;meeple red n1&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
     &amp;lt;div id=&amp;quot;meeple_red_2&amp;quot; class=&amp;quot;meeple red n2&amp;quot;&amp;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;
ggg.css:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.meeple {&lt;br /&gt;
	width: 32px;&lt;br /&gt;
	height: 39px;&lt;br /&gt;
	background-image: url(img/78_64_stand_meeples.png);&lt;br /&gt;
	background-size: 352px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.meeple.red {&lt;br /&gt;
	background-position: 30% 0%;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* There should be straight forward mapping between server id and js id (or 1:1)&lt;br /&gt;
* You place objects in different zones of the layout, and setup css to take care of layout&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.home .meeple{&lt;br /&gt;
   display: inline-block;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* If you need to have a temporary object that look like original you can use dojo.clone (and change id to some temp id)&lt;br /&gt;
* If there is lots of repetition or zone grid you can use template generator, but inject style declaration in css instead of inline style for flexibility&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
* If you use this model you cannot use premade js components such as Stock and Zone&lt;br /&gt;
* You have to use alternative methods of animation (slightly altered) since default method will leave object with inline style attributes which you don&#039;t need&lt;br /&gt;
&lt;br /&gt;
=== Logs ===&lt;br /&gt;
&lt;br /&gt;
==== Inject icon images in the log ====&lt;br /&gt;
&lt;br /&gt;
Here is an example of what was done for Terra Mystica which is simple and straightforward:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
//Define the proper message&lt;br /&gt;
		$message = clienttranslate(&#039;${player_name} gets ${power_income} via Structures&#039;);&lt;br /&gt;
		if ($price &amp;gt; 0) {&lt;br /&gt;
			self::DbQuery(&amp;quot;UPDATE player SET player_score = player_score - $price WHERE player_id = $player_id&amp;quot;);&lt;br /&gt;
			$message = clienttranslate(&#039;${player_name} pays ${vp_price} and gets ${power_income} via Structures&#039;);&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
// Notify&lt;br /&gt;
		self::notifyAllPlayers( &amp;quot;powerViaStructures&amp;quot;, $message, array(&lt;br /&gt;
			&#039;i18n&#039; =&amp;gt; array( ),&lt;br /&gt;
			&#039;player_id&#039; =&amp;gt; $player_id,&lt;br /&gt;
			&#039;player_name&#039; =&amp;gt; self::getUniqueValueFromDb( &amp;quot;SELECT player_name FROM player WHERE player_id = $player_id&amp;quot; ),&lt;br /&gt;
			&#039;power_tokens&#039; =&amp;gt; $power_tokens,&lt;br /&gt;
			&#039;vp_price&#039; =&amp;gt; self::getLogsVPAmount($price),&lt;br /&gt;
			&#039;power_income&#039; =&amp;gt; self::getLogsPowerAmount($power_income),&lt;br /&gt;
			&#039;newScore&#039; =&amp;gt; self::getUniqueValueFromDb( &amp;quot;SELECT player_score FROM player WHERE player_id = $player_id&amp;quot; ),&lt;br /&gt;
			&#039;counters&#039; =&amp;gt; $this-&amp;gt;getGameCounters(null),&lt;br /&gt;
		) );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With some functions to have the needed html added inside the substitution variable, such as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function getLogsPowerAmount( $amount ) {&lt;br /&gt;
		return &amp;quot;&amp;lt;div class=&#039;tmlogs_icon&#039; title=&#039;Power&#039;&amp;gt;&amp;lt;div class=&#039;power_amount&#039;&amp;gt;$amount&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: injecting html from php is not ideal but easy, if you want more clean solution, use method below but it is a lot more sophisticated.&lt;br /&gt;
&lt;br /&gt;
==== Inject images and styled html in the log ====&lt;br /&gt;
&lt;br /&gt;
So you want nice pictures in the game log. What do you do? The first idea that comes to mind is to send html from php in notifications (see method above). &lt;br /&gt;
&lt;br /&gt;
This is a bad idea for many reasons:&lt;br /&gt;
&lt;br /&gt;
* It&#039;s bad architecture. ui elements leak into the server, and now you have to manage the ui in multiple places.&lt;br /&gt;
* If you decided to change something in the ui in future version, replay logs for old games and tutorials may not work, since they use stored notifications.&lt;br /&gt;
* Log previews for old games become unreadable. (This is the log state before you enter the game replay, which is useful for troubleshooting and game analysis.)&lt;br /&gt;
* It&#039;s more data to transfer and store in the db.&lt;br /&gt;
* It&#039;s a nightmare for translators.&lt;br /&gt;
&lt;br /&gt;
So what else can you do? You can use client side log injection to intercept log arguments (which come from the server) and replace them with html on the client side. Here are three different method you can use to achieve this.&lt;br /&gt;
&lt;br /&gt;
===== First way : Override &amp;lt;code&amp;gt;this.format_string_recursive()&amp;lt;/code&amp;gt; method =====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, ggg.game.php&lt;br /&gt;
&lt;br /&gt;
I use this recipe for &#039;&#039;&#039;client side log injection&#039;&#039;&#039; to intercept log arguments (which come from the server) and replace them with html on the client side.&lt;br /&gt;
&lt;br /&gt;
[[File:clientloginjection.png|left]] &lt;br /&gt;
&lt;br /&gt;
ggg.js&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
        /** Override this function to inject html into log items. This is a built-in BGA method.  */&lt;br /&gt;
&lt;br /&gt;
        /* @Override */&lt;br /&gt;
        format_string_recursive : function format_string_recursive(log, args) {&lt;br /&gt;
            try {&lt;br /&gt;
                if (log &amp;amp;&amp;amp; args &amp;amp;&amp;amp; !args.processed) {&lt;br /&gt;
                    args.processed = true;&lt;br /&gt;
                    &lt;br /&gt;
&lt;br /&gt;
                    // list of special keys we want to replace with images&lt;br /&gt;
                    var keys = [&#039;place_name&#039;,&#039;token_name&#039;];&lt;br /&gt;
                    &lt;br /&gt;
                  &lt;br /&gt;
                    for ( var i in keys) {&lt;br /&gt;
                        var key = keys[i];&lt;br /&gt;
                        key in args &amp;amp;&amp;amp; args[key] = this.getTokenDiv(key, args);                            &lt;br /&gt;
&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            } catch (e) {&lt;br /&gt;
                console.error(log,args,&amp;quot;Exception thrown&amp;quot;, e.stack);&lt;br /&gt;
            }&lt;br /&gt;
            return this.inherited({callee: format_string_recursive}, arguments);&lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important:&#039;&#039;&#039; In the &#039;&#039;format_string_recursive&#039;&#039; method, the &#039;args&#039; parameter will only contain arguments passed to it from the notify method in ggg.game.php (see below).&lt;br /&gt;
&lt;br /&gt;
The &#039;log&#039; parameter is the actual string that is inserted into the logs. You can perform additional js string manipulation on it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        getTokenDiv : function(key, args) {&lt;br /&gt;
            // ... implement whatever html you want here, example from sharedcode.js&lt;br /&gt;
            var token_id = args[key];&lt;br /&gt;
            var item_type = getPart(token_id,0);&lt;br /&gt;
            var logid = &amp;quot;log&amp;quot; + (this.globalid++) + &amp;quot;_&amp;quot; + token_id;&lt;br /&gt;
            switch (item_type) {&lt;br /&gt;
                case &#039;wcube&#039;:&lt;br /&gt;
                    var tokenDiv = this.format_block(&#039;jstpl_resource_log&#039;, {&lt;br /&gt;
                        &amp;quot;id&amp;quot; : logid,&lt;br /&gt;
                        &amp;quot;type&amp;quot; : &amp;quot;wcube&amp;quot;,&lt;br /&gt;
                        &amp;quot;color&amp;quot; : getPart(token_id,1),&lt;br /&gt;
                    });&lt;br /&gt;
                    return tokenDiv;&lt;br /&gt;
             &lt;br /&gt;
                case &#039;meeple&#039;:&lt;br /&gt;
                    if ($(token_id)) {&lt;br /&gt;
                        var clone = dojo.clone($(token_id));&lt;br /&gt;
    &lt;br /&gt;
                        dojo.attr(clone, &amp;quot;id&amp;quot;, logid);&lt;br /&gt;
                        this.stripPosition(clone);&lt;br /&gt;
                        dojo.addClass(clone, &amp;quot;logitem&amp;quot;);&lt;br /&gt;
                        return clone.outerHTML;&lt;br /&gt;
                    }&lt;br /&gt;
                    break;&lt;br /&gt;
     &lt;br /&gt;
                default:&lt;br /&gt;
                    break;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            return &amp;quot;&#039;&amp;quot; + this.clienttranslate_string(this.getTokenName(token_id)) + &amp;quot;&#039;&amp;quot;;&lt;br /&gt;
       },&lt;br /&gt;
       getTokenName : function(key) {&lt;br /&gt;
           return this.gamedatas.token_types[key].name; // get name for the key, from static table for example&lt;br /&gt;
       },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that in this case the server simply injects token_id as a name, and the client substitutes it for the translated name or the picture.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ggg.game.php:&lt;br /&gt;
&lt;br /&gt;
           $this-&amp;gt;notifyAllPlayers(&#039;playerLog&#039;,clienttranslate(&#039;Game moves ${token_name}&#039;),[&#039;token_name&#039;=&amp;gt;$token_id]);&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important:&#039;&#039;&#039; As noted above, only arguments actually passed by this method are available to the args parameter received in the client-side &#039;&#039;format_string_recursive&#039;&#039; method.&lt;br /&gt;
&lt;br /&gt;
Sometimes it is the case that you want to pass arguments that are not actually included in the output message. For example, suppose we have a method like this:&lt;br /&gt;
&lt;br /&gt;
           $this-&amp;gt;notifyAllPlayers(&#039;tokenPlaced&#039;,clienttranslate(&#039;Player placed ${token_name}&#039;),array(&lt;br /&gt;
              &#039;token_name&#039; =&amp;gt; $token_id,&lt;br /&gt;
              &#039;zone_played&#039; =&amp;gt; $zone);&lt;br /&gt;
&lt;br /&gt;
This will output &amp;quot;Player placed ${token_name}&amp;quot; in the log, and if we subscribe to a notification method activated by the &amp;quot;tokenPlaced&amp;quot; event in the client-side code, that method can make use of the &#039;zone_played&#039; argument. &lt;br /&gt;
&lt;br /&gt;
Now if you want to make some really cool things with game log, most probably you would need more arguments than are included in log message. The problem with that,&lt;br /&gt;
it will work at first, but if you reload game using F5 or when the game loads in turn based mode, you will loose your additional parameters, why? Because when game reloads it does not actually send same notifications, it sends special &amp;quot;hitstorical_log&amp;quot; notification where all  parameters not listed in the message are removed. In example above, field zone_played would be removed from historical log as it is not included in message of the notification. You can till preserve specific arguments in historical log by adding special field preserve to notification arguments like this:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
           $this-&amp;gt;notifyAllPlayers(&#039;tokenPlaced&#039;,clienttranslate(&#039;Player placed ${token_name}&#039;),array(&lt;br /&gt;
              &#039;token_name&#039; =&amp;gt; $token_id,&lt;br /&gt;
              &#039;zone_played&#039; =&amp;gt; $zone,&lt;br /&gt;
              &#039;preserve&#039; =&amp;gt; [ &#039;zone_played&#039; ]&lt;br /&gt;
           );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now you can use zone_played in format_string_recursive even in historical logs.&lt;br /&gt;
&lt;br /&gt;
===== Second way: rely on the &amp;lt;code&amp;gt;:formatFunction&amp;lt;/code&amp;gt; option provided by &amp;lt;code&amp;gt;dojo.string.substitute&amp;lt;/code&amp;gt; =====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, ggg.game.php, ggg_ggg.tpl, ggg.css&lt;br /&gt;
&lt;br /&gt;
The above method will work in most of the cases, but if you use dotted keys such as &amp;lt;code&amp;gt;${card.name}&amp;lt;/code&amp;gt; (which is supported by the framework, for private state args), the key won&#039;t be substituted because the &amp;lt;code&amp;gt;key in arg&amp;lt;/code&amp;gt; test will fail. If so you need to rely either on this way, or the one after.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;WARNING:&#039;&#039;&#039; using this method on an already advanced project will require you to go through all your notifications to change keys !&lt;br /&gt;
&lt;br /&gt;
Under the hood, the &#039;&#039;&#039;this.format_string_recursive()&#039;&#039;&#039; function calls the &#039;&#039;&#039;dojo.string.substitute&#039;&#039;&#039; method which substitutes &amp;lt;code&amp;gt;${keys}&amp;lt;/code&amp;gt; with the value provided. If you take a look at the [https://dojotoolkit.org/reference-guide/1.7/dojo/string.html#substitute documentation] and [https://github.com/dojo/dojo/blob/c3ceb017cfa25b703f5662dc83d1c8aae9bc5d81/string.js#L163 source code] you can notice that the key can be suffixed with a colon (&amp;lt;code&amp;gt;:&amp;lt;/code&amp;gt;) followed by a function name. This will allow you to specify directly in the substitution string which keys need HTML injection.&lt;br /&gt;
&lt;br /&gt;
First of all, you need to define your formatting function in the ggg.js file:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[[ggg.js]]&lt;br /&gt;
        getTokenDiv : function(value, key) {&lt;br /&gt;
            //This is only an example implementation, you need to write your own.&lt;br /&gt;
            //The method should return HTML code&lt;br /&gt;
            switch (key) {&lt;br /&gt;
                case &#039;html_injected_argument1&#039;:&lt;br /&gt;
                    return this.format_block(&#039;jstpl_HTMLLogElement1&#039;,{value: value});&lt;br /&gt;
                case &#039;html_injected_argument2&#039;:&lt;br /&gt;
                    return this.format_block(&#039;jstpl_HTMLLogElement2&#039;,{value: value});&lt;br /&gt;
                ...&lt;br /&gt;
            }&lt;br /&gt;
       }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Obviously you need to define the appropriate templates in the ggg_ggg.tpl file:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[[ggg_ggg.tpl]]&lt;br /&gt;
let jstpl_HTMLLogElement1 = &#039;&amp;lt;div class=&amp;quot;log-element log-element-1-${value}&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
let jstpl_HTMLLogElement2 = &#039;&amp;lt;div class=&amp;quot;log-element log-element-2-${value}&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
And the appropriate classes in ggg.css.&lt;br /&gt;
&lt;br /&gt;
Then you need to add the &amp;lt;code&amp;gt;dojo/aspect&amp;lt;/code&amp;gt; module at the top of the ggg.js file:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[ggg.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 define([&lt;br /&gt;
     &amp;quot;dojo&amp;quot;, &amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&amp;quot;dojo/aspect&amp;quot;,&amp;lt;/span&amp;gt;                 //MUST BE IN THIRD POSITION&#039;&#039;&#039; (see [[#Including your own JavaScript module (II)|below]])&lt;br /&gt;
     &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
 ], function (dojo, declare, &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&#039;&#039;&#039;aspect&#039;&#039;&#039;&amp;lt;/span&amp;gt;) {&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
And you also need to add the following code in your &amp;lt;code&amp;gt;contructor&amp;lt;/code&amp;gt; method in the ggg.js:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[ggg.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
         constructor: function(){&lt;br /&gt;
             console.log(&#039;progressevolutiontechnologyswh constructor&#039;);&lt;br /&gt;
               &lt;br /&gt;
             // Here, you can init the global variables of your user interface&lt;br /&gt;
             // Example:&lt;br /&gt;
             // this.myGlobalValue = 0;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&#039;&#039;&#039;let gameObject = this;&#039;&#039;&#039;            //Needed as the this object in aspect.before will not refer to the game object in which the formatting function resides&lt;br /&gt;
             &#039;&#039;&#039;aspect.before(dojo.string, &amp;quot;substitute&amp;quot;, function(template, map, transform) {&#039;&#039;&#039;      //This allows you to modify the arguments of the dojo.string.substitute method before they&#039;re actually passed to it&lt;br /&gt;
                 &#039;&#039;&#039;return [template, map, transform, gameObject];&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now you&#039;re all set to inject HTML in your logs. To actually achieve this, you must specify the function name with the key like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[ggg.game.php]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 $this-&amp;gt;notifyAllPlayers(&amp;quot;notificationName&amp;quot;, clienttranslate(&amp;quot;This log message contains ${plainTextArgument} and the following will receive HTML injection: ${html_injected_argument1:getTokenDiv}&amp;quot;), [&lt;br /&gt;
     &amp;quot;plainTextArgument&amp;quot; =&amp;gt; &amp;quot;some plain text here&amp;quot;,&lt;br /&gt;
     &amp;quot;html_injected_argument1&amp;quot; =&amp;gt; &amp;quot;some value used by getTokenDiv&amp;quot;,&lt;br /&gt;
 ]);&lt;br /&gt;
&lt;br /&gt;
You&#039;re not limited writing only one function, you can write as many functions as you like, and have them each inject a specific type of HTML. You just need to specify the relevant function name after the column in the substitution key.&lt;br /&gt;
&lt;br /&gt;
===== Third way: rely on the &amp;lt;code&amp;gt;transform&amp;lt;/code&amp;gt; argument of &amp;lt;code&amp;gt;dojo.string.substitute&amp;lt;/code&amp;gt; =====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, ggg.game.php, ggg_ggg.tpl, ggg.css&lt;br /&gt;
&lt;br /&gt;
This method is also relying on the use of &amp;lt;code&amp;gt;dojo.string.substitute&amp;lt;/code&amp;gt; by the framework, and will use the &amp;lt;code&amp;gt;transform&amp;lt;/code&amp;gt; argument, which, accordting to [https://github.com/dojo/dojo/blob/c3ceb017cfa25b703f5662dc83d1c8aae9bc5d81/string.js#L163 source code] and [https://dojotoolkit.org/reference-guide/1.7/dojo/string.html#substitute documentation] will be run on all the messages going through dojo.string.substitute.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;WARNING:&#039;&#039;&#039; As this method will be applied to all strings that go through dojo.string.substitute. As such you must take extra care not to substitute keys that may be used by the framework (i.e. ${id}). In order to do so, a good practise would be to prefix all keys that need substitution with a trigram of the game name.&lt;br /&gt;
&lt;br /&gt;
Since all the keys will be fed to the tranform function, by default, it must return the value, substituted or not per your needs. You can define the function like this in the ggg.js file:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[ggg.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
         getTokenDiv : function(value, key) {&lt;br /&gt;
             //This is only an example implementation, you need to write your own.&lt;br /&gt;
             //The method should return HTML code&lt;br /&gt;
             switch (key) {&lt;br /&gt;
                 case &#039;html_injected_argument1&#039;:&lt;br /&gt;
                     return this.format_block(&#039;jstpl_HTMLLogElement1&#039;,{value: value});&lt;br /&gt;
                 case &#039;html_injected_argument2&#039;:&lt;br /&gt;
                     return this.format_block(&#039;jstpl_HTMLLogElement2&#039;,{value: value});&lt;br /&gt;
                 ...&lt;br /&gt;
                 &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&#039;&#039;&#039;default:&#039;&#039;&#039;&lt;br /&gt;
                     &#039;&#039;&#039;return value;&#039;&#039;&#039;&amp;lt;/span&amp;gt;                  &#039;&#039;&#039;//Needed otherwise regular strings won&#039;t appear since since the value isn&#039;t returned by the function&#039;&#039;&#039;&lt;br /&gt;
             }&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
The templates must be defined in the ggg_ggg.tpl file and the corresponding CSS classes in the ggg.css file.&lt;br /&gt;
&lt;br /&gt;
You need to add the following code at the beginning of the ggg.js file:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[ggg.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 define([&lt;br /&gt;
     &amp;quot;dojo&amp;quot;, &amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&amp;quot;dojo/aspect&amp;quot;,&amp;lt;/span&amp;gt;                 //MUST BE IN THIRD POSITION&#039;&#039;&#039; (see [[#Including your own JavaScript module (II)|below]])&lt;br /&gt;
     &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
 ], function (dojo, declare, &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&#039;&#039;&#039;aspect&#039;&#039;&#039;&amp;lt;/span&amp;gt;) {&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
And the following code to the &amp;lt;code&amp;gt;constructor&amp;lt;/code&amp;gt; method in ggg.js:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[[ggg.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
         constructor: function(){&lt;br /&gt;
             console.log(&#039;progressevolutiontechnologyswh constructor&#039;);&lt;br /&gt;
               &lt;br /&gt;
             // Here, you can init the global variables of your user interface&lt;br /&gt;
             // Example:&lt;br /&gt;
             // this.myGlobalValue = 0;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&#039;&#039;&#039;let transformFunction = dojo.hitch(this, &amp;quot;getTokenDiv&amp;quot;);&#039;&#039;&#039;            //Needed as the this object in aspect.before will not refer to the game object in which the formatting function resides&lt;br /&gt;
             &#039;&#039;&#039;aspect.before(dojo.string, &amp;quot;substitute&amp;quot;, function(template, map, transform) {&#039;&#039;&#039;&lt;br /&gt;
                 &#039;&#039;&#039;if (undefined === transform) {&#039;&#039;&#039;                                   //Check for a transform function presence, just in case&lt;br /&gt;
                     &#039;&#039;&#039;return [template, map, transform];&#039;&#039;&#039;&lt;br /&gt;
                 &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Processing logs on re-loading ====&lt;br /&gt;
&lt;br /&gt;
You rarely need to process logs when reloading, but if you want to do something fancy you may have to do it after logs are loaded. &lt;br /&gt;
Logs are loaded asyncronously so you have to listen for logs to be fully loaded.&lt;br /&gt;
Unfortunately there is no direct way of doing it so this is the hack.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Hack alert&#039;&#039;&#039; - this extends undocumented function and may be broken when framework is updated&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
			/*&lt;br /&gt;
  			* [Undocumented] Override BGA framework functions to call onLoadingLogsComplete when loading is done&lt;br /&gt;
                        @Override&lt;br /&gt;
   			*/&lt;br /&gt;
			setLoader: function(image_progress, logs_progress) {&lt;br /&gt;
				this.inherited(arguments); // required, this is &amp;quot;super()&amp;quot; call, do not remove&lt;br /&gt;
				//console.log(&amp;quot;loader&amp;quot;, image_progress, logs_progress)&lt;br /&gt;
				if (!this.isLoadingLogsComplete &amp;amp;&amp;amp; logs_progress &amp;gt;= 100) {&lt;br /&gt;
					this.isLoadingLogsComplete = true; // this is to prevent from calling this more then once&lt;br /&gt;
					this.onLoadingLogsComplete();&lt;br /&gt;
				}&lt;br /&gt;
			},&lt;br /&gt;
&lt;br /&gt;
			onLoadingLogsComplete: function() {&lt;br /&gt;
				console.log(&#039;Loading logs complete&#039;);&lt;br /&gt;
				// do something here&lt;br /&gt;
			},&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Player Panel ===&lt;br /&gt;
&lt;br /&gt;
==== Inserting non-player panel ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, ggg_ggg.tpl&lt;br /&gt;
&lt;br /&gt;
If you want to insert non-player panel on the right side (for example to hold extra preferences, zooming controls, etc)&lt;br /&gt;
&lt;br /&gt;
this can go pretty much anywhere in template it will be moved later&lt;br /&gt;
&lt;br /&gt;
ggg_ggg.tpl:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	&amp;lt;div class=&#039;player_board_config&#039; id=&amp;quot;player_board_config&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;!-- here is whatever you want, buttons just example --&amp;gt;&lt;br /&gt;
		&amp;lt;button id=&amp;quot;zoom-out&amp;quot; class=&amp;quot; fa fa-search-minus fa-2x config-control&amp;quot;&amp;gt;&amp;lt;/button&amp;gt;&lt;br /&gt;
		&amp;lt;button id=&amp;quot;zoom-in&amp;quot; class=&amp;quot; fa fa-search-plus fa-2x config-control&amp;quot;&amp;gt;&amp;lt;/button&amp;gt;&lt;br /&gt;
		&amp;lt;button id=&amp;quot;show-settings&amp;quot; class=&amp;quot;fa fa-cog fa-2x config-control &amp;quot;&amp;gt;&amp;lt;/button&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
some hackery required in js&lt;br /&gt;
&lt;br /&gt;
ggg.js:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* @Override */&lt;br /&gt;
	updatePlayerOrdering() {&lt;br /&gt;
		this.inherited(arguments);&lt;br /&gt;
		dojo.place(&#039;player_board_config&#039;, &#039;player_boards&#039;, &#039;first&#039;);&lt;br /&gt;
	},&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Images and Icons ===&lt;br /&gt;
&lt;br /&gt;
==== Accessing images from js ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
     // your game resources&lt;br /&gt;
     &lt;br /&gt;
     var my_img = &#039;&amp;lt;img src=&amp;quot;&#039;+g_gamethemeurl+&#039;img/cards.jpg&amp;quot;/&amp;gt;&#039;;&lt;br /&gt;
     &lt;br /&gt;
     // shared resources&lt;br /&gt;
     var my_help_img = &amp;quot;&amp;lt;img class=&#039;imgtext&#039; src=&#039;&amp;quot; + g_themeurl + &amp;quot;img/layout/help_click.png&#039; alt=&#039;action&#039; /&amp;gt; &amp;lt;span class=&#039;tooltiptext&#039;&amp;gt;&amp;quot; +&lt;br /&gt;
                    text + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== High-Definition Graphics ====&lt;br /&gt;
&lt;br /&gt;
Some users will have screens which can display text and images at a greater resolution than the usual 72 dpi, e.g. the &amp;quot;Retina&amp;quot; screens on the 5k iMac, all iPads, and high-DPI screens on laptops from many manufacturers. If you can get art assets at this size, they will make your game look extra beautiful. You &#039;&#039;could&#039;&#039; just use large graphics and scale them down, but that would increase the download time and bandwidth for users who can&#039;t display them. Instead, a good way is to prepare a separate graphics file at exactly twice the size you would use otherwise, and add &amp;quot;@2x&amp;quot; at the end of the filename, e.g. if pieces.png is 240x320, then pieces@2x.png is 480x640.&lt;br /&gt;
&lt;br /&gt;
There are two changes required in order to use the separate graphics files. First in your css, where you use a file, add a media query which overrides the original definition and uses the bigger version on devices which can display them. Ensuring that the &amp;quot;background-size&amp;quot; attribute is set means that the size of the displayed object doesn&#039;t change, but only is drawn at the improved dot pitch.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.piece {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    background-image: url(&#039;img/pieces.png&#039;);&lt;br /&gt;
    background-size:240px 320px;&lt;br /&gt;
    z-index: 10;&lt;br /&gt;
}&lt;br /&gt;
@media (-webkit-min-device-pixel-ratio: 2), (min-device-pixel-ratio: 2), (min-resolution: 192dpi)&lt;br /&gt;
{&lt;br /&gt;
    .piece {&lt;br /&gt;
        background-image: url(&#039;img/pieces@2x.png&#039;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Secondly, in your setup function in javascript, you must ensure than only the appropriate one version of the file gets pre-loaded (otherwise you more than waste the bandwidth saved by maintaining the standard-resolution file). Note that the media query is the same in both cases:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
            var isRetina = &amp;quot;(-webkit-min-device-pixel-ratio: 2), (min-device-pixel-ratio: 2), (min-resolution: 192dpi)&amp;quot;;&lt;br /&gt;
            if (window.matchMedia(isRetina).matches)&lt;br /&gt;
            {&lt;br /&gt;
                this.dontPreloadImage( &#039;pieces.png&#039; );&lt;br /&gt;
                this.dontPreloadImage( &#039;board.jpg&#039; );&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                this.dontPreloadImage( &#039;pieces@2x.png&#039; );&lt;br /&gt;
                this.dontPreloadImage( &#039;board@2x.jpg&#039; );&lt;br /&gt;
            }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using CSS to create different colors of game pieces if you have only white piece ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
background-color: #${color}; &lt;br /&gt;
background-blend-mode: multiply;&lt;br /&gt;
background-image: url( &#039;img/mypiece.png&#039;);&lt;br /&gt;
mask: url(&#039;img/mypiece.png&#039;);&lt;br /&gt;
-webkit-mask: url(&#039;img/mypiece.png&#039;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where ${color} - is color you want&lt;br /&gt;
&lt;br /&gt;
Note: piece has to be white (shades of gray). Sprite can be used too, just add add blackground-position as usuall.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Other Fluff ===&lt;br /&gt;
&lt;br /&gt;
==== Use thematic fonts ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.css&lt;br /&gt;
&lt;br /&gt;
Sometime game elements use specific fonts of text, if you want to match it up you can load some specific font (IMPORTANT: from some &#039;&#039;&#039;free font&#039;&#039;&#039; source. See notes below).&lt;br /&gt;
&lt;br /&gt;
[[File:Dragonline_font.png]]&lt;br /&gt;
&lt;br /&gt;
.css&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* latin-ext */&lt;br /&gt;
@font-face {&lt;br /&gt;
  font-family: &#039;Qwigley&#039;;&lt;br /&gt;
  font-style: normal;&lt;br /&gt;
  font-weight: 400;&lt;br /&gt;
  src: local(&#039;Qwigley&#039;), local(&#039;Qwigley-Regular&#039;), url(https://fonts.gstatic.com/s/qwigley/v6/2Dy1Unur1HJoklbsg4iPJ_Y6323mHUZFJMgTvxaG2iE.woff2) format(&#039;woff2&#039;);&lt;br /&gt;
  unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;&lt;br /&gt;
}&lt;br /&gt;
/* latin */&lt;br /&gt;
@font-face {&lt;br /&gt;
  font-family: &#039;Qwigley&#039;;&lt;br /&gt;
  font-style: normal;&lt;br /&gt;
  font-weight: normal;&lt;br /&gt;
  src: local(&#039;Qwigley&#039;), local(&#039;Qwigley-Regular&#039;), url(https://fonts.gstatic.com/s/qwigley/v6/gThgNuQB0o5ITpgpLi4Zpw.woff2) format(&#039;woff2&#039;);&lt;br /&gt;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;&lt;br /&gt;
}&lt;br /&gt;
@font-face {&lt;br /&gt;
  font-family: &#039;Qwigley&#039;;&lt;br /&gt;
  font-style: normal;&lt;br /&gt;
  font-weight: normal;&lt;br /&gt;
  src: local(&#039;Qwigley&#039;), local(&#039;Qwigley-Regular&#039;), url(http://ff.static.1001fonts.net/q/w/qwigley.regular.ttf) format(&#039;ttf&#039;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.zone_title {&lt;br /&gt;
	display: inline-block;&lt;br /&gt;
	position: absolute;&lt;br /&gt;
	font: italic 32px/32px &amp;quot;Qwigley&amp;quot;, cursive;	   &lt;br /&gt;
	height: 32px;&lt;br /&gt;
	width: auto;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NB:&#039;&#039;&#039; if you need to include a font that&#039;s not available online, an extra action will be needed from an admin. Please include the font file(s) in your img directory, and mention it to admins when requesting your game to be moved to alpha. &#039;&#039;&#039;Please remember that the font has to be free, and include a .txt with all appropriate license information about the font.&#039;&#039;&#039;&lt;br /&gt;
You can look for free fonts (for example) on https://fonts.google.com or https://www.fontsquirrel.com/)&lt;br /&gt;
&lt;br /&gt;
=== Use player color in template ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg_ggg.tpl, ggg.view.php&lt;br /&gt;
&lt;br /&gt;
.view.php:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    function build_page($viewArgs) {&lt;br /&gt;
        // Get players &amp;amp; players number&lt;br /&gt;
        $players = $this-&amp;gt;game-&amp;gt;loadPlayersBasicInfos();&lt;br /&gt;
        $players_nbr = count($players);&lt;br /&gt;
        /**&lt;br /&gt;
         * ********* Place your code below: ***********&lt;br /&gt;
         */&lt;br /&gt;
        &lt;br /&gt;
        // Set PCOLOR to the current player color hex&lt;br /&gt;
        global $g_user;&lt;br /&gt;
        $cplayer = $g_user-&amp;gt;get_id();&lt;br /&gt;
        if (array_key_exists($cplayer, $players)) { // may be not set if spectator&lt;br /&gt;
            $player_color = $players [$cplayer] [&#039;player_color&#039;];&lt;br /&gt;
        } else {&lt;br /&gt;
            $player_color = &#039;ffffff&#039;; // spectator&lt;br /&gt;
        }&lt;br /&gt;
        $this-&amp;gt;tpl [&#039;PCOLOR&#039;] = $player_color;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Scale to fit for big boards ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg_ggg.tpl, ggg.js&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Lets say you have huge game board, and lets say you want it to be 1400px wide. Besides the board there will be side bar which is 240 and trim. &lt;br /&gt;
My display is 1920 wide so it fits, but there is big chance other people won&#039;t have that width. What do you do?&lt;br /&gt;
&lt;br /&gt;
You have to decide:&lt;br /&gt;
* If board does not fit you want scale whole thing down, the best way is probably use viewport (see https://en.doc.boardgamearena.com/Your_game_mobile_version)&lt;br /&gt;
* You can leave the board as is and make sure it is scrollable horizonatally&lt;br /&gt;
* You add custom scale just for the board (can add user controls  - and hook to transform: scale())&lt;br /&gt;
&lt;br /&gt;
I tried to auto-scale but this just does work, too many variables - browser zoom, 3d mode, viewport, custom bga scaling, devicePixelRatio - all create some impossible coctail of zooming...&lt;br /&gt;
Here is scaling functing for custom user scaling&lt;br /&gt;
&lt;br /&gt;
ggg_ggg.tpl:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   &amp;lt;div id=&amp;quot;thething&amp;quot; class=&amp;quot;thething&amp;quot;&amp;gt;&lt;br /&gt;
            ... everything else you declare ...&lt;br /&gt;
   &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ggg.js:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    onZoomPlus: function() {&lt;br /&gt;
       this.my_zoom+=0.1;&lt;br /&gt;
       this.zoommy(&#039;thething&#039;,this.my_zoom);&lt;br /&gt;
    },&lt;br /&gt;
&lt;br /&gt;
    zoommy: function(node, zoom) {&lt;br /&gt;
                node=$(node);&lt;br /&gt;
		var width = 100 / zoom;&lt;br /&gt;
		node.style.transformOrigin = &amp;quot;0 0&amp;quot;;&lt;br /&gt;
		node.style.transform = &amp;quot;scale(&amp;quot; + zoom + &amp;quot;)&amp;quot;;&lt;br /&gt;
		node.style.width = width + &amp;quot;%&amp;quot;;&lt;br /&gt;
    },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Dynamic tooltips ===&lt;br /&gt;
&lt;br /&gt;
If you really need a dynamic tooltip you can use this technique. (Only use it if the static tooltips provided by the BGA framework are not sufficient.)&lt;br /&gt;
&lt;br /&gt;
            new dijit.Tooltip({&lt;br /&gt;
                connectId: [&amp;quot;divItemId&amp;quot;],&lt;br /&gt;
                getContent: function(matchedNode){&lt;br /&gt;
                    return &amp;quot;... calculated ...&amp;quot;; &lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is an out-of-the-box djit.Tooltip. It has a &#039;&#039;getContent&#039;&#039; method which is called dynamically.&lt;br /&gt;
&lt;br /&gt;
The string function return becomes the innerHTML of the tooltip, so it can be anything. In this example matchedNode is a dojo node representing dom object with id of &amp;quot;divItemId&amp;quot; but there are more parameters which I am not posting here which allows more sophisticated subnode queries (i.e. you can attach tooltip to all nodes with class or whatever).&lt;br /&gt;
&lt;br /&gt;
[https://dojotoolkit.org/reference-guide/1.10/dijit/Tooltip.html dijit.Tooltip]&lt;br /&gt;
&lt;br /&gt;
It&#039;s not part of the BGA API so use at your own risk.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Rendering text with players color and proper background ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
This example actually writes &amp;quot;You&amp;quot; but you can replace this with player name as easily, drop translating function in this case&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        /* Implementation of proper colored You with background in case of white or light colors  */&lt;br /&gt;
 &lt;br /&gt;
        divYou : function() {&lt;br /&gt;
            var color = this.gamedatas.players[this.player_id].color;&lt;br /&gt;
            var color_bg = &amp;quot;&amp;quot;;&lt;br /&gt;
            if (this.gamedatas.players[this.player_id] &amp;amp;&amp;amp; this.gamedatas.players[this.player_id].color_back) {&lt;br /&gt;
                color_bg = &amp;quot;background-color:#&amp;quot; + this.gamedatas.players[this.player_id].color_back + &amp;quot;;&amp;quot;;&lt;br /&gt;
            }&lt;br /&gt;
            var you = &amp;quot;&amp;lt;span style=\&amp;quot;font-weight:bold;color:#&amp;quot; + color + &amp;quot;;&amp;quot; + color_bg + &amp;quot;\&amp;quot;&amp;gt;&amp;quot; + __(&amp;quot;lang_mainsite&amp;quot;, &amp;quot;You&amp;quot;) + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
            return you;&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Cool realistic shadow effect with CSS ===&lt;br /&gt;
&lt;br /&gt;
==== Rectangles and circles ====&lt;br /&gt;
&lt;br /&gt;
It is often nice to have a drop shadow around tiles and tokens, to separate them from the table visually. It is very easy to add a shadow to rectangular elements, just add this to your css:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.xxx-tile {&lt;br /&gt;
    box-shadow: 3px 3px 3px #000000a0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
box-shadow obeys &#039;&#039;&#039;border-radius&#039;&#039;&#039; of the element, so it will look good for rounded rectangles, and hence also circles (if border-radius is set appropriately).&lt;br /&gt;
&lt;br /&gt;
box-shadow also supports various other parameters and can be used to achieve effects such as glowing, borders, inner shadows etc. If you need to animate a box-shadow, you may be able to get better performance (avoiding redraws) if you attach the shadow to another element (possibly an ::after pseudo-element) and change only the &#039;&#039;&#039;opacity&#039;&#039;&#039; of that element.&lt;br /&gt;
&lt;br /&gt;
==== Irregular Shapes ====&lt;br /&gt;
&lt;br /&gt;
If you wish to make a shadow effect for game pieces that are not a rectangle, but your game pieces are drawn from rectangles in a PNG image, you can apply the shadow to the piece using any art package and save it inside the image. This usually will yield the best performance. Remember to account for the size of the shadow when you lay out images in the sprite sheet.&lt;br /&gt;
&lt;br /&gt;
However that sometimes will not be an option, for example if the image needs to be rotated while the shadow remains offset in the same direction. In this case, one option is to not use box-shadow but use filter, which is supported by recent major browsers.  This way, you can use the alpha channel of your element to drop a shadow.  This even work for transparent backgrounds, so that if you are using the &amp;quot;CSS-sprite&amp;quot; method, it will work!&lt;br /&gt;
&lt;br /&gt;
For instance:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.xxx-token {&lt;br /&gt;
    filter: drop-shadow(0px 0px 1px #000000);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beware that some browsers still do not always draw drop-shadow correctly. In particular, Safari frequently leaves bits of shadow behind when objects move around the screen. In Chrome, shadows sometimes flicker badly if another element is animating close by. Some of these correctness issues can be solved by adding &#039;&#039;&#039;isolation: isolate; will-change: filter;&#039;&#039;&#039; to affected elements, but this significantly affects redraw performance.&lt;br /&gt;
&lt;br /&gt;
Beware of performance issues - particularly on Safari (MacOS, iPhone and iPad). Keep in mind that drop-shadow are very GPU intensive. This becomes noticeable once you have about 40 components with drop-shadow filter. If that is your case, you can quite easily implement a user preference to disable shadows for users on slower machines:&lt;br /&gt;
&lt;br /&gt;
gameoptions.inc.php&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
100 =&amp;gt; array(&lt;br /&gt;
			&#039;name&#039; =&amp;gt; totranslate(&#039;Shadows&#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;Enabled&#039; ), &#039;cssPref&#039; =&amp;gt; &#039;&#039; ),&lt;br /&gt;
					2 =&amp;gt; array( &#039;name&#039; =&amp;gt; totranslate( &#039;Disabled&#039; ), &#039;cssPref&#039; =&amp;gt; &#039;no-shadow&#039; )&lt;br /&gt;
			)&lt;br /&gt;
	),&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[game].css&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.no-shadow * {&lt;br /&gt;
	filter: none !important; &lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Shadows with clip-path ====&lt;br /&gt;
&lt;br /&gt;
For some reason, a shadow will not work together with clip-path on one element. To use both clip-path (when for example using .svg to cut out cardboard components from your .jpg spritesheet) and drop-shadow, you need to wrap the element into another one, and apply drop-shadow to the outer one, and clip-path to the inner one.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;div class=&#039;my-token-wrap&#039;&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&#039;my-token&#039;&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;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.my-token-wrap {&lt;br /&gt;
    filter: drop-shadow(0px 0px 1px #000000);&lt;br /&gt;
}&lt;br /&gt;
.my-token-wrap .my-token {&lt;br /&gt;
    clip-path: url(#my-token-path);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Using the CSS classes from the state machine ===&lt;br /&gt;
&lt;br /&gt;
If you need to hide or show stuff depending on the state of your game, you can of course use javascript, but CSS is hand enough for that.  The #overall-content element does change class depending on the game state.  For instance, if you are in state &#039;&#039;playerTurn&#039;&#039;, it will have the class &#039;&#039;gamestate_playerTurn&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
So now, if you want to show the discard pile only during player turns, you may use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#discard_pile { display: none }&lt;br /&gt;
.gamestate_playerTurn #discard_pile { display: block }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This can be used if you want to change sizing of elements, position, layout or visual appearance.&lt;br /&gt;
&lt;br /&gt;
== Game Model and Database design ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Database for The euro game ===&lt;br /&gt;
Lets say we have a game with workers, dice, tokens, board, resources, money and vp. Workers and dice can be placed in various zones on the board, and you can get resources, money, tokens and vp in your home zone. Also tokens can be flipped or not flipped.&lt;br /&gt;
&lt;br /&gt;
[[File:Madeira board.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now lets try to map it, we have&lt;br /&gt;
* (meeple,zone)&lt;br /&gt;
* (die, zone, sideup)&lt;br /&gt;
* (resource cube/money token/vp token,player home zone)&lt;br /&gt;
* (token, player home zone, flip state)&lt;br /&gt;
We can notice that resource and money are uncountable, and don&#039;t need to be track individually so we can replace our mapping to&lt;br /&gt;
* (resource type/money,player home zone, count)&lt;br /&gt;
And vp stored already for us in player table, so we can remove it from that list.&lt;br /&gt;
&lt;br /&gt;
Now when we get to encode it we can see that everything can be encoded as (object,zone,state) form, where object and zone is string and state is integer. The resource mapping is slightly different semantically so you can go with two table, or counting using same table with state been used as count for resources.&lt;br /&gt;
&lt;br /&gt;
So the piece mapping for non-grid based games can be in most case represented by (string: token_key, string: token_location, int: token_state), example of such database schema can be found here: [https://github.com/elaskavaia/bga-sharedcode/blob/master/dbmodel.sql dbmodel.sql] and class implementing access to it here [https://github.com/elaskavaia/bga-sharedcode/blob/master/modules/tokens.php table.game.php].&lt;br /&gt;
&lt;br /&gt;
Variant 1: Minimalistic&lt;br /&gt;
&lt;br /&gt;
 CREATE TABLE IF NOT EXISTS `token` (&lt;br /&gt;
  `token_key` varchar(32) NOT NULL,&lt;br /&gt;
  `token_location` varchar(32) NOT NULL,&lt;br /&gt;
  `token_state` int(10),&lt;br /&gt;
  PRIMARY KEY (`token_key`)&lt;br /&gt;
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+token&lt;br /&gt;
! token_key&lt;br /&gt;
! token_location&lt;br /&gt;
! token_state&lt;br /&gt;
|-&lt;br /&gt;
|meeple_red_1&lt;br /&gt;
|home_red&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
|dice_black_2&lt;br /&gt;
|board_guard&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
|dice_green_1&lt;br /&gt;
|board_action_mayor&lt;br /&gt;
|3&lt;br /&gt;
|-&lt;br /&gt;
|bread&lt;br /&gt;
|home_red&lt;br /&gt;
|5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Now how we represent resource counters such as bread?&lt;br /&gt;
Using same table from we simply add special counter token for bread and use state to indicate the count. Note to keep first column unique we have to add player identification for that counter, i.e. ff0000 is red player.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+token&lt;br /&gt;
! token_key&lt;br /&gt;
! token_location&lt;br /&gt;
! token_state&lt;br /&gt;
|-&lt;br /&gt;
|bread_ff0000&lt;br /&gt;
|tableau_ff0000&lt;br /&gt;
|5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See php module for this table here https://github.com/elaskavaia/bga-sharedcode/blob/master/modules/tokens.php&lt;br /&gt;
&lt;br /&gt;
Variant 2: Additional resource table, resource count for each player id&lt;br /&gt;
&lt;br /&gt;
 CREATE TABLE IF NOT EXISTS `resource` (&lt;br /&gt;
  `player_id` int(10) unsigned NOT NULL,&lt;br /&gt;
  `resource_key` varchar(32) NOT NULL,&lt;br /&gt;
  `resource_count` int(10) signed NOT NULL,&lt;br /&gt;
  PRIMARY KEY (`player_id`,`resource_key`)&lt;br /&gt;
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;&lt;br /&gt;
&lt;br /&gt;
 ALTER TABLE resource ADD CONSTRAINT fk_player_id FOREIGN KEY (player_id) REFERENCES player(player_id);&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+resource&lt;br /&gt;
! player_id&lt;br /&gt;
! resource_key&lt;br /&gt;
! resource_count&lt;br /&gt;
|-&lt;br /&gt;
|123456&lt;br /&gt;
|bread&lt;br /&gt;
|5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Variant 3: More normalised&lt;br /&gt;
&lt;br /&gt;
This version is similar to &amp;quot;card&amp;quot; table from hearts tutorial, you can also use exact cards database schema and Deck implementation for most purposes (even you not dealing with cards). &lt;br /&gt;
&lt;br /&gt;
 CREATE TABLE IF NOT EXISTS `token` (&lt;br /&gt;
  `token_id` int(10) unsigned NOT NULL AUTO_INCREMENT,&lt;br /&gt;
  `token_type` varchar(16) NOT NULL,&lt;br /&gt;
  `token_arg` int(11) NOT NULL,&lt;br /&gt;
  `token_location` varchar(32) NOT NULL,&lt;br /&gt;
  `token_state` int(10),&lt;br /&gt;
  PRIMARY KEY (`token_id`)&lt;br /&gt;
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+token&lt;br /&gt;
! token_id&lt;br /&gt;
! token_type&lt;br /&gt;
! token_arg&lt;br /&gt;
! token_location&lt;br /&gt;
! token_state&lt;br /&gt;
|-&lt;br /&gt;
|22&lt;br /&gt;
|meeple&lt;br /&gt;
|123456&lt;br /&gt;
|home_123456&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
|23&lt;br /&gt;
|dice&lt;br /&gt;
|2&lt;br /&gt;
|board_guard&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
|26&lt;br /&gt;
|dice&lt;br /&gt;
|1&lt;br /&gt;
|board_action_mayor&lt;br /&gt;
|3&lt;br /&gt;
|-&lt;br /&gt;
|49&lt;br /&gt;
|bread&lt;br /&gt;
|0&lt;br /&gt;
|home_123456&lt;br /&gt;
|5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Advantages of this would be is a bit more straightforward to do some queries in db, disadvantage its hard to read (as you can compare with previous example, you&lt;br /&gt;
cannot just look at say, ah I know what it means). Another questionable advantage is it allows you to do id randomisation, so it hard to do crafted queries to &lt;br /&gt;
cheat, the down side of that you cannot understand it either, and handcraft db states for debugging or testing.&lt;br /&gt;
&lt;br /&gt;
=== Database for The card game ===&lt;br /&gt;
&lt;br /&gt;
Lets say you have a standard card game, player have hidden cards in hand, you can draw card from draw deck, play card on tableau and discard to discard pile.&lt;br /&gt;
We have to design database for such game.&lt;br /&gt;
&lt;br /&gt;
In real word to &amp;quot;save&amp;quot; the game we take a picture a play area, save cards from it, then put away draw deck, discard and hand of each player separately and mark it, also we will record current scoring (if any) and who&#039;s turn was it.&lt;br /&gt;
&lt;br /&gt;
* Framework handles state machine transition, so you don&#039;t have to worry about database design for that (i.e. who&#039;s turn it is, what phase of the game we are at, you still have to design it but part of state machine step)&lt;br /&gt;
* Also framework supports basic player information, color, order around the table, basic scoring, etc, so you don&#039;t have to worry about it either&lt;br /&gt;
* The only thing you need in our database is state of the &amp;quot;board&amp;quot;, which is &amp;quot;where each pieces is, and in what state&amp;quot;, or (position,rotation) pair.&lt;br /&gt;
&lt;br /&gt;
Lets see what we have for that:&lt;br /&gt;
* The card state is very simple, its usually &amp;quot;face up/face down&amp;quot;, &amp;quot;tapped/untapped&amp;quot;, &amp;quot;right side up/up side down&amp;quot;&lt;br /&gt;
* As position go we never need real coordinates x,y,z. We need to know what &amp;quot;zone&amp;quot; card was, and depending on the zone it may sometimes need an extra &amp;quot;z&amp;quot; or &amp;quot;x&amp;quot; as card order. The zone position usually static or irrelevant.&lt;br /&gt;
* So our model is: we have cards, which have some attributes, at any given point in time they belong to a &amp;quot;zone&amp;quot;, and can also have order and state&lt;br /&gt;
* Now for mapping we should consider what information changes and what information is static, later is always candidate for material file&lt;br /&gt;
* For dynamic information we should try to reduce amount of fields we need&lt;br /&gt;
**  we need at least a field for card, so its one&lt;br /&gt;
**  we need to know what zone cards belong to, its 2&lt;br /&gt;
**  and we have possibly few other fields, if you look closely at you game you may find out that most of the zone only need one attribute at a time, i.e. draw pile always have cards face down, hand always face up, also for hand and discard order does not matter at all (but for draw it does matter). So in majority of cases we can get away with one single extra integer field representing state or order&lt;br /&gt;
* In real database both card and zone will be integers as primary keys referring to additional tables, but in our case its total overkill, so they can be strings as easily&lt;br /&gt;
&lt;br /&gt;
Variant 1: Minimalistic&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE TABLE IF NOT EXISTS `card` (&lt;br /&gt;
  `card_key` varchar(32) unsigned NOT NULL,&lt;br /&gt;
  `card_location` varchar(32) NOT NULL,&lt;br /&gt;
  `card_state` int(11) NOT NULL,&lt;br /&gt;
  PRIMARY KEY (`card_id`)&lt;br /&gt;
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Variant 2: More normalised&lt;br /&gt;
&lt;br /&gt;
This version supported by Deck php class, so unless you want to rewrite db access layer go with this one&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE TABLE IF NOT EXISTS `card` (&lt;br /&gt;
  `card_id` int(10) unsigned NOT NULL AUTO_INCREMENT,&lt;br /&gt;
  `card_type` varchar(16) NOT NULL,&lt;br /&gt;
  `card_type_arg` int(11) NOT NULL,&lt;br /&gt;
  `card_location` varchar(16) NOT NULL,&lt;br /&gt;
  `card_location_arg` int(11) NOT NULL,&lt;br /&gt;
  PRIMARY KEY (`card_id`)&lt;br /&gt;
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: if you using this schema, some zones/locations have special semantic. The &#039;hand&#039; location is actually multiple locations - one per player, but player id is encoded as card_location_arg. If &#039;hand&#039; in your game is ordered, visible or can have some other card states, you cannot use hand location (replacement is hand_&amp;lt;player_id&amp;gt; or hand_&amp;lt;color_id&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
== Code Organization ==&lt;br /&gt;
&lt;br /&gt;
=== Including your own JavaScript module ===&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, modules/ggg_other.js&lt;br /&gt;
&lt;br /&gt;
* Create ggg_other.js in modules/ folder and sync&lt;br /&gt;
* Modify ggg.js to include it&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  define([ &amp;quot;dojo&amp;quot;, &amp;quot;dojo/_base/declare&amp;quot;, &amp;quot;ebg/core/gamegui&amp;quot;, &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
    // load my own module!!!&lt;br /&gt;
    g_gamethemeurl + &amp;quot;modules/ggg_other.js&amp;quot; ], function(dojo,&lt;br /&gt;
        declare) {&lt;br /&gt;
&lt;br /&gt;
=== Including your own JavaScript module (II) ===&lt;br /&gt;
&lt;br /&gt;
* Create ggg_other.js in modules/ folder and sync&lt;br /&gt;
&lt;br /&gt;
  define([], function () {&lt;br /&gt;
    return &amp;quot;value&amp;quot;;&lt;br /&gt;
  });&lt;br /&gt;
&lt;br /&gt;
* Modify ggg.js to include it&lt;br /&gt;
&lt;br /&gt;
  define([ &lt;br /&gt;
    &amp;quot;dojo&amp;quot;, &lt;br /&gt;
    &amp;quot;dojo/_base/declare&amp;quot;, &lt;br /&gt;
    &amp;quot;bgagame/modules/ggg_other&amp;quot;, &lt;br /&gt;
    &amp;quot;ebg/core/gamegui&amp;quot;, &lt;br /&gt;
    &amp;quot;ebg/counter&amp;quot;&lt;br /&gt;
  ], function(dojo, declare, other) {&lt;br /&gt;
  &lt;br /&gt;
  });&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
This is maybe a little bit more the idea of the AMD Loader than the first option, although the first option should work as well.&lt;br /&gt;
&lt;br /&gt;
A little explanation to this:&lt;br /&gt;
The define function loads all the modules listed in the array and calls the following function with these loaded modules as parameters.&lt;br /&gt;
By putting your module at the third position in the array it is passed as the third parameter to the function. Be aware that the modules are resolved by position only, not by name. So you can load the module &#039;&#039;&#039;ggg_other&#039;&#039;&#039; and pass it as a parameter with the name &#039;&#039;&#039;other&#039;&#039;&#039;. &#039;&#039;&#039;gamegui&#039;&#039;&#039; and &#039;&#039;&#039;counter&#039;&#039;&#039; are passed in as well, but when the parameters are not defined they are just skipped. Because these modules put their content into the global scope it does not matter and you can use them from there.&lt;br /&gt;
&lt;br /&gt;
In the example above the string &amp;quot;value&amp;quot; is passed for the parameter &#039;&#039;&#039;other&#039;&#039;&#039;, but the function in your module can return whatever you want. It can be an object, an array, something you declared with dojo.declare, you can return even functions. &lt;br /&gt;
Your module can load other modules. Just put them in the array at the beginning and pass them as parameters to your function.&lt;br /&gt;
The advantage of passing the values as parameter is that you do not need to put these values in the global scope, so they can&#039;t be collisions with values defined in other scripts or the BGA Framework.&lt;br /&gt;
&lt;br /&gt;
The dojo toolkit provides good documentation to all of its components, the complete documentation for the AMD-Loader is here:&lt;br /&gt;
https://dojotoolkit.org/documentation/tutorials/1.10/modules/index.html It should be still correct, even as it seems to be only for version 1.10&lt;br /&gt;
&lt;br /&gt;
=== Including your own PHP module ===&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.game.php, modules/ggg_other.php&lt;br /&gt;
&lt;br /&gt;
* Create ggg_other.php in modules/ folder and sync&lt;br /&gt;
* Modify ggg.game.php to include it&lt;br /&gt;
&lt;br /&gt;
 require_once (&#039;modules/ggg_other.php&#039;);&lt;br /&gt;
&lt;br /&gt;
=== Creating a test class to run PHP locally ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.game.php, stubs&lt;br /&gt;
For this you need stubs of other method you can use this for example&lt;br /&gt;
https://github.com/elaskavaia/bga-sharedcode/raw/master/misc/module/table/table.game.php&lt;br /&gt;
&lt;br /&gt;
Create another php files, i.e ggg_test.php&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
define(&amp;quot;APP_GAMEMODULE_PATH&amp;quot;, &amp;quot;misc/&amp;quot;); // include path to stubs, which defines &amp;quot;table.game.php&amp;quot; and other classes&lt;br /&gt;
require_once (&#039;eminentdomaine.game.php&#039;);&lt;br /&gt;
&lt;br /&gt;
class MyGameTest1 extends MyGame { // this is your game class defined in ggg.game.php&lt;br /&gt;
    function __construct() {&lt;br /&gt;
        parent::__construct();&lt;br /&gt;
        include &#039;../material.inc.php&#039;;// this is how this normally included, from constructor&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // override/stub methods here that access db and stuff&lt;br /&gt;
    function getGameStateValue($var) {&lt;br /&gt;
        if ($var == &#039;round&#039;)&lt;br /&gt;
            return 3;&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
$x = new MyGameTest1(); // instantiate your class&lt;br /&gt;
$p = $x-&amp;gt;getGameProgression(); // call one of the methods to test&lt;br /&gt;
if ($p != 50)&lt;br /&gt;
    echo &amp;quot;Test1: FAILED&amp;quot;;&lt;br /&gt;
else&lt;br /&gt;
    echo &amp;quot;Test1: PASSED&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Run from command line like&lt;br /&gt;
 php7 ggg_test.php&lt;br /&gt;
&lt;br /&gt;
If you do it this way - you can also use local php debugger (i.e. integrated with IDE or command line).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Avoiding code in dojo declare style ===&lt;br /&gt;
Dojo class declarations are rather bizzare and do not work with most IDEs.&lt;br /&gt;
If you want to write in plain JS with classes, you can stub all the dojo define/declare stuff&lt;br /&gt;
and hook your class into that, so the classes are outside of this mess.&lt;br /&gt;
&lt;br /&gt;
NOTE: this technique is for experienced developers, do not try it if you do not understand&lt;br /&gt;
the consequences.&lt;br /&gt;
&lt;br /&gt;
This is complete example of game .js class&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  // Testla is game name is has to be changed&lt;br /&gt;
class Testla {&lt;br /&gt;
	constructor(game) {&lt;br /&gt;
		console.log(&#039;game constructor&#039;);&lt;br /&gt;
		this.game = game;&lt;br /&gt;
		this.varfoo = new MyFoo(); // this example of class from custom module&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	setup(gamedatas) {&lt;br /&gt;
		console.log(&amp;quot;Starting game setup&amp;quot;, this.varfoo);&lt;br /&gt;
		this.gamedatas = gamedatas;&lt;br /&gt;
		this.dojo.create(&amp;quot;div&amp;quot;, { class: &#039;whiteblock&#039;, innerHTML: _(&amp;quot;hello&amp;quot;) }, &#039;thething&#039;);&lt;br /&gt;
		console.log(&amp;quot;Ending game setup&amp;quot;);&lt;br /&gt;
	};&lt;br /&gt;
	onEnteringState(stateName, args) {&lt;br /&gt;
		console.log(&#039;onEnteringState : &#039; + stateName, args);&lt;br /&gt;
		this.game.addActionButton(&#039;b1&#039;,_(&#039;Click Me&#039;), (e)=&amp;gt;this.onButtonClick(e));&lt;br /&gt;
	};&lt;br /&gt;
	onLeavingState(stateName) {&lt;br /&gt;
		console.log(&#039;onLeavingState : &#039; + stateName, args);&lt;br /&gt;
	};&lt;br /&gt;
	onUpdateActionButtons(stateName, args) {&lt;br /&gt;
		console.log(&#039;onUpdateActionButtons : &#039; + stateName, args);&lt;br /&gt;
	};&lt;br /&gt;
	onButtonClick(event) {&lt;br /&gt;
		console.log(&#039;onButtonClick&#039;,event);&lt;br /&gt;
	};&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&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;
	g_gamethemeurl + &#039;/modules/foo.js&#039; // custom module if needed&lt;br /&gt;
],&lt;br /&gt;
	function(dojo, declare) {&lt;br /&gt;
                // testla is game name is has to be changed&lt;br /&gt;
		return declare(&amp;quot;bgagame.testla&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
			constructor: function() {&lt;br /&gt;
				this.xapp = new Testla(this);&lt;br /&gt;
				this.xapp.dojo = dojo;&lt;br /&gt;
			},&lt;br /&gt;
			setup: function(gamedatas) {&lt;br /&gt;
				this.xapp.setup(gamedatas);&lt;br /&gt;
			},&lt;br /&gt;
			onEnteringState: function(stateName, args) {&lt;br /&gt;
				this.xapp.onEnteringState(stateName, args.args);&lt;br /&gt;
			},&lt;br /&gt;
			onLeavingState: function(stateName) {&lt;br /&gt;
				this.xapp.onLeavingState(stateName, args);&lt;br /&gt;
			},&lt;br /&gt;
			onUpdateActionButtons: function(stateName, args) {&lt;br /&gt;
				this.xapp.onUpdateActionButtons(stateName, args);&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;
=== More readable JS: onEnteringState ===&lt;br /&gt;
&lt;br /&gt;
If you have a lot of states onEnteringState and friends become rather wild, you can do this trick to call some method dynamically.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
     onEnteringState: function(stateName, args) {&lt;br /&gt;
       console.log(&#039;Entering state: &#039; + stateName, args);&lt;br /&gt;
&lt;br /&gt;
       // Call appropriate method&lt;br /&gt;
       var methodName = &amp;quot;onEnteringState_&amp;quot; + stateName;&lt;br /&gt;
       if (this[methodName] !== undefined) {             &lt;br /&gt;
          console.log(&#039;Calling &#039; + methodName, args.args);&lt;br /&gt;
          this[methodName](args.args);&lt;br /&gt;
       }&lt;br /&gt;
     },&lt;br /&gt;
&lt;br /&gt;
     onEnteringState_playerTurn: function(args) { // this is args directly, not args.args &lt;br /&gt;
         // process&lt;br /&gt;
     },&lt;br /&gt;
&lt;br /&gt;
     onEnteringState_playerSomethingElse: function(args) { &lt;br /&gt;
         // process&lt;br /&gt;
     },&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: since its ignores the undefined functions you don&#039;t have define function for each state, but on the other hand you cannot make typos.&lt;br /&gt;
Same applies to onUpdateActionButtons except you pass &#039;args&#039; to method, not args.args, and for onLeavingState where you don&#039;t pass anything.&lt;br /&gt;
&lt;br /&gt;
=== Frameworks and Preprocessors ===&lt;br /&gt;
&lt;br /&gt;
* [[Using Vue]] - work-in-progress guide on using the modern framework Vue.js to create a game&lt;br /&gt;
* [[Using Typescript and Scss]] - How to auto-build Typescript and SCSS files to make your code cleaner&lt;br /&gt;
&lt;br /&gt;
== Assorted Stuff ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Out-of-turn actions: Un-pass ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, ggg.game.php, ggg.action.php, states.inc.php&lt;br /&gt;
&lt;br /&gt;
In multiplayer game sometimes players passes but than they think more and want to un-Pass and redo their choice. &lt;br /&gt;
To re-active a player who passes some trickery required.&lt;br /&gt;
&lt;br /&gt;
Define a special action that does that and hook it up.&lt;br /&gt;
&lt;br /&gt;
In states.inc.php add an action to mmultipleactiveplayer state to &amp;quot;unpass&amp;quot;, lets call it &amp;quot;actionCancel&amp;quot;&lt;br /&gt;
&lt;br /&gt;
In ggg.action.php add action hook&lt;br /&gt;
    public function actionCancel() {&lt;br /&gt;
        self::setAjaxMode();&lt;br /&gt;
        $this-&amp;gt;game-&amp;gt;actionCancel();&lt;br /&gt;
        self::ajaxResponse();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
In ggg.game.php add action handler&lt;br /&gt;
    function actionCancel() {&lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;checkPossibleAction(&#039;actionCancel&#039;);&lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;setPlayersMultiactive(array ($this-&amp;gt;getCurrentPlayerId() ), &#039;error&#039;, false);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
Finally to call this in client ggg.js you would do something like:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 onUpdateActionButtons:  function(stateName, args) {&lt;br /&gt;
   if (this.isCurrentPlayerActive()) { &lt;br /&gt;
     // ...&lt;br /&gt;
   } else if (!this.isSpectator) { // player is NOT active but not spectator&lt;br /&gt;
       switch (stateName) {&lt;br /&gt;
          case &#039;playerTurnMuliPlayerState&#039;:&lt;br /&gt;
		this.addActionButton(&#039;button_unpass&#039;, _(&#039;Oh no!&#039;), &#039;onUnpass&#039;);&lt;br /&gt;
		break;&lt;br /&gt;
	}&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
				&lt;br /&gt;
 onUnpass: function(e) {&lt;br /&gt;
    this.ajaxcall(&amp;quot;/&amp;quot; + this.game_name + &amp;quot;/&amp;quot; +  this.game_name + &amp;quot;/actionCancel.html&amp;quot;, {}, this); // no checkAction!&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Although be careful that if the turn comes back to the player while he is about to click cancel, the action buttons will be updated and the player will misclick which can be quite frustrating. To avoid this, move the cancel button to another position, like to the left of pagemaintitletext:&lt;br /&gt;
  dojo.place(&#039;button_unpass&#039;, &#039;pagemaintitletext&#039;, &#039;before&#039;);&lt;br /&gt;
Being out of the generalactions div, it won&#039;t be automatically destroyed like normal buttons, so you&#039;ll have to handle that yourself in onLeavingState. You might also want to change the button color to red (blue buttons for active player only, red buttons also for inactive players?)&lt;br /&gt;
&lt;br /&gt;
Note: same technique can be used to do other out-of-turn actions, such as re-arranging cards in hand, exchanging resources, etc (i.e. if permitted by rules, such as &amp;quot;at any time player can...&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
=== Multi Step Interactions: Select Worker/Place Worker - Using Selection ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
Simple way to implement something like that without extra states is to use &amp;quot;selection&amp;quot; mechanism. When user click on worker add some sort of class into that element i.e. &#039;selected&#039; (which also have to have some indication by css i.e. outline).&lt;br /&gt;
&lt;br /&gt;
Than user can click on placement zone, you can use dojo.query for &amp;quot;selected&amp;quot; element and use it along with zone id to send data to server. If proper worker is not selected yet can give a error message using this.showMessage(...) function.&lt;br /&gt;
&lt;br /&gt;
Extra code required to properly cleanup selection between states.&lt;br /&gt;
Also when you do that sometimes you want to change the state prompt, see below &#039;Change state prompt&#039;&lt;br /&gt;
&lt;br /&gt;
=== Multi Step Interactions: Select Worker/Place Worker - Using Client States ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
I don&#039;t think its documented feature but there is a way to do client-only states, which is absolutely wonderful for few reasons&lt;br /&gt;
* When player interaction is two step process, such as select worker, place worker, or place worker, pick one of two resources of your choice&lt;br /&gt;
* When multi-step process can result of impossible situation and has to be undone (by rules)&lt;br /&gt;
* When multi-step process is triggered from multiple states (such as you can do same thing as activated card action, pass action or main action)&lt;br /&gt;
&lt;br /&gt;
So lets do Select Worker/Place Worker&lt;br /&gt;
&lt;br /&gt;
Define your server state as usual, i.e. playerMainTurn -&amp;gt; &amp;quot;You must pick up a worker&amp;quot;.&lt;br /&gt;
Now define a client state, we only need &amp;quot;name&amp;quot; and &amp;quot;descriptionmyturn&amp;quot;, lets say &amp;quot;client_playerPicksLocation&amp;quot;. Always prefix names of client state with &amp;quot;client_&amp;quot; to avoid confusion. Now we have to do the following:&lt;br /&gt;
* Have a handler for onUpdateActionButtons for playerMainTurn to activate all possible workers he can pick&lt;br /&gt;
* When player clicks workers, remember the worker in one of the members of the main class, I usually use one called this.clientStateArgs.&lt;br /&gt;
* Transition to new client state&lt;br /&gt;
  onWorker: function(e) {&lt;br /&gt;
      var id = event.currentTarget.id;&lt;br /&gt;
      dojo.stopEvent(event);&lt;br /&gt;
      ... // do validity checks&lt;br /&gt;
      this.clientStateArgs.worker_id = id;&lt;br /&gt;
      this.setClientState(&amp;quot;client_playerPicksLocation&amp;quot;, {&lt;br /&gt;
                                descriptionmyturn : _(&amp;quot;${you} must select location&amp;quot;),&lt;br /&gt;
                            });&lt;br /&gt;
   }&lt;br /&gt;
* Have a handler for onUpdateActionButtons for client_playerPicksLocation to activate all possible locations this worker can go AND add Cancel button (see below)&lt;br /&gt;
* Have a location handler which will eventually send a server request, using stored this.clientStateArgs.worker_id as worker id&lt;br /&gt;
* The cancel button should call a method to restore server state, also if you doing it for more than one state you can add this universally using this.on_client_state check&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        if (this.isCurrentPlayerActive()) {&lt;br /&gt;
          if (this.on_client_state &amp;amp;&amp;amp; !$(&#039;button_cancel&#039;)) {&lt;br /&gt;
               this.addActionButton(&#039;button_cancel&#039;, _(&#039;Cancel&#039;), dojo.hitch(this, function() {&lt;br /&gt;
                                             this.restoreServerGameState();&lt;br /&gt;
               }));&lt;br /&gt;
          }&lt;br /&gt;
        } &lt;br /&gt;
Note: usually I call my own function call this.cancelLocalStateEffects() which will do more stuff first then call restoreServerGameState(), same function is usually needs to be called when server request has failed (i.e. invalid move)&lt;br /&gt;
&lt;br /&gt;
Note: If you need more than 2 steps, you may have to do client side animation to reflect the new state, which gets trickier because you have to undo that also on cancellation.&lt;br /&gt;
&lt;br /&gt;
Code is available here [https://github.com/elaskavaia/bga-sharedcode/blob/master/sharedcode.js sharedcode.js] (its using playerTurnPlayCubes and client_selectCubeLocation).&lt;br /&gt;
&lt;br /&gt;
=== Action Stack - Using Client States ===&lt;br /&gt;
&lt;br /&gt;
Action stack required where game is very complex and use triggered effects that can &amp;quot;stack&amp;quot;. It not always actual stack, it can be queue or random access&lt;br /&gt;
Examples:&lt;br /&gt;
* Magic the Gathering - classic card game where effects go on Stack, that allows to counter spell and counter spell of counter spell (not on bga - it just example of mechanics)&lt;br /&gt;
* Ultimate Railroads - action taking game where effects can be executed in any order&lt;br /&gt;
* Lewis and Clark - card game where actions executed as queue&lt;br /&gt;
&lt;br /&gt;
There is two ways of implementing it - on the server or the client.&lt;br /&gt;
For the server see article below.&lt;br /&gt;
The requirement for client side stack is all action can be undone, which means&lt;br /&gt;
* No dice rolls&lt;br /&gt;
* No card drawn&lt;br /&gt;
* No other players interaction&lt;br /&gt;
&lt;br /&gt;
No snippets are here, as this will be too complex but basically flow is:&lt;br /&gt;
* You have a action/effect stack (queue/list) as js object attached to &amp;quot;this&amp;quot;, i.e. this.unprocessed_actions&lt;br /&gt;
* When player plays a card, worker, etc, you read the effect of that card from the material file (client copy), and place into stack&lt;br /&gt;
* Then we call dispatch method which pulls the next action from the stack and change client state accordinly,i.e.  this.setClientState(&amp;quot;client_playerGainsCubes&amp;quot;)&lt;br /&gt;
* When players acts on it - the action is removed from the stack and added to &amp;quot;server action arguments&amp;quot; list, this is another object which be used to send ajax call, i.e. this.clientStateArgs&lt;br /&gt;
* If nothing left in stack we can submit the ajax call assembling parameters from collected arguments (that can include action name)&lt;br /&gt;
* This method allows cheap undo - by restoring server state you will wipe out all user actions (but if you need intermediate aninmation you have to handle it yourself)&lt;br /&gt;
&lt;br /&gt;
Code can be found in Ultimate Railroads game (but it is random access list - so it a bit complex) and Lewis and Clark (complexity - use can always deny part of any effect)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Action Stack - Using Server States ===&lt;br /&gt;
&lt;br /&gt;
See definition of Action Stack above.&lt;br /&gt;
&lt;br /&gt;
To implement you usually need another db table that has the following fields: index of effect - which is used for sorted access, type - which is essense of the effect (i.e. collect resource), some extra arguments (i.e. resource type and resource count), and usually owner of the effect (i.e. player id)&lt;br /&gt;
The flow is:&lt;br /&gt;
* There is some initial player state, where player can play card for example&lt;br /&gt;
* Player main action - pushes the card effect on stack, which also can cause triggered effects which also go on stack&lt;br /&gt;
* After action processing is finished switch to game state which is &amp;quot;dispatcher&amp;quot;&lt;br /&gt;
* Gispatcher pulls the top effect (whatever definition of the top is), changes the active player and changes the state to appropriate player state to collect response&lt;br /&gt;
* Player state knows about the stack and pulls arguments (argX) from the effect arguments of the db&lt;br /&gt;
* Player action should clear up the top effect, and can possibly add more effects, then switch to &amp;quot;dispatcher&amp;quot; state again&lt;br /&gt;
* If stack is empty, dispatcher can either pick next player itself or use another game state which responsible for picking next player&lt;br /&gt;
&lt;br /&gt;
Code can be found in Tapestry.&lt;br /&gt;
&lt;br /&gt;
=== Changing state prompt ===&lt;br /&gt;
&lt;br /&gt;
State prompt is message displayed for player which usually comes from state description.&lt;br /&gt;
Sometimes you want to change it without changing state (one way is change state but locally, see client states above).&lt;br /&gt;
&lt;br /&gt;
Simple way just change the html&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        setMainTitle: function(text) {&lt;br /&gt;
            $(&#039;pagemaintitletext&#039;).innerHTML = text;&lt;br /&gt;
        },&lt;br /&gt;
         // usage&lt;br /&gt;
        onMeeple: function(event) {&lt;br /&gt;
              //... &lt;br /&gt;
              this.setMainTitle(_(&#039;You must select where meeple is going&#039;));&lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This however will not work with parameters and will not draw You in color, if you want this its more sophisticated:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        setDescriptionOnMyTurn : function(text) {&lt;br /&gt;
            this.gamedatas.gamestate.descriptionmyturn = text;&lt;br /&gt;
            var tpl = dojo.clone(this.gamedatas.gamestate.args);&lt;br /&gt;
            if (tpl === null) {&lt;br /&gt;
                tpl = {};&lt;br /&gt;
            }&lt;br /&gt;
            var title = &amp;quot;&amp;quot;;&lt;br /&gt;
            if (this.isCurrentPlayerActive() &amp;amp;&amp;amp; text !== null) {&lt;br /&gt;
                tpl.you = this.divYou(); &lt;br /&gt;
            }&lt;br /&gt;
            title = this.format_string_recursive(text, tpl);&lt;br /&gt;
&lt;br /&gt;
            if (!title) {&lt;br /&gt;
                this.setMainTitle(&amp;quot;&amp;amp;nbsp;&amp;quot;);&lt;br /&gt;
            } else {&lt;br /&gt;
                this.setMainTitle(title);&lt;br /&gt;
            }&lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: this method uses &#039;&#039;&#039;setMainTitle&#039;&#039;&#039; defined above and &#039;&#039;&#039;divYou&#039;&#039;&#039; defined in another section of this wiki.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Adding Image buttons ===&lt;br /&gt;
&lt;br /&gt;
Its pretty trivial but just in case you need a working function:&lt;br /&gt;
&lt;br /&gt;
ggg.js:&lt;br /&gt;
&lt;br /&gt;
                addImageActionButton: function (id, div_html, handler) { // div_html is string not node&lt;br /&gt;
                    this.addActionButton(id, div_html, handler, &#039;&#039;, false, &#039;gray&#039;); &lt;br /&gt;
                    dojo.style(id, &amp;quot;border&amp;quot;, &amp;quot;none&amp;quot;); // remove ugly border&lt;br /&gt;
                    dojo.addClass(id, &amp;quot;bgaimagebutton&amp;quot;); // add css class to do more styling&lt;br /&gt;
                    return $(id); // return node for chaining&lt;br /&gt;
                },&lt;br /&gt;
&lt;br /&gt;
Example of usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    this.addImageActionButton(&#039;button_coin&#039;,&amp;quot;&amp;lt;div class=&#039;coin&#039;&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;, ()=&amp;gt;{ alert(&#039;Ha!&#039;); });&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Assigning Player Order ===&lt;br /&gt;
Normally when game starts there is &amp;quot;natural&amp;quot; player order assigned randomly.&lt;br /&gt;
&lt;br /&gt;
If you want to deliberatly assign player order at the start of the game (for example, in a game with teams options), you can do so by retrieving the initialization-only player attribute &#039;&#039;&#039;player_table_order&#039;&#039;&#039; and using it to assign values to &#039;&#039;&#039;player_no&#039;&#039;&#039; (which is normally assigned at the start of a game in the order in which players come to the table). (See [https://en.doc.boardgamearena.com/Game_database_model:_dbmodel.sql#The_player_table Game database model] for more details.)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Example:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                // Retrieve inital player order ([0=&amp;gt;playerId1, 1=&amp;gt;playerId2, ...])&lt;br /&gt;
		$playerInitialOrder = [];&lt;br /&gt;
		foreach ($players as $playerId =&amp;gt; $player) {&lt;br /&gt;
			$playerInitialOrder[$player[&#039;player_table_order&#039;]] = $playerId;&lt;br /&gt;
		}&lt;br /&gt;
		ksort($playerInitialOrder);&lt;br /&gt;
		$playerInitialOrder = array_flip(array_values($playerInitialOrder));&lt;br /&gt;
&lt;br /&gt;
		// Player order based on &#039;playerTeams&#039; option&lt;br /&gt;
		$playerOrder = [0, 1, 2, 3];&lt;br /&gt;
		switch (self::getGameStateValue(&#039;playerTeams&#039;)) {&lt;br /&gt;
			case self::TEAM_1_2:&lt;br /&gt;
				$playerOrder = [0, 2, 1, 3];&lt;br /&gt;
				break;&lt;br /&gt;
			case self::TEAM_1_4:&lt;br /&gt;
				$playerOrder = [0, 1, 3, 2];&lt;br /&gt;
				break;&lt;br /&gt;
			case self::TEAM_RANDOM:&lt;br /&gt;
				shuffle($playerOrder);&lt;br /&gt;
				break;&lt;br /&gt;
			default:&lt;br /&gt;
			case self::TEAM_1_3:&lt;br /&gt;
				// Default order&lt;br /&gt;
				break;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
                // Create players&lt;br /&gt;
		// Note: if you added some extra field on &amp;quot;player&amp;quot; table in the database (dbmodel.sql), you can initialize it there.&lt;br /&gt;
		$sql =&lt;br /&gt;
			&#039;INSERT INTO player (player_id, player_color, player_canal, player_name, player_avatar, player_no) VALUES &#039;;&lt;br /&gt;
		$values = [];&lt;br /&gt;
&lt;br /&gt;
		foreach ($players as $playerId =&amp;gt; $player) {&lt;br /&gt;
			$color = array_shift($default_colors);&lt;br /&gt;
			$values[] =&lt;br /&gt;
				&amp;quot;(&#039;&amp;quot; .&lt;br /&gt;
				$playerId .&lt;br /&gt;
				&amp;quot;&#039;,&#039;$color&#039;,&#039;&amp;quot; .&lt;br /&gt;
				$player[&#039;player_canal&#039;] .&lt;br /&gt;
				&amp;quot;&#039;,&#039;&amp;quot; .&lt;br /&gt;
				addslashes($player[&#039;player_name&#039;]) .&lt;br /&gt;
				&amp;quot;&#039;,&#039;&amp;quot; .&lt;br /&gt;
				addslashes($player[&#039;player_avatar&#039;]) .&lt;br /&gt;
				&amp;quot;&#039;,&#039;&amp;quot; .&lt;br /&gt;
				$playerOrder[$playerInitialOrder[$playerId]] .&lt;br /&gt;
				&amp;quot;&#039;)&amp;quot;;&lt;br /&gt;
		}&lt;br /&gt;
		$sql .= implode(&#039;,&#039;, $values);&lt;br /&gt;
		self::DbQuery($sql);&lt;br /&gt;
		self::reattributeColorsBasedOnPreferences(&lt;br /&gt;
			$players,&lt;br /&gt;
			$gameinfos[&#039;player_colors&#039;]&lt;br /&gt;
		);&lt;br /&gt;
		self::reloadPlayersBasicInfos();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Send different notifications to active player vs everybody else ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
Hack alert. This is a hack. We were hoping for proper solution by bga framework.&lt;br /&gt;
&lt;br /&gt;
This will allow you to send notification with two message one for specific player and one for everybody else including spectators.&lt;br /&gt;
Note that this does not split the data - all data must be shared.&lt;br /&gt;
&lt;br /&gt;
Add this to .js file (if you already overriding it merge obviously)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/** @Override */&lt;br /&gt;
format_string_recursive: function(log, args) {&lt;br /&gt;
   if (typeof args.log_others != &#039;undefined&#039; &amp;amp;&amp;amp; typeof args.player_id != &#039;undefined&#039; &amp;amp;&amp;amp; this.player_id != args.player_id)&lt;br /&gt;
	log = args.log_others;&lt;br /&gt;
   return this.inherited(arguments); // you must call this to call super &lt;br /&gt;
},&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example of usage (from eminentdomain)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    $this-&amp;gt;notifyAllPlayers(&#039;tokenMoved&#039;, &lt;br /&gt;
             clienttranslate(&#039;${player_name} adds +2 Colonies to ${place_name}&#039;), // notification with show for player with player_id&lt;br /&gt;
             [&#039;player_id&#039;=&amp;gt;$player_id, // this is mandatory&lt;br /&gt;
             &#039;log_others&#039;=&amp;gt;clienttranslate(&#039;${player_name} adds +2 Colonies to an unknown planet&#039;), // notification will show for others&lt;br /&gt;
              ...&lt;br /&gt;
             ]);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Send transient notifications without incrementing move ID ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.php&lt;br /&gt;
&lt;br /&gt;
Hack alert. This is a hack.&lt;br /&gt;
&lt;br /&gt;
Use this if you need to send some transient notification that should not create a new move ID. The notification should be idempotent -- it should have no practical effect on the game state and would be &#039;&#039;&#039;safe to drop&#039;&#039;&#039; (e.g., it would not matter if a player never received this notification). For example, in a co-op game you want all players to see a real-time preview of some action, before the active player commits their turn.&lt;br /&gt;
&lt;br /&gt;
Doing this mainly affects the instant replay &amp;amp; archive modes. During replay, the BGA framework automatically inserts a 1.5-second pause between each &amp;quot;move&amp;quot;. With this hack, your transient notifications are not considered to be a &amp;quot;move&amp;quot;, so no pause gets added.&lt;br /&gt;
&lt;br /&gt;
; In ggg.php&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$this-&amp;gt;not_a_move_notification = true; // note: do not increase the move counter&lt;br /&gt;
$this-&amp;gt;notifyAllPlayers(&#039;cardsPreview&#039;, &#039;&#039;, $args);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: you cannot have code that send notification or even changes state after this, and you cannot reset this variable back either because it only takes effect when you exit action handling function&lt;br /&gt;
&lt;br /&gt;
=== Ajax Call wrapper ===&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
The current ajaxcall is super vebose and prone to errors, I suggest using a helper function. It does a lot of stuff you must do anyways.&lt;br /&gt;
Most beginner mistakes come from missing part of this code (which is understandstandable - this is a huge snippet to clone every time).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	ajaxcallwrapper: function(action, args, handler) {&lt;br /&gt;
		if (!args) args = []; // this allows to skip args parameter for action which do not require them&lt;br /&gt;
			&lt;br /&gt;
		args.lock = true; // this allows to avoid rapid action clicking which can cause race condition on server&lt;br /&gt;
		if (this.checkAction(action)) { // this does all the proper check that player is active and action is declared&lt;br /&gt;
			this.ajaxcall(&amp;quot;/&amp;quot; + this.game_name + &amp;quot;/&amp;quot; + this.game_name + &amp;quot;/&amp;quot; + action + &amp;quot;.html&amp;quot;, args, // this is mandatory fluff &lt;br /&gt;
				this, (result) =&amp;gt; { },  // success result handler is empty - it is never needed&lt;br /&gt;
                                               handler); // this is real result handler - it called both on success and error, it has optional param  &amp;quot;is_error&amp;quot; - you rarely need it&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   this.ajaxcallwrapper(&#039;pass&#039;); // no args&lt;br /&gt;
   this.ajaxcallwrapper(&#039;playCard&#039;, {card: card_id}); // with args&lt;br /&gt;
   this.ajaxcallwrapper(&#039;playCard&#039;, {card: card_id}, (is_error)=&amp;gt;{if (!is_error) dojo.query(&amp;quot;.selected&amp;quot;).removeClass(&#039;selected&#039;);}) // with handler that cleans up &#039;selected&#039; class on success&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: this always will lock interface and always check for action, you can modify this method to do it optionally, i.e&lt;br /&gt;
  if (args.lock!==false) args.lock = true; else delete args.lock; // it does not work with false value - it has to be removed&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Studio]]&lt;/div&gt;</summary>
		<author><name>SwHawk</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=BGA_Studio_Cookbook&amp;diff=14215</id>
		<title>BGA Studio Cookbook</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=BGA_Studio_Cookbook&amp;diff=14215"/>
		<updated>2022-07-31T21:07:03Z</updated>

		<summary type="html">&lt;p&gt;SwHawk: /* Second way: rely on the :formatFunction option provided by dojo.string.substitute */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
This page is collection of design and implementation recipes for BGA Studio framework.&lt;br /&gt;
For tooling and usage recipes see [[Tools and tips of BGA Studio]].&lt;br /&gt;
If you have your own recipes feel free to edit this page.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Visual Effects, Layout and Animation ==&lt;br /&gt;
&lt;br /&gt;
=== DOM manipulatons ===&lt;br /&gt;
&lt;br /&gt;
==== Create pieces dynamically (using template) ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg_ggg.tpl, ggg.js&lt;br /&gt;
&lt;br /&gt;
Note: this method is recommended by BGA guildlines&lt;br /&gt;
&lt;br /&gt;
Declared js template with variables in .tpl file, like this&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;
    // Javascript HTML templates&lt;br /&gt;
    var jstpl_ipiece = &#039;&amp;lt;div class=&amp;quot;${type} ${type}_${color} inlineblock&amp;quot; aria-label=&amp;quot;${name}&amp;quot; title=&amp;quot;${name}&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use it like this in .js file&lt;br /&gt;
  div = this.format_block(&#039;jstpl_ipiece&#039;, {&lt;br /&gt;
                                type : &#039;meeple&#039;,&lt;br /&gt;
                                color : &#039;ff0000&#039;,&lt;br /&gt;
                                name : &#039;Bob&#039;,&lt;br /&gt;
                            });&lt;br /&gt;
  &lt;br /&gt;
Then you do whatever you need to do with that div, this one specifically design to go to log entries, because it has embedded title (otherwise its a picture only) and no id.&lt;br /&gt;
&lt;br /&gt;
Note: you could have place this variable in js itself, but keeping it in .tpl allows you to have your js code be free of HTML. Normally it never happens but&lt;br /&gt;
it is good to strive for it.&lt;br /&gt;
Note: you can also use string concatenation, its less readable. You can also use dojo dom object creation api&#039;s but its brutally verbose and its more unreadable.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Create pieces dynamically (using string concatenation) ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
Note: Not recommended&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  div = &amp;quot;&amp;lt;div class=&#039;meeple &amp;quot;+color+&amp;quot;&#039;&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
==== Create all pieces statically ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg_ggg.tpl, ggg.css, ggg.view.php (optional) &lt;br /&gt;
&lt;br /&gt;
* Create ALL game pieces in html template (.tpl)&lt;br /&gt;
* ALL pieces should have unique id, and it should be meaningful, i.e. meeple_red_1&lt;br /&gt;
* Do not use inline styling&lt;br /&gt;
* Id of player&#039;s specific pieces should use some sort of &#039;color&#039; identification, since player id cannot be used in static layout, you can use english color name, hex 6 char value, or color &amp;quot;number&amp;quot; (1,2,3...)&lt;br /&gt;
* Pieces should have separated class for its color, type, etc, so it can be easily styled in groups. In example below you now can style all meeples, all red meeples or all red tokens, or all &amp;quot;first&amp;quot; meeples&lt;br /&gt;
&lt;br /&gt;
ggg.tpl:&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
  &amp;lt;div id=&amp;quot;home_red&amp;quot; class=&amp;quot;home_red home&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;div id=&amp;quot;meeple_red_1&amp;quot; class=&amp;quot;meeple red n1&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
     &amp;lt;div id=&amp;quot;meeple_red_2&amp;quot; class=&amp;quot;meeple red n2&amp;quot;&amp;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;
ggg.css:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.meeple {&lt;br /&gt;
	width: 32px;&lt;br /&gt;
	height: 39px;&lt;br /&gt;
	background-image: url(img/78_64_stand_meeples.png);&lt;br /&gt;
	background-size: 352px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.meeple.red {&lt;br /&gt;
	background-position: 30% 0%;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* There should be straight forward mapping between server id and js id (or 1:1)&lt;br /&gt;
* You place objects in different zones of the layout, and setup css to take care of layout&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.home .meeple{&lt;br /&gt;
   display: inline-block;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* If you need to have a temporary object that look like original you can use dojo.clone (and change id to some temp id)&lt;br /&gt;
* If there is lots of repetition or zone grid you can use template generator, but inject style declaration in css instead of inline style for flexibility&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
* If you use this model you cannot use premade js components such as Stock and Zone&lt;br /&gt;
* You have to use alternative methods of animation (slightly altered) since default method will leave object with inline style attributes which you don&#039;t need&lt;br /&gt;
&lt;br /&gt;
=== Logs ===&lt;br /&gt;
&lt;br /&gt;
==== Inject icon images in the log ====&lt;br /&gt;
&lt;br /&gt;
Here is an example of what was done for Terra Mystica which is simple and straightforward:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
//Define the proper message&lt;br /&gt;
		$message = clienttranslate(&#039;${player_name} gets ${power_income} via Structures&#039;);&lt;br /&gt;
		if ($price &amp;gt; 0) {&lt;br /&gt;
			self::DbQuery(&amp;quot;UPDATE player SET player_score = player_score - $price WHERE player_id = $player_id&amp;quot;);&lt;br /&gt;
			$message = clienttranslate(&#039;${player_name} pays ${vp_price} and gets ${power_income} via Structures&#039;);&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
// Notify&lt;br /&gt;
		self::notifyAllPlayers( &amp;quot;powerViaStructures&amp;quot;, $message, array(&lt;br /&gt;
			&#039;i18n&#039; =&amp;gt; array( ),&lt;br /&gt;
			&#039;player_id&#039; =&amp;gt; $player_id,&lt;br /&gt;
			&#039;player_name&#039; =&amp;gt; self::getUniqueValueFromDb( &amp;quot;SELECT player_name FROM player WHERE player_id = $player_id&amp;quot; ),&lt;br /&gt;
			&#039;power_tokens&#039; =&amp;gt; $power_tokens,&lt;br /&gt;
			&#039;vp_price&#039; =&amp;gt; self::getLogsVPAmount($price),&lt;br /&gt;
			&#039;power_income&#039; =&amp;gt; self::getLogsPowerAmount($power_income),&lt;br /&gt;
			&#039;newScore&#039; =&amp;gt; self::getUniqueValueFromDb( &amp;quot;SELECT player_score FROM player WHERE player_id = $player_id&amp;quot; ),&lt;br /&gt;
			&#039;counters&#039; =&amp;gt; $this-&amp;gt;getGameCounters(null),&lt;br /&gt;
		) );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With some functions to have the needed html added inside the substitution variable, such as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function getLogsPowerAmount( $amount ) {&lt;br /&gt;
		return &amp;quot;&amp;lt;div class=&#039;tmlogs_icon&#039; title=&#039;Power&#039;&amp;gt;&amp;lt;div class=&#039;power_amount&#039;&amp;gt;$amount&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: injecting html from php is not ideal but easy, if you want more clean solution, use method below but it is a lot more sophisticated.&lt;br /&gt;
&lt;br /&gt;
==== Inject images and styled html in the log ====&lt;br /&gt;
&lt;br /&gt;
So you want nice pictures in the game log. What do you do? The first idea that comes to mind is to send html from php in notifications (see method above). &lt;br /&gt;
&lt;br /&gt;
This is a bad idea for many reasons:&lt;br /&gt;
&lt;br /&gt;
* It&#039;s bad architecture. ui elements leak into the server, and now you have to manage the ui in multiple places.&lt;br /&gt;
* If you decided to change something in the ui in future version, replay logs for old games and tutorials may not work, since they use stored notifications.&lt;br /&gt;
* Log previews for old games become unreadable. (This is the log state before you enter the game replay, which is useful for troubleshooting and game analysis.)&lt;br /&gt;
* It&#039;s more data to transfer and store in the db.&lt;br /&gt;
* It&#039;s a nightmare for translators.&lt;br /&gt;
&lt;br /&gt;
So what else can you do? You can use client side log injection to intercept log arguments (which come from the server) and replace them with html on the client side. Here are three different method you can use to achieve this.&lt;br /&gt;
&lt;br /&gt;
===== First way : Override &amp;lt;code&amp;gt;this.format_string_recursive()&amp;lt;/code&amp;gt; method =====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, ggg.game.php&lt;br /&gt;
&lt;br /&gt;
I use this recipe for &#039;&#039;&#039;client side log injection&#039;&#039;&#039; to intercept log arguments (which come from the server) and replace them with html on the client side.&lt;br /&gt;
&lt;br /&gt;
[[File:clientloginjection.png|left]] &lt;br /&gt;
&lt;br /&gt;
ggg.js&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
        /** Override this function to inject html into log items. This is a built-in BGA method.  */&lt;br /&gt;
&lt;br /&gt;
        /* @Override */&lt;br /&gt;
        format_string_recursive : function format_string_recursive(log, args) {&lt;br /&gt;
            try {&lt;br /&gt;
                if (log &amp;amp;&amp;amp; args &amp;amp;&amp;amp; !args.processed) {&lt;br /&gt;
                    args.processed = true;&lt;br /&gt;
                    &lt;br /&gt;
&lt;br /&gt;
                    // list of special keys we want to replace with images&lt;br /&gt;
                    var keys = [&#039;place_name&#039;,&#039;token_name&#039;];&lt;br /&gt;
                    &lt;br /&gt;
                  &lt;br /&gt;
                    for ( var i in keys) {&lt;br /&gt;
                        var key = keys[i];&lt;br /&gt;
                        key in args &amp;amp;&amp;amp; args[key] = this.getTokenDiv(key, args);                            &lt;br /&gt;
&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            } catch (e) {&lt;br /&gt;
                console.error(log,args,&amp;quot;Exception thrown&amp;quot;, e.stack);&lt;br /&gt;
            }&lt;br /&gt;
            return this.inherited({callee: format_string_recursive}, arguments);&lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important:&#039;&#039;&#039; In the &#039;&#039;format_string_recursive&#039;&#039; method, the &#039;args&#039; parameter will only contain arguments passed to it from the notify method in ggg.game.php (see below).&lt;br /&gt;
&lt;br /&gt;
The &#039;log&#039; parameter is the actual string that is inserted into the logs. You can perform additional js string manipulation on it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        getTokenDiv : function(key, args) {&lt;br /&gt;
            // ... implement whatever html you want here, example from sharedcode.js&lt;br /&gt;
            var token_id = args[key];&lt;br /&gt;
            var item_type = getPart(token_id,0);&lt;br /&gt;
            var logid = &amp;quot;log&amp;quot; + (this.globalid++) + &amp;quot;_&amp;quot; + token_id;&lt;br /&gt;
            switch (item_type) {&lt;br /&gt;
                case &#039;wcube&#039;:&lt;br /&gt;
                    var tokenDiv = this.format_block(&#039;jstpl_resource_log&#039;, {&lt;br /&gt;
                        &amp;quot;id&amp;quot; : logid,&lt;br /&gt;
                        &amp;quot;type&amp;quot; : &amp;quot;wcube&amp;quot;,&lt;br /&gt;
                        &amp;quot;color&amp;quot; : getPart(token_id,1),&lt;br /&gt;
                    });&lt;br /&gt;
                    return tokenDiv;&lt;br /&gt;
             &lt;br /&gt;
                case &#039;meeple&#039;:&lt;br /&gt;
                    if ($(token_id)) {&lt;br /&gt;
                        var clone = dojo.clone($(token_id));&lt;br /&gt;
    &lt;br /&gt;
                        dojo.attr(clone, &amp;quot;id&amp;quot;, logid);&lt;br /&gt;
                        this.stripPosition(clone);&lt;br /&gt;
                        dojo.addClass(clone, &amp;quot;logitem&amp;quot;);&lt;br /&gt;
                        return clone.outerHTML;&lt;br /&gt;
                    }&lt;br /&gt;
                    break;&lt;br /&gt;
     &lt;br /&gt;
                default:&lt;br /&gt;
                    break;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            return &amp;quot;&#039;&amp;quot; + this.clienttranslate_string(this.getTokenName(token_id)) + &amp;quot;&#039;&amp;quot;;&lt;br /&gt;
       },&lt;br /&gt;
       getTokenName : function(key) {&lt;br /&gt;
           return this.gamedatas.token_types[key].name; // get name for the key, from static table for example&lt;br /&gt;
       },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that in this case the server simply injects token_id as a name, and the client substitutes it for the translated name or the picture.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ggg.game.php:&lt;br /&gt;
&lt;br /&gt;
           $this-&amp;gt;notifyAllPlayers(&#039;playerLog&#039;,clienttranslate(&#039;Game moves ${token_name}&#039;),[&#039;token_name&#039;=&amp;gt;$token_id]);&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important:&#039;&#039;&#039; As noted above, only arguments actually passed by this method are available to the args parameter received in the client-side &#039;&#039;format_string_recursive&#039;&#039; method.&lt;br /&gt;
&lt;br /&gt;
Sometimes it is the case that you want to pass arguments that are not actually included in the output message. For example, suppose we have a method like this:&lt;br /&gt;
&lt;br /&gt;
           $this-&amp;gt;notifyAllPlayers(&#039;tokenPlaced&#039;,clienttranslate(&#039;Player placed ${token_name}&#039;),array(&lt;br /&gt;
              &#039;token_name&#039; =&amp;gt; $token_id,&lt;br /&gt;
              &#039;zone_played&#039; =&amp;gt; $zone);&lt;br /&gt;
&lt;br /&gt;
This will output &amp;quot;Player placed ${token_name}&amp;quot; in the log, and if we subscribe to a notification method activated by the &amp;quot;tokenPlaced&amp;quot; event in the client-side code, that method can make use of the &#039;zone_played&#039; argument. &lt;br /&gt;
&lt;br /&gt;
Now if you want to make some really cool things with game log, most probably you would need more arguments than are included in log message. The problem with that,&lt;br /&gt;
it will work at first, but if you reload game using F5 or when the game loads in turn based mode, you will loose your additional parameters, why? Because when game reloads it does not actually send same notifications, it sends special &amp;quot;hitstorical_log&amp;quot; notification where all  parameters not listed in the message are removed. In example above, field zone_played would be removed from historical log as it is not included in message of the notification. You can till preserve specific arguments in historical log by adding special field preserve to notification arguments like this:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
           $this-&amp;gt;notifyAllPlayers(&#039;tokenPlaced&#039;,clienttranslate(&#039;Player placed ${token_name}&#039;),array(&lt;br /&gt;
              &#039;token_name&#039; =&amp;gt; $token_id,&lt;br /&gt;
              &#039;zone_played&#039; =&amp;gt; $zone,&lt;br /&gt;
              &#039;preserve&#039; =&amp;gt; [ &#039;zone_played&#039; ]&lt;br /&gt;
           );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now you can use zone_played in format_string_recursive even in historical logs.&lt;br /&gt;
&lt;br /&gt;
===== Second way: rely on the &amp;lt;code&amp;gt;:formatFunction&amp;lt;/code&amp;gt; option provided by &amp;lt;code&amp;gt;dojo.string.substitute&amp;lt;/code&amp;gt; =====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, ggg.game.php, ggg_ggg.tpl, ggg.css&lt;br /&gt;
&lt;br /&gt;
The above method will work in most of the cases, but if you use dotted keys such as &amp;lt;code&amp;gt;${card.name}&amp;lt;/code&amp;gt; (which is supported by the framework, for private state args), the key won&#039;t be substituted because the &amp;lt;code&amp;gt;key in arg&amp;lt;/code&amp;gt; test will fail. If so you need to rely either on this way, or the one after.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;WARNING:&#039;&#039;&#039; using this method on an already advanced project will require you to go through all your notifications to change keys !&lt;br /&gt;
&lt;br /&gt;
Under the hood, the &#039;&#039;&#039;this.format_string_recursive()&#039;&#039;&#039; function calls the &#039;&#039;&#039;dojo.string.substitute&#039;&#039;&#039; method which substitutes &amp;lt;code&amp;gt;${keys}&amp;lt;/code&amp;gt; with the value provided. If you take a look at the [https://dojotoolkit.org/reference-guide/1.7/dojo/string.html#substitute documentation] and [https://github.com/dojo/dojo/blob/c3ceb017cfa25b703f5662dc83d1c8aae9bc5d81/string.js#L163 source code] you can notice that the key can be suffixed with a colon (&amp;lt;code&amp;gt;:&amp;lt;/code&amp;gt;) followed by a function name. This will allow you to specify directly in the substitution string which keys need HTML injection.&lt;br /&gt;
&lt;br /&gt;
First of all, you need to define your formatting function in the ggg.js file:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[[ggg.js]]&lt;br /&gt;
        getTokenDiv : function(value, key) {&lt;br /&gt;
            //This is only an example implementation, you need to write your own.&lt;br /&gt;
            //The method should return HTML code&lt;br /&gt;
            switch (key) {&lt;br /&gt;
                case &#039;html_injected_argument1&#039;:&lt;br /&gt;
                    return this.format_block(&#039;jstpl_HTMLLogElement1&#039;,{value: value});&lt;br /&gt;
                case &#039;html_injected_argument2&#039;:&lt;br /&gt;
                    return this.format_block(&#039;jstpl_HTMLLogElement2&#039;,{value: value});&lt;br /&gt;
                ...&lt;br /&gt;
            }&lt;br /&gt;
       }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Obviously you need to define the appropriate templates in the ggg_ggg.tpl file:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[[ggg_ggg.tpl]]&lt;br /&gt;
let jstpl_HTMLLogElement1 = &#039;&amp;lt;div class=&amp;quot;log-element log-element-1-${value}&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
let jstpl_HTMLLogElement2 = &#039;&amp;lt;div class=&amp;quot;log-element log-element-2-${value}&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
And the appropriate classes in ggg.css.&lt;br /&gt;
&lt;br /&gt;
Then you need to add the &amp;lt;code&amp;gt;dojo/aspect&amp;lt;/code&amp;gt; module at the top of the ggg.js file:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[ggg.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 define([&lt;br /&gt;
     &amp;quot;dojo&amp;quot;, &amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&amp;quot;dojo/aspect&amp;quot;,&amp;lt;/span&amp;gt;                 //MUST BE IN THIRD POSITION&#039;&#039;&#039; (see [[#Including your own JavaScript module (II)|below]])&lt;br /&gt;
     &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
 ], function (dojo, declare, &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&#039;&#039;&#039;aspect&#039;&#039;&#039;&amp;lt;/span&amp;gt;) {&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
And you also need to add the following code in your &amp;lt;code&amp;gt;contructor&amp;lt;/code&amp;gt; method in the ggg.js:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[ggg.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
         constructor: function(){&lt;br /&gt;
             console.log(&#039;progressevolutiontechnologyswh constructor&#039;);&lt;br /&gt;
               &lt;br /&gt;
             // Here, you can init the global variables of your user interface&lt;br /&gt;
             // Example:&lt;br /&gt;
             // this.myGlobalValue = 0;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&#039;&#039;&#039;let gameObject = this;&#039;&#039;&#039;            //Needed as the this object in aspect.before will not refer to the game object in which the formatting function resides&lt;br /&gt;
             &#039;&#039;&#039;aspect.before(dojo.string, &amp;quot;substitute&amp;quot;, function(template, map, transform) {&#039;&#039;&#039;      //This allows you to modify the arguments of the dojo.string.substitute method before they&#039;re actually passed to it&lt;br /&gt;
                 &#039;&#039;&#039;return [template, map, transform, gameObject];&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now you&#039;re all set to inject HTML in your logs. To actually achieve this, you must specify the function name with the key like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[ggg.game.php]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 $this-&amp;gt;notifyAllPlayers(&amp;quot;notificationName&amp;quot;, clienttranslate(&amp;quot;This log message contains ${plainTextArgument} and the following will receive HTML injection: ${html_injected_argument1:getTokenDiv}), [&lt;br /&gt;
     &amp;quot;plainTextArgument&amp;quot; =&amp;gt; &amp;quot;some plain text here&amp;quot;,&lt;br /&gt;
     &amp;quot;html_injected_argument1&amp;quot; =&amp;gt; &amp;quot;some value used by getTokenDiv&amp;quot;,&lt;br /&gt;
 ]);&lt;br /&gt;
&lt;br /&gt;
You&#039;re not limited writing only one function, you can write as many functions as you like, and have them each inject a specific type of HTML. You just need to specify the relevant function name after the column in the substitution key.&lt;br /&gt;
&lt;br /&gt;
===== Third way: rely on the &amp;lt;code&amp;gt;transform&amp;lt;/code&amp;gt; argument of &amp;lt;code&amp;gt;dojo.string.substitute&amp;lt;/code&amp;gt; =====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, ggg.game.php, ggg_ggg.tpl, ggg.css&lt;br /&gt;
&lt;br /&gt;
This method is also relying on the use of &amp;lt;code&amp;gt;dojo.string.substitute&amp;lt;/code&amp;gt; by the framework, and will use the &amp;lt;code&amp;gt;transform&amp;lt;/code&amp;gt; argument, which, accordting to [https://github.com/dojo/dojo/blob/c3ceb017cfa25b703f5662dc83d1c8aae9bc5d81/string.js#L163 source code] and [https://dojotoolkit.org/reference-guide/1.7/dojo/string.html#substitute documentation] will be run on all the messages going through dojo.string.substitute.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;WARNING:&#039;&#039;&#039; As this method will be applied to all strings that go through dojo.string.substitute. As such you must take extra care not to substitute keys that may be used by the framework (i.e. ${id}). In order to do so, a good practise would be to prefix all keys that need substitution with a trigram of the game name.&lt;br /&gt;
&lt;br /&gt;
Since all the keys will be fed to the tranform function, by default, it must return the value, substituted or not per your needs. You can define the function like this in the ggg.js file:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[ggg.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
         getTokenDiv : function(value, key) {&lt;br /&gt;
             //This is only an example implementation, you need to write your own.&lt;br /&gt;
             //The method should return HTML code&lt;br /&gt;
             switch (key) {&lt;br /&gt;
                 case &#039;html_injected_argument1&#039;:&lt;br /&gt;
                     return this.format_block(&#039;jstpl_HTMLLogElement1&#039;,{value: value});&lt;br /&gt;
                 case &#039;html_injected_argument2&#039;:&lt;br /&gt;
                     return this.format_block(&#039;jstpl_HTMLLogElement2&#039;,{value: value});&lt;br /&gt;
                 ...&lt;br /&gt;
                 &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&#039;&#039;&#039;default:&#039;&#039;&#039;&lt;br /&gt;
                     &#039;&#039;&#039;return value;&#039;&#039;&#039;&amp;lt;/span&amp;gt;                  &#039;&#039;&#039;//Needed otherwise regular strings won&#039;t appear since since the value isn&#039;t returned by the function&#039;&#039;&#039;&lt;br /&gt;
             }&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
The templates must be defined in the ggg_ggg.tpl file and the corresponding CSS classes in the ggg.css file.&lt;br /&gt;
&lt;br /&gt;
You need to add the following code at the beginning of the ggg.js file:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[ggg.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 define([&lt;br /&gt;
     &amp;quot;dojo&amp;quot;, &amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&amp;quot;dojo/aspect&amp;quot;,&amp;lt;/span&amp;gt;                 //MUST BE IN THIRD POSITION&#039;&#039;&#039; (see [[#Including your own JavaScript module (II)|below]])&lt;br /&gt;
     &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
 ], function (dojo, declare, &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&#039;&#039;&#039;aspect&#039;&#039;&#039;&amp;lt;/span&amp;gt;) {&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
And the following code to the &amp;lt;code&amp;gt;constructor&amp;lt;/code&amp;gt; method in ggg.js:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[[ggg.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
         constructor: function(){&lt;br /&gt;
             console.log(&#039;progressevolutiontechnologyswh constructor&#039;);&lt;br /&gt;
               &lt;br /&gt;
             // Here, you can init the global variables of your user interface&lt;br /&gt;
             // Example:&lt;br /&gt;
             // this.myGlobalValue = 0;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&#039;&#039;&#039;let transformFunction = dojo.hitch(this, &amp;quot;getTokenDiv&amp;quot;);&#039;&#039;&#039;            //Needed as the this object in aspect.before will not refer to the game object in which the formatting function resides&lt;br /&gt;
             &#039;&#039;&#039;aspect.before(dojo.string, &amp;quot;substitute&amp;quot;, function(template, map, transform) {&#039;&#039;&#039;&lt;br /&gt;
                 &#039;&#039;&#039;if (undefined === transform) {&#039;&#039;&#039;                                   //Check for a transform function presence, just in case&lt;br /&gt;
                     &#039;&#039;&#039;return [template, map, transform];&#039;&#039;&#039;&lt;br /&gt;
                 &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Processing logs on re-loading ====&lt;br /&gt;
&lt;br /&gt;
You rarely need to process logs when reloading, but if you want to do something fancy you may have to do it after logs are loaded. &lt;br /&gt;
Logs are loaded asyncronously so you have to listen for logs to be fully loaded.&lt;br /&gt;
Unfortunately there is no direct way of doing it so this is the hack.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Hack alert&#039;&#039;&#039; - this extends undocumented function and may be broken when framework is updated&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
			/*&lt;br /&gt;
  			* [Undocumented] Override BGA framework functions to call onLoadingLogsComplete when loading is done&lt;br /&gt;
                        @Override&lt;br /&gt;
   			*/&lt;br /&gt;
			setLoader: function(image_progress, logs_progress) {&lt;br /&gt;
				this.inherited(arguments); // required, this is &amp;quot;super()&amp;quot; call, do not remove&lt;br /&gt;
				//console.log(&amp;quot;loader&amp;quot;, image_progress, logs_progress)&lt;br /&gt;
				if (!this.isLoadingLogsComplete &amp;amp;&amp;amp; logs_progress &amp;gt;= 100) {&lt;br /&gt;
					this.isLoadingLogsComplete = true; // this is to prevent from calling this more then once&lt;br /&gt;
					this.onLoadingLogsComplete();&lt;br /&gt;
				}&lt;br /&gt;
			},&lt;br /&gt;
&lt;br /&gt;
			onLoadingLogsComplete: function() {&lt;br /&gt;
				console.log(&#039;Loading logs complete&#039;);&lt;br /&gt;
				// do something here&lt;br /&gt;
			},&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Player Panel ===&lt;br /&gt;
&lt;br /&gt;
==== Inserting non-player panel ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, ggg_ggg.tpl&lt;br /&gt;
&lt;br /&gt;
If you want to insert non-player panel on the right side (for example to hold extra preferences, zooming controls, etc)&lt;br /&gt;
&lt;br /&gt;
this can go pretty much anywhere in template it will be moved later&lt;br /&gt;
&lt;br /&gt;
ggg_ggg.tpl:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	&amp;lt;div class=&#039;player_board_config&#039; id=&amp;quot;player_board_config&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;!-- here is whatever you want, buttons just example --&amp;gt;&lt;br /&gt;
		&amp;lt;button id=&amp;quot;zoom-out&amp;quot; class=&amp;quot; fa fa-search-minus fa-2x config-control&amp;quot;&amp;gt;&amp;lt;/button&amp;gt;&lt;br /&gt;
		&amp;lt;button id=&amp;quot;zoom-in&amp;quot; class=&amp;quot; fa fa-search-plus fa-2x config-control&amp;quot;&amp;gt;&amp;lt;/button&amp;gt;&lt;br /&gt;
		&amp;lt;button id=&amp;quot;show-settings&amp;quot; class=&amp;quot;fa fa-cog fa-2x config-control &amp;quot;&amp;gt;&amp;lt;/button&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
some hackery required in js&lt;br /&gt;
&lt;br /&gt;
ggg.js:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* @Override */&lt;br /&gt;
	updatePlayerOrdering() {&lt;br /&gt;
		this.inherited(arguments);&lt;br /&gt;
		dojo.place(&#039;player_board_config&#039;, &#039;player_boards&#039;, &#039;first&#039;);&lt;br /&gt;
	},&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Images and Icons ===&lt;br /&gt;
&lt;br /&gt;
==== Accessing images from js ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
     // your game resources&lt;br /&gt;
     &lt;br /&gt;
     var my_img = &#039;&amp;lt;img src=&amp;quot;&#039;+g_gamethemeurl+&#039;img/cards.jpg&amp;quot;/&amp;gt;&#039;;&lt;br /&gt;
     &lt;br /&gt;
     // shared resources&lt;br /&gt;
     var my_help_img = &amp;quot;&amp;lt;img class=&#039;imgtext&#039; src=&#039;&amp;quot; + g_themeurl + &amp;quot;img/layout/help_click.png&#039; alt=&#039;action&#039; /&amp;gt; &amp;lt;span class=&#039;tooltiptext&#039;&amp;gt;&amp;quot; +&lt;br /&gt;
                    text + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== High-Definition Graphics ====&lt;br /&gt;
&lt;br /&gt;
Some users will have screens which can display text and images at a greater resolution than the usual 72 dpi, e.g. the &amp;quot;Retina&amp;quot; screens on the 5k iMac, all iPads, and high-DPI screens on laptops from many manufacturers. If you can get art assets at this size, they will make your game look extra beautiful. You &#039;&#039;could&#039;&#039; just use large graphics and scale them down, but that would increase the download time and bandwidth for users who can&#039;t display them. Instead, a good way is to prepare a separate graphics file at exactly twice the size you would use otherwise, and add &amp;quot;@2x&amp;quot; at the end of the filename, e.g. if pieces.png is 240x320, then pieces@2x.png is 480x640.&lt;br /&gt;
&lt;br /&gt;
There are two changes required in order to use the separate graphics files. First in your css, where you use a file, add a media query which overrides the original definition and uses the bigger version on devices which can display them. Ensuring that the &amp;quot;background-size&amp;quot; attribute is set means that the size of the displayed object doesn&#039;t change, but only is drawn at the improved dot pitch.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.piece {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    background-image: url(&#039;img/pieces.png&#039;);&lt;br /&gt;
    background-size:240px 320px;&lt;br /&gt;
    z-index: 10;&lt;br /&gt;
}&lt;br /&gt;
@media (-webkit-min-device-pixel-ratio: 2), (min-device-pixel-ratio: 2), (min-resolution: 192dpi)&lt;br /&gt;
{&lt;br /&gt;
    .piece {&lt;br /&gt;
        background-image: url(&#039;img/pieces@2x.png&#039;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Secondly, in your setup function in javascript, you must ensure than only the appropriate one version of the file gets pre-loaded (otherwise you more than waste the bandwidth saved by maintaining the standard-resolution file). Note that the media query is the same in both cases:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
            var isRetina = &amp;quot;(-webkit-min-device-pixel-ratio: 2), (min-device-pixel-ratio: 2), (min-resolution: 192dpi)&amp;quot;;&lt;br /&gt;
            if (window.matchMedia(isRetina).matches)&lt;br /&gt;
            {&lt;br /&gt;
                this.dontPreloadImage( &#039;pieces.png&#039; );&lt;br /&gt;
                this.dontPreloadImage( &#039;board.jpg&#039; );&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                this.dontPreloadImage( &#039;pieces@2x.png&#039; );&lt;br /&gt;
                this.dontPreloadImage( &#039;board@2x.jpg&#039; );&lt;br /&gt;
            }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using CSS to create different colors of game pieces if you have only white piece ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
background-color: #${color}; &lt;br /&gt;
background-blend-mode: multiply;&lt;br /&gt;
background-image: url( &#039;img/mypiece.png&#039;);&lt;br /&gt;
mask: url(&#039;img/mypiece.png&#039;);&lt;br /&gt;
-webkit-mask: url(&#039;img/mypiece.png&#039;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where ${color} - is color you want&lt;br /&gt;
&lt;br /&gt;
Note: piece has to be white (shades of gray). Sprite can be used too, just add add blackground-position as usuall.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Other Fluff ===&lt;br /&gt;
&lt;br /&gt;
==== Use thematic fonts ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.css&lt;br /&gt;
&lt;br /&gt;
Sometime game elements use specific fonts of text, if you want to match it up you can load some specific font (IMPORTANT: from some &#039;&#039;&#039;free font&#039;&#039;&#039; source. See notes below).&lt;br /&gt;
&lt;br /&gt;
[[File:Dragonline_font.png]]&lt;br /&gt;
&lt;br /&gt;
.css&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* latin-ext */&lt;br /&gt;
@font-face {&lt;br /&gt;
  font-family: &#039;Qwigley&#039;;&lt;br /&gt;
  font-style: normal;&lt;br /&gt;
  font-weight: 400;&lt;br /&gt;
  src: local(&#039;Qwigley&#039;), local(&#039;Qwigley-Regular&#039;), url(https://fonts.gstatic.com/s/qwigley/v6/2Dy1Unur1HJoklbsg4iPJ_Y6323mHUZFJMgTvxaG2iE.woff2) format(&#039;woff2&#039;);&lt;br /&gt;
  unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;&lt;br /&gt;
}&lt;br /&gt;
/* latin */&lt;br /&gt;
@font-face {&lt;br /&gt;
  font-family: &#039;Qwigley&#039;;&lt;br /&gt;
  font-style: normal;&lt;br /&gt;
  font-weight: normal;&lt;br /&gt;
  src: local(&#039;Qwigley&#039;), local(&#039;Qwigley-Regular&#039;), url(https://fonts.gstatic.com/s/qwigley/v6/gThgNuQB0o5ITpgpLi4Zpw.woff2) format(&#039;woff2&#039;);&lt;br /&gt;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;&lt;br /&gt;
}&lt;br /&gt;
@font-face {&lt;br /&gt;
  font-family: &#039;Qwigley&#039;;&lt;br /&gt;
  font-style: normal;&lt;br /&gt;
  font-weight: normal;&lt;br /&gt;
  src: local(&#039;Qwigley&#039;), local(&#039;Qwigley-Regular&#039;), url(http://ff.static.1001fonts.net/q/w/qwigley.regular.ttf) format(&#039;ttf&#039;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.zone_title {&lt;br /&gt;
	display: inline-block;&lt;br /&gt;
	position: absolute;&lt;br /&gt;
	font: italic 32px/32px &amp;quot;Qwigley&amp;quot;, cursive;	   &lt;br /&gt;
	height: 32px;&lt;br /&gt;
	width: auto;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NB:&#039;&#039;&#039; if you need to include a font that&#039;s not available online, an extra action will be needed from an admin. Please include the font file(s) in your img directory, and mention it to admins when requesting your game to be moved to alpha. &#039;&#039;&#039;Please remember that the font has to be free, and include a .txt with all appropriate license information about the font.&#039;&#039;&#039;&lt;br /&gt;
You can look for free fonts (for example) on https://fonts.google.com or https://www.fontsquirrel.com/)&lt;br /&gt;
&lt;br /&gt;
=== Use player color in template ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg_ggg.tpl, ggg.view.php&lt;br /&gt;
&lt;br /&gt;
.view.php:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    function build_page($viewArgs) {&lt;br /&gt;
        // Get players &amp;amp; players number&lt;br /&gt;
        $players = $this-&amp;gt;game-&amp;gt;loadPlayersBasicInfos();&lt;br /&gt;
        $players_nbr = count($players);&lt;br /&gt;
        /**&lt;br /&gt;
         * ********* Place your code below: ***********&lt;br /&gt;
         */&lt;br /&gt;
        &lt;br /&gt;
        // Set PCOLOR to the current player color hex&lt;br /&gt;
        global $g_user;&lt;br /&gt;
        $cplayer = $g_user-&amp;gt;get_id();&lt;br /&gt;
        if (array_key_exists($cplayer, $players)) { // may be not set if spectator&lt;br /&gt;
            $player_color = $players [$cplayer] [&#039;player_color&#039;];&lt;br /&gt;
        } else {&lt;br /&gt;
            $player_color = &#039;ffffff&#039;; // spectator&lt;br /&gt;
        }&lt;br /&gt;
        $this-&amp;gt;tpl [&#039;PCOLOR&#039;] = $player_color;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Scale to fit for big boards ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg_ggg.tpl, ggg.js&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Lets say you have huge game board, and lets say you want it to be 1400px wide. Besides the board there will be side bar which is 240 and trim. &lt;br /&gt;
My display is 1920 wide so it fits, but there is big chance other people won&#039;t have that width. What do you do?&lt;br /&gt;
&lt;br /&gt;
You have to decide:&lt;br /&gt;
* If board does not fit you want scale whole thing down, the best way is probably use viewport (see https://en.doc.boardgamearena.com/Your_game_mobile_version)&lt;br /&gt;
* You can leave the board as is and make sure it is scrollable horizonatally&lt;br /&gt;
* You add custom scale just for the board (can add user controls  - and hook to transform: scale())&lt;br /&gt;
&lt;br /&gt;
I tried to auto-scale but this just does work, too many variables - browser zoom, 3d mode, viewport, custom bga scaling, devicePixelRatio - all create some impossible coctail of zooming...&lt;br /&gt;
Here is scaling functing for custom user scaling&lt;br /&gt;
&lt;br /&gt;
ggg_ggg.tpl:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   &amp;lt;div id=&amp;quot;thething&amp;quot; class=&amp;quot;thething&amp;quot;&amp;gt;&lt;br /&gt;
            ... everything else you declare ...&lt;br /&gt;
   &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ggg.js:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    onZoomPlus: function() {&lt;br /&gt;
       this.my_zoom+=0.1;&lt;br /&gt;
       this.zoommy(&#039;thething&#039;,this.my_zoom);&lt;br /&gt;
    },&lt;br /&gt;
&lt;br /&gt;
    zoommy: function(node, zoom) {&lt;br /&gt;
                node=$(node);&lt;br /&gt;
		var width = 100 / zoom;&lt;br /&gt;
		node.style.transformOrigin = &amp;quot;0 0&amp;quot;;&lt;br /&gt;
		node.style.transform = &amp;quot;scale(&amp;quot; + zoom + &amp;quot;)&amp;quot;;&lt;br /&gt;
		node.style.width = width + &amp;quot;%&amp;quot;;&lt;br /&gt;
    },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Dynamic tooltips ===&lt;br /&gt;
&lt;br /&gt;
If you really need a dynamic tooltip you can use this technique. (Only use it if the static tooltips provided by the BGA framework are not sufficient.)&lt;br /&gt;
&lt;br /&gt;
            new dijit.Tooltip({&lt;br /&gt;
                connectId: [&amp;quot;divItemId&amp;quot;],&lt;br /&gt;
                getContent: function(matchedNode){&lt;br /&gt;
                    return &amp;quot;... calculated ...&amp;quot;; &lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is an out-of-the-box djit.Tooltip. It has a &#039;&#039;getContent&#039;&#039; method which is called dynamically.&lt;br /&gt;
&lt;br /&gt;
The string function return becomes the innerHTML of the tooltip, so it can be anything. In this example matchedNode is a dojo node representing dom object with id of &amp;quot;divItemId&amp;quot; but there are more parameters which I am not posting here which allows more sophisticated subnode queries (i.e. you can attach tooltip to all nodes with class or whatever).&lt;br /&gt;
&lt;br /&gt;
[https://dojotoolkit.org/reference-guide/1.10/dijit/Tooltip.html dijit.Tooltip]&lt;br /&gt;
&lt;br /&gt;
It&#039;s not part of the BGA API so use at your own risk.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Rendering text with players color and proper background ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
This example actually writes &amp;quot;You&amp;quot; but you can replace this with player name as easily, drop translating function in this case&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        /* Implementation of proper colored You with background in case of white or light colors  */&lt;br /&gt;
 &lt;br /&gt;
        divYou : function() {&lt;br /&gt;
            var color = this.gamedatas.players[this.player_id].color;&lt;br /&gt;
            var color_bg = &amp;quot;&amp;quot;;&lt;br /&gt;
            if (this.gamedatas.players[this.player_id] &amp;amp;&amp;amp; this.gamedatas.players[this.player_id].color_back) {&lt;br /&gt;
                color_bg = &amp;quot;background-color:#&amp;quot; + this.gamedatas.players[this.player_id].color_back + &amp;quot;;&amp;quot;;&lt;br /&gt;
            }&lt;br /&gt;
            var you = &amp;quot;&amp;lt;span style=\&amp;quot;font-weight:bold;color:#&amp;quot; + color + &amp;quot;;&amp;quot; + color_bg + &amp;quot;\&amp;quot;&amp;gt;&amp;quot; + __(&amp;quot;lang_mainsite&amp;quot;, &amp;quot;You&amp;quot;) + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
            return you;&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Cool realistic shadow effect with CSS ===&lt;br /&gt;
&lt;br /&gt;
==== Rectangles and circles ====&lt;br /&gt;
&lt;br /&gt;
It is often nice to have a drop shadow around tiles and tokens, to separate them from the table visually. It is very easy to add a shadow to rectangular elements, just add this to your css:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.xxx-tile {&lt;br /&gt;
    box-shadow: 3px 3px 3px #000000a0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
box-shadow obeys &#039;&#039;&#039;border-radius&#039;&#039;&#039; of the element, so it will look good for rounded rectangles, and hence also circles (if border-radius is set appropriately).&lt;br /&gt;
&lt;br /&gt;
box-shadow also supports various other parameters and can be used to achieve effects such as glowing, borders, inner shadows etc. If you need to animate a box-shadow, you may be able to get better performance (avoiding redraws) if you attach the shadow to another element (possibly an ::after pseudo-element) and change only the &#039;&#039;&#039;opacity&#039;&#039;&#039; of that element.&lt;br /&gt;
&lt;br /&gt;
==== Irregular Shapes ====&lt;br /&gt;
&lt;br /&gt;
If you wish to make a shadow effect for game pieces that are not a rectangle, but your game pieces are drawn from rectangles in a PNG image, you can apply the shadow to the piece using any art package and save it inside the image. This usually will yield the best performance. Remember to account for the size of the shadow when you lay out images in the sprite sheet.&lt;br /&gt;
&lt;br /&gt;
However that sometimes will not be an option, for example if the image needs to be rotated while the shadow remains offset in the same direction. In this case, one option is to not use box-shadow but use filter, which is supported by recent major browsers.  This way, you can use the alpha channel of your element to drop a shadow.  This even work for transparent backgrounds, so that if you are using the &amp;quot;CSS-sprite&amp;quot; method, it will work!&lt;br /&gt;
&lt;br /&gt;
For instance:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.xxx-token {&lt;br /&gt;
    filter: drop-shadow(0px 0px 1px #000000);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beware that some browsers still do not always draw drop-shadow correctly. In particular, Safari frequently leaves bits of shadow behind when objects move around the screen. In Chrome, shadows sometimes flicker badly if another element is animating close by. Some of these correctness issues can be solved by adding &#039;&#039;&#039;isolation: isolate; will-change: filter;&#039;&#039;&#039; to affected elements, but this significantly affects redraw performance.&lt;br /&gt;
&lt;br /&gt;
Beware of performance issues - particularly on Safari (MacOS, iPhone and iPad). Keep in mind that drop-shadow are very GPU intensive. This becomes noticeable once you have about 40 components with drop-shadow filter. If that is your case, you can quite easily implement a user preference to disable shadows for users on slower machines:&lt;br /&gt;
&lt;br /&gt;
gameoptions.inc.php&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
100 =&amp;gt; array(&lt;br /&gt;
			&#039;name&#039; =&amp;gt; totranslate(&#039;Shadows&#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;Enabled&#039; ), &#039;cssPref&#039; =&amp;gt; &#039;&#039; ),&lt;br /&gt;
					2 =&amp;gt; array( &#039;name&#039; =&amp;gt; totranslate( &#039;Disabled&#039; ), &#039;cssPref&#039; =&amp;gt; &#039;no-shadow&#039; )&lt;br /&gt;
			)&lt;br /&gt;
	),&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[game].css&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.no-shadow * {&lt;br /&gt;
	filter: none !important; &lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Shadows with clip-path ====&lt;br /&gt;
&lt;br /&gt;
For some reason, a shadow will not work together with clip-path on one element. To use both clip-path (when for example using .svg to cut out cardboard components from your .jpg spritesheet) and drop-shadow, you need to wrap the element into another one, and apply drop-shadow to the outer one, and clip-path to the inner one.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;div class=&#039;my-token-wrap&#039;&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&#039;my-token&#039;&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;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.my-token-wrap {&lt;br /&gt;
    filter: drop-shadow(0px 0px 1px #000000);&lt;br /&gt;
}&lt;br /&gt;
.my-token-wrap .my-token {&lt;br /&gt;
    clip-path: url(#my-token-path);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Using the CSS classes from the state machine ===&lt;br /&gt;
&lt;br /&gt;
If you need to hide or show stuff depending on the state of your game, you can of course use javascript, but CSS is hand enough for that.  The #overall-content element does change class depending on the game state.  For instance, if you are in state &#039;&#039;playerTurn&#039;&#039;, it will have the class &#039;&#039;gamestate_playerTurn&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
So now, if you want to show the discard pile only during player turns, you may use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#discard_pile { display: none }&lt;br /&gt;
.gamestate_playerTurn #discard_pile { display: block }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This can be used if you want to change sizing of elements, position, layout or visual appearance.&lt;br /&gt;
&lt;br /&gt;
== Game Model and Database design ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Database for The euro game ===&lt;br /&gt;
Lets say we have a game with workers, dice, tokens, board, resources, money and vp. Workers and dice can be placed in various zones on the board, and you can get resources, money, tokens and vp in your home zone. Also tokens can be flipped or not flipped.&lt;br /&gt;
&lt;br /&gt;
[[File:Madeira board.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now lets try to map it, we have&lt;br /&gt;
* (meeple,zone)&lt;br /&gt;
* (die, zone, sideup)&lt;br /&gt;
* (resource cube/money token/vp token,player home zone)&lt;br /&gt;
* (token, player home zone, flip state)&lt;br /&gt;
We can notice that resource and money are uncountable, and don&#039;t need to be track individually so we can replace our mapping to&lt;br /&gt;
* (resource type/money,player home zone, count)&lt;br /&gt;
And vp stored already for us in player table, so we can remove it from that list.&lt;br /&gt;
&lt;br /&gt;
Now when we get to encode it we can see that everything can be encoded as (object,zone,state) form, where object and zone is string and state is integer. The resource mapping is slightly different semantically so you can go with two table, or counting using same table with state been used as count for resources.&lt;br /&gt;
&lt;br /&gt;
So the piece mapping for non-grid based games can be in most case represented by (string: token_key, string: token_location, int: token_state), example of such database schema can be found here: [https://github.com/elaskavaia/bga-sharedcode/blob/master/dbmodel.sql dbmodel.sql] and class implementing access to it here [https://github.com/elaskavaia/bga-sharedcode/blob/master/modules/tokens.php table.game.php].&lt;br /&gt;
&lt;br /&gt;
Variant 1: Minimalistic&lt;br /&gt;
&lt;br /&gt;
 CREATE TABLE IF NOT EXISTS `token` (&lt;br /&gt;
  `token_key` varchar(32) NOT NULL,&lt;br /&gt;
  `token_location` varchar(32) NOT NULL,&lt;br /&gt;
  `token_state` int(10),&lt;br /&gt;
  PRIMARY KEY (`token_key`)&lt;br /&gt;
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+token&lt;br /&gt;
! token_key&lt;br /&gt;
! token_location&lt;br /&gt;
! token_state&lt;br /&gt;
|-&lt;br /&gt;
|meeple_red_1&lt;br /&gt;
|home_red&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
|dice_black_2&lt;br /&gt;
|board_guard&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
|dice_green_1&lt;br /&gt;
|board_action_mayor&lt;br /&gt;
|3&lt;br /&gt;
|-&lt;br /&gt;
|bread&lt;br /&gt;
|home_red&lt;br /&gt;
|5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Now how we represent resource counters such as bread?&lt;br /&gt;
Using same table from we simply add special counter token for bread and use state to indicate the count. Note to keep first column unique we have to add player identification for that counter, i.e. ff0000 is red player.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+token&lt;br /&gt;
! token_key&lt;br /&gt;
! token_location&lt;br /&gt;
! token_state&lt;br /&gt;
|-&lt;br /&gt;
|bread_ff0000&lt;br /&gt;
|tableau_ff0000&lt;br /&gt;
|5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See php module for this table here https://github.com/elaskavaia/bga-sharedcode/blob/master/modules/tokens.php&lt;br /&gt;
&lt;br /&gt;
Variant 2: Additional resource table, resource count for each player id&lt;br /&gt;
&lt;br /&gt;
 CREATE TABLE IF NOT EXISTS `resource` (&lt;br /&gt;
  `player_id` int(10) unsigned NOT NULL,&lt;br /&gt;
  `resource_key` varchar(32) NOT NULL,&lt;br /&gt;
  `resource_count` int(10) signed NOT NULL,&lt;br /&gt;
  PRIMARY KEY (`player_id`,`resource_key`)&lt;br /&gt;
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;&lt;br /&gt;
&lt;br /&gt;
 ALTER TABLE resource ADD CONSTRAINT fk_player_id FOREIGN KEY (player_id) REFERENCES player(player_id);&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+resource&lt;br /&gt;
! player_id&lt;br /&gt;
! resource_key&lt;br /&gt;
! resource_count&lt;br /&gt;
|-&lt;br /&gt;
|123456&lt;br /&gt;
|bread&lt;br /&gt;
|5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Variant 3: More normalised&lt;br /&gt;
&lt;br /&gt;
This version is similar to &amp;quot;card&amp;quot; table from hearts tutorial, you can also use exact cards database schema and Deck implementation for most purposes (even you not dealing with cards). &lt;br /&gt;
&lt;br /&gt;
 CREATE TABLE IF NOT EXISTS `token` (&lt;br /&gt;
  `token_id` int(10) unsigned NOT NULL AUTO_INCREMENT,&lt;br /&gt;
  `token_type` varchar(16) NOT NULL,&lt;br /&gt;
  `token_arg` int(11) NOT NULL,&lt;br /&gt;
  `token_location` varchar(32) NOT NULL,&lt;br /&gt;
  `token_state` int(10),&lt;br /&gt;
  PRIMARY KEY (`token_id`)&lt;br /&gt;
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+token&lt;br /&gt;
! token_id&lt;br /&gt;
! token_type&lt;br /&gt;
! token_arg&lt;br /&gt;
! token_location&lt;br /&gt;
! token_state&lt;br /&gt;
|-&lt;br /&gt;
|22&lt;br /&gt;
|meeple&lt;br /&gt;
|123456&lt;br /&gt;
|home_123456&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
|23&lt;br /&gt;
|dice&lt;br /&gt;
|2&lt;br /&gt;
|board_guard&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
|26&lt;br /&gt;
|dice&lt;br /&gt;
|1&lt;br /&gt;
|board_action_mayor&lt;br /&gt;
|3&lt;br /&gt;
|-&lt;br /&gt;
|49&lt;br /&gt;
|bread&lt;br /&gt;
|0&lt;br /&gt;
|home_123456&lt;br /&gt;
|5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Advantages of this would be is a bit more straightforward to do some queries in db, disadvantage its hard to read (as you can compare with previous example, you&lt;br /&gt;
cannot just look at say, ah I know what it means). Another questionable advantage is it allows you to do id randomisation, so it hard to do crafted queries to &lt;br /&gt;
cheat, the down side of that you cannot understand it either, and handcraft db states for debugging or testing.&lt;br /&gt;
&lt;br /&gt;
=== Database for The card game ===&lt;br /&gt;
&lt;br /&gt;
Lets say you have a standard card game, player have hidden cards in hand, you can draw card from draw deck, play card on tableau and discard to discard pile.&lt;br /&gt;
We have to design database for such game.&lt;br /&gt;
&lt;br /&gt;
In real word to &amp;quot;save&amp;quot; the game we take a picture a play area, save cards from it, then put away draw deck, discard and hand of each player separately and mark it, also we will record current scoring (if any) and who&#039;s turn was it.&lt;br /&gt;
&lt;br /&gt;
* Framework handles state machine transition, so you don&#039;t have to worry about database design for that (i.e. who&#039;s turn it is, what phase of the game we are at, you still have to design it but part of state machine step)&lt;br /&gt;
* Also framework supports basic player information, color, order around the table, basic scoring, etc, so you don&#039;t have to worry about it either&lt;br /&gt;
* The only thing you need in our database is state of the &amp;quot;board&amp;quot;, which is &amp;quot;where each pieces is, and in what state&amp;quot;, or (position,rotation) pair.&lt;br /&gt;
&lt;br /&gt;
Lets see what we have for that:&lt;br /&gt;
* The card state is very simple, its usually &amp;quot;face up/face down&amp;quot;, &amp;quot;tapped/untapped&amp;quot;, &amp;quot;right side up/up side down&amp;quot;&lt;br /&gt;
* As position go we never need real coordinates x,y,z. We need to know what &amp;quot;zone&amp;quot; card was, and depending on the zone it may sometimes need an extra &amp;quot;z&amp;quot; or &amp;quot;x&amp;quot; as card order. The zone position usually static or irrelevant.&lt;br /&gt;
* So our model is: we have cards, which have some attributes, at any given point in time they belong to a &amp;quot;zone&amp;quot;, and can also have order and state&lt;br /&gt;
* Now for mapping we should consider what information changes and what information is static, later is always candidate for material file&lt;br /&gt;
* For dynamic information we should try to reduce amount of fields we need&lt;br /&gt;
**  we need at least a field for card, so its one&lt;br /&gt;
**  we need to know what zone cards belong to, its 2&lt;br /&gt;
**  and we have possibly few other fields, if you look closely at you game you may find out that most of the zone only need one attribute at a time, i.e. draw pile always have cards face down, hand always face up, also for hand and discard order does not matter at all (but for draw it does matter). So in majority of cases we can get away with one single extra integer field representing state or order&lt;br /&gt;
* In real database both card and zone will be integers as primary keys referring to additional tables, but in our case its total overkill, so they can be strings as easily&lt;br /&gt;
&lt;br /&gt;
Variant 1: Minimalistic&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE TABLE IF NOT EXISTS `card` (&lt;br /&gt;
  `card_key` varchar(32) unsigned NOT NULL,&lt;br /&gt;
  `card_location` varchar(32) NOT NULL,&lt;br /&gt;
  `card_state` int(11) NOT NULL,&lt;br /&gt;
  PRIMARY KEY (`card_id`)&lt;br /&gt;
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Variant 2: More normalised&lt;br /&gt;
&lt;br /&gt;
This version supported by Deck php class, so unless you want to rewrite db access layer go with this one&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE TABLE IF NOT EXISTS `card` (&lt;br /&gt;
  `card_id` int(10) unsigned NOT NULL AUTO_INCREMENT,&lt;br /&gt;
  `card_type` varchar(16) NOT NULL,&lt;br /&gt;
  `card_type_arg` int(11) NOT NULL,&lt;br /&gt;
  `card_location` varchar(16) NOT NULL,&lt;br /&gt;
  `card_location_arg` int(11) NOT NULL,&lt;br /&gt;
  PRIMARY KEY (`card_id`)&lt;br /&gt;
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: if you using this schema, some zones/locations have special semantic. The &#039;hand&#039; location is actually multiple locations - one per player, but player id is encoded as card_location_arg. If &#039;hand&#039; in your game is ordered, visible or can have some other card states, you cannot use hand location (replacement is hand_&amp;lt;player_id&amp;gt; or hand_&amp;lt;color_id&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
== Code Organization ==&lt;br /&gt;
&lt;br /&gt;
=== Including your own JavaScript module ===&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, modules/ggg_other.js&lt;br /&gt;
&lt;br /&gt;
* Create ggg_other.js in modules/ folder and sync&lt;br /&gt;
* Modify ggg.js to include it&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  define([ &amp;quot;dojo&amp;quot;, &amp;quot;dojo/_base/declare&amp;quot;, &amp;quot;ebg/core/gamegui&amp;quot;, &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
    // load my own module!!!&lt;br /&gt;
    g_gamethemeurl + &amp;quot;modules/ggg_other.js&amp;quot; ], function(dojo,&lt;br /&gt;
        declare) {&lt;br /&gt;
&lt;br /&gt;
=== Including your own JavaScript module (II) ===&lt;br /&gt;
&lt;br /&gt;
* Create ggg_other.js in modules/ folder and sync&lt;br /&gt;
&lt;br /&gt;
  define([], function () {&lt;br /&gt;
    return &amp;quot;value&amp;quot;;&lt;br /&gt;
  });&lt;br /&gt;
&lt;br /&gt;
* Modify ggg.js to include it&lt;br /&gt;
&lt;br /&gt;
  define([ &lt;br /&gt;
    &amp;quot;dojo&amp;quot;, &lt;br /&gt;
    &amp;quot;dojo/_base/declare&amp;quot;, &lt;br /&gt;
    &amp;quot;bgagame/modules/ggg_other&amp;quot;, &lt;br /&gt;
    &amp;quot;ebg/core/gamegui&amp;quot;, &lt;br /&gt;
    &amp;quot;ebg/counter&amp;quot;&lt;br /&gt;
  ], function(dojo, declare, other) {&lt;br /&gt;
  &lt;br /&gt;
  });&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
This is maybe a little bit more the idea of the AMD Loader than the first option, although the first option should work as well.&lt;br /&gt;
&lt;br /&gt;
A little explanation to this:&lt;br /&gt;
The define function loads all the modules listed in the array and calls the following function with these loaded modules as parameters.&lt;br /&gt;
By putting your module at the third position in the array it is passed as the third parameter to the function. Be aware that the modules are resolved by position only, not by name. So you can load the module &#039;&#039;&#039;ggg_other&#039;&#039;&#039; and pass it as a parameter with the name &#039;&#039;&#039;other&#039;&#039;&#039;. &#039;&#039;&#039;gamegui&#039;&#039;&#039; and &#039;&#039;&#039;counter&#039;&#039;&#039; are passed in as well, but when the parameters are not defined they are just skipped. Because these modules put their content into the global scope it does not matter and you can use them from there.&lt;br /&gt;
&lt;br /&gt;
In the example above the string &amp;quot;value&amp;quot; is passed for the parameter &#039;&#039;&#039;other&#039;&#039;&#039;, but the function in your module can return whatever you want. It can be an object, an array, something you declared with dojo.declare, you can return even functions. &lt;br /&gt;
Your module can load other modules. Just put them in the array at the beginning and pass them as parameters to your function.&lt;br /&gt;
The advantage of passing the values as parameter is that you do not need to put these values in the global scope, so they can&#039;t be collisions with values defined in other scripts or the BGA Framework.&lt;br /&gt;
&lt;br /&gt;
The dojo toolkit provides good documentation to all of its components, the complete documentation for the AMD-Loader is here:&lt;br /&gt;
https://dojotoolkit.org/documentation/tutorials/1.10/modules/index.html It should be still correct, even as it seems to be only for version 1.10&lt;br /&gt;
&lt;br /&gt;
=== Including your own PHP module ===&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.game.php, modules/ggg_other.php&lt;br /&gt;
&lt;br /&gt;
* Create ggg_other.php in modules/ folder and sync&lt;br /&gt;
* Modify ggg.game.php to include it&lt;br /&gt;
&lt;br /&gt;
 require_once (&#039;modules/ggg_other.php&#039;);&lt;br /&gt;
&lt;br /&gt;
=== Creating a test class to run PHP locally ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.game.php, stubs&lt;br /&gt;
For this you need stubs of other method you can use this for example&lt;br /&gt;
https://github.com/elaskavaia/bga-sharedcode/raw/master/misc/module/table/table.game.php&lt;br /&gt;
&lt;br /&gt;
Create another php files, i.e ggg_test.php&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
define(&amp;quot;APP_GAMEMODULE_PATH&amp;quot;, &amp;quot;misc/&amp;quot;); // include path to stubs, which defines &amp;quot;table.game.php&amp;quot; and other classes&lt;br /&gt;
require_once (&#039;eminentdomaine.game.php&#039;);&lt;br /&gt;
&lt;br /&gt;
class MyGameTest1 extends MyGame { // this is your game class defined in ggg.game.php&lt;br /&gt;
    function __construct() {&lt;br /&gt;
        parent::__construct();&lt;br /&gt;
        include &#039;../material.inc.php&#039;;// this is how this normally included, from constructor&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // override/stub methods here that access db and stuff&lt;br /&gt;
    function getGameStateValue($var) {&lt;br /&gt;
        if ($var == &#039;round&#039;)&lt;br /&gt;
            return 3;&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
$x = new MyGameTest1(); // instantiate your class&lt;br /&gt;
$p = $x-&amp;gt;getGameProgression(); // call one of the methods to test&lt;br /&gt;
if ($p != 50)&lt;br /&gt;
    echo &amp;quot;Test1: FAILED&amp;quot;;&lt;br /&gt;
else&lt;br /&gt;
    echo &amp;quot;Test1: PASSED&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Run from command line like&lt;br /&gt;
 php7 ggg_test.php&lt;br /&gt;
&lt;br /&gt;
If you do it this way - you can also use local php debugger (i.e. integrated with IDE or command line).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Avoiding code in dojo declare style ===&lt;br /&gt;
Dojo class declarations are rather bizzare and do not work with most IDEs.&lt;br /&gt;
If you want to write in plain JS with classes, you can stub all the dojo define/declare stuff&lt;br /&gt;
and hook your class into that, so the classes are outside of this mess.&lt;br /&gt;
&lt;br /&gt;
NOTE: this technique is for experienced developers, do not try it if you do not understand&lt;br /&gt;
the consequences.&lt;br /&gt;
&lt;br /&gt;
This is complete example of game .js class&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  // Testla is game name is has to be changed&lt;br /&gt;
class Testla {&lt;br /&gt;
	constructor(game) {&lt;br /&gt;
		console.log(&#039;game constructor&#039;);&lt;br /&gt;
		this.game = game;&lt;br /&gt;
		this.varfoo = new MyFoo(); // this example of class from custom module&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	setup(gamedatas) {&lt;br /&gt;
		console.log(&amp;quot;Starting game setup&amp;quot;, this.varfoo);&lt;br /&gt;
		this.gamedatas = gamedatas;&lt;br /&gt;
		this.dojo.create(&amp;quot;div&amp;quot;, { class: &#039;whiteblock&#039;, innerHTML: _(&amp;quot;hello&amp;quot;) }, &#039;thething&#039;);&lt;br /&gt;
		console.log(&amp;quot;Ending game setup&amp;quot;);&lt;br /&gt;
	};&lt;br /&gt;
	onEnteringState(stateName, args) {&lt;br /&gt;
		console.log(&#039;onEnteringState : &#039; + stateName, args);&lt;br /&gt;
		this.game.addActionButton(&#039;b1&#039;,_(&#039;Click Me&#039;), (e)=&amp;gt;this.onButtonClick(e));&lt;br /&gt;
	};&lt;br /&gt;
	onLeavingState(stateName) {&lt;br /&gt;
		console.log(&#039;onLeavingState : &#039; + stateName, args);&lt;br /&gt;
	};&lt;br /&gt;
	onUpdateActionButtons(stateName, args) {&lt;br /&gt;
		console.log(&#039;onUpdateActionButtons : &#039; + stateName, args);&lt;br /&gt;
	};&lt;br /&gt;
	onButtonClick(event) {&lt;br /&gt;
		console.log(&#039;onButtonClick&#039;,event);&lt;br /&gt;
	};&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&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;
	g_gamethemeurl + &#039;/modules/foo.js&#039; // custom module if needed&lt;br /&gt;
],&lt;br /&gt;
	function(dojo, declare) {&lt;br /&gt;
                // testla is game name is has to be changed&lt;br /&gt;
		return declare(&amp;quot;bgagame.testla&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
			constructor: function() {&lt;br /&gt;
				this.xapp = new Testla(this);&lt;br /&gt;
				this.xapp.dojo = dojo;&lt;br /&gt;
			},&lt;br /&gt;
			setup: function(gamedatas) {&lt;br /&gt;
				this.xapp.setup(gamedatas);&lt;br /&gt;
			},&lt;br /&gt;
			onEnteringState: function(stateName, args) {&lt;br /&gt;
				this.xapp.onEnteringState(stateName, args.args);&lt;br /&gt;
			},&lt;br /&gt;
			onLeavingState: function(stateName) {&lt;br /&gt;
				this.xapp.onLeavingState(stateName, args);&lt;br /&gt;
			},&lt;br /&gt;
			onUpdateActionButtons: function(stateName, args) {&lt;br /&gt;
				this.xapp.onUpdateActionButtons(stateName, args);&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;
=== More readable JS: onEnteringState ===&lt;br /&gt;
&lt;br /&gt;
If you have a lot of states onEnteringState and friends become rather wild, you can do this trick to call some method dynamically.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
     onEnteringState: function(stateName, args) {&lt;br /&gt;
       console.log(&#039;Entering state: &#039; + stateName, args);&lt;br /&gt;
&lt;br /&gt;
       // Call appropriate method&lt;br /&gt;
       var methodName = &amp;quot;onEnteringState_&amp;quot; + stateName;&lt;br /&gt;
       if (this[methodName] !== undefined) {             &lt;br /&gt;
          console.log(&#039;Calling &#039; + methodName, args.args);&lt;br /&gt;
          this[methodName](args.args);&lt;br /&gt;
       }&lt;br /&gt;
     },&lt;br /&gt;
&lt;br /&gt;
     onEnteringState_playerTurn: function(args) { // this is args directly, not args.args &lt;br /&gt;
         // process&lt;br /&gt;
     },&lt;br /&gt;
&lt;br /&gt;
     onEnteringState_playerSomethingElse: function(args) { &lt;br /&gt;
         // process&lt;br /&gt;
     },&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: since its ignores the undefined functions you don&#039;t have define function for each state, but on the other hand you cannot make typos.&lt;br /&gt;
Same applies to onUpdateActionButtons except you pass &#039;args&#039; to method, not args.args, and for onLeavingState where you don&#039;t pass anything.&lt;br /&gt;
&lt;br /&gt;
=== Frameworks and Preprocessors ===&lt;br /&gt;
&lt;br /&gt;
* [[Using Vue]] - work-in-progress guide on using the modern framework Vue.js to create a game&lt;br /&gt;
* [[Using Typescript and Scss]] - How to auto-build Typescript and SCSS files to make your code cleaner&lt;br /&gt;
&lt;br /&gt;
== Assorted Stuff ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Out-of-turn actions: Un-pass ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, ggg.game.php, ggg.action.php, states.inc.php&lt;br /&gt;
&lt;br /&gt;
In multiplayer game sometimes players passes but than they think more and want to un-Pass and redo their choice. &lt;br /&gt;
To re-active a player who passes some trickery required.&lt;br /&gt;
&lt;br /&gt;
Define a special action that does that and hook it up.&lt;br /&gt;
&lt;br /&gt;
In states.inc.php add an action to mmultipleactiveplayer state to &amp;quot;unpass&amp;quot;, lets call it &amp;quot;actionCancel&amp;quot;&lt;br /&gt;
&lt;br /&gt;
In ggg.action.php add action hook&lt;br /&gt;
    public function actionCancel() {&lt;br /&gt;
        self::setAjaxMode();&lt;br /&gt;
        $this-&amp;gt;game-&amp;gt;actionCancel();&lt;br /&gt;
        self::ajaxResponse();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
In ggg.game.php add action handler&lt;br /&gt;
    function actionCancel() {&lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;checkPossibleAction(&#039;actionCancel&#039;);&lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;setPlayersMultiactive(array ($this-&amp;gt;getCurrentPlayerId() ), &#039;error&#039;, false);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
Finally to call this in client ggg.js you would do something like:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 onUpdateActionButtons:  function(stateName, args) {&lt;br /&gt;
   if (this.isCurrentPlayerActive()) { &lt;br /&gt;
     // ...&lt;br /&gt;
   } else if (!this.isSpectator) { // player is NOT active but not spectator&lt;br /&gt;
       switch (stateName) {&lt;br /&gt;
          case &#039;playerTurnMuliPlayerState&#039;:&lt;br /&gt;
		this.addActionButton(&#039;button_unpass&#039;, _(&#039;Oh no!&#039;), &#039;onUnpass&#039;);&lt;br /&gt;
		break;&lt;br /&gt;
	}&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
				&lt;br /&gt;
 onUnpass: function(e) {&lt;br /&gt;
    this.ajaxcall(&amp;quot;/&amp;quot; + this.game_name + &amp;quot;/&amp;quot; +  this.game_name + &amp;quot;/actionCancel.html&amp;quot;, {}, this); // no checkAction!&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Although be careful that if the turn comes back to the player while he is about to click cancel, the action buttons will be updated and the player will misclick which can be quite frustrating. To avoid this, move the cancel button to another position, like to the left of pagemaintitletext:&lt;br /&gt;
  dojo.place(&#039;button_unpass&#039;, &#039;pagemaintitletext&#039;, &#039;before&#039;);&lt;br /&gt;
Being out of the generalactions div, it won&#039;t be automatically destroyed like normal buttons, so you&#039;ll have to handle that yourself in onLeavingState. You might also want to change the button color to red (blue buttons for active player only, red buttons also for inactive players?)&lt;br /&gt;
&lt;br /&gt;
Note: same technique can be used to do other out-of-turn actions, such as re-arranging cards in hand, exchanging resources, etc (i.e. if permitted by rules, such as &amp;quot;at any time player can...&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
=== Multi Step Interactions: Select Worker/Place Worker - Using Selection ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
Simple way to implement something like that without extra states is to use &amp;quot;selection&amp;quot; mechanism. When user click on worker add some sort of class into that element i.e. &#039;selected&#039; (which also have to have some indication by css i.e. outline).&lt;br /&gt;
&lt;br /&gt;
Than user can click on placement zone, you can use dojo.query for &amp;quot;selected&amp;quot; element and use it along with zone id to send data to server. If proper worker is not selected yet can give a error message using this.showMessage(...) function.&lt;br /&gt;
&lt;br /&gt;
Extra code required to properly cleanup selection between states.&lt;br /&gt;
Also when you do that sometimes you want to change the state prompt, see below &#039;Change state prompt&#039;&lt;br /&gt;
&lt;br /&gt;
=== Multi Step Interactions: Select Worker/Place Worker - Using Client States ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
I don&#039;t think its documented feature but there is a way to do client-only states, which is absolutely wonderful for few reasons&lt;br /&gt;
* When player interaction is two step process, such as select worker, place worker, or place worker, pick one of two resources of your choice&lt;br /&gt;
* When multi-step process can result of impossible situation and has to be undone (by rules)&lt;br /&gt;
* When multi-step process is triggered from multiple states (such as you can do same thing as activated card action, pass action or main action)&lt;br /&gt;
&lt;br /&gt;
So lets do Select Worker/Place Worker&lt;br /&gt;
&lt;br /&gt;
Define your server state as usual, i.e. playerMainTurn -&amp;gt; &amp;quot;You must pick up a worker&amp;quot;.&lt;br /&gt;
Now define a client state, we only need &amp;quot;name&amp;quot; and &amp;quot;descriptionmyturn&amp;quot;, lets say &amp;quot;client_playerPicksLocation&amp;quot;. Always prefix names of client state with &amp;quot;client_&amp;quot; to avoid confusion. Now we have to do the following:&lt;br /&gt;
* Have a handler for onUpdateActionButtons for playerMainTurn to activate all possible workers he can pick&lt;br /&gt;
* When player clicks workers, remember the worker in one of the members of the main class, I usually use one called this.clientStateArgs.&lt;br /&gt;
* Transition to new client state&lt;br /&gt;
  onWorker: function(e) {&lt;br /&gt;
      var id = event.currentTarget.id;&lt;br /&gt;
      dojo.stopEvent(event);&lt;br /&gt;
      ... // do validity checks&lt;br /&gt;
      this.clientStateArgs.worker_id = id;&lt;br /&gt;
      this.setClientState(&amp;quot;client_playerPicksLocation&amp;quot;, {&lt;br /&gt;
                                descriptionmyturn : _(&amp;quot;${you} must select location&amp;quot;),&lt;br /&gt;
                            });&lt;br /&gt;
   }&lt;br /&gt;
* Have a handler for onUpdateActionButtons for client_playerPicksLocation to activate all possible locations this worker can go AND add Cancel button (see below)&lt;br /&gt;
* Have a location handler which will eventually send a server request, using stored this.clientStateArgs.worker_id as worker id&lt;br /&gt;
* The cancel button should call a method to restore server state, also if you doing it for more than one state you can add this universally using this.on_client_state check&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        if (this.isCurrentPlayerActive()) {&lt;br /&gt;
          if (this.on_client_state &amp;amp;&amp;amp; !$(&#039;button_cancel&#039;)) {&lt;br /&gt;
               this.addActionButton(&#039;button_cancel&#039;, _(&#039;Cancel&#039;), dojo.hitch(this, function() {&lt;br /&gt;
                                             this.restoreServerGameState();&lt;br /&gt;
               }));&lt;br /&gt;
          }&lt;br /&gt;
        } &lt;br /&gt;
Note: usually I call my own function call this.cancelLocalStateEffects() which will do more stuff first then call restoreServerGameState(), same function is usually needs to be called when server request has failed (i.e. invalid move)&lt;br /&gt;
&lt;br /&gt;
Note: If you need more than 2 steps, you may have to do client side animation to reflect the new state, which gets trickier because you have to undo that also on cancellation.&lt;br /&gt;
&lt;br /&gt;
Code is available here [https://github.com/elaskavaia/bga-sharedcode/blob/master/sharedcode.js sharedcode.js] (its using playerTurnPlayCubes and client_selectCubeLocation).&lt;br /&gt;
&lt;br /&gt;
=== Action Stack - Using Client States ===&lt;br /&gt;
&lt;br /&gt;
Action stack required where game is very complex and use triggered effects that can &amp;quot;stack&amp;quot;. It not always actual stack, it can be queue or random access&lt;br /&gt;
Examples:&lt;br /&gt;
* Magic the Gathering - classic card game where effects go on Stack, that allows to counter spell and counter spell of counter spell (not on bga - it just example of mechanics)&lt;br /&gt;
* Ultimate Railroads - action taking game where effects can be executed in any order&lt;br /&gt;
* Lewis and Clark - card game where actions executed as queue&lt;br /&gt;
&lt;br /&gt;
There is two ways of implementing it - on the server or the client.&lt;br /&gt;
For the server see article below.&lt;br /&gt;
The requirement for client side stack is all action can be undone, which means&lt;br /&gt;
* No dice rolls&lt;br /&gt;
* No card drawn&lt;br /&gt;
* No other players interaction&lt;br /&gt;
&lt;br /&gt;
No snippets are here, as this will be too complex but basically flow is:&lt;br /&gt;
* You have a action/effect stack (queue/list) as js object attached to &amp;quot;this&amp;quot;, i.e. this.unprocessed_actions&lt;br /&gt;
* When player plays a card, worker, etc, you read the effect of that card from the material file (client copy), and place into stack&lt;br /&gt;
* Then we call dispatch method which pulls the next action from the stack and change client state accordinly,i.e.  this.setClientState(&amp;quot;client_playerGainsCubes&amp;quot;)&lt;br /&gt;
* When players acts on it - the action is removed from the stack and added to &amp;quot;server action arguments&amp;quot; list, this is another object which be used to send ajax call, i.e. this.clientStateArgs&lt;br /&gt;
* If nothing left in stack we can submit the ajax call assembling parameters from collected arguments (that can include action name)&lt;br /&gt;
* This method allows cheap undo - by restoring server state you will wipe out all user actions (but if you need intermediate aninmation you have to handle it yourself)&lt;br /&gt;
&lt;br /&gt;
Code can be found in Ultimate Railroads game (but it is random access list - so it a bit complex) and Lewis and Clark (complexity - use can always deny part of any effect)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Action Stack - Using Server States ===&lt;br /&gt;
&lt;br /&gt;
See definition of Action Stack above.&lt;br /&gt;
&lt;br /&gt;
To implement you usually need another db table that has the following fields: index of effect - which is used for sorted access, type - which is essense of the effect (i.e. collect resource), some extra arguments (i.e. resource type and resource count), and usually owner of the effect (i.e. player id)&lt;br /&gt;
The flow is:&lt;br /&gt;
* There is some initial player state, where player can play card for example&lt;br /&gt;
* Player main action - pushes the card effect on stack, which also can cause triggered effects which also go on stack&lt;br /&gt;
* After action processing is finished switch to game state which is &amp;quot;dispatcher&amp;quot;&lt;br /&gt;
* Gispatcher pulls the top effect (whatever definition of the top is), changes the active player and changes the state to appropriate player state to collect response&lt;br /&gt;
* Player state knows about the stack and pulls arguments (argX) from the effect arguments of the db&lt;br /&gt;
* Player action should clear up the top effect, and can possibly add more effects, then switch to &amp;quot;dispatcher&amp;quot; state again&lt;br /&gt;
* If stack is empty, dispatcher can either pick next player itself or use another game state which responsible for picking next player&lt;br /&gt;
&lt;br /&gt;
Code can be found in Tapestry.&lt;br /&gt;
&lt;br /&gt;
=== Changing state prompt ===&lt;br /&gt;
&lt;br /&gt;
State prompt is message displayed for player which usually comes from state description.&lt;br /&gt;
Sometimes you want to change it without changing state (one way is change state but locally, see client states above).&lt;br /&gt;
&lt;br /&gt;
Simple way just change the html&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        setMainTitle: function(text) {&lt;br /&gt;
            $(&#039;pagemaintitletext&#039;).innerHTML = text;&lt;br /&gt;
        },&lt;br /&gt;
         // usage&lt;br /&gt;
        onMeeple: function(event) {&lt;br /&gt;
              //... &lt;br /&gt;
              this.setMainTitle(_(&#039;You must select where meeple is going&#039;));&lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This however will not work with parameters and will not draw You in color, if you want this its more sophisticated:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        setDescriptionOnMyTurn : function(text) {&lt;br /&gt;
            this.gamedatas.gamestate.descriptionmyturn = text;&lt;br /&gt;
            var tpl = dojo.clone(this.gamedatas.gamestate.args);&lt;br /&gt;
            if (tpl === null) {&lt;br /&gt;
                tpl = {};&lt;br /&gt;
            }&lt;br /&gt;
            var title = &amp;quot;&amp;quot;;&lt;br /&gt;
            if (this.isCurrentPlayerActive() &amp;amp;&amp;amp; text !== null) {&lt;br /&gt;
                tpl.you = this.divYou(); &lt;br /&gt;
            }&lt;br /&gt;
            title = this.format_string_recursive(text, tpl);&lt;br /&gt;
&lt;br /&gt;
            if (!title) {&lt;br /&gt;
                this.setMainTitle(&amp;quot;&amp;amp;nbsp;&amp;quot;);&lt;br /&gt;
            } else {&lt;br /&gt;
                this.setMainTitle(title);&lt;br /&gt;
            }&lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: this method uses &#039;&#039;&#039;setMainTitle&#039;&#039;&#039; defined above and &#039;&#039;&#039;divYou&#039;&#039;&#039; defined in another section of this wiki.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Adding Image buttons ===&lt;br /&gt;
&lt;br /&gt;
Its pretty trivial but just in case you need a working function:&lt;br /&gt;
&lt;br /&gt;
ggg.js:&lt;br /&gt;
&lt;br /&gt;
                addImageActionButton: function (id, div_html, handler) { // div_html is string not node&lt;br /&gt;
                    this.addActionButton(id, div_html, handler, &#039;&#039;, false, &#039;gray&#039;); &lt;br /&gt;
                    dojo.style(id, &amp;quot;border&amp;quot;, &amp;quot;none&amp;quot;); // remove ugly border&lt;br /&gt;
                    dojo.addClass(id, &amp;quot;bgaimagebutton&amp;quot;); // add css class to do more styling&lt;br /&gt;
                    return $(id); // return node for chaining&lt;br /&gt;
                },&lt;br /&gt;
&lt;br /&gt;
Example of usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    this.addImageActionButton(&#039;button_coin&#039;,&amp;quot;&amp;lt;div class=&#039;coin&#039;&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;, ()=&amp;gt;{ alert(&#039;Ha!&#039;); });&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Assigning Player Order ===&lt;br /&gt;
Normally when game starts there is &amp;quot;natural&amp;quot; player order assigned randomly.&lt;br /&gt;
&lt;br /&gt;
If you want to deliberatly assign player order at the start of the game (for example, in a game with teams options), you can do so by retrieving the initialization-only player attribute &#039;&#039;&#039;player_table_order&#039;&#039;&#039; and using it to assign values to &#039;&#039;&#039;player_no&#039;&#039;&#039; (which is normally assigned at the start of a game in the order in which players come to the table). (See [https://en.doc.boardgamearena.com/Game_database_model:_dbmodel.sql#The_player_table Game database model] for more details.)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Example:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                // Retrieve inital player order ([0=&amp;gt;playerId1, 1=&amp;gt;playerId2, ...])&lt;br /&gt;
		$playerInitialOrder = [];&lt;br /&gt;
		foreach ($players as $playerId =&amp;gt; $player) {&lt;br /&gt;
			$playerInitialOrder[$player[&#039;player_table_order&#039;]] = $playerId;&lt;br /&gt;
		}&lt;br /&gt;
		ksort($playerInitialOrder);&lt;br /&gt;
		$playerInitialOrder = array_flip(array_values($playerInitialOrder));&lt;br /&gt;
&lt;br /&gt;
		// Player order based on &#039;playerTeams&#039; option&lt;br /&gt;
		$playerOrder = [0, 1, 2, 3];&lt;br /&gt;
		switch (self::getGameStateValue(&#039;playerTeams&#039;)) {&lt;br /&gt;
			case self::TEAM_1_2:&lt;br /&gt;
				$playerOrder = [0, 2, 1, 3];&lt;br /&gt;
				break;&lt;br /&gt;
			case self::TEAM_1_4:&lt;br /&gt;
				$playerOrder = [0, 1, 3, 2];&lt;br /&gt;
				break;&lt;br /&gt;
			case self::TEAM_RANDOM:&lt;br /&gt;
				shuffle($playerOrder);&lt;br /&gt;
				break;&lt;br /&gt;
			default:&lt;br /&gt;
			case self::TEAM_1_3:&lt;br /&gt;
				// Default order&lt;br /&gt;
				break;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
                // Create players&lt;br /&gt;
		// Note: if you added some extra field on &amp;quot;player&amp;quot; table in the database (dbmodel.sql), you can initialize it there.&lt;br /&gt;
		$sql =&lt;br /&gt;
			&#039;INSERT INTO player (player_id, player_color, player_canal, player_name, player_avatar, player_no) VALUES &#039;;&lt;br /&gt;
		$values = [];&lt;br /&gt;
&lt;br /&gt;
		foreach ($players as $playerId =&amp;gt; $player) {&lt;br /&gt;
			$color = array_shift($default_colors);&lt;br /&gt;
			$values[] =&lt;br /&gt;
				&amp;quot;(&#039;&amp;quot; .&lt;br /&gt;
				$playerId .&lt;br /&gt;
				&amp;quot;&#039;,&#039;$color&#039;,&#039;&amp;quot; .&lt;br /&gt;
				$player[&#039;player_canal&#039;] .&lt;br /&gt;
				&amp;quot;&#039;,&#039;&amp;quot; .&lt;br /&gt;
				addslashes($player[&#039;player_name&#039;]) .&lt;br /&gt;
				&amp;quot;&#039;,&#039;&amp;quot; .&lt;br /&gt;
				addslashes($player[&#039;player_avatar&#039;]) .&lt;br /&gt;
				&amp;quot;&#039;,&#039;&amp;quot; .&lt;br /&gt;
				$playerOrder[$playerInitialOrder[$playerId]] .&lt;br /&gt;
				&amp;quot;&#039;)&amp;quot;;&lt;br /&gt;
		}&lt;br /&gt;
		$sql .= implode(&#039;,&#039;, $values);&lt;br /&gt;
		self::DbQuery($sql);&lt;br /&gt;
		self::reattributeColorsBasedOnPreferences(&lt;br /&gt;
			$players,&lt;br /&gt;
			$gameinfos[&#039;player_colors&#039;]&lt;br /&gt;
		);&lt;br /&gt;
		self::reloadPlayersBasicInfos();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Send different notifications to active player vs everybody else ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
Hack alert. This is a hack. We were hoping for proper solution by bga framework.&lt;br /&gt;
&lt;br /&gt;
This will allow you to send notification with two message one for specific player and one for everybody else including spectators.&lt;br /&gt;
Note that this does not split the data - all data must be shared.&lt;br /&gt;
&lt;br /&gt;
Add this to .js file (if you already overriding it merge obviously)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/** @Override */&lt;br /&gt;
format_string_recursive: function(log, args) {&lt;br /&gt;
   if (typeof args.log_others != &#039;undefined&#039; &amp;amp;&amp;amp; typeof args.player_id != &#039;undefined&#039; &amp;amp;&amp;amp; this.player_id != args.player_id)&lt;br /&gt;
	log = args.log_others;&lt;br /&gt;
   return this.inherited(arguments); // you must call this to call super &lt;br /&gt;
},&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example of usage (from eminentdomain)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    $this-&amp;gt;notifyAllPlayers(&#039;tokenMoved&#039;, &lt;br /&gt;
             clienttranslate(&#039;${player_name} adds +2 Colonies to ${place_name}&#039;), // notification with show for player with player_id&lt;br /&gt;
             [&#039;player_id&#039;=&amp;gt;$player_id, // this is mandatory&lt;br /&gt;
             &#039;log_others&#039;=&amp;gt;clienttranslate(&#039;${player_name} adds +2 Colonies to an unknown planet&#039;), // notification will show for others&lt;br /&gt;
              ...&lt;br /&gt;
             ]);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Send transient notifications without incrementing move ID ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.php&lt;br /&gt;
&lt;br /&gt;
Hack alert. This is a hack.&lt;br /&gt;
&lt;br /&gt;
Use this if you need to send some transient notification that should not create a new move ID. The notification should be idempotent -- it should have no practical effect on the game state and would be &#039;&#039;&#039;safe to drop&#039;&#039;&#039; (e.g., it would not matter if a player never received this notification). For example, in a co-op game you want all players to see a real-time preview of some action, before the active player commits their turn.&lt;br /&gt;
&lt;br /&gt;
Doing this mainly affects the instant replay &amp;amp; archive modes. During replay, the BGA framework automatically inserts a 1.5-second pause between each &amp;quot;move&amp;quot;. With this hack, your transient notifications are not considered to be a &amp;quot;move&amp;quot;, so no pause gets added.&lt;br /&gt;
&lt;br /&gt;
; In ggg.php&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$this-&amp;gt;not_a_move_notification = true; // note: do not increase the move counter&lt;br /&gt;
$this-&amp;gt;notifyAllPlayers(&#039;cardsPreview&#039;, &#039;&#039;, $args);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: you cannot have code that send notification or even changes state after this, and you cannot reset this variable back either because it only takes effect when you exit action handling function&lt;br /&gt;
&lt;br /&gt;
=== Ajax Call wrapper ===&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
The current ajaxcall is super vebose and prone to errors, I suggest using a helper function. It does a lot of stuff you must do anyways.&lt;br /&gt;
Most beginner mistakes come from missing part of this code (which is understandstandable - this is a huge snippet to clone every time).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	ajaxcallwrapper: function(action, args, handler) {&lt;br /&gt;
		if (!args) args = []; // this allows to skip args parameter for action which do not require them&lt;br /&gt;
			&lt;br /&gt;
		args.lock = true; // this allows to avoid rapid action clicking which can cause race condition on server&lt;br /&gt;
		if (this.checkAction(action)) { // this does all the proper check that player is active and action is declared&lt;br /&gt;
			this.ajaxcall(&amp;quot;/&amp;quot; + this.game_name + &amp;quot;/&amp;quot; + this.game_name + &amp;quot;/&amp;quot; + action + &amp;quot;.html&amp;quot;, args, // this is mandatory fluff &lt;br /&gt;
				this, (result) =&amp;gt; { },  // success result handler is empty - it is never needed&lt;br /&gt;
                                               handler); // this is real result handler - it called both on success and error, it has optional param  &amp;quot;is_error&amp;quot; - you rarely need it&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   this.ajaxcallwrapper(&#039;pass&#039;); // no args&lt;br /&gt;
   this.ajaxcallwrapper(&#039;playCard&#039;, {card: card_id}); // with args&lt;br /&gt;
   this.ajaxcallwrapper(&#039;playCard&#039;, {card: card_id}, (is_error)=&amp;gt;{if (!is_error) dojo.query(&amp;quot;.selected&amp;quot;).removeClass(&#039;selected&#039;);}) // with handler that cleans up &#039;selected&#039; class on success&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: this always will lock interface and always check for action, you can modify this method to do it optionally, i.e&lt;br /&gt;
  if (args.lock!==false) args.lock = true; else delete args.lock; // it does not work with false value - it has to be removed&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Studio]]&lt;/div&gt;</summary>
		<author><name>SwHawk</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=BGA_Studio_Cookbook&amp;diff=14213</id>
		<title>BGA Studio Cookbook</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=BGA_Studio_Cookbook&amp;diff=14213"/>
		<updated>2022-07-31T15:50:34Z</updated>

		<summary type="html">&lt;p&gt;SwHawk: /* Second way: rely on the :formatFunction option provided by dojo.string.substitute */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
This page is collection of design and implementation recipes for BGA Studio framework.&lt;br /&gt;
For tooling and usage recipes see [[Tools and tips of BGA Studio]].&lt;br /&gt;
If you have your own recipes feel free to edit this page.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Visual Effects, Layout and Animation ==&lt;br /&gt;
&lt;br /&gt;
=== DOM manipulatons ===&lt;br /&gt;
&lt;br /&gt;
==== Create pieces dynamically (using template) ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg_ggg.tpl, ggg.js&lt;br /&gt;
&lt;br /&gt;
Note: this method is recommended by BGA guildlines&lt;br /&gt;
&lt;br /&gt;
Declared js template with variables in .tpl file, like this&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;
    // Javascript HTML templates&lt;br /&gt;
    var jstpl_ipiece = &#039;&amp;lt;div class=&amp;quot;${type} ${type}_${color} inlineblock&amp;quot; aria-label=&amp;quot;${name}&amp;quot; title=&amp;quot;${name}&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use it like this in .js file&lt;br /&gt;
  div = this.format_block(&#039;jstpl_ipiece&#039;, {&lt;br /&gt;
                                type : &#039;meeple&#039;,&lt;br /&gt;
                                color : &#039;ff0000&#039;,&lt;br /&gt;
                                name : &#039;Bob&#039;,&lt;br /&gt;
                            });&lt;br /&gt;
  &lt;br /&gt;
Then you do whatever you need to do with that div, this one specifically design to go to log entries, because it has embedded title (otherwise its a picture only) and no id.&lt;br /&gt;
&lt;br /&gt;
Note: you could have place this variable in js itself, but keeping it in .tpl allows you to have your js code be free of HTML. Normally it never happens but&lt;br /&gt;
it is good to strive for it.&lt;br /&gt;
Note: you can also use string concatenation, its less readable. You can also use dojo dom object creation api&#039;s but its brutally verbose and its more unreadable.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Create pieces dynamically (using string concatenation) ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
Note: Not recommended&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  div = &amp;quot;&amp;lt;div class=&#039;meeple &amp;quot;+color+&amp;quot;&#039;&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
==== Create all pieces statically ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg_ggg.tpl, ggg.css, ggg.view.php (optional) &lt;br /&gt;
&lt;br /&gt;
* Create ALL game pieces in html template (.tpl)&lt;br /&gt;
* ALL pieces should have unique id, and it should be meaningful, i.e. meeple_red_1&lt;br /&gt;
* Do not use inline styling&lt;br /&gt;
* Id of player&#039;s specific pieces should use some sort of &#039;color&#039; identification, since player id cannot be used in static layout, you can use english color name, hex 6 char value, or color &amp;quot;number&amp;quot; (1,2,3...)&lt;br /&gt;
* Pieces should have separated class for its color, type, etc, so it can be easily styled in groups. In example below you now can style all meeples, all red meeples or all red tokens, or all &amp;quot;first&amp;quot; meeples&lt;br /&gt;
&lt;br /&gt;
ggg.tpl:&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
  &amp;lt;div id=&amp;quot;home_red&amp;quot; class=&amp;quot;home_red home&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;div id=&amp;quot;meeple_red_1&amp;quot; class=&amp;quot;meeple red n1&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
     &amp;lt;div id=&amp;quot;meeple_red_2&amp;quot; class=&amp;quot;meeple red n2&amp;quot;&amp;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;
ggg.css:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.meeple {&lt;br /&gt;
	width: 32px;&lt;br /&gt;
	height: 39px;&lt;br /&gt;
	background-image: url(img/78_64_stand_meeples.png);&lt;br /&gt;
	background-size: 352px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.meeple.red {&lt;br /&gt;
	background-position: 30% 0%;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* There should be straight forward mapping between server id and js id (or 1:1)&lt;br /&gt;
* You place objects in different zones of the layout, and setup css to take care of layout&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.home .meeple{&lt;br /&gt;
   display: inline-block;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* If you need to have a temporary object that look like original you can use dojo.clone (and change id to some temp id)&lt;br /&gt;
* If there is lots of repetition or zone grid you can use template generator, but inject style declaration in css instead of inline style for flexibility&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
* If you use this model you cannot use premade js components such as Stock and Zone&lt;br /&gt;
* You have to use alternative methods of animation (slightly altered) since default method will leave object with inline style attributes which you don&#039;t need&lt;br /&gt;
&lt;br /&gt;
=== Logs ===&lt;br /&gt;
&lt;br /&gt;
==== Inject icon images in the log ====&lt;br /&gt;
&lt;br /&gt;
Here is an example of what was done for Terra Mystica which is simple and straightforward:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
//Define the proper message&lt;br /&gt;
		$message = clienttranslate(&#039;${player_name} gets ${power_income} via Structures&#039;);&lt;br /&gt;
		if ($price &amp;gt; 0) {&lt;br /&gt;
			self::DbQuery(&amp;quot;UPDATE player SET player_score = player_score - $price WHERE player_id = $player_id&amp;quot;);&lt;br /&gt;
			$message = clienttranslate(&#039;${player_name} pays ${vp_price} and gets ${power_income} via Structures&#039;);&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
// Notify&lt;br /&gt;
		self::notifyAllPlayers( &amp;quot;powerViaStructures&amp;quot;, $message, array(&lt;br /&gt;
			&#039;i18n&#039; =&amp;gt; array( ),&lt;br /&gt;
			&#039;player_id&#039; =&amp;gt; $player_id,&lt;br /&gt;
			&#039;player_name&#039; =&amp;gt; self::getUniqueValueFromDb( &amp;quot;SELECT player_name FROM player WHERE player_id = $player_id&amp;quot; ),&lt;br /&gt;
			&#039;power_tokens&#039; =&amp;gt; $power_tokens,&lt;br /&gt;
			&#039;vp_price&#039; =&amp;gt; self::getLogsVPAmount($price),&lt;br /&gt;
			&#039;power_income&#039; =&amp;gt; self::getLogsPowerAmount($power_income),&lt;br /&gt;
			&#039;newScore&#039; =&amp;gt; self::getUniqueValueFromDb( &amp;quot;SELECT player_score FROM player WHERE player_id = $player_id&amp;quot; ),&lt;br /&gt;
			&#039;counters&#039; =&amp;gt; $this-&amp;gt;getGameCounters(null),&lt;br /&gt;
		) );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With some functions to have the needed html added inside the substitution variable, such as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function getLogsPowerAmount( $amount ) {&lt;br /&gt;
		return &amp;quot;&amp;lt;div class=&#039;tmlogs_icon&#039; title=&#039;Power&#039;&amp;gt;&amp;lt;div class=&#039;power_amount&#039;&amp;gt;$amount&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: injecting html from php is not ideal but easy, if you want more clean solution, use method below but it is a lot more sophisticated.&lt;br /&gt;
&lt;br /&gt;
==== Inject images and styled html in the log ====&lt;br /&gt;
&lt;br /&gt;
So you want nice pictures in the game log. What do you do? The first idea that comes to mind is to send html from php in notifications (see method above). &lt;br /&gt;
&lt;br /&gt;
This is a bad idea for many reasons:&lt;br /&gt;
&lt;br /&gt;
* It&#039;s bad architecture. ui elements leak into the server, and now you have to manage the ui in multiple places.&lt;br /&gt;
* If you decided to change something in the ui in future version, replay logs for old games and tutorials may not work, since they use stored notifications.&lt;br /&gt;
* Log previews for old games become unreadable. (This is the log state before you enter the game replay, which is useful for troubleshooting and game analysis.)&lt;br /&gt;
* It&#039;s more data to transfer and store in the db.&lt;br /&gt;
* It&#039;s a nightmare for translators.&lt;br /&gt;
&lt;br /&gt;
So what else can you do? You can use client side log injection to intercept log arguments (which come from the server) and replace them with html on the client side. Here are three different method you can use to achieve this.&lt;br /&gt;
&lt;br /&gt;
===== First way : Override &amp;lt;code&amp;gt;this.format_string_recursive()&amp;lt;/code&amp;gt; method =====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, ggg.game.php&lt;br /&gt;
&lt;br /&gt;
I use this recipe for &#039;&#039;&#039;client side log injection&#039;&#039;&#039; to intercept log arguments (which come from the server) and replace them with html on the client side.&lt;br /&gt;
&lt;br /&gt;
[[File:clientloginjection.png|left]] &lt;br /&gt;
&lt;br /&gt;
ggg.js&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
        /** Override this function to inject html into log items. This is a built-in BGA method.  */&lt;br /&gt;
&lt;br /&gt;
        /* @Override */&lt;br /&gt;
        format_string_recursive : function format_string_recursive(log, args) {&lt;br /&gt;
            try {&lt;br /&gt;
                if (log &amp;amp;&amp;amp; args &amp;amp;&amp;amp; !args.processed) {&lt;br /&gt;
                    args.processed = true;&lt;br /&gt;
                    &lt;br /&gt;
&lt;br /&gt;
                    // list of special keys we want to replace with images&lt;br /&gt;
                    var keys = [&#039;place_name&#039;,&#039;token_name&#039;];&lt;br /&gt;
                    &lt;br /&gt;
                  &lt;br /&gt;
                    for ( var i in keys) {&lt;br /&gt;
                        var key = keys[i];&lt;br /&gt;
                        key in args &amp;amp;&amp;amp; args[key] = this.getTokenDiv(key, args);                            &lt;br /&gt;
&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            } catch (e) {&lt;br /&gt;
                console.error(log,args,&amp;quot;Exception thrown&amp;quot;, e.stack);&lt;br /&gt;
            }&lt;br /&gt;
            return this.inherited({callee: format_string_recursive}, arguments);&lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important:&#039;&#039;&#039; In the &#039;&#039;format_string_recursive&#039;&#039; method, the &#039;args&#039; parameter will only contain arguments passed to it from the notify method in ggg.game.php (see below).&lt;br /&gt;
&lt;br /&gt;
The &#039;log&#039; parameter is the actual string that is inserted into the logs. You can perform additional js string manipulation on it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        getTokenDiv : function(key, args) {&lt;br /&gt;
            // ... implement whatever html you want here, example from sharedcode.js&lt;br /&gt;
            var token_id = args[key];&lt;br /&gt;
            var item_type = getPart(token_id,0);&lt;br /&gt;
            var logid = &amp;quot;log&amp;quot; + (this.globalid++) + &amp;quot;_&amp;quot; + token_id;&lt;br /&gt;
            switch (item_type) {&lt;br /&gt;
                case &#039;wcube&#039;:&lt;br /&gt;
                    var tokenDiv = this.format_block(&#039;jstpl_resource_log&#039;, {&lt;br /&gt;
                        &amp;quot;id&amp;quot; : logid,&lt;br /&gt;
                        &amp;quot;type&amp;quot; : &amp;quot;wcube&amp;quot;,&lt;br /&gt;
                        &amp;quot;color&amp;quot; : getPart(token_id,1),&lt;br /&gt;
                    });&lt;br /&gt;
                    return tokenDiv;&lt;br /&gt;
             &lt;br /&gt;
                case &#039;meeple&#039;:&lt;br /&gt;
                    if ($(token_id)) {&lt;br /&gt;
                        var clone = dojo.clone($(token_id));&lt;br /&gt;
    &lt;br /&gt;
                        dojo.attr(clone, &amp;quot;id&amp;quot;, logid);&lt;br /&gt;
                        this.stripPosition(clone);&lt;br /&gt;
                        dojo.addClass(clone, &amp;quot;logitem&amp;quot;);&lt;br /&gt;
                        return clone.outerHTML;&lt;br /&gt;
                    }&lt;br /&gt;
                    break;&lt;br /&gt;
     &lt;br /&gt;
                default:&lt;br /&gt;
                    break;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            return &amp;quot;&#039;&amp;quot; + this.clienttranslate_string(this.getTokenName(token_id)) + &amp;quot;&#039;&amp;quot;;&lt;br /&gt;
       },&lt;br /&gt;
       getTokenName : function(key) {&lt;br /&gt;
           return this.gamedatas.token_types[key].name; // get name for the key, from static table for example&lt;br /&gt;
       },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that in this case the server simply injects token_id as a name, and the client substitutes it for the translated name or the picture.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ggg.game.php:&lt;br /&gt;
&lt;br /&gt;
           $this-&amp;gt;notifyAllPlayers(&#039;playerLog&#039;,clienttranslate(&#039;Game moves ${token_name}&#039;),[&#039;token_name&#039;=&amp;gt;$token_id]);&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important:&#039;&#039;&#039; As noted above, only arguments actually passed by this method are available to the args parameter received in the client-side &#039;&#039;format_string_recursive&#039;&#039; method.&lt;br /&gt;
&lt;br /&gt;
Sometimes it is the case that you want to pass arguments that are not actually included in the output message. For example, suppose we have a method like this:&lt;br /&gt;
&lt;br /&gt;
           $this-&amp;gt;notifyAllPlayers(&#039;tokenPlaced&#039;,clienttranslate(&#039;Player placed ${token_name}&#039;),array(&lt;br /&gt;
              &#039;token_name&#039; =&amp;gt; $token_id,&lt;br /&gt;
              &#039;zone_played&#039; =&amp;gt; $zone);&lt;br /&gt;
&lt;br /&gt;
This will output &amp;quot;Player placed ${token_name}&amp;quot; in the log, and if we subscribe to a notification method activated by the &amp;quot;tokenPlaced&amp;quot; event in the client-side code, that method can make use of the &#039;zone_played&#039; argument. &lt;br /&gt;
&lt;br /&gt;
Now if you want to make some really cool things with game log, most probably you would need more arguments than are included in log message. The problem with that,&lt;br /&gt;
it will work at first, but if you reload game using F5 or when the game loads in turn based mode, you will loose your additional parameters, why? Because when game reloads it does not actually send same notifications, it sends special &amp;quot;hitstorical_log&amp;quot; notification where all  parameters not listed in the message are removed. In example above, field zone_played would be removed from historical log as it is not included in message of the notification. You can till preserve specific arguments in historical log by adding special field preserve to notification arguments like this:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
           $this-&amp;gt;notifyAllPlayers(&#039;tokenPlaced&#039;,clienttranslate(&#039;Player placed ${token_name}&#039;),array(&lt;br /&gt;
              &#039;token_name&#039; =&amp;gt; $token_id,&lt;br /&gt;
              &#039;zone_played&#039; =&amp;gt; $zone,&lt;br /&gt;
              &#039;preserve&#039; =&amp;gt; [ &#039;zone_played&#039; ]&lt;br /&gt;
           );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now you can use zone_played in format_string_recursive even in historical logs.&lt;br /&gt;
&lt;br /&gt;
===== Second way: rely on the &amp;lt;code&amp;gt;:formatFunction&amp;lt;/code&amp;gt; option provided by &amp;lt;code&amp;gt;dojo.string.substitute&amp;lt;/code&amp;gt; =====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, ggg.game.php, ggg_ggg.tpl, ggg.css&lt;br /&gt;
&lt;br /&gt;
The above method will work in most of the cases, but if you use dotted keys such as &amp;lt;code&amp;gt;${card.name}&amp;lt;/code&amp;gt; (which is supported by the framework, for private state args), the key won&#039;t be substituted because the &amp;lt;code&amp;gt;key in arg&amp;lt;/code&amp;gt; test will fail. If so you need to rely either on this way, or the one after.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;WARNING:&#039;&#039;&#039; using this method on an already advanced project will require you to go through all your notifications to change keys !&lt;br /&gt;
&lt;br /&gt;
Under the hood, the &#039;&#039;&#039;this.format_string_recursive()&#039;&#039;&#039; function calls the &#039;&#039;&#039;dojo.string.substitute&#039;&#039;&#039; method which substitutes &amp;lt;code&amp;gt;${keys}&amp;lt;/code&amp;gt; with the value provided. If you take a look at the [https://dojotoolkit.org/reference-guide/1.7/dojo/string.html#substitute documentation] and [https://github.com/dojo/dojo/blob/c3ceb017cfa25b703f5662dc83d1c8aae9bc5d81/string.js#L163 source code] you can notice that the key can be suffixed with a colon (&amp;lt;code&amp;gt;:&amp;lt;/code&amp;gt;) followed by a function name. This will allow you to specify directly in the substitution string which keys need HTML injection.&lt;br /&gt;
&lt;br /&gt;
First of all, you need to define your formatting function in the ggg.js file:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[[ggg.js]]&lt;br /&gt;
        getTokenDiv : function(value, key) {&lt;br /&gt;
            //This is only an example implementation, you need to write your own.&lt;br /&gt;
            //The method should return HTML code&lt;br /&gt;
            switch (key) {&lt;br /&gt;
                case &#039;html_injected_argument1&#039;:&lt;br /&gt;
                    return this.format_block(&#039;jstpl_HTMLLogElement1&#039;,{value: value});&lt;br /&gt;
                case &#039;html_injected_argument2&#039;:&lt;br /&gt;
                    return this.format_block(&#039;jstpl_HTMLLogElement2&#039;,{value: value});&lt;br /&gt;
                ...&lt;br /&gt;
            }&lt;br /&gt;
       }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Obviously you need to define the appropriate templates in the ggg_ggg.tpl file:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[[ggg_ggg.tpl]]&lt;br /&gt;
let jstpl_HTMLLogElement1 = &#039;&amp;lt;div class=&amp;quot;log-element log-element-1-${value}&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
let jstpl_HTMLLogElement2 = &#039;&amp;lt;div class=&amp;quot;log-element log-element-2-${value}&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
And the appropriate classes in ggg.css.&lt;br /&gt;
&lt;br /&gt;
Then you need to add the &amp;lt;code&amp;gt;dojo/aspect&amp;lt;/code&amp;gt; module at the top of the ggg.js file:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[ggg.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 define([&lt;br /&gt;
     &amp;quot;dojo&amp;quot;, &amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&amp;quot;dojo/aspect&amp;quot;,&amp;lt;/span&amp;gt;                 //MUST BE IN THIRD POSITION&#039;&#039;&#039; (see [[#Including your own JavaScript module (II)|below]])&lt;br /&gt;
     &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
 ], function (dojo, declare, &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&#039;&#039;&#039;aspect&#039;&#039;&#039;&amp;lt;/span&amp;gt;) {&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
And you also need to add the following code in your &amp;lt;code&amp;gt;contructor&amp;lt;/code&amp;gt; method in the ggg.js:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[ggg.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
         constructor: function(){&lt;br /&gt;
             console.log(&#039;progressevolutiontechnologyswh constructor&#039;);&lt;br /&gt;
               &lt;br /&gt;
             // Here, you can init the global variables of your user interface&lt;br /&gt;
             // Example:&lt;br /&gt;
             // this.myGlobalValue = 0;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&#039;&#039;&#039;let gameObject = this;&#039;&#039;&#039;            //Needed as the this object in aspect.before will not refer to the game object in which the formatting function resides&lt;br /&gt;
             &#039;&#039;&#039;aspect.before(dojo.string, &amp;quot;substitute&amp;quot;, function(template, map, transform) {&#039;&#039;&#039;      //This allows you to modify the arguments of the dojo.string.substitute method before they&#039;re actually passed to it&lt;br /&gt;
                 &#039;&#039;&#039;return [template, map, transform, gameObject];&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now you&#039;re all set to inject HTML in your logs.&lt;br /&gt;
&lt;br /&gt;
===== Third way: rely on the &amp;lt;code&amp;gt;transform&amp;lt;/code&amp;gt; argument of &amp;lt;code&amp;gt;dojo.string.substitute&amp;lt;/code&amp;gt; =====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, ggg.game.php, ggg_ggg.tpl, ggg.css&lt;br /&gt;
&lt;br /&gt;
This method is also relying on the use of &amp;lt;code&amp;gt;dojo.string.substitute&amp;lt;/code&amp;gt; by the framework, and will use the &amp;lt;code&amp;gt;transform&amp;lt;/code&amp;gt; argument, which, accordting to [https://github.com/dojo/dojo/blob/c3ceb017cfa25b703f5662dc83d1c8aae9bc5d81/string.js#L163 source code] and [https://dojotoolkit.org/reference-guide/1.7/dojo/string.html#substitute documentation] will be run on all the messages going through dojo.string.substitute.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;WARNING:&#039;&#039;&#039; As this method will be applied to all strings that go through dojo.string.substitute. As such you must take extra care not to substitute keys that may be used by the framework (i.e. ${id}). In order to do so, a good practise would be to prefix all keys that need substitution with a trigram of the game name.&lt;br /&gt;
&lt;br /&gt;
Since all the keys will be fed to the tranform function, by default, it must return the value, substituted or not per your needs. You can define the function like this in the ggg.js file:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[ggg.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
         getTokenDiv : function(value, key) {&lt;br /&gt;
             //This is only an example implementation, you need to write your own.&lt;br /&gt;
             //The method should return HTML code&lt;br /&gt;
             switch (key) {&lt;br /&gt;
                 case &#039;html_injected_argument1&#039;:&lt;br /&gt;
                     return this.format_block(&#039;jstpl_HTMLLogElement1&#039;,{value: value});&lt;br /&gt;
                 case &#039;html_injected_argument2&#039;:&lt;br /&gt;
                     return this.format_block(&#039;jstpl_HTMLLogElement2&#039;,{value: value});&lt;br /&gt;
                 ...&lt;br /&gt;
                 &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&#039;&#039;&#039;default:&#039;&#039;&#039;&lt;br /&gt;
                     &#039;&#039;&#039;return value;&#039;&#039;&#039;&amp;lt;/span&amp;gt;                  &#039;&#039;&#039;//Needed otherwise regular strings won&#039;t appear since since the value isn&#039;t returned by the function&#039;&#039;&#039;&lt;br /&gt;
             }&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
The templates must be defined in the ggg_ggg.tpl file and the corresponding CSS classes in the ggg.css file.&lt;br /&gt;
&lt;br /&gt;
You need to add the following code at the beginning of the ggg.js file:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[ggg.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 define([&lt;br /&gt;
     &amp;quot;dojo&amp;quot;, &amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&amp;quot;dojo/aspect&amp;quot;,&amp;lt;/span&amp;gt;                 //MUST BE IN THIRD POSITION&#039;&#039;&#039; (see [[#Including your own JavaScript module (II)|below]])&lt;br /&gt;
     &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
 ], function (dojo, declare, &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&#039;&#039;&#039;aspect&#039;&#039;&#039;&amp;lt;/span&amp;gt;) {&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
And the following code to the &amp;lt;code&amp;gt;constructor&amp;lt;/code&amp;gt; method in ggg.js:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[[ggg.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
         constructor: function(){&lt;br /&gt;
             console.log(&#039;progressevolutiontechnologyswh constructor&#039;);&lt;br /&gt;
               &lt;br /&gt;
             // Here, you can init the global variables of your user interface&lt;br /&gt;
             // Example:&lt;br /&gt;
             // this.myGlobalValue = 0;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&#039;&#039;&#039;let transformFunction = dojo.hitch(this, &amp;quot;getTokenDiv&amp;quot;);&#039;&#039;&#039;            //Needed as the this object in aspect.before will not refer to the game object in which the formatting function resides&lt;br /&gt;
             &#039;&#039;&#039;aspect.before(dojo.string, &amp;quot;substitute&amp;quot;, function(template, map, transform) {&#039;&#039;&#039;&lt;br /&gt;
                 &#039;&#039;&#039;if (undefined === transform) {&#039;&#039;&#039;                                   //Check for a transform function presence, just in case&lt;br /&gt;
                     &#039;&#039;&#039;return [template, map, transform];&#039;&#039;&#039;&lt;br /&gt;
                 &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Processing logs on re-loading ====&lt;br /&gt;
&lt;br /&gt;
You rarely need to process logs when reloading, but if you want to do something fancy you may have to do it after logs are loaded. &lt;br /&gt;
Logs are loaded asyncronously so you have to listen for logs to be fully loaded.&lt;br /&gt;
Unfortunately there is no direct way of doing it so this is the hack.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Hack alert&#039;&#039;&#039; - this extends undocumented function and may be broken when framework is updated&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
			/*&lt;br /&gt;
  			* [Undocumented] Override BGA framework functions to call onLoadingLogsComplete when loading is done&lt;br /&gt;
                        @Override&lt;br /&gt;
   			*/&lt;br /&gt;
			setLoader: function(image_progress, logs_progress) {&lt;br /&gt;
				this.inherited(arguments); // required, this is &amp;quot;super()&amp;quot; call, do not remove&lt;br /&gt;
				//console.log(&amp;quot;loader&amp;quot;, image_progress, logs_progress)&lt;br /&gt;
				if (!this.isLoadingLogsComplete &amp;amp;&amp;amp; logs_progress &amp;gt;= 100) {&lt;br /&gt;
					this.isLoadingLogsComplete = true; // this is to prevent from calling this more then once&lt;br /&gt;
					this.onLoadingLogsComplete();&lt;br /&gt;
				}&lt;br /&gt;
			},&lt;br /&gt;
&lt;br /&gt;
			onLoadingLogsComplete: function() {&lt;br /&gt;
				console.log(&#039;Loading logs complete&#039;);&lt;br /&gt;
				// do something here&lt;br /&gt;
			},&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Player Panel ===&lt;br /&gt;
&lt;br /&gt;
==== Inserting non-player panel ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, ggg_ggg.tpl&lt;br /&gt;
&lt;br /&gt;
If you want to insert non-player panel on the right side (for example to hold extra preferences, zooming controls, etc)&lt;br /&gt;
&lt;br /&gt;
this can go pretty much anywhere in template it will be moved later&lt;br /&gt;
&lt;br /&gt;
ggg_ggg.tpl:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	&amp;lt;div class=&#039;player_board_config&#039; id=&amp;quot;player_board_config&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;!-- here is whatever you want, buttons just example --&amp;gt;&lt;br /&gt;
		&amp;lt;button id=&amp;quot;zoom-out&amp;quot; class=&amp;quot; fa fa-search-minus fa-2x config-control&amp;quot;&amp;gt;&amp;lt;/button&amp;gt;&lt;br /&gt;
		&amp;lt;button id=&amp;quot;zoom-in&amp;quot; class=&amp;quot; fa fa-search-plus fa-2x config-control&amp;quot;&amp;gt;&amp;lt;/button&amp;gt;&lt;br /&gt;
		&amp;lt;button id=&amp;quot;show-settings&amp;quot; class=&amp;quot;fa fa-cog fa-2x config-control &amp;quot;&amp;gt;&amp;lt;/button&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
some hackery required in js&lt;br /&gt;
&lt;br /&gt;
ggg.js:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* @Override */&lt;br /&gt;
	updatePlayerOrdering() {&lt;br /&gt;
		this.inherited(arguments);&lt;br /&gt;
		dojo.place(&#039;player_board_config&#039;, &#039;player_boards&#039;, &#039;first&#039;);&lt;br /&gt;
	},&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Images and Icons ===&lt;br /&gt;
&lt;br /&gt;
==== Accessing images from js ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
     // your game resources&lt;br /&gt;
     &lt;br /&gt;
     var my_img = &#039;&amp;lt;img src=&amp;quot;&#039;+g_gamethemeurl+&#039;img/cards.jpg&amp;quot;/&amp;gt;&#039;;&lt;br /&gt;
     &lt;br /&gt;
     // shared resources&lt;br /&gt;
     var my_help_img = &amp;quot;&amp;lt;img class=&#039;imgtext&#039; src=&#039;&amp;quot; + g_themeurl + &amp;quot;img/layout/help_click.png&#039; alt=&#039;action&#039; /&amp;gt; &amp;lt;span class=&#039;tooltiptext&#039;&amp;gt;&amp;quot; +&lt;br /&gt;
                    text + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== High-Definition Graphics ====&lt;br /&gt;
&lt;br /&gt;
Some users will have screens which can display text and images at a greater resolution than the usual 72 dpi, e.g. the &amp;quot;Retina&amp;quot; screens on the 5k iMac, all iPads, and high-DPI screens on laptops from many manufacturers. If you can get art assets at this size, they will make your game look extra beautiful. You &#039;&#039;could&#039;&#039; just use large graphics and scale them down, but that would increase the download time and bandwidth for users who can&#039;t display them. Instead, a good way is to prepare a separate graphics file at exactly twice the size you would use otherwise, and add &amp;quot;@2x&amp;quot; at the end of the filename, e.g. if pieces.png is 240x320, then pieces@2x.png is 480x640.&lt;br /&gt;
&lt;br /&gt;
There are two changes required in order to use the separate graphics files. First in your css, where you use a file, add a media query which overrides the original definition and uses the bigger version on devices which can display them. Ensuring that the &amp;quot;background-size&amp;quot; attribute is set means that the size of the displayed object doesn&#039;t change, but only is drawn at the improved dot pitch.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.piece {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    background-image: url(&#039;img/pieces.png&#039;);&lt;br /&gt;
    background-size:240px 320px;&lt;br /&gt;
    z-index: 10;&lt;br /&gt;
}&lt;br /&gt;
@media (-webkit-min-device-pixel-ratio: 2), (min-device-pixel-ratio: 2), (min-resolution: 192dpi)&lt;br /&gt;
{&lt;br /&gt;
    .piece {&lt;br /&gt;
        background-image: url(&#039;img/pieces@2x.png&#039;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Secondly, in your setup function in javascript, you must ensure than only the appropriate one version of the file gets pre-loaded (otherwise you more than waste the bandwidth saved by maintaining the standard-resolution file). Note that the media query is the same in both cases:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
            var isRetina = &amp;quot;(-webkit-min-device-pixel-ratio: 2), (min-device-pixel-ratio: 2), (min-resolution: 192dpi)&amp;quot;;&lt;br /&gt;
            if (window.matchMedia(isRetina).matches)&lt;br /&gt;
            {&lt;br /&gt;
                this.dontPreloadImage( &#039;pieces.png&#039; );&lt;br /&gt;
                this.dontPreloadImage( &#039;board.jpg&#039; );&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                this.dontPreloadImage( &#039;pieces@2x.png&#039; );&lt;br /&gt;
                this.dontPreloadImage( &#039;board@2x.jpg&#039; );&lt;br /&gt;
            }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using CSS to create different colors of game pieces if you have only white piece ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
background-color: #${color}; &lt;br /&gt;
background-blend-mode: multiply;&lt;br /&gt;
background-image: url( &#039;img/mypiece.png&#039;);&lt;br /&gt;
mask: url(&#039;img/mypiece.png&#039;);&lt;br /&gt;
-webkit-mask: url(&#039;img/mypiece.png&#039;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where ${color} - is color you want&lt;br /&gt;
&lt;br /&gt;
Note: piece has to be white (shades of gray). Sprite can be used too, just add add blackground-position as usuall.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Other Fluff ===&lt;br /&gt;
&lt;br /&gt;
==== Use thematic fonts ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.css&lt;br /&gt;
&lt;br /&gt;
Sometime game elements use specific fonts of text, if you want to match it up you can load some specific font (IMPORTANT: from some &#039;&#039;&#039;free font&#039;&#039;&#039; source. See notes below).&lt;br /&gt;
&lt;br /&gt;
[[File:Dragonline_font.png]]&lt;br /&gt;
&lt;br /&gt;
.css&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* latin-ext */&lt;br /&gt;
@font-face {&lt;br /&gt;
  font-family: &#039;Qwigley&#039;;&lt;br /&gt;
  font-style: normal;&lt;br /&gt;
  font-weight: 400;&lt;br /&gt;
  src: local(&#039;Qwigley&#039;), local(&#039;Qwigley-Regular&#039;), url(https://fonts.gstatic.com/s/qwigley/v6/2Dy1Unur1HJoklbsg4iPJ_Y6323mHUZFJMgTvxaG2iE.woff2) format(&#039;woff2&#039;);&lt;br /&gt;
  unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;&lt;br /&gt;
}&lt;br /&gt;
/* latin */&lt;br /&gt;
@font-face {&lt;br /&gt;
  font-family: &#039;Qwigley&#039;;&lt;br /&gt;
  font-style: normal;&lt;br /&gt;
  font-weight: normal;&lt;br /&gt;
  src: local(&#039;Qwigley&#039;), local(&#039;Qwigley-Regular&#039;), url(https://fonts.gstatic.com/s/qwigley/v6/gThgNuQB0o5ITpgpLi4Zpw.woff2) format(&#039;woff2&#039;);&lt;br /&gt;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;&lt;br /&gt;
}&lt;br /&gt;
@font-face {&lt;br /&gt;
  font-family: &#039;Qwigley&#039;;&lt;br /&gt;
  font-style: normal;&lt;br /&gt;
  font-weight: normal;&lt;br /&gt;
  src: local(&#039;Qwigley&#039;), local(&#039;Qwigley-Regular&#039;), url(http://ff.static.1001fonts.net/q/w/qwigley.regular.ttf) format(&#039;ttf&#039;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.zone_title {&lt;br /&gt;
	display: inline-block;&lt;br /&gt;
	position: absolute;&lt;br /&gt;
	font: italic 32px/32px &amp;quot;Qwigley&amp;quot;, cursive;	   &lt;br /&gt;
	height: 32px;&lt;br /&gt;
	width: auto;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NB:&#039;&#039;&#039; if you need to include a font that&#039;s not available online, an extra action will be needed from an admin. Please include the font file(s) in your img directory, and mention it to admins when requesting your game to be moved to alpha. &#039;&#039;&#039;Please remember that the font has to be free, and include a .txt with all appropriate license information about the font.&#039;&#039;&#039;&lt;br /&gt;
You can look for free fonts (for example) on https://fonts.google.com or https://www.fontsquirrel.com/)&lt;br /&gt;
&lt;br /&gt;
=== Use player color in template ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg_ggg.tpl, ggg.view.php&lt;br /&gt;
&lt;br /&gt;
.view.php:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    function build_page($viewArgs) {&lt;br /&gt;
        // Get players &amp;amp; players number&lt;br /&gt;
        $players = $this-&amp;gt;game-&amp;gt;loadPlayersBasicInfos();&lt;br /&gt;
        $players_nbr = count($players);&lt;br /&gt;
        /**&lt;br /&gt;
         * ********* Place your code below: ***********&lt;br /&gt;
         */&lt;br /&gt;
        &lt;br /&gt;
        // Set PCOLOR to the current player color hex&lt;br /&gt;
        global $g_user;&lt;br /&gt;
        $cplayer = $g_user-&amp;gt;get_id();&lt;br /&gt;
        if (array_key_exists($cplayer, $players)) { // may be not set if spectator&lt;br /&gt;
            $player_color = $players [$cplayer] [&#039;player_color&#039;];&lt;br /&gt;
        } else {&lt;br /&gt;
            $player_color = &#039;ffffff&#039;; // spectator&lt;br /&gt;
        }&lt;br /&gt;
        $this-&amp;gt;tpl [&#039;PCOLOR&#039;] = $player_color;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Scale to fit for big boards ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg_ggg.tpl, ggg.js&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Lets say you have huge game board, and lets say you want it to be 1400px wide. Besides the board there will be side bar which is 240 and trim. &lt;br /&gt;
My display is 1920 wide so it fits, but there is big chance other people won&#039;t have that width. What do you do?&lt;br /&gt;
&lt;br /&gt;
You have to decide:&lt;br /&gt;
* If board does not fit you want scale whole thing down, the best way is probably use viewport (see https://en.doc.boardgamearena.com/Your_game_mobile_version)&lt;br /&gt;
* You can leave the board as is and make sure it is scrollable horizonatally&lt;br /&gt;
* You add custom scale just for the board (can add user controls  - and hook to transform: scale())&lt;br /&gt;
&lt;br /&gt;
I tried to auto-scale but this just does work, too many variables - browser zoom, 3d mode, viewport, custom bga scaling, devicePixelRatio - all create some impossible coctail of zooming...&lt;br /&gt;
Here is scaling functing for custom user scaling&lt;br /&gt;
&lt;br /&gt;
ggg_ggg.tpl:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   &amp;lt;div id=&amp;quot;thething&amp;quot; class=&amp;quot;thething&amp;quot;&amp;gt;&lt;br /&gt;
            ... everything else you declare ...&lt;br /&gt;
   &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ggg.js:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    onZoomPlus: function() {&lt;br /&gt;
       this.my_zoom+=0.1;&lt;br /&gt;
       this.zoommy(&#039;thething&#039;,this.my_zoom);&lt;br /&gt;
    },&lt;br /&gt;
&lt;br /&gt;
    zoommy: function(node, zoom) {&lt;br /&gt;
                node=$(node);&lt;br /&gt;
		var width = 100 / zoom;&lt;br /&gt;
		node.style.transformOrigin = &amp;quot;0 0&amp;quot;;&lt;br /&gt;
		node.style.transform = &amp;quot;scale(&amp;quot; + zoom + &amp;quot;)&amp;quot;;&lt;br /&gt;
		node.style.width = width + &amp;quot;%&amp;quot;;&lt;br /&gt;
    },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Dynamic tooltips ===&lt;br /&gt;
&lt;br /&gt;
If you really need a dynamic tooltip you can use this technique. (Only use it if the static tooltips provided by the BGA framework are not sufficient.)&lt;br /&gt;
&lt;br /&gt;
            new dijit.Tooltip({&lt;br /&gt;
                connectId: [&amp;quot;divItemId&amp;quot;],&lt;br /&gt;
                getContent: function(matchedNode){&lt;br /&gt;
                    return &amp;quot;... calculated ...&amp;quot;; &lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is an out-of-the-box djit.Tooltip. It has a &#039;&#039;getContent&#039;&#039; method which is called dynamically.&lt;br /&gt;
&lt;br /&gt;
The string function return becomes the innerHTML of the tooltip, so it can be anything. In this example matchedNode is a dojo node representing dom object with id of &amp;quot;divItemId&amp;quot; but there are more parameters which I am not posting here which allows more sophisticated subnode queries (i.e. you can attach tooltip to all nodes with class or whatever).&lt;br /&gt;
&lt;br /&gt;
[https://dojotoolkit.org/reference-guide/1.10/dijit/Tooltip.html dijit.Tooltip]&lt;br /&gt;
&lt;br /&gt;
It&#039;s not part of the BGA API so use at your own risk.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Rendering text with players color and proper background ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
This example actually writes &amp;quot;You&amp;quot; but you can replace this with player name as easily, drop translating function in this case&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        /* Implementation of proper colored You with background in case of white or light colors  */&lt;br /&gt;
 &lt;br /&gt;
        divYou : function() {&lt;br /&gt;
            var color = this.gamedatas.players[this.player_id].color;&lt;br /&gt;
            var color_bg = &amp;quot;&amp;quot;;&lt;br /&gt;
            if (this.gamedatas.players[this.player_id] &amp;amp;&amp;amp; this.gamedatas.players[this.player_id].color_back) {&lt;br /&gt;
                color_bg = &amp;quot;background-color:#&amp;quot; + this.gamedatas.players[this.player_id].color_back + &amp;quot;;&amp;quot;;&lt;br /&gt;
            }&lt;br /&gt;
            var you = &amp;quot;&amp;lt;span style=\&amp;quot;font-weight:bold;color:#&amp;quot; + color + &amp;quot;;&amp;quot; + color_bg + &amp;quot;\&amp;quot;&amp;gt;&amp;quot; + __(&amp;quot;lang_mainsite&amp;quot;, &amp;quot;You&amp;quot;) + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
            return you;&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Cool realistic shadow effect with CSS ===&lt;br /&gt;
&lt;br /&gt;
==== Rectangles and circles ====&lt;br /&gt;
&lt;br /&gt;
It is often nice to have a drop shadow around tiles and tokens, to separate them from the table visually. It is very easy to add a shadow to rectangular elements, just add this to your css:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.xxx-tile {&lt;br /&gt;
    box-shadow: 3px 3px 3px #000000a0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
box-shadow obeys &#039;&#039;&#039;border-radius&#039;&#039;&#039; of the element, so it will look good for rounded rectangles, and hence also circles (if border-radius is set appropriately).&lt;br /&gt;
&lt;br /&gt;
box-shadow also supports various other parameters and can be used to achieve effects such as glowing, borders, inner shadows etc. If you need to animate a box-shadow, you may be able to get better performance (avoiding redraws) if you attach the shadow to another element (possibly an ::after pseudo-element) and change only the &#039;&#039;&#039;opacity&#039;&#039;&#039; of that element.&lt;br /&gt;
&lt;br /&gt;
==== Irregular Shapes ====&lt;br /&gt;
&lt;br /&gt;
If you wish to make a shadow effect for game pieces that are not a rectangle, but your game pieces are drawn from rectangles in a PNG image, you can apply the shadow to the piece using any art package and save it inside the image. This usually will yield the best performance. Remember to account for the size of the shadow when you lay out images in the sprite sheet.&lt;br /&gt;
&lt;br /&gt;
However that sometimes will not be an option, for example if the image needs to be rotated while the shadow remains offset in the same direction. In this case, one option is to not use box-shadow but use filter, which is supported by recent major browsers.  This way, you can use the alpha channel of your element to drop a shadow.  This even work for transparent backgrounds, so that if you are using the &amp;quot;CSS-sprite&amp;quot; method, it will work!&lt;br /&gt;
&lt;br /&gt;
For instance:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.xxx-token {&lt;br /&gt;
    filter: drop-shadow(0px 0px 1px #000000);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beware that some browsers still do not always draw drop-shadow correctly. In particular, Safari frequently leaves bits of shadow behind when objects move around the screen. In Chrome, shadows sometimes flicker badly if another element is animating close by. Some of these correctness issues can be solved by adding &#039;&#039;&#039;isolation: isolate; will-change: filter;&#039;&#039;&#039; to affected elements, but this significantly affects redraw performance.&lt;br /&gt;
&lt;br /&gt;
Beware of performance issues - particularly on Safari (MacOS, iPhone and iPad). Keep in mind that drop-shadow are very GPU intensive. This becomes noticeable once you have about 40 components with drop-shadow filter. If that is your case, you can quite easily implement a user preference to disable shadows for users on slower machines:&lt;br /&gt;
&lt;br /&gt;
gameoptions.inc.php&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
100 =&amp;gt; array(&lt;br /&gt;
			&#039;name&#039; =&amp;gt; totranslate(&#039;Shadows&#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;Enabled&#039; ), &#039;cssPref&#039; =&amp;gt; &#039;&#039; ),&lt;br /&gt;
					2 =&amp;gt; array( &#039;name&#039; =&amp;gt; totranslate( &#039;Disabled&#039; ), &#039;cssPref&#039; =&amp;gt; &#039;no-shadow&#039; )&lt;br /&gt;
			)&lt;br /&gt;
	),&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[game].css&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.no-shadow * {&lt;br /&gt;
	filter: none !important; &lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Shadows with clip-path ====&lt;br /&gt;
&lt;br /&gt;
For some reason, a shadow will not work together with clip-path on one element. To use both clip-path (when for example using .svg to cut out cardboard components from your .jpg spritesheet) and drop-shadow, you need to wrap the element into another one, and apply drop-shadow to the outer one, and clip-path to the inner one.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;div class=&#039;my-token-wrap&#039;&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&#039;my-token&#039;&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;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.my-token-wrap {&lt;br /&gt;
    filter: drop-shadow(0px 0px 1px #000000);&lt;br /&gt;
}&lt;br /&gt;
.my-token-wrap .my-token {&lt;br /&gt;
    clip-path: url(#my-token-path);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Using the CSS classes from the state machine ===&lt;br /&gt;
&lt;br /&gt;
If you need to hide or show stuff depending on the state of your game, you can of course use javascript, but CSS is hand enough for that.  The #overall-content element does change class depending on the game state.  For instance, if you are in state &#039;&#039;playerTurn&#039;&#039;, it will have the class &#039;&#039;gamestate_playerTurn&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
So now, if you want to show the discard pile only during player turns, you may use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#discard_pile { display: none }&lt;br /&gt;
.gamestate_playerTurn #discard_pile { display: block }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This can be used if you want to change sizing of elements, position, layout or visual appearance.&lt;br /&gt;
&lt;br /&gt;
== Game Model and Database design ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Database for The euro game ===&lt;br /&gt;
Lets say we have a game with workers, dice, tokens, board, resources, money and vp. Workers and dice can be placed in various zones on the board, and you can get resources, money, tokens and vp in your home zone. Also tokens can be flipped or not flipped.&lt;br /&gt;
&lt;br /&gt;
[[File:Madeira board.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now lets try to map it, we have&lt;br /&gt;
* (meeple,zone)&lt;br /&gt;
* (die, zone, sideup)&lt;br /&gt;
* (resource cube/money token/vp token,player home zone)&lt;br /&gt;
* (token, player home zone, flip state)&lt;br /&gt;
We can notice that resource and money are uncountable, and don&#039;t need to be track individually so we can replace our mapping to&lt;br /&gt;
* (resource type/money,player home zone, count)&lt;br /&gt;
And vp stored already for us in player table, so we can remove it from that list.&lt;br /&gt;
&lt;br /&gt;
Now when we get to encode it we can see that everything can be encoded as (object,zone,state) form, where object and zone is string and state is integer. The resource mapping is slightly different semantically so you can go with two table, or counting using same table with state been used as count for resources.&lt;br /&gt;
&lt;br /&gt;
So the piece mapping for non-grid based games can be in most case represented by (string: token_key, string: token_location, int: token_state), example of such database schema can be found here: [https://github.com/elaskavaia/bga-sharedcode/blob/master/dbmodel.sql dbmodel.sql] and class implementing access to it here [https://github.com/elaskavaia/bga-sharedcode/blob/master/modules/tokens.php table.game.php].&lt;br /&gt;
&lt;br /&gt;
Variant 1: Minimalistic&lt;br /&gt;
&lt;br /&gt;
 CREATE TABLE IF NOT EXISTS `token` (&lt;br /&gt;
  `token_key` varchar(32) NOT NULL,&lt;br /&gt;
  `token_location` varchar(32) NOT NULL,&lt;br /&gt;
  `token_state` int(10),&lt;br /&gt;
  PRIMARY KEY (`token_key`)&lt;br /&gt;
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+token&lt;br /&gt;
! token_key&lt;br /&gt;
! token_location&lt;br /&gt;
! token_state&lt;br /&gt;
|-&lt;br /&gt;
|meeple_red_1&lt;br /&gt;
|home_red&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
|dice_black_2&lt;br /&gt;
|board_guard&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
|dice_green_1&lt;br /&gt;
|board_action_mayor&lt;br /&gt;
|3&lt;br /&gt;
|-&lt;br /&gt;
|bread&lt;br /&gt;
|home_red&lt;br /&gt;
|5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Now how we represent resource counters such as bread?&lt;br /&gt;
Using same table from we simply add special counter token for bread and use state to indicate the count. Note to keep first column unique we have to add player identification for that counter, i.e. ff0000 is red player.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+token&lt;br /&gt;
! token_key&lt;br /&gt;
! token_location&lt;br /&gt;
! token_state&lt;br /&gt;
|-&lt;br /&gt;
|bread_ff0000&lt;br /&gt;
|tableau_ff0000&lt;br /&gt;
|5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See php module for this table here https://github.com/elaskavaia/bga-sharedcode/blob/master/modules/tokens.php&lt;br /&gt;
&lt;br /&gt;
Variant 2: Additional resource table, resource count for each player id&lt;br /&gt;
&lt;br /&gt;
 CREATE TABLE IF NOT EXISTS `resource` (&lt;br /&gt;
  `player_id` int(10) unsigned NOT NULL,&lt;br /&gt;
  `resource_key` varchar(32) NOT NULL,&lt;br /&gt;
  `resource_count` int(10) signed NOT NULL,&lt;br /&gt;
  PRIMARY KEY (`player_id`,`resource_key`)&lt;br /&gt;
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;&lt;br /&gt;
&lt;br /&gt;
 ALTER TABLE resource ADD CONSTRAINT fk_player_id FOREIGN KEY (player_id) REFERENCES player(player_id);&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+resource&lt;br /&gt;
! player_id&lt;br /&gt;
! resource_key&lt;br /&gt;
! resource_count&lt;br /&gt;
|-&lt;br /&gt;
|123456&lt;br /&gt;
|bread&lt;br /&gt;
|5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Variant 3: More normalised&lt;br /&gt;
&lt;br /&gt;
This version is similar to &amp;quot;card&amp;quot; table from hearts tutorial, you can also use exact cards database schema and Deck implementation for most purposes (even you not dealing with cards). &lt;br /&gt;
&lt;br /&gt;
 CREATE TABLE IF NOT EXISTS `token` (&lt;br /&gt;
  `token_id` int(10) unsigned NOT NULL AUTO_INCREMENT,&lt;br /&gt;
  `token_type` varchar(16) NOT NULL,&lt;br /&gt;
  `token_arg` int(11) NOT NULL,&lt;br /&gt;
  `token_location` varchar(32) NOT NULL,&lt;br /&gt;
  `token_state` int(10),&lt;br /&gt;
  PRIMARY KEY (`token_id`)&lt;br /&gt;
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+token&lt;br /&gt;
! token_id&lt;br /&gt;
! token_type&lt;br /&gt;
! token_arg&lt;br /&gt;
! token_location&lt;br /&gt;
! token_state&lt;br /&gt;
|-&lt;br /&gt;
|22&lt;br /&gt;
|meeple&lt;br /&gt;
|123456&lt;br /&gt;
|home_123456&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
|23&lt;br /&gt;
|dice&lt;br /&gt;
|2&lt;br /&gt;
|board_guard&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
|26&lt;br /&gt;
|dice&lt;br /&gt;
|1&lt;br /&gt;
|board_action_mayor&lt;br /&gt;
|3&lt;br /&gt;
|-&lt;br /&gt;
|49&lt;br /&gt;
|bread&lt;br /&gt;
|0&lt;br /&gt;
|home_123456&lt;br /&gt;
|5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Advantages of this would be is a bit more straightforward to do some queries in db, disadvantage its hard to read (as you can compare with previous example, you&lt;br /&gt;
cannot just look at say, ah I know what it means). Another questionable advantage is it allows you to do id randomisation, so it hard to do crafted queries to &lt;br /&gt;
cheat, the down side of that you cannot understand it either, and handcraft db states for debugging or testing.&lt;br /&gt;
&lt;br /&gt;
=== Database for The card game ===&lt;br /&gt;
&lt;br /&gt;
Lets say you have a standard card game, player have hidden cards in hand, you can draw card from draw deck, play card on tableau and discard to discard pile.&lt;br /&gt;
We have to design database for such game.&lt;br /&gt;
&lt;br /&gt;
In real word to &amp;quot;save&amp;quot; the game we take a picture a play area, save cards from it, then put away draw deck, discard and hand of each player separately and mark it, also we will record current scoring (if any) and who&#039;s turn was it.&lt;br /&gt;
&lt;br /&gt;
* Framework handles state machine transition, so you don&#039;t have to worry about database design for that (i.e. who&#039;s turn it is, what phase of the game we are at, you still have to design it but part of state machine step)&lt;br /&gt;
* Also framework supports basic player information, color, order around the table, basic scoring, etc, so you don&#039;t have to worry about it either&lt;br /&gt;
* The only thing you need in our database is state of the &amp;quot;board&amp;quot;, which is &amp;quot;where each pieces is, and in what state&amp;quot;, or (position,rotation) pair.&lt;br /&gt;
&lt;br /&gt;
Lets see what we have for that:&lt;br /&gt;
* The card state is very simple, its usually &amp;quot;face up/face down&amp;quot;, &amp;quot;tapped/untapped&amp;quot;, &amp;quot;right side up/up side down&amp;quot;&lt;br /&gt;
* As position go we never need real coordinates x,y,z. We need to know what &amp;quot;zone&amp;quot; card was, and depending on the zone it may sometimes need an extra &amp;quot;z&amp;quot; or &amp;quot;x&amp;quot; as card order. The zone position usually static or irrelevant.&lt;br /&gt;
* So our model is: we have cards, which have some attributes, at any given point in time they belong to a &amp;quot;zone&amp;quot;, and can also have order and state&lt;br /&gt;
* Now for mapping we should consider what information changes and what information is static, later is always candidate for material file&lt;br /&gt;
* For dynamic information we should try to reduce amount of fields we need&lt;br /&gt;
**  we need at least a field for card, so its one&lt;br /&gt;
**  we need to know what zone cards belong to, its 2&lt;br /&gt;
**  and we have possibly few other fields, if you look closely at you game you may find out that most of the zone only need one attribute at a time, i.e. draw pile always have cards face down, hand always face up, also for hand and discard order does not matter at all (but for draw it does matter). So in majority of cases we can get away with one single extra integer field representing state or order&lt;br /&gt;
* In real database both card and zone will be integers as primary keys referring to additional tables, but in our case its total overkill, so they can be strings as easily&lt;br /&gt;
&lt;br /&gt;
Variant 1: Minimalistic&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE TABLE IF NOT EXISTS `card` (&lt;br /&gt;
  `card_key` varchar(32) unsigned NOT NULL,&lt;br /&gt;
  `card_location` varchar(32) NOT NULL,&lt;br /&gt;
  `card_state` int(11) NOT NULL,&lt;br /&gt;
  PRIMARY KEY (`card_id`)&lt;br /&gt;
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Variant 2: More normalised&lt;br /&gt;
&lt;br /&gt;
This version supported by Deck php class, so unless you want to rewrite db access layer go with this one&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE TABLE IF NOT EXISTS `card` (&lt;br /&gt;
  `card_id` int(10) unsigned NOT NULL AUTO_INCREMENT,&lt;br /&gt;
  `card_type` varchar(16) NOT NULL,&lt;br /&gt;
  `card_type_arg` int(11) NOT NULL,&lt;br /&gt;
  `card_location` varchar(16) NOT NULL,&lt;br /&gt;
  `card_location_arg` int(11) NOT NULL,&lt;br /&gt;
  PRIMARY KEY (`card_id`)&lt;br /&gt;
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: if you using this schema, some zones/locations have special semantic. The &#039;hand&#039; location is actually multiple locations - one per player, but player id is encoded as card_location_arg. If &#039;hand&#039; in your game is ordered, visible or can have some other card states, you cannot use hand location (replacement is hand_&amp;lt;player_id&amp;gt; or hand_&amp;lt;color_id&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
== Code Organization ==&lt;br /&gt;
&lt;br /&gt;
=== Including your own JavaScript module ===&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, modules/ggg_other.js&lt;br /&gt;
&lt;br /&gt;
* Create ggg_other.js in modules/ folder and sync&lt;br /&gt;
* Modify ggg.js to include it&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  define([ &amp;quot;dojo&amp;quot;, &amp;quot;dojo/_base/declare&amp;quot;, &amp;quot;ebg/core/gamegui&amp;quot;, &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
    // load my own module!!!&lt;br /&gt;
    g_gamethemeurl + &amp;quot;modules/ggg_other.js&amp;quot; ], function(dojo,&lt;br /&gt;
        declare) {&lt;br /&gt;
&lt;br /&gt;
=== Including your own JavaScript module (II) ===&lt;br /&gt;
&lt;br /&gt;
* Create ggg_other.js in modules/ folder and sync&lt;br /&gt;
&lt;br /&gt;
  define([], function () {&lt;br /&gt;
    return &amp;quot;value&amp;quot;;&lt;br /&gt;
  });&lt;br /&gt;
&lt;br /&gt;
* Modify ggg.js to include it&lt;br /&gt;
&lt;br /&gt;
  define([ &lt;br /&gt;
    &amp;quot;dojo&amp;quot;, &lt;br /&gt;
    &amp;quot;dojo/_base/declare&amp;quot;, &lt;br /&gt;
    &amp;quot;bgagame/modules/ggg_other&amp;quot;, &lt;br /&gt;
    &amp;quot;ebg/core/gamegui&amp;quot;, &lt;br /&gt;
    &amp;quot;ebg/counter&amp;quot;&lt;br /&gt;
  ], function(dojo, declare, other) {&lt;br /&gt;
  &lt;br /&gt;
  });&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
This is maybe a little bit more the idea of the AMD Loader than the first option, although the first option should work as well.&lt;br /&gt;
&lt;br /&gt;
A little explanation to this:&lt;br /&gt;
The define function loads all the modules listed in the array and calls the following function with these loaded modules as parameters.&lt;br /&gt;
By putting your module at the third position in the array it is passed as the third parameter to the function. Be aware that the modules are resolved by position only, not by name. So you can load the module &#039;&#039;&#039;ggg_other&#039;&#039;&#039; and pass it as a parameter with the name &#039;&#039;&#039;other&#039;&#039;&#039;. &#039;&#039;&#039;gamegui&#039;&#039;&#039; and &#039;&#039;&#039;counter&#039;&#039;&#039; are passed in as well, but when the parameters are not defined they are just skipped. Because these modules put their content into the global scope it does not matter and you can use them from there.&lt;br /&gt;
&lt;br /&gt;
In the example above the string &amp;quot;value&amp;quot; is passed for the parameter &#039;&#039;&#039;other&#039;&#039;&#039;, but the function in your module can return whatever you want. It can be an object, an array, something you declared with dojo.declare, you can return even functions. &lt;br /&gt;
Your module can load other modules. Just put them in the array at the beginning and pass them as parameters to your function.&lt;br /&gt;
The advantage of passing the values as parameter is that you do not need to put these values in the global scope, so they can&#039;t be collisions with values defined in other scripts or the BGA Framework.&lt;br /&gt;
&lt;br /&gt;
The dojo toolkit provides good documentation to all of its components, the complete documentation for the AMD-Loader is here:&lt;br /&gt;
https://dojotoolkit.org/documentation/tutorials/1.10/modules/index.html It should be still correct, even as it seems to be only for version 1.10&lt;br /&gt;
&lt;br /&gt;
=== Including your own PHP module ===&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.game.php, modules/ggg_other.php&lt;br /&gt;
&lt;br /&gt;
* Create ggg_other.php in modules/ folder and sync&lt;br /&gt;
* Modify ggg.game.php to include it&lt;br /&gt;
&lt;br /&gt;
 require_once (&#039;modules/ggg_other.php&#039;);&lt;br /&gt;
&lt;br /&gt;
=== Creating a test class to run PHP locally ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.game.php, stubs&lt;br /&gt;
For this you need stubs of other method you can use this for example&lt;br /&gt;
https://github.com/elaskavaia/bga-sharedcode/raw/master/misc/module/table/table.game.php&lt;br /&gt;
&lt;br /&gt;
Create another php files, i.e ggg_test.php&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
define(&amp;quot;APP_GAMEMODULE_PATH&amp;quot;, &amp;quot;misc/&amp;quot;); // include path to stubs, which defines &amp;quot;table.game.php&amp;quot; and other classes&lt;br /&gt;
require_once (&#039;eminentdomaine.game.php&#039;);&lt;br /&gt;
&lt;br /&gt;
class MyGameTest1 extends MyGame { // this is your game class defined in ggg.game.php&lt;br /&gt;
    function __construct() {&lt;br /&gt;
        parent::__construct();&lt;br /&gt;
        include &#039;../material.inc.php&#039;;// this is how this normally included, from constructor&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // override/stub methods here that access db and stuff&lt;br /&gt;
    function getGameStateValue($var) {&lt;br /&gt;
        if ($var == &#039;round&#039;)&lt;br /&gt;
            return 3;&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
$x = new MyGameTest1(); // instantiate your class&lt;br /&gt;
$p = $x-&amp;gt;getGameProgression(); // call one of the methods to test&lt;br /&gt;
if ($p != 50)&lt;br /&gt;
    echo &amp;quot;Test1: FAILED&amp;quot;;&lt;br /&gt;
else&lt;br /&gt;
    echo &amp;quot;Test1: PASSED&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Run from command line like&lt;br /&gt;
 php7 ggg_test.php&lt;br /&gt;
&lt;br /&gt;
If you do it this way - you can also use local php debugger (i.e. integrated with IDE or command line).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Avoiding code in dojo declare style ===&lt;br /&gt;
Dojo class declarations are rather bizzare and do not work with most IDEs.&lt;br /&gt;
If you want to write in plain JS with classes, you can stub all the dojo define/declare stuff&lt;br /&gt;
and hook your class into that, so the classes are outside of this mess.&lt;br /&gt;
&lt;br /&gt;
NOTE: this technique is for experienced developers, do not try it if you do not understand&lt;br /&gt;
the consequences.&lt;br /&gt;
&lt;br /&gt;
This is complete example of game .js class&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  // Testla is game name is has to be changed&lt;br /&gt;
class Testla {&lt;br /&gt;
	constructor(game) {&lt;br /&gt;
		console.log(&#039;game constructor&#039;);&lt;br /&gt;
		this.game = game;&lt;br /&gt;
		this.varfoo = new MyFoo(); // this example of class from custom module&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	setup(gamedatas) {&lt;br /&gt;
		console.log(&amp;quot;Starting game setup&amp;quot;, this.varfoo);&lt;br /&gt;
		this.gamedatas = gamedatas;&lt;br /&gt;
		this.dojo.create(&amp;quot;div&amp;quot;, { class: &#039;whiteblock&#039;, innerHTML: _(&amp;quot;hello&amp;quot;) }, &#039;thething&#039;);&lt;br /&gt;
		console.log(&amp;quot;Ending game setup&amp;quot;);&lt;br /&gt;
	};&lt;br /&gt;
	onEnteringState(stateName, args) {&lt;br /&gt;
		console.log(&#039;onEnteringState : &#039; + stateName, args);&lt;br /&gt;
		this.game.addActionButton(&#039;b1&#039;,_(&#039;Click Me&#039;), (e)=&amp;gt;this.onButtonClick(e));&lt;br /&gt;
	};&lt;br /&gt;
	onLeavingState(stateName) {&lt;br /&gt;
		console.log(&#039;onLeavingState : &#039; + stateName, args);&lt;br /&gt;
	};&lt;br /&gt;
	onUpdateActionButtons(stateName, args) {&lt;br /&gt;
		console.log(&#039;onUpdateActionButtons : &#039; + stateName, args);&lt;br /&gt;
	};&lt;br /&gt;
	onButtonClick(event) {&lt;br /&gt;
		console.log(&#039;onButtonClick&#039;,event);&lt;br /&gt;
	};&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&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;
	g_gamethemeurl + &#039;/modules/foo.js&#039; // custom module if needed&lt;br /&gt;
],&lt;br /&gt;
	function(dojo, declare) {&lt;br /&gt;
                // testla is game name is has to be changed&lt;br /&gt;
		return declare(&amp;quot;bgagame.testla&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
			constructor: function() {&lt;br /&gt;
				this.xapp = new Testla(this);&lt;br /&gt;
				this.xapp.dojo = dojo;&lt;br /&gt;
			},&lt;br /&gt;
			setup: function(gamedatas) {&lt;br /&gt;
				this.xapp.setup(gamedatas);&lt;br /&gt;
			},&lt;br /&gt;
			onEnteringState: function(stateName, args) {&lt;br /&gt;
				this.xapp.onEnteringState(stateName, args.args);&lt;br /&gt;
			},&lt;br /&gt;
			onLeavingState: function(stateName) {&lt;br /&gt;
				this.xapp.onLeavingState(stateName, args);&lt;br /&gt;
			},&lt;br /&gt;
			onUpdateActionButtons: function(stateName, args) {&lt;br /&gt;
				this.xapp.onUpdateActionButtons(stateName, args);&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;
=== More readable JS: onEnteringState ===&lt;br /&gt;
&lt;br /&gt;
If you have a lot of states onEnteringState and friends become rather wild, you can do this trick to call some method dynamically.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
     onEnteringState: function(stateName, args) {&lt;br /&gt;
       console.log(&#039;Entering state: &#039; + stateName, args);&lt;br /&gt;
&lt;br /&gt;
       // Call appropriate method&lt;br /&gt;
       var methodName = &amp;quot;onEnteringState_&amp;quot; + stateName;&lt;br /&gt;
       if (this[methodName] !== undefined) {             &lt;br /&gt;
          console.log(&#039;Calling &#039; + methodName, args.args);&lt;br /&gt;
          this[methodName](args.args);&lt;br /&gt;
       }&lt;br /&gt;
     },&lt;br /&gt;
&lt;br /&gt;
     onEnteringState_playerTurn: function(args) { // this is args directly, not args.args &lt;br /&gt;
         // process&lt;br /&gt;
     },&lt;br /&gt;
&lt;br /&gt;
     onEnteringState_playerSomethingElse: function(args) { &lt;br /&gt;
         // process&lt;br /&gt;
     },&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: since its ignores the undefined functions you don&#039;t have define function for each state, but on the other hand you cannot make typos.&lt;br /&gt;
Same applies to onUpdateActionButtons except you pass &#039;args&#039; to method, not args.args, and for onLeavingState where you don&#039;t pass anything.&lt;br /&gt;
&lt;br /&gt;
=== Frameworks and Preprocessors ===&lt;br /&gt;
&lt;br /&gt;
* [[Using Vue]] - work-in-progress guide on using the modern framework Vue.js to create a game&lt;br /&gt;
* [[Using Typescript and Scss]] - How to auto-build Typescript and SCSS files to make your code cleaner&lt;br /&gt;
&lt;br /&gt;
== Assorted Stuff ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Out-of-turn actions: Un-pass ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, ggg.game.php, ggg.action.php, states.inc.php&lt;br /&gt;
&lt;br /&gt;
In multiplayer game sometimes players passes but than they think more and want to un-Pass and redo their choice. &lt;br /&gt;
To re-active a player who passes some trickery required.&lt;br /&gt;
&lt;br /&gt;
Define a special action that does that and hook it up.&lt;br /&gt;
&lt;br /&gt;
In states.inc.php add an action to mmultipleactiveplayer state to &amp;quot;unpass&amp;quot;, lets call it &amp;quot;actionCancel&amp;quot;&lt;br /&gt;
&lt;br /&gt;
In ggg.action.php add action hook&lt;br /&gt;
    public function actionCancel() {&lt;br /&gt;
        self::setAjaxMode();&lt;br /&gt;
        $this-&amp;gt;game-&amp;gt;actionCancel();&lt;br /&gt;
        self::ajaxResponse();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
In ggg.game.php add action handler&lt;br /&gt;
    function actionCancel() {&lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;checkPossibleAction(&#039;actionCancel&#039;);&lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;setPlayersMultiactive(array ($this-&amp;gt;getCurrentPlayerId() ), &#039;error&#039;, false);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
Finally to call this in client ggg.js you would do something like:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 onUpdateActionButtons:  function(stateName, args) {&lt;br /&gt;
   if (this.isCurrentPlayerActive()) { &lt;br /&gt;
     // ...&lt;br /&gt;
   } else if (!this.isSpectator) { // player is NOT active but not spectator&lt;br /&gt;
       switch (stateName) {&lt;br /&gt;
          case &#039;playerTurnMuliPlayerState&#039;:&lt;br /&gt;
		this.addActionButton(&#039;button_unpass&#039;, _(&#039;Oh no!&#039;), &#039;onUnpass&#039;);&lt;br /&gt;
		break;&lt;br /&gt;
	}&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
				&lt;br /&gt;
 onUnpass: function(e) {&lt;br /&gt;
    this.ajaxcall(&amp;quot;/&amp;quot; + this.game_name + &amp;quot;/&amp;quot; +  this.game_name + &amp;quot;/actionCancel.html&amp;quot;, {}, this); // no checkAction!&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Although be careful that if the turn comes back to the player while he is about to click cancel, the action buttons will be updated and the player will misclick which can be quite frustrating. To avoid this, move the cancel button to another position, like to the left of pagemaintitletext:&lt;br /&gt;
  dojo.place(&#039;button_unpass&#039;, &#039;pagemaintitletext&#039;, &#039;before&#039;);&lt;br /&gt;
Being out of the generalactions div, it won&#039;t be automatically destroyed like normal buttons, so you&#039;ll have to handle that yourself in onLeavingState. You might also want to change the button color to red (blue buttons for active player only, red buttons also for inactive players?)&lt;br /&gt;
&lt;br /&gt;
Note: same technique can be used to do other out-of-turn actions, such as re-arranging cards in hand, exchanging resources, etc (i.e. if permitted by rules, such as &amp;quot;at any time player can...&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
=== Multi Step Interactions: Select Worker/Place Worker - Using Selection ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
Simple way to implement something like that without extra states is to use &amp;quot;selection&amp;quot; mechanism. When user click on worker add some sort of class into that element i.e. &#039;selected&#039; (which also have to have some indication by css i.e. outline).&lt;br /&gt;
&lt;br /&gt;
Than user can click on placement zone, you can use dojo.query for &amp;quot;selected&amp;quot; element and use it along with zone id to send data to server. If proper worker is not selected yet can give a error message using this.showMessage(...) function.&lt;br /&gt;
&lt;br /&gt;
Extra code required to properly cleanup selection between states.&lt;br /&gt;
Also when you do that sometimes you want to change the state prompt, see below &#039;Change state prompt&#039;&lt;br /&gt;
&lt;br /&gt;
=== Multi Step Interactions: Select Worker/Place Worker - Using Client States ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
I don&#039;t think its documented feature but there is a way to do client-only states, which is absolutely wonderful for few reasons&lt;br /&gt;
* When player interaction is two step process, such as select worker, place worker, or place worker, pick one of two resources of your choice&lt;br /&gt;
* When multi-step process can result of impossible situation and has to be undone (by rules)&lt;br /&gt;
* When multi-step process is triggered from multiple states (such as you can do same thing as activated card action, pass action or main action)&lt;br /&gt;
&lt;br /&gt;
So lets do Select Worker/Place Worker&lt;br /&gt;
&lt;br /&gt;
Define your server state as usual, i.e. playerMainTurn -&amp;gt; &amp;quot;You must pick up a worker&amp;quot;.&lt;br /&gt;
Now define a client state, we only need &amp;quot;name&amp;quot; and &amp;quot;descriptionmyturn&amp;quot;, lets say &amp;quot;client_playerPicksLocation&amp;quot;. Always prefix names of client state with &amp;quot;client_&amp;quot; to avoid confusion. Now we have to do the following:&lt;br /&gt;
* Have a handler for onUpdateActionButtons for playerMainTurn to activate all possible workers he can pick&lt;br /&gt;
* When player clicks workers, remember the worker in one of the members of the main class, I usually use one called this.clientStateArgs.&lt;br /&gt;
* Transition to new client state&lt;br /&gt;
  onWorker: function(e) {&lt;br /&gt;
      var id = event.currentTarget.id;&lt;br /&gt;
      dojo.stopEvent(event);&lt;br /&gt;
      ... // do validity checks&lt;br /&gt;
      this.clientStateArgs.worker_id = id;&lt;br /&gt;
      this.setClientState(&amp;quot;client_playerPicksLocation&amp;quot;, {&lt;br /&gt;
                                descriptionmyturn : _(&amp;quot;${you} must select location&amp;quot;),&lt;br /&gt;
                            });&lt;br /&gt;
   }&lt;br /&gt;
* Have a handler for onUpdateActionButtons for client_playerPicksLocation to activate all possible locations this worker can go AND add Cancel button (see below)&lt;br /&gt;
* Have a location handler which will eventually send a server request, using stored this.clientStateArgs.worker_id as worker id&lt;br /&gt;
* The cancel button should call a method to restore server state, also if you doing it for more than one state you can add this universally using this.on_client_state check&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        if (this.isCurrentPlayerActive()) {&lt;br /&gt;
          if (this.on_client_state &amp;amp;&amp;amp; !$(&#039;button_cancel&#039;)) {&lt;br /&gt;
               this.addActionButton(&#039;button_cancel&#039;, _(&#039;Cancel&#039;), dojo.hitch(this, function() {&lt;br /&gt;
                                             this.restoreServerGameState();&lt;br /&gt;
               }));&lt;br /&gt;
          }&lt;br /&gt;
        } &lt;br /&gt;
Note: usually I call my own function call this.cancelLocalStateEffects() which will do more stuff first then call restoreServerGameState(), same function is usually needs to be called when server request has failed (i.e. invalid move)&lt;br /&gt;
&lt;br /&gt;
Note: If you need more than 2 steps, you may have to do client side animation to reflect the new state, which gets trickier because you have to undo that also on cancellation.&lt;br /&gt;
&lt;br /&gt;
Code is available here [https://github.com/elaskavaia/bga-sharedcode/blob/master/sharedcode.js sharedcode.js] (its using playerTurnPlayCubes and client_selectCubeLocation).&lt;br /&gt;
&lt;br /&gt;
=== Action Stack - Using Client States ===&lt;br /&gt;
&lt;br /&gt;
Action stack required where game is very complex and use triggered effects that can &amp;quot;stack&amp;quot;. It not always actual stack, it can be queue or random access&lt;br /&gt;
Examples:&lt;br /&gt;
* Magic the Gathering - classic card game where effects go on Stack, that allows to counter spell and counter spell of counter spell (not on bga - it just example of mechanics)&lt;br /&gt;
* Ultimate Railroads - action taking game where effects can be executed in any order&lt;br /&gt;
* Lewis and Clark - card game where actions executed as queue&lt;br /&gt;
&lt;br /&gt;
There is two ways of implementing it - on the server or the client.&lt;br /&gt;
For the server see article below.&lt;br /&gt;
The requirement for client side stack is all action can be undone, which means&lt;br /&gt;
* No dice rolls&lt;br /&gt;
* No card drawn&lt;br /&gt;
* No other players interaction&lt;br /&gt;
&lt;br /&gt;
No snippets are here, as this will be too complex but basically flow is:&lt;br /&gt;
* You have a action/effect stack (queue/list) as js object attached to &amp;quot;this&amp;quot;, i.e. this.unprocessed_actions&lt;br /&gt;
* When player plays a card, worker, etc, you read the effect of that card from the material file (client copy), and place into stack&lt;br /&gt;
* Then we call dispatch method which pulls the next action from the stack and change client state accordinly,i.e.  this.setClientState(&amp;quot;client_playerGainsCubes&amp;quot;)&lt;br /&gt;
* When players acts on it - the action is removed from the stack and added to &amp;quot;server action arguments&amp;quot; list, this is another object which be used to send ajax call, i.e. this.clientStateArgs&lt;br /&gt;
* If nothing left in stack we can submit the ajax call assembling parameters from collected arguments (that can include action name)&lt;br /&gt;
* This method allows cheap undo - by restoring server state you will wipe out all user actions (but if you need intermediate aninmation you have to handle it yourself)&lt;br /&gt;
&lt;br /&gt;
Code can be found in Ultimate Railroads game (but it is random access list - so it a bit complex) and Lewis and Clark (complexity - use can always deny part of any effect)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Action Stack - Using Server States ===&lt;br /&gt;
&lt;br /&gt;
See definition of Action Stack above.&lt;br /&gt;
&lt;br /&gt;
To implement you usually need another db table that has the following fields: index of effect - which is used for sorted access, type - which is essense of the effect (i.e. collect resource), some extra arguments (i.e. resource type and resource count), and usually owner of the effect (i.e. player id)&lt;br /&gt;
The flow is:&lt;br /&gt;
* There is some initial player state, where player can play card for example&lt;br /&gt;
* Player main action - pushes the card effect on stack, which also can cause triggered effects which also go on stack&lt;br /&gt;
* After action processing is finished switch to game state which is &amp;quot;dispatcher&amp;quot;&lt;br /&gt;
* Gispatcher pulls the top effect (whatever definition of the top is), changes the active player and changes the state to appropriate player state to collect response&lt;br /&gt;
* Player state knows about the stack and pulls arguments (argX) from the effect arguments of the db&lt;br /&gt;
* Player action should clear up the top effect, and can possibly add more effects, then switch to &amp;quot;dispatcher&amp;quot; state again&lt;br /&gt;
* If stack is empty, dispatcher can either pick next player itself or use another game state which responsible for picking next player&lt;br /&gt;
&lt;br /&gt;
Code can be found in Tapestry.&lt;br /&gt;
&lt;br /&gt;
=== Changing state prompt ===&lt;br /&gt;
&lt;br /&gt;
State prompt is message displayed for player which usually comes from state description.&lt;br /&gt;
Sometimes you want to change it without changing state (one way is change state but locally, see client states above).&lt;br /&gt;
&lt;br /&gt;
Simple way just change the html&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        setMainTitle: function(text) {&lt;br /&gt;
            $(&#039;pagemaintitletext&#039;).innerHTML = text;&lt;br /&gt;
        },&lt;br /&gt;
         // usage&lt;br /&gt;
        onMeeple: function(event) {&lt;br /&gt;
              //... &lt;br /&gt;
              this.setMainTitle(_(&#039;You must select where meeple is going&#039;));&lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This however will not work with parameters and will not draw You in color, if you want this its more sophisticated:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        setDescriptionOnMyTurn : function(text) {&lt;br /&gt;
            this.gamedatas.gamestate.descriptionmyturn = text;&lt;br /&gt;
            var tpl = dojo.clone(this.gamedatas.gamestate.args);&lt;br /&gt;
            if (tpl === null) {&lt;br /&gt;
                tpl = {};&lt;br /&gt;
            }&lt;br /&gt;
            var title = &amp;quot;&amp;quot;;&lt;br /&gt;
            if (this.isCurrentPlayerActive() &amp;amp;&amp;amp; text !== null) {&lt;br /&gt;
                tpl.you = this.divYou(); &lt;br /&gt;
            }&lt;br /&gt;
            title = this.format_string_recursive(text, tpl);&lt;br /&gt;
&lt;br /&gt;
            if (!title) {&lt;br /&gt;
                this.setMainTitle(&amp;quot;&amp;amp;nbsp;&amp;quot;);&lt;br /&gt;
            } else {&lt;br /&gt;
                this.setMainTitle(title);&lt;br /&gt;
            }&lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: this method uses &#039;&#039;&#039;setMainTitle&#039;&#039;&#039; defined above and &#039;&#039;&#039;divYou&#039;&#039;&#039; defined in another section of this wiki.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Adding Image buttons ===&lt;br /&gt;
&lt;br /&gt;
Its pretty trivial but just in case you need a working function:&lt;br /&gt;
&lt;br /&gt;
ggg.js:&lt;br /&gt;
&lt;br /&gt;
                addImageActionButton: function (id, div_html, handler) { // div_html is string not node&lt;br /&gt;
                    this.addActionButton(id, div_html, handler, &#039;&#039;, false, &#039;gray&#039;); &lt;br /&gt;
                    dojo.style(id, &amp;quot;border&amp;quot;, &amp;quot;none&amp;quot;); // remove ugly border&lt;br /&gt;
                    dojo.addClass(id, &amp;quot;bgaimagebutton&amp;quot;); // add css class to do more styling&lt;br /&gt;
                    return $(id); // return node for chaining&lt;br /&gt;
                },&lt;br /&gt;
&lt;br /&gt;
Example of usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    this.addImageActionButton(&#039;button_coin&#039;,&amp;quot;&amp;lt;div class=&#039;coin&#039;&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;, ()=&amp;gt;{ alert(&#039;Ha!&#039;); });&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Assigning Player Order ===&lt;br /&gt;
Normally when game starts there is &amp;quot;natural&amp;quot; player order assigned randomly.&lt;br /&gt;
&lt;br /&gt;
If you want to deliberatly assign player order at the start of the game (for example, in a game with teams options), you can do so by retrieving the initialization-only player attribute &#039;&#039;&#039;player_table_order&#039;&#039;&#039; and using it to assign values to &#039;&#039;&#039;player_no&#039;&#039;&#039; (which is normally assigned at the start of a game in the order in which players come to the table). (See [https://en.doc.boardgamearena.com/Game_database_model:_dbmodel.sql#The_player_table Game database model] for more details.)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Example:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                // Retrieve inital player order ([0=&amp;gt;playerId1, 1=&amp;gt;playerId2, ...])&lt;br /&gt;
		$playerInitialOrder = [];&lt;br /&gt;
		foreach ($players as $playerId =&amp;gt; $player) {&lt;br /&gt;
			$playerInitialOrder[$player[&#039;player_table_order&#039;]] = $playerId;&lt;br /&gt;
		}&lt;br /&gt;
		ksort($playerInitialOrder);&lt;br /&gt;
		$playerInitialOrder = array_flip(array_values($playerInitialOrder));&lt;br /&gt;
&lt;br /&gt;
		// Player order based on &#039;playerTeams&#039; option&lt;br /&gt;
		$playerOrder = [0, 1, 2, 3];&lt;br /&gt;
		switch (self::getGameStateValue(&#039;playerTeams&#039;)) {&lt;br /&gt;
			case self::TEAM_1_2:&lt;br /&gt;
				$playerOrder = [0, 2, 1, 3];&lt;br /&gt;
				break;&lt;br /&gt;
			case self::TEAM_1_4:&lt;br /&gt;
				$playerOrder = [0, 1, 3, 2];&lt;br /&gt;
				break;&lt;br /&gt;
			case self::TEAM_RANDOM:&lt;br /&gt;
				shuffle($playerOrder);&lt;br /&gt;
				break;&lt;br /&gt;
			default:&lt;br /&gt;
			case self::TEAM_1_3:&lt;br /&gt;
				// Default order&lt;br /&gt;
				break;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
                // Create players&lt;br /&gt;
		// Note: if you added some extra field on &amp;quot;player&amp;quot; table in the database (dbmodel.sql), you can initialize it there.&lt;br /&gt;
		$sql =&lt;br /&gt;
			&#039;INSERT INTO player (player_id, player_color, player_canal, player_name, player_avatar, player_no) VALUES &#039;;&lt;br /&gt;
		$values = [];&lt;br /&gt;
&lt;br /&gt;
		foreach ($players as $playerId =&amp;gt; $player) {&lt;br /&gt;
			$color = array_shift($default_colors);&lt;br /&gt;
			$values[] =&lt;br /&gt;
				&amp;quot;(&#039;&amp;quot; .&lt;br /&gt;
				$playerId .&lt;br /&gt;
				&amp;quot;&#039;,&#039;$color&#039;,&#039;&amp;quot; .&lt;br /&gt;
				$player[&#039;player_canal&#039;] .&lt;br /&gt;
				&amp;quot;&#039;,&#039;&amp;quot; .&lt;br /&gt;
				addslashes($player[&#039;player_name&#039;]) .&lt;br /&gt;
				&amp;quot;&#039;,&#039;&amp;quot; .&lt;br /&gt;
				addslashes($player[&#039;player_avatar&#039;]) .&lt;br /&gt;
				&amp;quot;&#039;,&#039;&amp;quot; .&lt;br /&gt;
				$playerOrder[$playerInitialOrder[$playerId]] .&lt;br /&gt;
				&amp;quot;&#039;)&amp;quot;;&lt;br /&gt;
		}&lt;br /&gt;
		$sql .= implode(&#039;,&#039;, $values);&lt;br /&gt;
		self::DbQuery($sql);&lt;br /&gt;
		self::reattributeColorsBasedOnPreferences(&lt;br /&gt;
			$players,&lt;br /&gt;
			$gameinfos[&#039;player_colors&#039;]&lt;br /&gt;
		);&lt;br /&gt;
		self::reloadPlayersBasicInfos();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Send different notifications to active player vs everybody else ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
Hack alert. This is a hack. We were hoping for proper solution by bga framework.&lt;br /&gt;
&lt;br /&gt;
This will allow you to send notification with two message one for specific player and one for everybody else including spectators.&lt;br /&gt;
Note that this does not split the data - all data must be shared.&lt;br /&gt;
&lt;br /&gt;
Add this to .js file (if you already overriding it merge obviously)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/** @Override */&lt;br /&gt;
format_string_recursive: function(log, args) {&lt;br /&gt;
   if (typeof args.log_others != &#039;undefined&#039; &amp;amp;&amp;amp; typeof args.player_id != &#039;undefined&#039; &amp;amp;&amp;amp; this.player_id != args.player_id)&lt;br /&gt;
	log = args.log_others;&lt;br /&gt;
   return this.inherited(arguments); // you must call this to call super &lt;br /&gt;
},&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example of usage (from eminentdomain)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    $this-&amp;gt;notifyAllPlayers(&#039;tokenMoved&#039;, &lt;br /&gt;
             clienttranslate(&#039;${player_name} adds +2 Colonies to ${place_name}&#039;), // notification with show for player with player_id&lt;br /&gt;
             [&#039;player_id&#039;=&amp;gt;$player_id, // this is mandatory&lt;br /&gt;
             &#039;log_others&#039;=&amp;gt;clienttranslate(&#039;${player_name} adds +2 Colonies to an unknown planet&#039;), // notification will show for others&lt;br /&gt;
              ...&lt;br /&gt;
             ]);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Send transient notifications without incrementing move ID ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.php&lt;br /&gt;
&lt;br /&gt;
Hack alert. This is a hack.&lt;br /&gt;
&lt;br /&gt;
Use this if you need to send some transient notification that should not create a new move ID. The notification should be idempotent -- it should have no practical effect on the game state and would be &#039;&#039;&#039;safe to drop&#039;&#039;&#039; (e.g., it would not matter if a player never received this notification). For example, in a co-op game you want all players to see a real-time preview of some action, before the active player commits their turn.&lt;br /&gt;
&lt;br /&gt;
Doing this mainly affects the instant replay &amp;amp; archive modes. During replay, the BGA framework automatically inserts a 1.5-second pause between each &amp;quot;move&amp;quot;. With this hack, your transient notifications are not considered to be a &amp;quot;move&amp;quot;, so no pause gets added.&lt;br /&gt;
&lt;br /&gt;
; In ggg.php&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$this-&amp;gt;not_a_move_notification = true; // note: do not increase the move counter&lt;br /&gt;
$this-&amp;gt;notifyAllPlayers(&#039;cardsPreview&#039;, &#039;&#039;, $args);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: you cannot have code that send notification or even changes state after this, and you cannot reset this variable back either because it only takes effect when you exit action handling function&lt;br /&gt;
&lt;br /&gt;
=== Ajax Call wrapper ===&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
The current ajaxcall is super vebose and prone to errors, I suggest using a helper function. It does a lot of stuff you must do anyways.&lt;br /&gt;
Most beginner mistakes come from missing part of this code (which is understandstandable - this is a huge snippet to clone every time).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	ajaxcallwrapper: function(action, args, handler) {&lt;br /&gt;
		if (!args) args = []; // this allows to skip args parameter for action which do not require them&lt;br /&gt;
			&lt;br /&gt;
		args.lock = true; // this allows to avoid rapid action clicking which can cause race condition on server&lt;br /&gt;
		if (this.checkAction(action)) { // this does all the proper check that player is active and action is declared&lt;br /&gt;
			this.ajaxcall(&amp;quot;/&amp;quot; + this.game_name + &amp;quot;/&amp;quot; + this.game_name + &amp;quot;/&amp;quot; + action + &amp;quot;.html&amp;quot;, args, // this is mandatory fluff &lt;br /&gt;
				this, (result) =&amp;gt; { },  // success result handler is empty - it is never needed&lt;br /&gt;
                                               handler); // this is real result handler - it called both on success and error, it has optional param  &amp;quot;is_error&amp;quot; - you rarely need it&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   this.ajaxcallwrapper(&#039;pass&#039;); // no args&lt;br /&gt;
   this.ajaxcallwrapper(&#039;playCard&#039;, {card: card_id}); // with args&lt;br /&gt;
   this.ajaxcallwrapper(&#039;playCard&#039;, {card: card_id}, (is_error)=&amp;gt;{if (!is_error) dojo.query(&amp;quot;.selected&amp;quot;).removeClass(&#039;selected&#039;);}) // with handler that cleans up &#039;selected&#039; class on success&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: this always will lock interface and always check for action, you can modify this method to do it optionally, i.e&lt;br /&gt;
  if (args.lock!==false) args.lock = true; else delete args.lock; // it does not work with false value - it has to be removed&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Studio]]&lt;/div&gt;</summary>
		<author><name>SwHawk</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=BGA_Studio_Cookbook&amp;diff=14212</id>
		<title>BGA Studio Cookbook</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=BGA_Studio_Cookbook&amp;diff=14212"/>
		<updated>2022-07-31T15:50:15Z</updated>

		<summary type="html">&lt;p&gt;SwHawk: /* Second way: rely on the :formatFunction option provided by dojo.string.substitute */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
This page is collection of design and implementation recipes for BGA Studio framework.&lt;br /&gt;
For tooling and usage recipes see [[Tools and tips of BGA Studio]].&lt;br /&gt;
If you have your own recipes feel free to edit this page.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Visual Effects, Layout and Animation ==&lt;br /&gt;
&lt;br /&gt;
=== DOM manipulatons ===&lt;br /&gt;
&lt;br /&gt;
==== Create pieces dynamically (using template) ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg_ggg.tpl, ggg.js&lt;br /&gt;
&lt;br /&gt;
Note: this method is recommended by BGA guildlines&lt;br /&gt;
&lt;br /&gt;
Declared js template with variables in .tpl file, like this&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;
    // Javascript HTML templates&lt;br /&gt;
    var jstpl_ipiece = &#039;&amp;lt;div class=&amp;quot;${type} ${type}_${color} inlineblock&amp;quot; aria-label=&amp;quot;${name}&amp;quot; title=&amp;quot;${name}&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use it like this in .js file&lt;br /&gt;
  div = this.format_block(&#039;jstpl_ipiece&#039;, {&lt;br /&gt;
                                type : &#039;meeple&#039;,&lt;br /&gt;
                                color : &#039;ff0000&#039;,&lt;br /&gt;
                                name : &#039;Bob&#039;,&lt;br /&gt;
                            });&lt;br /&gt;
  &lt;br /&gt;
Then you do whatever you need to do with that div, this one specifically design to go to log entries, because it has embedded title (otherwise its a picture only) and no id.&lt;br /&gt;
&lt;br /&gt;
Note: you could have place this variable in js itself, but keeping it in .tpl allows you to have your js code be free of HTML. Normally it never happens but&lt;br /&gt;
it is good to strive for it.&lt;br /&gt;
Note: you can also use string concatenation, its less readable. You can also use dojo dom object creation api&#039;s but its brutally verbose and its more unreadable.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Create pieces dynamically (using string concatenation) ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
Note: Not recommended&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  div = &amp;quot;&amp;lt;div class=&#039;meeple &amp;quot;+color+&amp;quot;&#039;&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
==== Create all pieces statically ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg_ggg.tpl, ggg.css, ggg.view.php (optional) &lt;br /&gt;
&lt;br /&gt;
* Create ALL game pieces in html template (.tpl)&lt;br /&gt;
* ALL pieces should have unique id, and it should be meaningful, i.e. meeple_red_1&lt;br /&gt;
* Do not use inline styling&lt;br /&gt;
* Id of player&#039;s specific pieces should use some sort of &#039;color&#039; identification, since player id cannot be used in static layout, you can use english color name, hex 6 char value, or color &amp;quot;number&amp;quot; (1,2,3...)&lt;br /&gt;
* Pieces should have separated class for its color, type, etc, so it can be easily styled in groups. In example below you now can style all meeples, all red meeples or all red tokens, or all &amp;quot;first&amp;quot; meeples&lt;br /&gt;
&lt;br /&gt;
ggg.tpl:&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
  &amp;lt;div id=&amp;quot;home_red&amp;quot; class=&amp;quot;home_red home&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;div id=&amp;quot;meeple_red_1&amp;quot; class=&amp;quot;meeple red n1&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
     &amp;lt;div id=&amp;quot;meeple_red_2&amp;quot; class=&amp;quot;meeple red n2&amp;quot;&amp;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;
ggg.css:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.meeple {&lt;br /&gt;
	width: 32px;&lt;br /&gt;
	height: 39px;&lt;br /&gt;
	background-image: url(img/78_64_stand_meeples.png);&lt;br /&gt;
	background-size: 352px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.meeple.red {&lt;br /&gt;
	background-position: 30% 0%;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* There should be straight forward mapping between server id and js id (or 1:1)&lt;br /&gt;
* You place objects in different zones of the layout, and setup css to take care of layout&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.home .meeple{&lt;br /&gt;
   display: inline-block;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* If you need to have a temporary object that look like original you can use dojo.clone (and change id to some temp id)&lt;br /&gt;
* If there is lots of repetition or zone grid you can use template generator, but inject style declaration in css instead of inline style for flexibility&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
* If you use this model you cannot use premade js components such as Stock and Zone&lt;br /&gt;
* You have to use alternative methods of animation (slightly altered) since default method will leave object with inline style attributes which you don&#039;t need&lt;br /&gt;
&lt;br /&gt;
=== Logs ===&lt;br /&gt;
&lt;br /&gt;
==== Inject icon images in the log ====&lt;br /&gt;
&lt;br /&gt;
Here is an example of what was done for Terra Mystica which is simple and straightforward:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
//Define the proper message&lt;br /&gt;
		$message = clienttranslate(&#039;${player_name} gets ${power_income} via Structures&#039;);&lt;br /&gt;
		if ($price &amp;gt; 0) {&lt;br /&gt;
			self::DbQuery(&amp;quot;UPDATE player SET player_score = player_score - $price WHERE player_id = $player_id&amp;quot;);&lt;br /&gt;
			$message = clienttranslate(&#039;${player_name} pays ${vp_price} and gets ${power_income} via Structures&#039;);&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
// Notify&lt;br /&gt;
		self::notifyAllPlayers( &amp;quot;powerViaStructures&amp;quot;, $message, array(&lt;br /&gt;
			&#039;i18n&#039; =&amp;gt; array( ),&lt;br /&gt;
			&#039;player_id&#039; =&amp;gt; $player_id,&lt;br /&gt;
			&#039;player_name&#039; =&amp;gt; self::getUniqueValueFromDb( &amp;quot;SELECT player_name FROM player WHERE player_id = $player_id&amp;quot; ),&lt;br /&gt;
			&#039;power_tokens&#039; =&amp;gt; $power_tokens,&lt;br /&gt;
			&#039;vp_price&#039; =&amp;gt; self::getLogsVPAmount($price),&lt;br /&gt;
			&#039;power_income&#039; =&amp;gt; self::getLogsPowerAmount($power_income),&lt;br /&gt;
			&#039;newScore&#039; =&amp;gt; self::getUniqueValueFromDb( &amp;quot;SELECT player_score FROM player WHERE player_id = $player_id&amp;quot; ),&lt;br /&gt;
			&#039;counters&#039; =&amp;gt; $this-&amp;gt;getGameCounters(null),&lt;br /&gt;
		) );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With some functions to have the needed html added inside the substitution variable, such as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function getLogsPowerAmount( $amount ) {&lt;br /&gt;
		return &amp;quot;&amp;lt;div class=&#039;tmlogs_icon&#039; title=&#039;Power&#039;&amp;gt;&amp;lt;div class=&#039;power_amount&#039;&amp;gt;$amount&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: injecting html from php is not ideal but easy, if you want more clean solution, use method below but it is a lot more sophisticated.&lt;br /&gt;
&lt;br /&gt;
==== Inject images and styled html in the log ====&lt;br /&gt;
&lt;br /&gt;
So you want nice pictures in the game log. What do you do? The first idea that comes to mind is to send html from php in notifications (see method above). &lt;br /&gt;
&lt;br /&gt;
This is a bad idea for many reasons:&lt;br /&gt;
&lt;br /&gt;
* It&#039;s bad architecture. ui elements leak into the server, and now you have to manage the ui in multiple places.&lt;br /&gt;
* If you decided to change something in the ui in future version, replay logs for old games and tutorials may not work, since they use stored notifications.&lt;br /&gt;
* Log previews for old games become unreadable. (This is the log state before you enter the game replay, which is useful for troubleshooting and game analysis.)&lt;br /&gt;
* It&#039;s more data to transfer and store in the db.&lt;br /&gt;
* It&#039;s a nightmare for translators.&lt;br /&gt;
&lt;br /&gt;
So what else can you do? You can use client side log injection to intercept log arguments (which come from the server) and replace them with html on the client side. Here are three different method you can use to achieve this.&lt;br /&gt;
&lt;br /&gt;
===== First way : Override &amp;lt;code&amp;gt;this.format_string_recursive()&amp;lt;/code&amp;gt; method =====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, ggg.game.php&lt;br /&gt;
&lt;br /&gt;
I use this recipe for &#039;&#039;&#039;client side log injection&#039;&#039;&#039; to intercept log arguments (which come from the server) and replace them with html on the client side.&lt;br /&gt;
&lt;br /&gt;
[[File:clientloginjection.png|left]] &lt;br /&gt;
&lt;br /&gt;
ggg.js&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
        /** Override this function to inject html into log items. This is a built-in BGA method.  */&lt;br /&gt;
&lt;br /&gt;
        /* @Override */&lt;br /&gt;
        format_string_recursive : function format_string_recursive(log, args) {&lt;br /&gt;
            try {&lt;br /&gt;
                if (log &amp;amp;&amp;amp; args &amp;amp;&amp;amp; !args.processed) {&lt;br /&gt;
                    args.processed = true;&lt;br /&gt;
                    &lt;br /&gt;
&lt;br /&gt;
                    // list of special keys we want to replace with images&lt;br /&gt;
                    var keys = [&#039;place_name&#039;,&#039;token_name&#039;];&lt;br /&gt;
                    &lt;br /&gt;
                  &lt;br /&gt;
                    for ( var i in keys) {&lt;br /&gt;
                        var key = keys[i];&lt;br /&gt;
                        key in args &amp;amp;&amp;amp; args[key] = this.getTokenDiv(key, args);                            &lt;br /&gt;
&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            } catch (e) {&lt;br /&gt;
                console.error(log,args,&amp;quot;Exception thrown&amp;quot;, e.stack);&lt;br /&gt;
            }&lt;br /&gt;
            return this.inherited({callee: format_string_recursive}, arguments);&lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important:&#039;&#039;&#039; In the &#039;&#039;format_string_recursive&#039;&#039; method, the &#039;args&#039; parameter will only contain arguments passed to it from the notify method in ggg.game.php (see below).&lt;br /&gt;
&lt;br /&gt;
The &#039;log&#039; parameter is the actual string that is inserted into the logs. You can perform additional js string manipulation on it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        getTokenDiv : function(key, args) {&lt;br /&gt;
            // ... implement whatever html you want here, example from sharedcode.js&lt;br /&gt;
            var token_id = args[key];&lt;br /&gt;
            var item_type = getPart(token_id,0);&lt;br /&gt;
            var logid = &amp;quot;log&amp;quot; + (this.globalid++) + &amp;quot;_&amp;quot; + token_id;&lt;br /&gt;
            switch (item_type) {&lt;br /&gt;
                case &#039;wcube&#039;:&lt;br /&gt;
                    var tokenDiv = this.format_block(&#039;jstpl_resource_log&#039;, {&lt;br /&gt;
                        &amp;quot;id&amp;quot; : logid,&lt;br /&gt;
                        &amp;quot;type&amp;quot; : &amp;quot;wcube&amp;quot;,&lt;br /&gt;
                        &amp;quot;color&amp;quot; : getPart(token_id,1),&lt;br /&gt;
                    });&lt;br /&gt;
                    return tokenDiv;&lt;br /&gt;
             &lt;br /&gt;
                case &#039;meeple&#039;:&lt;br /&gt;
                    if ($(token_id)) {&lt;br /&gt;
                        var clone = dojo.clone($(token_id));&lt;br /&gt;
    &lt;br /&gt;
                        dojo.attr(clone, &amp;quot;id&amp;quot;, logid);&lt;br /&gt;
                        this.stripPosition(clone);&lt;br /&gt;
                        dojo.addClass(clone, &amp;quot;logitem&amp;quot;);&lt;br /&gt;
                        return clone.outerHTML;&lt;br /&gt;
                    }&lt;br /&gt;
                    break;&lt;br /&gt;
     &lt;br /&gt;
                default:&lt;br /&gt;
                    break;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            return &amp;quot;&#039;&amp;quot; + this.clienttranslate_string(this.getTokenName(token_id)) + &amp;quot;&#039;&amp;quot;;&lt;br /&gt;
       },&lt;br /&gt;
       getTokenName : function(key) {&lt;br /&gt;
           return this.gamedatas.token_types[key].name; // get name for the key, from static table for example&lt;br /&gt;
       },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that in this case the server simply injects token_id as a name, and the client substitutes it for the translated name or the picture.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ggg.game.php:&lt;br /&gt;
&lt;br /&gt;
           $this-&amp;gt;notifyAllPlayers(&#039;playerLog&#039;,clienttranslate(&#039;Game moves ${token_name}&#039;),[&#039;token_name&#039;=&amp;gt;$token_id]);&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important:&#039;&#039;&#039; As noted above, only arguments actually passed by this method are available to the args parameter received in the client-side &#039;&#039;format_string_recursive&#039;&#039; method.&lt;br /&gt;
&lt;br /&gt;
Sometimes it is the case that you want to pass arguments that are not actually included in the output message. For example, suppose we have a method like this:&lt;br /&gt;
&lt;br /&gt;
           $this-&amp;gt;notifyAllPlayers(&#039;tokenPlaced&#039;,clienttranslate(&#039;Player placed ${token_name}&#039;),array(&lt;br /&gt;
              &#039;token_name&#039; =&amp;gt; $token_id,&lt;br /&gt;
              &#039;zone_played&#039; =&amp;gt; $zone);&lt;br /&gt;
&lt;br /&gt;
This will output &amp;quot;Player placed ${token_name}&amp;quot; in the log, and if we subscribe to a notification method activated by the &amp;quot;tokenPlaced&amp;quot; event in the client-side code, that method can make use of the &#039;zone_played&#039; argument. &lt;br /&gt;
&lt;br /&gt;
Now if you want to make some really cool things with game log, most probably you would need more arguments than are included in log message. The problem with that,&lt;br /&gt;
it will work at first, but if you reload game using F5 or when the game loads in turn based mode, you will loose your additional parameters, why? Because when game reloads it does not actually send same notifications, it sends special &amp;quot;hitstorical_log&amp;quot; notification where all  parameters not listed in the message are removed. In example above, field zone_played would be removed from historical log as it is not included in message of the notification. You can till preserve specific arguments in historical log by adding special field preserve to notification arguments like this:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
           $this-&amp;gt;notifyAllPlayers(&#039;tokenPlaced&#039;,clienttranslate(&#039;Player placed ${token_name}&#039;),array(&lt;br /&gt;
              &#039;token_name&#039; =&amp;gt; $token_id,&lt;br /&gt;
              &#039;zone_played&#039; =&amp;gt; $zone,&lt;br /&gt;
              &#039;preserve&#039; =&amp;gt; [ &#039;zone_played&#039; ]&lt;br /&gt;
           );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now you can use zone_played in format_string_recursive even in historical logs.&lt;br /&gt;
&lt;br /&gt;
===== Second way: rely on the &amp;lt;code&amp;gt;:formatFunction&amp;lt;/code&amp;gt; option provided by &amp;lt;code&amp;gt;dojo.string.substitute&amp;lt;/code&amp;gt; =====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, ggg.game.php, ggg_ggg.tpl, ggg.css&lt;br /&gt;
&lt;br /&gt;
The above method will work in most of the cases, but if you use dotted keys such as &amp;lt;code&amp;gt;${card.name}&amp;lt;/code&amp;gt; (which is supported by the framework, for private state args), the key won&#039;t be substituted because the &amp;lt;code&amp;gt;key in arg&amp;lt;/code&amp;gt; test will fail. If so you need to rely either on this way, or the one after.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;WARNING:&#039;&#039;&#039; using this method on an already advanced project will require you to go through all your notifications to change keys !&lt;br /&gt;
&lt;br /&gt;
Under the hood, the &#039;&#039;&#039;this.format_string_recursive()&#039;&#039;&#039; function calls the &#039;&#039;&#039;dojo.string.substitute&#039;&#039;&#039; method which substitutes &amp;lt;code&amp;gt;${keys}&amp;lt;/code&amp;gt; with the value provided. If you take a look at the [https://dojotoolkit.org/reference-guide/1.7/dojo/string.html#substitute documentation] and [https://github.com/dojo/dojo/blob/c3ceb017cfa25b703f5662dc83d1c8aae9bc5d81/string.js#L163 source code] you can notice that the key can be suffixed with a colon (&amp;lt;code&amp;gt;:&amp;lt;/code&amp;gt;) followed by a function name. This will allow you to specify directly in the substitution string which keys need HTML injection.&lt;br /&gt;
&lt;br /&gt;
First of all, you need to define your formatting function in the ggg.js file:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[[ggg.js]]&lt;br /&gt;
        getTokenDiv : function(value, key) {&lt;br /&gt;
            //This is only an example implementation, you need to write your own.&lt;br /&gt;
            //The method should return HTML code&lt;br /&gt;
            switch (key) {&lt;br /&gt;
                case &#039;html_injected_argument1&#039;:&lt;br /&gt;
                    return this.format_block(&#039;jstpl_HTMLLogElement1&#039;,{value: value});&lt;br /&gt;
                case &#039;html_injected_argument2&#039;:&lt;br /&gt;
                    return this.format_block(&#039;jstpl_HTMLLogElement2&#039;,{value: value});&lt;br /&gt;
                ...&lt;br /&gt;
            }&lt;br /&gt;
       }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Obviously you need to define the appropriate templates in the ggg_ggg.tpl file:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[[ggg_ggg.tpl]]&lt;br /&gt;
let jstpl_HTMLLogElement1 = &#039;&amp;lt;div class=&amp;quot;log-element log-element-1-${value}&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
let jstpl_HTMLLogElement2 = &#039;&amp;lt;div class=&amp;quot;log-element log-element-2-${value}&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
And the appropriate classes in ggg.css.&lt;br /&gt;
&lt;br /&gt;
Then you need to add the &amp;lt;code&amp;gt;dojo/aspect&amp;lt;/code&amp;gt; module at the top of the ggg.js file:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[ggg.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 define([&lt;br /&gt;
     &amp;quot;dojo&amp;quot;, &amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&amp;quot;dojo/aspect&amp;quot;,&amp;lt;/span&amp;gt;                 //MUST BE IN THIRD POSITION&#039;&#039;&#039; (see [[#Including your own JavaScript module (II)|below]])&lt;br /&gt;
     &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
 ], function (dojo, declare, &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&#039;&#039;&#039;aspect&#039;&#039;&#039;&amp;lt;/span&amp;gt;) {&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
And you also need to add the following code in your &amp;lt;code&amp;gt;contructor&amp;lt;/code&amp;gt; method in the ggg.js:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[ggg.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
         constructor: function(){&lt;br /&gt;
             console.log(&#039;progressevolutiontechnologyswh constructor&#039;);&lt;br /&gt;
               &lt;br /&gt;
             // Here, you can init the global variables of your user interface&lt;br /&gt;
             // Example:&lt;br /&gt;
             // this.myGlobalValue = 0;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&#039;&#039;&#039;let gameObject = this;&#039;&#039;&#039;            //Needed as the this object in aspect.before will not refer to the game object in which the formatting function resides&lt;br /&gt;
             &#039;&#039;&#039;aspect.before(dojo.string, &amp;quot;substitute&amp;quot;, function(template, map, transform) {&#039;&#039;&#039;      //This allow you to modify the arguments of the dojo.string.substitute method before they&#039;re actually passed to it&lt;br /&gt;
                 &#039;&#039;&#039;return [template, map, transform, gameObject];&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now you&#039;re all set to inject HTML in your logs.&lt;br /&gt;
&lt;br /&gt;
===== Third way: rely on the &amp;lt;code&amp;gt;transform&amp;lt;/code&amp;gt; argument of &amp;lt;code&amp;gt;dojo.string.substitute&amp;lt;/code&amp;gt; =====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, ggg.game.php, ggg_ggg.tpl, ggg.css&lt;br /&gt;
&lt;br /&gt;
This method is also relying on the use of &amp;lt;code&amp;gt;dojo.string.substitute&amp;lt;/code&amp;gt; by the framework, and will use the &amp;lt;code&amp;gt;transform&amp;lt;/code&amp;gt; argument, which, accordting to [https://github.com/dojo/dojo/blob/c3ceb017cfa25b703f5662dc83d1c8aae9bc5d81/string.js#L163 source code] and [https://dojotoolkit.org/reference-guide/1.7/dojo/string.html#substitute documentation] will be run on all the messages going through dojo.string.substitute.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;WARNING:&#039;&#039;&#039; As this method will be applied to all strings that go through dojo.string.substitute. As such you must take extra care not to substitute keys that may be used by the framework (i.e. ${id}). In order to do so, a good practise would be to prefix all keys that need substitution with a trigram of the game name.&lt;br /&gt;
&lt;br /&gt;
Since all the keys will be fed to the tranform function, by default, it must return the value, substituted or not per your needs. You can define the function like this in the ggg.js file:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[ggg.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
         getTokenDiv : function(value, key) {&lt;br /&gt;
             //This is only an example implementation, you need to write your own.&lt;br /&gt;
             //The method should return HTML code&lt;br /&gt;
             switch (key) {&lt;br /&gt;
                 case &#039;html_injected_argument1&#039;:&lt;br /&gt;
                     return this.format_block(&#039;jstpl_HTMLLogElement1&#039;,{value: value});&lt;br /&gt;
                 case &#039;html_injected_argument2&#039;:&lt;br /&gt;
                     return this.format_block(&#039;jstpl_HTMLLogElement2&#039;,{value: value});&lt;br /&gt;
                 ...&lt;br /&gt;
                 &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&#039;&#039;&#039;default:&#039;&#039;&#039;&lt;br /&gt;
                     &#039;&#039;&#039;return value;&#039;&#039;&#039;&amp;lt;/span&amp;gt;                  &#039;&#039;&#039;//Needed otherwise regular strings won&#039;t appear since since the value isn&#039;t returned by the function&#039;&#039;&#039;&lt;br /&gt;
             }&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
The templates must be defined in the ggg_ggg.tpl file and the corresponding CSS classes in the ggg.css file.&lt;br /&gt;
&lt;br /&gt;
You need to add the following code at the beginning of the ggg.js file:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[ggg.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 define([&lt;br /&gt;
     &amp;quot;dojo&amp;quot;, &amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&amp;quot;dojo/aspect&amp;quot;,&amp;lt;/span&amp;gt;                 //MUST BE IN THIRD POSITION&#039;&#039;&#039; (see [[#Including your own JavaScript module (II)|below]])&lt;br /&gt;
     &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
 ], function (dojo, declare, &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&#039;&#039;&#039;aspect&#039;&#039;&#039;&amp;lt;/span&amp;gt;) {&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
And the following code to the &amp;lt;code&amp;gt;constructor&amp;lt;/code&amp;gt; method in ggg.js:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[[ggg.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
         constructor: function(){&lt;br /&gt;
             console.log(&#039;progressevolutiontechnologyswh constructor&#039;);&lt;br /&gt;
               &lt;br /&gt;
             // Here, you can init the global variables of your user interface&lt;br /&gt;
             // Example:&lt;br /&gt;
             // this.myGlobalValue = 0;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&#039;&#039;&#039;let transformFunction = dojo.hitch(this, &amp;quot;getTokenDiv&amp;quot;);&#039;&#039;&#039;            //Needed as the this object in aspect.before will not refer to the game object in which the formatting function resides&lt;br /&gt;
             &#039;&#039;&#039;aspect.before(dojo.string, &amp;quot;substitute&amp;quot;, function(template, map, transform) {&#039;&#039;&#039;&lt;br /&gt;
                 &#039;&#039;&#039;if (undefined === transform) {&#039;&#039;&#039;                                   //Check for a transform function presence, just in case&lt;br /&gt;
                     &#039;&#039;&#039;return [template, map, transform];&#039;&#039;&#039;&lt;br /&gt;
                 &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Processing logs on re-loading ====&lt;br /&gt;
&lt;br /&gt;
You rarely need to process logs when reloading, but if you want to do something fancy you may have to do it after logs are loaded. &lt;br /&gt;
Logs are loaded asyncronously so you have to listen for logs to be fully loaded.&lt;br /&gt;
Unfortunately there is no direct way of doing it so this is the hack.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Hack alert&#039;&#039;&#039; - this extends undocumented function and may be broken when framework is updated&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
			/*&lt;br /&gt;
  			* [Undocumented] Override BGA framework functions to call onLoadingLogsComplete when loading is done&lt;br /&gt;
                        @Override&lt;br /&gt;
   			*/&lt;br /&gt;
			setLoader: function(image_progress, logs_progress) {&lt;br /&gt;
				this.inherited(arguments); // required, this is &amp;quot;super()&amp;quot; call, do not remove&lt;br /&gt;
				//console.log(&amp;quot;loader&amp;quot;, image_progress, logs_progress)&lt;br /&gt;
				if (!this.isLoadingLogsComplete &amp;amp;&amp;amp; logs_progress &amp;gt;= 100) {&lt;br /&gt;
					this.isLoadingLogsComplete = true; // this is to prevent from calling this more then once&lt;br /&gt;
					this.onLoadingLogsComplete();&lt;br /&gt;
				}&lt;br /&gt;
			},&lt;br /&gt;
&lt;br /&gt;
			onLoadingLogsComplete: function() {&lt;br /&gt;
				console.log(&#039;Loading logs complete&#039;);&lt;br /&gt;
				// do something here&lt;br /&gt;
			},&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Player Panel ===&lt;br /&gt;
&lt;br /&gt;
==== Inserting non-player panel ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, ggg_ggg.tpl&lt;br /&gt;
&lt;br /&gt;
If you want to insert non-player panel on the right side (for example to hold extra preferences, zooming controls, etc)&lt;br /&gt;
&lt;br /&gt;
this can go pretty much anywhere in template it will be moved later&lt;br /&gt;
&lt;br /&gt;
ggg_ggg.tpl:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	&amp;lt;div class=&#039;player_board_config&#039; id=&amp;quot;player_board_config&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;!-- here is whatever you want, buttons just example --&amp;gt;&lt;br /&gt;
		&amp;lt;button id=&amp;quot;zoom-out&amp;quot; class=&amp;quot; fa fa-search-minus fa-2x config-control&amp;quot;&amp;gt;&amp;lt;/button&amp;gt;&lt;br /&gt;
		&amp;lt;button id=&amp;quot;zoom-in&amp;quot; class=&amp;quot; fa fa-search-plus fa-2x config-control&amp;quot;&amp;gt;&amp;lt;/button&amp;gt;&lt;br /&gt;
		&amp;lt;button id=&amp;quot;show-settings&amp;quot; class=&amp;quot;fa fa-cog fa-2x config-control &amp;quot;&amp;gt;&amp;lt;/button&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
some hackery required in js&lt;br /&gt;
&lt;br /&gt;
ggg.js:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* @Override */&lt;br /&gt;
	updatePlayerOrdering() {&lt;br /&gt;
		this.inherited(arguments);&lt;br /&gt;
		dojo.place(&#039;player_board_config&#039;, &#039;player_boards&#039;, &#039;first&#039;);&lt;br /&gt;
	},&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Images and Icons ===&lt;br /&gt;
&lt;br /&gt;
==== Accessing images from js ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
     // your game resources&lt;br /&gt;
     &lt;br /&gt;
     var my_img = &#039;&amp;lt;img src=&amp;quot;&#039;+g_gamethemeurl+&#039;img/cards.jpg&amp;quot;/&amp;gt;&#039;;&lt;br /&gt;
     &lt;br /&gt;
     // shared resources&lt;br /&gt;
     var my_help_img = &amp;quot;&amp;lt;img class=&#039;imgtext&#039; src=&#039;&amp;quot; + g_themeurl + &amp;quot;img/layout/help_click.png&#039; alt=&#039;action&#039; /&amp;gt; &amp;lt;span class=&#039;tooltiptext&#039;&amp;gt;&amp;quot; +&lt;br /&gt;
                    text + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== High-Definition Graphics ====&lt;br /&gt;
&lt;br /&gt;
Some users will have screens which can display text and images at a greater resolution than the usual 72 dpi, e.g. the &amp;quot;Retina&amp;quot; screens on the 5k iMac, all iPads, and high-DPI screens on laptops from many manufacturers. If you can get art assets at this size, they will make your game look extra beautiful. You &#039;&#039;could&#039;&#039; just use large graphics and scale them down, but that would increase the download time and bandwidth for users who can&#039;t display them. Instead, a good way is to prepare a separate graphics file at exactly twice the size you would use otherwise, and add &amp;quot;@2x&amp;quot; at the end of the filename, e.g. if pieces.png is 240x320, then pieces@2x.png is 480x640.&lt;br /&gt;
&lt;br /&gt;
There are two changes required in order to use the separate graphics files. First in your css, where you use a file, add a media query which overrides the original definition and uses the bigger version on devices which can display them. Ensuring that the &amp;quot;background-size&amp;quot; attribute is set means that the size of the displayed object doesn&#039;t change, but only is drawn at the improved dot pitch.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.piece {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    background-image: url(&#039;img/pieces.png&#039;);&lt;br /&gt;
    background-size:240px 320px;&lt;br /&gt;
    z-index: 10;&lt;br /&gt;
}&lt;br /&gt;
@media (-webkit-min-device-pixel-ratio: 2), (min-device-pixel-ratio: 2), (min-resolution: 192dpi)&lt;br /&gt;
{&lt;br /&gt;
    .piece {&lt;br /&gt;
        background-image: url(&#039;img/pieces@2x.png&#039;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Secondly, in your setup function in javascript, you must ensure than only the appropriate one version of the file gets pre-loaded (otherwise you more than waste the bandwidth saved by maintaining the standard-resolution file). Note that the media query is the same in both cases:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
            var isRetina = &amp;quot;(-webkit-min-device-pixel-ratio: 2), (min-device-pixel-ratio: 2), (min-resolution: 192dpi)&amp;quot;;&lt;br /&gt;
            if (window.matchMedia(isRetina).matches)&lt;br /&gt;
            {&lt;br /&gt;
                this.dontPreloadImage( &#039;pieces.png&#039; );&lt;br /&gt;
                this.dontPreloadImage( &#039;board.jpg&#039; );&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                this.dontPreloadImage( &#039;pieces@2x.png&#039; );&lt;br /&gt;
                this.dontPreloadImage( &#039;board@2x.jpg&#039; );&lt;br /&gt;
            }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using CSS to create different colors of game pieces if you have only white piece ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
background-color: #${color}; &lt;br /&gt;
background-blend-mode: multiply;&lt;br /&gt;
background-image: url( &#039;img/mypiece.png&#039;);&lt;br /&gt;
mask: url(&#039;img/mypiece.png&#039;);&lt;br /&gt;
-webkit-mask: url(&#039;img/mypiece.png&#039;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where ${color} - is color you want&lt;br /&gt;
&lt;br /&gt;
Note: piece has to be white (shades of gray). Sprite can be used too, just add add blackground-position as usuall.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Other Fluff ===&lt;br /&gt;
&lt;br /&gt;
==== Use thematic fonts ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.css&lt;br /&gt;
&lt;br /&gt;
Sometime game elements use specific fonts of text, if you want to match it up you can load some specific font (IMPORTANT: from some &#039;&#039;&#039;free font&#039;&#039;&#039; source. See notes below).&lt;br /&gt;
&lt;br /&gt;
[[File:Dragonline_font.png]]&lt;br /&gt;
&lt;br /&gt;
.css&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* latin-ext */&lt;br /&gt;
@font-face {&lt;br /&gt;
  font-family: &#039;Qwigley&#039;;&lt;br /&gt;
  font-style: normal;&lt;br /&gt;
  font-weight: 400;&lt;br /&gt;
  src: local(&#039;Qwigley&#039;), local(&#039;Qwigley-Regular&#039;), url(https://fonts.gstatic.com/s/qwigley/v6/2Dy1Unur1HJoklbsg4iPJ_Y6323mHUZFJMgTvxaG2iE.woff2) format(&#039;woff2&#039;);&lt;br /&gt;
  unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;&lt;br /&gt;
}&lt;br /&gt;
/* latin */&lt;br /&gt;
@font-face {&lt;br /&gt;
  font-family: &#039;Qwigley&#039;;&lt;br /&gt;
  font-style: normal;&lt;br /&gt;
  font-weight: normal;&lt;br /&gt;
  src: local(&#039;Qwigley&#039;), local(&#039;Qwigley-Regular&#039;), url(https://fonts.gstatic.com/s/qwigley/v6/gThgNuQB0o5ITpgpLi4Zpw.woff2) format(&#039;woff2&#039;);&lt;br /&gt;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;&lt;br /&gt;
}&lt;br /&gt;
@font-face {&lt;br /&gt;
  font-family: &#039;Qwigley&#039;;&lt;br /&gt;
  font-style: normal;&lt;br /&gt;
  font-weight: normal;&lt;br /&gt;
  src: local(&#039;Qwigley&#039;), local(&#039;Qwigley-Regular&#039;), url(http://ff.static.1001fonts.net/q/w/qwigley.regular.ttf) format(&#039;ttf&#039;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.zone_title {&lt;br /&gt;
	display: inline-block;&lt;br /&gt;
	position: absolute;&lt;br /&gt;
	font: italic 32px/32px &amp;quot;Qwigley&amp;quot;, cursive;	   &lt;br /&gt;
	height: 32px;&lt;br /&gt;
	width: auto;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NB:&#039;&#039;&#039; if you need to include a font that&#039;s not available online, an extra action will be needed from an admin. Please include the font file(s) in your img directory, and mention it to admins when requesting your game to be moved to alpha. &#039;&#039;&#039;Please remember that the font has to be free, and include a .txt with all appropriate license information about the font.&#039;&#039;&#039;&lt;br /&gt;
You can look for free fonts (for example) on https://fonts.google.com or https://www.fontsquirrel.com/)&lt;br /&gt;
&lt;br /&gt;
=== Use player color in template ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg_ggg.tpl, ggg.view.php&lt;br /&gt;
&lt;br /&gt;
.view.php:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    function build_page($viewArgs) {&lt;br /&gt;
        // Get players &amp;amp; players number&lt;br /&gt;
        $players = $this-&amp;gt;game-&amp;gt;loadPlayersBasicInfos();&lt;br /&gt;
        $players_nbr = count($players);&lt;br /&gt;
        /**&lt;br /&gt;
         * ********* Place your code below: ***********&lt;br /&gt;
         */&lt;br /&gt;
        &lt;br /&gt;
        // Set PCOLOR to the current player color hex&lt;br /&gt;
        global $g_user;&lt;br /&gt;
        $cplayer = $g_user-&amp;gt;get_id();&lt;br /&gt;
        if (array_key_exists($cplayer, $players)) { // may be not set if spectator&lt;br /&gt;
            $player_color = $players [$cplayer] [&#039;player_color&#039;];&lt;br /&gt;
        } else {&lt;br /&gt;
            $player_color = &#039;ffffff&#039;; // spectator&lt;br /&gt;
        }&lt;br /&gt;
        $this-&amp;gt;tpl [&#039;PCOLOR&#039;] = $player_color;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Scale to fit for big boards ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg_ggg.tpl, ggg.js&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Lets say you have huge game board, and lets say you want it to be 1400px wide. Besides the board there will be side bar which is 240 and trim. &lt;br /&gt;
My display is 1920 wide so it fits, but there is big chance other people won&#039;t have that width. What do you do?&lt;br /&gt;
&lt;br /&gt;
You have to decide:&lt;br /&gt;
* If board does not fit you want scale whole thing down, the best way is probably use viewport (see https://en.doc.boardgamearena.com/Your_game_mobile_version)&lt;br /&gt;
* You can leave the board as is and make sure it is scrollable horizonatally&lt;br /&gt;
* You add custom scale just for the board (can add user controls  - and hook to transform: scale())&lt;br /&gt;
&lt;br /&gt;
I tried to auto-scale but this just does work, too many variables - browser zoom, 3d mode, viewport, custom bga scaling, devicePixelRatio - all create some impossible coctail of zooming...&lt;br /&gt;
Here is scaling functing for custom user scaling&lt;br /&gt;
&lt;br /&gt;
ggg_ggg.tpl:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   &amp;lt;div id=&amp;quot;thething&amp;quot; class=&amp;quot;thething&amp;quot;&amp;gt;&lt;br /&gt;
            ... everything else you declare ...&lt;br /&gt;
   &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ggg.js:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    onZoomPlus: function() {&lt;br /&gt;
       this.my_zoom+=0.1;&lt;br /&gt;
       this.zoommy(&#039;thething&#039;,this.my_zoom);&lt;br /&gt;
    },&lt;br /&gt;
&lt;br /&gt;
    zoommy: function(node, zoom) {&lt;br /&gt;
                node=$(node);&lt;br /&gt;
		var width = 100 / zoom;&lt;br /&gt;
		node.style.transformOrigin = &amp;quot;0 0&amp;quot;;&lt;br /&gt;
		node.style.transform = &amp;quot;scale(&amp;quot; + zoom + &amp;quot;)&amp;quot;;&lt;br /&gt;
		node.style.width = width + &amp;quot;%&amp;quot;;&lt;br /&gt;
    },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Dynamic tooltips ===&lt;br /&gt;
&lt;br /&gt;
If you really need a dynamic tooltip you can use this technique. (Only use it if the static tooltips provided by the BGA framework are not sufficient.)&lt;br /&gt;
&lt;br /&gt;
            new dijit.Tooltip({&lt;br /&gt;
                connectId: [&amp;quot;divItemId&amp;quot;],&lt;br /&gt;
                getContent: function(matchedNode){&lt;br /&gt;
                    return &amp;quot;... calculated ...&amp;quot;; &lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is an out-of-the-box djit.Tooltip. It has a &#039;&#039;getContent&#039;&#039; method which is called dynamically.&lt;br /&gt;
&lt;br /&gt;
The string function return becomes the innerHTML of the tooltip, so it can be anything. In this example matchedNode is a dojo node representing dom object with id of &amp;quot;divItemId&amp;quot; but there are more parameters which I am not posting here which allows more sophisticated subnode queries (i.e. you can attach tooltip to all nodes with class or whatever).&lt;br /&gt;
&lt;br /&gt;
[https://dojotoolkit.org/reference-guide/1.10/dijit/Tooltip.html dijit.Tooltip]&lt;br /&gt;
&lt;br /&gt;
It&#039;s not part of the BGA API so use at your own risk.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Rendering text with players color and proper background ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
This example actually writes &amp;quot;You&amp;quot; but you can replace this with player name as easily, drop translating function in this case&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        /* Implementation of proper colored You with background in case of white or light colors  */&lt;br /&gt;
 &lt;br /&gt;
        divYou : function() {&lt;br /&gt;
            var color = this.gamedatas.players[this.player_id].color;&lt;br /&gt;
            var color_bg = &amp;quot;&amp;quot;;&lt;br /&gt;
            if (this.gamedatas.players[this.player_id] &amp;amp;&amp;amp; this.gamedatas.players[this.player_id].color_back) {&lt;br /&gt;
                color_bg = &amp;quot;background-color:#&amp;quot; + this.gamedatas.players[this.player_id].color_back + &amp;quot;;&amp;quot;;&lt;br /&gt;
            }&lt;br /&gt;
            var you = &amp;quot;&amp;lt;span style=\&amp;quot;font-weight:bold;color:#&amp;quot; + color + &amp;quot;;&amp;quot; + color_bg + &amp;quot;\&amp;quot;&amp;gt;&amp;quot; + __(&amp;quot;lang_mainsite&amp;quot;, &amp;quot;You&amp;quot;) + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
            return you;&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Cool realistic shadow effect with CSS ===&lt;br /&gt;
&lt;br /&gt;
==== Rectangles and circles ====&lt;br /&gt;
&lt;br /&gt;
It is often nice to have a drop shadow around tiles and tokens, to separate them from the table visually. It is very easy to add a shadow to rectangular elements, just add this to your css:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.xxx-tile {&lt;br /&gt;
    box-shadow: 3px 3px 3px #000000a0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
box-shadow obeys &#039;&#039;&#039;border-radius&#039;&#039;&#039; of the element, so it will look good for rounded rectangles, and hence also circles (if border-radius is set appropriately).&lt;br /&gt;
&lt;br /&gt;
box-shadow also supports various other parameters and can be used to achieve effects such as glowing, borders, inner shadows etc. If you need to animate a box-shadow, you may be able to get better performance (avoiding redraws) if you attach the shadow to another element (possibly an ::after pseudo-element) and change only the &#039;&#039;&#039;opacity&#039;&#039;&#039; of that element.&lt;br /&gt;
&lt;br /&gt;
==== Irregular Shapes ====&lt;br /&gt;
&lt;br /&gt;
If you wish to make a shadow effect for game pieces that are not a rectangle, but your game pieces are drawn from rectangles in a PNG image, you can apply the shadow to the piece using any art package and save it inside the image. This usually will yield the best performance. Remember to account for the size of the shadow when you lay out images in the sprite sheet.&lt;br /&gt;
&lt;br /&gt;
However that sometimes will not be an option, for example if the image needs to be rotated while the shadow remains offset in the same direction. In this case, one option is to not use box-shadow but use filter, which is supported by recent major browsers.  This way, you can use the alpha channel of your element to drop a shadow.  This even work for transparent backgrounds, so that if you are using the &amp;quot;CSS-sprite&amp;quot; method, it will work!&lt;br /&gt;
&lt;br /&gt;
For instance:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.xxx-token {&lt;br /&gt;
    filter: drop-shadow(0px 0px 1px #000000);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beware that some browsers still do not always draw drop-shadow correctly. In particular, Safari frequently leaves bits of shadow behind when objects move around the screen. In Chrome, shadows sometimes flicker badly if another element is animating close by. Some of these correctness issues can be solved by adding &#039;&#039;&#039;isolation: isolate; will-change: filter;&#039;&#039;&#039; to affected elements, but this significantly affects redraw performance.&lt;br /&gt;
&lt;br /&gt;
Beware of performance issues - particularly on Safari (MacOS, iPhone and iPad). Keep in mind that drop-shadow are very GPU intensive. This becomes noticeable once you have about 40 components with drop-shadow filter. If that is your case, you can quite easily implement a user preference to disable shadows for users on slower machines:&lt;br /&gt;
&lt;br /&gt;
gameoptions.inc.php&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
100 =&amp;gt; array(&lt;br /&gt;
			&#039;name&#039; =&amp;gt; totranslate(&#039;Shadows&#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;Enabled&#039; ), &#039;cssPref&#039; =&amp;gt; &#039;&#039; ),&lt;br /&gt;
					2 =&amp;gt; array( &#039;name&#039; =&amp;gt; totranslate( &#039;Disabled&#039; ), &#039;cssPref&#039; =&amp;gt; &#039;no-shadow&#039; )&lt;br /&gt;
			)&lt;br /&gt;
	),&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[game].css&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.no-shadow * {&lt;br /&gt;
	filter: none !important; &lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Shadows with clip-path ====&lt;br /&gt;
&lt;br /&gt;
For some reason, a shadow will not work together with clip-path on one element. To use both clip-path (when for example using .svg to cut out cardboard components from your .jpg spritesheet) and drop-shadow, you need to wrap the element into another one, and apply drop-shadow to the outer one, and clip-path to the inner one.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;div class=&#039;my-token-wrap&#039;&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&#039;my-token&#039;&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;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.my-token-wrap {&lt;br /&gt;
    filter: drop-shadow(0px 0px 1px #000000);&lt;br /&gt;
}&lt;br /&gt;
.my-token-wrap .my-token {&lt;br /&gt;
    clip-path: url(#my-token-path);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Using the CSS classes from the state machine ===&lt;br /&gt;
&lt;br /&gt;
If you need to hide or show stuff depending on the state of your game, you can of course use javascript, but CSS is hand enough for that.  The #overall-content element does change class depending on the game state.  For instance, if you are in state &#039;&#039;playerTurn&#039;&#039;, it will have the class &#039;&#039;gamestate_playerTurn&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
So now, if you want to show the discard pile only during player turns, you may use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#discard_pile { display: none }&lt;br /&gt;
.gamestate_playerTurn #discard_pile { display: block }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This can be used if you want to change sizing of elements, position, layout or visual appearance.&lt;br /&gt;
&lt;br /&gt;
== Game Model and Database design ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Database for The euro game ===&lt;br /&gt;
Lets say we have a game with workers, dice, tokens, board, resources, money and vp. Workers and dice can be placed in various zones on the board, and you can get resources, money, tokens and vp in your home zone. Also tokens can be flipped or not flipped.&lt;br /&gt;
&lt;br /&gt;
[[File:Madeira board.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now lets try to map it, we have&lt;br /&gt;
* (meeple,zone)&lt;br /&gt;
* (die, zone, sideup)&lt;br /&gt;
* (resource cube/money token/vp token,player home zone)&lt;br /&gt;
* (token, player home zone, flip state)&lt;br /&gt;
We can notice that resource and money are uncountable, and don&#039;t need to be track individually so we can replace our mapping to&lt;br /&gt;
* (resource type/money,player home zone, count)&lt;br /&gt;
And vp stored already for us in player table, so we can remove it from that list.&lt;br /&gt;
&lt;br /&gt;
Now when we get to encode it we can see that everything can be encoded as (object,zone,state) form, where object and zone is string and state is integer. The resource mapping is slightly different semantically so you can go with two table, or counting using same table with state been used as count for resources.&lt;br /&gt;
&lt;br /&gt;
So the piece mapping for non-grid based games can be in most case represented by (string: token_key, string: token_location, int: token_state), example of such database schema can be found here: [https://github.com/elaskavaia/bga-sharedcode/blob/master/dbmodel.sql dbmodel.sql] and class implementing access to it here [https://github.com/elaskavaia/bga-sharedcode/blob/master/modules/tokens.php table.game.php].&lt;br /&gt;
&lt;br /&gt;
Variant 1: Minimalistic&lt;br /&gt;
&lt;br /&gt;
 CREATE TABLE IF NOT EXISTS `token` (&lt;br /&gt;
  `token_key` varchar(32) NOT NULL,&lt;br /&gt;
  `token_location` varchar(32) NOT NULL,&lt;br /&gt;
  `token_state` int(10),&lt;br /&gt;
  PRIMARY KEY (`token_key`)&lt;br /&gt;
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+token&lt;br /&gt;
! token_key&lt;br /&gt;
! token_location&lt;br /&gt;
! token_state&lt;br /&gt;
|-&lt;br /&gt;
|meeple_red_1&lt;br /&gt;
|home_red&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
|dice_black_2&lt;br /&gt;
|board_guard&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
|dice_green_1&lt;br /&gt;
|board_action_mayor&lt;br /&gt;
|3&lt;br /&gt;
|-&lt;br /&gt;
|bread&lt;br /&gt;
|home_red&lt;br /&gt;
|5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Now how we represent resource counters such as bread?&lt;br /&gt;
Using same table from we simply add special counter token for bread and use state to indicate the count. Note to keep first column unique we have to add player identification for that counter, i.e. ff0000 is red player.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+token&lt;br /&gt;
! token_key&lt;br /&gt;
! token_location&lt;br /&gt;
! token_state&lt;br /&gt;
|-&lt;br /&gt;
|bread_ff0000&lt;br /&gt;
|tableau_ff0000&lt;br /&gt;
|5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See php module for this table here https://github.com/elaskavaia/bga-sharedcode/blob/master/modules/tokens.php&lt;br /&gt;
&lt;br /&gt;
Variant 2: Additional resource table, resource count for each player id&lt;br /&gt;
&lt;br /&gt;
 CREATE TABLE IF NOT EXISTS `resource` (&lt;br /&gt;
  `player_id` int(10) unsigned NOT NULL,&lt;br /&gt;
  `resource_key` varchar(32) NOT NULL,&lt;br /&gt;
  `resource_count` int(10) signed NOT NULL,&lt;br /&gt;
  PRIMARY KEY (`player_id`,`resource_key`)&lt;br /&gt;
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;&lt;br /&gt;
&lt;br /&gt;
 ALTER TABLE resource ADD CONSTRAINT fk_player_id FOREIGN KEY (player_id) REFERENCES player(player_id);&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+resource&lt;br /&gt;
! player_id&lt;br /&gt;
! resource_key&lt;br /&gt;
! resource_count&lt;br /&gt;
|-&lt;br /&gt;
|123456&lt;br /&gt;
|bread&lt;br /&gt;
|5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Variant 3: More normalised&lt;br /&gt;
&lt;br /&gt;
This version is similar to &amp;quot;card&amp;quot; table from hearts tutorial, you can also use exact cards database schema and Deck implementation for most purposes (even you not dealing with cards). &lt;br /&gt;
&lt;br /&gt;
 CREATE TABLE IF NOT EXISTS `token` (&lt;br /&gt;
  `token_id` int(10) unsigned NOT NULL AUTO_INCREMENT,&lt;br /&gt;
  `token_type` varchar(16) NOT NULL,&lt;br /&gt;
  `token_arg` int(11) NOT NULL,&lt;br /&gt;
  `token_location` varchar(32) NOT NULL,&lt;br /&gt;
  `token_state` int(10),&lt;br /&gt;
  PRIMARY KEY (`token_id`)&lt;br /&gt;
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+token&lt;br /&gt;
! token_id&lt;br /&gt;
! token_type&lt;br /&gt;
! token_arg&lt;br /&gt;
! token_location&lt;br /&gt;
! token_state&lt;br /&gt;
|-&lt;br /&gt;
|22&lt;br /&gt;
|meeple&lt;br /&gt;
|123456&lt;br /&gt;
|home_123456&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
|23&lt;br /&gt;
|dice&lt;br /&gt;
|2&lt;br /&gt;
|board_guard&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
|26&lt;br /&gt;
|dice&lt;br /&gt;
|1&lt;br /&gt;
|board_action_mayor&lt;br /&gt;
|3&lt;br /&gt;
|-&lt;br /&gt;
|49&lt;br /&gt;
|bread&lt;br /&gt;
|0&lt;br /&gt;
|home_123456&lt;br /&gt;
|5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Advantages of this would be is a bit more straightforward to do some queries in db, disadvantage its hard to read (as you can compare with previous example, you&lt;br /&gt;
cannot just look at say, ah I know what it means). Another questionable advantage is it allows you to do id randomisation, so it hard to do crafted queries to &lt;br /&gt;
cheat, the down side of that you cannot understand it either, and handcraft db states for debugging or testing.&lt;br /&gt;
&lt;br /&gt;
=== Database for The card game ===&lt;br /&gt;
&lt;br /&gt;
Lets say you have a standard card game, player have hidden cards in hand, you can draw card from draw deck, play card on tableau and discard to discard pile.&lt;br /&gt;
We have to design database for such game.&lt;br /&gt;
&lt;br /&gt;
In real word to &amp;quot;save&amp;quot; the game we take a picture a play area, save cards from it, then put away draw deck, discard and hand of each player separately and mark it, also we will record current scoring (if any) and who&#039;s turn was it.&lt;br /&gt;
&lt;br /&gt;
* Framework handles state machine transition, so you don&#039;t have to worry about database design for that (i.e. who&#039;s turn it is, what phase of the game we are at, you still have to design it but part of state machine step)&lt;br /&gt;
* Also framework supports basic player information, color, order around the table, basic scoring, etc, so you don&#039;t have to worry about it either&lt;br /&gt;
* The only thing you need in our database is state of the &amp;quot;board&amp;quot;, which is &amp;quot;where each pieces is, and in what state&amp;quot;, or (position,rotation) pair.&lt;br /&gt;
&lt;br /&gt;
Lets see what we have for that:&lt;br /&gt;
* The card state is very simple, its usually &amp;quot;face up/face down&amp;quot;, &amp;quot;tapped/untapped&amp;quot;, &amp;quot;right side up/up side down&amp;quot;&lt;br /&gt;
* As position go we never need real coordinates x,y,z. We need to know what &amp;quot;zone&amp;quot; card was, and depending on the zone it may sometimes need an extra &amp;quot;z&amp;quot; or &amp;quot;x&amp;quot; as card order. The zone position usually static or irrelevant.&lt;br /&gt;
* So our model is: we have cards, which have some attributes, at any given point in time they belong to a &amp;quot;zone&amp;quot;, and can also have order and state&lt;br /&gt;
* Now for mapping we should consider what information changes and what information is static, later is always candidate for material file&lt;br /&gt;
* For dynamic information we should try to reduce amount of fields we need&lt;br /&gt;
**  we need at least a field for card, so its one&lt;br /&gt;
**  we need to know what zone cards belong to, its 2&lt;br /&gt;
**  and we have possibly few other fields, if you look closely at you game you may find out that most of the zone only need one attribute at a time, i.e. draw pile always have cards face down, hand always face up, also for hand and discard order does not matter at all (but for draw it does matter). So in majority of cases we can get away with one single extra integer field representing state or order&lt;br /&gt;
* In real database both card and zone will be integers as primary keys referring to additional tables, but in our case its total overkill, so they can be strings as easily&lt;br /&gt;
&lt;br /&gt;
Variant 1: Minimalistic&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE TABLE IF NOT EXISTS `card` (&lt;br /&gt;
  `card_key` varchar(32) unsigned NOT NULL,&lt;br /&gt;
  `card_location` varchar(32) NOT NULL,&lt;br /&gt;
  `card_state` int(11) NOT NULL,&lt;br /&gt;
  PRIMARY KEY (`card_id`)&lt;br /&gt;
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Variant 2: More normalised&lt;br /&gt;
&lt;br /&gt;
This version supported by Deck php class, so unless you want to rewrite db access layer go with this one&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE TABLE IF NOT EXISTS `card` (&lt;br /&gt;
  `card_id` int(10) unsigned NOT NULL AUTO_INCREMENT,&lt;br /&gt;
  `card_type` varchar(16) NOT NULL,&lt;br /&gt;
  `card_type_arg` int(11) NOT NULL,&lt;br /&gt;
  `card_location` varchar(16) NOT NULL,&lt;br /&gt;
  `card_location_arg` int(11) NOT NULL,&lt;br /&gt;
  PRIMARY KEY (`card_id`)&lt;br /&gt;
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: if you using this schema, some zones/locations have special semantic. The &#039;hand&#039; location is actually multiple locations - one per player, but player id is encoded as card_location_arg. If &#039;hand&#039; in your game is ordered, visible or can have some other card states, you cannot use hand location (replacement is hand_&amp;lt;player_id&amp;gt; or hand_&amp;lt;color_id&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
== Code Organization ==&lt;br /&gt;
&lt;br /&gt;
=== Including your own JavaScript module ===&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, modules/ggg_other.js&lt;br /&gt;
&lt;br /&gt;
* Create ggg_other.js in modules/ folder and sync&lt;br /&gt;
* Modify ggg.js to include it&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  define([ &amp;quot;dojo&amp;quot;, &amp;quot;dojo/_base/declare&amp;quot;, &amp;quot;ebg/core/gamegui&amp;quot;, &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
    // load my own module!!!&lt;br /&gt;
    g_gamethemeurl + &amp;quot;modules/ggg_other.js&amp;quot; ], function(dojo,&lt;br /&gt;
        declare) {&lt;br /&gt;
&lt;br /&gt;
=== Including your own JavaScript module (II) ===&lt;br /&gt;
&lt;br /&gt;
* Create ggg_other.js in modules/ folder and sync&lt;br /&gt;
&lt;br /&gt;
  define([], function () {&lt;br /&gt;
    return &amp;quot;value&amp;quot;;&lt;br /&gt;
  });&lt;br /&gt;
&lt;br /&gt;
* Modify ggg.js to include it&lt;br /&gt;
&lt;br /&gt;
  define([ &lt;br /&gt;
    &amp;quot;dojo&amp;quot;, &lt;br /&gt;
    &amp;quot;dojo/_base/declare&amp;quot;, &lt;br /&gt;
    &amp;quot;bgagame/modules/ggg_other&amp;quot;, &lt;br /&gt;
    &amp;quot;ebg/core/gamegui&amp;quot;, &lt;br /&gt;
    &amp;quot;ebg/counter&amp;quot;&lt;br /&gt;
  ], function(dojo, declare, other) {&lt;br /&gt;
  &lt;br /&gt;
  });&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
This is maybe a little bit more the idea of the AMD Loader than the first option, although the first option should work as well.&lt;br /&gt;
&lt;br /&gt;
A little explanation to this:&lt;br /&gt;
The define function loads all the modules listed in the array and calls the following function with these loaded modules as parameters.&lt;br /&gt;
By putting your module at the third position in the array it is passed as the third parameter to the function. Be aware that the modules are resolved by position only, not by name. So you can load the module &#039;&#039;&#039;ggg_other&#039;&#039;&#039; and pass it as a parameter with the name &#039;&#039;&#039;other&#039;&#039;&#039;. &#039;&#039;&#039;gamegui&#039;&#039;&#039; and &#039;&#039;&#039;counter&#039;&#039;&#039; are passed in as well, but when the parameters are not defined they are just skipped. Because these modules put their content into the global scope it does not matter and you can use them from there.&lt;br /&gt;
&lt;br /&gt;
In the example above the string &amp;quot;value&amp;quot; is passed for the parameter &#039;&#039;&#039;other&#039;&#039;&#039;, but the function in your module can return whatever you want. It can be an object, an array, something you declared with dojo.declare, you can return even functions. &lt;br /&gt;
Your module can load other modules. Just put them in the array at the beginning and pass them as parameters to your function.&lt;br /&gt;
The advantage of passing the values as parameter is that you do not need to put these values in the global scope, so they can&#039;t be collisions with values defined in other scripts or the BGA Framework.&lt;br /&gt;
&lt;br /&gt;
The dojo toolkit provides good documentation to all of its components, the complete documentation for the AMD-Loader is here:&lt;br /&gt;
https://dojotoolkit.org/documentation/tutorials/1.10/modules/index.html It should be still correct, even as it seems to be only for version 1.10&lt;br /&gt;
&lt;br /&gt;
=== Including your own PHP module ===&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.game.php, modules/ggg_other.php&lt;br /&gt;
&lt;br /&gt;
* Create ggg_other.php in modules/ folder and sync&lt;br /&gt;
* Modify ggg.game.php to include it&lt;br /&gt;
&lt;br /&gt;
 require_once (&#039;modules/ggg_other.php&#039;);&lt;br /&gt;
&lt;br /&gt;
=== Creating a test class to run PHP locally ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.game.php, stubs&lt;br /&gt;
For this you need stubs of other method you can use this for example&lt;br /&gt;
https://github.com/elaskavaia/bga-sharedcode/raw/master/misc/module/table/table.game.php&lt;br /&gt;
&lt;br /&gt;
Create another php files, i.e ggg_test.php&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
define(&amp;quot;APP_GAMEMODULE_PATH&amp;quot;, &amp;quot;misc/&amp;quot;); // include path to stubs, which defines &amp;quot;table.game.php&amp;quot; and other classes&lt;br /&gt;
require_once (&#039;eminentdomaine.game.php&#039;);&lt;br /&gt;
&lt;br /&gt;
class MyGameTest1 extends MyGame { // this is your game class defined in ggg.game.php&lt;br /&gt;
    function __construct() {&lt;br /&gt;
        parent::__construct();&lt;br /&gt;
        include &#039;../material.inc.php&#039;;// this is how this normally included, from constructor&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // override/stub methods here that access db and stuff&lt;br /&gt;
    function getGameStateValue($var) {&lt;br /&gt;
        if ($var == &#039;round&#039;)&lt;br /&gt;
            return 3;&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
$x = new MyGameTest1(); // instantiate your class&lt;br /&gt;
$p = $x-&amp;gt;getGameProgression(); // call one of the methods to test&lt;br /&gt;
if ($p != 50)&lt;br /&gt;
    echo &amp;quot;Test1: FAILED&amp;quot;;&lt;br /&gt;
else&lt;br /&gt;
    echo &amp;quot;Test1: PASSED&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Run from command line like&lt;br /&gt;
 php7 ggg_test.php&lt;br /&gt;
&lt;br /&gt;
If you do it this way - you can also use local php debugger (i.e. integrated with IDE or command line).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Avoiding code in dojo declare style ===&lt;br /&gt;
Dojo class declarations are rather bizzare and do not work with most IDEs.&lt;br /&gt;
If you want to write in plain JS with classes, you can stub all the dojo define/declare stuff&lt;br /&gt;
and hook your class into that, so the classes are outside of this mess.&lt;br /&gt;
&lt;br /&gt;
NOTE: this technique is for experienced developers, do not try it if you do not understand&lt;br /&gt;
the consequences.&lt;br /&gt;
&lt;br /&gt;
This is complete example of game .js class&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  // Testla is game name is has to be changed&lt;br /&gt;
class Testla {&lt;br /&gt;
	constructor(game) {&lt;br /&gt;
		console.log(&#039;game constructor&#039;);&lt;br /&gt;
		this.game = game;&lt;br /&gt;
		this.varfoo = new MyFoo(); // this example of class from custom module&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	setup(gamedatas) {&lt;br /&gt;
		console.log(&amp;quot;Starting game setup&amp;quot;, this.varfoo);&lt;br /&gt;
		this.gamedatas = gamedatas;&lt;br /&gt;
		this.dojo.create(&amp;quot;div&amp;quot;, { class: &#039;whiteblock&#039;, innerHTML: _(&amp;quot;hello&amp;quot;) }, &#039;thething&#039;);&lt;br /&gt;
		console.log(&amp;quot;Ending game setup&amp;quot;);&lt;br /&gt;
	};&lt;br /&gt;
	onEnteringState(stateName, args) {&lt;br /&gt;
		console.log(&#039;onEnteringState : &#039; + stateName, args);&lt;br /&gt;
		this.game.addActionButton(&#039;b1&#039;,_(&#039;Click Me&#039;), (e)=&amp;gt;this.onButtonClick(e));&lt;br /&gt;
	};&lt;br /&gt;
	onLeavingState(stateName) {&lt;br /&gt;
		console.log(&#039;onLeavingState : &#039; + stateName, args);&lt;br /&gt;
	};&lt;br /&gt;
	onUpdateActionButtons(stateName, args) {&lt;br /&gt;
		console.log(&#039;onUpdateActionButtons : &#039; + stateName, args);&lt;br /&gt;
	};&lt;br /&gt;
	onButtonClick(event) {&lt;br /&gt;
		console.log(&#039;onButtonClick&#039;,event);&lt;br /&gt;
	};&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&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;
	g_gamethemeurl + &#039;/modules/foo.js&#039; // custom module if needed&lt;br /&gt;
],&lt;br /&gt;
	function(dojo, declare) {&lt;br /&gt;
                // testla is game name is has to be changed&lt;br /&gt;
		return declare(&amp;quot;bgagame.testla&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
			constructor: function() {&lt;br /&gt;
				this.xapp = new Testla(this);&lt;br /&gt;
				this.xapp.dojo = dojo;&lt;br /&gt;
			},&lt;br /&gt;
			setup: function(gamedatas) {&lt;br /&gt;
				this.xapp.setup(gamedatas);&lt;br /&gt;
			},&lt;br /&gt;
			onEnteringState: function(stateName, args) {&lt;br /&gt;
				this.xapp.onEnteringState(stateName, args.args);&lt;br /&gt;
			},&lt;br /&gt;
			onLeavingState: function(stateName) {&lt;br /&gt;
				this.xapp.onLeavingState(stateName, args);&lt;br /&gt;
			},&lt;br /&gt;
			onUpdateActionButtons: function(stateName, args) {&lt;br /&gt;
				this.xapp.onUpdateActionButtons(stateName, args);&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;
=== More readable JS: onEnteringState ===&lt;br /&gt;
&lt;br /&gt;
If you have a lot of states onEnteringState and friends become rather wild, you can do this trick to call some method dynamically.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
     onEnteringState: function(stateName, args) {&lt;br /&gt;
       console.log(&#039;Entering state: &#039; + stateName, args);&lt;br /&gt;
&lt;br /&gt;
       // Call appropriate method&lt;br /&gt;
       var methodName = &amp;quot;onEnteringState_&amp;quot; + stateName;&lt;br /&gt;
       if (this[methodName] !== undefined) {             &lt;br /&gt;
          console.log(&#039;Calling &#039; + methodName, args.args);&lt;br /&gt;
          this[methodName](args.args);&lt;br /&gt;
       }&lt;br /&gt;
     },&lt;br /&gt;
&lt;br /&gt;
     onEnteringState_playerTurn: function(args) { // this is args directly, not args.args &lt;br /&gt;
         // process&lt;br /&gt;
     },&lt;br /&gt;
&lt;br /&gt;
     onEnteringState_playerSomethingElse: function(args) { &lt;br /&gt;
         // process&lt;br /&gt;
     },&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: since its ignores the undefined functions you don&#039;t have define function for each state, but on the other hand you cannot make typos.&lt;br /&gt;
Same applies to onUpdateActionButtons except you pass &#039;args&#039; to method, not args.args, and for onLeavingState where you don&#039;t pass anything.&lt;br /&gt;
&lt;br /&gt;
=== Frameworks and Preprocessors ===&lt;br /&gt;
&lt;br /&gt;
* [[Using Vue]] - work-in-progress guide on using the modern framework Vue.js to create a game&lt;br /&gt;
* [[Using Typescript and Scss]] - How to auto-build Typescript and SCSS files to make your code cleaner&lt;br /&gt;
&lt;br /&gt;
== Assorted Stuff ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Out-of-turn actions: Un-pass ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, ggg.game.php, ggg.action.php, states.inc.php&lt;br /&gt;
&lt;br /&gt;
In multiplayer game sometimes players passes but than they think more and want to un-Pass and redo their choice. &lt;br /&gt;
To re-active a player who passes some trickery required.&lt;br /&gt;
&lt;br /&gt;
Define a special action that does that and hook it up.&lt;br /&gt;
&lt;br /&gt;
In states.inc.php add an action to mmultipleactiveplayer state to &amp;quot;unpass&amp;quot;, lets call it &amp;quot;actionCancel&amp;quot;&lt;br /&gt;
&lt;br /&gt;
In ggg.action.php add action hook&lt;br /&gt;
    public function actionCancel() {&lt;br /&gt;
        self::setAjaxMode();&lt;br /&gt;
        $this-&amp;gt;game-&amp;gt;actionCancel();&lt;br /&gt;
        self::ajaxResponse();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
In ggg.game.php add action handler&lt;br /&gt;
    function actionCancel() {&lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;checkPossibleAction(&#039;actionCancel&#039;);&lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;setPlayersMultiactive(array ($this-&amp;gt;getCurrentPlayerId() ), &#039;error&#039;, false);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
Finally to call this in client ggg.js you would do something like:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 onUpdateActionButtons:  function(stateName, args) {&lt;br /&gt;
   if (this.isCurrentPlayerActive()) { &lt;br /&gt;
     // ...&lt;br /&gt;
   } else if (!this.isSpectator) { // player is NOT active but not spectator&lt;br /&gt;
       switch (stateName) {&lt;br /&gt;
          case &#039;playerTurnMuliPlayerState&#039;:&lt;br /&gt;
		this.addActionButton(&#039;button_unpass&#039;, _(&#039;Oh no!&#039;), &#039;onUnpass&#039;);&lt;br /&gt;
		break;&lt;br /&gt;
	}&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
				&lt;br /&gt;
 onUnpass: function(e) {&lt;br /&gt;
    this.ajaxcall(&amp;quot;/&amp;quot; + this.game_name + &amp;quot;/&amp;quot; +  this.game_name + &amp;quot;/actionCancel.html&amp;quot;, {}, this); // no checkAction!&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Although be careful that if the turn comes back to the player while he is about to click cancel, the action buttons will be updated and the player will misclick which can be quite frustrating. To avoid this, move the cancel button to another position, like to the left of pagemaintitletext:&lt;br /&gt;
  dojo.place(&#039;button_unpass&#039;, &#039;pagemaintitletext&#039;, &#039;before&#039;);&lt;br /&gt;
Being out of the generalactions div, it won&#039;t be automatically destroyed like normal buttons, so you&#039;ll have to handle that yourself in onLeavingState. You might also want to change the button color to red (blue buttons for active player only, red buttons also for inactive players?)&lt;br /&gt;
&lt;br /&gt;
Note: same technique can be used to do other out-of-turn actions, such as re-arranging cards in hand, exchanging resources, etc (i.e. if permitted by rules, such as &amp;quot;at any time player can...&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
=== Multi Step Interactions: Select Worker/Place Worker - Using Selection ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
Simple way to implement something like that without extra states is to use &amp;quot;selection&amp;quot; mechanism. When user click on worker add some sort of class into that element i.e. &#039;selected&#039; (which also have to have some indication by css i.e. outline).&lt;br /&gt;
&lt;br /&gt;
Than user can click on placement zone, you can use dojo.query for &amp;quot;selected&amp;quot; element and use it along with zone id to send data to server. If proper worker is not selected yet can give a error message using this.showMessage(...) function.&lt;br /&gt;
&lt;br /&gt;
Extra code required to properly cleanup selection between states.&lt;br /&gt;
Also when you do that sometimes you want to change the state prompt, see below &#039;Change state prompt&#039;&lt;br /&gt;
&lt;br /&gt;
=== Multi Step Interactions: Select Worker/Place Worker - Using Client States ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
I don&#039;t think its documented feature but there is a way to do client-only states, which is absolutely wonderful for few reasons&lt;br /&gt;
* When player interaction is two step process, such as select worker, place worker, or place worker, pick one of two resources of your choice&lt;br /&gt;
* When multi-step process can result of impossible situation and has to be undone (by rules)&lt;br /&gt;
* When multi-step process is triggered from multiple states (such as you can do same thing as activated card action, pass action or main action)&lt;br /&gt;
&lt;br /&gt;
So lets do Select Worker/Place Worker&lt;br /&gt;
&lt;br /&gt;
Define your server state as usual, i.e. playerMainTurn -&amp;gt; &amp;quot;You must pick up a worker&amp;quot;.&lt;br /&gt;
Now define a client state, we only need &amp;quot;name&amp;quot; and &amp;quot;descriptionmyturn&amp;quot;, lets say &amp;quot;client_playerPicksLocation&amp;quot;. Always prefix names of client state with &amp;quot;client_&amp;quot; to avoid confusion. Now we have to do the following:&lt;br /&gt;
* Have a handler for onUpdateActionButtons for playerMainTurn to activate all possible workers he can pick&lt;br /&gt;
* When player clicks workers, remember the worker in one of the members of the main class, I usually use one called this.clientStateArgs.&lt;br /&gt;
* Transition to new client state&lt;br /&gt;
  onWorker: function(e) {&lt;br /&gt;
      var id = event.currentTarget.id;&lt;br /&gt;
      dojo.stopEvent(event);&lt;br /&gt;
      ... // do validity checks&lt;br /&gt;
      this.clientStateArgs.worker_id = id;&lt;br /&gt;
      this.setClientState(&amp;quot;client_playerPicksLocation&amp;quot;, {&lt;br /&gt;
                                descriptionmyturn : _(&amp;quot;${you} must select location&amp;quot;),&lt;br /&gt;
                            });&lt;br /&gt;
   }&lt;br /&gt;
* Have a handler for onUpdateActionButtons for client_playerPicksLocation to activate all possible locations this worker can go AND add Cancel button (see below)&lt;br /&gt;
* Have a location handler which will eventually send a server request, using stored this.clientStateArgs.worker_id as worker id&lt;br /&gt;
* The cancel button should call a method to restore server state, also if you doing it for more than one state you can add this universally using this.on_client_state check&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        if (this.isCurrentPlayerActive()) {&lt;br /&gt;
          if (this.on_client_state &amp;amp;&amp;amp; !$(&#039;button_cancel&#039;)) {&lt;br /&gt;
               this.addActionButton(&#039;button_cancel&#039;, _(&#039;Cancel&#039;), dojo.hitch(this, function() {&lt;br /&gt;
                                             this.restoreServerGameState();&lt;br /&gt;
               }));&lt;br /&gt;
          }&lt;br /&gt;
        } &lt;br /&gt;
Note: usually I call my own function call this.cancelLocalStateEffects() which will do more stuff first then call restoreServerGameState(), same function is usually needs to be called when server request has failed (i.e. invalid move)&lt;br /&gt;
&lt;br /&gt;
Note: If you need more than 2 steps, you may have to do client side animation to reflect the new state, which gets trickier because you have to undo that also on cancellation.&lt;br /&gt;
&lt;br /&gt;
Code is available here [https://github.com/elaskavaia/bga-sharedcode/blob/master/sharedcode.js sharedcode.js] (its using playerTurnPlayCubes and client_selectCubeLocation).&lt;br /&gt;
&lt;br /&gt;
=== Action Stack - Using Client States ===&lt;br /&gt;
&lt;br /&gt;
Action stack required where game is very complex and use triggered effects that can &amp;quot;stack&amp;quot;. It not always actual stack, it can be queue or random access&lt;br /&gt;
Examples:&lt;br /&gt;
* Magic the Gathering - classic card game where effects go on Stack, that allows to counter spell and counter spell of counter spell (not on bga - it just example of mechanics)&lt;br /&gt;
* Ultimate Railroads - action taking game where effects can be executed in any order&lt;br /&gt;
* Lewis and Clark - card game where actions executed as queue&lt;br /&gt;
&lt;br /&gt;
There is two ways of implementing it - on the server or the client.&lt;br /&gt;
For the server see article below.&lt;br /&gt;
The requirement for client side stack is all action can be undone, which means&lt;br /&gt;
* No dice rolls&lt;br /&gt;
* No card drawn&lt;br /&gt;
* No other players interaction&lt;br /&gt;
&lt;br /&gt;
No snippets are here, as this will be too complex but basically flow is:&lt;br /&gt;
* You have a action/effect stack (queue/list) as js object attached to &amp;quot;this&amp;quot;, i.e. this.unprocessed_actions&lt;br /&gt;
* When player plays a card, worker, etc, you read the effect of that card from the material file (client copy), and place into stack&lt;br /&gt;
* Then we call dispatch method which pulls the next action from the stack and change client state accordinly,i.e.  this.setClientState(&amp;quot;client_playerGainsCubes&amp;quot;)&lt;br /&gt;
* When players acts on it - the action is removed from the stack and added to &amp;quot;server action arguments&amp;quot; list, this is another object which be used to send ajax call, i.e. this.clientStateArgs&lt;br /&gt;
* If nothing left in stack we can submit the ajax call assembling parameters from collected arguments (that can include action name)&lt;br /&gt;
* This method allows cheap undo - by restoring server state you will wipe out all user actions (but if you need intermediate aninmation you have to handle it yourself)&lt;br /&gt;
&lt;br /&gt;
Code can be found in Ultimate Railroads game (but it is random access list - so it a bit complex) and Lewis and Clark (complexity - use can always deny part of any effect)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Action Stack - Using Server States ===&lt;br /&gt;
&lt;br /&gt;
See definition of Action Stack above.&lt;br /&gt;
&lt;br /&gt;
To implement you usually need another db table that has the following fields: index of effect - which is used for sorted access, type - which is essense of the effect (i.e. collect resource), some extra arguments (i.e. resource type and resource count), and usually owner of the effect (i.e. player id)&lt;br /&gt;
The flow is:&lt;br /&gt;
* There is some initial player state, where player can play card for example&lt;br /&gt;
* Player main action - pushes the card effect on stack, which also can cause triggered effects which also go on stack&lt;br /&gt;
* After action processing is finished switch to game state which is &amp;quot;dispatcher&amp;quot;&lt;br /&gt;
* Gispatcher pulls the top effect (whatever definition of the top is), changes the active player and changes the state to appropriate player state to collect response&lt;br /&gt;
* Player state knows about the stack and pulls arguments (argX) from the effect arguments of the db&lt;br /&gt;
* Player action should clear up the top effect, and can possibly add more effects, then switch to &amp;quot;dispatcher&amp;quot; state again&lt;br /&gt;
* If stack is empty, dispatcher can either pick next player itself or use another game state which responsible for picking next player&lt;br /&gt;
&lt;br /&gt;
Code can be found in Tapestry.&lt;br /&gt;
&lt;br /&gt;
=== Changing state prompt ===&lt;br /&gt;
&lt;br /&gt;
State prompt is message displayed for player which usually comes from state description.&lt;br /&gt;
Sometimes you want to change it without changing state (one way is change state but locally, see client states above).&lt;br /&gt;
&lt;br /&gt;
Simple way just change the html&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        setMainTitle: function(text) {&lt;br /&gt;
            $(&#039;pagemaintitletext&#039;).innerHTML = text;&lt;br /&gt;
        },&lt;br /&gt;
         // usage&lt;br /&gt;
        onMeeple: function(event) {&lt;br /&gt;
              //... &lt;br /&gt;
              this.setMainTitle(_(&#039;You must select where meeple is going&#039;));&lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This however will not work with parameters and will not draw You in color, if you want this its more sophisticated:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        setDescriptionOnMyTurn : function(text) {&lt;br /&gt;
            this.gamedatas.gamestate.descriptionmyturn = text;&lt;br /&gt;
            var tpl = dojo.clone(this.gamedatas.gamestate.args);&lt;br /&gt;
            if (tpl === null) {&lt;br /&gt;
                tpl = {};&lt;br /&gt;
            }&lt;br /&gt;
            var title = &amp;quot;&amp;quot;;&lt;br /&gt;
            if (this.isCurrentPlayerActive() &amp;amp;&amp;amp; text !== null) {&lt;br /&gt;
                tpl.you = this.divYou(); &lt;br /&gt;
            }&lt;br /&gt;
            title = this.format_string_recursive(text, tpl);&lt;br /&gt;
&lt;br /&gt;
            if (!title) {&lt;br /&gt;
                this.setMainTitle(&amp;quot;&amp;amp;nbsp;&amp;quot;);&lt;br /&gt;
            } else {&lt;br /&gt;
                this.setMainTitle(title);&lt;br /&gt;
            }&lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: this method uses &#039;&#039;&#039;setMainTitle&#039;&#039;&#039; defined above and &#039;&#039;&#039;divYou&#039;&#039;&#039; defined in another section of this wiki.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Adding Image buttons ===&lt;br /&gt;
&lt;br /&gt;
Its pretty trivial but just in case you need a working function:&lt;br /&gt;
&lt;br /&gt;
ggg.js:&lt;br /&gt;
&lt;br /&gt;
                addImageActionButton: function (id, div_html, handler) { // div_html is string not node&lt;br /&gt;
                    this.addActionButton(id, div_html, handler, &#039;&#039;, false, &#039;gray&#039;); &lt;br /&gt;
                    dojo.style(id, &amp;quot;border&amp;quot;, &amp;quot;none&amp;quot;); // remove ugly border&lt;br /&gt;
                    dojo.addClass(id, &amp;quot;bgaimagebutton&amp;quot;); // add css class to do more styling&lt;br /&gt;
                    return $(id); // return node for chaining&lt;br /&gt;
                },&lt;br /&gt;
&lt;br /&gt;
Example of usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    this.addImageActionButton(&#039;button_coin&#039;,&amp;quot;&amp;lt;div class=&#039;coin&#039;&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;, ()=&amp;gt;{ alert(&#039;Ha!&#039;); });&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Assigning Player Order ===&lt;br /&gt;
Normally when game starts there is &amp;quot;natural&amp;quot; player order assigned randomly.&lt;br /&gt;
&lt;br /&gt;
If you want to deliberatly assign player order at the start of the game (for example, in a game with teams options), you can do so by retrieving the initialization-only player attribute &#039;&#039;&#039;player_table_order&#039;&#039;&#039; and using it to assign values to &#039;&#039;&#039;player_no&#039;&#039;&#039; (which is normally assigned at the start of a game in the order in which players come to the table). (See [https://en.doc.boardgamearena.com/Game_database_model:_dbmodel.sql#The_player_table Game database model] for more details.)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Example:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                // Retrieve inital player order ([0=&amp;gt;playerId1, 1=&amp;gt;playerId2, ...])&lt;br /&gt;
		$playerInitialOrder = [];&lt;br /&gt;
		foreach ($players as $playerId =&amp;gt; $player) {&lt;br /&gt;
			$playerInitialOrder[$player[&#039;player_table_order&#039;]] = $playerId;&lt;br /&gt;
		}&lt;br /&gt;
		ksort($playerInitialOrder);&lt;br /&gt;
		$playerInitialOrder = array_flip(array_values($playerInitialOrder));&lt;br /&gt;
&lt;br /&gt;
		// Player order based on &#039;playerTeams&#039; option&lt;br /&gt;
		$playerOrder = [0, 1, 2, 3];&lt;br /&gt;
		switch (self::getGameStateValue(&#039;playerTeams&#039;)) {&lt;br /&gt;
			case self::TEAM_1_2:&lt;br /&gt;
				$playerOrder = [0, 2, 1, 3];&lt;br /&gt;
				break;&lt;br /&gt;
			case self::TEAM_1_4:&lt;br /&gt;
				$playerOrder = [0, 1, 3, 2];&lt;br /&gt;
				break;&lt;br /&gt;
			case self::TEAM_RANDOM:&lt;br /&gt;
				shuffle($playerOrder);&lt;br /&gt;
				break;&lt;br /&gt;
			default:&lt;br /&gt;
			case self::TEAM_1_3:&lt;br /&gt;
				// Default order&lt;br /&gt;
				break;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
                // Create players&lt;br /&gt;
		// Note: if you added some extra field on &amp;quot;player&amp;quot; table in the database (dbmodel.sql), you can initialize it there.&lt;br /&gt;
		$sql =&lt;br /&gt;
			&#039;INSERT INTO player (player_id, player_color, player_canal, player_name, player_avatar, player_no) VALUES &#039;;&lt;br /&gt;
		$values = [];&lt;br /&gt;
&lt;br /&gt;
		foreach ($players as $playerId =&amp;gt; $player) {&lt;br /&gt;
			$color = array_shift($default_colors);&lt;br /&gt;
			$values[] =&lt;br /&gt;
				&amp;quot;(&#039;&amp;quot; .&lt;br /&gt;
				$playerId .&lt;br /&gt;
				&amp;quot;&#039;,&#039;$color&#039;,&#039;&amp;quot; .&lt;br /&gt;
				$player[&#039;player_canal&#039;] .&lt;br /&gt;
				&amp;quot;&#039;,&#039;&amp;quot; .&lt;br /&gt;
				addslashes($player[&#039;player_name&#039;]) .&lt;br /&gt;
				&amp;quot;&#039;,&#039;&amp;quot; .&lt;br /&gt;
				addslashes($player[&#039;player_avatar&#039;]) .&lt;br /&gt;
				&amp;quot;&#039;,&#039;&amp;quot; .&lt;br /&gt;
				$playerOrder[$playerInitialOrder[$playerId]] .&lt;br /&gt;
				&amp;quot;&#039;)&amp;quot;;&lt;br /&gt;
		}&lt;br /&gt;
		$sql .= implode(&#039;,&#039;, $values);&lt;br /&gt;
		self::DbQuery($sql);&lt;br /&gt;
		self::reattributeColorsBasedOnPreferences(&lt;br /&gt;
			$players,&lt;br /&gt;
			$gameinfos[&#039;player_colors&#039;]&lt;br /&gt;
		);&lt;br /&gt;
		self::reloadPlayersBasicInfos();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Send different notifications to active player vs everybody else ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
Hack alert. This is a hack. We were hoping for proper solution by bga framework.&lt;br /&gt;
&lt;br /&gt;
This will allow you to send notification with two message one for specific player and one for everybody else including spectators.&lt;br /&gt;
Note that this does not split the data - all data must be shared.&lt;br /&gt;
&lt;br /&gt;
Add this to .js file (if you already overriding it merge obviously)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/** @Override */&lt;br /&gt;
format_string_recursive: function(log, args) {&lt;br /&gt;
   if (typeof args.log_others != &#039;undefined&#039; &amp;amp;&amp;amp; typeof args.player_id != &#039;undefined&#039; &amp;amp;&amp;amp; this.player_id != args.player_id)&lt;br /&gt;
	log = args.log_others;&lt;br /&gt;
   return this.inherited(arguments); // you must call this to call super &lt;br /&gt;
},&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example of usage (from eminentdomain)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    $this-&amp;gt;notifyAllPlayers(&#039;tokenMoved&#039;, &lt;br /&gt;
             clienttranslate(&#039;${player_name} adds +2 Colonies to ${place_name}&#039;), // notification with show for player with player_id&lt;br /&gt;
             [&#039;player_id&#039;=&amp;gt;$player_id, // this is mandatory&lt;br /&gt;
             &#039;log_others&#039;=&amp;gt;clienttranslate(&#039;${player_name} adds +2 Colonies to an unknown planet&#039;), // notification will show for others&lt;br /&gt;
              ...&lt;br /&gt;
             ]);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Send transient notifications without incrementing move ID ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.php&lt;br /&gt;
&lt;br /&gt;
Hack alert. This is a hack.&lt;br /&gt;
&lt;br /&gt;
Use this if you need to send some transient notification that should not create a new move ID. The notification should be idempotent -- it should have no practical effect on the game state and would be &#039;&#039;&#039;safe to drop&#039;&#039;&#039; (e.g., it would not matter if a player never received this notification). For example, in a co-op game you want all players to see a real-time preview of some action, before the active player commits their turn.&lt;br /&gt;
&lt;br /&gt;
Doing this mainly affects the instant replay &amp;amp; archive modes. During replay, the BGA framework automatically inserts a 1.5-second pause between each &amp;quot;move&amp;quot;. With this hack, your transient notifications are not considered to be a &amp;quot;move&amp;quot;, so no pause gets added.&lt;br /&gt;
&lt;br /&gt;
; In ggg.php&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$this-&amp;gt;not_a_move_notification = true; // note: do not increase the move counter&lt;br /&gt;
$this-&amp;gt;notifyAllPlayers(&#039;cardsPreview&#039;, &#039;&#039;, $args);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: you cannot have code that send notification or even changes state after this, and you cannot reset this variable back either because it only takes effect when you exit action handling function&lt;br /&gt;
&lt;br /&gt;
=== Ajax Call wrapper ===&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
The current ajaxcall is super vebose and prone to errors, I suggest using a helper function. It does a lot of stuff you must do anyways.&lt;br /&gt;
Most beginner mistakes come from missing part of this code (which is understandstandable - this is a huge snippet to clone every time).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	ajaxcallwrapper: function(action, args, handler) {&lt;br /&gt;
		if (!args) args = []; // this allows to skip args parameter for action which do not require them&lt;br /&gt;
			&lt;br /&gt;
		args.lock = true; // this allows to avoid rapid action clicking which can cause race condition on server&lt;br /&gt;
		if (this.checkAction(action)) { // this does all the proper check that player is active and action is declared&lt;br /&gt;
			this.ajaxcall(&amp;quot;/&amp;quot; + this.game_name + &amp;quot;/&amp;quot; + this.game_name + &amp;quot;/&amp;quot; + action + &amp;quot;.html&amp;quot;, args, // this is mandatory fluff &lt;br /&gt;
				this, (result) =&amp;gt; { },  // success result handler is empty - it is never needed&lt;br /&gt;
                                               handler); // this is real result handler - it called both on success and error, it has optional param  &amp;quot;is_error&amp;quot; - you rarely need it&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   this.ajaxcallwrapper(&#039;pass&#039;); // no args&lt;br /&gt;
   this.ajaxcallwrapper(&#039;playCard&#039;, {card: card_id}); // with args&lt;br /&gt;
   this.ajaxcallwrapper(&#039;playCard&#039;, {card: card_id}, (is_error)=&amp;gt;{if (!is_error) dojo.query(&amp;quot;.selected&amp;quot;).removeClass(&#039;selected&#039;);}) // with handler that cleans up &#039;selected&#039; class on success&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: this always will lock interface and always check for action, you can modify this method to do it optionally, i.e&lt;br /&gt;
  if (args.lock!==false) args.lock = true; else delete args.lock; // it does not work with false value - it has to be removed&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Studio]]&lt;/div&gt;</summary>
		<author><name>SwHawk</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=BGA_Studio_Cookbook&amp;diff=14211</id>
		<title>BGA Studio Cookbook</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=BGA_Studio_Cookbook&amp;diff=14211"/>
		<updated>2022-07-31T15:48:58Z</updated>

		<summary type="html">&lt;p&gt;SwHawk: /* Second way: rely on the :formatFunction option provided by dojo.string.substitute */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
This page is collection of design and implementation recipes for BGA Studio framework.&lt;br /&gt;
For tooling and usage recipes see [[Tools and tips of BGA Studio]].&lt;br /&gt;
If you have your own recipes feel free to edit this page.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Visual Effects, Layout and Animation ==&lt;br /&gt;
&lt;br /&gt;
=== DOM manipulatons ===&lt;br /&gt;
&lt;br /&gt;
==== Create pieces dynamically (using template) ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg_ggg.tpl, ggg.js&lt;br /&gt;
&lt;br /&gt;
Note: this method is recommended by BGA guildlines&lt;br /&gt;
&lt;br /&gt;
Declared js template with variables in .tpl file, like this&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;
    // Javascript HTML templates&lt;br /&gt;
    var jstpl_ipiece = &#039;&amp;lt;div class=&amp;quot;${type} ${type}_${color} inlineblock&amp;quot; aria-label=&amp;quot;${name}&amp;quot; title=&amp;quot;${name}&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use it like this in .js file&lt;br /&gt;
  div = this.format_block(&#039;jstpl_ipiece&#039;, {&lt;br /&gt;
                                type : &#039;meeple&#039;,&lt;br /&gt;
                                color : &#039;ff0000&#039;,&lt;br /&gt;
                                name : &#039;Bob&#039;,&lt;br /&gt;
                            });&lt;br /&gt;
  &lt;br /&gt;
Then you do whatever you need to do with that div, this one specifically design to go to log entries, because it has embedded title (otherwise its a picture only) and no id.&lt;br /&gt;
&lt;br /&gt;
Note: you could have place this variable in js itself, but keeping it in .tpl allows you to have your js code be free of HTML. Normally it never happens but&lt;br /&gt;
it is good to strive for it.&lt;br /&gt;
Note: you can also use string concatenation, its less readable. You can also use dojo dom object creation api&#039;s but its brutally verbose and its more unreadable.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Create pieces dynamically (using string concatenation) ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
Note: Not recommended&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  div = &amp;quot;&amp;lt;div class=&#039;meeple &amp;quot;+color+&amp;quot;&#039;&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
==== Create all pieces statically ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg_ggg.tpl, ggg.css, ggg.view.php (optional) &lt;br /&gt;
&lt;br /&gt;
* Create ALL game pieces in html template (.tpl)&lt;br /&gt;
* ALL pieces should have unique id, and it should be meaningful, i.e. meeple_red_1&lt;br /&gt;
* Do not use inline styling&lt;br /&gt;
* Id of player&#039;s specific pieces should use some sort of &#039;color&#039; identification, since player id cannot be used in static layout, you can use english color name, hex 6 char value, or color &amp;quot;number&amp;quot; (1,2,3...)&lt;br /&gt;
* Pieces should have separated class for its color, type, etc, so it can be easily styled in groups. In example below you now can style all meeples, all red meeples or all red tokens, or all &amp;quot;first&amp;quot; meeples&lt;br /&gt;
&lt;br /&gt;
ggg.tpl:&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
  &amp;lt;div id=&amp;quot;home_red&amp;quot; class=&amp;quot;home_red home&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;div id=&amp;quot;meeple_red_1&amp;quot; class=&amp;quot;meeple red n1&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
     &amp;lt;div id=&amp;quot;meeple_red_2&amp;quot; class=&amp;quot;meeple red n2&amp;quot;&amp;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;
ggg.css:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.meeple {&lt;br /&gt;
	width: 32px;&lt;br /&gt;
	height: 39px;&lt;br /&gt;
	background-image: url(img/78_64_stand_meeples.png);&lt;br /&gt;
	background-size: 352px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.meeple.red {&lt;br /&gt;
	background-position: 30% 0%;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* There should be straight forward mapping between server id and js id (or 1:1)&lt;br /&gt;
* You place objects in different zones of the layout, and setup css to take care of layout&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.home .meeple{&lt;br /&gt;
   display: inline-block;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* If you need to have a temporary object that look like original you can use dojo.clone (and change id to some temp id)&lt;br /&gt;
* If there is lots of repetition or zone grid you can use template generator, but inject style declaration in css instead of inline style for flexibility&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
* If you use this model you cannot use premade js components such as Stock and Zone&lt;br /&gt;
* You have to use alternative methods of animation (slightly altered) since default method will leave object with inline style attributes which you don&#039;t need&lt;br /&gt;
&lt;br /&gt;
=== Logs ===&lt;br /&gt;
&lt;br /&gt;
==== Inject icon images in the log ====&lt;br /&gt;
&lt;br /&gt;
Here is an example of what was done for Terra Mystica which is simple and straightforward:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
//Define the proper message&lt;br /&gt;
		$message = clienttranslate(&#039;${player_name} gets ${power_income} via Structures&#039;);&lt;br /&gt;
		if ($price &amp;gt; 0) {&lt;br /&gt;
			self::DbQuery(&amp;quot;UPDATE player SET player_score = player_score - $price WHERE player_id = $player_id&amp;quot;);&lt;br /&gt;
			$message = clienttranslate(&#039;${player_name} pays ${vp_price} and gets ${power_income} via Structures&#039;);&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
// Notify&lt;br /&gt;
		self::notifyAllPlayers( &amp;quot;powerViaStructures&amp;quot;, $message, array(&lt;br /&gt;
			&#039;i18n&#039; =&amp;gt; array( ),&lt;br /&gt;
			&#039;player_id&#039; =&amp;gt; $player_id,&lt;br /&gt;
			&#039;player_name&#039; =&amp;gt; self::getUniqueValueFromDb( &amp;quot;SELECT player_name FROM player WHERE player_id = $player_id&amp;quot; ),&lt;br /&gt;
			&#039;power_tokens&#039; =&amp;gt; $power_tokens,&lt;br /&gt;
			&#039;vp_price&#039; =&amp;gt; self::getLogsVPAmount($price),&lt;br /&gt;
			&#039;power_income&#039; =&amp;gt; self::getLogsPowerAmount($power_income),&lt;br /&gt;
			&#039;newScore&#039; =&amp;gt; self::getUniqueValueFromDb( &amp;quot;SELECT player_score FROM player WHERE player_id = $player_id&amp;quot; ),&lt;br /&gt;
			&#039;counters&#039; =&amp;gt; $this-&amp;gt;getGameCounters(null),&lt;br /&gt;
		) );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With some functions to have the needed html added inside the substitution variable, such as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function getLogsPowerAmount( $amount ) {&lt;br /&gt;
		return &amp;quot;&amp;lt;div class=&#039;tmlogs_icon&#039; title=&#039;Power&#039;&amp;gt;&amp;lt;div class=&#039;power_amount&#039;&amp;gt;$amount&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: injecting html from php is not ideal but easy, if you want more clean solution, use method below but it is a lot more sophisticated.&lt;br /&gt;
&lt;br /&gt;
==== Inject images and styled html in the log ====&lt;br /&gt;
&lt;br /&gt;
So you want nice pictures in the game log. What do you do? The first idea that comes to mind is to send html from php in notifications (see method above). &lt;br /&gt;
&lt;br /&gt;
This is a bad idea for many reasons:&lt;br /&gt;
&lt;br /&gt;
* It&#039;s bad architecture. ui elements leak into the server, and now you have to manage the ui in multiple places.&lt;br /&gt;
* If you decided to change something in the ui in future version, replay logs for old games and tutorials may not work, since they use stored notifications.&lt;br /&gt;
* Log previews for old games become unreadable. (This is the log state before you enter the game replay, which is useful for troubleshooting and game analysis.)&lt;br /&gt;
* It&#039;s more data to transfer and store in the db.&lt;br /&gt;
* It&#039;s a nightmare for translators.&lt;br /&gt;
&lt;br /&gt;
So what else can you do? You can use client side log injection to intercept log arguments (which come from the server) and replace them with html on the client side. Here are three different method you can use to achieve this.&lt;br /&gt;
&lt;br /&gt;
===== First way : Override &amp;lt;code&amp;gt;this.format_string_recursive()&amp;lt;/code&amp;gt; method =====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, ggg.game.php&lt;br /&gt;
&lt;br /&gt;
I use this recipe for &#039;&#039;&#039;client side log injection&#039;&#039;&#039; to intercept log arguments (which come from the server) and replace them with html on the client side.&lt;br /&gt;
&lt;br /&gt;
[[File:clientloginjection.png|left]] &lt;br /&gt;
&lt;br /&gt;
ggg.js&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
        /** Override this function to inject html into log items. This is a built-in BGA method.  */&lt;br /&gt;
&lt;br /&gt;
        /* @Override */&lt;br /&gt;
        format_string_recursive : function format_string_recursive(log, args) {&lt;br /&gt;
            try {&lt;br /&gt;
                if (log &amp;amp;&amp;amp; args &amp;amp;&amp;amp; !args.processed) {&lt;br /&gt;
                    args.processed = true;&lt;br /&gt;
                    &lt;br /&gt;
&lt;br /&gt;
                    // list of special keys we want to replace with images&lt;br /&gt;
                    var keys = [&#039;place_name&#039;,&#039;token_name&#039;];&lt;br /&gt;
                    &lt;br /&gt;
                  &lt;br /&gt;
                    for ( var i in keys) {&lt;br /&gt;
                        var key = keys[i];&lt;br /&gt;
                        key in args &amp;amp;&amp;amp; args[key] = this.getTokenDiv(key, args);                            &lt;br /&gt;
&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            } catch (e) {&lt;br /&gt;
                console.error(log,args,&amp;quot;Exception thrown&amp;quot;, e.stack);&lt;br /&gt;
            }&lt;br /&gt;
            return this.inherited({callee: format_string_recursive}, arguments);&lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important:&#039;&#039;&#039; In the &#039;&#039;format_string_recursive&#039;&#039; method, the &#039;args&#039; parameter will only contain arguments passed to it from the notify method in ggg.game.php (see below).&lt;br /&gt;
&lt;br /&gt;
The &#039;log&#039; parameter is the actual string that is inserted into the logs. You can perform additional js string manipulation on it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        getTokenDiv : function(key, args) {&lt;br /&gt;
            // ... implement whatever html you want here, example from sharedcode.js&lt;br /&gt;
            var token_id = args[key];&lt;br /&gt;
            var item_type = getPart(token_id,0);&lt;br /&gt;
            var logid = &amp;quot;log&amp;quot; + (this.globalid++) + &amp;quot;_&amp;quot; + token_id;&lt;br /&gt;
            switch (item_type) {&lt;br /&gt;
                case &#039;wcube&#039;:&lt;br /&gt;
                    var tokenDiv = this.format_block(&#039;jstpl_resource_log&#039;, {&lt;br /&gt;
                        &amp;quot;id&amp;quot; : logid,&lt;br /&gt;
                        &amp;quot;type&amp;quot; : &amp;quot;wcube&amp;quot;,&lt;br /&gt;
                        &amp;quot;color&amp;quot; : getPart(token_id,1),&lt;br /&gt;
                    });&lt;br /&gt;
                    return tokenDiv;&lt;br /&gt;
             &lt;br /&gt;
                case &#039;meeple&#039;:&lt;br /&gt;
                    if ($(token_id)) {&lt;br /&gt;
                        var clone = dojo.clone($(token_id));&lt;br /&gt;
    &lt;br /&gt;
                        dojo.attr(clone, &amp;quot;id&amp;quot;, logid);&lt;br /&gt;
                        this.stripPosition(clone);&lt;br /&gt;
                        dojo.addClass(clone, &amp;quot;logitem&amp;quot;);&lt;br /&gt;
                        return clone.outerHTML;&lt;br /&gt;
                    }&lt;br /&gt;
                    break;&lt;br /&gt;
     &lt;br /&gt;
                default:&lt;br /&gt;
                    break;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            return &amp;quot;&#039;&amp;quot; + this.clienttranslate_string(this.getTokenName(token_id)) + &amp;quot;&#039;&amp;quot;;&lt;br /&gt;
       },&lt;br /&gt;
       getTokenName : function(key) {&lt;br /&gt;
           return this.gamedatas.token_types[key].name; // get name for the key, from static table for example&lt;br /&gt;
       },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that in this case the server simply injects token_id as a name, and the client substitutes it for the translated name or the picture.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ggg.game.php:&lt;br /&gt;
&lt;br /&gt;
           $this-&amp;gt;notifyAllPlayers(&#039;playerLog&#039;,clienttranslate(&#039;Game moves ${token_name}&#039;),[&#039;token_name&#039;=&amp;gt;$token_id]);&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important:&#039;&#039;&#039; As noted above, only arguments actually passed by this method are available to the args parameter received in the client-side &#039;&#039;format_string_recursive&#039;&#039; method.&lt;br /&gt;
&lt;br /&gt;
Sometimes it is the case that you want to pass arguments that are not actually included in the output message. For example, suppose we have a method like this:&lt;br /&gt;
&lt;br /&gt;
           $this-&amp;gt;notifyAllPlayers(&#039;tokenPlaced&#039;,clienttranslate(&#039;Player placed ${token_name}&#039;),array(&lt;br /&gt;
              &#039;token_name&#039; =&amp;gt; $token_id,&lt;br /&gt;
              &#039;zone_played&#039; =&amp;gt; $zone);&lt;br /&gt;
&lt;br /&gt;
This will output &amp;quot;Player placed ${token_name}&amp;quot; in the log, and if we subscribe to a notification method activated by the &amp;quot;tokenPlaced&amp;quot; event in the client-side code, that method can make use of the &#039;zone_played&#039; argument. &lt;br /&gt;
&lt;br /&gt;
Now if you want to make some really cool things with game log, most probably you would need more arguments than are included in log message. The problem with that,&lt;br /&gt;
it will work at first, but if you reload game using F5 or when the game loads in turn based mode, you will loose your additional parameters, why? Because when game reloads it does not actually send same notifications, it sends special &amp;quot;hitstorical_log&amp;quot; notification where all  parameters not listed in the message are removed. In example above, field zone_played would be removed from historical log as it is not included in message of the notification. You can till preserve specific arguments in historical log by adding special field preserve to notification arguments like this:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
           $this-&amp;gt;notifyAllPlayers(&#039;tokenPlaced&#039;,clienttranslate(&#039;Player placed ${token_name}&#039;),array(&lt;br /&gt;
              &#039;token_name&#039; =&amp;gt; $token_id,&lt;br /&gt;
              &#039;zone_played&#039; =&amp;gt; $zone,&lt;br /&gt;
              &#039;preserve&#039; =&amp;gt; [ &#039;zone_played&#039; ]&lt;br /&gt;
           );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now you can use zone_played in format_string_recursive even in historical logs.&lt;br /&gt;
&lt;br /&gt;
===== Second way: rely on the &amp;lt;code&amp;gt;:formatFunction&amp;lt;/code&amp;gt; option provided by &amp;lt;code&amp;gt;dojo.string.substitute&amp;lt;/code&amp;gt; =====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, ggg.game.php, ggg_ggg.tpl, ggg.css&lt;br /&gt;
&lt;br /&gt;
The above method will work in most of the cases, but if you use dotted keys such as &amp;lt;code&amp;gt;${card.name}&amp;lt;/code&amp;gt; (which is supported by the framework, for private state args), the key won&#039;t be substituted because the &amp;lt;code&amp;gt;key in arg&amp;lt;/code&amp;gt; test will fail. If so you need to rely either on this way, or the one after.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;WARNING:&#039;&#039;&#039; using this method on an already advanced project will require you to go through all your notifications to change keys !&lt;br /&gt;
&lt;br /&gt;
Under the hood, the &#039;&#039;&#039;this.format_string_recursive()&#039;&#039;&#039; function calls the &#039;&#039;&#039;dojo.string.substitute&#039;&#039;&#039; method which substitutes &amp;lt;code&amp;gt;${keys}&amp;lt;/code&amp;gt; with the value provided. If you take a look at the [https://dojotoolkit.org/reference-guide/1.7/dojo/string.html#substitute documentation] and [https://github.com/dojo/dojo/blob/c3ceb017cfa25b703f5662dc83d1c8aae9bc5d81/string.js#L163 source code] you can notice that the key can be suffixed with a colon (&amp;lt;code&amp;gt;:&amp;lt;/code&amp;gt;) followed by a function name. This will allow you to specify directly in the substitution string which keys need HTML injection.&lt;br /&gt;
&lt;br /&gt;
First of all, you need to define your formatting function in the ggg.js file:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[[ggg.js]]&lt;br /&gt;
        getTokenDiv : function(value, key) {&lt;br /&gt;
            //This is only an example implementation, you need to write your own.&lt;br /&gt;
            //The method should return HTML code&lt;br /&gt;
            switch (key) {&lt;br /&gt;
                case &#039;html_injected_argument1&#039;:&lt;br /&gt;
                    return this.format_block(&#039;jstpl_HTMLLogElement1&#039;,{value: value});&lt;br /&gt;
                case &#039;html_injected_argument2&#039;:&lt;br /&gt;
                    return this.format_block(&#039;jstpl_HTMLLogElement2&#039;,{value: value});&lt;br /&gt;
                ...&lt;br /&gt;
            }&lt;br /&gt;
       }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Obviously you need to define the appropriate templates in the ggg_ggg.tpl file:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[[ggg_ggg.tpl]]&lt;br /&gt;
let jstpl_HTMLLogElement1 = &#039;&amp;lt;div class=&amp;quot;log-element log-element-1-${value}&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
let jstpl_HTMLLogElement2 = &#039;&amp;lt;div class=&amp;quot;log-element log-element-2-${value}&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
And the appropriate classes in ggg.css.&lt;br /&gt;
&lt;br /&gt;
Then you need to add the &amp;lt;code&amp;gt;dojo/aspect&amp;lt;/code&amp;gt; module at the top of the ggg.js file:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[ggg.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 define([&lt;br /&gt;
     &amp;quot;dojo&amp;quot;, &amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&amp;quot;dojo/aspect&amp;quot;,&amp;lt;/span&amp;gt;                 //MUST BE IN THIRD POSITION&#039;&#039;&#039; (see [[#Including your own JavaScript module (II)|below]])&lt;br /&gt;
     &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
 ], function (dojo, declare, &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&#039;&#039;&#039;aspect&#039;&#039;&#039;&amp;lt;/span&amp;gt;) {&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
And you also need to add the following code in your &amp;lt;code&amp;gt;contructor&amp;lt;/code&amp;gt; method in the ggg.js:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[ggg.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
         constructor: function(){&lt;br /&gt;
             console.log(&#039;progressevolutiontechnologyswh constructor&#039;);&lt;br /&gt;
               &lt;br /&gt;
             // Here, you can init the global variables of your user interface&lt;br /&gt;
             // Example:&lt;br /&gt;
             // this.myGlobalValue = 0;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&#039;&#039;&#039;let gameObject = this;&#039;&#039;&#039;            //Needed as the this object in aspect.before will not refer to the game object in which the formatting function resides&lt;br /&gt;
             &#039;&#039;&#039;aspect.before(dojo.string, &amp;quot;substitute&amp;quot;, function(template, map, transform) {&#039;&#039;&#039;&lt;br /&gt;
                 &#039;&#039;&#039;return [template, map, transform, gameObject];&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now you&#039;re all set to inject HTML in your logs.&lt;br /&gt;
&lt;br /&gt;
===== Third way: rely on the &amp;lt;code&amp;gt;transform&amp;lt;/code&amp;gt; argument of &amp;lt;code&amp;gt;dojo.string.substitute&amp;lt;/code&amp;gt; =====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, ggg.game.php, ggg_ggg.tpl, ggg.css&lt;br /&gt;
&lt;br /&gt;
This method is also relying on the use of &amp;lt;code&amp;gt;dojo.string.substitute&amp;lt;/code&amp;gt; by the framework, and will use the &amp;lt;code&amp;gt;transform&amp;lt;/code&amp;gt; argument, which, accordting to [https://github.com/dojo/dojo/blob/c3ceb017cfa25b703f5662dc83d1c8aae9bc5d81/string.js#L163 source code] and [https://dojotoolkit.org/reference-guide/1.7/dojo/string.html#substitute documentation] will be run on all the messages going through dojo.string.substitute.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;WARNING:&#039;&#039;&#039; As this method will be applied to all strings that go through dojo.string.substitute. As such you must take extra care not to substitute keys that may be used by the framework (i.e. ${id}). In order to do so, a good practise would be to prefix all keys that need substitution with a trigram of the game name.&lt;br /&gt;
&lt;br /&gt;
Since all the keys will be fed to the tranform function, by default, it must return the value, substituted or not per your needs. You can define the function like this in the ggg.js file:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[ggg.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
         getTokenDiv : function(value, key) {&lt;br /&gt;
             //This is only an example implementation, you need to write your own.&lt;br /&gt;
             //The method should return HTML code&lt;br /&gt;
             switch (key) {&lt;br /&gt;
                 case &#039;html_injected_argument1&#039;:&lt;br /&gt;
                     return this.format_block(&#039;jstpl_HTMLLogElement1&#039;,{value: value});&lt;br /&gt;
                 case &#039;html_injected_argument2&#039;:&lt;br /&gt;
                     return this.format_block(&#039;jstpl_HTMLLogElement2&#039;,{value: value});&lt;br /&gt;
                 ...&lt;br /&gt;
                 &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&#039;&#039;&#039;default:&#039;&#039;&#039;&lt;br /&gt;
                     &#039;&#039;&#039;return value;&#039;&#039;&#039;&amp;lt;/span&amp;gt;                  &#039;&#039;&#039;//Needed otherwise regular strings won&#039;t appear since since the value isn&#039;t returned by the function&#039;&#039;&#039;&lt;br /&gt;
             }&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
The templates must be defined in the ggg_ggg.tpl file and the corresponding CSS classes in the ggg.css file.&lt;br /&gt;
&lt;br /&gt;
You need to add the following code at the beginning of the ggg.js file:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[ggg.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 define([&lt;br /&gt;
     &amp;quot;dojo&amp;quot;, &amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&amp;quot;dojo/aspect&amp;quot;,&amp;lt;/span&amp;gt;                 //MUST BE IN THIRD POSITION&#039;&#039;&#039; (see [[#Including your own JavaScript module (II)|below]])&lt;br /&gt;
     &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
 ], function (dojo, declare, &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&#039;&#039;&#039;aspect&#039;&#039;&#039;&amp;lt;/span&amp;gt;) {&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
And the following code to the &amp;lt;code&amp;gt;constructor&amp;lt;/code&amp;gt; method in ggg.js:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[[ggg.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
         constructor: function(){&lt;br /&gt;
             console.log(&#039;progressevolutiontechnologyswh constructor&#039;);&lt;br /&gt;
               &lt;br /&gt;
             // Here, you can init the global variables of your user interface&lt;br /&gt;
             // Example:&lt;br /&gt;
             // this.myGlobalValue = 0;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&#039;&#039;&#039;let transformFunction = dojo.hitch(this, &amp;quot;getTokenDiv&amp;quot;);&#039;&#039;&#039;            //Needed as the this object in aspect.before will not refer to the game object in which the formatting function resides&lt;br /&gt;
             &#039;&#039;&#039;aspect.before(dojo.string, &amp;quot;substitute&amp;quot;, function(template, map, transform) {&#039;&#039;&#039;&lt;br /&gt;
                 &#039;&#039;&#039;if (undefined === transform) {&#039;&#039;&#039;                                   //Check for a transform function presence, just in case&lt;br /&gt;
                     &#039;&#039;&#039;return [template, map, transform];&#039;&#039;&#039;&lt;br /&gt;
                 &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Processing logs on re-loading ====&lt;br /&gt;
&lt;br /&gt;
You rarely need to process logs when reloading, but if you want to do something fancy you may have to do it after logs are loaded. &lt;br /&gt;
Logs are loaded asyncronously so you have to listen for logs to be fully loaded.&lt;br /&gt;
Unfortunately there is no direct way of doing it so this is the hack.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Hack alert&#039;&#039;&#039; - this extends undocumented function and may be broken when framework is updated&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
			/*&lt;br /&gt;
  			* [Undocumented] Override BGA framework functions to call onLoadingLogsComplete when loading is done&lt;br /&gt;
                        @Override&lt;br /&gt;
   			*/&lt;br /&gt;
			setLoader: function(image_progress, logs_progress) {&lt;br /&gt;
				this.inherited(arguments); // required, this is &amp;quot;super()&amp;quot; call, do not remove&lt;br /&gt;
				//console.log(&amp;quot;loader&amp;quot;, image_progress, logs_progress)&lt;br /&gt;
				if (!this.isLoadingLogsComplete &amp;amp;&amp;amp; logs_progress &amp;gt;= 100) {&lt;br /&gt;
					this.isLoadingLogsComplete = true; // this is to prevent from calling this more then once&lt;br /&gt;
					this.onLoadingLogsComplete();&lt;br /&gt;
				}&lt;br /&gt;
			},&lt;br /&gt;
&lt;br /&gt;
			onLoadingLogsComplete: function() {&lt;br /&gt;
				console.log(&#039;Loading logs complete&#039;);&lt;br /&gt;
				// do something here&lt;br /&gt;
			},&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Player Panel ===&lt;br /&gt;
&lt;br /&gt;
==== Inserting non-player panel ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, ggg_ggg.tpl&lt;br /&gt;
&lt;br /&gt;
If you want to insert non-player panel on the right side (for example to hold extra preferences, zooming controls, etc)&lt;br /&gt;
&lt;br /&gt;
this can go pretty much anywhere in template it will be moved later&lt;br /&gt;
&lt;br /&gt;
ggg_ggg.tpl:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	&amp;lt;div class=&#039;player_board_config&#039; id=&amp;quot;player_board_config&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;!-- here is whatever you want, buttons just example --&amp;gt;&lt;br /&gt;
		&amp;lt;button id=&amp;quot;zoom-out&amp;quot; class=&amp;quot; fa fa-search-minus fa-2x config-control&amp;quot;&amp;gt;&amp;lt;/button&amp;gt;&lt;br /&gt;
		&amp;lt;button id=&amp;quot;zoom-in&amp;quot; class=&amp;quot; fa fa-search-plus fa-2x config-control&amp;quot;&amp;gt;&amp;lt;/button&amp;gt;&lt;br /&gt;
		&amp;lt;button id=&amp;quot;show-settings&amp;quot; class=&amp;quot;fa fa-cog fa-2x config-control &amp;quot;&amp;gt;&amp;lt;/button&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
some hackery required in js&lt;br /&gt;
&lt;br /&gt;
ggg.js:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* @Override */&lt;br /&gt;
	updatePlayerOrdering() {&lt;br /&gt;
		this.inherited(arguments);&lt;br /&gt;
		dojo.place(&#039;player_board_config&#039;, &#039;player_boards&#039;, &#039;first&#039;);&lt;br /&gt;
	},&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Images and Icons ===&lt;br /&gt;
&lt;br /&gt;
==== Accessing images from js ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
     // your game resources&lt;br /&gt;
     &lt;br /&gt;
     var my_img = &#039;&amp;lt;img src=&amp;quot;&#039;+g_gamethemeurl+&#039;img/cards.jpg&amp;quot;/&amp;gt;&#039;;&lt;br /&gt;
     &lt;br /&gt;
     // shared resources&lt;br /&gt;
     var my_help_img = &amp;quot;&amp;lt;img class=&#039;imgtext&#039; src=&#039;&amp;quot; + g_themeurl + &amp;quot;img/layout/help_click.png&#039; alt=&#039;action&#039; /&amp;gt; &amp;lt;span class=&#039;tooltiptext&#039;&amp;gt;&amp;quot; +&lt;br /&gt;
                    text + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== High-Definition Graphics ====&lt;br /&gt;
&lt;br /&gt;
Some users will have screens which can display text and images at a greater resolution than the usual 72 dpi, e.g. the &amp;quot;Retina&amp;quot; screens on the 5k iMac, all iPads, and high-DPI screens on laptops from many manufacturers. If you can get art assets at this size, they will make your game look extra beautiful. You &#039;&#039;could&#039;&#039; just use large graphics and scale them down, but that would increase the download time and bandwidth for users who can&#039;t display them. Instead, a good way is to prepare a separate graphics file at exactly twice the size you would use otherwise, and add &amp;quot;@2x&amp;quot; at the end of the filename, e.g. if pieces.png is 240x320, then pieces@2x.png is 480x640.&lt;br /&gt;
&lt;br /&gt;
There are two changes required in order to use the separate graphics files. First in your css, where you use a file, add a media query which overrides the original definition and uses the bigger version on devices which can display them. Ensuring that the &amp;quot;background-size&amp;quot; attribute is set means that the size of the displayed object doesn&#039;t change, but only is drawn at the improved dot pitch.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.piece {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    background-image: url(&#039;img/pieces.png&#039;);&lt;br /&gt;
    background-size:240px 320px;&lt;br /&gt;
    z-index: 10;&lt;br /&gt;
}&lt;br /&gt;
@media (-webkit-min-device-pixel-ratio: 2), (min-device-pixel-ratio: 2), (min-resolution: 192dpi)&lt;br /&gt;
{&lt;br /&gt;
    .piece {&lt;br /&gt;
        background-image: url(&#039;img/pieces@2x.png&#039;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Secondly, in your setup function in javascript, you must ensure than only the appropriate one version of the file gets pre-loaded (otherwise you more than waste the bandwidth saved by maintaining the standard-resolution file). Note that the media query is the same in both cases:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
            var isRetina = &amp;quot;(-webkit-min-device-pixel-ratio: 2), (min-device-pixel-ratio: 2), (min-resolution: 192dpi)&amp;quot;;&lt;br /&gt;
            if (window.matchMedia(isRetina).matches)&lt;br /&gt;
            {&lt;br /&gt;
                this.dontPreloadImage( &#039;pieces.png&#039; );&lt;br /&gt;
                this.dontPreloadImage( &#039;board.jpg&#039; );&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                this.dontPreloadImage( &#039;pieces@2x.png&#039; );&lt;br /&gt;
                this.dontPreloadImage( &#039;board@2x.jpg&#039; );&lt;br /&gt;
            }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using CSS to create different colors of game pieces if you have only white piece ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
background-color: #${color}; &lt;br /&gt;
background-blend-mode: multiply;&lt;br /&gt;
background-image: url( &#039;img/mypiece.png&#039;);&lt;br /&gt;
mask: url(&#039;img/mypiece.png&#039;);&lt;br /&gt;
-webkit-mask: url(&#039;img/mypiece.png&#039;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where ${color} - is color you want&lt;br /&gt;
&lt;br /&gt;
Note: piece has to be white (shades of gray). Sprite can be used too, just add add blackground-position as usuall.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Other Fluff ===&lt;br /&gt;
&lt;br /&gt;
==== Use thematic fonts ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.css&lt;br /&gt;
&lt;br /&gt;
Sometime game elements use specific fonts of text, if you want to match it up you can load some specific font (IMPORTANT: from some &#039;&#039;&#039;free font&#039;&#039;&#039; source. See notes below).&lt;br /&gt;
&lt;br /&gt;
[[File:Dragonline_font.png]]&lt;br /&gt;
&lt;br /&gt;
.css&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* latin-ext */&lt;br /&gt;
@font-face {&lt;br /&gt;
  font-family: &#039;Qwigley&#039;;&lt;br /&gt;
  font-style: normal;&lt;br /&gt;
  font-weight: 400;&lt;br /&gt;
  src: local(&#039;Qwigley&#039;), local(&#039;Qwigley-Regular&#039;), url(https://fonts.gstatic.com/s/qwigley/v6/2Dy1Unur1HJoklbsg4iPJ_Y6323mHUZFJMgTvxaG2iE.woff2) format(&#039;woff2&#039;);&lt;br /&gt;
  unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;&lt;br /&gt;
}&lt;br /&gt;
/* latin */&lt;br /&gt;
@font-face {&lt;br /&gt;
  font-family: &#039;Qwigley&#039;;&lt;br /&gt;
  font-style: normal;&lt;br /&gt;
  font-weight: normal;&lt;br /&gt;
  src: local(&#039;Qwigley&#039;), local(&#039;Qwigley-Regular&#039;), url(https://fonts.gstatic.com/s/qwigley/v6/gThgNuQB0o5ITpgpLi4Zpw.woff2) format(&#039;woff2&#039;);&lt;br /&gt;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;&lt;br /&gt;
}&lt;br /&gt;
@font-face {&lt;br /&gt;
  font-family: &#039;Qwigley&#039;;&lt;br /&gt;
  font-style: normal;&lt;br /&gt;
  font-weight: normal;&lt;br /&gt;
  src: local(&#039;Qwigley&#039;), local(&#039;Qwigley-Regular&#039;), url(http://ff.static.1001fonts.net/q/w/qwigley.regular.ttf) format(&#039;ttf&#039;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.zone_title {&lt;br /&gt;
	display: inline-block;&lt;br /&gt;
	position: absolute;&lt;br /&gt;
	font: italic 32px/32px &amp;quot;Qwigley&amp;quot;, cursive;	   &lt;br /&gt;
	height: 32px;&lt;br /&gt;
	width: auto;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NB:&#039;&#039;&#039; if you need to include a font that&#039;s not available online, an extra action will be needed from an admin. Please include the font file(s) in your img directory, and mention it to admins when requesting your game to be moved to alpha. &#039;&#039;&#039;Please remember that the font has to be free, and include a .txt with all appropriate license information about the font.&#039;&#039;&#039;&lt;br /&gt;
You can look for free fonts (for example) on https://fonts.google.com or https://www.fontsquirrel.com/)&lt;br /&gt;
&lt;br /&gt;
=== Use player color in template ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg_ggg.tpl, ggg.view.php&lt;br /&gt;
&lt;br /&gt;
.view.php:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    function build_page($viewArgs) {&lt;br /&gt;
        // Get players &amp;amp; players number&lt;br /&gt;
        $players = $this-&amp;gt;game-&amp;gt;loadPlayersBasicInfos();&lt;br /&gt;
        $players_nbr = count($players);&lt;br /&gt;
        /**&lt;br /&gt;
         * ********* Place your code below: ***********&lt;br /&gt;
         */&lt;br /&gt;
        &lt;br /&gt;
        // Set PCOLOR to the current player color hex&lt;br /&gt;
        global $g_user;&lt;br /&gt;
        $cplayer = $g_user-&amp;gt;get_id();&lt;br /&gt;
        if (array_key_exists($cplayer, $players)) { // may be not set if spectator&lt;br /&gt;
            $player_color = $players [$cplayer] [&#039;player_color&#039;];&lt;br /&gt;
        } else {&lt;br /&gt;
            $player_color = &#039;ffffff&#039;; // spectator&lt;br /&gt;
        }&lt;br /&gt;
        $this-&amp;gt;tpl [&#039;PCOLOR&#039;] = $player_color;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Scale to fit for big boards ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg_ggg.tpl, ggg.js&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Lets say you have huge game board, and lets say you want it to be 1400px wide. Besides the board there will be side bar which is 240 and trim. &lt;br /&gt;
My display is 1920 wide so it fits, but there is big chance other people won&#039;t have that width. What do you do?&lt;br /&gt;
&lt;br /&gt;
You have to decide:&lt;br /&gt;
* If board does not fit you want scale whole thing down, the best way is probably use viewport (see https://en.doc.boardgamearena.com/Your_game_mobile_version)&lt;br /&gt;
* You can leave the board as is and make sure it is scrollable horizonatally&lt;br /&gt;
* You add custom scale just for the board (can add user controls  - and hook to transform: scale())&lt;br /&gt;
&lt;br /&gt;
I tried to auto-scale but this just does work, too many variables - browser zoom, 3d mode, viewport, custom bga scaling, devicePixelRatio - all create some impossible coctail of zooming...&lt;br /&gt;
Here is scaling functing for custom user scaling&lt;br /&gt;
&lt;br /&gt;
ggg_ggg.tpl:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   &amp;lt;div id=&amp;quot;thething&amp;quot; class=&amp;quot;thething&amp;quot;&amp;gt;&lt;br /&gt;
            ... everything else you declare ...&lt;br /&gt;
   &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ggg.js:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    onZoomPlus: function() {&lt;br /&gt;
       this.my_zoom+=0.1;&lt;br /&gt;
       this.zoommy(&#039;thething&#039;,this.my_zoom);&lt;br /&gt;
    },&lt;br /&gt;
&lt;br /&gt;
    zoommy: function(node, zoom) {&lt;br /&gt;
                node=$(node);&lt;br /&gt;
		var width = 100 / zoom;&lt;br /&gt;
		node.style.transformOrigin = &amp;quot;0 0&amp;quot;;&lt;br /&gt;
		node.style.transform = &amp;quot;scale(&amp;quot; + zoom + &amp;quot;)&amp;quot;;&lt;br /&gt;
		node.style.width = width + &amp;quot;%&amp;quot;;&lt;br /&gt;
    },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Dynamic tooltips ===&lt;br /&gt;
&lt;br /&gt;
If you really need a dynamic tooltip you can use this technique. (Only use it if the static tooltips provided by the BGA framework are not sufficient.)&lt;br /&gt;
&lt;br /&gt;
            new dijit.Tooltip({&lt;br /&gt;
                connectId: [&amp;quot;divItemId&amp;quot;],&lt;br /&gt;
                getContent: function(matchedNode){&lt;br /&gt;
                    return &amp;quot;... calculated ...&amp;quot;; &lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is an out-of-the-box djit.Tooltip. It has a &#039;&#039;getContent&#039;&#039; method which is called dynamically.&lt;br /&gt;
&lt;br /&gt;
The string function return becomes the innerHTML of the tooltip, so it can be anything. In this example matchedNode is a dojo node representing dom object with id of &amp;quot;divItemId&amp;quot; but there are more parameters which I am not posting here which allows more sophisticated subnode queries (i.e. you can attach tooltip to all nodes with class or whatever).&lt;br /&gt;
&lt;br /&gt;
[https://dojotoolkit.org/reference-guide/1.10/dijit/Tooltip.html dijit.Tooltip]&lt;br /&gt;
&lt;br /&gt;
It&#039;s not part of the BGA API so use at your own risk.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Rendering text with players color and proper background ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
This example actually writes &amp;quot;You&amp;quot; but you can replace this with player name as easily, drop translating function in this case&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        /* Implementation of proper colored You with background in case of white or light colors  */&lt;br /&gt;
 &lt;br /&gt;
        divYou : function() {&lt;br /&gt;
            var color = this.gamedatas.players[this.player_id].color;&lt;br /&gt;
            var color_bg = &amp;quot;&amp;quot;;&lt;br /&gt;
            if (this.gamedatas.players[this.player_id] &amp;amp;&amp;amp; this.gamedatas.players[this.player_id].color_back) {&lt;br /&gt;
                color_bg = &amp;quot;background-color:#&amp;quot; + this.gamedatas.players[this.player_id].color_back + &amp;quot;;&amp;quot;;&lt;br /&gt;
            }&lt;br /&gt;
            var you = &amp;quot;&amp;lt;span style=\&amp;quot;font-weight:bold;color:#&amp;quot; + color + &amp;quot;;&amp;quot; + color_bg + &amp;quot;\&amp;quot;&amp;gt;&amp;quot; + __(&amp;quot;lang_mainsite&amp;quot;, &amp;quot;You&amp;quot;) + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
            return you;&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Cool realistic shadow effect with CSS ===&lt;br /&gt;
&lt;br /&gt;
==== Rectangles and circles ====&lt;br /&gt;
&lt;br /&gt;
It is often nice to have a drop shadow around tiles and tokens, to separate them from the table visually. It is very easy to add a shadow to rectangular elements, just add this to your css:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.xxx-tile {&lt;br /&gt;
    box-shadow: 3px 3px 3px #000000a0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
box-shadow obeys &#039;&#039;&#039;border-radius&#039;&#039;&#039; of the element, so it will look good for rounded rectangles, and hence also circles (if border-radius is set appropriately).&lt;br /&gt;
&lt;br /&gt;
box-shadow also supports various other parameters and can be used to achieve effects such as glowing, borders, inner shadows etc. If you need to animate a box-shadow, you may be able to get better performance (avoiding redraws) if you attach the shadow to another element (possibly an ::after pseudo-element) and change only the &#039;&#039;&#039;opacity&#039;&#039;&#039; of that element.&lt;br /&gt;
&lt;br /&gt;
==== Irregular Shapes ====&lt;br /&gt;
&lt;br /&gt;
If you wish to make a shadow effect for game pieces that are not a rectangle, but your game pieces are drawn from rectangles in a PNG image, you can apply the shadow to the piece using any art package and save it inside the image. This usually will yield the best performance. Remember to account for the size of the shadow when you lay out images in the sprite sheet.&lt;br /&gt;
&lt;br /&gt;
However that sometimes will not be an option, for example if the image needs to be rotated while the shadow remains offset in the same direction. In this case, one option is to not use box-shadow but use filter, which is supported by recent major browsers.  This way, you can use the alpha channel of your element to drop a shadow.  This even work for transparent backgrounds, so that if you are using the &amp;quot;CSS-sprite&amp;quot; method, it will work!&lt;br /&gt;
&lt;br /&gt;
For instance:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.xxx-token {&lt;br /&gt;
    filter: drop-shadow(0px 0px 1px #000000);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beware that some browsers still do not always draw drop-shadow correctly. In particular, Safari frequently leaves bits of shadow behind when objects move around the screen. In Chrome, shadows sometimes flicker badly if another element is animating close by. Some of these correctness issues can be solved by adding &#039;&#039;&#039;isolation: isolate; will-change: filter;&#039;&#039;&#039; to affected elements, but this significantly affects redraw performance.&lt;br /&gt;
&lt;br /&gt;
Beware of performance issues - particularly on Safari (MacOS, iPhone and iPad). Keep in mind that drop-shadow are very GPU intensive. This becomes noticeable once you have about 40 components with drop-shadow filter. If that is your case, you can quite easily implement a user preference to disable shadows for users on slower machines:&lt;br /&gt;
&lt;br /&gt;
gameoptions.inc.php&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
100 =&amp;gt; array(&lt;br /&gt;
			&#039;name&#039; =&amp;gt; totranslate(&#039;Shadows&#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;Enabled&#039; ), &#039;cssPref&#039; =&amp;gt; &#039;&#039; ),&lt;br /&gt;
					2 =&amp;gt; array( &#039;name&#039; =&amp;gt; totranslate( &#039;Disabled&#039; ), &#039;cssPref&#039; =&amp;gt; &#039;no-shadow&#039; )&lt;br /&gt;
			)&lt;br /&gt;
	),&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[game].css&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.no-shadow * {&lt;br /&gt;
	filter: none !important; &lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Shadows with clip-path ====&lt;br /&gt;
&lt;br /&gt;
For some reason, a shadow will not work together with clip-path on one element. To use both clip-path (when for example using .svg to cut out cardboard components from your .jpg spritesheet) and drop-shadow, you need to wrap the element into another one, and apply drop-shadow to the outer one, and clip-path to the inner one.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;div class=&#039;my-token-wrap&#039;&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&#039;my-token&#039;&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;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.my-token-wrap {&lt;br /&gt;
    filter: drop-shadow(0px 0px 1px #000000);&lt;br /&gt;
}&lt;br /&gt;
.my-token-wrap .my-token {&lt;br /&gt;
    clip-path: url(#my-token-path);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Using the CSS classes from the state machine ===&lt;br /&gt;
&lt;br /&gt;
If you need to hide or show stuff depending on the state of your game, you can of course use javascript, but CSS is hand enough for that.  The #overall-content element does change class depending on the game state.  For instance, if you are in state &#039;&#039;playerTurn&#039;&#039;, it will have the class &#039;&#039;gamestate_playerTurn&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
So now, if you want to show the discard pile only during player turns, you may use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#discard_pile { display: none }&lt;br /&gt;
.gamestate_playerTurn #discard_pile { display: block }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This can be used if you want to change sizing of elements, position, layout or visual appearance.&lt;br /&gt;
&lt;br /&gt;
== Game Model and Database design ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Database for The euro game ===&lt;br /&gt;
Lets say we have a game with workers, dice, tokens, board, resources, money and vp. Workers and dice can be placed in various zones on the board, and you can get resources, money, tokens and vp in your home zone. Also tokens can be flipped or not flipped.&lt;br /&gt;
&lt;br /&gt;
[[File:Madeira board.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now lets try to map it, we have&lt;br /&gt;
* (meeple,zone)&lt;br /&gt;
* (die, zone, sideup)&lt;br /&gt;
* (resource cube/money token/vp token,player home zone)&lt;br /&gt;
* (token, player home zone, flip state)&lt;br /&gt;
We can notice that resource and money are uncountable, and don&#039;t need to be track individually so we can replace our mapping to&lt;br /&gt;
* (resource type/money,player home zone, count)&lt;br /&gt;
And vp stored already for us in player table, so we can remove it from that list.&lt;br /&gt;
&lt;br /&gt;
Now when we get to encode it we can see that everything can be encoded as (object,zone,state) form, where object and zone is string and state is integer. The resource mapping is slightly different semantically so you can go with two table, or counting using same table with state been used as count for resources.&lt;br /&gt;
&lt;br /&gt;
So the piece mapping for non-grid based games can be in most case represented by (string: token_key, string: token_location, int: token_state), example of such database schema can be found here: [https://github.com/elaskavaia/bga-sharedcode/blob/master/dbmodel.sql dbmodel.sql] and class implementing access to it here [https://github.com/elaskavaia/bga-sharedcode/blob/master/modules/tokens.php table.game.php].&lt;br /&gt;
&lt;br /&gt;
Variant 1: Minimalistic&lt;br /&gt;
&lt;br /&gt;
 CREATE TABLE IF NOT EXISTS `token` (&lt;br /&gt;
  `token_key` varchar(32) NOT NULL,&lt;br /&gt;
  `token_location` varchar(32) NOT NULL,&lt;br /&gt;
  `token_state` int(10),&lt;br /&gt;
  PRIMARY KEY (`token_key`)&lt;br /&gt;
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+token&lt;br /&gt;
! token_key&lt;br /&gt;
! token_location&lt;br /&gt;
! token_state&lt;br /&gt;
|-&lt;br /&gt;
|meeple_red_1&lt;br /&gt;
|home_red&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
|dice_black_2&lt;br /&gt;
|board_guard&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
|dice_green_1&lt;br /&gt;
|board_action_mayor&lt;br /&gt;
|3&lt;br /&gt;
|-&lt;br /&gt;
|bread&lt;br /&gt;
|home_red&lt;br /&gt;
|5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Now how we represent resource counters such as bread?&lt;br /&gt;
Using same table from we simply add special counter token for bread and use state to indicate the count. Note to keep first column unique we have to add player identification for that counter, i.e. ff0000 is red player.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+token&lt;br /&gt;
! token_key&lt;br /&gt;
! token_location&lt;br /&gt;
! token_state&lt;br /&gt;
|-&lt;br /&gt;
|bread_ff0000&lt;br /&gt;
|tableau_ff0000&lt;br /&gt;
|5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See php module for this table here https://github.com/elaskavaia/bga-sharedcode/blob/master/modules/tokens.php&lt;br /&gt;
&lt;br /&gt;
Variant 2: Additional resource table, resource count for each player id&lt;br /&gt;
&lt;br /&gt;
 CREATE TABLE IF NOT EXISTS `resource` (&lt;br /&gt;
  `player_id` int(10) unsigned NOT NULL,&lt;br /&gt;
  `resource_key` varchar(32) NOT NULL,&lt;br /&gt;
  `resource_count` int(10) signed NOT NULL,&lt;br /&gt;
  PRIMARY KEY (`player_id`,`resource_key`)&lt;br /&gt;
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;&lt;br /&gt;
&lt;br /&gt;
 ALTER TABLE resource ADD CONSTRAINT fk_player_id FOREIGN KEY (player_id) REFERENCES player(player_id);&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+resource&lt;br /&gt;
! player_id&lt;br /&gt;
! resource_key&lt;br /&gt;
! resource_count&lt;br /&gt;
|-&lt;br /&gt;
|123456&lt;br /&gt;
|bread&lt;br /&gt;
|5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Variant 3: More normalised&lt;br /&gt;
&lt;br /&gt;
This version is similar to &amp;quot;card&amp;quot; table from hearts tutorial, you can also use exact cards database schema and Deck implementation for most purposes (even you not dealing with cards). &lt;br /&gt;
&lt;br /&gt;
 CREATE TABLE IF NOT EXISTS `token` (&lt;br /&gt;
  `token_id` int(10) unsigned NOT NULL AUTO_INCREMENT,&lt;br /&gt;
  `token_type` varchar(16) NOT NULL,&lt;br /&gt;
  `token_arg` int(11) NOT NULL,&lt;br /&gt;
  `token_location` varchar(32) NOT NULL,&lt;br /&gt;
  `token_state` int(10),&lt;br /&gt;
  PRIMARY KEY (`token_id`)&lt;br /&gt;
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+token&lt;br /&gt;
! token_id&lt;br /&gt;
! token_type&lt;br /&gt;
! token_arg&lt;br /&gt;
! token_location&lt;br /&gt;
! token_state&lt;br /&gt;
|-&lt;br /&gt;
|22&lt;br /&gt;
|meeple&lt;br /&gt;
|123456&lt;br /&gt;
|home_123456&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
|23&lt;br /&gt;
|dice&lt;br /&gt;
|2&lt;br /&gt;
|board_guard&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
|26&lt;br /&gt;
|dice&lt;br /&gt;
|1&lt;br /&gt;
|board_action_mayor&lt;br /&gt;
|3&lt;br /&gt;
|-&lt;br /&gt;
|49&lt;br /&gt;
|bread&lt;br /&gt;
|0&lt;br /&gt;
|home_123456&lt;br /&gt;
|5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Advantages of this would be is a bit more straightforward to do some queries in db, disadvantage its hard to read (as you can compare with previous example, you&lt;br /&gt;
cannot just look at say, ah I know what it means). Another questionable advantage is it allows you to do id randomisation, so it hard to do crafted queries to &lt;br /&gt;
cheat, the down side of that you cannot understand it either, and handcraft db states for debugging or testing.&lt;br /&gt;
&lt;br /&gt;
=== Database for The card game ===&lt;br /&gt;
&lt;br /&gt;
Lets say you have a standard card game, player have hidden cards in hand, you can draw card from draw deck, play card on tableau and discard to discard pile.&lt;br /&gt;
We have to design database for such game.&lt;br /&gt;
&lt;br /&gt;
In real word to &amp;quot;save&amp;quot; the game we take a picture a play area, save cards from it, then put away draw deck, discard and hand of each player separately and mark it, also we will record current scoring (if any) and who&#039;s turn was it.&lt;br /&gt;
&lt;br /&gt;
* Framework handles state machine transition, so you don&#039;t have to worry about database design for that (i.e. who&#039;s turn it is, what phase of the game we are at, you still have to design it but part of state machine step)&lt;br /&gt;
* Also framework supports basic player information, color, order around the table, basic scoring, etc, so you don&#039;t have to worry about it either&lt;br /&gt;
* The only thing you need in our database is state of the &amp;quot;board&amp;quot;, which is &amp;quot;where each pieces is, and in what state&amp;quot;, or (position,rotation) pair.&lt;br /&gt;
&lt;br /&gt;
Lets see what we have for that:&lt;br /&gt;
* The card state is very simple, its usually &amp;quot;face up/face down&amp;quot;, &amp;quot;tapped/untapped&amp;quot;, &amp;quot;right side up/up side down&amp;quot;&lt;br /&gt;
* As position go we never need real coordinates x,y,z. We need to know what &amp;quot;zone&amp;quot; card was, and depending on the zone it may sometimes need an extra &amp;quot;z&amp;quot; or &amp;quot;x&amp;quot; as card order. The zone position usually static or irrelevant.&lt;br /&gt;
* So our model is: we have cards, which have some attributes, at any given point in time they belong to a &amp;quot;zone&amp;quot;, and can also have order and state&lt;br /&gt;
* Now for mapping we should consider what information changes and what information is static, later is always candidate for material file&lt;br /&gt;
* For dynamic information we should try to reduce amount of fields we need&lt;br /&gt;
**  we need at least a field for card, so its one&lt;br /&gt;
**  we need to know what zone cards belong to, its 2&lt;br /&gt;
**  and we have possibly few other fields, if you look closely at you game you may find out that most of the zone only need one attribute at a time, i.e. draw pile always have cards face down, hand always face up, also for hand and discard order does not matter at all (but for draw it does matter). So in majority of cases we can get away with one single extra integer field representing state or order&lt;br /&gt;
* In real database both card and zone will be integers as primary keys referring to additional tables, but in our case its total overkill, so they can be strings as easily&lt;br /&gt;
&lt;br /&gt;
Variant 1: Minimalistic&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE TABLE IF NOT EXISTS `card` (&lt;br /&gt;
  `card_key` varchar(32) unsigned NOT NULL,&lt;br /&gt;
  `card_location` varchar(32) NOT NULL,&lt;br /&gt;
  `card_state` int(11) NOT NULL,&lt;br /&gt;
  PRIMARY KEY (`card_id`)&lt;br /&gt;
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Variant 2: More normalised&lt;br /&gt;
&lt;br /&gt;
This version supported by Deck php class, so unless you want to rewrite db access layer go with this one&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE TABLE IF NOT EXISTS `card` (&lt;br /&gt;
  `card_id` int(10) unsigned NOT NULL AUTO_INCREMENT,&lt;br /&gt;
  `card_type` varchar(16) NOT NULL,&lt;br /&gt;
  `card_type_arg` int(11) NOT NULL,&lt;br /&gt;
  `card_location` varchar(16) NOT NULL,&lt;br /&gt;
  `card_location_arg` int(11) NOT NULL,&lt;br /&gt;
  PRIMARY KEY (`card_id`)&lt;br /&gt;
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: if you using this schema, some zones/locations have special semantic. The &#039;hand&#039; location is actually multiple locations - one per player, but player id is encoded as card_location_arg. If &#039;hand&#039; in your game is ordered, visible or can have some other card states, you cannot use hand location (replacement is hand_&amp;lt;player_id&amp;gt; or hand_&amp;lt;color_id&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
== Code Organization ==&lt;br /&gt;
&lt;br /&gt;
=== Including your own JavaScript module ===&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, modules/ggg_other.js&lt;br /&gt;
&lt;br /&gt;
* Create ggg_other.js in modules/ folder and sync&lt;br /&gt;
* Modify ggg.js to include it&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  define([ &amp;quot;dojo&amp;quot;, &amp;quot;dojo/_base/declare&amp;quot;, &amp;quot;ebg/core/gamegui&amp;quot;, &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
    // load my own module!!!&lt;br /&gt;
    g_gamethemeurl + &amp;quot;modules/ggg_other.js&amp;quot; ], function(dojo,&lt;br /&gt;
        declare) {&lt;br /&gt;
&lt;br /&gt;
=== Including your own JavaScript module (II) ===&lt;br /&gt;
&lt;br /&gt;
* Create ggg_other.js in modules/ folder and sync&lt;br /&gt;
&lt;br /&gt;
  define([], function () {&lt;br /&gt;
    return &amp;quot;value&amp;quot;;&lt;br /&gt;
  });&lt;br /&gt;
&lt;br /&gt;
* Modify ggg.js to include it&lt;br /&gt;
&lt;br /&gt;
  define([ &lt;br /&gt;
    &amp;quot;dojo&amp;quot;, &lt;br /&gt;
    &amp;quot;dojo/_base/declare&amp;quot;, &lt;br /&gt;
    &amp;quot;bgagame/modules/ggg_other&amp;quot;, &lt;br /&gt;
    &amp;quot;ebg/core/gamegui&amp;quot;, &lt;br /&gt;
    &amp;quot;ebg/counter&amp;quot;&lt;br /&gt;
  ], function(dojo, declare, other) {&lt;br /&gt;
  &lt;br /&gt;
  });&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
This is maybe a little bit more the idea of the AMD Loader than the first option, although the first option should work as well.&lt;br /&gt;
&lt;br /&gt;
A little explanation to this:&lt;br /&gt;
The define function loads all the modules listed in the array and calls the following function with these loaded modules as parameters.&lt;br /&gt;
By putting your module at the third position in the array it is passed as the third parameter to the function. Be aware that the modules are resolved by position only, not by name. So you can load the module &#039;&#039;&#039;ggg_other&#039;&#039;&#039; and pass it as a parameter with the name &#039;&#039;&#039;other&#039;&#039;&#039;. &#039;&#039;&#039;gamegui&#039;&#039;&#039; and &#039;&#039;&#039;counter&#039;&#039;&#039; are passed in as well, but when the parameters are not defined they are just skipped. Because these modules put their content into the global scope it does not matter and you can use them from there.&lt;br /&gt;
&lt;br /&gt;
In the example above the string &amp;quot;value&amp;quot; is passed for the parameter &#039;&#039;&#039;other&#039;&#039;&#039;, but the function in your module can return whatever you want. It can be an object, an array, something you declared with dojo.declare, you can return even functions. &lt;br /&gt;
Your module can load other modules. Just put them in the array at the beginning and pass them as parameters to your function.&lt;br /&gt;
The advantage of passing the values as parameter is that you do not need to put these values in the global scope, so they can&#039;t be collisions with values defined in other scripts or the BGA Framework.&lt;br /&gt;
&lt;br /&gt;
The dojo toolkit provides good documentation to all of its components, the complete documentation for the AMD-Loader is here:&lt;br /&gt;
https://dojotoolkit.org/documentation/tutorials/1.10/modules/index.html It should be still correct, even as it seems to be only for version 1.10&lt;br /&gt;
&lt;br /&gt;
=== Including your own PHP module ===&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.game.php, modules/ggg_other.php&lt;br /&gt;
&lt;br /&gt;
* Create ggg_other.php in modules/ folder and sync&lt;br /&gt;
* Modify ggg.game.php to include it&lt;br /&gt;
&lt;br /&gt;
 require_once (&#039;modules/ggg_other.php&#039;);&lt;br /&gt;
&lt;br /&gt;
=== Creating a test class to run PHP locally ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.game.php, stubs&lt;br /&gt;
For this you need stubs of other method you can use this for example&lt;br /&gt;
https://github.com/elaskavaia/bga-sharedcode/raw/master/misc/module/table/table.game.php&lt;br /&gt;
&lt;br /&gt;
Create another php files, i.e ggg_test.php&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
define(&amp;quot;APP_GAMEMODULE_PATH&amp;quot;, &amp;quot;misc/&amp;quot;); // include path to stubs, which defines &amp;quot;table.game.php&amp;quot; and other classes&lt;br /&gt;
require_once (&#039;eminentdomaine.game.php&#039;);&lt;br /&gt;
&lt;br /&gt;
class MyGameTest1 extends MyGame { // this is your game class defined in ggg.game.php&lt;br /&gt;
    function __construct() {&lt;br /&gt;
        parent::__construct();&lt;br /&gt;
        include &#039;../material.inc.php&#039;;// this is how this normally included, from constructor&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // override/stub methods here that access db and stuff&lt;br /&gt;
    function getGameStateValue($var) {&lt;br /&gt;
        if ($var == &#039;round&#039;)&lt;br /&gt;
            return 3;&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
$x = new MyGameTest1(); // instantiate your class&lt;br /&gt;
$p = $x-&amp;gt;getGameProgression(); // call one of the methods to test&lt;br /&gt;
if ($p != 50)&lt;br /&gt;
    echo &amp;quot;Test1: FAILED&amp;quot;;&lt;br /&gt;
else&lt;br /&gt;
    echo &amp;quot;Test1: PASSED&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Run from command line like&lt;br /&gt;
 php7 ggg_test.php&lt;br /&gt;
&lt;br /&gt;
If you do it this way - you can also use local php debugger (i.e. integrated with IDE or command line).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Avoiding code in dojo declare style ===&lt;br /&gt;
Dojo class declarations are rather bizzare and do not work with most IDEs.&lt;br /&gt;
If you want to write in plain JS with classes, you can stub all the dojo define/declare stuff&lt;br /&gt;
and hook your class into that, so the classes are outside of this mess.&lt;br /&gt;
&lt;br /&gt;
NOTE: this technique is for experienced developers, do not try it if you do not understand&lt;br /&gt;
the consequences.&lt;br /&gt;
&lt;br /&gt;
This is complete example of game .js class&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  // Testla is game name is has to be changed&lt;br /&gt;
class Testla {&lt;br /&gt;
	constructor(game) {&lt;br /&gt;
		console.log(&#039;game constructor&#039;);&lt;br /&gt;
		this.game = game;&lt;br /&gt;
		this.varfoo = new MyFoo(); // this example of class from custom module&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	setup(gamedatas) {&lt;br /&gt;
		console.log(&amp;quot;Starting game setup&amp;quot;, this.varfoo);&lt;br /&gt;
		this.gamedatas = gamedatas;&lt;br /&gt;
		this.dojo.create(&amp;quot;div&amp;quot;, { class: &#039;whiteblock&#039;, innerHTML: _(&amp;quot;hello&amp;quot;) }, &#039;thething&#039;);&lt;br /&gt;
		console.log(&amp;quot;Ending game setup&amp;quot;);&lt;br /&gt;
	};&lt;br /&gt;
	onEnteringState(stateName, args) {&lt;br /&gt;
		console.log(&#039;onEnteringState : &#039; + stateName, args);&lt;br /&gt;
		this.game.addActionButton(&#039;b1&#039;,_(&#039;Click Me&#039;), (e)=&amp;gt;this.onButtonClick(e));&lt;br /&gt;
	};&lt;br /&gt;
	onLeavingState(stateName) {&lt;br /&gt;
		console.log(&#039;onLeavingState : &#039; + stateName, args);&lt;br /&gt;
	};&lt;br /&gt;
	onUpdateActionButtons(stateName, args) {&lt;br /&gt;
		console.log(&#039;onUpdateActionButtons : &#039; + stateName, args);&lt;br /&gt;
	};&lt;br /&gt;
	onButtonClick(event) {&lt;br /&gt;
		console.log(&#039;onButtonClick&#039;,event);&lt;br /&gt;
	};&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&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;
	g_gamethemeurl + &#039;/modules/foo.js&#039; // custom module if needed&lt;br /&gt;
],&lt;br /&gt;
	function(dojo, declare) {&lt;br /&gt;
                // testla is game name is has to be changed&lt;br /&gt;
		return declare(&amp;quot;bgagame.testla&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
			constructor: function() {&lt;br /&gt;
				this.xapp = new Testla(this);&lt;br /&gt;
				this.xapp.dojo = dojo;&lt;br /&gt;
			},&lt;br /&gt;
			setup: function(gamedatas) {&lt;br /&gt;
				this.xapp.setup(gamedatas);&lt;br /&gt;
			},&lt;br /&gt;
			onEnteringState: function(stateName, args) {&lt;br /&gt;
				this.xapp.onEnteringState(stateName, args.args);&lt;br /&gt;
			},&lt;br /&gt;
			onLeavingState: function(stateName) {&lt;br /&gt;
				this.xapp.onLeavingState(stateName, args);&lt;br /&gt;
			},&lt;br /&gt;
			onUpdateActionButtons: function(stateName, args) {&lt;br /&gt;
				this.xapp.onUpdateActionButtons(stateName, args);&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;
=== More readable JS: onEnteringState ===&lt;br /&gt;
&lt;br /&gt;
If you have a lot of states onEnteringState and friends become rather wild, you can do this trick to call some method dynamically.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
     onEnteringState: function(stateName, args) {&lt;br /&gt;
       console.log(&#039;Entering state: &#039; + stateName, args);&lt;br /&gt;
&lt;br /&gt;
       // Call appropriate method&lt;br /&gt;
       var methodName = &amp;quot;onEnteringState_&amp;quot; + stateName;&lt;br /&gt;
       if (this[methodName] !== undefined) {             &lt;br /&gt;
          console.log(&#039;Calling &#039; + methodName, args.args);&lt;br /&gt;
          this[methodName](args.args);&lt;br /&gt;
       }&lt;br /&gt;
     },&lt;br /&gt;
&lt;br /&gt;
     onEnteringState_playerTurn: function(args) { // this is args directly, not args.args &lt;br /&gt;
         // process&lt;br /&gt;
     },&lt;br /&gt;
&lt;br /&gt;
     onEnteringState_playerSomethingElse: function(args) { &lt;br /&gt;
         // process&lt;br /&gt;
     },&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: since its ignores the undefined functions you don&#039;t have define function for each state, but on the other hand you cannot make typos.&lt;br /&gt;
Same applies to onUpdateActionButtons except you pass &#039;args&#039; to method, not args.args, and for onLeavingState where you don&#039;t pass anything.&lt;br /&gt;
&lt;br /&gt;
=== Frameworks and Preprocessors ===&lt;br /&gt;
&lt;br /&gt;
* [[Using Vue]] - work-in-progress guide on using the modern framework Vue.js to create a game&lt;br /&gt;
* [[Using Typescript and Scss]] - How to auto-build Typescript and SCSS files to make your code cleaner&lt;br /&gt;
&lt;br /&gt;
== Assorted Stuff ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Out-of-turn actions: Un-pass ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, ggg.game.php, ggg.action.php, states.inc.php&lt;br /&gt;
&lt;br /&gt;
In multiplayer game sometimes players passes but than they think more and want to un-Pass and redo their choice. &lt;br /&gt;
To re-active a player who passes some trickery required.&lt;br /&gt;
&lt;br /&gt;
Define a special action that does that and hook it up.&lt;br /&gt;
&lt;br /&gt;
In states.inc.php add an action to mmultipleactiveplayer state to &amp;quot;unpass&amp;quot;, lets call it &amp;quot;actionCancel&amp;quot;&lt;br /&gt;
&lt;br /&gt;
In ggg.action.php add action hook&lt;br /&gt;
    public function actionCancel() {&lt;br /&gt;
        self::setAjaxMode();&lt;br /&gt;
        $this-&amp;gt;game-&amp;gt;actionCancel();&lt;br /&gt;
        self::ajaxResponse();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
In ggg.game.php add action handler&lt;br /&gt;
    function actionCancel() {&lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;checkPossibleAction(&#039;actionCancel&#039;);&lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;setPlayersMultiactive(array ($this-&amp;gt;getCurrentPlayerId() ), &#039;error&#039;, false);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
Finally to call this in client ggg.js you would do something like:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 onUpdateActionButtons:  function(stateName, args) {&lt;br /&gt;
   if (this.isCurrentPlayerActive()) { &lt;br /&gt;
     // ...&lt;br /&gt;
   } else if (!this.isSpectator) { // player is NOT active but not spectator&lt;br /&gt;
       switch (stateName) {&lt;br /&gt;
          case &#039;playerTurnMuliPlayerState&#039;:&lt;br /&gt;
		this.addActionButton(&#039;button_unpass&#039;, _(&#039;Oh no!&#039;), &#039;onUnpass&#039;);&lt;br /&gt;
		break;&lt;br /&gt;
	}&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
				&lt;br /&gt;
 onUnpass: function(e) {&lt;br /&gt;
    this.ajaxcall(&amp;quot;/&amp;quot; + this.game_name + &amp;quot;/&amp;quot; +  this.game_name + &amp;quot;/actionCancel.html&amp;quot;, {}, this); // no checkAction!&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Although be careful that if the turn comes back to the player while he is about to click cancel, the action buttons will be updated and the player will misclick which can be quite frustrating. To avoid this, move the cancel button to another position, like to the left of pagemaintitletext:&lt;br /&gt;
  dojo.place(&#039;button_unpass&#039;, &#039;pagemaintitletext&#039;, &#039;before&#039;);&lt;br /&gt;
Being out of the generalactions div, it won&#039;t be automatically destroyed like normal buttons, so you&#039;ll have to handle that yourself in onLeavingState. You might also want to change the button color to red (blue buttons for active player only, red buttons also for inactive players?)&lt;br /&gt;
&lt;br /&gt;
Note: same technique can be used to do other out-of-turn actions, such as re-arranging cards in hand, exchanging resources, etc (i.e. if permitted by rules, such as &amp;quot;at any time player can...&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
=== Multi Step Interactions: Select Worker/Place Worker - Using Selection ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
Simple way to implement something like that without extra states is to use &amp;quot;selection&amp;quot; mechanism. When user click on worker add some sort of class into that element i.e. &#039;selected&#039; (which also have to have some indication by css i.e. outline).&lt;br /&gt;
&lt;br /&gt;
Than user can click on placement zone, you can use dojo.query for &amp;quot;selected&amp;quot; element and use it along with zone id to send data to server. If proper worker is not selected yet can give a error message using this.showMessage(...) function.&lt;br /&gt;
&lt;br /&gt;
Extra code required to properly cleanup selection between states.&lt;br /&gt;
Also when you do that sometimes you want to change the state prompt, see below &#039;Change state prompt&#039;&lt;br /&gt;
&lt;br /&gt;
=== Multi Step Interactions: Select Worker/Place Worker - Using Client States ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
I don&#039;t think its documented feature but there is a way to do client-only states, which is absolutely wonderful for few reasons&lt;br /&gt;
* When player interaction is two step process, such as select worker, place worker, or place worker, pick one of two resources of your choice&lt;br /&gt;
* When multi-step process can result of impossible situation and has to be undone (by rules)&lt;br /&gt;
* When multi-step process is triggered from multiple states (such as you can do same thing as activated card action, pass action or main action)&lt;br /&gt;
&lt;br /&gt;
So lets do Select Worker/Place Worker&lt;br /&gt;
&lt;br /&gt;
Define your server state as usual, i.e. playerMainTurn -&amp;gt; &amp;quot;You must pick up a worker&amp;quot;.&lt;br /&gt;
Now define a client state, we only need &amp;quot;name&amp;quot; and &amp;quot;descriptionmyturn&amp;quot;, lets say &amp;quot;client_playerPicksLocation&amp;quot;. Always prefix names of client state with &amp;quot;client_&amp;quot; to avoid confusion. Now we have to do the following:&lt;br /&gt;
* Have a handler for onUpdateActionButtons for playerMainTurn to activate all possible workers he can pick&lt;br /&gt;
* When player clicks workers, remember the worker in one of the members of the main class, I usually use one called this.clientStateArgs.&lt;br /&gt;
* Transition to new client state&lt;br /&gt;
  onWorker: function(e) {&lt;br /&gt;
      var id = event.currentTarget.id;&lt;br /&gt;
      dojo.stopEvent(event);&lt;br /&gt;
      ... // do validity checks&lt;br /&gt;
      this.clientStateArgs.worker_id = id;&lt;br /&gt;
      this.setClientState(&amp;quot;client_playerPicksLocation&amp;quot;, {&lt;br /&gt;
                                descriptionmyturn : _(&amp;quot;${you} must select location&amp;quot;),&lt;br /&gt;
                            });&lt;br /&gt;
   }&lt;br /&gt;
* Have a handler for onUpdateActionButtons for client_playerPicksLocation to activate all possible locations this worker can go AND add Cancel button (see below)&lt;br /&gt;
* Have a location handler which will eventually send a server request, using stored this.clientStateArgs.worker_id as worker id&lt;br /&gt;
* The cancel button should call a method to restore server state, also if you doing it for more than one state you can add this universally using this.on_client_state check&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        if (this.isCurrentPlayerActive()) {&lt;br /&gt;
          if (this.on_client_state &amp;amp;&amp;amp; !$(&#039;button_cancel&#039;)) {&lt;br /&gt;
               this.addActionButton(&#039;button_cancel&#039;, _(&#039;Cancel&#039;), dojo.hitch(this, function() {&lt;br /&gt;
                                             this.restoreServerGameState();&lt;br /&gt;
               }));&lt;br /&gt;
          }&lt;br /&gt;
        } &lt;br /&gt;
Note: usually I call my own function call this.cancelLocalStateEffects() which will do more stuff first then call restoreServerGameState(), same function is usually needs to be called when server request has failed (i.e. invalid move)&lt;br /&gt;
&lt;br /&gt;
Note: If you need more than 2 steps, you may have to do client side animation to reflect the new state, which gets trickier because you have to undo that also on cancellation.&lt;br /&gt;
&lt;br /&gt;
Code is available here [https://github.com/elaskavaia/bga-sharedcode/blob/master/sharedcode.js sharedcode.js] (its using playerTurnPlayCubes and client_selectCubeLocation).&lt;br /&gt;
&lt;br /&gt;
=== Action Stack - Using Client States ===&lt;br /&gt;
&lt;br /&gt;
Action stack required where game is very complex and use triggered effects that can &amp;quot;stack&amp;quot;. It not always actual stack, it can be queue or random access&lt;br /&gt;
Examples:&lt;br /&gt;
* Magic the Gathering - classic card game where effects go on Stack, that allows to counter spell and counter spell of counter spell (not on bga - it just example of mechanics)&lt;br /&gt;
* Ultimate Railroads - action taking game where effects can be executed in any order&lt;br /&gt;
* Lewis and Clark - card game where actions executed as queue&lt;br /&gt;
&lt;br /&gt;
There is two ways of implementing it - on the server or the client.&lt;br /&gt;
For the server see article below.&lt;br /&gt;
The requirement for client side stack is all action can be undone, which means&lt;br /&gt;
* No dice rolls&lt;br /&gt;
* No card drawn&lt;br /&gt;
* No other players interaction&lt;br /&gt;
&lt;br /&gt;
No snippets are here, as this will be too complex but basically flow is:&lt;br /&gt;
* You have a action/effect stack (queue/list) as js object attached to &amp;quot;this&amp;quot;, i.e. this.unprocessed_actions&lt;br /&gt;
* When player plays a card, worker, etc, you read the effect of that card from the material file (client copy), and place into stack&lt;br /&gt;
* Then we call dispatch method which pulls the next action from the stack and change client state accordinly,i.e.  this.setClientState(&amp;quot;client_playerGainsCubes&amp;quot;)&lt;br /&gt;
* When players acts on it - the action is removed from the stack and added to &amp;quot;server action arguments&amp;quot; list, this is another object which be used to send ajax call, i.e. this.clientStateArgs&lt;br /&gt;
* If nothing left in stack we can submit the ajax call assembling parameters from collected arguments (that can include action name)&lt;br /&gt;
* This method allows cheap undo - by restoring server state you will wipe out all user actions (but if you need intermediate aninmation you have to handle it yourself)&lt;br /&gt;
&lt;br /&gt;
Code can be found in Ultimate Railroads game (but it is random access list - so it a bit complex) and Lewis and Clark (complexity - use can always deny part of any effect)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Action Stack - Using Server States ===&lt;br /&gt;
&lt;br /&gt;
See definition of Action Stack above.&lt;br /&gt;
&lt;br /&gt;
To implement you usually need another db table that has the following fields: index of effect - which is used for sorted access, type - which is essense of the effect (i.e. collect resource), some extra arguments (i.e. resource type and resource count), and usually owner of the effect (i.e. player id)&lt;br /&gt;
The flow is:&lt;br /&gt;
* There is some initial player state, where player can play card for example&lt;br /&gt;
* Player main action - pushes the card effect on stack, which also can cause triggered effects which also go on stack&lt;br /&gt;
* After action processing is finished switch to game state which is &amp;quot;dispatcher&amp;quot;&lt;br /&gt;
* Gispatcher pulls the top effect (whatever definition of the top is), changes the active player and changes the state to appropriate player state to collect response&lt;br /&gt;
* Player state knows about the stack and pulls arguments (argX) from the effect arguments of the db&lt;br /&gt;
* Player action should clear up the top effect, and can possibly add more effects, then switch to &amp;quot;dispatcher&amp;quot; state again&lt;br /&gt;
* If stack is empty, dispatcher can either pick next player itself or use another game state which responsible for picking next player&lt;br /&gt;
&lt;br /&gt;
Code can be found in Tapestry.&lt;br /&gt;
&lt;br /&gt;
=== Changing state prompt ===&lt;br /&gt;
&lt;br /&gt;
State prompt is message displayed for player which usually comes from state description.&lt;br /&gt;
Sometimes you want to change it without changing state (one way is change state but locally, see client states above).&lt;br /&gt;
&lt;br /&gt;
Simple way just change the html&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        setMainTitle: function(text) {&lt;br /&gt;
            $(&#039;pagemaintitletext&#039;).innerHTML = text;&lt;br /&gt;
        },&lt;br /&gt;
         // usage&lt;br /&gt;
        onMeeple: function(event) {&lt;br /&gt;
              //... &lt;br /&gt;
              this.setMainTitle(_(&#039;You must select where meeple is going&#039;));&lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This however will not work with parameters and will not draw You in color, if you want this its more sophisticated:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        setDescriptionOnMyTurn : function(text) {&lt;br /&gt;
            this.gamedatas.gamestate.descriptionmyturn = text;&lt;br /&gt;
            var tpl = dojo.clone(this.gamedatas.gamestate.args);&lt;br /&gt;
            if (tpl === null) {&lt;br /&gt;
                tpl = {};&lt;br /&gt;
            }&lt;br /&gt;
            var title = &amp;quot;&amp;quot;;&lt;br /&gt;
            if (this.isCurrentPlayerActive() &amp;amp;&amp;amp; text !== null) {&lt;br /&gt;
                tpl.you = this.divYou(); &lt;br /&gt;
            }&lt;br /&gt;
            title = this.format_string_recursive(text, tpl);&lt;br /&gt;
&lt;br /&gt;
            if (!title) {&lt;br /&gt;
                this.setMainTitle(&amp;quot;&amp;amp;nbsp;&amp;quot;);&lt;br /&gt;
            } else {&lt;br /&gt;
                this.setMainTitle(title);&lt;br /&gt;
            }&lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: this method uses &#039;&#039;&#039;setMainTitle&#039;&#039;&#039; defined above and &#039;&#039;&#039;divYou&#039;&#039;&#039; defined in another section of this wiki.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Adding Image buttons ===&lt;br /&gt;
&lt;br /&gt;
Its pretty trivial but just in case you need a working function:&lt;br /&gt;
&lt;br /&gt;
ggg.js:&lt;br /&gt;
&lt;br /&gt;
                addImageActionButton: function (id, div_html, handler) { // div_html is string not node&lt;br /&gt;
                    this.addActionButton(id, div_html, handler, &#039;&#039;, false, &#039;gray&#039;); &lt;br /&gt;
                    dojo.style(id, &amp;quot;border&amp;quot;, &amp;quot;none&amp;quot;); // remove ugly border&lt;br /&gt;
                    dojo.addClass(id, &amp;quot;bgaimagebutton&amp;quot;); // add css class to do more styling&lt;br /&gt;
                    return $(id); // return node for chaining&lt;br /&gt;
                },&lt;br /&gt;
&lt;br /&gt;
Example of usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    this.addImageActionButton(&#039;button_coin&#039;,&amp;quot;&amp;lt;div class=&#039;coin&#039;&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;, ()=&amp;gt;{ alert(&#039;Ha!&#039;); });&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Assigning Player Order ===&lt;br /&gt;
Normally when game starts there is &amp;quot;natural&amp;quot; player order assigned randomly.&lt;br /&gt;
&lt;br /&gt;
If you want to deliberatly assign player order at the start of the game (for example, in a game with teams options), you can do so by retrieving the initialization-only player attribute &#039;&#039;&#039;player_table_order&#039;&#039;&#039; and using it to assign values to &#039;&#039;&#039;player_no&#039;&#039;&#039; (which is normally assigned at the start of a game in the order in which players come to the table). (See [https://en.doc.boardgamearena.com/Game_database_model:_dbmodel.sql#The_player_table Game database model] for more details.)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Example:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                // Retrieve inital player order ([0=&amp;gt;playerId1, 1=&amp;gt;playerId2, ...])&lt;br /&gt;
		$playerInitialOrder = [];&lt;br /&gt;
		foreach ($players as $playerId =&amp;gt; $player) {&lt;br /&gt;
			$playerInitialOrder[$player[&#039;player_table_order&#039;]] = $playerId;&lt;br /&gt;
		}&lt;br /&gt;
		ksort($playerInitialOrder);&lt;br /&gt;
		$playerInitialOrder = array_flip(array_values($playerInitialOrder));&lt;br /&gt;
&lt;br /&gt;
		// Player order based on &#039;playerTeams&#039; option&lt;br /&gt;
		$playerOrder = [0, 1, 2, 3];&lt;br /&gt;
		switch (self::getGameStateValue(&#039;playerTeams&#039;)) {&lt;br /&gt;
			case self::TEAM_1_2:&lt;br /&gt;
				$playerOrder = [0, 2, 1, 3];&lt;br /&gt;
				break;&lt;br /&gt;
			case self::TEAM_1_4:&lt;br /&gt;
				$playerOrder = [0, 1, 3, 2];&lt;br /&gt;
				break;&lt;br /&gt;
			case self::TEAM_RANDOM:&lt;br /&gt;
				shuffle($playerOrder);&lt;br /&gt;
				break;&lt;br /&gt;
			default:&lt;br /&gt;
			case self::TEAM_1_3:&lt;br /&gt;
				// Default order&lt;br /&gt;
				break;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
                // Create players&lt;br /&gt;
		// Note: if you added some extra field on &amp;quot;player&amp;quot; table in the database (dbmodel.sql), you can initialize it there.&lt;br /&gt;
		$sql =&lt;br /&gt;
			&#039;INSERT INTO player (player_id, player_color, player_canal, player_name, player_avatar, player_no) VALUES &#039;;&lt;br /&gt;
		$values = [];&lt;br /&gt;
&lt;br /&gt;
		foreach ($players as $playerId =&amp;gt; $player) {&lt;br /&gt;
			$color = array_shift($default_colors);&lt;br /&gt;
			$values[] =&lt;br /&gt;
				&amp;quot;(&#039;&amp;quot; .&lt;br /&gt;
				$playerId .&lt;br /&gt;
				&amp;quot;&#039;,&#039;$color&#039;,&#039;&amp;quot; .&lt;br /&gt;
				$player[&#039;player_canal&#039;] .&lt;br /&gt;
				&amp;quot;&#039;,&#039;&amp;quot; .&lt;br /&gt;
				addslashes($player[&#039;player_name&#039;]) .&lt;br /&gt;
				&amp;quot;&#039;,&#039;&amp;quot; .&lt;br /&gt;
				addslashes($player[&#039;player_avatar&#039;]) .&lt;br /&gt;
				&amp;quot;&#039;,&#039;&amp;quot; .&lt;br /&gt;
				$playerOrder[$playerInitialOrder[$playerId]] .&lt;br /&gt;
				&amp;quot;&#039;)&amp;quot;;&lt;br /&gt;
		}&lt;br /&gt;
		$sql .= implode(&#039;,&#039;, $values);&lt;br /&gt;
		self::DbQuery($sql);&lt;br /&gt;
		self::reattributeColorsBasedOnPreferences(&lt;br /&gt;
			$players,&lt;br /&gt;
			$gameinfos[&#039;player_colors&#039;]&lt;br /&gt;
		);&lt;br /&gt;
		self::reloadPlayersBasicInfos();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Send different notifications to active player vs everybody else ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
Hack alert. This is a hack. We were hoping for proper solution by bga framework.&lt;br /&gt;
&lt;br /&gt;
This will allow you to send notification with two message one for specific player and one for everybody else including spectators.&lt;br /&gt;
Note that this does not split the data - all data must be shared.&lt;br /&gt;
&lt;br /&gt;
Add this to .js file (if you already overriding it merge obviously)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/** @Override */&lt;br /&gt;
format_string_recursive: function(log, args) {&lt;br /&gt;
   if (typeof args.log_others != &#039;undefined&#039; &amp;amp;&amp;amp; typeof args.player_id != &#039;undefined&#039; &amp;amp;&amp;amp; this.player_id != args.player_id)&lt;br /&gt;
	log = args.log_others;&lt;br /&gt;
   return this.inherited(arguments); // you must call this to call super &lt;br /&gt;
},&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example of usage (from eminentdomain)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    $this-&amp;gt;notifyAllPlayers(&#039;tokenMoved&#039;, &lt;br /&gt;
             clienttranslate(&#039;${player_name} adds +2 Colonies to ${place_name}&#039;), // notification with show for player with player_id&lt;br /&gt;
             [&#039;player_id&#039;=&amp;gt;$player_id, // this is mandatory&lt;br /&gt;
             &#039;log_others&#039;=&amp;gt;clienttranslate(&#039;${player_name} adds +2 Colonies to an unknown planet&#039;), // notification will show for others&lt;br /&gt;
              ...&lt;br /&gt;
             ]);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Send transient notifications without incrementing move ID ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.php&lt;br /&gt;
&lt;br /&gt;
Hack alert. This is a hack.&lt;br /&gt;
&lt;br /&gt;
Use this if you need to send some transient notification that should not create a new move ID. The notification should be idempotent -- it should have no practical effect on the game state and would be &#039;&#039;&#039;safe to drop&#039;&#039;&#039; (e.g., it would not matter if a player never received this notification). For example, in a co-op game you want all players to see a real-time preview of some action, before the active player commits their turn.&lt;br /&gt;
&lt;br /&gt;
Doing this mainly affects the instant replay &amp;amp; archive modes. During replay, the BGA framework automatically inserts a 1.5-second pause between each &amp;quot;move&amp;quot;. With this hack, your transient notifications are not considered to be a &amp;quot;move&amp;quot;, so no pause gets added.&lt;br /&gt;
&lt;br /&gt;
; In ggg.php&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$this-&amp;gt;not_a_move_notification = true; // note: do not increase the move counter&lt;br /&gt;
$this-&amp;gt;notifyAllPlayers(&#039;cardsPreview&#039;, &#039;&#039;, $args);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: you cannot have code that send notification or even changes state after this, and you cannot reset this variable back either because it only takes effect when you exit action handling function&lt;br /&gt;
&lt;br /&gt;
=== Ajax Call wrapper ===&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
The current ajaxcall is super vebose and prone to errors, I suggest using a helper function. It does a lot of stuff you must do anyways.&lt;br /&gt;
Most beginner mistakes come from missing part of this code (which is understandstandable - this is a huge snippet to clone every time).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	ajaxcallwrapper: function(action, args, handler) {&lt;br /&gt;
		if (!args) args = []; // this allows to skip args parameter for action which do not require them&lt;br /&gt;
			&lt;br /&gt;
		args.lock = true; // this allows to avoid rapid action clicking which can cause race condition on server&lt;br /&gt;
		if (this.checkAction(action)) { // this does all the proper check that player is active and action is declared&lt;br /&gt;
			this.ajaxcall(&amp;quot;/&amp;quot; + this.game_name + &amp;quot;/&amp;quot; + this.game_name + &amp;quot;/&amp;quot; + action + &amp;quot;.html&amp;quot;, args, // this is mandatory fluff &lt;br /&gt;
				this, (result) =&amp;gt; { },  // success result handler is empty - it is never needed&lt;br /&gt;
                                               handler); // this is real result handler - it called both on success and error, it has optional param  &amp;quot;is_error&amp;quot; - you rarely need it&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   this.ajaxcallwrapper(&#039;pass&#039;); // no args&lt;br /&gt;
   this.ajaxcallwrapper(&#039;playCard&#039;, {card: card_id}); // with args&lt;br /&gt;
   this.ajaxcallwrapper(&#039;playCard&#039;, {card: card_id}, (is_error)=&amp;gt;{if (!is_error) dojo.query(&amp;quot;.selected&amp;quot;).removeClass(&#039;selected&#039;);}) // with handler that cleans up &#039;selected&#039; class on success&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: this always will lock interface and always check for action, you can modify this method to do it optionally, i.e&lt;br /&gt;
  if (args.lock!==false) args.lock = true; else delete args.lock; // it does not work with false value - it has to be removed&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Studio]]&lt;/div&gt;</summary>
		<author><name>SwHawk</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=BGA_Studio_Cookbook&amp;diff=14200</id>
		<title>BGA Studio Cookbook</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=BGA_Studio_Cookbook&amp;diff=14200"/>
		<updated>2022-07-29T18:32:40Z</updated>

		<summary type="html">&lt;p&gt;SwHawk: /* Inject images and styled html in the log */ Added new ways to inject HTML in the log&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
This page is collection of design and implementation recipes for BGA Studio framework.&lt;br /&gt;
For tooling and usage recipes see [[Tools and tips of BGA Studio]].&lt;br /&gt;
If you have your own recipes feel free to edit this page.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Visual Effects, Layout and Animation ==&lt;br /&gt;
&lt;br /&gt;
=== DOM manipulatons ===&lt;br /&gt;
&lt;br /&gt;
==== Create pieces dynamically (using template) ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg_ggg.tpl, ggg.js&lt;br /&gt;
&lt;br /&gt;
Note: this method is recommended by BGA guildlines&lt;br /&gt;
&lt;br /&gt;
Declared js template with variables in .tpl file, like this&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;
    // Javascript HTML templates&lt;br /&gt;
    var jstpl_ipiece = &#039;&amp;lt;div class=&amp;quot;${type} ${type}_${color} inlineblock&amp;quot; aria-label=&amp;quot;${name}&amp;quot; title=&amp;quot;${name}&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use it like this in .js file&lt;br /&gt;
  div = this.format_block(&#039;jstpl_ipiece&#039;, {&lt;br /&gt;
                                type : &#039;meeple&#039;,&lt;br /&gt;
                                color : &#039;ff0000&#039;,&lt;br /&gt;
                                name : &#039;Bob&#039;,&lt;br /&gt;
                            });&lt;br /&gt;
  &lt;br /&gt;
Then you do whatever you need to do with that div, this one specifically design to go to log entries, because it has embedded title (otherwise its a picture only) and no id.&lt;br /&gt;
&lt;br /&gt;
Note: you could have place this variable in js itself, but keeping it in .tpl allows you to have your js code be free of HTML. Normally it never happens but&lt;br /&gt;
it is good to strive for it.&lt;br /&gt;
Note: you can also use string concatenation, its less readable. You can also use dojo dom object creation api&#039;s but its brutally verbose and its more unreadable.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Create pieces dynamically (using string concatenation) ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
Note: Not recommended&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  div = &amp;quot;&amp;lt;div class=&#039;meeple &amp;quot;+color+&amp;quot;&#039;&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
==== Create all pieces statically ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg_ggg.tpl, ggg.css, ggg.view.php (optional) &lt;br /&gt;
&lt;br /&gt;
* Create ALL game pieces in html template (.tpl)&lt;br /&gt;
* ALL pieces should have unique id, and it should be meaningful, i.e. meeple_red_1&lt;br /&gt;
* Do not use inline styling&lt;br /&gt;
* Id of player&#039;s specific pieces should use some sort of &#039;color&#039; identification, since player id cannot be used in static layout, you can use english color name, hex 6 char value, or color &amp;quot;number&amp;quot; (1,2,3...)&lt;br /&gt;
* Pieces should have separated class for its color, type, etc, so it can be easily styled in groups. In example below you now can style all meeples, all red meeples or all red tokens, or all &amp;quot;first&amp;quot; meeples&lt;br /&gt;
&lt;br /&gt;
ggg.tpl:&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
  &amp;lt;div id=&amp;quot;home_red&amp;quot; class=&amp;quot;home_red home&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;div id=&amp;quot;meeple_red_1&amp;quot; class=&amp;quot;meeple red n1&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
     &amp;lt;div id=&amp;quot;meeple_red_2&amp;quot; class=&amp;quot;meeple red n2&amp;quot;&amp;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;
ggg.css:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.meeple {&lt;br /&gt;
	width: 32px;&lt;br /&gt;
	height: 39px;&lt;br /&gt;
	background-image: url(img/78_64_stand_meeples.png);&lt;br /&gt;
	background-size: 352px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.meeple.red {&lt;br /&gt;
	background-position: 30% 0%;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* There should be straight forward mapping between server id and js id (or 1:1)&lt;br /&gt;
* You place objects in different zones of the layout, and setup css to take care of layout&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.home .meeple{&lt;br /&gt;
   display: inline-block;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* If you need to have a temporary object that look like original you can use dojo.clone (and change id to some temp id)&lt;br /&gt;
* If there is lots of repetition or zone grid you can use template generator, but inject style declaration in css instead of inline style for flexibility&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
* If you use this model you cannot use premade js components such as Stock and Zone&lt;br /&gt;
* You have to use alternative methods of animation (slightly altered) since default method will leave object with inline style attributes which you don&#039;t need&lt;br /&gt;
&lt;br /&gt;
=== Logs ===&lt;br /&gt;
&lt;br /&gt;
==== Inject icon images in the log ====&lt;br /&gt;
&lt;br /&gt;
Here is an example of what was done for Terra Mystica which is simple and straightforward:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
//Define the proper message&lt;br /&gt;
		$message = clienttranslate(&#039;${player_name} gets ${power_income} via Structures&#039;);&lt;br /&gt;
		if ($price &amp;gt; 0) {&lt;br /&gt;
			self::DbQuery(&amp;quot;UPDATE player SET player_score = player_score - $price WHERE player_id = $player_id&amp;quot;);&lt;br /&gt;
			$message = clienttranslate(&#039;${player_name} pays ${vp_price} and gets ${power_income} via Structures&#039;);&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
// Notify&lt;br /&gt;
		self::notifyAllPlayers( &amp;quot;powerViaStructures&amp;quot;, $message, array(&lt;br /&gt;
			&#039;i18n&#039; =&amp;gt; array( ),&lt;br /&gt;
			&#039;player_id&#039; =&amp;gt; $player_id,&lt;br /&gt;
			&#039;player_name&#039; =&amp;gt; self::getUniqueValueFromDb( &amp;quot;SELECT player_name FROM player WHERE player_id = $player_id&amp;quot; ),&lt;br /&gt;
			&#039;power_tokens&#039; =&amp;gt; $power_tokens,&lt;br /&gt;
			&#039;vp_price&#039; =&amp;gt; self::getLogsVPAmount($price),&lt;br /&gt;
			&#039;power_income&#039; =&amp;gt; self::getLogsPowerAmount($power_income),&lt;br /&gt;
			&#039;newScore&#039; =&amp;gt; self::getUniqueValueFromDb( &amp;quot;SELECT player_score FROM player WHERE player_id = $player_id&amp;quot; ),&lt;br /&gt;
			&#039;counters&#039; =&amp;gt; $this-&amp;gt;getGameCounters(null),&lt;br /&gt;
		) );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With some functions to have the needed html added inside the substitution variable, such as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function getLogsPowerAmount( $amount ) {&lt;br /&gt;
		return &amp;quot;&amp;lt;div class=&#039;tmlogs_icon&#039; title=&#039;Power&#039;&amp;gt;&amp;lt;div class=&#039;power_amount&#039;&amp;gt;$amount&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: injecting html from php is not ideal but easy, if you want more clean solution, use method below but it is a lot more sophisticated.&lt;br /&gt;
&lt;br /&gt;
==== Inject images and styled html in the log ====&lt;br /&gt;
&lt;br /&gt;
So you want nice pictures in the game log. What do you do? The first idea that comes to mind is to send html from php in notifications (see method above). &lt;br /&gt;
&lt;br /&gt;
This is a bad idea for many reasons:&lt;br /&gt;
&lt;br /&gt;
* It&#039;s bad architecture. ui elements leak into the server, and now you have to manage the ui in multiple places.&lt;br /&gt;
* If you decided to change something in the ui in future version, replay logs for old games and tutorials may not work, since they use stored notifications.&lt;br /&gt;
* Log previews for old games become unreadable. (This is the log state before you enter the game replay, which is useful for troubleshooting and game analysis.)&lt;br /&gt;
* It&#039;s more data to transfer and store in the db.&lt;br /&gt;
* It&#039;s a nightmare for translators.&lt;br /&gt;
&lt;br /&gt;
So what else can you do? You can use client side log injection to intercept log arguments (which come from the server) and replace them with html on the client side. Here are three different method you can use to achieve this.&lt;br /&gt;
&lt;br /&gt;
===== First way : Override &amp;lt;code&amp;gt;this.format_string_recursive()&amp;lt;/code&amp;gt; method =====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, ggg.game.php&lt;br /&gt;
&lt;br /&gt;
I use this recipe for &#039;&#039;&#039;client side log injection&#039;&#039;&#039; to intercept log arguments (which come from the server) and replace them with html on the client side.&lt;br /&gt;
&lt;br /&gt;
[[File:clientloginjection.png|left]] &lt;br /&gt;
&lt;br /&gt;
ggg.js&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
        /** Override this function to inject html into log items. This is a built-in BGA method.  */&lt;br /&gt;
&lt;br /&gt;
        /* @Override */&lt;br /&gt;
        format_string_recursive : function format_string_recursive(log, args) {&lt;br /&gt;
            try {&lt;br /&gt;
                if (log &amp;amp;&amp;amp; args &amp;amp;&amp;amp; !args.processed) {&lt;br /&gt;
                    args.processed = true;&lt;br /&gt;
                    &lt;br /&gt;
&lt;br /&gt;
                    // list of special keys we want to replace with images&lt;br /&gt;
                    var keys = [&#039;place_name&#039;,&#039;token_name&#039;];&lt;br /&gt;
                    &lt;br /&gt;
                  &lt;br /&gt;
                    for ( var i in keys) {&lt;br /&gt;
                        var key = keys[i];&lt;br /&gt;
                        key in args &amp;amp;&amp;amp; args[key] = this.getTokenDiv(key, args);                            &lt;br /&gt;
&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            } catch (e) {&lt;br /&gt;
                console.error(log,args,&amp;quot;Exception thrown&amp;quot;, e.stack);&lt;br /&gt;
            }&lt;br /&gt;
            return this.inherited({callee: format_string_recursive}, arguments);&lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important:&#039;&#039;&#039; In the &#039;&#039;format_string_recursive&#039;&#039; method, the &#039;args&#039; parameter will only contain arguments passed to it from the notify method in ggg.game.php (see below).&lt;br /&gt;
&lt;br /&gt;
The &#039;log&#039; parameter is the actual string that is inserted into the logs. You can perform additional js string manipulation on it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        getTokenDiv : function(key, args) {&lt;br /&gt;
            // ... implement whatever html you want here, example from sharedcode.js&lt;br /&gt;
            var token_id = args[key];&lt;br /&gt;
            var item_type = getPart(token_id,0);&lt;br /&gt;
            var logid = &amp;quot;log&amp;quot; + (this.globalid++) + &amp;quot;_&amp;quot; + token_id;&lt;br /&gt;
            switch (item_type) {&lt;br /&gt;
                case &#039;wcube&#039;:&lt;br /&gt;
                    var tokenDiv = this.format_block(&#039;jstpl_resource_log&#039;, {&lt;br /&gt;
                        &amp;quot;id&amp;quot; : logid,&lt;br /&gt;
                        &amp;quot;type&amp;quot; : &amp;quot;wcube&amp;quot;,&lt;br /&gt;
                        &amp;quot;color&amp;quot; : getPart(token_id,1),&lt;br /&gt;
                    });&lt;br /&gt;
                    return tokenDiv;&lt;br /&gt;
             &lt;br /&gt;
                case &#039;meeple&#039;:&lt;br /&gt;
                    if ($(token_id)) {&lt;br /&gt;
                        var clone = dojo.clone($(token_id));&lt;br /&gt;
    &lt;br /&gt;
                        dojo.attr(clone, &amp;quot;id&amp;quot;, logid);&lt;br /&gt;
                        this.stripPosition(clone);&lt;br /&gt;
                        dojo.addClass(clone, &amp;quot;logitem&amp;quot;);&lt;br /&gt;
                        return clone.outerHTML;&lt;br /&gt;
                    }&lt;br /&gt;
                    break;&lt;br /&gt;
     &lt;br /&gt;
                default:&lt;br /&gt;
                    break;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            return &amp;quot;&#039;&amp;quot; + this.clienttranslate_string(this.getTokenName(token_id)) + &amp;quot;&#039;&amp;quot;;&lt;br /&gt;
       },&lt;br /&gt;
       getTokenName : function(key) {&lt;br /&gt;
           return this.gamedatas.token_types[key].name; // get name for the key, from static table for example&lt;br /&gt;
       },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that in this case the server simply injects token_id as a name, and the client substitutes it for the translated name or the picture.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ggg.game.php:&lt;br /&gt;
&lt;br /&gt;
           $this-&amp;gt;notifyAllPlayers(&#039;playerLog&#039;,clienttranslate(&#039;Game moves ${token_name}&#039;),[&#039;token_name&#039;=&amp;gt;$token_id]);&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important:&#039;&#039;&#039; As noted above, only arguments actually passed by this method are available to the args parameter received in the client-side &#039;&#039;format_string_recursive&#039;&#039; method.&lt;br /&gt;
&lt;br /&gt;
Sometimes it is the case that you want to pass arguments that are not actually included in the output message. For example, suppose we have a method like this:&lt;br /&gt;
&lt;br /&gt;
           $this-&amp;gt;notifyAllPlayers(&#039;tokenPlaced&#039;,clienttranslate(&#039;Player placed ${token_name}&#039;),array(&lt;br /&gt;
              &#039;token_name&#039; =&amp;gt; $token_id,&lt;br /&gt;
              &#039;zone_played&#039; =&amp;gt; $zone);&lt;br /&gt;
&lt;br /&gt;
This will output &amp;quot;Player placed ${token_name}&amp;quot; in the log, and if we subscribe to a notification method activated by the &amp;quot;tokenPlaced&amp;quot; event in the client-side code, that method can make use of the &#039;zone_played&#039; argument. &lt;br /&gt;
&lt;br /&gt;
Now if you want to make some really cool things with game log, most probably you would need more arguments than are included in log message. The problem with that,&lt;br /&gt;
it will work at first, but if you reload game using F5 or when the game loads in turn based mode, you will loose your additional parameters, why? Because when game reloads it does not actually send same notifications, it sends special &amp;quot;hitstorical_log&amp;quot; notification where all  parameters not listed in the message are removed. In example above, field zone_played would be removed from historical log as it is not included in message of the notification. You can till preserve specific arguments in historical log by adding special field preserve to notification arguments like this:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
           $this-&amp;gt;notifyAllPlayers(&#039;tokenPlaced&#039;,clienttranslate(&#039;Player placed ${token_name}&#039;),array(&lt;br /&gt;
              &#039;token_name&#039; =&amp;gt; $token_id,&lt;br /&gt;
              &#039;zone_played&#039; =&amp;gt; $zone,&lt;br /&gt;
              &#039;preserve&#039; =&amp;gt; [ &#039;zone_played&#039; ]&lt;br /&gt;
           );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now you can use zone_played in format_string_recursive even in historical logs.&lt;br /&gt;
&lt;br /&gt;
===== Second way: rely on the &amp;lt;code&amp;gt;:formatFunction&amp;lt;/code&amp;gt; option provided by &amp;lt;code&amp;gt;dojo.string.substitute&amp;lt;/code&amp;gt; =====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, ggg.game.php, ggg_ggg.tpl, ggg.css&lt;br /&gt;
&lt;br /&gt;
The above method will work in most of the cases, but if you use dotted keys such as &amp;lt;code&amp;gt;${card.name}&amp;lt;/code&amp;gt; (which is supported by the framework, for private state args), the key won&#039;t be substituted because the &amp;lt;code&amp;gt;key in arg&amp;lt;/code&amp;gt; test will fail. If so you need to rely either on this way, or the one after.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;WARNING:&#039;&#039;&#039; using this method on an already advanced project will require you to go through all your notifications to change keys !&lt;br /&gt;
&lt;br /&gt;
Under the hood, the &#039;&#039;&#039;this.format_string_recursive()&#039;&#039;&#039; function calls the dojo.string.substitute which substitutes &amp;lt;code&amp;gt;${keys}&amp;lt;/code&amp;gt; with the value provided. If you take a look at the [https://dojotoolkit.org/reference-guide/1.7/dojo/string.html#substitute documentation] and [https://github.com/dojo/dojo/blob/c3ceb017cfa25b703f5662dc83d1c8aae9bc5d81/string.js#L163 source code] you can notice that the key can be suffixed with a colon (&amp;lt;code&amp;gt;:&amp;lt;/code&amp;gt;) followed by a function name. This will allow you to specify directly in the substitution string which keys need HTML injection.&lt;br /&gt;
&lt;br /&gt;
First of all, you need to define your formatting function in the ggg.js file:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[[ggg.js]]&lt;br /&gt;
        getTokenDiv : function(value, key) {&lt;br /&gt;
            //This is only an example implementation, you need to write your own.&lt;br /&gt;
            //The method should return HTML code&lt;br /&gt;
            switch (key) {&lt;br /&gt;
                case &#039;html_injected_argument1&#039;:&lt;br /&gt;
                    return this.format_block(&#039;jstpl_HTMLLogElement1&#039;,{value: value});&lt;br /&gt;
                case &#039;html_injected_argument2&#039;:&lt;br /&gt;
                    return this.format_block(&#039;jstpl_HTMLLogElement2&#039;,{value: value});&lt;br /&gt;
                ...&lt;br /&gt;
            }&lt;br /&gt;
       }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Obviously you need to define the appropriate templates in the ggg_ggg.tpl file:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[[ggg_ggg.tpl]]&lt;br /&gt;
let jstpl_HTMLLogElement1 = &#039;&amp;lt;div class=&amp;quot;log-element log-element-1-${value}&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
let jstpl_HTMLLogElement2 = &#039;&amp;lt;div class=&amp;quot;log-element log-element-2-${value}&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
And the appropriate classes in ggg.css.&lt;br /&gt;
&lt;br /&gt;
Then you need to add the &amp;lt;code&amp;gt;dojo/aspect&amp;lt;/code&amp;gt; module at the top of the ggg.js file:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[ggg.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 define([&lt;br /&gt;
     &amp;quot;dojo&amp;quot;, &amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&amp;quot;dojo/aspect&amp;quot;,&amp;lt;/span&amp;gt;                 //MUST BE IN THIRD POSITION&#039;&#039;&#039; (see [[#Including your own JavaScript module (II)|below]])&lt;br /&gt;
     &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
 ], function (dojo, declare, &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&#039;&#039;&#039;aspect&#039;&#039;&#039;&amp;lt;/span&amp;gt;) {&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
And you also need to add the following code in your &amp;lt;code&amp;gt;contructor&amp;lt;/code&amp;gt; method in the ggg.js:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[ggg.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
         constructor: function(){&lt;br /&gt;
             console.log(&#039;progressevolutiontechnologyswh constructor&#039;);&lt;br /&gt;
               &lt;br /&gt;
             // Here, you can init the global variables of your user interface&lt;br /&gt;
             // Example:&lt;br /&gt;
             // this.myGlobalValue = 0;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&#039;&#039;&#039;let gameObject = this;&#039;&#039;&#039;            //Needed as the this object in aspect.before will not refer to the game object in which the formatting function resides&lt;br /&gt;
             &#039;&#039;&#039;aspect.before(dojo.string, &amp;quot;substitute&amp;quot;, function(template, map, transform) {&#039;&#039;&#039;&lt;br /&gt;
                 &#039;&#039;&#039;return [template, map, transform, gameObject];&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now you&#039;re all set to inject HTML in your logs.&lt;br /&gt;
&lt;br /&gt;
===== Third way: rely on the &amp;lt;code&amp;gt;transform&amp;lt;/code&amp;gt; argument of &amp;lt;code&amp;gt;dojo.string.substitute&amp;lt;/code&amp;gt; =====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, ggg.game.php, ggg_ggg.tpl, ggg.css&lt;br /&gt;
&lt;br /&gt;
This method is also relying on the use of &amp;lt;code&amp;gt;dojo.string.substitute&amp;lt;/code&amp;gt; by the framework, and will use the &amp;lt;code&amp;gt;transform&amp;lt;/code&amp;gt; argument, which, accordting to [https://github.com/dojo/dojo/blob/c3ceb017cfa25b703f5662dc83d1c8aae9bc5d81/string.js#L163 source code] and [https://dojotoolkit.org/reference-guide/1.7/dojo/string.html#substitute documentation] will be run on all the messages going through dojo.string.substitute.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;WARNING:&#039;&#039;&#039; As this method will be applied to all strings that go through dojo.string.substitute. As such you must take extra care not to substitute keys that may be used by the framework (i.e. ${id}). In order to do so, a good practise would be to prefix all keys that need substitution with a trigram of the game name.&lt;br /&gt;
&lt;br /&gt;
Since all the keys will be fed to the tranform function, by default, it must return the value, substituted or not per your needs. You can define the function like this in the ggg.js file:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[ggg.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
         getTokenDiv : function(value, key) {&lt;br /&gt;
             //This is only an example implementation, you need to write your own.&lt;br /&gt;
             //The method should return HTML code&lt;br /&gt;
             switch (key) {&lt;br /&gt;
                 case &#039;html_injected_argument1&#039;:&lt;br /&gt;
                     return this.format_block(&#039;jstpl_HTMLLogElement1&#039;,{value: value});&lt;br /&gt;
                 case &#039;html_injected_argument2&#039;:&lt;br /&gt;
                     return this.format_block(&#039;jstpl_HTMLLogElement2&#039;,{value: value});&lt;br /&gt;
                 ...&lt;br /&gt;
                 &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&#039;&#039;&#039;default:&#039;&#039;&#039;&lt;br /&gt;
                     &#039;&#039;&#039;return value;&#039;&#039;&#039;&amp;lt;/span&amp;gt;                  &#039;&#039;&#039;//Needed otherwise regular strings won&#039;t appear since since the value isn&#039;t returned by the function&#039;&#039;&#039;&lt;br /&gt;
             }&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
The templates must be defined in the ggg_ggg.tpl file and the corresponding CSS classes in the ggg.css file.&lt;br /&gt;
&lt;br /&gt;
You need to add the following code at the beginning of the ggg.js file:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[ggg.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 define([&lt;br /&gt;
     &amp;quot;dojo&amp;quot;, &amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&amp;quot;dojo/aspect&amp;quot;,&amp;lt;/span&amp;gt;                 //MUST BE IN THIRD POSITION&#039;&#039;&#039; (see [[#Including your own JavaScript module (II)|below]])&lt;br /&gt;
     &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
 ], function (dojo, declare, &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&#039;&#039;&#039;aspect&#039;&#039;&#039;&amp;lt;/span&amp;gt;) {&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
And the following code to the &amp;lt;code&amp;gt;constructor&amp;lt;/code&amp;gt; method in ggg.js:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[[ggg.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
         constructor: function(){&lt;br /&gt;
             console.log(&#039;progressevolutiontechnologyswh constructor&#039;);&lt;br /&gt;
               &lt;br /&gt;
             // Here, you can init the global variables of your user interface&lt;br /&gt;
             // Example:&lt;br /&gt;
             // this.myGlobalValue = 0;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;&#039;&#039;&#039;let transformFunction = dojo.hitch(this, &amp;quot;getTokenDiv&amp;quot;);&#039;&#039;&#039;            //Needed as the this object in aspect.before will not refer to the game object in which the formatting function resides&lt;br /&gt;
             &#039;&#039;&#039;aspect.before(dojo.string, &amp;quot;substitute&amp;quot;, function(template, map, transform) {&#039;&#039;&#039;&lt;br /&gt;
                 &#039;&#039;&#039;if (undefined === transform) {&#039;&#039;&#039;                                   //Check for a transform function presence, just in case&lt;br /&gt;
                     &#039;&#039;&#039;return [template, map, transform];&#039;&#039;&#039;&lt;br /&gt;
                 &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Processing logs on re-loading ====&lt;br /&gt;
&lt;br /&gt;
You rarely need to process logs when reloading, but if you want to do something fancy you may have to do it after logs are loaded. &lt;br /&gt;
Logs are loaded asyncronously so you have to listen for logs to be fully loaded.&lt;br /&gt;
Unfortunately there is no direct way of doing it so this is the hack.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Hack alert&#039;&#039;&#039; - this extends undocumented function and may be broken when framework is updated&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
			/*&lt;br /&gt;
  			* [Undocumented] Override BGA framework functions to call onLoadingLogsComplete when loading is done&lt;br /&gt;
                        @Override&lt;br /&gt;
   			*/&lt;br /&gt;
			setLoader: function(image_progress, logs_progress) {&lt;br /&gt;
				this.inherited(arguments); // required, this is &amp;quot;super()&amp;quot; call, do not remove&lt;br /&gt;
				//console.log(&amp;quot;loader&amp;quot;, image_progress, logs_progress)&lt;br /&gt;
				if (!this.isLoadingLogsComplete &amp;amp;&amp;amp; logs_progress &amp;gt;= 100) {&lt;br /&gt;
					this.isLoadingLogsComplete = true; // this is to prevent from calling this more then once&lt;br /&gt;
					this.onLoadingLogsComplete();&lt;br /&gt;
				}&lt;br /&gt;
			},&lt;br /&gt;
&lt;br /&gt;
			onLoadingLogsComplete: function() {&lt;br /&gt;
				console.log(&#039;Loading logs complete&#039;);&lt;br /&gt;
				// do something here&lt;br /&gt;
			},&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Player Panel ===&lt;br /&gt;
&lt;br /&gt;
==== Inserting non-player panel ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, ggg_ggg.tpl&lt;br /&gt;
&lt;br /&gt;
If you want to insert non-player panel on the right side (for example to hold extra preferences, zooming controls, etc)&lt;br /&gt;
&lt;br /&gt;
this can go pretty much anywhere in template it will be moved later&lt;br /&gt;
&lt;br /&gt;
ggg_ggg.tpl:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	&amp;lt;div class=&#039;player_board_config&#039; id=&amp;quot;player_board_config&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;!-- here is whatever you want, buttons just example --&amp;gt;&lt;br /&gt;
		&amp;lt;button id=&amp;quot;zoom-out&amp;quot; class=&amp;quot; fa fa-search-minus fa-2x config-control&amp;quot;&amp;gt;&amp;lt;/button&amp;gt;&lt;br /&gt;
		&amp;lt;button id=&amp;quot;zoom-in&amp;quot; class=&amp;quot; fa fa-search-plus fa-2x config-control&amp;quot;&amp;gt;&amp;lt;/button&amp;gt;&lt;br /&gt;
		&amp;lt;button id=&amp;quot;show-settings&amp;quot; class=&amp;quot;fa fa-cog fa-2x config-control &amp;quot;&amp;gt;&amp;lt;/button&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
some hackery required in js&lt;br /&gt;
&lt;br /&gt;
ggg.js:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* @Override */&lt;br /&gt;
	updatePlayerOrdering() {&lt;br /&gt;
		this.inherited(arguments);&lt;br /&gt;
		dojo.place(&#039;player_board_config&#039;, &#039;player_boards&#039;, &#039;first&#039;);&lt;br /&gt;
	},&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Images and Icons ===&lt;br /&gt;
&lt;br /&gt;
==== Accessing images from js ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
     // your game resources&lt;br /&gt;
     &lt;br /&gt;
     var my_img = &#039;&amp;lt;img src=&amp;quot;&#039;+g_gamethemeurl+&#039;img/cards.jpg&amp;quot;/&amp;gt;&#039;;&lt;br /&gt;
     &lt;br /&gt;
     // shared resources&lt;br /&gt;
     var my_help_img = &amp;quot;&amp;lt;img class=&#039;imgtext&#039; src=&#039;&amp;quot; + g_themeurl + &amp;quot;img/layout/help_click.png&#039; alt=&#039;action&#039; /&amp;gt; &amp;lt;span class=&#039;tooltiptext&#039;&amp;gt;&amp;quot; +&lt;br /&gt;
                    text + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== High-Definition Graphics ====&lt;br /&gt;
&lt;br /&gt;
Some users will have screens which can display text and images at a greater resolution than the usual 72 dpi, e.g. the &amp;quot;Retina&amp;quot; screens on the 5k iMac, all iPads, and high-DPI screens on laptops from many manufacturers. If you can get art assets at this size, they will make your game look extra beautiful. You &#039;&#039;could&#039;&#039; just use large graphics and scale them down, but that would increase the download time and bandwidth for users who can&#039;t display them. Instead, a good way is to prepare a separate graphics file at exactly twice the size you would use otherwise, and add &amp;quot;@2x&amp;quot; at the end of the filename, e.g. if pieces.png is 240x320, then pieces@2x.png is 480x640.&lt;br /&gt;
&lt;br /&gt;
There are two changes required in order to use the separate graphics files. First in your css, where you use a file, add a media query which overrides the original definition and uses the bigger version on devices which can display them. Ensuring that the &amp;quot;background-size&amp;quot; attribute is set means that the size of the displayed object doesn&#039;t change, but only is drawn at the improved dot pitch.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.piece {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    background-image: url(&#039;img/pieces.png&#039;);&lt;br /&gt;
    background-size:240px 320px;&lt;br /&gt;
    z-index: 10;&lt;br /&gt;
}&lt;br /&gt;
@media (-webkit-min-device-pixel-ratio: 2), (min-device-pixel-ratio: 2), (min-resolution: 192dpi)&lt;br /&gt;
{&lt;br /&gt;
    .piece {&lt;br /&gt;
        background-image: url(&#039;img/pieces@2x.png&#039;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Secondly, in your setup function in javascript, you must ensure than only the appropriate one version of the file gets pre-loaded (otherwise you more than waste the bandwidth saved by maintaining the standard-resolution file). Note that the media query is the same in both cases:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
            var isRetina = &amp;quot;(-webkit-min-device-pixel-ratio: 2), (min-device-pixel-ratio: 2), (min-resolution: 192dpi)&amp;quot;;&lt;br /&gt;
            if (window.matchMedia(isRetina).matches)&lt;br /&gt;
            {&lt;br /&gt;
                this.dontPreloadImage( &#039;pieces.png&#039; );&lt;br /&gt;
                this.dontPreloadImage( &#039;board.jpg&#039; );&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                this.dontPreloadImage( &#039;pieces@2x.png&#039; );&lt;br /&gt;
                this.dontPreloadImage( &#039;board@2x.jpg&#039; );&lt;br /&gt;
            }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using CSS to create different colors of game pieces if you have only white piece ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
background-color: #${color}; &lt;br /&gt;
background-blend-mode: multiply;&lt;br /&gt;
background-image: url( &#039;img/mypiece.png&#039;);&lt;br /&gt;
mask: url(&#039;img/mypiece.png&#039;);&lt;br /&gt;
-webkit-mask: url(&#039;img/mypiece.png&#039;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where ${color} - is color you want&lt;br /&gt;
&lt;br /&gt;
Note: piece has to be white (shades of gray). Sprite can be used too, just add add blackground-position as usuall.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Other Fluff ===&lt;br /&gt;
&lt;br /&gt;
==== Use thematic fonts ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.css&lt;br /&gt;
&lt;br /&gt;
Sometime game elements use specific fonts of text, if you want to match it up you can load some specific font (IMPORTANT: from some &#039;&#039;&#039;free font&#039;&#039;&#039; source. See notes below).&lt;br /&gt;
&lt;br /&gt;
[[File:Dragonline_font.png]]&lt;br /&gt;
&lt;br /&gt;
.css&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* latin-ext */&lt;br /&gt;
@font-face {&lt;br /&gt;
  font-family: &#039;Qwigley&#039;;&lt;br /&gt;
  font-style: normal;&lt;br /&gt;
  font-weight: 400;&lt;br /&gt;
  src: local(&#039;Qwigley&#039;), local(&#039;Qwigley-Regular&#039;), url(https://fonts.gstatic.com/s/qwigley/v6/2Dy1Unur1HJoklbsg4iPJ_Y6323mHUZFJMgTvxaG2iE.woff2) format(&#039;woff2&#039;);&lt;br /&gt;
  unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;&lt;br /&gt;
}&lt;br /&gt;
/* latin */&lt;br /&gt;
@font-face {&lt;br /&gt;
  font-family: &#039;Qwigley&#039;;&lt;br /&gt;
  font-style: normal;&lt;br /&gt;
  font-weight: normal;&lt;br /&gt;
  src: local(&#039;Qwigley&#039;), local(&#039;Qwigley-Regular&#039;), url(https://fonts.gstatic.com/s/qwigley/v6/gThgNuQB0o5ITpgpLi4Zpw.woff2) format(&#039;woff2&#039;);&lt;br /&gt;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;&lt;br /&gt;
}&lt;br /&gt;
@font-face {&lt;br /&gt;
  font-family: &#039;Qwigley&#039;;&lt;br /&gt;
  font-style: normal;&lt;br /&gt;
  font-weight: normal;&lt;br /&gt;
  src: local(&#039;Qwigley&#039;), local(&#039;Qwigley-Regular&#039;), url(http://ff.static.1001fonts.net/q/w/qwigley.regular.ttf) format(&#039;ttf&#039;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.zone_title {&lt;br /&gt;
	display: inline-block;&lt;br /&gt;
	position: absolute;&lt;br /&gt;
	font: italic 32px/32px &amp;quot;Qwigley&amp;quot;, cursive;	   &lt;br /&gt;
	height: 32px;&lt;br /&gt;
	width: auto;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NB:&#039;&#039;&#039; if you need to include a font that&#039;s not available online, an extra action will be needed from an admin. Please include the font file(s) in your img directory, and mention it to admins when requesting your game to be moved to alpha. &#039;&#039;&#039;Please remember that the font has to be free, and include a .txt with all appropriate license information about the font.&#039;&#039;&#039;&lt;br /&gt;
You can look for free fonts (for example) on https://fonts.google.com or https://www.fontsquirrel.com/)&lt;br /&gt;
&lt;br /&gt;
=== Use player color in template ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg_ggg.tpl, ggg.view.php&lt;br /&gt;
&lt;br /&gt;
.view.php:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    function build_page($viewArgs) {&lt;br /&gt;
        // Get players &amp;amp; players number&lt;br /&gt;
        $players = $this-&amp;gt;game-&amp;gt;loadPlayersBasicInfos();&lt;br /&gt;
        $players_nbr = count($players);&lt;br /&gt;
        /**&lt;br /&gt;
         * ********* Place your code below: ***********&lt;br /&gt;
         */&lt;br /&gt;
        &lt;br /&gt;
        // Set PCOLOR to the current player color hex&lt;br /&gt;
        global $g_user;&lt;br /&gt;
        $cplayer = $g_user-&amp;gt;get_id();&lt;br /&gt;
        if (array_key_exists($cplayer, $players)) { // may be not set if spectator&lt;br /&gt;
            $player_color = $players [$cplayer] [&#039;player_color&#039;];&lt;br /&gt;
        } else {&lt;br /&gt;
            $player_color = &#039;ffffff&#039;; // spectator&lt;br /&gt;
        }&lt;br /&gt;
        $this-&amp;gt;tpl [&#039;PCOLOR&#039;] = $player_color;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Scale to fit for big boards ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg_ggg.tpl, ggg.js&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Lets say you have huge game board, and lets say you want it to be 1400px wide. Besides the board there will be side bar which is 240 and trim. &lt;br /&gt;
My display is 1920 wide so it fits, but there is big chance other people won&#039;t have that width. What do you do?&lt;br /&gt;
&lt;br /&gt;
You have to decide:&lt;br /&gt;
* If board does not fit you want scale whole thing down, the best way is probably use viewport (see https://en.doc.boardgamearena.com/Your_game_mobile_version)&lt;br /&gt;
* You can leave the board as is and make sure it is scrollable horizonatally&lt;br /&gt;
* You add custom scale just for the board (can add user controls  - and hook to transform: scale())&lt;br /&gt;
&lt;br /&gt;
I tried to auto-scale but this just does work, too many variables - browser zoom, 3d mode, viewport, custom bga scaling, devicePixelRatio - all create some impossible coctail of zooming...&lt;br /&gt;
Here is scaling functing for custom user scaling&lt;br /&gt;
&lt;br /&gt;
ggg_ggg.tpl:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   &amp;lt;div id=&amp;quot;thething&amp;quot; class=&amp;quot;thething&amp;quot;&amp;gt;&lt;br /&gt;
            ... everything else you declare ...&lt;br /&gt;
   &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ggg.js:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    onZoomPlus: function() {&lt;br /&gt;
       this.my_zoom+=0.1;&lt;br /&gt;
       this.zoommy(&#039;thething&#039;,this.my_zoom);&lt;br /&gt;
    },&lt;br /&gt;
&lt;br /&gt;
    zoommy: function(node, zoom) {&lt;br /&gt;
                node=$(node);&lt;br /&gt;
		var width = 100 / zoom;&lt;br /&gt;
		node.style.transformOrigin = &amp;quot;0 0&amp;quot;;&lt;br /&gt;
		node.style.transform = &amp;quot;scale(&amp;quot; + zoom + &amp;quot;)&amp;quot;;&lt;br /&gt;
		node.style.width = width + &amp;quot;%&amp;quot;;&lt;br /&gt;
    },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Dynamic tooltips ===&lt;br /&gt;
&lt;br /&gt;
If you really need a dynamic tooltip you can use this technique. (Only use it if the static tooltips provided by the BGA framework are not sufficient.)&lt;br /&gt;
&lt;br /&gt;
            new dijit.Tooltip({&lt;br /&gt;
                connectId: [&amp;quot;divItemId&amp;quot;],&lt;br /&gt;
                getContent: function(matchedNode){&lt;br /&gt;
                    return &amp;quot;... calculated ...&amp;quot;; &lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is an out-of-the-box djit.Tooltip. It has a &#039;&#039;getContent&#039;&#039; method which is called dynamically.&lt;br /&gt;
&lt;br /&gt;
The string function return becomes the innerHTML of the tooltip, so it can be anything. In this example matchedNode is a dojo node representing dom object with id of &amp;quot;divItemId&amp;quot; but there are more parameters which I am not posting here which allows more sophisticated subnode queries (i.e. you can attach tooltip to all nodes with class or whatever).&lt;br /&gt;
&lt;br /&gt;
[https://dojotoolkit.org/reference-guide/1.10/dijit/Tooltip.html dijit.Tooltip]&lt;br /&gt;
&lt;br /&gt;
It&#039;s not part of the BGA API so use at your own risk.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Rendering text with players color and proper background ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
This example actually writes &amp;quot;You&amp;quot; but you can replace this with player name as easily, drop translating function in this case&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        /* Implementation of proper colored You with background in case of white or light colors  */&lt;br /&gt;
 &lt;br /&gt;
        divYou : function() {&lt;br /&gt;
            var color = this.gamedatas.players[this.player_id].color;&lt;br /&gt;
            var color_bg = &amp;quot;&amp;quot;;&lt;br /&gt;
            if (this.gamedatas.players[this.player_id] &amp;amp;&amp;amp; this.gamedatas.players[this.player_id].color_back) {&lt;br /&gt;
                color_bg = &amp;quot;background-color:#&amp;quot; + this.gamedatas.players[this.player_id].color_back + &amp;quot;;&amp;quot;;&lt;br /&gt;
            }&lt;br /&gt;
            var you = &amp;quot;&amp;lt;span style=\&amp;quot;font-weight:bold;color:#&amp;quot; + color + &amp;quot;;&amp;quot; + color_bg + &amp;quot;\&amp;quot;&amp;gt;&amp;quot; + __(&amp;quot;lang_mainsite&amp;quot;, &amp;quot;You&amp;quot;) + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
            return you;&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Cool realistic shadow effect with CSS ===&lt;br /&gt;
&lt;br /&gt;
==== Rectangles and circles ====&lt;br /&gt;
&lt;br /&gt;
It is often nice to have a drop shadow around tiles and tokens, to separate them from the table visually. It is very easy to add a shadow to rectangular elements, just add this to your css:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.xxx-tile {&lt;br /&gt;
    box-shadow: 3px 3px 3px #000000a0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
box-shadow obeys &#039;&#039;&#039;border-radius&#039;&#039;&#039; of the element, so it will look good for rounded rectangles, and hence also circles (if border-radius is set appropriately).&lt;br /&gt;
&lt;br /&gt;
box-shadow also supports various other parameters and can be used to achieve effects such as glowing, borders, inner shadows etc. If you need to animate a box-shadow, you may be able to get better performance (avoiding redraws) if you attach the shadow to another element (possibly an ::after pseudo-element) and change only the &#039;&#039;&#039;opacity&#039;&#039;&#039; of that element.&lt;br /&gt;
&lt;br /&gt;
==== Irregular Shapes ====&lt;br /&gt;
&lt;br /&gt;
If you wish to make a shadow effect for game pieces that are not a rectangle, but your game pieces are drawn from rectangles in a PNG image, you can apply the shadow to the piece using any art package and save it inside the image. This usually will yield the best performance. Remember to account for the size of the shadow when you lay out images in the sprite sheet.&lt;br /&gt;
&lt;br /&gt;
However that sometimes will not be an option, for example if the image needs to be rotated while the shadow remains offset in the same direction. In this case, one option is to not use box-shadow but use filter, which is supported by recent major browsers.  This way, you can use the alpha channel of your element to drop a shadow.  This even work for transparent backgrounds, so that if you are using the &amp;quot;CSS-sprite&amp;quot; method, it will work!&lt;br /&gt;
&lt;br /&gt;
For instance:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.xxx-token {&lt;br /&gt;
    filter: drop-shadow(0px 0px 1px #000000);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beware that some browsers still do not always draw drop-shadow correctly. In particular, Safari frequently leaves bits of shadow behind when objects move around the screen. In Chrome, shadows sometimes flicker badly if another element is animating close by. Some of these correctness issues can be solved by adding &#039;&#039;&#039;isolation: isolate; will-change: filter;&#039;&#039;&#039; to affected elements, but this significantly affects redraw performance.&lt;br /&gt;
&lt;br /&gt;
Beware of performance issues - particularly on Safari (MacOS, iPhone and iPad). Keep in mind that drop-shadow are very GPU intensive. This becomes noticeable once you have about 40 components with drop-shadow filter. If that is your case, you can quite easily implement a user preference to disable shadows for users on slower machines:&lt;br /&gt;
&lt;br /&gt;
gameoptions.inc.php&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
100 =&amp;gt; array(&lt;br /&gt;
			&#039;name&#039; =&amp;gt; totranslate(&#039;Shadows&#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;Enabled&#039; ), &#039;cssPref&#039; =&amp;gt; &#039;&#039; ),&lt;br /&gt;
					2 =&amp;gt; array( &#039;name&#039; =&amp;gt; totranslate( &#039;Disabled&#039; ), &#039;cssPref&#039; =&amp;gt; &#039;no-shadow&#039; )&lt;br /&gt;
			)&lt;br /&gt;
	),&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[game].css&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.no-shadow * {&lt;br /&gt;
	filter: none !important; &lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Shadows with clip-path ====&lt;br /&gt;
&lt;br /&gt;
For some reason, a shadow will not work together with clip-path on one element. To use both clip-path (when for example using .svg to cut out cardboard components from your .jpg spritesheet) and drop-shadow, you need to wrap the element into another one, and apply drop-shadow to the outer one, and clip-path to the inner one.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;div class=&#039;my-token-wrap&#039;&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&#039;my-token&#039;&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;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.my-token-wrap {&lt;br /&gt;
    filter: drop-shadow(0px 0px 1px #000000);&lt;br /&gt;
}&lt;br /&gt;
.my-token-wrap .my-token {&lt;br /&gt;
    clip-path: url(#my-token-path);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Using the CSS classes from the state machine ===&lt;br /&gt;
&lt;br /&gt;
If you need to hide or show stuff depending on the state of your game, you can of course use javascript, but CSS is hand enough for that.  The #overall-content element does change class depending on the game state.  For instance, if you are in state &#039;&#039;playerTurn&#039;&#039;, it will have the class &#039;&#039;gamestate_playerTurn&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
So now, if you want to show the discard pile only during player turns, you may use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#discard_pile { display: none }&lt;br /&gt;
.gamestate_playerTurn #discard_pile { display: block }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This can be used if you want to change sizing of elements, position, layout or visual appearance.&lt;br /&gt;
&lt;br /&gt;
== Game Model and Database design ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Database for The euro game ===&lt;br /&gt;
Lets say we have a game with workers, dice, tokens, board, resources, money and vp. Workers and dice can be placed in various zones on the board, and you can get resources, money, tokens and vp in your home zone. Also tokens can be flipped or not flipped.&lt;br /&gt;
&lt;br /&gt;
[[File:Madeira board.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now lets try to map it, we have&lt;br /&gt;
* (meeple,zone)&lt;br /&gt;
* (die, zone, sideup)&lt;br /&gt;
* (resource cube/money token/vp token,player home zone)&lt;br /&gt;
* (token, player home zone, flip state)&lt;br /&gt;
We can notice that resource and money are uncountable, and don&#039;t need to be track individually so we can replace our mapping to&lt;br /&gt;
* (resource type/money,player home zone, count)&lt;br /&gt;
And vp stored already for us in player table, so we can remove it from that list.&lt;br /&gt;
&lt;br /&gt;
Now when we get to encode it we can see that everything can be encoded as (object,zone,state) form, where object and zone is string and state is integer. The resource mapping is slightly different semantically so you can go with two table, or counting using same table with state been used as count for resources.&lt;br /&gt;
&lt;br /&gt;
So the piece mapping for non-grid based games can be in most case represented by (string: token_key, string: token_location, int: token_state), example of such database schema can be found here: [https://github.com/elaskavaia/bga-sharedcode/blob/master/dbmodel.sql dbmodel.sql] and class implementing access to it here [https://github.com/elaskavaia/bga-sharedcode/blob/master/modules/tokens.php table.game.php].&lt;br /&gt;
&lt;br /&gt;
Variant 1: Minimalistic&lt;br /&gt;
&lt;br /&gt;
 CREATE TABLE IF NOT EXISTS `token` (&lt;br /&gt;
  `token_key` varchar(32) NOT NULL,&lt;br /&gt;
  `token_location` varchar(32) NOT NULL,&lt;br /&gt;
  `token_state` int(10),&lt;br /&gt;
  PRIMARY KEY (`token_key`)&lt;br /&gt;
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+token&lt;br /&gt;
! token_key&lt;br /&gt;
! token_location&lt;br /&gt;
! token_state&lt;br /&gt;
|-&lt;br /&gt;
|meeple_red_1&lt;br /&gt;
|home_red&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
|dice_black_2&lt;br /&gt;
|board_guard&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
|dice_green_1&lt;br /&gt;
|board_action_mayor&lt;br /&gt;
|3&lt;br /&gt;
|-&lt;br /&gt;
|bread&lt;br /&gt;
|home_red&lt;br /&gt;
|5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Now how we represent resource counters such as bread?&lt;br /&gt;
Using same table from we simply add special counter token for bread and use state to indicate the count. Note to keep first column unique we have to add player identification for that counter, i.e. ff0000 is red player.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+token&lt;br /&gt;
! token_key&lt;br /&gt;
! token_location&lt;br /&gt;
! token_state&lt;br /&gt;
|-&lt;br /&gt;
|bread_ff0000&lt;br /&gt;
|tableau_ff0000&lt;br /&gt;
|5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See php module for this table here https://github.com/elaskavaia/bga-sharedcode/blob/master/modules/tokens.php&lt;br /&gt;
&lt;br /&gt;
Variant 2: Additional resource table, resource count for each player id&lt;br /&gt;
&lt;br /&gt;
 CREATE TABLE IF NOT EXISTS `resource` (&lt;br /&gt;
  `player_id` int(10) unsigned NOT NULL,&lt;br /&gt;
  `resource_key` varchar(32) NOT NULL,&lt;br /&gt;
  `resource_count` int(10) signed NOT NULL,&lt;br /&gt;
  PRIMARY KEY (`player_id`,`resource_key`)&lt;br /&gt;
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;&lt;br /&gt;
&lt;br /&gt;
 ALTER TABLE resource ADD CONSTRAINT fk_player_id FOREIGN KEY (player_id) REFERENCES player(player_id);&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+resource&lt;br /&gt;
! player_id&lt;br /&gt;
! resource_key&lt;br /&gt;
! resource_count&lt;br /&gt;
|-&lt;br /&gt;
|123456&lt;br /&gt;
|bread&lt;br /&gt;
|5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Variant 3: More normalised&lt;br /&gt;
&lt;br /&gt;
This version is similar to &amp;quot;card&amp;quot; table from hearts tutorial, you can also use exact cards database schema and Deck implementation for most purposes (even you not dealing with cards). &lt;br /&gt;
&lt;br /&gt;
 CREATE TABLE IF NOT EXISTS `token` (&lt;br /&gt;
  `token_id` int(10) unsigned NOT NULL AUTO_INCREMENT,&lt;br /&gt;
  `token_type` varchar(16) NOT NULL,&lt;br /&gt;
  `token_arg` int(11) NOT NULL,&lt;br /&gt;
  `token_location` varchar(32) NOT NULL,&lt;br /&gt;
  `token_state` int(10),&lt;br /&gt;
  PRIMARY KEY (`token_id`)&lt;br /&gt;
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+token&lt;br /&gt;
! token_id&lt;br /&gt;
! token_type&lt;br /&gt;
! token_arg&lt;br /&gt;
! token_location&lt;br /&gt;
! token_state&lt;br /&gt;
|-&lt;br /&gt;
|22&lt;br /&gt;
|meeple&lt;br /&gt;
|123456&lt;br /&gt;
|home_123456&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
|23&lt;br /&gt;
|dice&lt;br /&gt;
|2&lt;br /&gt;
|board_guard&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
|26&lt;br /&gt;
|dice&lt;br /&gt;
|1&lt;br /&gt;
|board_action_mayor&lt;br /&gt;
|3&lt;br /&gt;
|-&lt;br /&gt;
|49&lt;br /&gt;
|bread&lt;br /&gt;
|0&lt;br /&gt;
|home_123456&lt;br /&gt;
|5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Advantages of this would be is a bit more straightforward to do some queries in db, disadvantage its hard to read (as you can compare with previous example, you&lt;br /&gt;
cannot just look at say, ah I know what it means). Another questionable advantage is it allows you to do id randomisation, so it hard to do crafted queries to &lt;br /&gt;
cheat, the down side of that you cannot understand it either, and handcraft db states for debugging or testing.&lt;br /&gt;
&lt;br /&gt;
=== Database for The card game ===&lt;br /&gt;
&lt;br /&gt;
Lets say you have a standard card game, player have hidden cards in hand, you can draw card from draw deck, play card on tableau and discard to discard pile.&lt;br /&gt;
We have to design database for such game.&lt;br /&gt;
&lt;br /&gt;
In real word to &amp;quot;save&amp;quot; the game we take a picture a play area, save cards from it, then put away draw deck, discard and hand of each player separately and mark it, also we will record current scoring (if any) and who&#039;s turn was it.&lt;br /&gt;
&lt;br /&gt;
* Framework handles state machine transition, so you don&#039;t have to worry about database design for that (i.e. who&#039;s turn it is, what phase of the game we are at, you still have to design it but part of state machine step)&lt;br /&gt;
* Also framework supports basic player information, color, order around the table, basic scoring, etc, so you don&#039;t have to worry about it either&lt;br /&gt;
* The only thing you need in our database is state of the &amp;quot;board&amp;quot;, which is &amp;quot;where each pieces is, and in what state&amp;quot;, or (position,rotation) pair.&lt;br /&gt;
&lt;br /&gt;
Lets see what we have for that:&lt;br /&gt;
* The card state is very simple, its usually &amp;quot;face up/face down&amp;quot;, &amp;quot;tapped/untapped&amp;quot;, &amp;quot;right side up/up side down&amp;quot;&lt;br /&gt;
* As position go we never need real coordinates x,y,z. We need to know what &amp;quot;zone&amp;quot; card was, and depending on the zone it may sometimes need an extra &amp;quot;z&amp;quot; or &amp;quot;x&amp;quot; as card order. The zone position usually static or irrelevant.&lt;br /&gt;
* So our model is: we have cards, which have some attributes, at any given point in time they belong to a &amp;quot;zone&amp;quot;, and can also have order and state&lt;br /&gt;
* Now for mapping we should consider what information changes and what information is static, later is always candidate for material file&lt;br /&gt;
* For dynamic information we should try to reduce amount of fields we need&lt;br /&gt;
**  we need at least a field for card, so its one&lt;br /&gt;
**  we need to know what zone cards belong to, its 2&lt;br /&gt;
**  and we have possibly few other fields, if you look closely at you game you may find out that most of the zone only need one attribute at a time, i.e. draw pile always have cards face down, hand always face up, also for hand and discard order does not matter at all (but for draw it does matter). So in majority of cases we can get away with one single extra integer field representing state or order&lt;br /&gt;
* In real database both card and zone will be integers as primary keys referring to additional tables, but in our case its total overkill, so they can be strings as easily&lt;br /&gt;
&lt;br /&gt;
Variant 1: Minimalistic&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE TABLE IF NOT EXISTS `card` (&lt;br /&gt;
  `card_key` varchar(32) unsigned NOT NULL,&lt;br /&gt;
  `card_location` varchar(32) NOT NULL,&lt;br /&gt;
  `card_state` int(11) NOT NULL,&lt;br /&gt;
  PRIMARY KEY (`card_id`)&lt;br /&gt;
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Variant 2: More normalised&lt;br /&gt;
&lt;br /&gt;
This version supported by Deck php class, so unless you want to rewrite db access layer go with this one&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE TABLE IF NOT EXISTS `card` (&lt;br /&gt;
  `card_id` int(10) unsigned NOT NULL AUTO_INCREMENT,&lt;br /&gt;
  `card_type` varchar(16) NOT NULL,&lt;br /&gt;
  `card_type_arg` int(11) NOT NULL,&lt;br /&gt;
  `card_location` varchar(16) NOT NULL,&lt;br /&gt;
  `card_location_arg` int(11) NOT NULL,&lt;br /&gt;
  PRIMARY KEY (`card_id`)&lt;br /&gt;
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: if you using this schema, some zones/locations have special semantic. The &#039;hand&#039; location is actually multiple locations - one per player, but player id is encoded as card_location_arg. If &#039;hand&#039; in your game is ordered, visible or can have some other card states, you cannot use hand location (replacement is hand_&amp;lt;player_id&amp;gt; or hand_&amp;lt;color_id&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
== Code Organization ==&lt;br /&gt;
&lt;br /&gt;
=== Including your own JavaScript module ===&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, modules/ggg_other.js&lt;br /&gt;
&lt;br /&gt;
* Create ggg_other.js in modules/ folder and sync&lt;br /&gt;
* Modify ggg.js to include it&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  define([ &amp;quot;dojo&amp;quot;, &amp;quot;dojo/_base/declare&amp;quot;, &amp;quot;ebg/core/gamegui&amp;quot;, &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
    // load my own module!!!&lt;br /&gt;
    g_gamethemeurl + &amp;quot;modules/ggg_other.js&amp;quot; ], function(dojo,&lt;br /&gt;
        declare) {&lt;br /&gt;
&lt;br /&gt;
=== Including your own JavaScript module (II) ===&lt;br /&gt;
&lt;br /&gt;
* Create ggg_other.js in modules/ folder and sync&lt;br /&gt;
&lt;br /&gt;
  define([], function () {&lt;br /&gt;
    return &amp;quot;value&amp;quot;;&lt;br /&gt;
  });&lt;br /&gt;
&lt;br /&gt;
* Modify ggg.js to include it&lt;br /&gt;
&lt;br /&gt;
  define([ &lt;br /&gt;
    &amp;quot;dojo&amp;quot;, &lt;br /&gt;
    &amp;quot;dojo/_base/declare&amp;quot;, &lt;br /&gt;
    &amp;quot;bgagame/modules/ggg_other&amp;quot;, &lt;br /&gt;
    &amp;quot;ebg/core/gamegui&amp;quot;, &lt;br /&gt;
    &amp;quot;ebg/counter&amp;quot;&lt;br /&gt;
  ], function(dojo, declare, other) {&lt;br /&gt;
  &lt;br /&gt;
  });&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
This is maybe a little bit more the idea of the AMD Loader than the first option, although the first option should work as well.&lt;br /&gt;
&lt;br /&gt;
A little explanation to this:&lt;br /&gt;
The define function loads all the modules listed in the array and calls the following function with these loaded modules as parameters.&lt;br /&gt;
By putting your module at the third position in the array it is passed as the third parameter to the function. Be aware that the modules are resolved by position only, not by name. So you can load the module &#039;&#039;&#039;ggg_other&#039;&#039;&#039; and pass it as a parameter with the name &#039;&#039;&#039;other&#039;&#039;&#039;. &#039;&#039;&#039;gamegui&#039;&#039;&#039; and &#039;&#039;&#039;counter&#039;&#039;&#039; are passed in as well, but when the parameters are not defined they are just skipped. Because these modules put their content into the global scope it does not matter and you can use them from there.&lt;br /&gt;
&lt;br /&gt;
In the example above the string &amp;quot;value&amp;quot; is passed for the parameter &#039;&#039;&#039;other&#039;&#039;&#039;, but the function in your module can return whatever you want. It can be an object, an array, something you declared with dojo.declare, you can return even functions. &lt;br /&gt;
Your module can load other modules. Just put them in the array at the beginning and pass them as parameters to your function.&lt;br /&gt;
The advantage of passing the values as parameter is that you do not need to put these values in the global scope, so they can&#039;t be collisions with values defined in other scripts or the BGA Framework.&lt;br /&gt;
&lt;br /&gt;
The dojo toolkit provides good documentation to all of its components, the complete documentation for the AMD-Loader is here:&lt;br /&gt;
https://dojotoolkit.org/documentation/tutorials/1.10/modules/index.html It should be still correct, even as it seems to be only for version 1.10&lt;br /&gt;
&lt;br /&gt;
=== Including your own PHP module ===&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.game.php, modules/ggg_other.php&lt;br /&gt;
&lt;br /&gt;
* Create ggg_other.php in modules/ folder and sync&lt;br /&gt;
* Modify ggg.game.php to include it&lt;br /&gt;
&lt;br /&gt;
 require_once (&#039;modules/ggg_other.php&#039;);&lt;br /&gt;
&lt;br /&gt;
=== Creating a test class to run PHP locally ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.game.php, stubs&lt;br /&gt;
For this you need stubs of other method you can use this for example&lt;br /&gt;
https://github.com/elaskavaia/bga-sharedcode/raw/master/misc/module/table/table.game.php&lt;br /&gt;
&lt;br /&gt;
Create another php files, i.e ggg_test.php&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
define(&amp;quot;APP_GAMEMODULE_PATH&amp;quot;, &amp;quot;misc/&amp;quot;); // include path to stubs, which defines &amp;quot;table.game.php&amp;quot; and other classes&lt;br /&gt;
require_once (&#039;eminentdomaine.game.php&#039;);&lt;br /&gt;
&lt;br /&gt;
class MyGameTest1 extends MyGame { // this is your game class defined in ggg.game.php&lt;br /&gt;
    function __construct() {&lt;br /&gt;
        parent::__construct();&lt;br /&gt;
        include &#039;../material.inc.php&#039;;// this is how this normally included, from constructor&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // override/stub methods here that access db and stuff&lt;br /&gt;
    function getGameStateValue($var) {&lt;br /&gt;
        if ($var == &#039;round&#039;)&lt;br /&gt;
            return 3;&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
$x = new MyGameTest1(); // instantiate your class&lt;br /&gt;
$p = $x-&amp;gt;getGameProgression(); // call one of the methods to test&lt;br /&gt;
if ($p != 50)&lt;br /&gt;
    echo &amp;quot;Test1: FAILED&amp;quot;;&lt;br /&gt;
else&lt;br /&gt;
    echo &amp;quot;Test1: PASSED&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Run from command line like&lt;br /&gt;
 php7 ggg_test.php&lt;br /&gt;
&lt;br /&gt;
If you do it this way - you can also use local php debugger (i.e. integrated with IDE or command line).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Avoiding code in dojo declare style ===&lt;br /&gt;
Dojo class declarations are rather bizzare and do not work with most IDEs.&lt;br /&gt;
If you want to write in plain JS with classes, you can stub all the dojo define/declare stuff&lt;br /&gt;
and hook your class into that, so the classes are outside of this mess.&lt;br /&gt;
&lt;br /&gt;
NOTE: this technique is for experienced developers, do not try it if you do not understand&lt;br /&gt;
the consequences.&lt;br /&gt;
&lt;br /&gt;
This is complete example of game .js class&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  // Testla is game name is has to be changed&lt;br /&gt;
class Testla {&lt;br /&gt;
	constructor(game) {&lt;br /&gt;
		console.log(&#039;game constructor&#039;);&lt;br /&gt;
		this.game = game;&lt;br /&gt;
		this.varfoo = new MyFoo(); // this example of class from custom module&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	setup(gamedatas) {&lt;br /&gt;
		console.log(&amp;quot;Starting game setup&amp;quot;, this.varfoo);&lt;br /&gt;
		this.gamedatas = gamedatas;&lt;br /&gt;
		this.dojo.create(&amp;quot;div&amp;quot;, { class: &#039;whiteblock&#039;, innerHTML: _(&amp;quot;hello&amp;quot;) }, &#039;thething&#039;);&lt;br /&gt;
		console.log(&amp;quot;Ending game setup&amp;quot;);&lt;br /&gt;
	};&lt;br /&gt;
	onEnteringState(stateName, args) {&lt;br /&gt;
		console.log(&#039;onEnteringState : &#039; + stateName, args);&lt;br /&gt;
		this.game.addActionButton(&#039;b1&#039;,_(&#039;Click Me&#039;), (e)=&amp;gt;this.onButtonClick(e));&lt;br /&gt;
	};&lt;br /&gt;
	onLeavingState(stateName) {&lt;br /&gt;
		console.log(&#039;onLeavingState : &#039; + stateName, args);&lt;br /&gt;
	};&lt;br /&gt;
	onUpdateActionButtons(stateName, args) {&lt;br /&gt;
		console.log(&#039;onUpdateActionButtons : &#039; + stateName, args);&lt;br /&gt;
	};&lt;br /&gt;
	onButtonClick(event) {&lt;br /&gt;
		console.log(&#039;onButtonClick&#039;,event);&lt;br /&gt;
	};&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&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;
	g_gamethemeurl + &#039;/modules/foo.js&#039; // custom module if needed&lt;br /&gt;
],&lt;br /&gt;
	function(dojo, declare) {&lt;br /&gt;
                // testla is game name is has to be changed&lt;br /&gt;
		return declare(&amp;quot;bgagame.testla&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
			constructor: function() {&lt;br /&gt;
				this.xapp = new Testla(this);&lt;br /&gt;
				this.xapp.dojo = dojo;&lt;br /&gt;
			},&lt;br /&gt;
			setup: function(gamedatas) {&lt;br /&gt;
				this.xapp.setup(gamedatas);&lt;br /&gt;
			},&lt;br /&gt;
			onEnteringState: function(stateName, args) {&lt;br /&gt;
				this.xapp.onEnteringState(stateName, args.args);&lt;br /&gt;
			},&lt;br /&gt;
			onLeavingState: function(stateName) {&lt;br /&gt;
				this.xapp.onLeavingState(stateName, args);&lt;br /&gt;
			},&lt;br /&gt;
			onUpdateActionButtons: function(stateName, args) {&lt;br /&gt;
				this.xapp.onUpdateActionButtons(stateName, args);&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;
=== More readable JS: onEnteringState ===&lt;br /&gt;
&lt;br /&gt;
If you have a lot of states onEnteringState and friends become rather wild, you can do this trick to call some method dynamically.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
     onEnteringState: function(stateName, args) {&lt;br /&gt;
       console.log(&#039;Entering state: &#039; + stateName, args);&lt;br /&gt;
&lt;br /&gt;
       // Call appropriate method&lt;br /&gt;
       var methodName = &amp;quot;onEnteringState_&amp;quot; + stateName;&lt;br /&gt;
       if (this[methodName] !== undefined) {             &lt;br /&gt;
          console.log(&#039;Calling &#039; + methodName, args.args);&lt;br /&gt;
          this[methodName](args.args);&lt;br /&gt;
       }&lt;br /&gt;
     },&lt;br /&gt;
&lt;br /&gt;
     onEnteringState_playerTurn: function(args) { // this is args directly, not args.args &lt;br /&gt;
         // process&lt;br /&gt;
     },&lt;br /&gt;
&lt;br /&gt;
     onEnteringState_playerSomethingElse: function(args) { &lt;br /&gt;
         // process&lt;br /&gt;
     },&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: since its ignores the undefined functions you don&#039;t have define function for each state, but on the other hand you cannot make typos.&lt;br /&gt;
Same applies to onUpdateActionButtons except you pass &#039;args&#039; to method, not args.args, and for onLeavingState where you don&#039;t pass anything.&lt;br /&gt;
&lt;br /&gt;
=== Frameworks and Preprocessors ===&lt;br /&gt;
&lt;br /&gt;
* [[Using Vue]] - work-in-progress guide on using the modern framework Vue.js to create a game&lt;br /&gt;
* [[Using Typescript and Scss]] - How to auto-build Typescript and SCSS files to make your code cleaner&lt;br /&gt;
&lt;br /&gt;
== Assorted Stuff ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Out-of-turn actions: Un-pass ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, ggg.game.php, ggg.action.php, states.inc.php&lt;br /&gt;
&lt;br /&gt;
In multiplayer game sometimes players passes but than they think more and want to un-Pass and redo their choice. &lt;br /&gt;
To re-active a player who passes some trickery required.&lt;br /&gt;
&lt;br /&gt;
Define a special action that does that and hook it up.&lt;br /&gt;
&lt;br /&gt;
In states.inc.php add an action to mmultipleactiveplayer state to &amp;quot;unpass&amp;quot;, lets call it &amp;quot;actionCancel&amp;quot;&lt;br /&gt;
&lt;br /&gt;
In ggg.action.php add action hook&lt;br /&gt;
    public function actionCancel() {&lt;br /&gt;
        self::setAjaxMode();&lt;br /&gt;
        $this-&amp;gt;game-&amp;gt;actionCancel();&lt;br /&gt;
        self::ajaxResponse();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
In ggg.game.php add action handler&lt;br /&gt;
    function actionCancel() {&lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;checkPossibleAction(&#039;actionCancel&#039;);&lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;setPlayersMultiactive(array ($this-&amp;gt;getCurrentPlayerId() ), &#039;error&#039;, false);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
Finally to call this in client ggg.js you would do something like:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 onUpdateActionButtons:  function(stateName, args) {&lt;br /&gt;
   if (this.isCurrentPlayerActive()) { &lt;br /&gt;
     // ...&lt;br /&gt;
   } else if (!this.isSpectator) { // player is NOT active but not spectator&lt;br /&gt;
       switch (stateName) {&lt;br /&gt;
          case &#039;playerTurnMuliPlayerState&#039;:&lt;br /&gt;
		this.addActionButton(&#039;button_unpass&#039;, _(&#039;Oh no!&#039;), &#039;onUnpass&#039;);&lt;br /&gt;
		break;&lt;br /&gt;
	}&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
				&lt;br /&gt;
 onUnpass: function(e) {&lt;br /&gt;
    this.ajaxcall(&amp;quot;/&amp;quot; + this.game_name + &amp;quot;/&amp;quot; +  this.game_name + &amp;quot;/actionCancel.html&amp;quot;, {}, this); // no checkAction!&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Although be careful that if the turn comes back to the player while he is about to click cancel, the action buttons will be updated and the player will misclick which can be quite frustrating. To avoid this, move the cancel button to another position, like to the left of pagemaintitletext:&lt;br /&gt;
  dojo.place(&#039;button_unpass&#039;, &#039;pagemaintitletext&#039;, &#039;before&#039;);&lt;br /&gt;
Being out of the generalactions div, it won&#039;t be automatically destroyed like normal buttons, so you&#039;ll have to handle that yourself in onLeavingState. You might also want to change the button color to red (blue buttons for active player only, red buttons also for inactive players?)&lt;br /&gt;
&lt;br /&gt;
Note: same technique can be used to do other out-of-turn actions, such as re-arranging cards in hand, exchanging resources, etc (i.e. if permitted by rules, such as &amp;quot;at any time player can...&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
=== Multi Step Interactions: Select Worker/Place Worker - Using Selection ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
Simple way to implement something like that without extra states is to use &amp;quot;selection&amp;quot; mechanism. When user click on worker add some sort of class into that element i.e. &#039;selected&#039; (which also have to have some indication by css i.e. outline).&lt;br /&gt;
&lt;br /&gt;
Than user can click on placement zone, you can use dojo.query for &amp;quot;selected&amp;quot; element and use it along with zone id to send data to server. If proper worker is not selected yet can give a error message using this.showMessage(...) function.&lt;br /&gt;
&lt;br /&gt;
Extra code required to properly cleanup selection between states.&lt;br /&gt;
Also when you do that sometimes you want to change the state prompt, see below &#039;Change state prompt&#039;&lt;br /&gt;
&lt;br /&gt;
=== Multi Step Interactions: Select Worker/Place Worker - Using Client States ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
I don&#039;t think its documented feature but there is a way to do client-only states, which is absolutely wonderful for few reasons&lt;br /&gt;
* When player interaction is two step process, such as select worker, place worker, or place worker, pick one of two resources of your choice&lt;br /&gt;
* When multi-step process can result of impossible situation and has to be undone (by rules)&lt;br /&gt;
* When multi-step process is triggered from multiple states (such as you can do same thing as activated card action, pass action or main action)&lt;br /&gt;
&lt;br /&gt;
So lets do Select Worker/Place Worker&lt;br /&gt;
&lt;br /&gt;
Define your server state as usual, i.e. playerMainTurn -&amp;gt; &amp;quot;You must pick up a worker&amp;quot;.&lt;br /&gt;
Now define a client state, we only need &amp;quot;name&amp;quot; and &amp;quot;descriptionmyturn&amp;quot;, lets say &amp;quot;client_playerPicksLocation&amp;quot;. Always prefix names of client state with &amp;quot;client_&amp;quot; to avoid confusion. Now we have to do the following:&lt;br /&gt;
* Have a handler for onUpdateActionButtons for playerMainTurn to activate all possible workers he can pick&lt;br /&gt;
* When player clicks workers, remember the worker in one of the members of the main class, I usually use one called this.clientStateArgs.&lt;br /&gt;
* Transition to new client state&lt;br /&gt;
  onWorker: function(e) {&lt;br /&gt;
      var id = event.currentTarget.id;&lt;br /&gt;
      dojo.stopEvent(event);&lt;br /&gt;
      ... // do validity checks&lt;br /&gt;
      this.clientStateArgs.worker_id = id;&lt;br /&gt;
      this.setClientState(&amp;quot;client_playerPicksLocation&amp;quot;, {&lt;br /&gt;
                                descriptionmyturn : _(&amp;quot;${you} must select location&amp;quot;),&lt;br /&gt;
                            });&lt;br /&gt;
   }&lt;br /&gt;
* Have a handler for onUpdateActionButtons for client_playerPicksLocation to activate all possible locations this worker can go AND add Cancel button (see below)&lt;br /&gt;
* Have a location handler which will eventually send a server request, using stored this.clientStateArgs.worker_id as worker id&lt;br /&gt;
* The cancel button should call a method to restore server state, also if you doing it for more than one state you can add this universally using this.on_client_state check&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        if (this.isCurrentPlayerActive()) {&lt;br /&gt;
          if (this.on_client_state &amp;amp;&amp;amp; !$(&#039;button_cancel&#039;)) {&lt;br /&gt;
               this.addActionButton(&#039;button_cancel&#039;, _(&#039;Cancel&#039;), dojo.hitch(this, function() {&lt;br /&gt;
                                             this.restoreServerGameState();&lt;br /&gt;
               }));&lt;br /&gt;
          }&lt;br /&gt;
        } &lt;br /&gt;
Note: usually I call my own function call this.cancelLocalStateEffects() which will do more stuff first then call restoreServerGameState(), same function is usually needs to be called when server request has failed (i.e. invalid move)&lt;br /&gt;
&lt;br /&gt;
Note: If you need more than 2 steps, you may have to do client side animation to reflect the new state, which gets trickier because you have to undo that also on cancellation.&lt;br /&gt;
&lt;br /&gt;
Code is available here [https://github.com/elaskavaia/bga-sharedcode/blob/master/sharedcode.js sharedcode.js] (its using playerTurnPlayCubes and client_selectCubeLocation).&lt;br /&gt;
&lt;br /&gt;
=== Action Stack - Using Client States ===&lt;br /&gt;
&lt;br /&gt;
Action stack required where game is very complex and use triggered effects that can &amp;quot;stack&amp;quot;. It not always actual stack, it can be queue or random access&lt;br /&gt;
Examples:&lt;br /&gt;
* Magic the Gathering - classic card game where effects go on Stack, that allows to counter spell and counter spell of counter spell (not on bga - it just example of mechanics)&lt;br /&gt;
* Ultimate Railroads - action taking game where effects can be executed in any order&lt;br /&gt;
* Lewis and Clark - card game where actions executed as queue&lt;br /&gt;
&lt;br /&gt;
There is two ways of implementing it - on the server or the client.&lt;br /&gt;
For the server see article below.&lt;br /&gt;
The requirement for client side stack is all action can be undone, which means&lt;br /&gt;
* No dice rolls&lt;br /&gt;
* No card drawn&lt;br /&gt;
* No other players interaction&lt;br /&gt;
&lt;br /&gt;
No snippets are here, as this will be too complex but basically flow is:&lt;br /&gt;
* You have a action/effect stack (queue/list) as js object attached to &amp;quot;this&amp;quot;, i.e. this.unprocessed_actions&lt;br /&gt;
* When player plays a card, worker, etc, you read the effect of that card from the material file (client copy), and place into stack&lt;br /&gt;
* Then we call dispatch method which pulls the next action from the stack and change client state accordinly,i.e.  this.setClientState(&amp;quot;client_playerGainsCubes&amp;quot;)&lt;br /&gt;
* When players acts on it - the action is removed from the stack and added to &amp;quot;server action arguments&amp;quot; list, this is another object which be used to send ajax call, i.e. this.clientStateArgs&lt;br /&gt;
* If nothing left in stack we can submit the ajax call assembling parameters from collected arguments (that can include action name)&lt;br /&gt;
* This method allows cheap undo - by restoring server state you will wipe out all user actions (but if you need intermediate aninmation you have to handle it yourself)&lt;br /&gt;
&lt;br /&gt;
Code can be found in Ultimate Railroads game (but it is random access list - so it a bit complex) and Lewis and Clark (complexity - use can always deny part of any effect)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Action Stack - Using Server States ===&lt;br /&gt;
&lt;br /&gt;
See definition of Action Stack above.&lt;br /&gt;
&lt;br /&gt;
To implement you usually need another db table that has the following fields: index of effect - which is used for sorted access, type - which is essense of the effect (i.e. collect resource), some extra arguments (i.e. resource type and resource count), and usually owner of the effect (i.e. player id)&lt;br /&gt;
The flow is:&lt;br /&gt;
* There is some initial player state, where player can play card for example&lt;br /&gt;
* Player main action - pushes the card effect on stack, which also can cause triggered effects which also go on stack&lt;br /&gt;
* After action processing is finished switch to game state which is &amp;quot;dispatcher&amp;quot;&lt;br /&gt;
* Gispatcher pulls the top effect (whatever definition of the top is), changes the active player and changes the state to appropriate player state to collect response&lt;br /&gt;
* Player state knows about the stack and pulls arguments (argX) from the effect arguments of the db&lt;br /&gt;
* Player action should clear up the top effect, and can possibly add more effects, then switch to &amp;quot;dispatcher&amp;quot; state again&lt;br /&gt;
* If stack is empty, dispatcher can either pick next player itself or use another game state which responsible for picking next player&lt;br /&gt;
&lt;br /&gt;
Code can be found in Tapestry.&lt;br /&gt;
&lt;br /&gt;
=== Changing state prompt ===&lt;br /&gt;
&lt;br /&gt;
State prompt is message displayed for player which usually comes from state description.&lt;br /&gt;
Sometimes you want to change it without changing state (one way is change state but locally, see client states above).&lt;br /&gt;
&lt;br /&gt;
Simple way just change the html&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        setMainTitle: function(text) {&lt;br /&gt;
            $(&#039;pagemaintitletext&#039;).innerHTML = text;&lt;br /&gt;
        },&lt;br /&gt;
         // usage&lt;br /&gt;
        onMeeple: function(event) {&lt;br /&gt;
              //... &lt;br /&gt;
              this.setMainTitle(_(&#039;You must select where meeple is going&#039;));&lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This however will not work with parameters and will not draw You in color, if you want this its more sophisticated:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        setDescriptionOnMyTurn : function(text) {&lt;br /&gt;
            this.gamedatas.gamestate.descriptionmyturn = text;&lt;br /&gt;
            var tpl = dojo.clone(this.gamedatas.gamestate.args);&lt;br /&gt;
            if (tpl === null) {&lt;br /&gt;
                tpl = {};&lt;br /&gt;
            }&lt;br /&gt;
            var title = &amp;quot;&amp;quot;;&lt;br /&gt;
            if (this.isCurrentPlayerActive() &amp;amp;&amp;amp; text !== null) {&lt;br /&gt;
                tpl.you = this.divYou(); &lt;br /&gt;
            }&lt;br /&gt;
            title = this.format_string_recursive(text, tpl);&lt;br /&gt;
&lt;br /&gt;
            if (!title) {&lt;br /&gt;
                this.setMainTitle(&amp;quot;&amp;amp;nbsp;&amp;quot;);&lt;br /&gt;
            } else {&lt;br /&gt;
                this.setMainTitle(title);&lt;br /&gt;
            }&lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: this method uses &#039;&#039;&#039;setMainTitle&#039;&#039;&#039; defined above and &#039;&#039;&#039;divYou&#039;&#039;&#039; defined in another section of this wiki.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Adding Image buttons ===&lt;br /&gt;
&lt;br /&gt;
Its pretty trivial but just in case you need a working function:&lt;br /&gt;
&lt;br /&gt;
ggg.js:&lt;br /&gt;
&lt;br /&gt;
                addImageActionButton: function (id, div_html, handler) { // div_html is string not node&lt;br /&gt;
                    this.addActionButton(id, div_html, handler, &#039;&#039;, false, &#039;gray&#039;); &lt;br /&gt;
                    dojo.style(id, &amp;quot;border&amp;quot;, &amp;quot;none&amp;quot;); // remove ugly border&lt;br /&gt;
                    dojo.addClass(id, &amp;quot;bgaimagebutton&amp;quot;); // add css class to do more styling&lt;br /&gt;
                    return $(id); // return node for chaining&lt;br /&gt;
                },&lt;br /&gt;
&lt;br /&gt;
Example of usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    this.addImageActionButton(&#039;button_coin&#039;,&amp;quot;&amp;lt;div class=&#039;coin&#039;&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;, ()=&amp;gt;{ alert(&#039;Ha!&#039;); });&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Assigning Player Order ===&lt;br /&gt;
Normally when game starts there is &amp;quot;natural&amp;quot; player order assigned randomly.&lt;br /&gt;
&lt;br /&gt;
If you want to deliberatly assign player order at the start of the game (for example, in a game with teams options), you can do so by retrieving the initialization-only player attribute &#039;&#039;&#039;player_table_order&#039;&#039;&#039; and using it to assign values to &#039;&#039;&#039;player_no&#039;&#039;&#039; (which is normally assigned at the start of a game in the order in which players come to the table). (See [https://en.doc.boardgamearena.com/Game_database_model:_dbmodel.sql#The_player_table Game database model] for more details.)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Example:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                // Retrieve inital player order ([0=&amp;gt;playerId1, 1=&amp;gt;playerId2, ...])&lt;br /&gt;
		$playerInitialOrder = [];&lt;br /&gt;
		foreach ($players as $playerId =&amp;gt; $player) {&lt;br /&gt;
			$playerInitialOrder[$player[&#039;player_table_order&#039;]] = $playerId;&lt;br /&gt;
		}&lt;br /&gt;
		ksort($playerInitialOrder);&lt;br /&gt;
		$playerInitialOrder = array_flip(array_values($playerInitialOrder));&lt;br /&gt;
&lt;br /&gt;
		// Player order based on &#039;playerTeams&#039; option&lt;br /&gt;
		$playerOrder = [0, 1, 2, 3];&lt;br /&gt;
		switch (self::getGameStateValue(&#039;playerTeams&#039;)) {&lt;br /&gt;
			case self::TEAM_1_2:&lt;br /&gt;
				$playerOrder = [0, 2, 1, 3];&lt;br /&gt;
				break;&lt;br /&gt;
			case self::TEAM_1_4:&lt;br /&gt;
				$playerOrder = [0, 1, 3, 2];&lt;br /&gt;
				break;&lt;br /&gt;
			case self::TEAM_RANDOM:&lt;br /&gt;
				shuffle($playerOrder);&lt;br /&gt;
				break;&lt;br /&gt;
			default:&lt;br /&gt;
			case self::TEAM_1_3:&lt;br /&gt;
				// Default order&lt;br /&gt;
				break;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
                // Create players&lt;br /&gt;
		// Note: if you added some extra field on &amp;quot;player&amp;quot; table in the database (dbmodel.sql), you can initialize it there.&lt;br /&gt;
		$sql =&lt;br /&gt;
			&#039;INSERT INTO player (player_id, player_color, player_canal, player_name, player_avatar, player_no) VALUES &#039;;&lt;br /&gt;
		$values = [];&lt;br /&gt;
&lt;br /&gt;
		foreach ($players as $playerId =&amp;gt; $player) {&lt;br /&gt;
			$color = array_shift($default_colors);&lt;br /&gt;
			$values[] =&lt;br /&gt;
				&amp;quot;(&#039;&amp;quot; .&lt;br /&gt;
				$playerId .&lt;br /&gt;
				&amp;quot;&#039;,&#039;$color&#039;,&#039;&amp;quot; .&lt;br /&gt;
				$player[&#039;player_canal&#039;] .&lt;br /&gt;
				&amp;quot;&#039;,&#039;&amp;quot; .&lt;br /&gt;
				addslashes($player[&#039;player_name&#039;]) .&lt;br /&gt;
				&amp;quot;&#039;,&#039;&amp;quot; .&lt;br /&gt;
				addslashes($player[&#039;player_avatar&#039;]) .&lt;br /&gt;
				&amp;quot;&#039;,&#039;&amp;quot; .&lt;br /&gt;
				$playerOrder[$playerInitialOrder[$playerId]] .&lt;br /&gt;
				&amp;quot;&#039;)&amp;quot;;&lt;br /&gt;
		}&lt;br /&gt;
		$sql .= implode(&#039;,&#039;, $values);&lt;br /&gt;
		self::DbQuery($sql);&lt;br /&gt;
		self::reattributeColorsBasedOnPreferences(&lt;br /&gt;
			$players,&lt;br /&gt;
			$gameinfos[&#039;player_colors&#039;]&lt;br /&gt;
		);&lt;br /&gt;
		self::reloadPlayersBasicInfos();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Send different notifications to active player vs everybody else ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
Hack alert. This is a hack. We were hoping for proper solution by bga framework.&lt;br /&gt;
&lt;br /&gt;
This will allow you to send notification with two message one for specific player and one for everybody else including spectators.&lt;br /&gt;
Note that this does not split the data - all data must be shared.&lt;br /&gt;
&lt;br /&gt;
Add this to .js file (if you already overriding it merge obviously)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/** @Override */&lt;br /&gt;
format_string_recursive: function(log, args) {&lt;br /&gt;
   if (typeof args.log_others != &#039;undefined&#039; &amp;amp;&amp;amp; typeof args.player_id != &#039;undefined&#039; &amp;amp;&amp;amp; this.player_id != args.player_id)&lt;br /&gt;
	log = args.log_others;&lt;br /&gt;
   return this.inherited(arguments); // you must call this to call super &lt;br /&gt;
},&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example of usage (from eminentdomain)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    $this-&amp;gt;notifyAllPlayers(&#039;tokenMoved&#039;, &lt;br /&gt;
             clienttranslate(&#039;${player_name} adds +2 Colonies to ${place_name}&#039;), // notification with show for player with player_id&lt;br /&gt;
             [&#039;player_id&#039;=&amp;gt;$player_id, // this is mandatory&lt;br /&gt;
             &#039;log_others&#039;=&amp;gt;clienttranslate(&#039;${player_name} adds +2 Colonies to an unknown planet&#039;), // notification will show for others&lt;br /&gt;
              ...&lt;br /&gt;
             ]);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Send transient notifications without incrementing move ID ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.php&lt;br /&gt;
&lt;br /&gt;
Hack alert. This is a hack.&lt;br /&gt;
&lt;br /&gt;
Use this if you need to send some transient notification that should not create a new move ID. The notification should be idempotent -- it should have no practical effect on the game state and would be &#039;&#039;&#039;safe to drop&#039;&#039;&#039; (e.g., it would not matter if a player never received this notification). For example, in a co-op game you want all players to see a real-time preview of some action, before the active player commits their turn.&lt;br /&gt;
&lt;br /&gt;
Doing this mainly affects the instant replay &amp;amp; archive modes. During replay, the BGA framework automatically inserts a 1.5-second pause between each &amp;quot;move&amp;quot;. With this hack, your transient notifications are not considered to be a &amp;quot;move&amp;quot;, so no pause gets added.&lt;br /&gt;
&lt;br /&gt;
; In ggg.php&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$this-&amp;gt;not_a_move_notification = true; // note: do not increase the move counter&lt;br /&gt;
$this-&amp;gt;notifyAllPlayers(&#039;cardsPreview&#039;, &#039;&#039;, $args);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: you cannot have code that send notification or even changes state after this, and you cannot reset this variable back either because it only takes effect when you exit action handling function&lt;br /&gt;
&lt;br /&gt;
=== Ajax Call wrapper ===&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
The current ajaxcall is super vebose and prone to errors, I suggest using a helper function. It does a lot of stuff you must do anyways.&lt;br /&gt;
Most beginner mistakes come from missing part of this code (which is understandstandable - this is a huge snippet to clone every time).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	ajaxcallwrapper: function(action, args, handler) {&lt;br /&gt;
		if (!args) args = []; // this allows to skip args parameter for action which do not require them&lt;br /&gt;
			&lt;br /&gt;
		args.lock = true; // this allows to avoid rapid action clicking which can cause race condition on server&lt;br /&gt;
		if (this.checkAction(action)) { // this does all the proper check that player is active and action is declared&lt;br /&gt;
			this.ajaxcall(&amp;quot;/&amp;quot; + this.game_name + &amp;quot;/&amp;quot; + this.game_name + &amp;quot;/&amp;quot; + action + &amp;quot;.html&amp;quot;, args, // this is mandatory fluff &lt;br /&gt;
				this, (result) =&amp;gt; { },  // success result handler is empty - it is never needed&lt;br /&gt;
                                               handler); // this is real result handler - it called both on success and error, it has optional param  &amp;quot;is_error&amp;quot; - you rarely need it&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   this.ajaxcallwrapper(&#039;pass&#039;); // no args&lt;br /&gt;
   this.ajaxcallwrapper(&#039;playCard&#039;, {card: card_id}); // with args&lt;br /&gt;
   this.ajaxcallwrapper(&#039;playCard&#039;, {card: card_id}, (is_error)=&amp;gt;{if (!is_error) dojo.query(&amp;quot;.selected&amp;quot;).removeClass(&#039;selected&#039;);}) // with handler that cleans up &#039;selected&#039; class on success&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: this always will lock interface and always check for action, you can modify this method to do it optionally, i.e&lt;br /&gt;
  if (args.lock!==false) args.lock = true; else delete args.lock; // it does not work with false value - it has to be removed&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Studio]]&lt;/div&gt;</summary>
		<author><name>SwHawk</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=BGA_Studio_Cookbook&amp;diff=14025</id>
		<title>BGA Studio Cookbook</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=BGA_Studio_Cookbook&amp;diff=14025"/>
		<updated>2022-07-16T09:34:22Z</updated>

		<summary type="html">&lt;p&gt;SwHawk: /* Inject images and styled html in the log */ corrected javascript code to comply with strict_mode and conditonnally include keys if they&amp;#039;re present in args&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
This page is collection of design and implementation recipes for BGA Studio framework.&lt;br /&gt;
For tooling and usage recipes see [[Tools and tips of BGA Studio]].&lt;br /&gt;
If you have your own recipes feel free to edit this page.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Visual Effects, Layout and Animation ==&lt;br /&gt;
&lt;br /&gt;
=== DOM manipulatons ===&lt;br /&gt;
&lt;br /&gt;
==== Create pieces dynamically (using template) ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg_ggg.tpl, ggg.js&lt;br /&gt;
&lt;br /&gt;
Note: this method is recommended by BGA guildlines&lt;br /&gt;
&lt;br /&gt;
Declared js template with variables in .tpl file, like this&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;
    // Javascript HTML templates&lt;br /&gt;
    var jstpl_ipiece = &#039;&amp;lt;div class=&amp;quot;${type} ${type}_${color} inlineblock&amp;quot; aria-label=&amp;quot;${name}&amp;quot; title=&amp;quot;${name}&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use it like this in .js file&lt;br /&gt;
  div = this.format_block(&#039;jstpl_ipiece&#039;, {&lt;br /&gt;
                                type : &#039;meeple&#039;,&lt;br /&gt;
                                color : &#039;ff0000&#039;,&lt;br /&gt;
                                name : &#039;Bob&#039;,&lt;br /&gt;
                            });&lt;br /&gt;
  &lt;br /&gt;
Then you do whatever you need to do with that div, this one specifically design to go to log entries, because it has embedded title (otherwise its a picture only) and no id.&lt;br /&gt;
&lt;br /&gt;
Note: you could have place this variable in js itself, but keeping it in .tpl allows you to have your js code be free of HTML. Normally it never happens but&lt;br /&gt;
it is good to strive for it.&lt;br /&gt;
Note: you can also use string concatenation, its less readable. You can also use dojo dom object creation api&#039;s but its brutally verbose and its more unreadable.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Create pieces dynamically (using string concatenation) ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
Note: Not recommended&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  div = &amp;quot;&amp;lt;div class=&#039;meeple &amp;quot;+color+&amp;quot;&#039;&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
==== Create all pieces statically ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg_ggg.tpl, ggg.css, ggg.view.php (optional) &lt;br /&gt;
&lt;br /&gt;
* Create ALL game pieces in html template (.tpl)&lt;br /&gt;
* ALL pieces should have unique id, and it should be meaningful, i.e. meeple_red_1&lt;br /&gt;
* Do not use inline styling&lt;br /&gt;
* Id of player&#039;s specific pieces should use some sort of &#039;color&#039; identification, since player id cannot be used in static layout, you can use english color name, hex 6 char value, or color &amp;quot;number&amp;quot; (1,2,3...)&lt;br /&gt;
* Pieces should have separated class for its color, type, etc, so it can be easily styled in groups. In example below you now can style all meeples, all red meeples or all red tokens, or all &amp;quot;first&amp;quot; meeples&lt;br /&gt;
&lt;br /&gt;
ggg.tpl:&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
  &amp;lt;div id=&amp;quot;home_red&amp;quot; class=&amp;quot;home_red home&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;div id=&amp;quot;meeple_red_1&amp;quot; class=&amp;quot;meeple red n1&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
     &amp;lt;div id=&amp;quot;meeple_red_2&amp;quot; class=&amp;quot;meeple red n2&amp;quot;&amp;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;
ggg.css:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.meeple {&lt;br /&gt;
	width: 32px;&lt;br /&gt;
	height: 39px;&lt;br /&gt;
	background-image: url(img/78_64_stand_meeples.png);&lt;br /&gt;
	background-size: 352px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.meeple.red {&lt;br /&gt;
	background-position: 30% 0%;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* There should be straight forward mapping between server id and js id (or 1:1)&lt;br /&gt;
* You place objects in different zones of the layout, and setup css to take care of layout&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.home .meeple{&lt;br /&gt;
   display: inline-block;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* If you need to have a temporary object that look like original you can use dojo.clone (and change id to some temp id)&lt;br /&gt;
* If there is lots of repetition or zone grid you can use template generator, but inject style declaration in css instead of inline style for flexibility&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
* If you use this model you cannot use premade js components such as Stock and Zone&lt;br /&gt;
* You have to use alternative methods of animation (slightly altered) since default method will leave object with inline style attributes which you don&#039;t need&lt;br /&gt;
&lt;br /&gt;
=== Logs ===&lt;br /&gt;
&lt;br /&gt;
==== Inject icon images in the log ====&lt;br /&gt;
&lt;br /&gt;
Here is an example of what was done for Terra Mystica which is simple and straightforward:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
//Define the proper message&lt;br /&gt;
		$message = clienttranslate(&#039;${player_name} gets ${power_income} via Structures&#039;);&lt;br /&gt;
		if ($price &amp;gt; 0) {&lt;br /&gt;
			self::DbQuery(&amp;quot;UPDATE player SET player_score = player_score - $price WHERE player_id = $player_id&amp;quot;);&lt;br /&gt;
			$message = clienttranslate(&#039;${player_name} pays ${vp_price} and gets ${power_income} via Structures&#039;);&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
// Notify&lt;br /&gt;
		self::notifyAllPlayers( &amp;quot;powerViaStructures&amp;quot;, $message, array(&lt;br /&gt;
			&#039;i18n&#039; =&amp;gt; array( ),&lt;br /&gt;
			&#039;player_id&#039; =&amp;gt; $player_id,&lt;br /&gt;
			&#039;player_name&#039; =&amp;gt; self::getUniqueValueFromDb( &amp;quot;SELECT player_name FROM player WHERE player_id = $player_id&amp;quot; ),&lt;br /&gt;
			&#039;power_tokens&#039; =&amp;gt; $power_tokens,&lt;br /&gt;
			&#039;vp_price&#039; =&amp;gt; self::getLogsVPAmount($price),&lt;br /&gt;
			&#039;power_income&#039; =&amp;gt; self::getLogsPowerAmount($power_income),&lt;br /&gt;
			&#039;newScore&#039; =&amp;gt; self::getUniqueValueFromDb( &amp;quot;SELECT player_score FROM player WHERE player_id = $player_id&amp;quot; ),&lt;br /&gt;
			&#039;counters&#039; =&amp;gt; $this-&amp;gt;getGameCounters(null),&lt;br /&gt;
		) );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With some functions to have the needed html added inside the substitution variable, such as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function getLogsPowerAmount( $amount ) {&lt;br /&gt;
		return &amp;quot;&amp;lt;div class=&#039;tmlogs_icon&#039; title=&#039;Power&#039;&amp;gt;&amp;lt;div class=&#039;power_amount&#039;&amp;gt;$amount&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: injecting html from php is not ideal but easy, if you want more clean solution, use method below but it is a lot more sophisticated.&lt;br /&gt;
&lt;br /&gt;
==== Inject images and styled html in the log ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, ggg.game.php&lt;br /&gt;
&lt;br /&gt;
So you want nice pictures in the game log. What do you do? The first idea that comes to mind is to send html from php in notifications (see method above). &lt;br /&gt;
&lt;br /&gt;
This is a bad idea for many reasons:&lt;br /&gt;
&lt;br /&gt;
* It&#039;s bad architecture. ui elements leak into the server, and now you have to manage the ui in multiple places.&lt;br /&gt;
* If you decided to change something in the ui in future version, replay logs for old games and tutorials may not work, since they use stored notifications.&lt;br /&gt;
* Log previews for old games become unreadable. (This is the log state before you enter the game replay, which is useful for troubleshooting and game analysis.)&lt;br /&gt;
* It&#039;s more data to transfer and store in the db.&lt;br /&gt;
* It&#039;s a nightmare for translators.&lt;br /&gt;
&lt;br /&gt;
So what else can you do? I use this recipe for &#039;&#039;&#039;client side log injection&#039;&#039;&#039; to intercept log arguments (which come from the server) and replace them with html on the client side.&lt;br /&gt;
&lt;br /&gt;
[[File:clientloginjection.png|left]] &lt;br /&gt;
&lt;br /&gt;
ggg.js&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
        /** Override this function to inject html into log items. This is a built-in BGA method.  */&lt;br /&gt;
&lt;br /&gt;
        /* @Override */&lt;br /&gt;
        format_string_recursive : function format_string_recursive(log, args) {&lt;br /&gt;
            try {&lt;br /&gt;
                if (log &amp;amp;&amp;amp; args &amp;amp;&amp;amp; !args.processed) {&lt;br /&gt;
                    args.processed = true;&lt;br /&gt;
                    &lt;br /&gt;
&lt;br /&gt;
                    // list of special keys we want to replace with images&lt;br /&gt;
                    var keys = [&#039;place_name&#039;,&#039;token_name&#039;];&lt;br /&gt;
                    &lt;br /&gt;
                  &lt;br /&gt;
                    for ( var i in keys) {&lt;br /&gt;
                        var key = keys[i];&lt;br /&gt;
                        key in args &amp;amp;&amp;amp; args[key] = this.getTokenDiv(key, args);                            &lt;br /&gt;
&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            } catch (e) {&lt;br /&gt;
                console.error(log,args,&amp;quot;Exception thrown&amp;quot;, e.stack);&lt;br /&gt;
            }&lt;br /&gt;
            return this.inherited({callee: format_string_recursive}, arguments);&lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important:&#039;&#039;&#039; In the &#039;&#039;format_string_recursive&#039;&#039; method, the &#039;args&#039; parameter will only contain arguments passed to it from the notify method in ggg.game.php (see below).&lt;br /&gt;
&lt;br /&gt;
The &#039;log&#039; parameter is the actual string that is inserted into the logs. You can perform additional js string manipulation on it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        getTokenDiv : function(key, args) {&lt;br /&gt;
            // ... implement whatever html you want here, example from sharedcode.js&lt;br /&gt;
            var token_id = args[key];&lt;br /&gt;
            var item_type = getPart(token_id,0);&lt;br /&gt;
            var logid = &amp;quot;log&amp;quot; + (this.globalid++) + &amp;quot;_&amp;quot; + token_id;&lt;br /&gt;
            switch (item_type) {&lt;br /&gt;
                case &#039;wcube&#039;:&lt;br /&gt;
                    var tokenDiv = this.format_block(&#039;jstpl_resource_log&#039;, {&lt;br /&gt;
                        &amp;quot;id&amp;quot; : logid,&lt;br /&gt;
                        &amp;quot;type&amp;quot; : &amp;quot;wcube&amp;quot;,&lt;br /&gt;
                        &amp;quot;color&amp;quot; : getPart(token_id,1),&lt;br /&gt;
                    });&lt;br /&gt;
                    return tokenDiv;&lt;br /&gt;
             &lt;br /&gt;
                case &#039;meeple&#039;:&lt;br /&gt;
                    if ($(token_id)) {&lt;br /&gt;
                        var clone = dojo.clone($(token_id));&lt;br /&gt;
    &lt;br /&gt;
                        dojo.attr(clone, &amp;quot;id&amp;quot;, logid);&lt;br /&gt;
                        this.stripPosition(clone);&lt;br /&gt;
                        dojo.addClass(clone, &amp;quot;logitem&amp;quot;);&lt;br /&gt;
                        return clone.outerHTML;&lt;br /&gt;
                    }&lt;br /&gt;
                    break;&lt;br /&gt;
     &lt;br /&gt;
                default:&lt;br /&gt;
                    break;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            return &amp;quot;&#039;&amp;quot; + this.clienttranslate_string(this.getTokenName(token_id)) + &amp;quot;&#039;&amp;quot;;&lt;br /&gt;
       },&lt;br /&gt;
       getTokenName : function(key) {&lt;br /&gt;
           return this.gamedatas.token_types[key].name; // get name for the key, from static table for example&lt;br /&gt;
       },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that in this case the server simply injects token_id as a name, and the client substitutes it for the translated name or the picture.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ggg.game.php:&lt;br /&gt;
&lt;br /&gt;
           $this-&amp;gt;notifyAllPlayers(&#039;playerLog&#039;,clienttranslate(&#039;Game moves ${token_name}&#039;),[&#039;token_name&#039;=&amp;gt;$token_id]);&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important:&#039;&#039;&#039; As noted above, only arguments actually passed by this method are available to the args parameter received in the client-side &#039;&#039;format_string_recursive&#039;&#039; method.&lt;br /&gt;
&lt;br /&gt;
Sometimes it is the case that you want to pass arguments that are not actually included in the output message. For example, suppose we have a method like this:&lt;br /&gt;
&lt;br /&gt;
           $this-&amp;gt;notifyAllPlayers(&#039;tokenPlaced&#039;,clienttranslate(&#039;Player placed ${token_name}&#039;),array(&lt;br /&gt;
              &#039;token_name&#039; =&amp;gt; $token_id,&lt;br /&gt;
              &#039;zone_played&#039; =&amp;gt; $zone);&lt;br /&gt;
&lt;br /&gt;
This will output &amp;quot;Player placed ${token_name}&amp;quot; in the log, and if we subscribe to a notification method activated by the &amp;quot;tokenPlaced&amp;quot; event in the client-side code, that method can make use of the &#039;zone_played&#039; argument. &lt;br /&gt;
&lt;br /&gt;
Now if you want to make some really cool things with game log, most probably you would need more arguments than are included in log message. The problem with that,&lt;br /&gt;
it will work at first, but if you reload game using F5 or when the game loads in turn based mode, you will loose your additional parameters, why? Because when game reloads it does not actually send same notifications, it sends special &amp;quot;hitstorical_log&amp;quot; notification where all  parameters not listed in the message are removed. In example above, field zone_played would be removed from historical log as it is not included in message of the notification. You can till preserve specific arguments in historical log by adding special field preserve to notification arguments like this:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
           $this-&amp;gt;notifyAllPlayers(&#039;tokenPlaced&#039;,clienttranslate(&#039;Player placed ${token_name}&#039;),array(&lt;br /&gt;
              &#039;token_name&#039; =&amp;gt; $token_id,&lt;br /&gt;
              &#039;zone_played&#039; =&amp;gt; $zone,&lt;br /&gt;
              &#039;preserve&#039; =&amp;gt; [ &#039;zone_played&#039; ]&lt;br /&gt;
           );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now you can use zone_played in format_string_recursive even in historical logs.&lt;br /&gt;
&lt;br /&gt;
==== Processing logs on re-loading ====&lt;br /&gt;
&lt;br /&gt;
You rarely need to process logs when reloading, but if you want to do something fancy you may have to do it after logs are loaded. &lt;br /&gt;
Logs are loaded asyncronously so you have to listen for logs to be fully loaded.&lt;br /&gt;
Unfortunately there is no direct way of doing it so this is the hack.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Hack alert&#039;&#039;&#039; - this extends undocumented function and may be broken when framework is updated&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
			/*&lt;br /&gt;
  			* [Undocumented] Override BGA framework functions to call onLoadingLogsComplete when loading is done&lt;br /&gt;
                        @Override&lt;br /&gt;
   			*/&lt;br /&gt;
			setLoader: function(image_progress, logs_progress) {&lt;br /&gt;
				this.inherited(arguments); // required, this is &amp;quot;super()&amp;quot; call, do not remove&lt;br /&gt;
				//console.log(&amp;quot;loader&amp;quot;, image_progress, logs_progress)&lt;br /&gt;
				if (!this.isLoadingLogsComplete &amp;amp;&amp;amp; logs_progress &amp;gt;= 100) {&lt;br /&gt;
					this.isLoadingLogsComplete = true; // this is to prevent from calling this more then once&lt;br /&gt;
					this.onLoadingLogsComplete();&lt;br /&gt;
				}&lt;br /&gt;
			},&lt;br /&gt;
&lt;br /&gt;
			onLoadingLogsComplete: function() {&lt;br /&gt;
				console.log(&#039;Loading logs complete&#039;);&lt;br /&gt;
				// do something here&lt;br /&gt;
			},&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Player Panel ===&lt;br /&gt;
&lt;br /&gt;
==== Inserting non-player panel ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, ggg_ggg.tpl&lt;br /&gt;
&lt;br /&gt;
If you want to insert non-player panel on the right side (for example to hold extra preferences, zooming controls, etc)&lt;br /&gt;
&lt;br /&gt;
this can go pretty much anywhere in template it will be moved later&lt;br /&gt;
&lt;br /&gt;
ggg_ggg.tpl:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	&amp;lt;div class=&#039;player_board_config&#039; id=&amp;quot;player_board_config&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;!-- here is whatever you want, buttons just example --&amp;gt;&lt;br /&gt;
		&amp;lt;button id=&amp;quot;zoom-out&amp;quot; class=&amp;quot; fa fa-search-minus fa-2x config-control&amp;quot;&amp;gt;&amp;lt;/button&amp;gt;&lt;br /&gt;
		&amp;lt;button id=&amp;quot;zoom-in&amp;quot; class=&amp;quot; fa fa-search-plus fa-2x config-control&amp;quot;&amp;gt;&amp;lt;/button&amp;gt;&lt;br /&gt;
		&amp;lt;button id=&amp;quot;show-settings&amp;quot; class=&amp;quot;fa fa-cog fa-2x config-control &amp;quot;&amp;gt;&amp;lt;/button&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
some hackery required in js&lt;br /&gt;
&lt;br /&gt;
ggg.js:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* @Override */&lt;br /&gt;
	updatePlayerOrdering() {&lt;br /&gt;
		this.inherited(arguments);&lt;br /&gt;
		dojo.place(&#039;player_board_config&#039;, &#039;player_boards&#039;, &#039;first&#039;);&lt;br /&gt;
	},&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Images and Icons ===&lt;br /&gt;
&lt;br /&gt;
==== Accessing images from js ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
     // your game resources&lt;br /&gt;
     &lt;br /&gt;
     var my_img = &#039;&amp;lt;img src=&amp;quot;&#039;+g_gamethemeurl+&#039;img/cards.jpg&amp;quot;/&amp;gt;&#039;;&lt;br /&gt;
     &lt;br /&gt;
     // shared resources&lt;br /&gt;
     var my_help_img = &amp;quot;&amp;lt;img class=&#039;imgtext&#039; src=&#039;&amp;quot; + g_themeurl + &amp;quot;img/layout/help_click.png&#039; alt=&#039;action&#039; /&amp;gt; &amp;lt;span class=&#039;tooltiptext&#039;&amp;gt;&amp;quot; +&lt;br /&gt;
                    text + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== High-Definition Graphics ====&lt;br /&gt;
&lt;br /&gt;
Some users will have screens which can display text and images at a greater resolution than the usual 72 dpi, e.g. the &amp;quot;Retina&amp;quot; screens on the 5k iMac, all iPads, and high-DPI screens on laptops from many manufacturers. If you can get art assets at this size, they will make your game look extra beautiful. You &#039;&#039;could&#039;&#039; just use large graphics and scale them down, but that would increase the download time and bandwidth for users who can&#039;t display them. Instead, a good way is to prepare a separate graphics file at exactly twice the size you would use otherwise, and add &amp;quot;@2x&amp;quot; at the end of the filename, e.g. if pieces.png is 240x320, then pieces@2x.png is 480x640.&lt;br /&gt;
&lt;br /&gt;
There are two changes required in order to use the separate graphics files. First in your css, where you use a file, add a media query which overrides the original definition and uses the bigger version on devices which can display them. Ensuring that the &amp;quot;background-size&amp;quot; attribute is set means that the size of the displayed object doesn&#039;t change, but only is drawn at the improved dot pitch.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.piece {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    background-image: url(&#039;img/pieces.png&#039;);&lt;br /&gt;
    background-size:240px 320px;&lt;br /&gt;
    z-index: 10;&lt;br /&gt;
}&lt;br /&gt;
@media (-webkit-min-device-pixel-ratio: 2), (min-device-pixel-ratio: 2), (min-resolution: 192dpi)&lt;br /&gt;
{&lt;br /&gt;
    .piece {&lt;br /&gt;
        background-image: url(&#039;img/pieces@2x.png&#039;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Secondly, in your setup function in javascript, you must ensure than only the appropriate one version of the file gets pre-loaded (otherwise you more than waste the bandwidth saved by maintaining the standard-resolution file). Note that the media query is the same in both cases:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
            var isRetina = &amp;quot;(-webkit-min-device-pixel-ratio: 2), (min-device-pixel-ratio: 2), (min-resolution: 192dpi)&amp;quot;;&lt;br /&gt;
            if (window.matchMedia(isRetina).matches)&lt;br /&gt;
            {&lt;br /&gt;
                this.dontPreloadImage( &#039;pieces.png&#039; );&lt;br /&gt;
                this.dontPreloadImage( &#039;board.jpg&#039; );&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                this.dontPreloadImage( &#039;pieces@2x.png&#039; );&lt;br /&gt;
                this.dontPreloadImage( &#039;board@2x.jpg&#039; );&lt;br /&gt;
            }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Using CSS to create different colors of game pieces if you have only white piece ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
background-color: #${color}; &lt;br /&gt;
background-blend-mode: multiply;&lt;br /&gt;
background-image: url( &#039;img/mypiece.png&#039;);&lt;br /&gt;
mask: url(&#039;img/mypiece.png&#039;);&lt;br /&gt;
-webkit-mask: url(&#039;img/mypiece.png&#039;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where ${color} - is color you want&lt;br /&gt;
&lt;br /&gt;
Note: piece has to be white (shades of gray). Sprite can be used too, just add add blackground-position as usuall.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Other Fluff ===&lt;br /&gt;
&lt;br /&gt;
==== Use thematic fonts ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.css&lt;br /&gt;
&lt;br /&gt;
Sometime game elements use specific fonts of text, if you want to match it up you can load some specific font (IMPORTANT: from some &#039;&#039;&#039;free font&#039;&#039;&#039; source. See notes below).&lt;br /&gt;
&lt;br /&gt;
[[File:Dragonline_font.png]]&lt;br /&gt;
&lt;br /&gt;
.css&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* latin-ext */&lt;br /&gt;
@font-face {&lt;br /&gt;
  font-family: &#039;Qwigley&#039;;&lt;br /&gt;
  font-style: normal;&lt;br /&gt;
  font-weight: 400;&lt;br /&gt;
  src: local(&#039;Qwigley&#039;), local(&#039;Qwigley-Regular&#039;), url(https://fonts.gstatic.com/s/qwigley/v6/2Dy1Unur1HJoklbsg4iPJ_Y6323mHUZFJMgTvxaG2iE.woff2) format(&#039;woff2&#039;);&lt;br /&gt;
  unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;&lt;br /&gt;
}&lt;br /&gt;
/* latin */&lt;br /&gt;
@font-face {&lt;br /&gt;
  font-family: &#039;Qwigley&#039;;&lt;br /&gt;
  font-style: normal;&lt;br /&gt;
  font-weight: normal;&lt;br /&gt;
  src: local(&#039;Qwigley&#039;), local(&#039;Qwigley-Regular&#039;), url(https://fonts.gstatic.com/s/qwigley/v6/gThgNuQB0o5ITpgpLi4Zpw.woff2) format(&#039;woff2&#039;);&lt;br /&gt;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;&lt;br /&gt;
}&lt;br /&gt;
@font-face {&lt;br /&gt;
  font-family: &#039;Qwigley&#039;;&lt;br /&gt;
  font-style: normal;&lt;br /&gt;
  font-weight: normal;&lt;br /&gt;
  src: local(&#039;Qwigley&#039;), local(&#039;Qwigley-Regular&#039;), url(http://ff.static.1001fonts.net/q/w/qwigley.regular.ttf) format(&#039;ttf&#039;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.zone_title {&lt;br /&gt;
	display: inline-block;&lt;br /&gt;
	position: absolute;&lt;br /&gt;
	font: italic 32px/32px &amp;quot;Qwigley&amp;quot;, cursive;	   &lt;br /&gt;
	height: 32px;&lt;br /&gt;
	width: auto;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NB:&#039;&#039;&#039; if you need to include a font that&#039;s not available online, an extra action will be needed from an admin. Please include the font file(s) in your img directory, and mention it to admins when requesting your game to be moved to alpha. &#039;&#039;&#039;Please remember that the font has to be free, and include a .txt with all appropriate license information about the font.&#039;&#039;&#039;&lt;br /&gt;
You can look for free fonts (for example) on https://fonts.google.com or https://www.fontsquirrel.com/)&lt;br /&gt;
&lt;br /&gt;
=== Use player color in template ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg_ggg.tpl, ggg.view.php&lt;br /&gt;
&lt;br /&gt;
.view.php:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    function build_page($viewArgs) {&lt;br /&gt;
        // Get players &amp;amp; players number&lt;br /&gt;
        $players = $this-&amp;gt;game-&amp;gt;loadPlayersBasicInfos();&lt;br /&gt;
        $players_nbr = count($players);&lt;br /&gt;
        /**&lt;br /&gt;
         * ********* Place your code below: ***********&lt;br /&gt;
         */&lt;br /&gt;
        &lt;br /&gt;
        // Set PCOLOR to the current player color hex&lt;br /&gt;
        global $g_user;&lt;br /&gt;
        $cplayer = $g_user-&amp;gt;get_id();&lt;br /&gt;
        if (array_key_exists($cplayer, $players)) { // may be not set if spectator&lt;br /&gt;
            $player_color = $players [$cplayer] [&#039;player_color&#039;];&lt;br /&gt;
        } else {&lt;br /&gt;
            $player_color = &#039;ffffff&#039;; // spectator&lt;br /&gt;
        }&lt;br /&gt;
        $this-&amp;gt;tpl [&#039;PCOLOR&#039;] = $player_color;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Scale to fit for big boards ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg_ggg.tpl, ggg.js&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Lets say you have huge game board, and lets say you want it to be 1400px wide. Besides the board there will be side bar which is 240 and trim. &lt;br /&gt;
My display is 1920 wide so it fits, but there is big chance other people won&#039;t have that width. What do you do?&lt;br /&gt;
&lt;br /&gt;
You have to decide:&lt;br /&gt;
* If board does not fit you want scale whole thing down, the best way is probably use viewport (see https://en.doc.boardgamearena.com/Your_game_mobile_version)&lt;br /&gt;
* You can leave the board as is and make sure it is scrollable horizonatally&lt;br /&gt;
* You add custom scale just for the board (can add user controls  - and hook to transform: scale())&lt;br /&gt;
&lt;br /&gt;
I tried to auto-scale but this just does work, too many variables - browser zoom, 3d mode, viewport, custom bga scaling, devicePixelRatio - all create some impossible coctail of zooming...&lt;br /&gt;
Here is scaling functing for custom user scaling&lt;br /&gt;
&lt;br /&gt;
ggg_ggg.tpl:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   &amp;lt;div id=&amp;quot;thething&amp;quot; class=&amp;quot;thething&amp;quot;&amp;gt;&lt;br /&gt;
            ... everything else you declare ...&lt;br /&gt;
   &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ggg.js:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    onZoomPlus: function() {&lt;br /&gt;
       this.my_zoom+=0.1;&lt;br /&gt;
       this.zoommy(&#039;thething&#039;,this.my_zoom);&lt;br /&gt;
    },&lt;br /&gt;
&lt;br /&gt;
    zoommy: function(node, zoom) {&lt;br /&gt;
                node=$(node);&lt;br /&gt;
		var width = 100 / zoom;&lt;br /&gt;
		node.style.transformOrigin = &amp;quot;0 0&amp;quot;;&lt;br /&gt;
		node.style.transform = &amp;quot;scale(&amp;quot; + zoom + &amp;quot;)&amp;quot;;&lt;br /&gt;
		node.style.width = width + &amp;quot;%&amp;quot;;&lt;br /&gt;
    },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Dynamic tooltips ===&lt;br /&gt;
&lt;br /&gt;
If you really need a dynamic tooltip you can use this technique. (Only use it if the static tooltips provided by the BGA framework are not sufficient.)&lt;br /&gt;
&lt;br /&gt;
            new dijit.Tooltip({&lt;br /&gt;
                connectId: [&amp;quot;divItemId&amp;quot;],&lt;br /&gt;
                getContent: function(matchedNode){&lt;br /&gt;
                    return &amp;quot;... calculated ...&amp;quot;; &lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is an out-of-the-box djit.Tooltip. It has a &#039;&#039;getContent&#039;&#039; method which is called dynamically.&lt;br /&gt;
&lt;br /&gt;
The string function return becomes the innerHTML of the tooltip, so it can be anything. In this example matchedNode is a dojo node representing dom object with id of &amp;quot;divItemId&amp;quot; but there are more parameters which I am not posting here which allows more sophisticated subnode queries (i.e. you can attach tooltip to all nodes with class or whatever).&lt;br /&gt;
&lt;br /&gt;
[https://dojotoolkit.org/reference-guide/1.10/dijit/Tooltip.html dijit.Tooltip]&lt;br /&gt;
&lt;br /&gt;
It&#039;s not part of the BGA API so use at your own risk.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Rendering text with players color and proper background ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
This example actually writes &amp;quot;You&amp;quot; but you can replace this with player name as easily, drop translating function in this case&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        /* Implementation of proper colored You with background in case of white or light colors  */&lt;br /&gt;
 &lt;br /&gt;
        divYou : function() {&lt;br /&gt;
            var color = this.gamedatas.players[this.player_id].color;&lt;br /&gt;
            var color_bg = &amp;quot;&amp;quot;;&lt;br /&gt;
            if (this.gamedatas.players[this.player_id] &amp;amp;&amp;amp; this.gamedatas.players[this.player_id].color_back) {&lt;br /&gt;
                color_bg = &amp;quot;background-color:#&amp;quot; + this.gamedatas.players[this.player_id].color_back + &amp;quot;;&amp;quot;;&lt;br /&gt;
            }&lt;br /&gt;
            var you = &amp;quot;&amp;lt;span style=\&amp;quot;font-weight:bold;color:#&amp;quot; + color + &amp;quot;;&amp;quot; + color_bg + &amp;quot;\&amp;quot;&amp;gt;&amp;quot; + __(&amp;quot;lang_mainsite&amp;quot;, &amp;quot;You&amp;quot;) + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
            return you;&lt;br /&gt;
        },&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Cool realistic shadow effect with CSS ===&lt;br /&gt;
&lt;br /&gt;
==== Rectangles and circles ====&lt;br /&gt;
&lt;br /&gt;
It is often nice to have a drop shadow around tiles and tokens, to separate them from the table visually. It is very easy to add a shadow to rectangular elements, just add this to your css:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.xxx-tile {&lt;br /&gt;
    box-shadow: 3px 3px 3px #000000a0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
box-shadow obeys &#039;&#039;&#039;border-radius&#039;&#039;&#039; of the element, so it will look good for rounded rectangles, and hence also circles (if border-radius is set appropriately).&lt;br /&gt;
&lt;br /&gt;
box-shadow also supports various other parameters and can be used to achieve effects such as glowing, borders, inner shadows etc. If you need to animate a box-shadow, you may be able to get better performance (avoiding redraws) if you attach the shadow to another element (possibly an ::after pseudo-element) and change only the &#039;&#039;&#039;opacity&#039;&#039;&#039; of that element.&lt;br /&gt;
&lt;br /&gt;
==== Irregular Shapes ====&lt;br /&gt;
&lt;br /&gt;
If you wish to make a shadow effect for game pieces that are not a rectangle, but your game pieces are drawn from rectangles in a PNG image, you can apply the shadow to the piece using any art package and save it inside the image. This usually will yield the best performance. Remember to account for the size of the shadow when you lay out images in the sprite sheet.&lt;br /&gt;
&lt;br /&gt;
However that sometimes will not be an option, for example if the image needs to be rotated while the shadow remains offset in the same direction. In this case, one option is to not use box-shadow but use filter, which is supported by recent major browsers.  This way, you can use the alpha channel of your element to drop a shadow.  This even work for transparent backgrounds, so that if you are using the &amp;quot;CSS-sprite&amp;quot; method, it will work!&lt;br /&gt;
&lt;br /&gt;
For instance:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.xxx-token {&lt;br /&gt;
    filter: drop-shadow(0px 0px 1px #000000);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beware that some browsers still do not always draw drop-shadow correctly. In particular, Safari frequently leaves bits of shadow behind when objects move around the screen. In Chrome, shadows sometimes flicker badly if another element is animating close by. Some of these correctness issues can be solved by adding &#039;&#039;&#039;isolation: isolate; will-change: filter;&#039;&#039;&#039; to affected elements, but this significantly affects redraw performance.&lt;br /&gt;
&lt;br /&gt;
Beware of performance issues - particularly on Safari (MacOS, iPhone and iPad). Keep in mind that drop-shadow are very GPU intensive. This becomes noticeable once you have about 40 components with drop-shadow filter. If that is your case, you can quite easily implement a user preference to disable shadows for users on slower machines:&lt;br /&gt;
&lt;br /&gt;
gameoptions.inc.php&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
100 =&amp;gt; array(&lt;br /&gt;
			&#039;name&#039; =&amp;gt; totranslate(&#039;Shadows&#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;Enabled&#039; ), &#039;cssPref&#039; =&amp;gt; &#039;&#039; ),&lt;br /&gt;
					2 =&amp;gt; array( &#039;name&#039; =&amp;gt; totranslate( &#039;Disabled&#039; ), &#039;cssPref&#039; =&amp;gt; &#039;no-shadow&#039; )&lt;br /&gt;
			)&lt;br /&gt;
	),&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[game].css&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.no-shadow * {&lt;br /&gt;
	filter: none !important; &lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Shadows with clip-path ====&lt;br /&gt;
&lt;br /&gt;
For some reason, a shadow will not work together with clip-path on one element. To use both clip-path (when for example using .svg to cut out cardboard components from your .jpg spritesheet) and drop-shadow, you need to wrap the element into another one, and apply drop-shadow to the outer one, and clip-path to the inner one.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;div class=&#039;my-token-wrap&#039;&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&#039;my-token&#039;&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;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.my-token-wrap {&lt;br /&gt;
    filter: drop-shadow(0px 0px 1px #000000);&lt;br /&gt;
}&lt;br /&gt;
.my-token-wrap .my-token {&lt;br /&gt;
    clip-path: url(#my-token-path);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Using the CSS classes from the state machine ===&lt;br /&gt;
&lt;br /&gt;
If you need to hide or show stuff depending on the state of your game, you can of course use javascript, but CSS is hand enough for that.  The #overall-content element does change class depending on the game state.  For instance, if you are in state &#039;&#039;playerTurn&#039;&#039;, it will have the class &#039;&#039;gamestate_playerTurn&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
So now, if you want to show the discard pile only during player turns, you may use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#discard_pile { display: none }&lt;br /&gt;
.gamestate_playerTurn #discard_pile { display: block }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This can be used if you want to change sizing of elements, position, layout or visual appearance.&lt;br /&gt;
&lt;br /&gt;
== Game Model and Database design ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Database for The euro game ===&lt;br /&gt;
Lets say we have a game with workers, dice, tokens, board, resources, money and vp. Workers and dice can be placed in various zones on the board, and you can get resources, money, tokens and vp in your home zone. Also tokens can be flipped or not flipped.&lt;br /&gt;
&lt;br /&gt;
[[File:Madeira board.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now lets try to map it, we have&lt;br /&gt;
* (meeple,zone)&lt;br /&gt;
* (die, zone, sideup)&lt;br /&gt;
* (resource cube/money token/vp token,player home zone)&lt;br /&gt;
* (token, player home zone, flip state)&lt;br /&gt;
We can notice that resource and money are uncountable, and don&#039;t need to be track individually so we can replace our mapping to&lt;br /&gt;
* (resource type/money,player home zone, count)&lt;br /&gt;
And vp stored already for us in player table, so we can remove it from that list.&lt;br /&gt;
&lt;br /&gt;
Now when we get to encode it we can see that everything can be encoded as (object,zone,state) form, where object and zone is string and state is integer. The resource mapping is slightly different semantically so you can go with two table, or counting using same table with state been used as count for resources.&lt;br /&gt;
&lt;br /&gt;
So the piece mapping for non-grid based games can be in most case represented by (string: token_key, string: token_location, int: token_state), example of such database schema can be found here: [https://github.com/elaskavaia/bga-sharedcode/blob/master/dbmodel.sql dbmodel.sql] and class implementing access to it here [https://github.com/elaskavaia/bga-sharedcode/blob/master/modules/tokens.php table.game.php].&lt;br /&gt;
&lt;br /&gt;
Variant 1: Minimalistic&lt;br /&gt;
&lt;br /&gt;
 CREATE TABLE IF NOT EXISTS `token` (&lt;br /&gt;
  `token_key` varchar(32) NOT NULL,&lt;br /&gt;
  `token_location` varchar(32) NOT NULL,&lt;br /&gt;
  `token_state` int(10),&lt;br /&gt;
  PRIMARY KEY (`token_key`)&lt;br /&gt;
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+token&lt;br /&gt;
! token_key&lt;br /&gt;
! token_location&lt;br /&gt;
! token_state&lt;br /&gt;
|-&lt;br /&gt;
|meeple_red_1&lt;br /&gt;
|home_red&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
|dice_black_2&lt;br /&gt;
|board_guard&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
|dice_green_1&lt;br /&gt;
|board_action_mayor&lt;br /&gt;
|3&lt;br /&gt;
|-&lt;br /&gt;
|bread&lt;br /&gt;
|home_red&lt;br /&gt;
|5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Now how we represent resource counters such as bread?&lt;br /&gt;
Using same table from we simply add special counter token for bread and use state to indicate the count. Note to keep first column unique we have to add player identification for that counter, i.e. ff0000 is red player.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+token&lt;br /&gt;
! token_key&lt;br /&gt;
! token_location&lt;br /&gt;
! token_state&lt;br /&gt;
|-&lt;br /&gt;
|bread_ff0000&lt;br /&gt;
|tableau_ff0000&lt;br /&gt;
|5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See php module for this table here https://github.com/elaskavaia/bga-sharedcode/blob/master/modules/tokens.php&lt;br /&gt;
&lt;br /&gt;
Variant 2: Additional resource table, resource count for each player id&lt;br /&gt;
&lt;br /&gt;
 CREATE TABLE IF NOT EXISTS `resource` (&lt;br /&gt;
  `player_id` int(10) unsigned NOT NULL,&lt;br /&gt;
  `resource_key` varchar(32) NOT NULL,&lt;br /&gt;
  `resource_count` int(10) signed NOT NULL,&lt;br /&gt;
  PRIMARY KEY (`player_id`,`resource_key`)&lt;br /&gt;
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;&lt;br /&gt;
&lt;br /&gt;
 ALTER TABLE resource ADD CONSTRAINT fk_player_id FOREIGN KEY (player_id) REFERENCES player(player_id);&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+resource&lt;br /&gt;
! player_id&lt;br /&gt;
! resource_key&lt;br /&gt;
! resource_count&lt;br /&gt;
|-&lt;br /&gt;
|123456&lt;br /&gt;
|bread&lt;br /&gt;
|5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Variant 3: More normalised&lt;br /&gt;
&lt;br /&gt;
This version is similar to &amp;quot;card&amp;quot; table from hearts tutorial, you can also use exact cards database schema and Deck implementation for most purposes (even you not dealing with cards). &lt;br /&gt;
&lt;br /&gt;
 CREATE TABLE IF NOT EXISTS `token` (&lt;br /&gt;
  `token_id` int(10) unsigned NOT NULL AUTO_INCREMENT,&lt;br /&gt;
  `token_type` varchar(16) NOT NULL,&lt;br /&gt;
  `token_arg` int(11) NOT NULL,&lt;br /&gt;
  `token_location` varchar(32) NOT NULL,&lt;br /&gt;
  `token_state` int(10),&lt;br /&gt;
  PRIMARY KEY (`token_id`)&lt;br /&gt;
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+token&lt;br /&gt;
! token_id&lt;br /&gt;
! token_type&lt;br /&gt;
! token_arg&lt;br /&gt;
! token_location&lt;br /&gt;
! token_state&lt;br /&gt;
|-&lt;br /&gt;
|22&lt;br /&gt;
|meeple&lt;br /&gt;
|123456&lt;br /&gt;
|home_123456&lt;br /&gt;
|0&lt;br /&gt;
|-&lt;br /&gt;
|23&lt;br /&gt;
|dice&lt;br /&gt;
|2&lt;br /&gt;
|board_guard&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
|26&lt;br /&gt;
|dice&lt;br /&gt;
|1&lt;br /&gt;
|board_action_mayor&lt;br /&gt;
|3&lt;br /&gt;
|-&lt;br /&gt;
|49&lt;br /&gt;
|bread&lt;br /&gt;
|0&lt;br /&gt;
|home_123456&lt;br /&gt;
|5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Advantages of this would be is a bit more straightforward to do some queries in db, disadvantage its hard to read (as you can compare with previous example, you&lt;br /&gt;
cannot just look at say, ah I know what it means). Another questionable advantage is it allows you to do id randomisation, so it hard to do crafted queries to &lt;br /&gt;
cheat, the down side of that you cannot understand it either, and handcraft db states for debugging or testing.&lt;br /&gt;
&lt;br /&gt;
=== Database for The card game ===&lt;br /&gt;
&lt;br /&gt;
Lets say you have a standard card game, player have hidden cards in hand, you can draw card from draw deck, play card on tableau and discard to discard pile.&lt;br /&gt;
We have to design database for such game.&lt;br /&gt;
&lt;br /&gt;
In real word to &amp;quot;save&amp;quot; the game we take a picture a play area, save cards from it, then put away draw deck, discard and hand of each player separately and mark it, also we will record current scoring (if any) and who&#039;s turn was it.&lt;br /&gt;
&lt;br /&gt;
* Framework handles state machine transition, so you don&#039;t have to worry about database design for that (i.e. who&#039;s turn it is, what phase of the game we are at, you still have to design it but part of state machine step)&lt;br /&gt;
* Also framework supports basic player information, color, order around the table, basic scoring, etc, so you don&#039;t have to worry about it either&lt;br /&gt;
* The only thing you need in our database is state of the &amp;quot;board&amp;quot;, which is &amp;quot;where each pieces is, and in what state&amp;quot;, or (position,rotation) pair.&lt;br /&gt;
&lt;br /&gt;
Lets see what we have for that:&lt;br /&gt;
* The card state is very simple, its usually &amp;quot;face up/face down&amp;quot;, &amp;quot;tapped/untapped&amp;quot;, &amp;quot;right side up/up side down&amp;quot;&lt;br /&gt;
* As position go we never need real coordinates x,y,z. We need to know what &amp;quot;zone&amp;quot; card was, and depending on the zone it may sometimes need an extra &amp;quot;z&amp;quot; or &amp;quot;x&amp;quot; as card order. The zone position usually static or irrelevant.&lt;br /&gt;
* So our model is: we have cards, which have some attributes, at any given point in time they belong to a &amp;quot;zone&amp;quot;, and can also have order and state&lt;br /&gt;
* Now for mapping we should consider what information changes and what information is static, later is always candidate for material file&lt;br /&gt;
* For dynamic information we should try to reduce amount of fields we need&lt;br /&gt;
**  we need at least a field for card, so its one&lt;br /&gt;
**  we need to know what zone cards belong to, its 2&lt;br /&gt;
**  and we have possibly few other fields, if you look closely at you game you may find out that most of the zone only need one attribute at a time, i.e. draw pile always have cards face down, hand always face up, also for hand and discard order does not matter at all (but for draw it does matter). So in majority of cases we can get away with one single extra integer field representing state or order&lt;br /&gt;
* In real database both card and zone will be integers as primary keys referring to additional tables, but in our case its total overkill, so they can be strings as easily&lt;br /&gt;
&lt;br /&gt;
Variant 1: Minimalistic&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE TABLE IF NOT EXISTS `card` (&lt;br /&gt;
  `card_key` varchar(32) unsigned NOT NULL,&lt;br /&gt;
  `card_location` varchar(32) NOT NULL,&lt;br /&gt;
  `card_state` int(11) NOT NULL,&lt;br /&gt;
  PRIMARY KEY (`card_id`)&lt;br /&gt;
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Variant 2: More normalised&lt;br /&gt;
&lt;br /&gt;
This version supported by Deck php class, so unless you want to rewrite db access layer go with this one&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE TABLE IF NOT EXISTS `card` (&lt;br /&gt;
  `card_id` int(10) unsigned NOT NULL AUTO_INCREMENT,&lt;br /&gt;
  `card_type` varchar(16) NOT NULL,&lt;br /&gt;
  `card_type_arg` int(11) NOT NULL,&lt;br /&gt;
  `card_location` varchar(16) NOT NULL,&lt;br /&gt;
  `card_location_arg` int(11) NOT NULL,&lt;br /&gt;
  PRIMARY KEY (`card_id`)&lt;br /&gt;
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: if you using this schema, some zones/locations have special semantic. The &#039;hand&#039; location is actually multiple locations - one per player, but player id is encoded as card_location_arg. If &#039;hand&#039; in your game is ordered, visible or can have some other card states, you cannot use hand location (replacement is hand_&amp;lt;player_id&amp;gt; or hand_&amp;lt;color_id&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
== Code Organization ==&lt;br /&gt;
&lt;br /&gt;
=== Including your own JavaScript module ===&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, modules/ggg_other.js&lt;br /&gt;
&lt;br /&gt;
* Create ggg_other.js in modules/ folder and sync&lt;br /&gt;
* Modify ggg.js to include it&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  define([ &amp;quot;dojo&amp;quot;, &amp;quot;dojo/_base/declare&amp;quot;, &amp;quot;ebg/core/gamegui&amp;quot;, &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
    // load my own module!!!&lt;br /&gt;
    g_gamethemeurl + &amp;quot;modules/ggg_other.js&amp;quot; ], function(dojo,&lt;br /&gt;
        declare) {&lt;br /&gt;
&lt;br /&gt;
=== Including your own JavaScript module (II) ===&lt;br /&gt;
&lt;br /&gt;
* Create ggg_other.js in modules/ folder and sync&lt;br /&gt;
&lt;br /&gt;
  define([], function () {&lt;br /&gt;
    return &amp;quot;value&amp;quot;;&lt;br /&gt;
  });&lt;br /&gt;
&lt;br /&gt;
* Modify ggg.js to include it&lt;br /&gt;
&lt;br /&gt;
  define([ &lt;br /&gt;
    &amp;quot;dojo&amp;quot;, &lt;br /&gt;
    &amp;quot;dojo/_base/declare&amp;quot;, &lt;br /&gt;
    &amp;quot;bgagame/modules/ggg_other&amp;quot;, &lt;br /&gt;
    &amp;quot;ebg/core/gamegui&amp;quot;, &lt;br /&gt;
    &amp;quot;ebg/counter&amp;quot;&lt;br /&gt;
  ], function(dojo, declare, other) {&lt;br /&gt;
  &lt;br /&gt;
  });&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
This is maybe a little bit more the idea of the AMD Loader than the first option, although the first option should work as well.&lt;br /&gt;
&lt;br /&gt;
A little explanation to this:&lt;br /&gt;
The define function loads all the modules listed in the array and calls the following function with these loaded modules as parameters.&lt;br /&gt;
By putting your module at the third position in the array it is passed as the third parameter to the function. Be aware that the modules are resolved by position only, not by name. So you can load the module &#039;&#039;&#039;ggg_other&#039;&#039;&#039; and pass it as a parameter with the name &#039;&#039;&#039;other&#039;&#039;&#039;. &#039;&#039;&#039;gamegui&#039;&#039;&#039; and &#039;&#039;&#039;counter&#039;&#039;&#039; are passed in as well, but when the parameters are not defined they are just skipped. Because these modules put their content into the global scope it does not matter and you can use them from there.&lt;br /&gt;
&lt;br /&gt;
In the example above the string &amp;quot;value&amp;quot; is passed for the parameter &#039;&#039;&#039;other&#039;&#039;&#039;, but the function in your module can return whatever you want. It can be an object, an array, something you declared with dojo.declare, you can return even functions. &lt;br /&gt;
Your module can load other modules. Just put them in the array at the beginning and pass them as parameters to your function.&lt;br /&gt;
The advantage of passing the values as parameter is that you do not need to put these values in the global scope, so they can&#039;t be collisions with values defined in other scripts or the BGA Framework.&lt;br /&gt;
&lt;br /&gt;
The dojo toolkit provides good documentation to all of its components, the complete documentation for the AMD-Loader is here:&lt;br /&gt;
https://dojotoolkit.org/documentation/tutorials/1.10/modules/index.html It should be still correct, even as it seems to be only for version 1.10&lt;br /&gt;
&lt;br /&gt;
=== Including your own PHP module ===&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.game.php, modules/ggg_other.php&lt;br /&gt;
&lt;br /&gt;
* Create ggg_other.php in modules/ folder and sync&lt;br /&gt;
* Modify ggg.game.php to include it&lt;br /&gt;
&lt;br /&gt;
 require_once (&#039;modules/ggg_other.php&#039;);&lt;br /&gt;
&lt;br /&gt;
=== Creating a test class to run PHP locally ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.game.php, stubs&lt;br /&gt;
For this you need stubs of other method you can use this for example&lt;br /&gt;
https://github.com/elaskavaia/bga-sharedcode/raw/master/misc/module/table/table.game.php&lt;br /&gt;
&lt;br /&gt;
Create another php files, i.e ggg_test.php&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
define(&amp;quot;APP_GAMEMODULE_PATH&amp;quot;, &amp;quot;misc/&amp;quot;); // include path to stubs, which defines &amp;quot;table.game.php&amp;quot; and other classes&lt;br /&gt;
require_once (&#039;eminentdomaine.game.php&#039;);&lt;br /&gt;
&lt;br /&gt;
class MyGameTest1 extends MyGame { // this is your game class defined in ggg.game.php&lt;br /&gt;
    function __construct() {&lt;br /&gt;
        parent::__construct();&lt;br /&gt;
        include &#039;../material.inc.php&#039;;// this is how this normally included, from constructor&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // override/stub methods here that access db and stuff&lt;br /&gt;
    function getGameStateValue($var) {&lt;br /&gt;
        if ($var == &#039;round&#039;)&lt;br /&gt;
            return 3;&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
$x = new MyGameTest1(); // instantiate your class&lt;br /&gt;
$p = $x-&amp;gt;getGameProgression(); // call one of the methods to test&lt;br /&gt;
if ($p != 50)&lt;br /&gt;
    echo &amp;quot;Test1: FAILED&amp;quot;;&lt;br /&gt;
else&lt;br /&gt;
    echo &amp;quot;Test1: PASSED&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Run from command line like&lt;br /&gt;
 php7 ggg_test.php&lt;br /&gt;
&lt;br /&gt;
If you do it this way - you can also use local php debugger (i.e. integrated with IDE or command line).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Avoiding code in dojo declare style ===&lt;br /&gt;
Dojo class declarations are rather bizzare and do not work with most IDEs.&lt;br /&gt;
If you want to write in plain JS with classes, you can stub all the dojo define/declare stuff&lt;br /&gt;
and hook your class into that, so the classes are outside of this mess.&lt;br /&gt;
&lt;br /&gt;
NOTE: this technique is for experienced developers, do not try it if you do not understand&lt;br /&gt;
the consequences.&lt;br /&gt;
&lt;br /&gt;
This is complete example of game .js class&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  // Testla is game name is has to be changed&lt;br /&gt;
class Testla {&lt;br /&gt;
	constructor(game) {&lt;br /&gt;
		console.log(&#039;game constructor&#039;);&lt;br /&gt;
		this.game = game;&lt;br /&gt;
		this.varfoo = new MyFoo(); // this example of class from custom module&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	setup(gamedatas) {&lt;br /&gt;
		console.log(&amp;quot;Starting game setup&amp;quot;, this.varfoo);&lt;br /&gt;
		this.gamedatas = gamedatas;&lt;br /&gt;
		this.dojo.create(&amp;quot;div&amp;quot;, { class: &#039;whiteblock&#039;, innerHTML: _(&amp;quot;hello&amp;quot;) }, &#039;thething&#039;);&lt;br /&gt;
		console.log(&amp;quot;Ending game setup&amp;quot;);&lt;br /&gt;
	};&lt;br /&gt;
	onEnteringState(stateName, args) {&lt;br /&gt;
		console.log(&#039;onEnteringState : &#039; + stateName, args);&lt;br /&gt;
		this.game.addActionButton(&#039;b1&#039;,_(&#039;Click Me&#039;), (e)=&amp;gt;this.onButtonClick(e));&lt;br /&gt;
	};&lt;br /&gt;
	onLeavingState(stateName) {&lt;br /&gt;
		console.log(&#039;onLeavingState : &#039; + stateName, args);&lt;br /&gt;
	};&lt;br /&gt;
	onUpdateActionButtons(stateName, args) {&lt;br /&gt;
		console.log(&#039;onUpdateActionButtons : &#039; + stateName, args);&lt;br /&gt;
	};&lt;br /&gt;
	onButtonClick(event) {&lt;br /&gt;
		console.log(&#039;onButtonClick&#039;,event);&lt;br /&gt;
	};&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&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;
	g_gamethemeurl + &#039;/modules/foo.js&#039; // custom module if needed&lt;br /&gt;
],&lt;br /&gt;
	function(dojo, declare) {&lt;br /&gt;
                // testla is game name is has to be changed&lt;br /&gt;
		return declare(&amp;quot;bgagame.testla&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
			constructor: function() {&lt;br /&gt;
				this.xapp = new Testla(this);&lt;br /&gt;
				this.xapp.dojo = dojo;&lt;br /&gt;
			},&lt;br /&gt;
			setup: function(gamedatas) {&lt;br /&gt;
				this.xapp.setup(gamedatas);&lt;br /&gt;
			},&lt;br /&gt;
			onEnteringState: function(stateName, args) {&lt;br /&gt;
				this.xapp.onEnteringState(stateName, args.args);&lt;br /&gt;
			},&lt;br /&gt;
			onLeavingState: function(stateName) {&lt;br /&gt;
				this.xapp.onLeavingState(stateName, args);&lt;br /&gt;
			},&lt;br /&gt;
			onUpdateActionButtons: function(stateName, args) {&lt;br /&gt;
				this.xapp.onUpdateActionButtons(stateName, args);&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;
=== More readable JS: onEnteringState ===&lt;br /&gt;
&lt;br /&gt;
If you have a lot of states onEnteringState and friends become rather wild, you can do this trick to call some method dynamically.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
     onEnteringState: function(stateName, args) {&lt;br /&gt;
       console.log(&#039;Entering state: &#039; + stateName, args);&lt;br /&gt;
&lt;br /&gt;
       // Call appropriate method&lt;br /&gt;
       var methodName = &amp;quot;onEnteringState_&amp;quot; + stateName;&lt;br /&gt;
       if (this[methodName] !== undefined) {             &lt;br /&gt;
          console.log(&#039;Calling &#039; + methodName, args.args);&lt;br /&gt;
          this[methodName](args.args);&lt;br /&gt;
       }&lt;br /&gt;
     },&lt;br /&gt;
&lt;br /&gt;
     onEnteringState_playerTurn: function(args) { // this is args directly, not args.args &lt;br /&gt;
         // process&lt;br /&gt;
     },&lt;br /&gt;
&lt;br /&gt;
     onEnteringState_playerSomethingElse: function(args) { &lt;br /&gt;
         // process&lt;br /&gt;
     },&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: since its ignores the undefined functions you don&#039;t have define function for each state, but on the other hand you cannot make typos.&lt;br /&gt;
Same applies to onUpdateActionButtons except you pass &#039;args&#039; to method, not args.args, and for onLeavingState where you don&#039;t pass anything.&lt;br /&gt;
&lt;br /&gt;
=== Frameworks and Preprocessors ===&lt;br /&gt;
&lt;br /&gt;
* [[Using Vue]] - work-in-progress guide on using the modern framework Vue.js to create a game&lt;br /&gt;
* [[Using Typescript and Scss]] - How to auto-build Typescript and SCSS files to make your code cleaner&lt;br /&gt;
&lt;br /&gt;
== Assorted Stuff ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Out-of-turn actions: Un-pass ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js, ggg.game.php, ggg.action.php, states.inc.php&lt;br /&gt;
&lt;br /&gt;
In multiplayer game sometimes players passes but than they think more and want to un-Pass and redo their choice. &lt;br /&gt;
To re-active a player who passes some trickery required.&lt;br /&gt;
&lt;br /&gt;
Define a special action that does that and hook it up.&lt;br /&gt;
&lt;br /&gt;
In states.inc.php add an action to mmultipleactiveplayer state to &amp;quot;unpass&amp;quot;, lets call it &amp;quot;actionCancel&amp;quot;&lt;br /&gt;
&lt;br /&gt;
In ggg.action.php add action hook&lt;br /&gt;
    public function actionCancel() {&lt;br /&gt;
        self::setAjaxMode();&lt;br /&gt;
        $this-&amp;gt;game-&amp;gt;actionCancel();&lt;br /&gt;
        self::ajaxResponse();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
In ggg.game.php add action handler&lt;br /&gt;
    function actionCancel() {&lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;checkPossibleAction(&#039;actionCancel&#039;);&lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;setPlayersMultiactive(array ($this-&amp;gt;getCurrentPlayerId() ), &#039;error&#039;, false);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
Finally to call this in client ggg.js you would do something like:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 onUpdateActionButtons:  function(stateName, args) {&lt;br /&gt;
   if (this.isCurrentPlayerActive()) { &lt;br /&gt;
     // ...&lt;br /&gt;
   } else if (!this.isSpectator) { // player is NOT active but not spectator&lt;br /&gt;
       switch (stateName) {&lt;br /&gt;
          case &#039;playerTurnMuliPlayerState&#039;:&lt;br /&gt;
		this.addActionButton(&#039;button_unpass&#039;, _(&#039;Oh no!&#039;), &#039;onUnpass&#039;);&lt;br /&gt;
		break;&lt;br /&gt;
	}&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
				&lt;br /&gt;
 onUnpass: function(e) {&lt;br /&gt;
    this.ajaxcall(&amp;quot;/&amp;quot; + this.game_name + &amp;quot;/&amp;quot; +  this.game_name + &amp;quot;/actionCancel.html&amp;quot;, {}, this); // no checkAction!&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Although be careful that if the turn comes back to the player while he is about to click cancel, the action buttons will be updated and the player will misclick which can be quite frustrating. To avoid this, move the cancel button to another position, like to the left of pagemaintitletext:&lt;br /&gt;
  dojo.place(&#039;button_unpass&#039;, &#039;pagemaintitletext&#039;, &#039;before&#039;);&lt;br /&gt;
Being out of the generalactions div, it won&#039;t be automatically destroyed like normal buttons, so you&#039;ll have to handle that yourself in onLeavingState. You might also want to change the button color to red (blue buttons for active player only, red buttons also for inactive players?)&lt;br /&gt;
&lt;br /&gt;
Note: same technique can be used to do other out-of-turn actions, such as re-arranging cards in hand, exchanging resources, etc (i.e. if permitted by rules, such as &amp;quot;at any time player can...&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
=== Multi Step Interactions: Select Worker/Place Worker - Using Selection ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
Simple way to implement something like that without extra states is to use &amp;quot;selection&amp;quot; mechanism. When user click on worker add some sort of class into that element i.e. &#039;selected&#039; (which also have to have some indication by css i.e. outline).&lt;br /&gt;
&lt;br /&gt;
Than user can click on placement zone, you can use dojo.query for &amp;quot;selected&amp;quot; element and use it along with zone id to send data to server. If proper worker is not selected yet can give a error message using this.showMessage(...) function.&lt;br /&gt;
&lt;br /&gt;
Extra code required to properly cleanup selection between states.&lt;br /&gt;
Also when you do that sometimes you want to change the state prompt, see below &#039;Change state prompt&#039;&lt;br /&gt;
&lt;br /&gt;
=== Multi Step Interactions: Select Worker/Place Worker - Using Client States ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
I don&#039;t think its documented feature but there is a way to do client-only states, which is absolutely wonderful for few reasons&lt;br /&gt;
* When player interaction is two step process, such as select worker, place worker, or place worker, pick one of two resources of your choice&lt;br /&gt;
* When multi-step process can result of impossible situation and has to be undone (by rules)&lt;br /&gt;
* When multi-step process is triggered from multiple states (such as you can do same thing as activated card action, pass action or main action)&lt;br /&gt;
&lt;br /&gt;
So lets do Select Worker/Place Worker&lt;br /&gt;
&lt;br /&gt;
Define your server state as usual, i.e. playerMainTurn -&amp;gt; &amp;quot;You must pick up a worker&amp;quot;.&lt;br /&gt;
Now define a client state, we only need &amp;quot;name&amp;quot; and &amp;quot;descriptionmyturn&amp;quot;, lets say &amp;quot;client_playerPicksLocation&amp;quot;. Always prefix names of client state with &amp;quot;client_&amp;quot; to avoid confusion. Now we have to do the following:&lt;br /&gt;
* Have a handler for onUpdateActionButtons for playerMainTurn to activate all possible workers he can pick&lt;br /&gt;
* When player clicks workers, remember the worker in one of the members of the main class, I usually use one called this.clientStateArgs.&lt;br /&gt;
* Transition to new client state&lt;br /&gt;
  onWorker: function(e) {&lt;br /&gt;
      var id = event.currentTarget.id;&lt;br /&gt;
      dojo.stopEvent(event);&lt;br /&gt;
      ... // do validity checks&lt;br /&gt;
      this.clientStateArgs.worker_id = id;&lt;br /&gt;
      this.setClientState(&amp;quot;client_playerPicksLocation&amp;quot;, {&lt;br /&gt;
                                descriptionmyturn : _(&amp;quot;${you} must select location&amp;quot;),&lt;br /&gt;
                            });&lt;br /&gt;
   }&lt;br /&gt;
* Have a handler for onUpdateActionButtons for client_playerPicksLocation to activate all possible locations this worker can go AND add Cancel button (see below)&lt;br /&gt;
* Have a location handler which will eventually send a server request, using stored this.clientStateArgs.worker_id as worker id&lt;br /&gt;
* The cancel button should call a method to restore server state, also if you doing it for more than one state you can add this universally using this.on_client_state check&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        if (this.isCurrentPlayerActive()) {&lt;br /&gt;
          if (this.on_client_state &amp;amp;&amp;amp; !$(&#039;button_cancel&#039;)) {&lt;br /&gt;
               this.addActionButton(&#039;button_cancel&#039;, _(&#039;Cancel&#039;), dojo.hitch(this, function() {&lt;br /&gt;
                                             this.restoreServerGameState();&lt;br /&gt;
               }));&lt;br /&gt;
          }&lt;br /&gt;
        } &lt;br /&gt;
Note: usually I call my own function call this.cancelLocalStateEffects() which will do more stuff first then call restoreServerGameState(), same function is usually needs to be called when server request has failed (i.e. invalid move)&lt;br /&gt;
&lt;br /&gt;
Note: If you need more than 2 steps, you may have to do client side animation to reflect the new state, which gets trickier because you have to undo that also on cancellation.&lt;br /&gt;
&lt;br /&gt;
Code is available here [https://github.com/elaskavaia/bga-sharedcode/blob/master/sharedcode.js sharedcode.js] (its using playerTurnPlayCubes and client_selectCubeLocation).&lt;br /&gt;
&lt;br /&gt;
=== Action Stack - Using Client States ===&lt;br /&gt;
&lt;br /&gt;
Action stack required where game is very complex and use triggered effects that can &amp;quot;stack&amp;quot;. It not always actual stack, it can be queue or random access&lt;br /&gt;
Examples:&lt;br /&gt;
* Magic the Gathering - classic card game where effects go on Stack, that allows to counter spell and counter spell of counter spell (not on bga - it just example of mechanics)&lt;br /&gt;
* Ultimate Railroads - action taking game where effects can be executed in any order&lt;br /&gt;
* Lewis and Clark - card game where actions executed as queue&lt;br /&gt;
&lt;br /&gt;
There is two ways of implementing it - on the server or the client.&lt;br /&gt;
For the server see article below.&lt;br /&gt;
The requirement for client side stack is all action can be undone, which means&lt;br /&gt;
* No dice rolls&lt;br /&gt;
* No card drawn&lt;br /&gt;
* No other players interaction&lt;br /&gt;
&lt;br /&gt;
No snippets are here, as this will be too complex but basically flow is:&lt;br /&gt;
* You have a action/effect stack (queue/list) as js object attached to &amp;quot;this&amp;quot;, i.e. this.unprocessed_actions&lt;br /&gt;
* When player plays a card, worker, etc, you read the effect of that card from the material file (client copy), and place into stack&lt;br /&gt;
* Then we call dispatch method which pulls the next action from the stack and change client state accordinly,i.e.  this.setClientState(&amp;quot;client_playerGainsCubes&amp;quot;)&lt;br /&gt;
* When players acts on it - the action is removed from the stack and added to &amp;quot;server action arguments&amp;quot; list, this is another object which be used to send ajax call, i.e. this.clientStateArgs&lt;br /&gt;
* If nothing left in stack we can submit the ajax call assembling parameters from collected arguments (that can include action name)&lt;br /&gt;
* This method allows cheap undo - by restoring server state you will wipe out all user actions (but if you need intermediate aninmation you have to handle it yourself)&lt;br /&gt;
&lt;br /&gt;
Code can be found in Ultimate Railroads game (but it is random access list - so it a bit complex) and Lewis and Clark (complexity - use can always deny part of any effect)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Action Stack - Using Server States ===&lt;br /&gt;
&lt;br /&gt;
See definition of Action Stack above.&lt;br /&gt;
&lt;br /&gt;
To implement you usually need another db table that has the following fields: index of effect - which is used for sorted access, type - which is essense of the effect (i.e. collect resource), some extra arguments (i.e. resource type and resource count), and usually owner of the effect (i.e. player id)&lt;br /&gt;
The flow is:&lt;br /&gt;
* There is some initial player state, where player can play card for example&lt;br /&gt;
* Player main action - pushes the card effect on stack, which also can cause triggered effects which also go on stack&lt;br /&gt;
* After action processing is finished switch to game state which is &amp;quot;dispatcher&amp;quot;&lt;br /&gt;
* Gispatcher pulls the top effect (whatever definition of the top is), changes the active player and changes the state to appropriate player state to collect response&lt;br /&gt;
* Player state knows about the stack and pulls arguments (argX) from the effect arguments of the db&lt;br /&gt;
* Player action should clear up the top effect, and can possibly add more effects, then switch to &amp;quot;dispatcher&amp;quot; state again&lt;br /&gt;
* If stack is empty, dispatcher can either pick next player itself or use another game state which responsible for picking next player&lt;br /&gt;
&lt;br /&gt;
Code can be found in Tapestry.&lt;br /&gt;
&lt;br /&gt;
=== Changing state prompt ===&lt;br /&gt;
&lt;br /&gt;
State prompt is message displayed for player which usually comes from state description.&lt;br /&gt;
Sometimes you want to change it without changing state (one way is change state but locally, see client states above).&lt;br /&gt;
&lt;br /&gt;
Simple way just change the html&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        setMainTitle: function(text) {&lt;br /&gt;
            $(&#039;pagemaintitletext&#039;).innerHTML = text;&lt;br /&gt;
        },&lt;br /&gt;
         // usage&lt;br /&gt;
        onMeeple: function(event) {&lt;br /&gt;
              //... &lt;br /&gt;
              this.setMainTitle(_(&#039;You must select where meeple is going&#039;));&lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This however will not work with parameters and will not draw You in color, if you want this its more sophisticated:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        setDescriptionOnMyTurn : function(text) {&lt;br /&gt;
            this.gamedatas.gamestate.descriptionmyturn = text;&lt;br /&gt;
            var tpl = dojo.clone(this.gamedatas.gamestate.args);&lt;br /&gt;
            if (tpl === null) {&lt;br /&gt;
                tpl = {};&lt;br /&gt;
            }&lt;br /&gt;
            var title = &amp;quot;&amp;quot;;&lt;br /&gt;
            if (this.isCurrentPlayerActive() &amp;amp;&amp;amp; text !== null) {&lt;br /&gt;
                tpl.you = this.divYou(); &lt;br /&gt;
            }&lt;br /&gt;
            title = this.format_string_recursive(text, tpl);&lt;br /&gt;
&lt;br /&gt;
            if (!title) {&lt;br /&gt;
                this.setMainTitle(&amp;quot;&amp;amp;nbsp;&amp;quot;);&lt;br /&gt;
            } else {&lt;br /&gt;
                this.setMainTitle(title);&lt;br /&gt;
            }&lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: this method uses &#039;&#039;&#039;setMainTitle&#039;&#039;&#039; defined above and &#039;&#039;&#039;divYou&#039;&#039;&#039; defined in another section of this wiki.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Adding Image buttons ===&lt;br /&gt;
&lt;br /&gt;
Its pretty trivial but just in case you need a working function:&lt;br /&gt;
&lt;br /&gt;
ggg.js:&lt;br /&gt;
&lt;br /&gt;
                addImageActionButton: function (id, div_html, handler) { // div_html is string not node&lt;br /&gt;
                    this.addActionButton(id, div_html, handler, &#039;&#039;, false, &#039;gray&#039;); &lt;br /&gt;
                    dojo.style(id, &amp;quot;border&amp;quot;, &amp;quot;none&amp;quot;); // remove ugly border&lt;br /&gt;
                    dojo.addClass(id, &amp;quot;bgaimagebutton&amp;quot;); // add css class to do more styling&lt;br /&gt;
                    return $(id); // return node for chaining&lt;br /&gt;
                },&lt;br /&gt;
&lt;br /&gt;
Example of usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    this.addImageActionButton(&#039;button_coin&#039;,&amp;quot;&amp;lt;div class=&#039;coin&#039;&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;, ()=&amp;gt;{ alert(&#039;Ha!&#039;); });&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Assigning Player Order ===&lt;br /&gt;
Normally when game starts there is &amp;quot;natural&amp;quot; player order assigned randomly.&lt;br /&gt;
&lt;br /&gt;
If you want to deliberatly assign player order at the start of the game (for example, in a game with teams options), you can do so by retrieving the initialization-only player attribute &#039;&#039;&#039;player_table_order&#039;&#039;&#039; and using it to assign values to &#039;&#039;&#039;player_no&#039;&#039;&#039; (which is normally assigned at the start of a game in the order in which players come to the table). (See [https://en.doc.boardgamearena.com/Game_database_model:_dbmodel.sql#The_player_table Game database model] for more details.)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Example:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                // Retrieve inital player order ([0=&amp;gt;playerId1, 1=&amp;gt;playerId2, ...])&lt;br /&gt;
		$playerInitialOrder = [];&lt;br /&gt;
		foreach ($players as $playerId =&amp;gt; $player) {&lt;br /&gt;
			$playerInitialOrder[$player[&#039;player_table_order&#039;]] = $playerId;&lt;br /&gt;
		}&lt;br /&gt;
		ksort($playerInitialOrder);&lt;br /&gt;
		$playerInitialOrder = array_flip(array_values($playerInitialOrder));&lt;br /&gt;
&lt;br /&gt;
		// Player order based on &#039;playerTeams&#039; option&lt;br /&gt;
		$playerOrder = [0, 1, 2, 3];&lt;br /&gt;
		switch (self::getGameStateValue(&#039;playerTeams&#039;)) {&lt;br /&gt;
			case self::TEAM_1_2:&lt;br /&gt;
				$playerOrder = [0, 2, 1, 3];&lt;br /&gt;
				break;&lt;br /&gt;
			case self::TEAM_1_4:&lt;br /&gt;
				$playerOrder = [0, 1, 3, 2];&lt;br /&gt;
				break;&lt;br /&gt;
			case self::TEAM_RANDOM:&lt;br /&gt;
				shuffle($playerOrder);&lt;br /&gt;
				break;&lt;br /&gt;
			default:&lt;br /&gt;
			case self::TEAM_1_3:&lt;br /&gt;
				// Default order&lt;br /&gt;
				break;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
                // Create players&lt;br /&gt;
		// Note: if you added some extra field on &amp;quot;player&amp;quot; table in the database (dbmodel.sql), you can initialize it there.&lt;br /&gt;
		$sql =&lt;br /&gt;
			&#039;INSERT INTO player (player_id, player_color, player_canal, player_name, player_avatar, player_no) VALUES &#039;;&lt;br /&gt;
		$values = [];&lt;br /&gt;
&lt;br /&gt;
		foreach ($players as $playerId =&amp;gt; $player) {&lt;br /&gt;
			$color = array_shift($default_colors);&lt;br /&gt;
			$values[] =&lt;br /&gt;
				&amp;quot;(&#039;&amp;quot; .&lt;br /&gt;
				$playerId .&lt;br /&gt;
				&amp;quot;&#039;,&#039;$color&#039;,&#039;&amp;quot; .&lt;br /&gt;
				$player[&#039;player_canal&#039;] .&lt;br /&gt;
				&amp;quot;&#039;,&#039;&amp;quot; .&lt;br /&gt;
				addslashes($player[&#039;player_name&#039;]) .&lt;br /&gt;
				&amp;quot;&#039;,&#039;&amp;quot; .&lt;br /&gt;
				addslashes($player[&#039;player_avatar&#039;]) .&lt;br /&gt;
				&amp;quot;&#039;,&#039;&amp;quot; .&lt;br /&gt;
				$playerOrder[$playerInitialOrder[$playerId]] .&lt;br /&gt;
				&amp;quot;&#039;)&amp;quot;;&lt;br /&gt;
		}&lt;br /&gt;
		$sql .= implode(&#039;,&#039;, $values);&lt;br /&gt;
		self::DbQuery($sql);&lt;br /&gt;
		self::reattributeColorsBasedOnPreferences(&lt;br /&gt;
			$players,&lt;br /&gt;
			$gameinfos[&#039;player_colors&#039;]&lt;br /&gt;
		);&lt;br /&gt;
		self::reloadPlayersBasicInfos();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Send different notifications to active player vs everybody else ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
Hack alert. This is a hack. We were hoping for proper solution by bga framework.&lt;br /&gt;
&lt;br /&gt;
This will allow you to send notification with two message one for specific player and one for everybody else including spectators.&lt;br /&gt;
Note that this does not split the data - all data must be shared.&lt;br /&gt;
&lt;br /&gt;
Add this to .js file (if you already overriding it merge obviously)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/** @Override */&lt;br /&gt;
format_string_recursive: function(log, args) {&lt;br /&gt;
   if (typeof args.log_others != &#039;undefined&#039; &amp;amp;&amp;amp; typeof args.player_id != &#039;undefined&#039; &amp;amp;&amp;amp; this.player_id != args.player_id)&lt;br /&gt;
	log = args.log_others;&lt;br /&gt;
   return this.inherited(arguments); // you must call this to call super &lt;br /&gt;
},&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example of usage (from eminentdomain)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    $this-&amp;gt;notifyAllPlayers(&#039;tokenMoved&#039;, &lt;br /&gt;
             clienttranslate(&#039;${player_name} adds +2 Colonies to ${place_name}&#039;), // notification with show for player with player_id&lt;br /&gt;
             [&#039;player_id&#039;=&amp;gt;$player_id, // this is mandatory&lt;br /&gt;
             &#039;log_others&#039;=&amp;gt;clienttranslate(&#039;${player_name} adds +2 Colonies to an unknown planet&#039;), // notification will show for others&lt;br /&gt;
              ...&lt;br /&gt;
             ]);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Send transient notifications without incrementing move ID ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.php&lt;br /&gt;
&lt;br /&gt;
Hack alert. This is a hack.&lt;br /&gt;
&lt;br /&gt;
Use this if you need to send some transient notification that should not create a new move ID. The notification should be idempotent -- it should have no practical effect on the game state and would be &#039;&#039;&#039;safe to drop&#039;&#039;&#039; (e.g., it would not matter if a player never received this notification). For example, in a co-op game you want all players to see a real-time preview of some action, before the active player commits their turn.&lt;br /&gt;
&lt;br /&gt;
Doing this mainly affects the instant replay &amp;amp; archive modes. During replay, the BGA framework automatically inserts a 1.5-second pause between each &amp;quot;move&amp;quot;. With this hack, your transient notifications are not considered to be a &amp;quot;move&amp;quot;, so no pause gets added.&lt;br /&gt;
&lt;br /&gt;
; In ggg.php&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$this-&amp;gt;not_a_move_notification = true; // note: do not increase the move counter&lt;br /&gt;
$this-&amp;gt;notifyAllPlayers(&#039;cardsPreview&#039;, &#039;&#039;, $args);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: you cannot have code that send notification or even changes state after this, and you cannot reset this variable back either because it only takes effect when you exit action handling function&lt;br /&gt;
&lt;br /&gt;
=== Ajax Call wrapper ===&lt;br /&gt;
&#039;&#039;&#039;Ingredients:&#039;&#039;&#039; ggg.js&lt;br /&gt;
&lt;br /&gt;
The current ajaxcall is super vebose and prone to errors, I suggest using a helper function. It does a lot of stuff you must do anyways.&lt;br /&gt;
Most beginner mistakes come from missing part of this code (which is understandstandable - this is a huge snippet to clone every time).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	ajaxcallwrapper: function(action, args, handler) {&lt;br /&gt;
		if (!args) args = []; // this allows to skip args parameter for action which do not require them&lt;br /&gt;
			&lt;br /&gt;
		args.lock = true; // this allows to avoid rapid action clicking which can cause race condition on server&lt;br /&gt;
		if (this.checkAction(action)) { // this does all the proper check that player is active and action is declared&lt;br /&gt;
			this.ajaxcall(&amp;quot;/&amp;quot; + this.game_name + &amp;quot;/&amp;quot; + this.game_name + &amp;quot;/&amp;quot; + action + &amp;quot;.html&amp;quot;, args, // this is mandatory fluff &lt;br /&gt;
				this, (result) =&amp;gt; { },  // success result handler is empty - it is never needed&lt;br /&gt;
                                               handler); // this is real result handler - it called both on success and error, it has optional param  &amp;quot;is_error&amp;quot; - you rarely need it&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   this.ajaxcallwrapper(&#039;pass&#039;); // no args&lt;br /&gt;
   this.ajaxcallwrapper(&#039;playCard&#039;, {card: card_id}); // with args&lt;br /&gt;
   this.ajaxcallwrapper(&#039;playCard&#039;, {card: card_id}, (is_error)=&amp;gt;{if (!is_error) dojo.query(&amp;quot;.selected&amp;quot;).removeClass(&#039;selected&#039;);}) // with handler that cleans up &#039;selected&#039; class on success&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: this always will lock interface and always check for action, you can modify this method to do it optionally, i.e&lt;br /&gt;
  if (args.lock!==false) args.lock = true; else delete args.lock; // it does not work with false value - it has to be removed&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Studio]]&lt;/div&gt;</summary>
		<author><name>SwHawk</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Main_game_logic:_Game.php&amp;diff=13960</id>
		<title>Main game logic: Game.php</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Main_game_logic:_Game.php&amp;diff=13960"/>
		<updated>2022-07-12T19:17:03Z</updated>

		<summary type="html">&lt;p&gt;SwHawk: /* Use globals */ added $this to method name&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Studio_Framework_Navigation}}&lt;br /&gt;
&lt;br /&gt;
This is the main file for your game logic. Here you initialize the game, persist data, implement the rules and notify the client interface of changes.&lt;br /&gt;
&lt;br /&gt;
== File Structure ==&lt;br /&gt;
&lt;br /&gt;
The details of how the file is structured are described directly with comments in the code skeleton provided to you.&lt;br /&gt;
 &lt;br /&gt;
Here is the basic structure:&lt;br /&gt;
&lt;br /&gt;
* Constructor: where you define global variables.&lt;br /&gt;
* setupNewGame: initial setup of the game. Takes an array of players, indexed by player_id. Structure of each player includes player_name, player_canal, player_avatar, and flags indicating admin/ai/premium/order/language/beginner.&lt;br /&gt;
* getAllDatas: where you retrieve all game data during a complete reload of the game. Return value must be associative array. Value of &#039;players&#039; is reserved for returning players data from players table, if you set it it must follow certain rules &lt;br /&gt;
        $result [&#039;players&#039;] = self::getCollectionFromDb(&amp;quot;SELECT player_id id, player_score score, player_no no, player_color color FROM player&amp;quot;);&lt;br /&gt;
        // Returned value must include [&#039;players&#039;][$player_id]][&#039;score&#039;] for scores to populate when F5 is pressed.&lt;br /&gt;
* getGameProgression: where you compute the game progression indicator. Returns a number indicating percent of progression (0-100)&lt;br /&gt;
* Utility functions: your utility functions.&lt;br /&gt;
* Player actions: the entry points for players actions ([https://en.doc.boardgamearena.com/Players_actions:_yourgamename.action.php more info here]). &lt;br /&gt;
* Game state arguments: methods to return additional data on specific game states ([http://en.doc.boardgamearena.com/Your_game_state_machine:_states.inc.php#args more info here]).&lt;br /&gt;
* Game state actions: the logic to run when entering a new game state ([http://en.doc.boardgamearena.com/Your_game_state_machine:_states.inc.php#action more info here]).&lt;br /&gt;
* zombieTurn: what to do it&#039;s the turn of a zombie player.&lt;br /&gt;
* upgradeTableDb: function to migrate database if you change it after release on production.&lt;br /&gt;
&lt;br /&gt;
== Accessing player information ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important&#039;&#039;&#039;: In the following methods, be mindful of the difference between the &amp;quot;active&amp;quot; player and the &amp;quot;current&amp;quot; player. The &#039;&#039;&#039;active&#039;&#039;&#039; player is the player whose turn it is - not necessarily the player who sent a request! The &#039;&#039;&#039;current&#039;&#039;&#039; player is the player who sent the request and will see the results returned by your methods: not necessarily the player whose turn it is!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; getPlayersNumber()&lt;br /&gt;
: Returns the number of players playing at the table&lt;br /&gt;
: Note: doesn&#039;t work in setupNewGame (use count($players) instead).&lt;br /&gt;
&lt;br /&gt;
; getActivePlayerId()&lt;br /&gt;
: Get the &amp;quot;active_player&amp;quot;, whatever what is the current state type.&lt;br /&gt;
: Note: it does NOT mean that this player is active right now, because state type could be &amp;quot;game&amp;quot; or &amp;quot;multiplayer&amp;quot;&lt;br /&gt;
: Note: avoid using this method in a &amp;quot;multiplayer&amp;quot; state because it does not mean anything.&lt;br /&gt;
&lt;br /&gt;
; getActivePlayerName()&lt;br /&gt;
: Get the &amp;quot;active_player&amp;quot; name&lt;br /&gt;
: Note: avoid using this method in a &amp;quot;multiplayer&amp;quot; state because it does not mean anything.&lt;br /&gt;
&lt;br /&gt;
; getPlayerNameById($player_id)&lt;br /&gt;
: Get the name by id&lt;br /&gt;
&lt;br /&gt;
; getPlayerColorById($player_id)&lt;br /&gt;
: Get the color by id&lt;br /&gt;
&lt;br /&gt;
; getPlayerNoById($player_id)&lt;br /&gt;
: Get &#039;player_no&#039; (number) by id&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; loadPlayersBasicInfos()&lt;br /&gt;
: Get an associative array with generic data about players (ie: not game specific data).&lt;br /&gt;
: The key of the associative array is the player id. The returned table is cached, so ok to call multiple times without performance concerns.&lt;br /&gt;
: &amp;lt;code&amp;gt;array_keys($this-&amp;gt;loadPlayersBasicInfos())&amp;lt;/code&amp;gt; will therefore returns an array containing players id&lt;br /&gt;
: The content of each value is:&lt;br /&gt;
: * player_name - the name of the player&lt;br /&gt;
: * player_color (ex: ff0000) - the color code of the player&lt;br /&gt;
: * player_no - the position of the player at the start of the game in natural table order, i.e. 1,2,3&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                $players = $this-&amp;gt;loadPlayersBasicInfos();&lt;br /&gt;
                foreach ($players as $player_id =&amp;gt; $info) {&lt;br /&gt;
                    $player_color = $info[&#039;player_color&#039;];&lt;br /&gt;
                    ...&lt;br /&gt;
                }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: if you want array of player ids only you can do this:&lt;br /&gt;
    $player_ids =  array_keys($this-&amp;gt;loadPlayersBasicInfos());  &lt;br /&gt;
&lt;br /&gt;
; getCurrentPlayerId()&lt;br /&gt;
: Get the &amp;quot;current_player&amp;quot;. The current player is the one from which the action originated (the one who sent the request).&lt;br /&gt;
: &#039;&#039;&#039;Be careful&#039;&#039;&#039;: This is not necessarily the active player!&lt;br /&gt;
: In general, you shouldn&#039;t use this method, unless you are in &amp;quot;multiplayer&amp;quot; state.&lt;br /&gt;
: &#039;&#039;&#039;Very important&#039;&#039;&#039;: in your setupNewGame and zombieTurn function, you must never use getCurrentPlayerId() or getCurrentPlayerName(), otherwise it will fail with a &amp;quot;Not logged&amp;quot; error message (these actions are triggered from the main site and propagated to the gameserver from a server, not from a browser. As a consequence, there is no current player associated to these actions).&lt;br /&gt;
&lt;br /&gt;
; getCurrentPlayerName()&lt;br /&gt;
: Get the &amp;quot;current_player&amp;quot; name&lt;br /&gt;
: Be careful using this method (see above).&lt;br /&gt;
&lt;br /&gt;
; getCurrentPlayerColor()&lt;br /&gt;
: Get the &amp;quot;current_player&amp;quot; color&lt;br /&gt;
: Be careful using this method (see above).&lt;br /&gt;
&lt;br /&gt;
; isCurrentPlayerZombie()&lt;br /&gt;
: Check the &amp;quot;current_player&amp;quot; zombie status. If true, player is zombie, i.e. left or was kicked out of the game.&lt;br /&gt;
&lt;br /&gt;
; isSpectator()&lt;br /&gt;
: Check the &amp;quot;current_player&amp;quot; spectator status. If true, the user accessing the game is a spectator (not part of the game). For this user, the interface should display all public information, and no private information (like a friend sitting at the same table as players and just spectating the game).&lt;br /&gt;
&lt;br /&gt;
; getActivePlayerColor()&lt;br /&gt;
: This function does not seems to exist in API, if you need it here is implementation&lt;br /&gt;
      function getActivePlayerColor() {&lt;br /&gt;
        $player_id = self::getActivePlayerId();&lt;br /&gt;
        $players = self::loadPlayersBasicInfos();&lt;br /&gt;
        if (isset($players[$player_id]))&lt;br /&gt;
            return $players[$player_id][&#039;player_color&#039;];&lt;br /&gt;
        else&lt;br /&gt;
            return null;&lt;br /&gt;
    }&lt;br /&gt;
; isPlayerZombie($player_id)&lt;br /&gt;
: This method does not exists, but if you need it it looks like this&lt;br /&gt;
    protected function isPlayerZombie($player_id) {&lt;br /&gt;
        $players = self::loadPlayersBasicInfos();&lt;br /&gt;
        if (! isset($players[$player_id]))&lt;br /&gt;
            throw new BgaSystemException(&amp;quot;Player $player_id is not playing here&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        return ($players[$player_id][&#039;player_zombie&#039;] == 1);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
== Accessing the database ==&lt;br /&gt;
&lt;br /&gt;
The main game logic should be the only point from which you should access the game database. You access your database using SQL queries with the methods below.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;IMPORTANT&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
BGA uses [http://dev.mysql.com/doc/refman/5.0/en/sql-syntax-transactions.html database transactions]. This means that your database changes WON&#039;T BE APPLIED to the database until your request ends normally (web request, not database request). Using transactions is in fact very useful for you; at any time, if your game logic detects that something is wrong (example: a disallowed move), you just have to throw an exception and all changes to the game situation will be removed. This also means that you need not (and in fact cannot) use your own transactions for multiple related database operations.&lt;br /&gt;
&lt;br /&gt;
However there are sets of database operation that initite implicit commit (most common mistake is to use &amp;quot;TRUNCATE&amp;quot;), you cannot use these operations during the game, it breaks the unrolling of transactions and will lead to nasty issues&lt;br /&gt;
(https://mariadb.com/kb/en/sql-statements-that-cause-an-implicit-commit).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; DbQuery( $sql )&lt;br /&gt;
: This is the generic method to access the database.&lt;br /&gt;
: It can execute any type of SELECT/UPDATE/DELETE/REPLACE/INSERT query on the database.&lt;br /&gt;
: For SELECT queries, the specialized methods below are much better.&lt;br /&gt;
: Do not use method for TUNCATE, DROP and other table altering operations. See disclamer above about implicit commits. If you really need TRUNCATE use DELETE FROM xxx instead.&lt;br /&gt;
&lt;br /&gt;
; getUniqueValueFromDB( $sql )&lt;br /&gt;
: Returns a unique value from DB or null if no value is found.&lt;br /&gt;
: $sql must be a SELECT query.&lt;br /&gt;
: Raise an exception if more than 1 row is returned.&lt;br /&gt;
&lt;br /&gt;
; getCollectionFromDB( $sql, $bSingleValue=false )&lt;br /&gt;
: Returns an associative array of rows for a sql SELECT query.&lt;br /&gt;
: The key of the resulting associative array is the first field specified in the SELECT query.&lt;br /&gt;
: The value of the resulting associative array is an associative array with all the field specified in the SELECT query and associated values.&lt;br /&gt;
: First column must be a primary or alternate key (semantically, it does not actually have to declared in sql as such).&lt;br /&gt;
: The resulting collection can be empty (it won&#039;t be null).&lt;br /&gt;
: If you specified $bSingleValue=true and if your SQL query request 2 fields A and B, the method returns an associative array &amp;quot;A=&amp;gt;B&amp;quot;, otherwise its A=&amp;gt;[A,B]&lt;br /&gt;
: Note: The name a bit misleading, it really return associative array, i.e. map and NOT a collection. You cannot use it to get list of values which may have duplicates (hence primary key requirement on first column). If you need simple array use getObjectListFromDB() method.&lt;br /&gt;
&lt;br /&gt;
Example 1:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
self::getCollectionFromDB( &amp;quot;SELECT player_id id, player_name name, player_score score FROM player&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
Result:&lt;br /&gt;
array(&lt;br /&gt;
 1234 =&amp;gt; array( &#039;id&#039;=&amp;gt;1234, &#039;name&#039;=&amp;gt;&#039;myuser0&#039;, &#039;score&#039;=&amp;gt;1 ),&lt;br /&gt;
 1235 =&amp;gt; array( &#039;id&#039;=&amp;gt;1235, &#039;name&#039;=&amp;gt;&#039;myuser1&#039;, &#039;score&#039;=&amp;gt;0 )&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Example 2:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
self::getCollectionFromDB( &amp;quot;SELECT player_id id, player_name name FROM player&amp;quot;, true );&lt;br /&gt;
&lt;br /&gt;
Result:&lt;br /&gt;
array(&lt;br /&gt;
 1234 =&amp;gt; &#039;myuser0&#039;,&lt;br /&gt;
 1235 =&amp;gt; &#039;myuser1&#039;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; getNonEmptyCollectionFromDB( $sql )&lt;br /&gt;
: Same as getCollectionFromDB($sdl), but raise an exception if the collection is empty. Note: this function does NOT have 2nd argument as previous one does.&lt;br /&gt;
&lt;br /&gt;
; getObjectFromDB( $sql )&lt;br /&gt;
: Returns one row for the sql SELECT query as an associative array or null if there is no result&lt;br /&gt;
: Raise an exception if the query return more than one row (you can use LIMIT 1 in the query to avoid the exception)&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
self::getObjectFromDB( &amp;quot;SELECT player_id id, player_name name, player_score score FROM player WHERE player_id=&#039;$player_id&#039;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
Result:&lt;br /&gt;
array(&lt;br /&gt;
  &#039;id&#039;=&amp;gt;1234, &#039;name&#039;=&amp;gt;&#039;myuser0&#039;, &#039;score&#039;=&amp;gt;1 &lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; getNonEmptyObjectFromDB( $sql )&lt;br /&gt;
: Similar to previous one, but raise an exception if no row is found&lt;br /&gt;
&lt;br /&gt;
; getObjectListFromDB( $sql, $bUniqueValue=false )&lt;br /&gt;
: Return an array of rows for a sql SELECT query.&lt;br /&gt;
: The result is the same as &amp;quot;getCollectionFromDB&amp;quot; except that the result is a simple array (and not an associative array).&lt;br /&gt;
: The result can be empty.&lt;br /&gt;
: If you specified $bUniqueValue=true and if your SQL query request 1 field, the method returns directly an array of values.&lt;br /&gt;
&lt;br /&gt;
Example 1:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
self::getObjectListFromDB( &amp;quot;SELECT player_id id, player_name name, player_score score FROM player&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
Result:&lt;br /&gt;
array(&lt;br /&gt;
 array( &#039;id&#039;=&amp;gt;1234, &#039;name&#039;=&amp;gt;&#039;myuser0&#039;, &#039;score&#039;=&amp;gt;1 ),&lt;br /&gt;
 array( &#039;id&#039;=&amp;gt;1235, &#039;name&#039;=&amp;gt;&#039;myuser1&#039;, &#039;score&#039;=&amp;gt;0 )&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Example 2:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
self::getObjectListFromDB( &amp;quot;SELECT player_name name FROM player&amp;quot;, true );&lt;br /&gt;
&lt;br /&gt;
Result:&lt;br /&gt;
array(&lt;br /&gt;
 &#039;myuser0&#039;,&lt;br /&gt;
 &#039;myuser1&#039;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; getDoubleKeyCollectionFromDB( $sql, $bSingleValue=false )&lt;br /&gt;
: Return an associative array of associative array, from a SQL SELECT query.&lt;br /&gt;
: First array level correspond to first column specified in SQL query.&lt;br /&gt;
: Second array level correspond to second column specified in SQL query.&lt;br /&gt;
: If bSingleValue = true, keep only third column on result&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; DbGetLastId()&lt;br /&gt;
: Return the PRIMARY key of the last inserted row (see PHP mysql_insert_id function).&lt;br /&gt;
&lt;br /&gt;
; DbAffectedRow()&lt;br /&gt;
: Return the number of row affected by the last operation&lt;br /&gt;
&lt;br /&gt;
; escapeStringForDB( $string )&lt;br /&gt;
: You must use this function on every string type data in your database that contains unsafe data.&lt;br /&gt;
: (unsafe = can be modified by a player).&lt;br /&gt;
: This method makes sure that no SQL injection will be done through the string used.&lt;br /&gt;
: Note: if you using standard types in ajax actions, like AT_alphanum it is sanitized before arrival,&lt;br /&gt;
: this is only needed if you manage to get unchecked string, like in the games where user has to enter text as a response.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: see Editing [[Game database model: dbmodel.sql]] to know how to define your database model.&lt;br /&gt;
&lt;br /&gt;
== Use globals ==&lt;br /&gt;
&lt;br /&gt;
Sometimes, you want a single global integer value for your game, and you don&#039;t want to create a DB table specifically for it.&lt;br /&gt;
&lt;br /&gt;
You can do this with the BGA framework &amp;quot;global.&amp;quot; Your value will be stored in the &amp;quot;global&amp;quot; table in the database, and you can access it with simple methods.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;$this-&amp;gt;initGameStateLabels&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This method should be located at the beginning of __construct() method of &#039;&#039;yourgamename.game.php&#039;&#039;. This is where you define the globals used in your game logic, by assigning them IDs.&lt;br /&gt;
&lt;br /&gt;
You can define up to 80 globals, with IDs from 10 to 89 (inclusive, there can be gaps). You must &#039;&#039;&#039;not&#039;&#039;&#039; use globals outside this range, as those values are used by other components of the framework.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        $this-&amp;gt;initGameStateLabels( array( &lt;br /&gt;
                &amp;quot;my_first_global_variable&amp;quot; =&amp;gt; 10,&lt;br /&gt;
                &amp;quot;my_second_global_variable&amp;quot; =&amp;gt; 11&lt;br /&gt;
        ) );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        $this-&amp;gt;GAMESTATELABELS = [&amp;quot;my_first_global_variable&amp;quot; =&amp;gt; 10, &amp;quot;my_second_global_variable&amp;quot; =&amp;gt; 11];&lt;br /&gt;
        $this-&amp;gt;initGameStateLabels($this-&amp;gt;GAMESTATELABELS);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is also in this method that you will define your game options. In that case, IDs need to be between 100 and 199 (inclusive, there can be gaps) Check this for more details [[Game_options_and_preferences:_gameoptions.inc.php]]&lt;br /&gt;
&lt;br /&gt;
With option set, the method will look like&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        $this-&amp;gt;initGameStateLabels( array( &lt;br /&gt;
                &amp;quot;my_first_global_variable&amp;quot; =&amp;gt; 10,&lt;br /&gt;
                &amp;quot;my_second_global_variable&amp;quot; =&amp;gt; 11,&lt;br /&gt;
                &amp;quot;my_game_variant&amp;quot; =&amp;gt; 100&lt;br /&gt;
        ) );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;$this-&amp;gt;setGameStateInitialValue( $value_label, $value_value )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Initialize your global value. Must be called before any use of your global, so you should call this method from your &amp;quot;setupNewGame&amp;quot; method. $value_value must be an integer.&lt;br /&gt;
&lt;br /&gt;
It seems that a non initialized value will not be restored with undo system, so it is therefore advisable to initialize them all in your &amp;quot;setupNewGame&amp;quot; method.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;foreach ($this-&amp;gt;GAMESTATELABELS as $value_label=&amp;gt; $ID) if ($ID &amp;gt;= 10 &amp;amp;&amp;amp; $ID &amp;lt; 90) $this-&amp;gt;setGameStateInitialValue($value_label, 0);&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;$this-&amp;gt;getGameStateValue( $value_label )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Retrieve the current value of a global.&lt;br /&gt;
&lt;br /&gt;
For debugging purposes, you can have labels and value pairs send to client side by inserting that line of code in your &amp;quot;getAllDatas&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;$result[&#039;labels&#039;] = array_combine(array_keys($this-&amp;gt;GAMESTATELABELS), array_map(array($this,&#039;getGameStateValue&#039;), array_keys($this-&amp;gt;GAMESTATELABELS)));&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;$this-&amp;gt;setGameStateValue( $value_label, $value_value )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Set the current value of a global. $value_value must be an integer.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;incGameStateValue( $value_label, $increment )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Increment the current value of a global. If increment is negative, decrement the value of the global.&lt;br /&gt;
&lt;br /&gt;
Return the final value of the global.&lt;br /&gt;
&lt;br /&gt;
=== BGA predefined globals ===&lt;br /&gt;
&lt;br /&gt;
BGA already defines some globals in the &#039;&#039;global&#039;&#039; database table. You should not change them directly but it can be useful to know what they mean when debugging:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! global_id !! Meaning&lt;br /&gt;
|-&lt;br /&gt;
| 1 || Active state id&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Active player id&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Next move number&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Player turn number&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Game progression&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Initial reflection time&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Additional reflection time&lt;br /&gt;
|-&lt;br /&gt;
| 200 || Reflexion time profile&lt;br /&gt;
|-&lt;br /&gt;
| 207 || GAMESTATE_GAME_LANG&lt;br /&gt;
|-&lt;br /&gt;
| 201 || BGA ranking mode&lt;br /&gt;
|-&lt;br /&gt;
| 300 || GAMESTATE_GAMEVERSION: Current version of the game (when in production)&lt;br /&gt;
|-&lt;br /&gt;
| 301 || GAMESTATE_GAME_RESULT_NEUTRALIZED&lt;br /&gt;
|-&lt;br /&gt;
| 302 || GAMESTATE_NEUTRALIZED_PLAYER_ID&lt;br /&gt;
|-&lt;br /&gt;
| 304 || GAMESTATE_UNDO_MOVES_STORED&lt;br /&gt;
|-&lt;br /&gt;
| 305 || GAMESTATE_UNDO_MOVES_PLAYER&lt;br /&gt;
|-&lt;br /&gt;
| 306 || GAMESTATE_LOCK_TIMESTAMP&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Game states and active players ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Activate player handling ===&lt;br /&gt;
&lt;br /&gt;
; $this-&amp;gt;activeNextPlayer()&lt;br /&gt;
: Make the next player active in the natural player order.&lt;br /&gt;
: Note: you CANNOT use this method in a &amp;quot;activeplayer&amp;quot; or &amp;quot;multipleactiveplayer&amp;quot; state. You must use a &amp;quot;game&amp;quot; type game state for this.&lt;br /&gt;
&lt;br /&gt;
; $this-&amp;gt;activePrevPlayer()&lt;br /&gt;
: Make the previous player active (in the natural player order).&lt;br /&gt;
: Note: you CANNOT use this method in a &amp;quot;activeplayer&amp;quot; or &amp;quot;multipleactiveplayer&amp;quot; state. You must use a &amp;quot;game&amp;quot; type game state for this.&lt;br /&gt;
&lt;br /&gt;
; $this-&amp;gt;gamestate-&amp;gt;changeActivePlayer( $player_id )&lt;br /&gt;
: You can call this method to make any player active.&lt;br /&gt;
: Note: you CANNOT use this method in a &amp;quot;activeplayer&amp;quot; or &amp;quot;multipleactiveplayer&amp;quot; state. You must use a &amp;quot;game&amp;quot; type game state for this.&lt;br /&gt;
&lt;br /&gt;
; $this-&amp;gt;getActivePlayerId()&lt;br /&gt;
: Return the &amp;quot;active_player&amp;quot; id&lt;br /&gt;
: Note: it does NOT mean that this player is active right now, because state type could be &amp;quot;game&amp;quot; or &amp;quot;multipleactiveplayer&amp;quot;&lt;br /&gt;
: Note: avoid using this method in a &amp;quot;multipleactiveplayer&amp;quot; state because it does not mean anything.&lt;br /&gt;
&lt;br /&gt;
=== Multiple activate player handling ===&lt;br /&gt;
&lt;br /&gt;
; $this-&amp;gt;gamestate-&amp;gt;setAllPlayersMultiactive()&lt;br /&gt;
: All playing players are made active. Update notification is sent to all players (this will trigger &#039;&#039;&#039;onUpdateActionButtons&#039;&#039;&#039;).&lt;br /&gt;
: Usually, you use this method at the beginning of a game state (e.g., &amp;quot;stGameState&amp;quot;) which transitions to a &#039;&#039;multipleactiveplayer&#039;&#039; state in which multiple players have to perform some action. Do not use this method if you going to make some more changes in the active player list. (I.e., if you want to take away multipleactiveplayer status immediately afterwards, use setPlayersMultiactive instead.)&lt;br /&gt;
&lt;br /&gt;
Example of usage:&lt;br /&gt;
    &amp;lt;pre&amp;gt;&lt;br /&gt;
    function st_MultiPlayerInit() {&lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;setAllPlayersMultiactive();&lt;br /&gt;
    }&lt;br /&gt;
    &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; $this-&amp;gt;stMakeEveryoneActive()&lt;br /&gt;
:this method can be used in state machine to make everybody active as &amp;quot;st&amp;quot; method of multiplayeractive state, it just calls $this-&amp;gt;gamestate-&amp;gt;setAllPlayersMultiactive()&lt;br /&gt;
&lt;br /&gt;
This is to be used in state declaration:&lt;br /&gt;
    &amp;lt;pre&amp;gt;&lt;br /&gt;
    2 =&amp;gt; array(&lt;br /&gt;
    		&amp;quot;name&amp;quot; =&amp;gt; &amp;quot;playerTurnPlace&amp;quot;,&lt;br /&gt;
    		&amp;quot;description&amp;quot; =&amp;gt; clienttranslate(&#039;Other player must place ships&#039;),&lt;br /&gt;
    		&amp;quot;descriptionmyturn&amp;quot; =&amp;gt; clienttranslate(&#039;${you} must place ships (click on YOUR SHIPS board to place)&#039;),&lt;br /&gt;
    		&amp;quot;type&amp;quot; =&amp;gt; &amp;quot;multipleactiveplayer&amp;quot;,&lt;br /&gt;
                &#039;action&#039; =&amp;gt; &#039;stMakeEveryoneActive&#039;,&lt;br /&gt;
                &#039;args&#039; =&amp;gt; &#039;arg_playerTurnPlace&#039;,&lt;br /&gt;
    	     	&amp;quot;possibleactions&amp;quot; =&amp;gt; array( &amp;quot;actionBla&amp;quot; ),&lt;br /&gt;
                &amp;quot;transitions&amp;quot; =&amp;gt; array( &amp;quot;next&amp;quot; =&amp;gt; 4, &amp;quot;last&amp;quot; =&amp;gt; 99)&lt;br /&gt;
    ),&lt;br /&gt;
    &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; $this-&amp;gt;gamestate-&amp;gt;setAllPlayersNonMultiactive( $next_state )&lt;br /&gt;
: All playing players are made inactive. Transition to next state&lt;br /&gt;
&lt;br /&gt;
; $this-&amp;gt;gamestate-&amp;gt;setPlayersMultiactive( $players, $next_state, $bExclusive = false )&lt;br /&gt;
: Make a specific list of players active during a multiactive gamestate. Update notification is sent to all players whose state changed.&lt;br /&gt;
: &amp;quot;players&amp;quot; is the array of player id that should be made active. If &amp;quot;players&amp;quot; is not empty the value of &amp;quot;next_state&amp;quot; will be ignored (you can put whatever you want)&lt;br /&gt;
: If &amp;quot;exclusive&amp;quot; parameter is not set or false it doesn&#039;t deactivate other previously active players. If its set to true, the players who will be multiactive at the end are only these in &amp;quot;$players&amp;quot; array&lt;br /&gt;
&lt;br /&gt;
: In case &amp;quot;players&amp;quot; is empty, the method trigger the &amp;quot;next_state&amp;quot; transition to go to the next game state.&lt;br /&gt;
: returns true if state transition happened, false otherwise&lt;br /&gt;
&lt;br /&gt;
; $this-&amp;gt;gamestate-&amp;gt;setPlayerNonMultiactive( $player_id, $next_state )&lt;br /&gt;
: During a multiactive game state, make the specified player inactive.&lt;br /&gt;
: Usually, you call this method during a multiactive game state after a player did his action. It is also possible to call it directly from multiplayer action handler.&lt;br /&gt;
: If this player was the last active player, the method trigger the &amp;quot;next_state&amp;quot; transition to go to the next game state.&lt;br /&gt;
: returns true if state transition happened, false otherwise&lt;br /&gt;
Example of usage (see state declaration of playerTurnPlace above):&lt;br /&gt;
    &amp;lt;pre&amp;gt;&lt;br /&gt;
    function actionBla($args) {&lt;br /&gt;
        self::checkAction(&#039;actionBla&#039;);&lt;br /&gt;
        // handle the action using $this-&amp;gt;getCurrentPlayerId()&lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;setPlayerNonMultiactive( $this-&amp;gt;getCurrentPlayerId(), &#039;next&#039;);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; $this-&amp;gt;gamestate-&amp;gt;getActivePlayerList()&lt;br /&gt;
: With this method you can retrieve the list of the active player at any time.&lt;br /&gt;
: During a &amp;quot;game&amp;quot; type gamestate, it will return a void array.&lt;br /&gt;
: During a &amp;quot;activeplayer&amp;quot; type gamestate, it will return an array with one value (the active player id).&lt;br /&gt;
: During a &amp;quot;multipleactiveplayer&amp;quot; type gamestate, it will return an array of the active players id.&lt;br /&gt;
: Note: you should only use this method in the latter case.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
;  $this-&amp;gt;gamestate-&amp;gt;updateMultiactiveOrNextState( $next_state_if_none )&lt;br /&gt;
: Sends update notification about multiplayer changes. All multiactive set* functions above do that, however if you want to change state manually using db queries for complex calculations, you have to call this yourself after. Do not call this if you calling one of the other setters above.&lt;br /&gt;
Example: you have player teams and you want to activate all players in one team&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        $sql = &amp;quot;UPDATE player SET player_is_multiactive=&#039;0&#039;&amp;quot;;&lt;br /&gt;
        self::DbQuery( $sql );&lt;br /&gt;
        $sql = &amp;quot;UPDATE player SET player_is_multiactive=&#039;1&#039; WHERE player_id=&#039;$player_id&#039; AND player_team=&#039;$team_no&#039;&amp;quot;;&lt;br /&gt;
        self::DbQuery( $sql );&lt;br /&gt;
        &lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;updateMultiactiveOrNextState( &#039;error&#039; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; updating database manually&lt;br /&gt;
: Use this helper function to change multiactive state without sending notification&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    /**&lt;br /&gt;
     * Changes values of multiactivity in db, does not sent notifications.&lt;br /&gt;
     * To send notifications after use updateMultiactiveOrNextState&lt;br /&gt;
     * @param number $player_id, player id &amp;lt;=0 or null - means ALL&lt;br /&gt;
     * @param number $value - 1 multiactive, 0 non multiactive&lt;br /&gt;
     */&lt;br /&gt;
    function dbSetPlayerMultiactive($player_id = -1, $value = 1) {&lt;br /&gt;
        if (! $value)&lt;br /&gt;
            $value = 0;&lt;br /&gt;
        else&lt;br /&gt;
            $value = 1;&lt;br /&gt;
        $sql = &amp;quot;UPDATE player SET player_is_multiactive = &#039;$value&#039; WHERE player_zombie = 0 and player_eliminated = 0&amp;quot;;&lt;br /&gt;
        if ($player_id &amp;gt; 0) {&lt;br /&gt;
            $sql .= &amp;quot; AND player_id = $player_id&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
        self::DbQuery($sql);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;$this-&amp;gt;gamestate-&amp;gt;isPlayerActive($player_id)&lt;br /&gt;
:Return true if specified player is active right now.&lt;br /&gt;
:This method take into account game state type, ie nobody is active if game state is &amp;quot;game&amp;quot; and several players can be active if game state is &amp;quot;multiplayer&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== States functions ===&lt;br /&gt;
; $this-&amp;gt;gamestate-&amp;gt;nextState( $transition )&lt;br /&gt;
: Change current state to a new state. Important: the $transition parameter is the name of the transition, and NOT the name of the target game state, see [[Your game state machine: states.inc.php]] for more information about states.&lt;br /&gt;
&lt;br /&gt;
; $this-&amp;gt;checkAction( $actionName, $bThrowException=true )&lt;br /&gt;
: Check if the current player can perform a specific action in the current game state, and optionally throw an exception if they can&#039;t.&lt;br /&gt;
: The action is valid if it is listed in the &amp;quot;possibleactions&amp;quot; array for the current game state (see game state description).&lt;br /&gt;
: This method MUST be the first one called in ALL your PHP methods that handle player actions, in order to make sure a player doesn&#039;t perform an action not allowed by the rules at the point in the game.  It should not be called from methods where the current player is not necessarily the active player, otherwise it may fail with an &amp;quot;It is not your turn&amp;quot; exception.&lt;br /&gt;
: If &amp;quot;bThrowException&amp;quot; is set to &amp;quot;false&amp;quot;, the function returns &#039;&#039;&#039;false&#039;&#039;&#039; in case of failure instead of throwing an exception. This is useful when several actions are possible, in order to test each of them without throwing exceptions.&lt;br /&gt;
&lt;br /&gt;
; $this-&amp;gt;gamestate-&amp;gt;checkPossibleAction( $action )&lt;br /&gt;
: (rarely used)&lt;br /&gt;
: This works exactly like &amp;quot;checkAction&amp;quot; (above), except that it does NOT check if the current player is active.&lt;br /&gt;
: This is used specifically in certain game states when you want to authorize additional actions for players that are not active at the moment.&lt;br /&gt;
: Example: in &#039;&#039;Libertalia&#039;&#039;, you want to authorize players to change their mind about the card played. They are of course not active at the time they change their mind, so you cannot use &amp;quot;checkAction&amp;quot;; use &amp;quot;checkPossibleAction&amp;quot; instead.&lt;br /&gt;
&lt;br /&gt;
This is how PHP action looks that returns player to active state (only for multiplayeractive states). To be able to execute on js side do not checkAction on js side for this specific one.&lt;br /&gt;
&lt;br /&gt;
   function actionUnpass() {&lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;checkPossibleAction(&#039;actionUnpass&#039;); // player changed mind about passing while others were thinking&lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;setPlayersMultiactive(array ($this-&amp;gt;getCurrentPlayerId() ), &#039;error&#039;, false);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
; $this-&amp;gt;gamestate-&amp;gt;state()&lt;br /&gt;
: Get an associative array of current game state attributes, see [[Your game state machine: states.inc.php]] for state attributes.&lt;br /&gt;
&lt;br /&gt;
  $state=$this-&amp;gt;gamestate-&amp;gt;state(); if( $state[&#039;name&#039;] == &#039;myGameState&#039; ) {...}&lt;br /&gt;
&lt;br /&gt;
I suggest to define and use this function in your php class to access state name:&lt;br /&gt;
&lt;br /&gt;
    public function getStateName() {&lt;br /&gt;
        $state = $this-&amp;gt;gamestate-&amp;gt;state();&lt;br /&gt;
        return $state[&#039;name&#039;];&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
; $this-&amp;gt;gamestate-&amp;gt;state_id()&lt;br /&gt;
: Get the id of the current game state (rarely useful, its best to use name, unless you use constants for state ids)&lt;br /&gt;
&lt;br /&gt;
; $this-&amp;gt;gamestate-&amp;gt;isMutiactiveState()&lt;br /&gt;
: Return true if we are in multipleactiveplayer state, false otherwise&lt;br /&gt;
&lt;br /&gt;
=== Private parallel states ===&lt;br /&gt;
&lt;br /&gt;
See the overview of private parallel states [[Your_game_state_machine:_states.inc.php#Private_parallel_states|here]].&lt;br /&gt;
&lt;br /&gt;
; $this-&amp;gt;gamestate-&amp;gt;initializePrivateStateForAllActivePlayers()&lt;br /&gt;
: All active players in a multiactive state are entering a first private state defined in the master state&#039;s initialprivate parameter.&lt;br /&gt;
: Every time you need to start a private parallel states you need to call this or similar methods below.&lt;br /&gt;
: Note: at least one player needs to be active (see [[#Multiple_activate_player_handling|above]]) and current game state must be a multiactive state with initialprivate parameter defined&lt;br /&gt;
: Note: initialprivate parameter of master state should be set to the id of the first private state. This private state needs to be defined in states.php with the type set to &#039;private&#039;.&lt;br /&gt;
: Note: this method is usually preceded with activating some or all players&lt;br /&gt;
: Note: initializing private state can run action or args methods of the initial private state&lt;br /&gt;
&lt;br /&gt;
Example of usage:&lt;br /&gt;
    &amp;lt;pre&amp;gt;&lt;br /&gt;
    function stStartPlayerTurn() {&lt;br /&gt;
        // This is usually done in master state action method&lt;br /&gt;
        &lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;setAllPlayersMultiactive();&lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;initializePrivateStateForAllActivePlayers();&lt;br /&gt;
&lt;br /&gt;
        // in some cases you can move immediately some or all players to different private states&lt;br /&gt;
        if ($someCondition) {&lt;br /&gt;
            //move all players to different state &lt;br /&gt;
            $this-&amp;gt;gamestate-&amp;gt;nextPrivateStateForAllActivePlayers(&amp;quot;some_transition&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        if ($other condition) {&lt;br /&gt;
            //move single player to different state&lt;br /&gt;
            $this-&amp;gt;gamestate-&amp;gt;nextPrivateState($specificPlayerId, &amp;quot;some_transition&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; $this-&amp;gt;gamestate-&amp;gt;initializePrivateStateForPlayers($playerIds)&lt;br /&gt;
: Players with specified ids are entering a first private state defined in the master state initialprivate parameter.&lt;br /&gt;
: Same considerations apply as for the method above.&lt;br /&gt;
&lt;br /&gt;
; $this-&amp;gt;gamestate-&amp;gt;initializePrivateState($playerId)&lt;br /&gt;
: Player with the specified id is entering a first private state defined in the master state initialprivate parameter.&lt;br /&gt;
: Everytime you need to start a private parallel states you need to call this or similar methods above&lt;br /&gt;
: Note: player needs to be active (see [[#Multiple_activate_player_handling|above]]) and current game state must be a multiactive state with initialprivate parameter defined&lt;br /&gt;
: Note: initialprivate parameter of master state should be set to the id of the first private state. This private state needs to be defined in states.php with the type set to &#039;private&#039;.&lt;br /&gt;
: Note: this method is usually preceded with activating that player&lt;br /&gt;
: Note: initializing private state can run action or args methods of the initial private state&lt;br /&gt;
&lt;br /&gt;
Example of usage:&lt;br /&gt;
    &amp;lt;pre&amp;gt;&lt;br /&gt;
    function st_ChangeMind() {&lt;br /&gt;
        // This player finished his move before, but now decides change something while other players are still active&lt;br /&gt;
        // We activate the player and initialize his private state&lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;setPlayersMultiactive([$this-&amp;gt;getCurrentPlayerId()], &amp;quot;&amp;quot;);&lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;initializePrivateState(this-&amp;gt;getCurrentPlayerId());&lt;br /&gt;
&lt;br /&gt;
        // It is also possible to move the player to some other specific state immediately&lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;nextPrivateState($this-&amp;gt;getCurrentPlayerId(), &amp;quot;some_transition&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; $this-&amp;gt;gamestate-&amp;gt;nextPrivateStateForAllActivePlayers($transition)&lt;br /&gt;
: All active players will transition to next private state by specified transition&lt;br /&gt;
: Note: game needs to be in a master state which allows private parallel states&lt;br /&gt;
: Note: transition should lead to another private state (i.e. a state with type defined as &#039;private&#039;&lt;br /&gt;
: Note: transition should be defined in private state in which the players currently are. &lt;br /&gt;
: Note: this method can run action or args methods of the target state&lt;br /&gt;
: Note: this is usually used after initializing the private state to move players to specific private state according to the game logic&lt;br /&gt;
&lt;br /&gt;
Example of usage:&lt;br /&gt;
    &amp;lt;pre&amp;gt;&lt;br /&gt;
    function stStartPlayerTurn() {&lt;br /&gt;
        // This is usually done in master state action method&lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;setAllPlayersMultiactive();&lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;initializePrivateStateForAllActivePlayers();&lt;br /&gt;
&lt;br /&gt;
        if ($specificOption) {&lt;br /&gt;
            //move all players to different state &lt;br /&gt;
            $this-&amp;gt;gamestate-&amp;gt;nextPrivateStateForAllActivePlayers(&amp;quot;some_transition&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; $this-&amp;gt;gamestate-&amp;gt;nextPrivateStateForPlayers($playerIds, $transition)&lt;br /&gt;
: Players with specified ids will transition to next private state specified by provided transition.&lt;br /&gt;
: Same considerations apply as for the method above.&lt;br /&gt;
&lt;br /&gt;
; $this-&amp;gt;gamestate-&amp;gt;nextPrivateState($playerId, $transition)&lt;br /&gt;
: Player with specified id will transition to next private state specified by provided transition&lt;br /&gt;
: Note: game needs to be in a master state which allows private parallel states&lt;br /&gt;
: Note: transition should lead to another private state (i.e. a state with type defined as &#039;private&#039;&lt;br /&gt;
: Note: transition should be defined in private state in which the players currently are. &lt;br /&gt;
: Note: this method can run action or args methods of the target state for specified player&lt;br /&gt;
: Note: this is usually used after some player actions to move to next private state&lt;br /&gt;
&lt;br /&gt;
Example of usage:&lt;br /&gt;
    &amp;lt;pre&amp;gt;&lt;br /&gt;
    function someAction() {&lt;br /&gt;
        $this-&amp;gt;checkAction(&amp;quot;someAction&amp;quot;); //needs to be defined in the current state&lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;nextPrivateState($this-&amp;gt;getCurrentPlayerId(), &amp;quot;some_transition&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; $this-&amp;gt;gamestate-&amp;gt;unsetPrivateStateForAllPlayers()&lt;br /&gt;
: All players private state will be reset to null, which means they will get out of private parallel states and be in a master state like the private states are not used &lt;br /&gt;
: Note: game needs to be in a master state which allows private parallel states&lt;br /&gt;
: Note: this is usually used to clean up after leaving a master state in which private states were used, but can be used in other cases when we want to exit private parallel states and use a regular multiactive state for all players&lt;br /&gt;
: Note: After unseting private state only actions on master state are possible&lt;br /&gt;
: Note: Usually it is not necessary to unset private states as they will be initialized to first private state when private states are needed again. Nevertheless it is generally better to clean private state after exiting private parallel states to avoid bugs. &lt;br /&gt;
&lt;br /&gt;
Example of usage:&lt;br /&gt;
    &amp;lt;pre&amp;gt;&lt;br /&gt;
    function stNextRound() {&lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;unsetPrivateStateForAllPlayers();&lt;br /&gt;
    }&lt;br /&gt;
    &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; $this-&amp;gt;gamestate-&amp;gt;unsetPrivateStateForPlayers($playerIds, $transition)&lt;br /&gt;
: For players with specified ids private state will be reset to null, which means they will get out of private parallel states and be in a master state like the private states are not used.&lt;br /&gt;
: Same considerations apply as for the method above.&lt;br /&gt;
&lt;br /&gt;
; $this-&amp;gt;gamestate-&amp;gt;unsetPrivateState($playerId)&lt;br /&gt;
: For player with specified id private state will be reset to null, which means they will get out of private parallel states and be in a master state like the private states are not used &lt;br /&gt;
: Note: game needs to be in a master state which allows private parallel states&lt;br /&gt;
: Note: this is usually used when deactivating player to clean up their parallel state&lt;br /&gt;
: Note: After unseting private state only actions on master state are possible&lt;br /&gt;
: Note: Usually it is not necessary to unset private state as it will be initialized to first private state when private states are needed again. Nevertheless it is generally better to clean private state when not needed to avoid bugs. &lt;br /&gt;
&lt;br /&gt;
Example of usage:&lt;br /&gt;
    &amp;lt;pre&amp;gt;&lt;br /&gt;
    function done() {&lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;setPlayerNonMultiactive( $this-&amp;gt;getCurrentPlayerId(), &amp;quot;newTurn&amp;quot; );&lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;unsetPrivateState($this-&amp;gt;getCurrentPlayerId());&lt;br /&gt;
    }&lt;br /&gt;
    &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; $this-&amp;gt;gamestate-&amp;gt;setPrivateState($playerId, $newStateId)&lt;br /&gt;
: For player with specified id a new private state would be set&lt;br /&gt;
: Note: game needs to be in a master state which allows private parallel states&lt;br /&gt;
: Note: this should be rarely used as it doesn&#039;t check if the transition is allowed (it doesn&#039;t even specifies transition). This can be useful in very complex cases when standard state machine is not adequate (i.e. specific cards can lead to some micro action in various states where defining transitions back and forth can become very tedious.) &lt;br /&gt;
: Note: this method can run action or args methods of the target state for specified player&lt;br /&gt;
&lt;br /&gt;
Example of usage:&lt;br /&gt;
    &amp;lt;pre&amp;gt;&lt;br /&gt;
    function someAction() {&lt;br /&gt;
        $this-&amp;gt;checkAction(&amp;quot;someAction&amp;quot;); //needs to be defined in the current state&lt;br /&gt;
&lt;br /&gt;
        if ($playerHaveSpecificCard)&lt;br /&gt;
            return $this-&amp;gt;gamestate-&amp;gt;setPrivateState($this-&amp;gt;getCurrentPlayerId(), 35);&lt;br /&gt;
&lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;nextPrivateState($this-&amp;gt;getCurrentPlayerId(), &amp;quot;some_transition&amp;quot;);        &lt;br /&gt;
    }&lt;br /&gt;
    &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Players turn order ==&lt;br /&gt;
&lt;br /&gt;
When table is created the &amp;quot;natural&amp;quot; player order is assigned to player at random, and stored in &amp;quot;read-only&amp;quot; field &amp;quot;player_no&amp;quot;.&lt;br /&gt;
If you need to create a custom order you should never change natural order but have a separate data structure. &lt;br /&gt;
For example you can alter the players table to add another &amp;quot;custom_order&amp;quot; field, you can use state globals or you can use your natural board database, &lt;br /&gt;
to store meeple_color/position_location pair.&lt;br /&gt;
BGA currently does not provide any API to create/store custom player order.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;getNextPlayerTable()&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Return an associative array which associate each player with the next player around the table.&lt;br /&gt;
&lt;br /&gt;
In addition, key 0 is associated to the first player to play.&lt;br /&gt;
&lt;br /&gt;
Example: if three player with ID 1000, 2000 and 3000 are around the table, in this order, the method returns:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   array( &lt;br /&gt;
    1000 =&amp;gt; 2000, &lt;br /&gt;
    2000 =&amp;gt; 3000, &lt;br /&gt;
    3000 =&amp;gt; 1000, &lt;br /&gt;
    0 =&amp;gt; 1000 &lt;br /&gt;
   );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;getPrevPlayerTable()&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Same as above, but the associative array associate the previous player around the table. However there no 0 index here.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;getPlayerAfter( $player_id )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Get player playing after given player in natural playing order.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;getPlayerBefore( $player_id )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Get player playing before given player in natural playing order.&lt;br /&gt;
&lt;br /&gt;
Note: There is no API to modify this order, if you have custom player order you have to maintain it in your database&lt;br /&gt;
and have custom function to access it.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;createNextPlayerTable( $players, $bLoop=true )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Using $players array creates a map of current =&amp;gt; next as in example from getNextPlayerTable(), however you can use custom order here. &lt;br /&gt;
If parmeter $bLoop is set to true then last player will points to first (creaing a loop), false otherwise.&lt;br /&gt;
In any case index 0 points to first player (first element of $players array). $players is array of player ids in desired order.&lt;br /&gt;
&lt;br /&gt;
Note: This function &#039;&#039;&#039;DOES NOT&#039;&#039;&#039; change the order in database, it only creates a map using key/values as descibed.&lt;br /&gt;
&lt;br /&gt;
Example of usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    function getNextPlayerTableCustom() {&lt;br /&gt;
        $starting = $this-&amp;gt;getStartingPlayer(); // custom function to get starting player&lt;br /&gt;
        $player_ids = $this-&amp;gt;getPlayerIdsInOrder($starting); // custom function to create players array starting from starting player&lt;br /&gt;
        return $this-&amp;gt;createNextPlayerTable($player_ids, false); // create next player table in custom order&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$table = $this-&amp;gt;createNextPlayerTable([3,2,1], false);&lt;br /&gt;
&lt;br /&gt;
will return:&lt;br /&gt;
   [ &lt;br /&gt;
    3000 =&amp;gt; 2000, &lt;br /&gt;
    2000 =&amp;gt; 1000, &lt;br /&gt;
    1000 =&amp;gt; null,&lt;br /&gt;
    0 =&amp;gt; 3000 &lt;br /&gt;
   ]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Notify players ==&lt;br /&gt;
&lt;br /&gt;
To understand notifications, please read [http://www.slideshare.net/boardgamearena/the-bga-framework-at-a-glance The BGA Framework at a glance] first.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;IMPORTANT&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Notifications are sent at the very end of the request, when it ends normally. It means that if you throw an exception for any reason (ex: move not allowed), no notifications will be sent to players.&lt;br /&gt;
Notifications sent between the game start (setupNewGame) and the end of the &amp;quot;action&amp;quot; method of the first active state will never reach their destination.&lt;br /&gt;
&lt;br /&gt;
=== NotifyAllPlayers ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;notifyAllPlayers( $notification_type, $notification_log, $notification_args )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Send a notification to all players of the game.&lt;br /&gt;
&lt;br /&gt;
* notification_type:&lt;br /&gt;
A string that defines the type of your notification.&lt;br /&gt;
&lt;br /&gt;
Your game interface Javascript logic will use this to know what is the type of the received notification (and to trigger the corresponding method).&lt;br /&gt;
&lt;br /&gt;
* notification_log:&lt;br /&gt;
A string that defines what is to be displayed in the game log.&lt;br /&gt;
&lt;br /&gt;
You can use an empty string here (&amp;quot;&amp;quot;). In this case, nothing is displayed in the game log.&lt;br /&gt;
&lt;br /&gt;
If you define a real string here, you should use &amp;quot;clienttranslate&amp;quot; method to make sure it can be translated.&lt;br /&gt;
&lt;br /&gt;
You can use arguments in your notification_log strings, that refers to values defines in the &amp;quot;notification_args&amp;quot; argument (see below). &lt;br /&gt;
Note: Make sure you only use single quotes (&#039;), otherwise PHP will try to interpolate the variable and will ignore the values in the args array.&lt;br /&gt;
&lt;br /&gt;
* notification_args:&lt;br /&gt;
The arguments of your notifications, as an associative array.&lt;br /&gt;
&lt;br /&gt;
This array will be transmitted to the game interface logic, in order the game interface can be updated.&lt;br /&gt;
&lt;br /&gt;
Complete notifyAllPlayers example (from &amp;quot;Reversi&amp;quot;):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
self::notifyAllPlayers( &amp;quot;playDisc&amp;quot;, clienttranslate( &#039;${player_name} plays a disc and turns over ${returned_nbr} disc(s)&#039; ),&lt;br /&gt;
 array(&lt;br /&gt;
        &#039;player_id&#039; =&amp;gt; $player_id,&lt;br /&gt;
        &#039;player_name&#039; =&amp;gt; self::getActivePlayerName(),&lt;br /&gt;
        &#039;returned_nbr&#039; =&amp;gt; count( $turnedOverDiscs ),&lt;br /&gt;
        &#039;x&#039; =&amp;gt; $x,&lt;br /&gt;
        &#039;y&#039; =&amp;gt; $y&lt;br /&gt;
     ) );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can see in the example above the use of the &amp;quot;clienttranslate&amp;quot; method, and the use of 2 arguments &amp;quot;player_name&amp;quot; and &amp;quot;returned_nbr&amp;quot; in the notification log.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important&#039;&#039;&#039;: NO private data must be sent with this method, as a cheater could see it even if it is not used explicitly by the game interface logic. If you want to send private information to a player, please use notifyPlayer below.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important&#039;&#039;&#039;: this array is serialized to be sent to the browsers, and will be saved with the notification to be able to replay the game later. If it is too big, it can make notifications slower / less reliable, and replay archives very big (to the point of failing). So as a general rule, you should send only the minimum of information necessary to update the client interface with no overhead in order to keep the notifications as light as possible.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important&#039;&#039;&#039;: When the game page is reloaded (i.e. F5 or when loading turn based game) all previous notifications are replayed as history notifications. These notifications do not trigger notification handlers and are used basically to build the game log. Because of that most of the notification arguments, except i18n, player_id and all arguments used in the message, are removed from these history notifications. If you need additional arguments in history notifications you can add special field &amp;lt;b&amp;gt;preserve&amp;lt;/b&amp;gt; to notification arguments, like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
self::notifyAllPlayers( &amp;quot;playDisc&amp;quot;, clienttranslate( &#039;${player_name} plays a disc and turns over ${returned_nbr} disc(s)&#039; ),&lt;br /&gt;
 array(&lt;br /&gt;
        &#039;player_id&#039; =&amp;gt; $player_id,&lt;br /&gt;
        &#039;player_name&#039; =&amp;gt; self::getActivePlayerName(),&lt;br /&gt;
        &#039;returned_nbr&#039; =&amp;gt; count( $turnedOverDiscs ),&lt;br /&gt;
        &#039;x&#039; =&amp;gt; $x,&lt;br /&gt;
        &#039;y&#039; =&amp;gt; $y,&lt;br /&gt;
        &#039;preserve&#039; =&amp;gt; [ &#039;x&#039;, &#039;y&#039; ]&lt;br /&gt;
     ) );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In this example, fields x and y will be preserved when replaying history notification at the game load.&lt;br /&gt;
&lt;br /&gt;
==== HTML in Notifications ====&lt;br /&gt;
&lt;br /&gt;
You CAN use some HTML inside your notification log, however it not recommended for many reasons:&lt;br /&gt;
* Its bad architecture, ui elements leak into server now you have to manage ui in many places&lt;br /&gt;
* If you decided to change something in ui in future version, old games replay and tutorials may not work, since they use stored notifications&lt;br /&gt;
* When you read log preview for old games its unreadable (this is log before you enter the game replay, useful for troubleshooting or game analysis)&lt;br /&gt;
* Its more data to transfer and store in db&lt;br /&gt;
* Its nightmare for translators, at least don&#039;t put HTML tags inside the &amp;quot;clienttranslate&amp;quot; method. You can use a notification argument instead, and provide your HTML through this argument.&lt;br /&gt;
&lt;br /&gt;
If you still want to have pretty pictures in the log check this [[BGA_Studio_Cookbook#Inject_images_and_styled_html_in_the_log]].&lt;br /&gt;
&lt;br /&gt;
==== Recursive Notifications ====&lt;br /&gt;
&lt;br /&gt;
If your notification contains some phrases that build programmatically you may need to use recursive notifications. In this case the argument can be not only the string but&lt;br /&gt;
an array itself, which contains &#039;log&#039; and &#039;args&#039;, i.e.&lt;br /&gt;
&lt;br /&gt;
  $this-&amp;gt;notifyAllPlayers(&#039;playerLog&#039;,clienttranslate(&#039;Game moves ${token_name_rec}&#039;),&lt;br /&gt;
                   [&#039;token_name_rec&#039;=&amp;gt;[&#039;log&#039;=&amp;gt;&#039;${token_name} #${token_number}&#039;,&lt;br /&gt;
                                       &#039;args&#039;=&amp;gt; [&#039;token_name&#039;=&amp;gt;clienttranslate(&#039;Boo&#039;), &#039;token_number&#039;=&amp;gt;$number, &#039;i18n&#039;=&amp;gt;[&#039;token_name&#039;] ]&lt;br /&gt;
                                      ]&lt;br /&gt;
                   ]);&lt;br /&gt;
&lt;br /&gt;
Special handling of arguments:&lt;br /&gt;
* ${player_name}  - this will be wrapped in html and text shown using color of the corresponding player, some colors also have reserved background. This will apply recursively as well.&lt;br /&gt;
* ${player_name2} - same &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Excluding some players ====&lt;br /&gt;
&lt;br /&gt;
Sometimes you want to notify all players of a message but not have it appear in the log of specific players (for example, have every player see &amp;quot;Player X draws a card&amp;quot; but have Player X see &amp;quot;You draw the Ace of Spades&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
To send a notification to all players but have some clients ignore it, send it as normal from the server, but implement &#039;&#039;&#039;setIgnoreNotificationCheck&#039;&#039;&#039; on the client to ignore the message under given conditions. See the X.js documentation for more details.&lt;br /&gt;
&lt;br /&gt;
=== NotifyPlayer ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;notifyPlayer( $player_id, $notification_type, $notification_log, $notification_args )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Same as above, except that the notification is sent to one player only.&lt;br /&gt;
&lt;br /&gt;
This method must be used each time some private information must be transmitted to a player.&lt;br /&gt;
&lt;br /&gt;
Important: the variable for player name must be ${player_name} in order to be highlighted with the player color in the game log. If you want a second player name in the log, name the variable ${player_name2}, etc.&lt;br /&gt;
&lt;br /&gt;
Note that spectators cannot be notified using this method, because their player ID is not available via loadPlayersBasicInfos() or otherwise. You must use notifyAllPlayers() for any notification that spectators should get.&lt;br /&gt;
&lt;br /&gt;
== About random and randomness ==&lt;br /&gt;
&lt;br /&gt;
A large number of board games rely on random, most often based on dice, cards shuffling, picking some item in a bag, and so on. This is very important to ensure a high level of randomness for each of these situations.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s are a list of techniques you should use in these situations, from the best to the worst.&lt;br /&gt;
&lt;br /&gt;
=== Dice and bga_rand ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;bga_rand( min, max )&#039;&#039;&#039; &lt;br /&gt;
This is a BGA framework function that provides you a random number between &amp;quot;min&amp;quot; and &amp;quot;max&amp;quot; (inclusive), using the best available random method available on the system.&lt;br /&gt;
&lt;br /&gt;
This is the preferred function you should use, because we are updating it when a better method is introduced.&lt;br /&gt;
&lt;br /&gt;
As of now, bga_rand is based on the PHP function &amp;quot;random_int&amp;quot;, which ensures a cryptographic level of randomness.&lt;br /&gt;
&lt;br /&gt;
In particular, it is &#039;&#039;&#039;mandatory&#039;&#039;&#039; to use it for all &#039;&#039;&#039;dice throw&#039;&#039;&#039; (ie: games using other methods for dice throwing will be rejected by BGA during review).&lt;br /&gt;
&lt;br /&gt;
Note: rand() and mt_rand() are deprecated on BGA and should not be used anymore, as their randomness is not as good as &amp;quot;bga_rand&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== shuffle and cards shuffling ===&lt;br /&gt;
&lt;br /&gt;
To shuffle items, like a pile of cards, the best way is to use the BGA PHP [[Deck]] component and to use &amp;quot;shuffle&amp;quot; method. This ensures that the best available shuffling method is used, and that if in the future we improve it your game will be up to date.&lt;br /&gt;
&lt;br /&gt;
As of now, the Deck component shuffle method is based on PHP &amp;quot;shuffle&amp;quot; method, which has quite good randomness (even it is not as good as bga_rand). In consequence, we accept other shuffling methods during reviews, as long as they are based on PHP &amp;quot;shuffle&amp;quot; function (or similar, like &amp;quot;array_rand&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
=== Other methods ===&lt;br /&gt;
&lt;br /&gt;
Mysql &amp;quot;RAND()&amp;quot; function has not enough randomness to be a valid method to get a random element on BGA. This function has been used in some existing games and has given acceptable results, but now it should be avoided and you should use other methods instead.&lt;br /&gt;
&lt;br /&gt;
== Game statistics ==&lt;br /&gt;
&lt;br /&gt;
There are 2 types of statistics:&lt;br /&gt;
* a &amp;quot;player&amp;quot; statistic is a statistic associated to a player&lt;br /&gt;
* a &amp;quot;table&amp;quot; statistic is a statistic not associated to a player (global statistic for this game).&lt;br /&gt;
&lt;br /&gt;
See [[Game statistics: stats.inc.php]] to see how you define statistics for your game.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;initStat( $table_or_player, $name, $value, $player_id = null )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Create a statistic entry with a default value.&lt;br /&gt;
&lt;br /&gt;
This method must be called for each statistic of your game, in your setupNewGame method.&lt;br /&gt;
If you neglect to call this for a statistic, and also do not update the value during the course of a certain game using setStat or incStat, the value of the stat will be undefined rather than 0. This will result in it being ignored at the end of the game, as if it didn&#039;t apply to that particular game, and excluded from cumulative statistics. As a consequence - if do not want statistic to be applied, do not init it, or call set or inc on it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;$table_or_player&#039; must be set to &amp;quot;table&amp;quot; if this is a table statistic, or &amp;quot;player&amp;quot; if this is a player statistic.&lt;br /&gt;
&lt;br /&gt;
&#039;$name&#039; is the name of your statistic, as it has been defined in your stats.inc.php file.&lt;br /&gt;
&lt;br /&gt;
&#039;$value&#039; is the initial value of the statistic. If this is a player statistic and if the player is not specified by &amp;quot;$player_id&amp;quot; argument, the value is set for ALL players.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;setStat( $value, $name, $player_id = null )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Set a statistic $name to $value.&lt;br /&gt;
&lt;br /&gt;
If &amp;quot;$player_id&amp;quot; is not specified, setStat consider it is a TABLE statistic.&lt;br /&gt;
&lt;br /&gt;
If &amp;quot;$player_id&amp;quot; is specified, setStat consider it is a PLAYER statistic.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;incStat( $delta, $name, $player_id = null )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Increment (or decrement) specified statistic value by $delta value. Same behavior as setStat function.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;getStat( $name, $player_id = null )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Return the value of statistic specified by $name. Useful when creating derivative statistics such as average.&lt;br /&gt;
&lt;br /&gt;
== Translations ==&lt;br /&gt;
&lt;br /&gt;
See [[Translations]]&lt;br /&gt;
&lt;br /&gt;
== Manage player scores and Tie breaker ==&lt;br /&gt;
&lt;br /&gt;
=== Normal scoring ===&lt;br /&gt;
&lt;br /&gt;
At the end of the game, players automatically get a rank depending on their score: the player with the biggest score is #1, the player with the second biggest score is #2, and so on...&lt;br /&gt;
&lt;br /&gt;
During the game, you update player&#039;s score directly by updating &amp;quot;player_score&amp;quot; field of &amp;quot;player&amp;quot; table in database.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  // +2 points to active player&lt;br /&gt;
  self::DbQuery( &amp;quot;UPDATE player SET player_score=player_score+2 WHERE player_id=&#039;&amp;quot;.self::getActivePlayerId().&amp;quot;&#039;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Set score of active player to 5&lt;br /&gt;
  self::DbQuery( &amp;quot;UPDATE player SET player_score=5 WHERE player_id=&#039;&amp;quot;.self::getActivePlayerId().&amp;quot;&#039;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: don&#039;t forget to notify the client side in order the score control can be updated accordingly.&lt;br /&gt;
&lt;br /&gt;
=== Tie breaker ===&lt;br /&gt;
&lt;br /&gt;
Tie breaker is used when two players get the same score at the end of a game.&lt;br /&gt;
&lt;br /&gt;
Tie breaker is using &amp;quot;player_score_aux&amp;quot; field of &amp;quot;player&amp;quot; table. It is updated exactly like the &amp;quot;player_score&amp;quot; field.&lt;br /&gt;
&lt;br /&gt;
Tie breaker score is displayed only for players who are tied at the end of the game. Most of the time, it is not supposed to be displayed explicitly during the game.&lt;br /&gt;
&lt;br /&gt;
When you are using &amp;quot;player_score_aux&amp;quot; functionality, you must describe the formula to use in your gameinfos.inc.php file like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         &#039;tie_breaker_description&#039; =&amp;gt; totranslate(&amp;quot;Describe here your tie breaker formula&amp;quot;),&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This description will be used as a tooltip to explain to players how this auxiliary score has been calculated.&lt;br /&gt;
&lt;br /&gt;
See also [https://en.doc.boardgamearena.com/Game_meta-information:_gameinfos.inc.php#Multiple_tie_breaker_management Multiple Tie Breaker Management].&lt;br /&gt;
&lt;br /&gt;
=== Co-operative game ===&lt;br /&gt;
&lt;br /&gt;
To make everyone win/lose together in a full-coop game:&lt;br /&gt;
&lt;br /&gt;
Add the following in gameinfos.inc.php :&lt;br /&gt;
&#039;is_coop&#039; =&amp;gt; 1, // full cooperative&lt;br /&gt;
&lt;br /&gt;
Assign a score of zero to everyone if it&#039;s a loss.&lt;br /&gt;
Assign the same score &amp;gt; 0 to everyone if it&#039;s a win.&lt;br /&gt;
&lt;br /&gt;
=== Semi-coop ===&lt;br /&gt;
&lt;br /&gt;
If the game is not full-coop, then everyone loses = everyone is tied. I.e. set score to 0 to everybody.&lt;br /&gt;
&lt;br /&gt;
=== Only &amp;quot;winners&amp;quot; and &amp;quot;losers&amp;quot; ===&lt;br /&gt;
&lt;br /&gt;
For some games, there is only a group (or a single) &amp;quot;winner&amp;quot;, and everyone else is a &amp;quot;loser&amp;quot;, with no &amp;quot;end of game rank&amp;quot; (1st, 2nd, 3rd...).&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
* Coup&lt;br /&gt;
* Not Alone&lt;br /&gt;
* Werewolves&lt;br /&gt;
* Quantum&lt;br /&gt;
&lt;br /&gt;
In this case:&lt;br /&gt;
* Set the scores so that the winner has the best score, and the other players have the same (lower) score.&lt;br /&gt;
* Add the following lines to gameinfos.inc.php:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// If in the game, all losers are equal (no score to rank them or explicit in the rules that losers are not ranked between them), set this to true &lt;br /&gt;
// The game end result will display &amp;quot;Winner&amp;quot; for the 1st player and &amp;quot;Loser&amp;quot; for all other players&lt;br /&gt;
&#039;losers_not_ranked&#039; =&amp;gt; true,&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Werewolves and Coup are implemented like this, as you can see here:&lt;br /&gt;
* https://boardgamearena.com/#!gamepanel?game=werewolves&amp;amp;section=lastresults&lt;br /&gt;
* https://boardgamearena.com/#!gamepanel?game=coupcitystate&amp;amp;section=lastresults&lt;br /&gt;
&lt;br /&gt;
Adding this has the following effects:&lt;br /&gt;
* On game results for this game, &amp;quot;Winner&amp;quot; or &amp;quot;Loser&amp;quot; is going to appear instead of the usual &amp;quot;1st, 2nd, 3rd, ...&amp;quot;.&lt;br /&gt;
* When a game is over, the result of the game will be &amp;quot;End of game: Victory&amp;quot; or &amp;quot;End of game: Defeat&amp;quot; depending on the result of the CURRENT player (instead of the usual &amp;quot;Victory of XXX&amp;quot;).&lt;br /&gt;
* When calculating ELO points, if there is at least one &amp;quot;Loser&amp;quot;, no &amp;quot;victorious&amp;quot; player can lose ELO points, and no &amp;quot;losing&amp;quot; player can win ELO point. Usually it may happened because being tie with many players with a low rank is considered as a tie and may cost you points. If losers_not_ranked is set, we prevent this behavior and make sure you only gain/loss ELO when you get the corresponding results.&lt;br /&gt;
&lt;br /&gt;
Important: this SHOULD NOT be used for cooperative games (see is_coop parameter), or for 2 players games (it makes no sense in this case).&lt;br /&gt;
&lt;br /&gt;
=== Solo ===&lt;br /&gt;
&lt;br /&gt;
If game supports solo variant, a negative or zero score means defeat, a positive score means victory.&lt;br /&gt;
&lt;br /&gt;
=== Player elimination ===&lt;br /&gt;
&lt;br /&gt;
In some games, this is useful to eliminate a player from the game in order he/she can start another game without waiting for the current game end.&lt;br /&gt;
&lt;br /&gt;
This case should be rare. Please don&#039;t use player elimination feature if some player just has to wait the last 10% of the game for game end. This feature should be used only in games where players are eliminated all along the game (typical examples: &amp;quot;Perudo&amp;quot; or &amp;quot;The Werewolves of Miller&#039;s Hollow&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
&lt;br /&gt;
* Player to eliminate should NOT be active anymore (preferably use the feature in a &amp;quot;game&amp;quot; type game state).&lt;br /&gt;
* In your PHP code:&lt;br /&gt;
  self::eliminatePlayer( &amp;lt;player_to_eliminate_id&amp;gt; );&lt;br /&gt;
* the player is informed in a dialog box that he no longer have to play and can start another game if he/she wants too (with buttons &amp;quot;stay at this table&amp;quot; &amp;quot;quit table and back to main site&amp;quot;). In any case, the player is free to start &amp;amp; join another table from now.&lt;br /&gt;
* When your game is over, all players who have been eliminated before receive a &amp;quot;notification&amp;quot; (the small &amp;quot;!&amp;quot; icon on the top right of the BGA interface) that indicate them that &amp;quot;the game has ended&amp;quot; and invite them to review the game results.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important: this should not be used on a player who has already left the game (&amp;quot;zombie&amp;quot;) as leaving/being kicked of the game (outside of the scope of the rules) is not the same as being eliminated from the game (according to the rules), except if in the course of the game, the zombie player is eliminated according to the rules.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note: When all surviving players are eliminated at the same time BGA framework causes the game to be abandoned automatically.&#039;&#039;&#039;&lt;br /&gt;
&#039;&#039;&#039;To circumvent this, the game should leave 1 player not eliminated but change final scores accordingly and end the game.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Scoring Helper functions ===&lt;br /&gt;
&lt;br /&gt;
These functions should have been API but they are not, just add them to your php game and use for every game.&lt;br /&gt;
&lt;br /&gt;
    // get score&lt;br /&gt;
    function dbGetScore($player_id) {&lt;br /&gt;
        return $this-&amp;gt;getUniqueValueFromDB(&amp;quot;SELECT player_score FROM player WHERE player_id=&#039;$player_id&#039;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // set score&lt;br /&gt;
    function dbSetScore($player_id, $count) {&lt;br /&gt;
        $this-&amp;gt;DbQuery(&amp;quot;UPDATE player SET player_score=&#039;$count&#039; WHERE player_id=&#039;$player_id&#039;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // set aux score (tie breaker)&lt;br /&gt;
    function dbSetAuxScore($player_id, $score) {&lt;br /&gt;
        $this-&amp;gt;DbQuery(&amp;quot;UPDATE player SET player_score_aux=$score WHERE player_id=&#039;$player_id&#039;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // increment score (can be negative too)&lt;br /&gt;
    function dbIncScore($player_id, $inc) {&lt;br /&gt;
        $count = $this-&amp;gt;dbGetScore($player_id);&lt;br /&gt;
        if ($inc != 0) {&lt;br /&gt;
            $count += $inc;&lt;br /&gt;
            $this-&amp;gt;dbSetScore($player_id, $count);&lt;br /&gt;
        }&lt;br /&gt;
        return $count;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
== Reflexion time ==&lt;br /&gt;
&lt;br /&gt;
; function giveExtraTime( $player_id, $specific_time=null )&lt;br /&gt;
: Give standard extra time to this player.&lt;br /&gt;
: Standard extra time depends on the speed of the game (small with &amp;quot;slow&amp;quot; game option, bigger with other options).&lt;br /&gt;
: You can also specify an exact time to add, in seconds, with the &amp;quot;specified_time&amp;quot; argument (rarely used).&lt;br /&gt;
&lt;br /&gt;
; function isAsync()&lt;br /&gt;
: Returns true if game is turn based, false if it is realtime&lt;br /&gt;
&lt;br /&gt;
== Undo moves ==&lt;br /&gt;
&lt;br /&gt;
Please read our [[BGA Undo policy]] before.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important&#039;&#039;&#039;: Before using these methods, you must also add the following to your &amp;quot;gameinfos.inc.php&amp;quot; file, otherwise these methods are ineffective:&lt;br /&gt;
  &#039;db_undo_support&#039; =&amp;gt; true&lt;br /&gt;
&lt;br /&gt;
Note: if you deploy undo support after game is in production this will take into effect for new games only, old games will give user an error if user choses Undo action, but otherwise it should not affect them.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; function undoSavepoint( )&lt;br /&gt;
: Save the whole game situation inside an &amp;quot;Undo save point&amp;quot;.&lt;br /&gt;
: There is only ONE undo save point available (see [[BGA Undo policy]]). Cannot use in multiactivate state or in game state where next state is multiactive.&lt;br /&gt;
: Note: this function does not actually do anything when it is called, it only raises the flag to store the database AFTER transaction is over. So the actual state will be saved when you exit the function  calling it (technically before first queued notification is sent, which matters if you transition to game state not to user state after), this may affect what you end up saving.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; function undoRestorePoint()&lt;br /&gt;
: Restore the situation previously saved as an &amp;quot;Undo save point&amp;quot;.&lt;br /&gt;
: You must make sure that the active player is the same after and before the undoRestorePoint (ie: this is your responsibility to ensure that the player that is active when this method is called is exactly the same than the player that was active when the undoSavePoint method has been called).&lt;br /&gt;
&lt;br /&gt;
    function actionUndo() {&lt;br /&gt;
        self::checkAction(&#039;actionUndo&#039;);&lt;br /&gt;
        $this-&amp;gt;undoRestorePoint();&lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;nextState(&#039;next&#039;); // transition to single player state (i.e. beginning of player actions for this turn)&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important note&#039;&#039;&#039;: if you are reading game state variable right after restore (without changing state first) it won&#039;t work properly as the global table cache is not automatically refreshed after undoRestorePoint(). So you should either change state immediately to refresh game state values, or use $this-&amp;gt;gamestate-&amp;gt;reloadState() to refresh the state. If you choose to do the latest, be aware that this will bring the state machine back to the state during which the save point snapshot has been taken using undoSavepoint() (which means your transition you do after has to declared in the state which was saved, not in the state which was active for your actionUndo())&lt;br /&gt;
&lt;br /&gt;
== Managing errors and exceptions ==&lt;br /&gt;
&lt;br /&gt;
Note: when you throw an exception, all database changes and all notifications are cancelled immediately. This way, the game situation that existed before the request is completely restored.&lt;br /&gt;
&lt;br /&gt;
; throw new BgaUserException ( $error_message)&lt;br /&gt;
: Base class to notify a user error&lt;br /&gt;
: You must throw this exception when a player wants to do something that they are not allowed to do.&lt;br /&gt;
: The error message will be shown to the player as a &amp;quot;red message&amp;quot;.&lt;br /&gt;
: The error message must be translated, make sure you use self::_() or $this-&amp;gt;_() here and NOT clientranslate()&lt;br /&gt;
: Throwing such an exception is NOT considered a bug, so it is not traced in BGA error logs.&lt;br /&gt;
&lt;br /&gt;
Example from Gomoku:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     throw new BgaUserException( self::_(&amp;quot;There is already a stone on this intersection, you can&#039;t play there&amp;quot;) );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; throw new BgaVisibleSystemException ( $error_message)&lt;br /&gt;
: You must throw this exception when you detect something that is not supposed to happened in your code.&lt;br /&gt;
: The error message is shown to the user as an &amp;quot;Unexpected error&amp;quot;, in order that he can report it in the forum.&lt;br /&gt;
: The error message is logged in BGA error logs. If it happens regularly, we will report it to you.&lt;br /&gt;
&lt;br /&gt;
; throw new BgaSystemException ( $error_message)&lt;br /&gt;
: Base class to notify a system exception. The message will be hidden from the user, but show in the logs. Use this if the message contains technical information.&lt;br /&gt;
: You shouldn&#039;t use this type of exception except if you think the information shown could be critical. Indeed: a generic error message will be shown to the user, so it&#039;s going to be difficult for you to see what happened.&lt;br /&gt;
&lt;br /&gt;
== Zombie mode ==&lt;br /&gt;
&lt;br /&gt;
When a player leaves a game for any reason (expelled, quit), he becomes a &amp;quot;zombie player&amp;quot;. In this case, the results of the game won&#039;t count for statistics, but this is cool if the other players can finish the game anyway. That&#039;s why zombie mode exists: allow the other player to finish the game, even if the situation is not ideal.&lt;br /&gt;
&lt;br /&gt;
While developing your zombie mode, keep in mind that:&lt;br /&gt;
* Do not refer to the rules, because this situation is not planned by the rules.&lt;br /&gt;
* Try to figure that you are playing with your friends and one of them has to leave: how can we finish the game without killing the spirit of the game?&lt;br /&gt;
* The idea is NOT to develop an artificial intelligence for the game.&lt;br /&gt;
* Do not try to end the game early, even in a two-player game. The zombie is there to allow the game to continue, not to end it. Trying to end the game is not supported by the framework and will likely cause unexpected errors.&lt;br /&gt;
&lt;br /&gt;
Most of the time, the best thing to do when it is zombie player turn is to jump immediately to a state where he is not active anymore. For example, if he is in a game state where he has a choice between playing A and playing B, the best thing to do is NOT to choose A or B, but to pass. So, even if there&#039;s no &amp;quot;pass&amp;quot; action in the rules, add a &amp;quot;zombiepass&amp;quot; transitition in your game state and use it.&lt;br /&gt;
&lt;br /&gt;
Each time a zombie player must play, your &amp;quot;zombieTurn&amp;quot; method is called.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
* $state: the name of the current game state.&lt;br /&gt;
* $active_player: the id of the active player.&lt;br /&gt;
&lt;br /&gt;
Most of the time, your zombieTurn method looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    function zombieTurn( $state, $active_player )&lt;br /&gt;
    {&lt;br /&gt;
    	$statename = $state[&#039;name&#039;];&lt;br /&gt;
&lt;br /&gt;
        if( $statename == &#039;myFirstGameState&#039;&lt;br /&gt;
             ||  $statename == &#039;my2ndGameState&#039;&lt;br /&gt;
             ||  $statename == &#039;my3rdGameState&#039;&lt;br /&gt;
               ....&lt;br /&gt;
           )&lt;br /&gt;
        {&lt;br /&gt;
            $this-&amp;gt;gamestate-&amp;gt;nextState( &amp;quot;zombiePass&amp;quot; );&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            throw new BgaVisibleSystemException( &amp;quot;Zombie mode not supported at this game state: &amp;quot;.$statename );&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that in the example above, all corresponding game state should implement &amp;quot;zombiePass&amp;quot; as a transition.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Very important&#039;&#039;&#039;: your zombie code will be called when the player leaves the game. This action is triggered from the main site and propagated to the gameserver from a server, not from a browser. As a consequence, there is no current player associated to this action. In your zombieTurn function, you must &#039;&#039;&#039;never&#039;&#039;&#039; use getCurrentPlayerId() or getCurrentPlayerName(), otherwise it will fail with a &amp;quot;Not logged&amp;quot; error message.&lt;br /&gt;
&lt;br /&gt;
== Player color preferences ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
BGA players (Club members) may now choose their preferred color for playing. For example, if they are used to play green for every board game, they can select &amp;quot;green&amp;quot; in their BGA preferences page.&lt;br /&gt;
&lt;br /&gt;
Making your game compatible with colors preferences is very easy and requires only 1 line of configuration change:&lt;br /&gt;
&lt;br /&gt;
On your gameinfos.inc.php file, add the following lines :&lt;br /&gt;
&lt;br /&gt;
  // Favorite colors support: if set to &amp;quot;true&amp;quot;, support attribution of favorite colors based on player&#039;s preferences (see reattributeColorsBasedOnPreferences PHP method)&lt;br /&gt;
  // NB: this parameter is used only to flag games supporting this feature; you must use (or not use) reattributeColorsBasedOnPreferences PHP method to actually enable or disable the feature.&lt;br /&gt;
  &#039;favorite_colors_support&#039; =&amp;gt; true,&lt;br /&gt;
&lt;br /&gt;
Then, on your main &amp;lt;your_game&amp;gt;.game.php file check the code of &amp;quot;setupNewGame&amp;quot;. New template already have correct code, but if you editing very old game and it may be absent.&lt;br /&gt;
&lt;br /&gt;
        $gameinfos = $this-&amp;gt;getGameinfos();&lt;br /&gt;
        ...&lt;br /&gt;
        if ($gameinfos[&#039;favorite_colors_support&#039;])&lt;br /&gt;
            $this-&amp;gt;reattributeColorsBasedOnPreferences($players, $gameinfos[&#039;player_colors&#039;]); // this should be above reloadPlayersBasicInfos()&lt;br /&gt;
        self::reloadPlayersBasicInfos();&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;reattributeColorsBasedOnPreferences&amp;quot; method reattributes all colors, taking into account players color preferences and available colors.&lt;br /&gt;
&lt;br /&gt;
Note that you must update the colors to indicate the colors available for your game.&lt;br /&gt;
&lt;br /&gt;
Some important remarks:&lt;br /&gt;
* for some games (i.e. Chess), the color has an influence on a mechanism of the game, most of the time by giving a special advantage to a player (i.e. Starting the game). Color preference mechanism must NOT be used in such a case.&lt;br /&gt;
* your logic should NEVER consider that the first player has the color X, that the second player has the color Y, and so on. If this is the case, your game will NOT be compatible with reattributeColorsBasedOnPreferences as this method attribute colors to players based on their preferences and not based as their order at the table.&lt;br /&gt;
&lt;br /&gt;
Colours currently listed as a choice in preferences (Note - you don&#039;t have to pick these, the &amp;quot;closest&amp;quot; color will be found):&lt;br /&gt;
&lt;br /&gt;
* #ff0000 Red&lt;br /&gt;
* #008000 Green&lt;br /&gt;
* #0000ff Blue&lt;br /&gt;
* #ffa500 Yellow&lt;br /&gt;
* #000000 Black&lt;br /&gt;
* #ffffff White&lt;br /&gt;
* #e94190 Pink&lt;br /&gt;
* #982fff Purple&lt;br /&gt;
* #72c3b1 Cyan&lt;br /&gt;
* #f07f16 Orange&lt;br /&gt;
* #bdd002 Khaki green&lt;br /&gt;
* #7b7b7b Gray&lt;br /&gt;
&lt;br /&gt;
== Legacy games API ==&lt;br /&gt;
&lt;br /&gt;
For some very specific games (&amp;quot;legacy&amp;quot;, &amp;quot;campaign&amp;quot;), you need to keep some informations from a game to another.&lt;br /&gt;
&lt;br /&gt;
This should be an exceptional situation: the legacy API is costing resources on Board Game Arena databases, and is slowing down the game setup process + game end of game process. Please do not use it for things like:&lt;br /&gt;
* keeping a player preference/settings (=&amp;gt; player preferences and game options should be used instead)&lt;br /&gt;
* keeping a statistics, a score, or a ranking, while it is not planned in the physical board game, or while there is no added value compared to BGA statistics / rankings.&lt;br /&gt;
&lt;br /&gt;
You should use it for:&lt;br /&gt;
* legacy games: when some components of the game has been altered in a previous game and should be kept as it is.&lt;br /&gt;
* &amp;quot;campaign style&amp;quot; games: when a player is getting a &amp;quot;reward&amp;quot; at the end of a game, and should be able to use it in further games.&lt;br /&gt;
&lt;br /&gt;
Important: you cannot store more than 64k of data (serialized as JSON) per player per game. If you go over 64k, storeLegacyData function is going to FAIL, and there is a risk to create a major bug (= players blocked) in your game. You MUST make sure that no more than 64k of data is used for each player for your game. For example, if you are implementing a &amp;quot;campaign style&amp;quot; game and if you allow a player to start multiple campaign, you must LIMIT the number of different campaign so that the total data size to not go over the limit. We strongly recommend you to use this:&lt;br /&gt;
&lt;br /&gt;
  try &lt;br /&gt;
  {&lt;br /&gt;
  	$this-&amp;gt;storeLegacyTeamData( $my_data );&lt;br /&gt;
  }&lt;br /&gt;
  catch( feException $e ) // feException is a base class of BgaSystemException and others...&lt;br /&gt;
  {&lt;br /&gt;
  	if( $e-&amp;gt;getCode() == FEX_legacy_size_exceeded )&lt;br /&gt;
  	{&lt;br /&gt;
  		// Do something here to free some space in Legacy data (ex: by removing some variables)&lt;br /&gt;
  	}&lt;br /&gt;
  	else&lt;br /&gt;
  		throw $e;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
The keys may only contain letters and numbers, underscore seems not to be allowed.&lt;br /&gt;
&lt;br /&gt;
; function storeLegacyData( $player_id, $key, $data, $ttl = 365 )&lt;br /&gt;
: Store some data associated with $key for the given user / current game&lt;br /&gt;
: In the opposite of all other game data, this data will PERSIST after the end of this table, and can be re-used&lt;br /&gt;
: in a future table with the same game.&lt;br /&gt;
: IMPORTANT: The only possible place where you can use this method is when the game is over at your table (last game action). Otherwise, there is a risk of conflicts between ongoing games.    &lt;br /&gt;
: TTL is a time-to-live: the maximum, and default, is 365 days.&lt;br /&gt;
: In any way, the total data (= all keys) you can store for a given user+game is 64k (note: data is store serialized as JSON data)&lt;br /&gt;
: NOTICE: You can store some persistant data across all tables from your game using the specific player_id 0 which is unused. In such case, it&#039;s even more important to manage correctly the size of your data to avoid any exception or issue while storing updated data (ie. you can use this for some kind of leaderbord for solo game or contest)&lt;br /&gt;
&lt;br /&gt;
; function retrieveLegacyData( $player_id, $key )&lt;br /&gt;
: Get data associated with $key for the current game&lt;br /&gt;
: This data is common to ALL tables from the same game for this player, and persist from one table to another.&lt;br /&gt;
: Note: calling this function has an important cost =&amp;gt; please call it few times (possibly: only ONCE) for each player for 1 game if possible&lt;br /&gt;
: Note: you can use &#039;%&#039; in $key to retrieve all keys matching the given patterns&lt;br /&gt;
&lt;br /&gt;
; function removeLegacyData( $player_id, $key )&lt;br /&gt;
: Remove some legacy data with the given key&lt;br /&gt;
: (useful to free some data to avoid going over 64k)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; function storeLegacyTeamData( $data, $ttl = 365 )&lt;br /&gt;
: Same as storeLegacyData, except that it stores some data for the whole team within the current table and does not use a key&lt;br /&gt;
: Ie: if players A, B and C are at a table, the legacy data will be saved for future table with (exactly) A, B and C on the table.&lt;br /&gt;
: This is useful for games which are intended to be played several time by the same team.&lt;br /&gt;
: Note: the data total size is still limited, so you must implement catch the FEX_legacy_size_exceeded exception if it happens&lt;br /&gt;
&lt;br /&gt;
; function retrieveLegacyTeamData()&lt;br /&gt;
: Same as retrieveLegacyData, except that it retrieves some data for the whole team within the current table (set by storeLegacyTeamData)&lt;br /&gt;
&lt;br /&gt;
; function removeLegacyTeamData()&lt;br /&gt;
: Same as removeLegacyData, except that it retrieves some data for the whole team within the current table (set by storeLegacyTeamData)&lt;br /&gt;
&lt;br /&gt;
== Language dependent games API ==&lt;br /&gt;
&lt;br /&gt;
This API is used for games that are heavily language dependent. Two most common use cases are:&lt;br /&gt;
* Games that have a language dependent component that are not necessarily translatable, typically a list of words. (Think of games like Codenames, Decrypto, Just One...)&lt;br /&gt;
* Games with massive communication where players would like to ensure that all participants speak the same language. (Think of games like Werewolf, The Resistance, maybe even dixit...)&lt;br /&gt;
&lt;br /&gt;
If this option is used, the table created will be limited only to users that have specific language in their profile. Player starting the game would be able to chose one of the languages he speaks.&lt;br /&gt;
&lt;br /&gt;
There is a new property language_dependency in gameinfos.inc.php which can be set like this:&lt;br /&gt;
  &#039;language_dependency&#039; =&amp;gt; false,  //or if the property is missing, the game is not language dependent&lt;br /&gt;
  &#039;language_dependency&#039; =&amp;gt; true, //all players at the table must speak the same language&lt;br /&gt;
  &#039;language_dependency&#039; =&amp;gt; array( 1 =&amp;gt; &#039;en&#039;, 2 =&amp;gt; &#039;fr&#039;, 3 =&amp;gt; &#039;it&#039; ), //1-based list of supported languages&lt;br /&gt;
&lt;br /&gt;
In the gamename.game.php file, you can get the id of selected language with the method &#039;&#039;&#039;getGameLanguage&#039;&#039;&#039;.&lt;br /&gt;
; function getGameLanguage()&lt;br /&gt;
: Returns an index of the selected language as defined in gameinfos.inc.php.&lt;br /&gt;
&lt;br /&gt;
Languages currently available on BGA are:&lt;br /&gt;
  &#039;ar&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;العربية&amp;quot;, &#039;code&#039; =&amp;gt; &#039;ar_AE&#039; ),             // Arabic&lt;br /&gt;
  &#039;be&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;беларуская мова&amp;quot;, &#039;code&#039; =&amp;gt; &#039;be_BY&#039; ),     // Belarusian&lt;br /&gt;
  &#039;bn&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;বাংলা&amp;quot;, &#039;code&#039; =&amp;gt; &#039;bn_BD&#039; ),                // Bengali&lt;br /&gt;
  &#039;bg&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;български език&amp;quot;, &#039;code&#039; =&amp;gt; &#039;bg_BG&#039; ),      // Bulgarian&lt;br /&gt;
  &#039;ca&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;català&amp;quot;, &#039;code&#039; =&amp;gt; &#039;ca_ES&#039; ),              // Catalan&lt;br /&gt;
  &#039;cs&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;čeština&amp;quot;, &#039;code&#039; =&amp;gt; &#039;cs_CZ&#039; ),             // Czech&lt;br /&gt;
  &#039;da&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;dansk&amp;quot;, &#039;code&#039; =&amp;gt; &#039;da_DK&#039; ),               // Danish&lt;br /&gt;
  &#039;de&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;deutsch&amp;quot;, &#039;code&#039; =&amp;gt; &#039;de_DE&#039; ),             // German&lt;br /&gt;
  &#039;el&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;Ελληνικά&amp;quot;, &#039;code&#039; =&amp;gt; &#039;el_GR&#039; ),            // Greek&lt;br /&gt;
  &#039;en&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;English&amp;quot;, &#039;code&#039; =&amp;gt; &#039;en_US&#039; ),             // English&lt;br /&gt;
  &#039;es&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;español&amp;quot;, &#039;code&#039; =&amp;gt; &#039;es_ES&#039; ),             // Spanish&lt;br /&gt;
  &#039;et&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;eesti keel&amp;quot;, &#039;code&#039; =&amp;gt; &#039;et_EE&#039; ),          // Estonian       &lt;br /&gt;
  &#039;fi&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;suomi&amp;quot;, &#039;code&#039; =&amp;gt; &#039;fi_FI&#039; ),               // Finnish&lt;br /&gt;
  &#039;fr&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;français&amp;quot;, &#039;code&#039; =&amp;gt; &#039;fr_FR&#039; ),            // French&lt;br /&gt;
  &#039;he&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;עברית&amp;quot;, &#039;code&#039; =&amp;gt; &#039;he_IL&#039; ),               // Hebrew       &lt;br /&gt;
  &#039;hi&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;हिन्दी&amp;quot;, &#039;code&#039; =&amp;gt; &#039;hi_IN&#039; ),                 // Hindi&lt;br /&gt;
  &#039;hr&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;Hrvatski&amp;quot;, &#039;code&#039; =&amp;gt; &#039;hr_HR&#039; ),            // Croatian&lt;br /&gt;
  &#039;hu&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;magyar&amp;quot;, &#039;code&#039; =&amp;gt; &#039;hu_HU&#039; ),              // Hungarian&lt;br /&gt;
  &#039;id&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;Bahasa Indonesia&amp;quot;, &#039;code&#039; =&amp;gt; &#039;id_ID&#039; ),    // Indonesian&lt;br /&gt;
  &#039;ms&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;Bahasa Malaysia&amp;quot;, &#039;code&#039; =&amp;gt; &#039;ms_MY&#039; ),     // Malaysian&lt;br /&gt;
  &#039;it&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;italiano&amp;quot;, &#039;code&#039; =&amp;gt; &#039;it_IT&#039; ),            // Italian&lt;br /&gt;
  &#039;ja&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;日本語&amp;quot;, &#039;code&#039; =&amp;gt; &#039;ja_JP&#039; ),               // Japanese&lt;br /&gt;
  &#039;jv&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;Basa Jawa&amp;quot;, &#039;code&#039; =&amp;gt; &#039;jv_JV&#039; ),           // Javanese                       &lt;br /&gt;
  &#039;ko&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;한국어&amp;quot;, &#039;code&#039; =&amp;gt; &#039;ko_KR&#039; ),               // Korean&lt;br /&gt;
  &#039;lt&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;lietuvių&amp;quot;, &#039;code&#039; =&amp;gt; &#039;lt_LT&#039; ),            // Lithuanian&lt;br /&gt;
  &#039;lv&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;latviešu&amp;quot;, &#039;code&#039; =&amp;gt; &#039;lv_LV&#039; ),            // Latvian&lt;br /&gt;
  &#039;nl&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;nederlands&amp;quot;, &#039;code&#039; =&amp;gt; &#039;nl_NL&#039; ),          // Dutch&lt;br /&gt;
  &#039;no&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;norsk&amp;quot;, &#039;code&#039; =&amp;gt; &#039;nb_NO&#039; ),               // Norwegian&lt;br /&gt;
  &#039;oc&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;occitan&amp;quot;, &#039;code&#039; =&amp;gt; &#039;oc_FR&#039; ),             // Occitan&lt;br /&gt;
  &#039;pl&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;polski&amp;quot;, &#039;code&#039; =&amp;gt; &#039;pl_PL&#039; ),              // Polish&lt;br /&gt;
  &#039;pt&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;português&amp;quot;,  &#039;code&#039; =&amp;gt; &#039;pt_PT&#039; ),          // Portuguese&lt;br /&gt;
  &#039;ro&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;română&amp;quot;,  &#039;code&#039; =&amp;gt; &#039;ro_RO&#039;  ),            // Romanian&lt;br /&gt;
  &#039;ru&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;Русский язык&amp;quot;, &#039;code&#039; =&amp;gt; &#039;ru_RU&#039; ),        // Russian&lt;br /&gt;
  &#039;sk&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;slovenčina&amp;quot;, &#039;code&#039; =&amp;gt; &#039;sk_SK&#039; ),          // Slovak&lt;br /&gt;
  &#039;sl&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;slovenščina&amp;quot;, &#039;code&#039; =&amp;gt; &#039;sl_SI&#039; ),         // Slovenian       &lt;br /&gt;
  &#039;sr&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;Српски&amp;quot;, &#039;code&#039; =&amp;gt; &#039;sr_RS&#039; ),              // Serbian       &lt;br /&gt;
  &#039;sv&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;svenska&amp;quot;, &#039;code&#039; =&amp;gt; &#039;sv_SE&#039; ),             // Swedish&lt;br /&gt;
  &#039;tr&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;Türkçe&amp;quot;, &#039;code&#039; =&amp;gt; &#039;tr_TR&#039; ),              // Turkish       &lt;br /&gt;
  &#039;uk&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;Українська мова&amp;quot;, &#039;code&#039; =&amp;gt; &#039;uk_UA&#039; ),     // Ukrainian&lt;br /&gt;
  &#039;zh&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;中文 (漢)&amp;quot;,  &#039;code&#039; =&amp;gt; &#039;zh_TW&#039; ),           // Traditional Chinese (Hong Kong, Macau, Taiwan)&lt;br /&gt;
  &#039;zh-cn&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;中文 (汉)&amp;quot;, &#039;code&#039; =&amp;gt; &#039;zh_CN&#039; ),         // Simplified Chinese (Mainland China, Singapore)&lt;br /&gt;
&lt;br /&gt;
== Debugging and Tracing ==&lt;br /&gt;
&lt;br /&gt;
To debug php code you can use some tracing functions available from the parent class such as debug, trace, error, warn, dump.&lt;br /&gt;
  &lt;br /&gt;
  self::debug(&amp;quot;Ahh!&amp;quot;);&lt;br /&gt;
  self::dump(&#039;my_var&#039;,$my_var);&lt;br /&gt;
&lt;br /&gt;
See [[Practical_debugging]] section for complete information about debugging interfaces and where to find logs.&lt;br /&gt;
&lt;br /&gt;
[[Category:Studio]]&lt;/div&gt;</summary>
		<author><name>SwHawk</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Main_game_logic:_Game.php&amp;diff=13959</id>
		<title>Main game logic: Game.php</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Main_game_logic:_Game.php&amp;diff=13959"/>
		<updated>2022-07-12T19:16:21Z</updated>

		<summary type="html">&lt;p&gt;SwHawk: /* Use globals */ changed static methods calls to normal methods to reflect current state of framework&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Studio_Framework_Navigation}}&lt;br /&gt;
&lt;br /&gt;
This is the main file for your game logic. Here you initialize the game, persist data, implement the rules and notify the client interface of changes.&lt;br /&gt;
&lt;br /&gt;
== File Structure ==&lt;br /&gt;
&lt;br /&gt;
The details of how the file is structured are described directly with comments in the code skeleton provided to you.&lt;br /&gt;
 &lt;br /&gt;
Here is the basic structure:&lt;br /&gt;
&lt;br /&gt;
* Constructor: where you define global variables.&lt;br /&gt;
* setupNewGame: initial setup of the game. Takes an array of players, indexed by player_id. Structure of each player includes player_name, player_canal, player_avatar, and flags indicating admin/ai/premium/order/language/beginner.&lt;br /&gt;
* getAllDatas: where you retrieve all game data during a complete reload of the game. Return value must be associative array. Value of &#039;players&#039; is reserved for returning players data from players table, if you set it it must follow certain rules &lt;br /&gt;
        $result [&#039;players&#039;] = self::getCollectionFromDb(&amp;quot;SELECT player_id id, player_score score, player_no no, player_color color FROM player&amp;quot;);&lt;br /&gt;
        // Returned value must include [&#039;players&#039;][$player_id]][&#039;score&#039;] for scores to populate when F5 is pressed.&lt;br /&gt;
* getGameProgression: where you compute the game progression indicator. Returns a number indicating percent of progression (0-100)&lt;br /&gt;
* Utility functions: your utility functions.&lt;br /&gt;
* Player actions: the entry points for players actions ([https://en.doc.boardgamearena.com/Players_actions:_yourgamename.action.php more info here]). &lt;br /&gt;
* Game state arguments: methods to return additional data on specific game states ([http://en.doc.boardgamearena.com/Your_game_state_machine:_states.inc.php#args more info here]).&lt;br /&gt;
* Game state actions: the logic to run when entering a new game state ([http://en.doc.boardgamearena.com/Your_game_state_machine:_states.inc.php#action more info here]).&lt;br /&gt;
* zombieTurn: what to do it&#039;s the turn of a zombie player.&lt;br /&gt;
* upgradeTableDb: function to migrate database if you change it after release on production.&lt;br /&gt;
&lt;br /&gt;
== Accessing player information ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important&#039;&#039;&#039;: In the following methods, be mindful of the difference between the &amp;quot;active&amp;quot; player and the &amp;quot;current&amp;quot; player. The &#039;&#039;&#039;active&#039;&#039;&#039; player is the player whose turn it is - not necessarily the player who sent a request! The &#039;&#039;&#039;current&#039;&#039;&#039; player is the player who sent the request and will see the results returned by your methods: not necessarily the player whose turn it is!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; getPlayersNumber()&lt;br /&gt;
: Returns the number of players playing at the table&lt;br /&gt;
: Note: doesn&#039;t work in setupNewGame (use count($players) instead).&lt;br /&gt;
&lt;br /&gt;
; getActivePlayerId()&lt;br /&gt;
: Get the &amp;quot;active_player&amp;quot;, whatever what is the current state type.&lt;br /&gt;
: Note: it does NOT mean that this player is active right now, because state type could be &amp;quot;game&amp;quot; or &amp;quot;multiplayer&amp;quot;&lt;br /&gt;
: Note: avoid using this method in a &amp;quot;multiplayer&amp;quot; state because it does not mean anything.&lt;br /&gt;
&lt;br /&gt;
; getActivePlayerName()&lt;br /&gt;
: Get the &amp;quot;active_player&amp;quot; name&lt;br /&gt;
: Note: avoid using this method in a &amp;quot;multiplayer&amp;quot; state because it does not mean anything.&lt;br /&gt;
&lt;br /&gt;
; getPlayerNameById($player_id)&lt;br /&gt;
: Get the name by id&lt;br /&gt;
&lt;br /&gt;
; getPlayerColorById($player_id)&lt;br /&gt;
: Get the color by id&lt;br /&gt;
&lt;br /&gt;
; getPlayerNoById($player_id)&lt;br /&gt;
: Get &#039;player_no&#039; (number) by id&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; loadPlayersBasicInfos()&lt;br /&gt;
: Get an associative array with generic data about players (ie: not game specific data).&lt;br /&gt;
: The key of the associative array is the player id. The returned table is cached, so ok to call multiple times without performance concerns.&lt;br /&gt;
: &amp;lt;code&amp;gt;array_keys($this-&amp;gt;loadPlayersBasicInfos())&amp;lt;/code&amp;gt; will therefore returns an array containing players id&lt;br /&gt;
: The content of each value is:&lt;br /&gt;
: * player_name - the name of the player&lt;br /&gt;
: * player_color (ex: ff0000) - the color code of the player&lt;br /&gt;
: * player_no - the position of the player at the start of the game in natural table order, i.e. 1,2,3&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                $players = $this-&amp;gt;loadPlayersBasicInfos();&lt;br /&gt;
                foreach ($players as $player_id =&amp;gt; $info) {&lt;br /&gt;
                    $player_color = $info[&#039;player_color&#039;];&lt;br /&gt;
                    ...&lt;br /&gt;
                }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: if you want array of player ids only you can do this:&lt;br /&gt;
    $player_ids =  array_keys($this-&amp;gt;loadPlayersBasicInfos());  &lt;br /&gt;
&lt;br /&gt;
; getCurrentPlayerId()&lt;br /&gt;
: Get the &amp;quot;current_player&amp;quot;. The current player is the one from which the action originated (the one who sent the request).&lt;br /&gt;
: &#039;&#039;&#039;Be careful&#039;&#039;&#039;: This is not necessarily the active player!&lt;br /&gt;
: In general, you shouldn&#039;t use this method, unless you are in &amp;quot;multiplayer&amp;quot; state.&lt;br /&gt;
: &#039;&#039;&#039;Very important&#039;&#039;&#039;: in your setupNewGame and zombieTurn function, you must never use getCurrentPlayerId() or getCurrentPlayerName(), otherwise it will fail with a &amp;quot;Not logged&amp;quot; error message (these actions are triggered from the main site and propagated to the gameserver from a server, not from a browser. As a consequence, there is no current player associated to these actions).&lt;br /&gt;
&lt;br /&gt;
; getCurrentPlayerName()&lt;br /&gt;
: Get the &amp;quot;current_player&amp;quot; name&lt;br /&gt;
: Be careful using this method (see above).&lt;br /&gt;
&lt;br /&gt;
; getCurrentPlayerColor()&lt;br /&gt;
: Get the &amp;quot;current_player&amp;quot; color&lt;br /&gt;
: Be careful using this method (see above).&lt;br /&gt;
&lt;br /&gt;
; isCurrentPlayerZombie()&lt;br /&gt;
: Check the &amp;quot;current_player&amp;quot; zombie status. If true, player is zombie, i.e. left or was kicked out of the game.&lt;br /&gt;
&lt;br /&gt;
; isSpectator()&lt;br /&gt;
: Check the &amp;quot;current_player&amp;quot; spectator status. If true, the user accessing the game is a spectator (not part of the game). For this user, the interface should display all public information, and no private information (like a friend sitting at the same table as players and just spectating the game).&lt;br /&gt;
&lt;br /&gt;
; getActivePlayerColor()&lt;br /&gt;
: This function does not seems to exist in API, if you need it here is implementation&lt;br /&gt;
      function getActivePlayerColor() {&lt;br /&gt;
        $player_id = self::getActivePlayerId();&lt;br /&gt;
        $players = self::loadPlayersBasicInfos();&lt;br /&gt;
        if (isset($players[$player_id]))&lt;br /&gt;
            return $players[$player_id][&#039;player_color&#039;];&lt;br /&gt;
        else&lt;br /&gt;
            return null;&lt;br /&gt;
    }&lt;br /&gt;
; isPlayerZombie($player_id)&lt;br /&gt;
: This method does not exists, but if you need it it looks like this&lt;br /&gt;
    protected function isPlayerZombie($player_id) {&lt;br /&gt;
        $players = self::loadPlayersBasicInfos();&lt;br /&gt;
        if (! isset($players[$player_id]))&lt;br /&gt;
            throw new BgaSystemException(&amp;quot;Player $player_id is not playing here&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        return ($players[$player_id][&#039;player_zombie&#039;] == 1);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
== Accessing the database ==&lt;br /&gt;
&lt;br /&gt;
The main game logic should be the only point from which you should access the game database. You access your database using SQL queries with the methods below.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;IMPORTANT&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
BGA uses [http://dev.mysql.com/doc/refman/5.0/en/sql-syntax-transactions.html database transactions]. This means that your database changes WON&#039;T BE APPLIED to the database until your request ends normally (web request, not database request). Using transactions is in fact very useful for you; at any time, if your game logic detects that something is wrong (example: a disallowed move), you just have to throw an exception and all changes to the game situation will be removed. This also means that you need not (and in fact cannot) use your own transactions for multiple related database operations.&lt;br /&gt;
&lt;br /&gt;
However there are sets of database operation that initite implicit commit (most common mistake is to use &amp;quot;TRUNCATE&amp;quot;), you cannot use these operations during the game, it breaks the unrolling of transactions and will lead to nasty issues&lt;br /&gt;
(https://mariadb.com/kb/en/sql-statements-that-cause-an-implicit-commit).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; DbQuery( $sql )&lt;br /&gt;
: This is the generic method to access the database.&lt;br /&gt;
: It can execute any type of SELECT/UPDATE/DELETE/REPLACE/INSERT query on the database.&lt;br /&gt;
: For SELECT queries, the specialized methods below are much better.&lt;br /&gt;
: Do not use method for TUNCATE, DROP and other table altering operations. See disclamer above about implicit commits. If you really need TRUNCATE use DELETE FROM xxx instead.&lt;br /&gt;
&lt;br /&gt;
; getUniqueValueFromDB( $sql )&lt;br /&gt;
: Returns a unique value from DB or null if no value is found.&lt;br /&gt;
: $sql must be a SELECT query.&lt;br /&gt;
: Raise an exception if more than 1 row is returned.&lt;br /&gt;
&lt;br /&gt;
; getCollectionFromDB( $sql, $bSingleValue=false )&lt;br /&gt;
: Returns an associative array of rows for a sql SELECT query.&lt;br /&gt;
: The key of the resulting associative array is the first field specified in the SELECT query.&lt;br /&gt;
: The value of the resulting associative array is an associative array with all the field specified in the SELECT query and associated values.&lt;br /&gt;
: First column must be a primary or alternate key (semantically, it does not actually have to declared in sql as such).&lt;br /&gt;
: The resulting collection can be empty (it won&#039;t be null).&lt;br /&gt;
: If you specified $bSingleValue=true and if your SQL query request 2 fields A and B, the method returns an associative array &amp;quot;A=&amp;gt;B&amp;quot;, otherwise its A=&amp;gt;[A,B]&lt;br /&gt;
: Note: The name a bit misleading, it really return associative array, i.e. map and NOT a collection. You cannot use it to get list of values which may have duplicates (hence primary key requirement on first column). If you need simple array use getObjectListFromDB() method.&lt;br /&gt;
&lt;br /&gt;
Example 1:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
self::getCollectionFromDB( &amp;quot;SELECT player_id id, player_name name, player_score score FROM player&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
Result:&lt;br /&gt;
array(&lt;br /&gt;
 1234 =&amp;gt; array( &#039;id&#039;=&amp;gt;1234, &#039;name&#039;=&amp;gt;&#039;myuser0&#039;, &#039;score&#039;=&amp;gt;1 ),&lt;br /&gt;
 1235 =&amp;gt; array( &#039;id&#039;=&amp;gt;1235, &#039;name&#039;=&amp;gt;&#039;myuser1&#039;, &#039;score&#039;=&amp;gt;0 )&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Example 2:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
self::getCollectionFromDB( &amp;quot;SELECT player_id id, player_name name FROM player&amp;quot;, true );&lt;br /&gt;
&lt;br /&gt;
Result:&lt;br /&gt;
array(&lt;br /&gt;
 1234 =&amp;gt; &#039;myuser0&#039;,&lt;br /&gt;
 1235 =&amp;gt; &#039;myuser1&#039;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; getNonEmptyCollectionFromDB( $sql )&lt;br /&gt;
: Same as getCollectionFromDB($sdl), but raise an exception if the collection is empty. Note: this function does NOT have 2nd argument as previous one does.&lt;br /&gt;
&lt;br /&gt;
; getObjectFromDB( $sql )&lt;br /&gt;
: Returns one row for the sql SELECT query as an associative array or null if there is no result&lt;br /&gt;
: Raise an exception if the query return more than one row (you can use LIMIT 1 in the query to avoid the exception)&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
self::getObjectFromDB( &amp;quot;SELECT player_id id, player_name name, player_score score FROM player WHERE player_id=&#039;$player_id&#039;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
Result:&lt;br /&gt;
array(&lt;br /&gt;
  &#039;id&#039;=&amp;gt;1234, &#039;name&#039;=&amp;gt;&#039;myuser0&#039;, &#039;score&#039;=&amp;gt;1 &lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; getNonEmptyObjectFromDB( $sql )&lt;br /&gt;
: Similar to previous one, but raise an exception if no row is found&lt;br /&gt;
&lt;br /&gt;
; getObjectListFromDB( $sql, $bUniqueValue=false )&lt;br /&gt;
: Return an array of rows for a sql SELECT query.&lt;br /&gt;
: The result is the same as &amp;quot;getCollectionFromDB&amp;quot; except that the result is a simple array (and not an associative array).&lt;br /&gt;
: The result can be empty.&lt;br /&gt;
: If you specified $bUniqueValue=true and if your SQL query request 1 field, the method returns directly an array of values.&lt;br /&gt;
&lt;br /&gt;
Example 1:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
self::getObjectListFromDB( &amp;quot;SELECT player_id id, player_name name, player_score score FROM player&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
Result:&lt;br /&gt;
array(&lt;br /&gt;
 array( &#039;id&#039;=&amp;gt;1234, &#039;name&#039;=&amp;gt;&#039;myuser0&#039;, &#039;score&#039;=&amp;gt;1 ),&lt;br /&gt;
 array( &#039;id&#039;=&amp;gt;1235, &#039;name&#039;=&amp;gt;&#039;myuser1&#039;, &#039;score&#039;=&amp;gt;0 )&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Example 2:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
self::getObjectListFromDB( &amp;quot;SELECT player_name name FROM player&amp;quot;, true );&lt;br /&gt;
&lt;br /&gt;
Result:&lt;br /&gt;
array(&lt;br /&gt;
 &#039;myuser0&#039;,&lt;br /&gt;
 &#039;myuser1&#039;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; getDoubleKeyCollectionFromDB( $sql, $bSingleValue=false )&lt;br /&gt;
: Return an associative array of associative array, from a SQL SELECT query.&lt;br /&gt;
: First array level correspond to first column specified in SQL query.&lt;br /&gt;
: Second array level correspond to second column specified in SQL query.&lt;br /&gt;
: If bSingleValue = true, keep only third column on result&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; DbGetLastId()&lt;br /&gt;
: Return the PRIMARY key of the last inserted row (see PHP mysql_insert_id function).&lt;br /&gt;
&lt;br /&gt;
; DbAffectedRow()&lt;br /&gt;
: Return the number of row affected by the last operation&lt;br /&gt;
&lt;br /&gt;
; escapeStringForDB( $string )&lt;br /&gt;
: You must use this function on every string type data in your database that contains unsafe data.&lt;br /&gt;
: (unsafe = can be modified by a player).&lt;br /&gt;
: This method makes sure that no SQL injection will be done through the string used.&lt;br /&gt;
: Note: if you using standard types in ajax actions, like AT_alphanum it is sanitized before arrival,&lt;br /&gt;
: this is only needed if you manage to get unchecked string, like in the games where user has to enter text as a response.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: see Editing [[Game database model: dbmodel.sql]] to know how to define your database model.&lt;br /&gt;
&lt;br /&gt;
== Use globals ==&lt;br /&gt;
&lt;br /&gt;
Sometimes, you want a single global integer value for your game, and you don&#039;t want to create a DB table specifically for it.&lt;br /&gt;
&lt;br /&gt;
You can do this with the BGA framework &amp;quot;global.&amp;quot; Your value will be stored in the &amp;quot;global&amp;quot; table in the database, and you can access it with simple methods.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;initGameStateLabels&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This method should be located at the beginning of __construct() method of &#039;&#039;yourgamename.game.php&#039;&#039;. This is where you define the globals used in your game logic, by assigning them IDs.&lt;br /&gt;
&lt;br /&gt;
You can define up to 80 globals, with IDs from 10 to 89 (inclusive, there can be gaps). You must &#039;&#039;&#039;not&#039;&#039;&#039; use globals outside this range, as those values are used by other components of the framework.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        $this-&amp;gt;initGameStateLabels( array( &lt;br /&gt;
                &amp;quot;my_first_global_variable&amp;quot; =&amp;gt; 10,&lt;br /&gt;
                &amp;quot;my_second_global_variable&amp;quot; =&amp;gt; 11&lt;br /&gt;
        ) );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        $this-&amp;gt;GAMESTATELABELS = [&amp;quot;my_first_global_variable&amp;quot; =&amp;gt; 10, &amp;quot;my_second_global_variable&amp;quot; =&amp;gt; 11];&lt;br /&gt;
        $this-&amp;gt;initGameStateLabels($this-&amp;gt;GAMESTATELABELS);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is also in this method that you will define your game options. In that case, IDs need to be between 100 and 199 (inclusive, there can be gaps) Check this for more details [[Game_options_and_preferences:_gameoptions.inc.php]]&lt;br /&gt;
&lt;br /&gt;
With option set, the method will look like&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        $this-&amp;gt;initGameStateLabels( array( &lt;br /&gt;
                &amp;quot;my_first_global_variable&amp;quot; =&amp;gt; 10,&lt;br /&gt;
                &amp;quot;my_second_global_variable&amp;quot; =&amp;gt; 11,&lt;br /&gt;
                &amp;quot;my_game_variant&amp;quot; =&amp;gt; 100&lt;br /&gt;
        ) );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;setGameStateInitialValue( $value_label, $value_value )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Initialize your global value. Must be called before any use of your global, so you should call this method from your &amp;quot;setupNewGame&amp;quot; method. $value_value must be an integer.&lt;br /&gt;
&lt;br /&gt;
It seems that a non initialized value will not be restored with undo system, so it is therefore advisable to initialize them all in your &amp;quot;setupNewGame&amp;quot; method.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;foreach ($this-&amp;gt;GAMESTATELABELS as $value_label=&amp;gt; $ID) if ($ID &amp;gt;= 10 &amp;amp;&amp;amp; $ID &amp;lt; 90) $this-&amp;gt;setGameStateInitialValue($value_label, 0);&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;getGameStateValue( $value_label )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Retrieve the current value of a global.&lt;br /&gt;
&lt;br /&gt;
For debugging purposes, you can have labels and value pairs send to client side by inserting that line of code in your &amp;quot;getAllDatas&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;$result[&#039;labels&#039;] = array_combine(array_keys($this-&amp;gt;GAMESTATELABELS), array_map(array($this,&#039;getGameStateValue&#039;), array_keys($this-&amp;gt;GAMESTATELABELS)));&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;setGameStateValue( $value_label, $value_value )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Set the current value of a global. $value_value must be an integer.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;incGameStateValue( $value_label, $increment )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Increment the current value of a global. If increment is negative, decrement the value of the global.&lt;br /&gt;
&lt;br /&gt;
Return the final value of the global.&lt;br /&gt;
&lt;br /&gt;
=== BGA predefined globals ===&lt;br /&gt;
&lt;br /&gt;
BGA already defines some globals in the &#039;&#039;global&#039;&#039; database table. You should not change them directly but it can be useful to know what they mean when debugging:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! global_id !! Meaning&lt;br /&gt;
|-&lt;br /&gt;
| 1 || Active state id&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Active player id&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Next move number&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Player turn number&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Game progression&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Initial reflection time&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Additional reflection time&lt;br /&gt;
|-&lt;br /&gt;
| 200 || Reflexion time profile&lt;br /&gt;
|-&lt;br /&gt;
| 207 || GAMESTATE_GAME_LANG&lt;br /&gt;
|-&lt;br /&gt;
| 201 || BGA ranking mode&lt;br /&gt;
|-&lt;br /&gt;
| 300 || GAMESTATE_GAMEVERSION: Current version of the game (when in production)&lt;br /&gt;
|-&lt;br /&gt;
| 301 || GAMESTATE_GAME_RESULT_NEUTRALIZED&lt;br /&gt;
|-&lt;br /&gt;
| 302 || GAMESTATE_NEUTRALIZED_PLAYER_ID&lt;br /&gt;
|-&lt;br /&gt;
| 304 || GAMESTATE_UNDO_MOVES_STORED&lt;br /&gt;
|-&lt;br /&gt;
| 305 || GAMESTATE_UNDO_MOVES_PLAYER&lt;br /&gt;
|-&lt;br /&gt;
| 306 || GAMESTATE_LOCK_TIMESTAMP&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Game states and active players ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Activate player handling ===&lt;br /&gt;
&lt;br /&gt;
; $this-&amp;gt;activeNextPlayer()&lt;br /&gt;
: Make the next player active in the natural player order.&lt;br /&gt;
: Note: you CANNOT use this method in a &amp;quot;activeplayer&amp;quot; or &amp;quot;multipleactiveplayer&amp;quot; state. You must use a &amp;quot;game&amp;quot; type game state for this.&lt;br /&gt;
&lt;br /&gt;
; $this-&amp;gt;activePrevPlayer()&lt;br /&gt;
: Make the previous player active (in the natural player order).&lt;br /&gt;
: Note: you CANNOT use this method in a &amp;quot;activeplayer&amp;quot; or &amp;quot;multipleactiveplayer&amp;quot; state. You must use a &amp;quot;game&amp;quot; type game state for this.&lt;br /&gt;
&lt;br /&gt;
; $this-&amp;gt;gamestate-&amp;gt;changeActivePlayer( $player_id )&lt;br /&gt;
: You can call this method to make any player active.&lt;br /&gt;
: Note: you CANNOT use this method in a &amp;quot;activeplayer&amp;quot; or &amp;quot;multipleactiveplayer&amp;quot; state. You must use a &amp;quot;game&amp;quot; type game state for this.&lt;br /&gt;
&lt;br /&gt;
; $this-&amp;gt;getActivePlayerId()&lt;br /&gt;
: Return the &amp;quot;active_player&amp;quot; id&lt;br /&gt;
: Note: it does NOT mean that this player is active right now, because state type could be &amp;quot;game&amp;quot; or &amp;quot;multipleactiveplayer&amp;quot;&lt;br /&gt;
: Note: avoid using this method in a &amp;quot;multipleactiveplayer&amp;quot; state because it does not mean anything.&lt;br /&gt;
&lt;br /&gt;
=== Multiple activate player handling ===&lt;br /&gt;
&lt;br /&gt;
; $this-&amp;gt;gamestate-&amp;gt;setAllPlayersMultiactive()&lt;br /&gt;
: All playing players are made active. Update notification is sent to all players (this will trigger &#039;&#039;&#039;onUpdateActionButtons&#039;&#039;&#039;).&lt;br /&gt;
: Usually, you use this method at the beginning of a game state (e.g., &amp;quot;stGameState&amp;quot;) which transitions to a &#039;&#039;multipleactiveplayer&#039;&#039; state in which multiple players have to perform some action. Do not use this method if you going to make some more changes in the active player list. (I.e., if you want to take away multipleactiveplayer status immediately afterwards, use setPlayersMultiactive instead.)&lt;br /&gt;
&lt;br /&gt;
Example of usage:&lt;br /&gt;
    &amp;lt;pre&amp;gt;&lt;br /&gt;
    function st_MultiPlayerInit() {&lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;setAllPlayersMultiactive();&lt;br /&gt;
    }&lt;br /&gt;
    &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; $this-&amp;gt;stMakeEveryoneActive()&lt;br /&gt;
:this method can be used in state machine to make everybody active as &amp;quot;st&amp;quot; method of multiplayeractive state, it just calls $this-&amp;gt;gamestate-&amp;gt;setAllPlayersMultiactive()&lt;br /&gt;
&lt;br /&gt;
This is to be used in state declaration:&lt;br /&gt;
    &amp;lt;pre&amp;gt;&lt;br /&gt;
    2 =&amp;gt; array(&lt;br /&gt;
    		&amp;quot;name&amp;quot; =&amp;gt; &amp;quot;playerTurnPlace&amp;quot;,&lt;br /&gt;
    		&amp;quot;description&amp;quot; =&amp;gt; clienttranslate(&#039;Other player must place ships&#039;),&lt;br /&gt;
    		&amp;quot;descriptionmyturn&amp;quot; =&amp;gt; clienttranslate(&#039;${you} must place ships (click on YOUR SHIPS board to place)&#039;),&lt;br /&gt;
    		&amp;quot;type&amp;quot; =&amp;gt; &amp;quot;multipleactiveplayer&amp;quot;,&lt;br /&gt;
                &#039;action&#039; =&amp;gt; &#039;stMakeEveryoneActive&#039;,&lt;br /&gt;
                &#039;args&#039; =&amp;gt; &#039;arg_playerTurnPlace&#039;,&lt;br /&gt;
    	     	&amp;quot;possibleactions&amp;quot; =&amp;gt; array( &amp;quot;actionBla&amp;quot; ),&lt;br /&gt;
                &amp;quot;transitions&amp;quot; =&amp;gt; array( &amp;quot;next&amp;quot; =&amp;gt; 4, &amp;quot;last&amp;quot; =&amp;gt; 99)&lt;br /&gt;
    ),&lt;br /&gt;
    &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; $this-&amp;gt;gamestate-&amp;gt;setAllPlayersNonMultiactive( $next_state )&lt;br /&gt;
: All playing players are made inactive. Transition to next state&lt;br /&gt;
&lt;br /&gt;
; $this-&amp;gt;gamestate-&amp;gt;setPlayersMultiactive( $players, $next_state, $bExclusive = false )&lt;br /&gt;
: Make a specific list of players active during a multiactive gamestate. Update notification is sent to all players whose state changed.&lt;br /&gt;
: &amp;quot;players&amp;quot; is the array of player id that should be made active. If &amp;quot;players&amp;quot; is not empty the value of &amp;quot;next_state&amp;quot; will be ignored (you can put whatever you want)&lt;br /&gt;
: If &amp;quot;exclusive&amp;quot; parameter is not set or false it doesn&#039;t deactivate other previously active players. If its set to true, the players who will be multiactive at the end are only these in &amp;quot;$players&amp;quot; array&lt;br /&gt;
&lt;br /&gt;
: In case &amp;quot;players&amp;quot; is empty, the method trigger the &amp;quot;next_state&amp;quot; transition to go to the next game state.&lt;br /&gt;
: returns true if state transition happened, false otherwise&lt;br /&gt;
&lt;br /&gt;
; $this-&amp;gt;gamestate-&amp;gt;setPlayerNonMultiactive( $player_id, $next_state )&lt;br /&gt;
: During a multiactive game state, make the specified player inactive.&lt;br /&gt;
: Usually, you call this method during a multiactive game state after a player did his action. It is also possible to call it directly from multiplayer action handler.&lt;br /&gt;
: If this player was the last active player, the method trigger the &amp;quot;next_state&amp;quot; transition to go to the next game state.&lt;br /&gt;
: returns true if state transition happened, false otherwise&lt;br /&gt;
Example of usage (see state declaration of playerTurnPlace above):&lt;br /&gt;
    &amp;lt;pre&amp;gt;&lt;br /&gt;
    function actionBla($args) {&lt;br /&gt;
        self::checkAction(&#039;actionBla&#039;);&lt;br /&gt;
        // handle the action using $this-&amp;gt;getCurrentPlayerId()&lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;setPlayerNonMultiactive( $this-&amp;gt;getCurrentPlayerId(), &#039;next&#039;);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; $this-&amp;gt;gamestate-&amp;gt;getActivePlayerList()&lt;br /&gt;
: With this method you can retrieve the list of the active player at any time.&lt;br /&gt;
: During a &amp;quot;game&amp;quot; type gamestate, it will return a void array.&lt;br /&gt;
: During a &amp;quot;activeplayer&amp;quot; type gamestate, it will return an array with one value (the active player id).&lt;br /&gt;
: During a &amp;quot;multipleactiveplayer&amp;quot; type gamestate, it will return an array of the active players id.&lt;br /&gt;
: Note: you should only use this method in the latter case.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
;  $this-&amp;gt;gamestate-&amp;gt;updateMultiactiveOrNextState( $next_state_if_none )&lt;br /&gt;
: Sends update notification about multiplayer changes. All multiactive set* functions above do that, however if you want to change state manually using db queries for complex calculations, you have to call this yourself after. Do not call this if you calling one of the other setters above.&lt;br /&gt;
Example: you have player teams and you want to activate all players in one team&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        $sql = &amp;quot;UPDATE player SET player_is_multiactive=&#039;0&#039;&amp;quot;;&lt;br /&gt;
        self::DbQuery( $sql );&lt;br /&gt;
        $sql = &amp;quot;UPDATE player SET player_is_multiactive=&#039;1&#039; WHERE player_id=&#039;$player_id&#039; AND player_team=&#039;$team_no&#039;&amp;quot;;&lt;br /&gt;
        self::DbQuery( $sql );&lt;br /&gt;
        &lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;updateMultiactiveOrNextState( &#039;error&#039; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; updating database manually&lt;br /&gt;
: Use this helper function to change multiactive state without sending notification&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    /**&lt;br /&gt;
     * Changes values of multiactivity in db, does not sent notifications.&lt;br /&gt;
     * To send notifications after use updateMultiactiveOrNextState&lt;br /&gt;
     * @param number $player_id, player id &amp;lt;=0 or null - means ALL&lt;br /&gt;
     * @param number $value - 1 multiactive, 0 non multiactive&lt;br /&gt;
     */&lt;br /&gt;
    function dbSetPlayerMultiactive($player_id = -1, $value = 1) {&lt;br /&gt;
        if (! $value)&lt;br /&gt;
            $value = 0;&lt;br /&gt;
        else&lt;br /&gt;
            $value = 1;&lt;br /&gt;
        $sql = &amp;quot;UPDATE player SET player_is_multiactive = &#039;$value&#039; WHERE player_zombie = 0 and player_eliminated = 0&amp;quot;;&lt;br /&gt;
        if ($player_id &amp;gt; 0) {&lt;br /&gt;
            $sql .= &amp;quot; AND player_id = $player_id&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
        self::DbQuery($sql);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;$this-&amp;gt;gamestate-&amp;gt;isPlayerActive($player_id)&lt;br /&gt;
:Return true if specified player is active right now.&lt;br /&gt;
:This method take into account game state type, ie nobody is active if game state is &amp;quot;game&amp;quot; and several players can be active if game state is &amp;quot;multiplayer&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== States functions ===&lt;br /&gt;
; $this-&amp;gt;gamestate-&amp;gt;nextState( $transition )&lt;br /&gt;
: Change current state to a new state. Important: the $transition parameter is the name of the transition, and NOT the name of the target game state, see [[Your game state machine: states.inc.php]] for more information about states.&lt;br /&gt;
&lt;br /&gt;
; $this-&amp;gt;checkAction( $actionName, $bThrowException=true )&lt;br /&gt;
: Check if the current player can perform a specific action in the current game state, and optionally throw an exception if they can&#039;t.&lt;br /&gt;
: The action is valid if it is listed in the &amp;quot;possibleactions&amp;quot; array for the current game state (see game state description).&lt;br /&gt;
: This method MUST be the first one called in ALL your PHP methods that handle player actions, in order to make sure a player doesn&#039;t perform an action not allowed by the rules at the point in the game.  It should not be called from methods where the current player is not necessarily the active player, otherwise it may fail with an &amp;quot;It is not your turn&amp;quot; exception.&lt;br /&gt;
: If &amp;quot;bThrowException&amp;quot; is set to &amp;quot;false&amp;quot;, the function returns &#039;&#039;&#039;false&#039;&#039;&#039; in case of failure instead of throwing an exception. This is useful when several actions are possible, in order to test each of them without throwing exceptions.&lt;br /&gt;
&lt;br /&gt;
; $this-&amp;gt;gamestate-&amp;gt;checkPossibleAction( $action )&lt;br /&gt;
: (rarely used)&lt;br /&gt;
: This works exactly like &amp;quot;checkAction&amp;quot; (above), except that it does NOT check if the current player is active.&lt;br /&gt;
: This is used specifically in certain game states when you want to authorize additional actions for players that are not active at the moment.&lt;br /&gt;
: Example: in &#039;&#039;Libertalia&#039;&#039;, you want to authorize players to change their mind about the card played. They are of course not active at the time they change their mind, so you cannot use &amp;quot;checkAction&amp;quot;; use &amp;quot;checkPossibleAction&amp;quot; instead.&lt;br /&gt;
&lt;br /&gt;
This is how PHP action looks that returns player to active state (only for multiplayeractive states). To be able to execute on js side do not checkAction on js side for this specific one.&lt;br /&gt;
&lt;br /&gt;
   function actionUnpass() {&lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;checkPossibleAction(&#039;actionUnpass&#039;); // player changed mind about passing while others were thinking&lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;setPlayersMultiactive(array ($this-&amp;gt;getCurrentPlayerId() ), &#039;error&#039;, false);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
; $this-&amp;gt;gamestate-&amp;gt;state()&lt;br /&gt;
: Get an associative array of current game state attributes, see [[Your game state machine: states.inc.php]] for state attributes.&lt;br /&gt;
&lt;br /&gt;
  $state=$this-&amp;gt;gamestate-&amp;gt;state(); if( $state[&#039;name&#039;] == &#039;myGameState&#039; ) {...}&lt;br /&gt;
&lt;br /&gt;
I suggest to define and use this function in your php class to access state name:&lt;br /&gt;
&lt;br /&gt;
    public function getStateName() {&lt;br /&gt;
        $state = $this-&amp;gt;gamestate-&amp;gt;state();&lt;br /&gt;
        return $state[&#039;name&#039;];&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
; $this-&amp;gt;gamestate-&amp;gt;state_id()&lt;br /&gt;
: Get the id of the current game state (rarely useful, its best to use name, unless you use constants for state ids)&lt;br /&gt;
&lt;br /&gt;
; $this-&amp;gt;gamestate-&amp;gt;isMutiactiveState()&lt;br /&gt;
: Return true if we are in multipleactiveplayer state, false otherwise&lt;br /&gt;
&lt;br /&gt;
=== Private parallel states ===&lt;br /&gt;
&lt;br /&gt;
See the overview of private parallel states [[Your_game_state_machine:_states.inc.php#Private_parallel_states|here]].&lt;br /&gt;
&lt;br /&gt;
; $this-&amp;gt;gamestate-&amp;gt;initializePrivateStateForAllActivePlayers()&lt;br /&gt;
: All active players in a multiactive state are entering a first private state defined in the master state&#039;s initialprivate parameter.&lt;br /&gt;
: Every time you need to start a private parallel states you need to call this or similar methods below.&lt;br /&gt;
: Note: at least one player needs to be active (see [[#Multiple_activate_player_handling|above]]) and current game state must be a multiactive state with initialprivate parameter defined&lt;br /&gt;
: Note: initialprivate parameter of master state should be set to the id of the first private state. This private state needs to be defined in states.php with the type set to &#039;private&#039;.&lt;br /&gt;
: Note: this method is usually preceded with activating some or all players&lt;br /&gt;
: Note: initializing private state can run action or args methods of the initial private state&lt;br /&gt;
&lt;br /&gt;
Example of usage:&lt;br /&gt;
    &amp;lt;pre&amp;gt;&lt;br /&gt;
    function stStartPlayerTurn() {&lt;br /&gt;
        // This is usually done in master state action method&lt;br /&gt;
        &lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;setAllPlayersMultiactive();&lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;initializePrivateStateForAllActivePlayers();&lt;br /&gt;
&lt;br /&gt;
        // in some cases you can move immediately some or all players to different private states&lt;br /&gt;
        if ($someCondition) {&lt;br /&gt;
            //move all players to different state &lt;br /&gt;
            $this-&amp;gt;gamestate-&amp;gt;nextPrivateStateForAllActivePlayers(&amp;quot;some_transition&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        if ($other condition) {&lt;br /&gt;
            //move single player to different state&lt;br /&gt;
            $this-&amp;gt;gamestate-&amp;gt;nextPrivateState($specificPlayerId, &amp;quot;some_transition&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; $this-&amp;gt;gamestate-&amp;gt;initializePrivateStateForPlayers($playerIds)&lt;br /&gt;
: Players with specified ids are entering a first private state defined in the master state initialprivate parameter.&lt;br /&gt;
: Same considerations apply as for the method above.&lt;br /&gt;
&lt;br /&gt;
; $this-&amp;gt;gamestate-&amp;gt;initializePrivateState($playerId)&lt;br /&gt;
: Player with the specified id is entering a first private state defined in the master state initialprivate parameter.&lt;br /&gt;
: Everytime you need to start a private parallel states you need to call this or similar methods above&lt;br /&gt;
: Note: player needs to be active (see [[#Multiple_activate_player_handling|above]]) and current game state must be a multiactive state with initialprivate parameter defined&lt;br /&gt;
: Note: initialprivate parameter of master state should be set to the id of the first private state. This private state needs to be defined in states.php with the type set to &#039;private&#039;.&lt;br /&gt;
: Note: this method is usually preceded with activating that player&lt;br /&gt;
: Note: initializing private state can run action or args methods of the initial private state&lt;br /&gt;
&lt;br /&gt;
Example of usage:&lt;br /&gt;
    &amp;lt;pre&amp;gt;&lt;br /&gt;
    function st_ChangeMind() {&lt;br /&gt;
        // This player finished his move before, but now decides change something while other players are still active&lt;br /&gt;
        // We activate the player and initialize his private state&lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;setPlayersMultiactive([$this-&amp;gt;getCurrentPlayerId()], &amp;quot;&amp;quot;);&lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;initializePrivateState(this-&amp;gt;getCurrentPlayerId());&lt;br /&gt;
&lt;br /&gt;
        // It is also possible to move the player to some other specific state immediately&lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;nextPrivateState($this-&amp;gt;getCurrentPlayerId(), &amp;quot;some_transition&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; $this-&amp;gt;gamestate-&amp;gt;nextPrivateStateForAllActivePlayers($transition)&lt;br /&gt;
: All active players will transition to next private state by specified transition&lt;br /&gt;
: Note: game needs to be in a master state which allows private parallel states&lt;br /&gt;
: Note: transition should lead to another private state (i.e. a state with type defined as &#039;private&#039;&lt;br /&gt;
: Note: transition should be defined in private state in which the players currently are. &lt;br /&gt;
: Note: this method can run action or args methods of the target state&lt;br /&gt;
: Note: this is usually used after initializing the private state to move players to specific private state according to the game logic&lt;br /&gt;
&lt;br /&gt;
Example of usage:&lt;br /&gt;
    &amp;lt;pre&amp;gt;&lt;br /&gt;
    function stStartPlayerTurn() {&lt;br /&gt;
        // This is usually done in master state action method&lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;setAllPlayersMultiactive();&lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;initializePrivateStateForAllActivePlayers();&lt;br /&gt;
&lt;br /&gt;
        if ($specificOption) {&lt;br /&gt;
            //move all players to different state &lt;br /&gt;
            $this-&amp;gt;gamestate-&amp;gt;nextPrivateStateForAllActivePlayers(&amp;quot;some_transition&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; $this-&amp;gt;gamestate-&amp;gt;nextPrivateStateForPlayers($playerIds, $transition)&lt;br /&gt;
: Players with specified ids will transition to next private state specified by provided transition.&lt;br /&gt;
: Same considerations apply as for the method above.&lt;br /&gt;
&lt;br /&gt;
; $this-&amp;gt;gamestate-&amp;gt;nextPrivateState($playerId, $transition)&lt;br /&gt;
: Player with specified id will transition to next private state specified by provided transition&lt;br /&gt;
: Note: game needs to be in a master state which allows private parallel states&lt;br /&gt;
: Note: transition should lead to another private state (i.e. a state with type defined as &#039;private&#039;&lt;br /&gt;
: Note: transition should be defined in private state in which the players currently are. &lt;br /&gt;
: Note: this method can run action or args methods of the target state for specified player&lt;br /&gt;
: Note: this is usually used after some player actions to move to next private state&lt;br /&gt;
&lt;br /&gt;
Example of usage:&lt;br /&gt;
    &amp;lt;pre&amp;gt;&lt;br /&gt;
    function someAction() {&lt;br /&gt;
        $this-&amp;gt;checkAction(&amp;quot;someAction&amp;quot;); //needs to be defined in the current state&lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;nextPrivateState($this-&amp;gt;getCurrentPlayerId(), &amp;quot;some_transition&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; $this-&amp;gt;gamestate-&amp;gt;unsetPrivateStateForAllPlayers()&lt;br /&gt;
: All players private state will be reset to null, which means they will get out of private parallel states and be in a master state like the private states are not used &lt;br /&gt;
: Note: game needs to be in a master state which allows private parallel states&lt;br /&gt;
: Note: this is usually used to clean up after leaving a master state in which private states were used, but can be used in other cases when we want to exit private parallel states and use a regular multiactive state for all players&lt;br /&gt;
: Note: After unseting private state only actions on master state are possible&lt;br /&gt;
: Note: Usually it is not necessary to unset private states as they will be initialized to first private state when private states are needed again. Nevertheless it is generally better to clean private state after exiting private parallel states to avoid bugs. &lt;br /&gt;
&lt;br /&gt;
Example of usage:&lt;br /&gt;
    &amp;lt;pre&amp;gt;&lt;br /&gt;
    function stNextRound() {&lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;unsetPrivateStateForAllPlayers();&lt;br /&gt;
    }&lt;br /&gt;
    &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; $this-&amp;gt;gamestate-&amp;gt;unsetPrivateStateForPlayers($playerIds, $transition)&lt;br /&gt;
: For players with specified ids private state will be reset to null, which means they will get out of private parallel states and be in a master state like the private states are not used.&lt;br /&gt;
: Same considerations apply as for the method above.&lt;br /&gt;
&lt;br /&gt;
; $this-&amp;gt;gamestate-&amp;gt;unsetPrivateState($playerId)&lt;br /&gt;
: For player with specified id private state will be reset to null, which means they will get out of private parallel states and be in a master state like the private states are not used &lt;br /&gt;
: Note: game needs to be in a master state which allows private parallel states&lt;br /&gt;
: Note: this is usually used when deactivating player to clean up their parallel state&lt;br /&gt;
: Note: After unseting private state only actions on master state are possible&lt;br /&gt;
: Note: Usually it is not necessary to unset private state as it will be initialized to first private state when private states are needed again. Nevertheless it is generally better to clean private state when not needed to avoid bugs. &lt;br /&gt;
&lt;br /&gt;
Example of usage:&lt;br /&gt;
    &amp;lt;pre&amp;gt;&lt;br /&gt;
    function done() {&lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;setPlayerNonMultiactive( $this-&amp;gt;getCurrentPlayerId(), &amp;quot;newTurn&amp;quot; );&lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;unsetPrivateState($this-&amp;gt;getCurrentPlayerId());&lt;br /&gt;
    }&lt;br /&gt;
    &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; $this-&amp;gt;gamestate-&amp;gt;setPrivateState($playerId, $newStateId)&lt;br /&gt;
: For player with specified id a new private state would be set&lt;br /&gt;
: Note: game needs to be in a master state which allows private parallel states&lt;br /&gt;
: Note: this should be rarely used as it doesn&#039;t check if the transition is allowed (it doesn&#039;t even specifies transition). This can be useful in very complex cases when standard state machine is not adequate (i.e. specific cards can lead to some micro action in various states where defining transitions back and forth can become very tedious.) &lt;br /&gt;
: Note: this method can run action or args methods of the target state for specified player&lt;br /&gt;
&lt;br /&gt;
Example of usage:&lt;br /&gt;
    &amp;lt;pre&amp;gt;&lt;br /&gt;
    function someAction() {&lt;br /&gt;
        $this-&amp;gt;checkAction(&amp;quot;someAction&amp;quot;); //needs to be defined in the current state&lt;br /&gt;
&lt;br /&gt;
        if ($playerHaveSpecificCard)&lt;br /&gt;
            return $this-&amp;gt;gamestate-&amp;gt;setPrivateState($this-&amp;gt;getCurrentPlayerId(), 35);&lt;br /&gt;
&lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;nextPrivateState($this-&amp;gt;getCurrentPlayerId(), &amp;quot;some_transition&amp;quot;);        &lt;br /&gt;
    }&lt;br /&gt;
    &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Players turn order ==&lt;br /&gt;
&lt;br /&gt;
When table is created the &amp;quot;natural&amp;quot; player order is assigned to player at random, and stored in &amp;quot;read-only&amp;quot; field &amp;quot;player_no&amp;quot;.&lt;br /&gt;
If you need to create a custom order you should never change natural order but have a separate data structure. &lt;br /&gt;
For example you can alter the players table to add another &amp;quot;custom_order&amp;quot; field, you can use state globals or you can use your natural board database, &lt;br /&gt;
to store meeple_color/position_location pair.&lt;br /&gt;
BGA currently does not provide any API to create/store custom player order.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;getNextPlayerTable()&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Return an associative array which associate each player with the next player around the table.&lt;br /&gt;
&lt;br /&gt;
In addition, key 0 is associated to the first player to play.&lt;br /&gt;
&lt;br /&gt;
Example: if three player with ID 1000, 2000 and 3000 are around the table, in this order, the method returns:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   array( &lt;br /&gt;
    1000 =&amp;gt; 2000, &lt;br /&gt;
    2000 =&amp;gt; 3000, &lt;br /&gt;
    3000 =&amp;gt; 1000, &lt;br /&gt;
    0 =&amp;gt; 1000 &lt;br /&gt;
   );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;getPrevPlayerTable()&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Same as above, but the associative array associate the previous player around the table. However there no 0 index here.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;getPlayerAfter( $player_id )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Get player playing after given player in natural playing order.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;getPlayerBefore( $player_id )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Get player playing before given player in natural playing order.&lt;br /&gt;
&lt;br /&gt;
Note: There is no API to modify this order, if you have custom player order you have to maintain it in your database&lt;br /&gt;
and have custom function to access it.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;createNextPlayerTable( $players, $bLoop=true )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Using $players array creates a map of current =&amp;gt; next as in example from getNextPlayerTable(), however you can use custom order here. &lt;br /&gt;
If parmeter $bLoop is set to true then last player will points to first (creaing a loop), false otherwise.&lt;br /&gt;
In any case index 0 points to first player (first element of $players array). $players is array of player ids in desired order.&lt;br /&gt;
&lt;br /&gt;
Note: This function &#039;&#039;&#039;DOES NOT&#039;&#039;&#039; change the order in database, it only creates a map using key/values as descibed.&lt;br /&gt;
&lt;br /&gt;
Example of usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    function getNextPlayerTableCustom() {&lt;br /&gt;
        $starting = $this-&amp;gt;getStartingPlayer(); // custom function to get starting player&lt;br /&gt;
        $player_ids = $this-&amp;gt;getPlayerIdsInOrder($starting); // custom function to create players array starting from starting player&lt;br /&gt;
        return $this-&amp;gt;createNextPlayerTable($player_ids, false); // create next player table in custom order&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$table = $this-&amp;gt;createNextPlayerTable([3,2,1], false);&lt;br /&gt;
&lt;br /&gt;
will return:&lt;br /&gt;
   [ &lt;br /&gt;
    3000 =&amp;gt; 2000, &lt;br /&gt;
    2000 =&amp;gt; 1000, &lt;br /&gt;
    1000 =&amp;gt; null,&lt;br /&gt;
    0 =&amp;gt; 3000 &lt;br /&gt;
   ]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Notify players ==&lt;br /&gt;
&lt;br /&gt;
To understand notifications, please read [http://www.slideshare.net/boardgamearena/the-bga-framework-at-a-glance The BGA Framework at a glance] first.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;IMPORTANT&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Notifications are sent at the very end of the request, when it ends normally. It means that if you throw an exception for any reason (ex: move not allowed), no notifications will be sent to players.&lt;br /&gt;
Notifications sent between the game start (setupNewGame) and the end of the &amp;quot;action&amp;quot; method of the first active state will never reach their destination.&lt;br /&gt;
&lt;br /&gt;
=== NotifyAllPlayers ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;notifyAllPlayers( $notification_type, $notification_log, $notification_args )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Send a notification to all players of the game.&lt;br /&gt;
&lt;br /&gt;
* notification_type:&lt;br /&gt;
A string that defines the type of your notification.&lt;br /&gt;
&lt;br /&gt;
Your game interface Javascript logic will use this to know what is the type of the received notification (and to trigger the corresponding method).&lt;br /&gt;
&lt;br /&gt;
* notification_log:&lt;br /&gt;
A string that defines what is to be displayed in the game log.&lt;br /&gt;
&lt;br /&gt;
You can use an empty string here (&amp;quot;&amp;quot;). In this case, nothing is displayed in the game log.&lt;br /&gt;
&lt;br /&gt;
If you define a real string here, you should use &amp;quot;clienttranslate&amp;quot; method to make sure it can be translated.&lt;br /&gt;
&lt;br /&gt;
You can use arguments in your notification_log strings, that refers to values defines in the &amp;quot;notification_args&amp;quot; argument (see below). &lt;br /&gt;
Note: Make sure you only use single quotes (&#039;), otherwise PHP will try to interpolate the variable and will ignore the values in the args array.&lt;br /&gt;
&lt;br /&gt;
* notification_args:&lt;br /&gt;
The arguments of your notifications, as an associative array.&lt;br /&gt;
&lt;br /&gt;
This array will be transmitted to the game interface logic, in order the game interface can be updated.&lt;br /&gt;
&lt;br /&gt;
Complete notifyAllPlayers example (from &amp;quot;Reversi&amp;quot;):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
self::notifyAllPlayers( &amp;quot;playDisc&amp;quot;, clienttranslate( &#039;${player_name} plays a disc and turns over ${returned_nbr} disc(s)&#039; ),&lt;br /&gt;
 array(&lt;br /&gt;
        &#039;player_id&#039; =&amp;gt; $player_id,&lt;br /&gt;
        &#039;player_name&#039; =&amp;gt; self::getActivePlayerName(),&lt;br /&gt;
        &#039;returned_nbr&#039; =&amp;gt; count( $turnedOverDiscs ),&lt;br /&gt;
        &#039;x&#039; =&amp;gt; $x,&lt;br /&gt;
        &#039;y&#039; =&amp;gt; $y&lt;br /&gt;
     ) );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can see in the example above the use of the &amp;quot;clienttranslate&amp;quot; method, and the use of 2 arguments &amp;quot;player_name&amp;quot; and &amp;quot;returned_nbr&amp;quot; in the notification log.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important&#039;&#039;&#039;: NO private data must be sent with this method, as a cheater could see it even if it is not used explicitly by the game interface logic. If you want to send private information to a player, please use notifyPlayer below.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important&#039;&#039;&#039;: this array is serialized to be sent to the browsers, and will be saved with the notification to be able to replay the game later. If it is too big, it can make notifications slower / less reliable, and replay archives very big (to the point of failing). So as a general rule, you should send only the minimum of information necessary to update the client interface with no overhead in order to keep the notifications as light as possible.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important&#039;&#039;&#039;: When the game page is reloaded (i.e. F5 or when loading turn based game) all previous notifications are replayed as history notifications. These notifications do not trigger notification handlers and are used basically to build the game log. Because of that most of the notification arguments, except i18n, player_id and all arguments used in the message, are removed from these history notifications. If you need additional arguments in history notifications you can add special field &amp;lt;b&amp;gt;preserve&amp;lt;/b&amp;gt; to notification arguments, like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
self::notifyAllPlayers( &amp;quot;playDisc&amp;quot;, clienttranslate( &#039;${player_name} plays a disc and turns over ${returned_nbr} disc(s)&#039; ),&lt;br /&gt;
 array(&lt;br /&gt;
        &#039;player_id&#039; =&amp;gt; $player_id,&lt;br /&gt;
        &#039;player_name&#039; =&amp;gt; self::getActivePlayerName(),&lt;br /&gt;
        &#039;returned_nbr&#039; =&amp;gt; count( $turnedOverDiscs ),&lt;br /&gt;
        &#039;x&#039; =&amp;gt; $x,&lt;br /&gt;
        &#039;y&#039; =&amp;gt; $y,&lt;br /&gt;
        &#039;preserve&#039; =&amp;gt; [ &#039;x&#039;, &#039;y&#039; ]&lt;br /&gt;
     ) );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In this example, fields x and y will be preserved when replaying history notification at the game load.&lt;br /&gt;
&lt;br /&gt;
==== HTML in Notifications ====&lt;br /&gt;
&lt;br /&gt;
You CAN use some HTML inside your notification log, however it not recommended for many reasons:&lt;br /&gt;
* Its bad architecture, ui elements leak into server now you have to manage ui in many places&lt;br /&gt;
* If you decided to change something in ui in future version, old games replay and tutorials may not work, since they use stored notifications&lt;br /&gt;
* When you read log preview for old games its unreadable (this is log before you enter the game replay, useful for troubleshooting or game analysis)&lt;br /&gt;
* Its more data to transfer and store in db&lt;br /&gt;
* Its nightmare for translators, at least don&#039;t put HTML tags inside the &amp;quot;clienttranslate&amp;quot; method. You can use a notification argument instead, and provide your HTML through this argument.&lt;br /&gt;
&lt;br /&gt;
If you still want to have pretty pictures in the log check this [[BGA_Studio_Cookbook#Inject_images_and_styled_html_in_the_log]].&lt;br /&gt;
&lt;br /&gt;
==== Recursive Notifications ====&lt;br /&gt;
&lt;br /&gt;
If your notification contains some phrases that build programmatically you may need to use recursive notifications. In this case the argument can be not only the string but&lt;br /&gt;
an array itself, which contains &#039;log&#039; and &#039;args&#039;, i.e.&lt;br /&gt;
&lt;br /&gt;
  $this-&amp;gt;notifyAllPlayers(&#039;playerLog&#039;,clienttranslate(&#039;Game moves ${token_name_rec}&#039;),&lt;br /&gt;
                   [&#039;token_name_rec&#039;=&amp;gt;[&#039;log&#039;=&amp;gt;&#039;${token_name} #${token_number}&#039;,&lt;br /&gt;
                                       &#039;args&#039;=&amp;gt; [&#039;token_name&#039;=&amp;gt;clienttranslate(&#039;Boo&#039;), &#039;token_number&#039;=&amp;gt;$number, &#039;i18n&#039;=&amp;gt;[&#039;token_name&#039;] ]&lt;br /&gt;
                                      ]&lt;br /&gt;
                   ]);&lt;br /&gt;
&lt;br /&gt;
Special handling of arguments:&lt;br /&gt;
* ${player_name}  - this will be wrapped in html and text shown using color of the corresponding player, some colors also have reserved background. This will apply recursively as well.&lt;br /&gt;
* ${player_name2} - same &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Excluding some players ====&lt;br /&gt;
&lt;br /&gt;
Sometimes you want to notify all players of a message but not have it appear in the log of specific players (for example, have every player see &amp;quot;Player X draws a card&amp;quot; but have Player X see &amp;quot;You draw the Ace of Spades&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
To send a notification to all players but have some clients ignore it, send it as normal from the server, but implement &#039;&#039;&#039;setIgnoreNotificationCheck&#039;&#039;&#039; on the client to ignore the message under given conditions. See the X.js documentation for more details.&lt;br /&gt;
&lt;br /&gt;
=== NotifyPlayer ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;notifyPlayer( $player_id, $notification_type, $notification_log, $notification_args )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Same as above, except that the notification is sent to one player only.&lt;br /&gt;
&lt;br /&gt;
This method must be used each time some private information must be transmitted to a player.&lt;br /&gt;
&lt;br /&gt;
Important: the variable for player name must be ${player_name} in order to be highlighted with the player color in the game log. If you want a second player name in the log, name the variable ${player_name2}, etc.&lt;br /&gt;
&lt;br /&gt;
Note that spectators cannot be notified using this method, because their player ID is not available via loadPlayersBasicInfos() or otherwise. You must use notifyAllPlayers() for any notification that spectators should get.&lt;br /&gt;
&lt;br /&gt;
== About random and randomness ==&lt;br /&gt;
&lt;br /&gt;
A large number of board games rely on random, most often based on dice, cards shuffling, picking some item in a bag, and so on. This is very important to ensure a high level of randomness for each of these situations.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s are a list of techniques you should use in these situations, from the best to the worst.&lt;br /&gt;
&lt;br /&gt;
=== Dice and bga_rand ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;bga_rand( min, max )&#039;&#039;&#039; &lt;br /&gt;
This is a BGA framework function that provides you a random number between &amp;quot;min&amp;quot; and &amp;quot;max&amp;quot; (inclusive), using the best available random method available on the system.&lt;br /&gt;
&lt;br /&gt;
This is the preferred function you should use, because we are updating it when a better method is introduced.&lt;br /&gt;
&lt;br /&gt;
As of now, bga_rand is based on the PHP function &amp;quot;random_int&amp;quot;, which ensures a cryptographic level of randomness.&lt;br /&gt;
&lt;br /&gt;
In particular, it is &#039;&#039;&#039;mandatory&#039;&#039;&#039; to use it for all &#039;&#039;&#039;dice throw&#039;&#039;&#039; (ie: games using other methods for dice throwing will be rejected by BGA during review).&lt;br /&gt;
&lt;br /&gt;
Note: rand() and mt_rand() are deprecated on BGA and should not be used anymore, as their randomness is not as good as &amp;quot;bga_rand&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== shuffle and cards shuffling ===&lt;br /&gt;
&lt;br /&gt;
To shuffle items, like a pile of cards, the best way is to use the BGA PHP [[Deck]] component and to use &amp;quot;shuffle&amp;quot; method. This ensures that the best available shuffling method is used, and that if in the future we improve it your game will be up to date.&lt;br /&gt;
&lt;br /&gt;
As of now, the Deck component shuffle method is based on PHP &amp;quot;shuffle&amp;quot; method, which has quite good randomness (even it is not as good as bga_rand). In consequence, we accept other shuffling methods during reviews, as long as they are based on PHP &amp;quot;shuffle&amp;quot; function (or similar, like &amp;quot;array_rand&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
=== Other methods ===&lt;br /&gt;
&lt;br /&gt;
Mysql &amp;quot;RAND()&amp;quot; function has not enough randomness to be a valid method to get a random element on BGA. This function has been used in some existing games and has given acceptable results, but now it should be avoided and you should use other methods instead.&lt;br /&gt;
&lt;br /&gt;
== Game statistics ==&lt;br /&gt;
&lt;br /&gt;
There are 2 types of statistics:&lt;br /&gt;
* a &amp;quot;player&amp;quot; statistic is a statistic associated to a player&lt;br /&gt;
* a &amp;quot;table&amp;quot; statistic is a statistic not associated to a player (global statistic for this game).&lt;br /&gt;
&lt;br /&gt;
See [[Game statistics: stats.inc.php]] to see how you define statistics for your game.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;initStat( $table_or_player, $name, $value, $player_id = null )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Create a statistic entry with a default value.&lt;br /&gt;
&lt;br /&gt;
This method must be called for each statistic of your game, in your setupNewGame method.&lt;br /&gt;
If you neglect to call this for a statistic, and also do not update the value during the course of a certain game using setStat or incStat, the value of the stat will be undefined rather than 0. This will result in it being ignored at the end of the game, as if it didn&#039;t apply to that particular game, and excluded from cumulative statistics. As a consequence - if do not want statistic to be applied, do not init it, or call set or inc on it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;$table_or_player&#039; must be set to &amp;quot;table&amp;quot; if this is a table statistic, or &amp;quot;player&amp;quot; if this is a player statistic.&lt;br /&gt;
&lt;br /&gt;
&#039;$name&#039; is the name of your statistic, as it has been defined in your stats.inc.php file.&lt;br /&gt;
&lt;br /&gt;
&#039;$value&#039; is the initial value of the statistic. If this is a player statistic and if the player is not specified by &amp;quot;$player_id&amp;quot; argument, the value is set for ALL players.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;setStat( $value, $name, $player_id = null )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Set a statistic $name to $value.&lt;br /&gt;
&lt;br /&gt;
If &amp;quot;$player_id&amp;quot; is not specified, setStat consider it is a TABLE statistic.&lt;br /&gt;
&lt;br /&gt;
If &amp;quot;$player_id&amp;quot; is specified, setStat consider it is a PLAYER statistic.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;incStat( $delta, $name, $player_id = null )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Increment (or decrement) specified statistic value by $delta value. Same behavior as setStat function.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;getStat( $name, $player_id = null )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Return the value of statistic specified by $name. Useful when creating derivative statistics such as average.&lt;br /&gt;
&lt;br /&gt;
== Translations ==&lt;br /&gt;
&lt;br /&gt;
See [[Translations]]&lt;br /&gt;
&lt;br /&gt;
== Manage player scores and Tie breaker ==&lt;br /&gt;
&lt;br /&gt;
=== Normal scoring ===&lt;br /&gt;
&lt;br /&gt;
At the end of the game, players automatically get a rank depending on their score: the player with the biggest score is #1, the player with the second biggest score is #2, and so on...&lt;br /&gt;
&lt;br /&gt;
During the game, you update player&#039;s score directly by updating &amp;quot;player_score&amp;quot; field of &amp;quot;player&amp;quot; table in database.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  // +2 points to active player&lt;br /&gt;
  self::DbQuery( &amp;quot;UPDATE player SET player_score=player_score+2 WHERE player_id=&#039;&amp;quot;.self::getActivePlayerId().&amp;quot;&#039;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
  // Set score of active player to 5&lt;br /&gt;
  self::DbQuery( &amp;quot;UPDATE player SET player_score=5 WHERE player_id=&#039;&amp;quot;.self::getActivePlayerId().&amp;quot;&#039;&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: don&#039;t forget to notify the client side in order the score control can be updated accordingly.&lt;br /&gt;
&lt;br /&gt;
=== Tie breaker ===&lt;br /&gt;
&lt;br /&gt;
Tie breaker is used when two players get the same score at the end of a game.&lt;br /&gt;
&lt;br /&gt;
Tie breaker is using &amp;quot;player_score_aux&amp;quot; field of &amp;quot;player&amp;quot; table. It is updated exactly like the &amp;quot;player_score&amp;quot; field.&lt;br /&gt;
&lt;br /&gt;
Tie breaker score is displayed only for players who are tied at the end of the game. Most of the time, it is not supposed to be displayed explicitly during the game.&lt;br /&gt;
&lt;br /&gt;
When you are using &amp;quot;player_score_aux&amp;quot; functionality, you must describe the formula to use in your gameinfos.inc.php file like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         &#039;tie_breaker_description&#039; =&amp;gt; totranslate(&amp;quot;Describe here your tie breaker formula&amp;quot;),&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This description will be used as a tooltip to explain to players how this auxiliary score has been calculated.&lt;br /&gt;
&lt;br /&gt;
See also [https://en.doc.boardgamearena.com/Game_meta-information:_gameinfos.inc.php#Multiple_tie_breaker_management Multiple Tie Breaker Management].&lt;br /&gt;
&lt;br /&gt;
=== Co-operative game ===&lt;br /&gt;
&lt;br /&gt;
To make everyone win/lose together in a full-coop game:&lt;br /&gt;
&lt;br /&gt;
Add the following in gameinfos.inc.php :&lt;br /&gt;
&#039;is_coop&#039; =&amp;gt; 1, // full cooperative&lt;br /&gt;
&lt;br /&gt;
Assign a score of zero to everyone if it&#039;s a loss.&lt;br /&gt;
Assign the same score &amp;gt; 0 to everyone if it&#039;s a win.&lt;br /&gt;
&lt;br /&gt;
=== Semi-coop ===&lt;br /&gt;
&lt;br /&gt;
If the game is not full-coop, then everyone loses = everyone is tied. I.e. set score to 0 to everybody.&lt;br /&gt;
&lt;br /&gt;
=== Only &amp;quot;winners&amp;quot; and &amp;quot;losers&amp;quot; ===&lt;br /&gt;
&lt;br /&gt;
For some games, there is only a group (or a single) &amp;quot;winner&amp;quot;, and everyone else is a &amp;quot;loser&amp;quot;, with no &amp;quot;end of game rank&amp;quot; (1st, 2nd, 3rd...).&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
* Coup&lt;br /&gt;
* Not Alone&lt;br /&gt;
* Werewolves&lt;br /&gt;
* Quantum&lt;br /&gt;
&lt;br /&gt;
In this case:&lt;br /&gt;
* Set the scores so that the winner has the best score, and the other players have the same (lower) score.&lt;br /&gt;
* Add the following lines to gameinfos.inc.php:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// If in the game, all losers are equal (no score to rank them or explicit in the rules that losers are not ranked between them), set this to true &lt;br /&gt;
// The game end result will display &amp;quot;Winner&amp;quot; for the 1st player and &amp;quot;Loser&amp;quot; for all other players&lt;br /&gt;
&#039;losers_not_ranked&#039; =&amp;gt; true,&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Werewolves and Coup are implemented like this, as you can see here:&lt;br /&gt;
* https://boardgamearena.com/#!gamepanel?game=werewolves&amp;amp;section=lastresults&lt;br /&gt;
* https://boardgamearena.com/#!gamepanel?game=coupcitystate&amp;amp;section=lastresults&lt;br /&gt;
&lt;br /&gt;
Adding this has the following effects:&lt;br /&gt;
* On game results for this game, &amp;quot;Winner&amp;quot; or &amp;quot;Loser&amp;quot; is going to appear instead of the usual &amp;quot;1st, 2nd, 3rd, ...&amp;quot;.&lt;br /&gt;
* When a game is over, the result of the game will be &amp;quot;End of game: Victory&amp;quot; or &amp;quot;End of game: Defeat&amp;quot; depending on the result of the CURRENT player (instead of the usual &amp;quot;Victory of XXX&amp;quot;).&lt;br /&gt;
* When calculating ELO points, if there is at least one &amp;quot;Loser&amp;quot;, no &amp;quot;victorious&amp;quot; player can lose ELO points, and no &amp;quot;losing&amp;quot; player can win ELO point. Usually it may happened because being tie with many players with a low rank is considered as a tie and may cost you points. If losers_not_ranked is set, we prevent this behavior and make sure you only gain/loss ELO when you get the corresponding results.&lt;br /&gt;
&lt;br /&gt;
Important: this SHOULD NOT be used for cooperative games (see is_coop parameter), or for 2 players games (it makes no sense in this case).&lt;br /&gt;
&lt;br /&gt;
=== Solo ===&lt;br /&gt;
&lt;br /&gt;
If game supports solo variant, a negative or zero score means defeat, a positive score means victory.&lt;br /&gt;
&lt;br /&gt;
=== Player elimination ===&lt;br /&gt;
&lt;br /&gt;
In some games, this is useful to eliminate a player from the game in order he/she can start another game without waiting for the current game end.&lt;br /&gt;
&lt;br /&gt;
This case should be rare. Please don&#039;t use player elimination feature if some player just has to wait the last 10% of the game for game end. This feature should be used only in games where players are eliminated all along the game (typical examples: &amp;quot;Perudo&amp;quot; or &amp;quot;The Werewolves of Miller&#039;s Hollow&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
&lt;br /&gt;
* Player to eliminate should NOT be active anymore (preferably use the feature in a &amp;quot;game&amp;quot; type game state).&lt;br /&gt;
* In your PHP code:&lt;br /&gt;
  self::eliminatePlayer( &amp;lt;player_to_eliminate_id&amp;gt; );&lt;br /&gt;
* the player is informed in a dialog box that he no longer have to play and can start another game if he/she wants too (with buttons &amp;quot;stay at this table&amp;quot; &amp;quot;quit table and back to main site&amp;quot;). In any case, the player is free to start &amp;amp; join another table from now.&lt;br /&gt;
* When your game is over, all players who have been eliminated before receive a &amp;quot;notification&amp;quot; (the small &amp;quot;!&amp;quot; icon on the top right of the BGA interface) that indicate them that &amp;quot;the game has ended&amp;quot; and invite them to review the game results.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important: this should not be used on a player who has already left the game (&amp;quot;zombie&amp;quot;) as leaving/being kicked of the game (outside of the scope of the rules) is not the same as being eliminated from the game (according to the rules), except if in the course of the game, the zombie player is eliminated according to the rules.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note: When all surviving players are eliminated at the same time BGA framework causes the game to be abandoned automatically.&#039;&#039;&#039;&lt;br /&gt;
&#039;&#039;&#039;To circumvent this, the game should leave 1 player not eliminated but change final scores accordingly and end the game.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Scoring Helper functions ===&lt;br /&gt;
&lt;br /&gt;
These functions should have been API but they are not, just add them to your php game and use for every game.&lt;br /&gt;
&lt;br /&gt;
    // get score&lt;br /&gt;
    function dbGetScore($player_id) {&lt;br /&gt;
        return $this-&amp;gt;getUniqueValueFromDB(&amp;quot;SELECT player_score FROM player WHERE player_id=&#039;$player_id&#039;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // set score&lt;br /&gt;
    function dbSetScore($player_id, $count) {&lt;br /&gt;
        $this-&amp;gt;DbQuery(&amp;quot;UPDATE player SET player_score=&#039;$count&#039; WHERE player_id=&#039;$player_id&#039;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // set aux score (tie breaker)&lt;br /&gt;
    function dbSetAuxScore($player_id, $score) {&lt;br /&gt;
        $this-&amp;gt;DbQuery(&amp;quot;UPDATE player SET player_score_aux=$score WHERE player_id=&#039;$player_id&#039;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // increment score (can be negative too)&lt;br /&gt;
    function dbIncScore($player_id, $inc) {&lt;br /&gt;
        $count = $this-&amp;gt;dbGetScore($player_id);&lt;br /&gt;
        if ($inc != 0) {&lt;br /&gt;
            $count += $inc;&lt;br /&gt;
            $this-&amp;gt;dbSetScore($player_id, $count);&lt;br /&gt;
        }&lt;br /&gt;
        return $count;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
== Reflexion time ==&lt;br /&gt;
&lt;br /&gt;
; function giveExtraTime( $player_id, $specific_time=null )&lt;br /&gt;
: Give standard extra time to this player.&lt;br /&gt;
: Standard extra time depends on the speed of the game (small with &amp;quot;slow&amp;quot; game option, bigger with other options).&lt;br /&gt;
: You can also specify an exact time to add, in seconds, with the &amp;quot;specified_time&amp;quot; argument (rarely used).&lt;br /&gt;
&lt;br /&gt;
; function isAsync()&lt;br /&gt;
: Returns true if game is turn based, false if it is realtime&lt;br /&gt;
&lt;br /&gt;
== Undo moves ==&lt;br /&gt;
&lt;br /&gt;
Please read our [[BGA Undo policy]] before.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important&#039;&#039;&#039;: Before using these methods, you must also add the following to your &amp;quot;gameinfos.inc.php&amp;quot; file, otherwise these methods are ineffective:&lt;br /&gt;
  &#039;db_undo_support&#039; =&amp;gt; true&lt;br /&gt;
&lt;br /&gt;
Note: if you deploy undo support after game is in production this will take into effect for new games only, old games will give user an error if user choses Undo action, but otherwise it should not affect them.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; function undoSavepoint( )&lt;br /&gt;
: Save the whole game situation inside an &amp;quot;Undo save point&amp;quot;.&lt;br /&gt;
: There is only ONE undo save point available (see [[BGA Undo policy]]). Cannot use in multiactivate state or in game state where next state is multiactive.&lt;br /&gt;
: Note: this function does not actually do anything when it is called, it only raises the flag to store the database AFTER transaction is over. So the actual state will be saved when you exit the function  calling it (technically before first queued notification is sent, which matters if you transition to game state not to user state after), this may affect what you end up saving.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; function undoRestorePoint()&lt;br /&gt;
: Restore the situation previously saved as an &amp;quot;Undo save point&amp;quot;.&lt;br /&gt;
: You must make sure that the active player is the same after and before the undoRestorePoint (ie: this is your responsibility to ensure that the player that is active when this method is called is exactly the same than the player that was active when the undoSavePoint method has been called).&lt;br /&gt;
&lt;br /&gt;
    function actionUndo() {&lt;br /&gt;
        self::checkAction(&#039;actionUndo&#039;);&lt;br /&gt;
        $this-&amp;gt;undoRestorePoint();&lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;nextState(&#039;next&#039;); // transition to single player state (i.e. beginning of player actions for this turn)&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important note&#039;&#039;&#039;: if you are reading game state variable right after restore (without changing state first) it won&#039;t work properly as the global table cache is not automatically refreshed after undoRestorePoint(). So you should either change state immediately to refresh game state values, or use $this-&amp;gt;gamestate-&amp;gt;reloadState() to refresh the state. If you choose to do the latest, be aware that this will bring the state machine back to the state during which the save point snapshot has been taken using undoSavepoint() (which means your transition you do after has to declared in the state which was saved, not in the state which was active for your actionUndo())&lt;br /&gt;
&lt;br /&gt;
== Managing errors and exceptions ==&lt;br /&gt;
&lt;br /&gt;
Note: when you throw an exception, all database changes and all notifications are cancelled immediately. This way, the game situation that existed before the request is completely restored.&lt;br /&gt;
&lt;br /&gt;
; throw new BgaUserException ( $error_message)&lt;br /&gt;
: Base class to notify a user error&lt;br /&gt;
: You must throw this exception when a player wants to do something that they are not allowed to do.&lt;br /&gt;
: The error message will be shown to the player as a &amp;quot;red message&amp;quot;.&lt;br /&gt;
: The error message must be translated, make sure you use self::_() or $this-&amp;gt;_() here and NOT clientranslate()&lt;br /&gt;
: Throwing such an exception is NOT considered a bug, so it is not traced in BGA error logs.&lt;br /&gt;
&lt;br /&gt;
Example from Gomoku:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     throw new BgaUserException( self::_(&amp;quot;There is already a stone on this intersection, you can&#039;t play there&amp;quot;) );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; throw new BgaVisibleSystemException ( $error_message)&lt;br /&gt;
: You must throw this exception when you detect something that is not supposed to happened in your code.&lt;br /&gt;
: The error message is shown to the user as an &amp;quot;Unexpected error&amp;quot;, in order that he can report it in the forum.&lt;br /&gt;
: The error message is logged in BGA error logs. If it happens regularly, we will report it to you.&lt;br /&gt;
&lt;br /&gt;
; throw new BgaSystemException ( $error_message)&lt;br /&gt;
: Base class to notify a system exception. The message will be hidden from the user, but show in the logs. Use this if the message contains technical information.&lt;br /&gt;
: You shouldn&#039;t use this type of exception except if you think the information shown could be critical. Indeed: a generic error message will be shown to the user, so it&#039;s going to be difficult for you to see what happened.&lt;br /&gt;
&lt;br /&gt;
== Zombie mode ==&lt;br /&gt;
&lt;br /&gt;
When a player leaves a game for any reason (expelled, quit), he becomes a &amp;quot;zombie player&amp;quot;. In this case, the results of the game won&#039;t count for statistics, but this is cool if the other players can finish the game anyway. That&#039;s why zombie mode exists: allow the other player to finish the game, even if the situation is not ideal.&lt;br /&gt;
&lt;br /&gt;
While developing your zombie mode, keep in mind that:&lt;br /&gt;
* Do not refer to the rules, because this situation is not planned by the rules.&lt;br /&gt;
* Try to figure that you are playing with your friends and one of them has to leave: how can we finish the game without killing the spirit of the game?&lt;br /&gt;
* The idea is NOT to develop an artificial intelligence for the game.&lt;br /&gt;
* Do not try to end the game early, even in a two-player game. The zombie is there to allow the game to continue, not to end it. Trying to end the game is not supported by the framework and will likely cause unexpected errors.&lt;br /&gt;
&lt;br /&gt;
Most of the time, the best thing to do when it is zombie player turn is to jump immediately to a state where he is not active anymore. For example, if he is in a game state where he has a choice between playing A and playing B, the best thing to do is NOT to choose A or B, but to pass. So, even if there&#039;s no &amp;quot;pass&amp;quot; action in the rules, add a &amp;quot;zombiepass&amp;quot; transitition in your game state and use it.&lt;br /&gt;
&lt;br /&gt;
Each time a zombie player must play, your &amp;quot;zombieTurn&amp;quot; method is called.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
* $state: the name of the current game state.&lt;br /&gt;
* $active_player: the id of the active player.&lt;br /&gt;
&lt;br /&gt;
Most of the time, your zombieTurn method looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    function zombieTurn( $state, $active_player )&lt;br /&gt;
    {&lt;br /&gt;
    	$statename = $state[&#039;name&#039;];&lt;br /&gt;
&lt;br /&gt;
        if( $statename == &#039;myFirstGameState&#039;&lt;br /&gt;
             ||  $statename == &#039;my2ndGameState&#039;&lt;br /&gt;
             ||  $statename == &#039;my3rdGameState&#039;&lt;br /&gt;
               ....&lt;br /&gt;
           )&lt;br /&gt;
        {&lt;br /&gt;
            $this-&amp;gt;gamestate-&amp;gt;nextState( &amp;quot;zombiePass&amp;quot; );&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            throw new BgaVisibleSystemException( &amp;quot;Zombie mode not supported at this game state: &amp;quot;.$statename );&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that in the example above, all corresponding game state should implement &amp;quot;zombiePass&amp;quot; as a transition.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Very important&#039;&#039;&#039;: your zombie code will be called when the player leaves the game. This action is triggered from the main site and propagated to the gameserver from a server, not from a browser. As a consequence, there is no current player associated to this action. In your zombieTurn function, you must &#039;&#039;&#039;never&#039;&#039;&#039; use getCurrentPlayerId() or getCurrentPlayerName(), otherwise it will fail with a &amp;quot;Not logged&amp;quot; error message.&lt;br /&gt;
&lt;br /&gt;
== Player color preferences ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
BGA players (Club members) may now choose their preferred color for playing. For example, if they are used to play green for every board game, they can select &amp;quot;green&amp;quot; in their BGA preferences page.&lt;br /&gt;
&lt;br /&gt;
Making your game compatible with colors preferences is very easy and requires only 1 line of configuration change:&lt;br /&gt;
&lt;br /&gt;
On your gameinfos.inc.php file, add the following lines :&lt;br /&gt;
&lt;br /&gt;
  // Favorite colors support: if set to &amp;quot;true&amp;quot;, support attribution of favorite colors based on player&#039;s preferences (see reattributeColorsBasedOnPreferences PHP method)&lt;br /&gt;
  // NB: this parameter is used only to flag games supporting this feature; you must use (or not use) reattributeColorsBasedOnPreferences PHP method to actually enable or disable the feature.&lt;br /&gt;
  &#039;favorite_colors_support&#039; =&amp;gt; true,&lt;br /&gt;
&lt;br /&gt;
Then, on your main &amp;lt;your_game&amp;gt;.game.php file check the code of &amp;quot;setupNewGame&amp;quot;. New template already have correct code, but if you editing very old game and it may be absent.&lt;br /&gt;
&lt;br /&gt;
        $gameinfos = $this-&amp;gt;getGameinfos();&lt;br /&gt;
        ...&lt;br /&gt;
        if ($gameinfos[&#039;favorite_colors_support&#039;])&lt;br /&gt;
            $this-&amp;gt;reattributeColorsBasedOnPreferences($players, $gameinfos[&#039;player_colors&#039;]); // this should be above reloadPlayersBasicInfos()&lt;br /&gt;
        self::reloadPlayersBasicInfos();&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;reattributeColorsBasedOnPreferences&amp;quot; method reattributes all colors, taking into account players color preferences and available colors.&lt;br /&gt;
&lt;br /&gt;
Note that you must update the colors to indicate the colors available for your game.&lt;br /&gt;
&lt;br /&gt;
Some important remarks:&lt;br /&gt;
* for some games (i.e. Chess), the color has an influence on a mechanism of the game, most of the time by giving a special advantage to a player (i.e. Starting the game). Color preference mechanism must NOT be used in such a case.&lt;br /&gt;
* your logic should NEVER consider that the first player has the color X, that the second player has the color Y, and so on. If this is the case, your game will NOT be compatible with reattributeColorsBasedOnPreferences as this method attribute colors to players based on their preferences and not based as their order at the table.&lt;br /&gt;
&lt;br /&gt;
Colours currently listed as a choice in preferences (Note - you don&#039;t have to pick these, the &amp;quot;closest&amp;quot; color will be found):&lt;br /&gt;
&lt;br /&gt;
* #ff0000 Red&lt;br /&gt;
* #008000 Green&lt;br /&gt;
* #0000ff Blue&lt;br /&gt;
* #ffa500 Yellow&lt;br /&gt;
* #000000 Black&lt;br /&gt;
* #ffffff White&lt;br /&gt;
* #e94190 Pink&lt;br /&gt;
* #982fff Purple&lt;br /&gt;
* #72c3b1 Cyan&lt;br /&gt;
* #f07f16 Orange&lt;br /&gt;
* #bdd002 Khaki green&lt;br /&gt;
* #7b7b7b Gray&lt;br /&gt;
&lt;br /&gt;
== Legacy games API ==&lt;br /&gt;
&lt;br /&gt;
For some very specific games (&amp;quot;legacy&amp;quot;, &amp;quot;campaign&amp;quot;), you need to keep some informations from a game to another.&lt;br /&gt;
&lt;br /&gt;
This should be an exceptional situation: the legacy API is costing resources on Board Game Arena databases, and is slowing down the game setup process + game end of game process. Please do not use it for things like:&lt;br /&gt;
* keeping a player preference/settings (=&amp;gt; player preferences and game options should be used instead)&lt;br /&gt;
* keeping a statistics, a score, or a ranking, while it is not planned in the physical board game, or while there is no added value compared to BGA statistics / rankings.&lt;br /&gt;
&lt;br /&gt;
You should use it for:&lt;br /&gt;
* legacy games: when some components of the game has been altered in a previous game and should be kept as it is.&lt;br /&gt;
* &amp;quot;campaign style&amp;quot; games: when a player is getting a &amp;quot;reward&amp;quot; at the end of a game, and should be able to use it in further games.&lt;br /&gt;
&lt;br /&gt;
Important: you cannot store more than 64k of data (serialized as JSON) per player per game. If you go over 64k, storeLegacyData function is going to FAIL, and there is a risk to create a major bug (= players blocked) in your game. You MUST make sure that no more than 64k of data is used for each player for your game. For example, if you are implementing a &amp;quot;campaign style&amp;quot; game and if you allow a player to start multiple campaign, you must LIMIT the number of different campaign so that the total data size to not go over the limit. We strongly recommend you to use this:&lt;br /&gt;
&lt;br /&gt;
  try &lt;br /&gt;
  {&lt;br /&gt;
  	$this-&amp;gt;storeLegacyTeamData( $my_data );&lt;br /&gt;
  }&lt;br /&gt;
  catch( feException $e ) // feException is a base class of BgaSystemException and others...&lt;br /&gt;
  {&lt;br /&gt;
  	if( $e-&amp;gt;getCode() == FEX_legacy_size_exceeded )&lt;br /&gt;
  	{&lt;br /&gt;
  		// Do something here to free some space in Legacy data (ex: by removing some variables)&lt;br /&gt;
  	}&lt;br /&gt;
  	else&lt;br /&gt;
  		throw $e;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
The keys may only contain letters and numbers, underscore seems not to be allowed.&lt;br /&gt;
&lt;br /&gt;
; function storeLegacyData( $player_id, $key, $data, $ttl = 365 )&lt;br /&gt;
: Store some data associated with $key for the given user / current game&lt;br /&gt;
: In the opposite of all other game data, this data will PERSIST after the end of this table, and can be re-used&lt;br /&gt;
: in a future table with the same game.&lt;br /&gt;
: IMPORTANT: The only possible place where you can use this method is when the game is over at your table (last game action). Otherwise, there is a risk of conflicts between ongoing games.    &lt;br /&gt;
: TTL is a time-to-live: the maximum, and default, is 365 days.&lt;br /&gt;
: In any way, the total data (= all keys) you can store for a given user+game is 64k (note: data is store serialized as JSON data)&lt;br /&gt;
: NOTICE: You can store some persistant data across all tables from your game using the specific player_id 0 which is unused. In such case, it&#039;s even more important to manage correctly the size of your data to avoid any exception or issue while storing updated data (ie. you can use this for some kind of leaderbord for solo game or contest)&lt;br /&gt;
&lt;br /&gt;
; function retrieveLegacyData( $player_id, $key )&lt;br /&gt;
: Get data associated with $key for the current game&lt;br /&gt;
: This data is common to ALL tables from the same game for this player, and persist from one table to another.&lt;br /&gt;
: Note: calling this function has an important cost =&amp;gt; please call it few times (possibly: only ONCE) for each player for 1 game if possible&lt;br /&gt;
: Note: you can use &#039;%&#039; in $key to retrieve all keys matching the given patterns&lt;br /&gt;
&lt;br /&gt;
; function removeLegacyData( $player_id, $key )&lt;br /&gt;
: Remove some legacy data with the given key&lt;br /&gt;
: (useful to free some data to avoid going over 64k)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; function storeLegacyTeamData( $data, $ttl = 365 )&lt;br /&gt;
: Same as storeLegacyData, except that it stores some data for the whole team within the current table and does not use a key&lt;br /&gt;
: Ie: if players A, B and C are at a table, the legacy data will be saved for future table with (exactly) A, B and C on the table.&lt;br /&gt;
: This is useful for games which are intended to be played several time by the same team.&lt;br /&gt;
: Note: the data total size is still limited, so you must implement catch the FEX_legacy_size_exceeded exception if it happens&lt;br /&gt;
&lt;br /&gt;
; function retrieveLegacyTeamData()&lt;br /&gt;
: Same as retrieveLegacyData, except that it retrieves some data for the whole team within the current table (set by storeLegacyTeamData)&lt;br /&gt;
&lt;br /&gt;
; function removeLegacyTeamData()&lt;br /&gt;
: Same as removeLegacyData, except that it retrieves some data for the whole team within the current table (set by storeLegacyTeamData)&lt;br /&gt;
&lt;br /&gt;
== Language dependent games API ==&lt;br /&gt;
&lt;br /&gt;
This API is used for games that are heavily language dependent. Two most common use cases are:&lt;br /&gt;
* Games that have a language dependent component that are not necessarily translatable, typically a list of words. (Think of games like Codenames, Decrypto, Just One...)&lt;br /&gt;
* Games with massive communication where players would like to ensure that all participants speak the same language. (Think of games like Werewolf, The Resistance, maybe even dixit...)&lt;br /&gt;
&lt;br /&gt;
If this option is used, the table created will be limited only to users that have specific language in their profile. Player starting the game would be able to chose one of the languages he speaks.&lt;br /&gt;
&lt;br /&gt;
There is a new property language_dependency in gameinfos.inc.php which can be set like this:&lt;br /&gt;
  &#039;language_dependency&#039; =&amp;gt; false,  //or if the property is missing, the game is not language dependent&lt;br /&gt;
  &#039;language_dependency&#039; =&amp;gt; true, //all players at the table must speak the same language&lt;br /&gt;
  &#039;language_dependency&#039; =&amp;gt; array( 1 =&amp;gt; &#039;en&#039;, 2 =&amp;gt; &#039;fr&#039;, 3 =&amp;gt; &#039;it&#039; ), //1-based list of supported languages&lt;br /&gt;
&lt;br /&gt;
In the gamename.game.php file, you can get the id of selected language with the method &#039;&#039;&#039;getGameLanguage&#039;&#039;&#039;.&lt;br /&gt;
; function getGameLanguage()&lt;br /&gt;
: Returns an index of the selected language as defined in gameinfos.inc.php.&lt;br /&gt;
&lt;br /&gt;
Languages currently available on BGA are:&lt;br /&gt;
  &#039;ar&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;العربية&amp;quot;, &#039;code&#039; =&amp;gt; &#039;ar_AE&#039; ),             // Arabic&lt;br /&gt;
  &#039;be&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;беларуская мова&amp;quot;, &#039;code&#039; =&amp;gt; &#039;be_BY&#039; ),     // Belarusian&lt;br /&gt;
  &#039;bn&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;বাংলা&amp;quot;, &#039;code&#039; =&amp;gt; &#039;bn_BD&#039; ),                // Bengali&lt;br /&gt;
  &#039;bg&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;български език&amp;quot;, &#039;code&#039; =&amp;gt; &#039;bg_BG&#039; ),      // Bulgarian&lt;br /&gt;
  &#039;ca&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;català&amp;quot;, &#039;code&#039; =&amp;gt; &#039;ca_ES&#039; ),              // Catalan&lt;br /&gt;
  &#039;cs&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;čeština&amp;quot;, &#039;code&#039; =&amp;gt; &#039;cs_CZ&#039; ),             // Czech&lt;br /&gt;
  &#039;da&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;dansk&amp;quot;, &#039;code&#039; =&amp;gt; &#039;da_DK&#039; ),               // Danish&lt;br /&gt;
  &#039;de&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;deutsch&amp;quot;, &#039;code&#039; =&amp;gt; &#039;de_DE&#039; ),             // German&lt;br /&gt;
  &#039;el&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;Ελληνικά&amp;quot;, &#039;code&#039; =&amp;gt; &#039;el_GR&#039; ),            // Greek&lt;br /&gt;
  &#039;en&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;English&amp;quot;, &#039;code&#039; =&amp;gt; &#039;en_US&#039; ),             // English&lt;br /&gt;
  &#039;es&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;español&amp;quot;, &#039;code&#039; =&amp;gt; &#039;es_ES&#039; ),             // Spanish&lt;br /&gt;
  &#039;et&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;eesti keel&amp;quot;, &#039;code&#039; =&amp;gt; &#039;et_EE&#039; ),          // Estonian       &lt;br /&gt;
  &#039;fi&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;suomi&amp;quot;, &#039;code&#039; =&amp;gt; &#039;fi_FI&#039; ),               // Finnish&lt;br /&gt;
  &#039;fr&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;français&amp;quot;, &#039;code&#039; =&amp;gt; &#039;fr_FR&#039; ),            // French&lt;br /&gt;
  &#039;he&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;עברית&amp;quot;, &#039;code&#039; =&amp;gt; &#039;he_IL&#039; ),               // Hebrew       &lt;br /&gt;
  &#039;hi&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;हिन्दी&amp;quot;, &#039;code&#039; =&amp;gt; &#039;hi_IN&#039; ),                 // Hindi&lt;br /&gt;
  &#039;hr&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;Hrvatski&amp;quot;, &#039;code&#039; =&amp;gt; &#039;hr_HR&#039; ),            // Croatian&lt;br /&gt;
  &#039;hu&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;magyar&amp;quot;, &#039;code&#039; =&amp;gt; &#039;hu_HU&#039; ),              // Hungarian&lt;br /&gt;
  &#039;id&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;Bahasa Indonesia&amp;quot;, &#039;code&#039; =&amp;gt; &#039;id_ID&#039; ),    // Indonesian&lt;br /&gt;
  &#039;ms&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;Bahasa Malaysia&amp;quot;, &#039;code&#039; =&amp;gt; &#039;ms_MY&#039; ),     // Malaysian&lt;br /&gt;
  &#039;it&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;italiano&amp;quot;, &#039;code&#039; =&amp;gt; &#039;it_IT&#039; ),            // Italian&lt;br /&gt;
  &#039;ja&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;日本語&amp;quot;, &#039;code&#039; =&amp;gt; &#039;ja_JP&#039; ),               // Japanese&lt;br /&gt;
  &#039;jv&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;Basa Jawa&amp;quot;, &#039;code&#039; =&amp;gt; &#039;jv_JV&#039; ),           // Javanese                       &lt;br /&gt;
  &#039;ko&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;한국어&amp;quot;, &#039;code&#039; =&amp;gt; &#039;ko_KR&#039; ),               // Korean&lt;br /&gt;
  &#039;lt&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;lietuvių&amp;quot;, &#039;code&#039; =&amp;gt; &#039;lt_LT&#039; ),            // Lithuanian&lt;br /&gt;
  &#039;lv&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;latviešu&amp;quot;, &#039;code&#039; =&amp;gt; &#039;lv_LV&#039; ),            // Latvian&lt;br /&gt;
  &#039;nl&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;nederlands&amp;quot;, &#039;code&#039; =&amp;gt; &#039;nl_NL&#039; ),          // Dutch&lt;br /&gt;
  &#039;no&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;norsk&amp;quot;, &#039;code&#039; =&amp;gt; &#039;nb_NO&#039; ),               // Norwegian&lt;br /&gt;
  &#039;oc&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;occitan&amp;quot;, &#039;code&#039; =&amp;gt; &#039;oc_FR&#039; ),             // Occitan&lt;br /&gt;
  &#039;pl&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;polski&amp;quot;, &#039;code&#039; =&amp;gt; &#039;pl_PL&#039; ),              // Polish&lt;br /&gt;
  &#039;pt&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;português&amp;quot;,  &#039;code&#039; =&amp;gt; &#039;pt_PT&#039; ),          // Portuguese&lt;br /&gt;
  &#039;ro&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;română&amp;quot;,  &#039;code&#039; =&amp;gt; &#039;ro_RO&#039;  ),            // Romanian&lt;br /&gt;
  &#039;ru&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;Русский язык&amp;quot;, &#039;code&#039; =&amp;gt; &#039;ru_RU&#039; ),        // Russian&lt;br /&gt;
  &#039;sk&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;slovenčina&amp;quot;, &#039;code&#039; =&amp;gt; &#039;sk_SK&#039; ),          // Slovak&lt;br /&gt;
  &#039;sl&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;slovenščina&amp;quot;, &#039;code&#039; =&amp;gt; &#039;sl_SI&#039; ),         // Slovenian       &lt;br /&gt;
  &#039;sr&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;Српски&amp;quot;, &#039;code&#039; =&amp;gt; &#039;sr_RS&#039; ),              // Serbian       &lt;br /&gt;
  &#039;sv&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;svenska&amp;quot;, &#039;code&#039; =&amp;gt; &#039;sv_SE&#039; ),             // Swedish&lt;br /&gt;
  &#039;tr&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;Türkçe&amp;quot;, &#039;code&#039; =&amp;gt; &#039;tr_TR&#039; ),              // Turkish       &lt;br /&gt;
  &#039;uk&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;Українська мова&amp;quot;, &#039;code&#039; =&amp;gt; &#039;uk_UA&#039; ),     // Ukrainian&lt;br /&gt;
  &#039;zh&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;中文 (漢)&amp;quot;,  &#039;code&#039; =&amp;gt; &#039;zh_TW&#039; ),           // Traditional Chinese (Hong Kong, Macau, Taiwan)&lt;br /&gt;
  &#039;zh-cn&#039; =&amp;gt; array( &#039;name&#039; =&amp;gt; &amp;quot;中文 (汉)&amp;quot;, &#039;code&#039; =&amp;gt; &#039;zh_CN&#039; ),         // Simplified Chinese (Mainland China, Singapore)&lt;br /&gt;
&lt;br /&gt;
== Debugging and Tracing ==&lt;br /&gt;
&lt;br /&gt;
To debug php code you can use some tracing functions available from the parent class such as debug, trace, error, warn, dump.&lt;br /&gt;
  &lt;br /&gt;
  self::debug(&amp;quot;Ahh!&amp;quot;);&lt;br /&gt;
  self::dump(&#039;my_var&#039;,$my_var);&lt;br /&gt;
&lt;br /&gt;
See [[Practical_debugging]] section for complete information about debugging interfaces and where to find logs.&lt;br /&gt;
&lt;br /&gt;
[[Category:Studio]]&lt;/div&gt;</summary>
		<author><name>SwHawk</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=User:SwHawk/Create_Modular_Code&amp;diff=13816</id>
		<title>User:SwHawk/Create Modular Code</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=User:SwHawk/Create_Modular_Code&amp;diff=13816"/>
		<updated>2022-06-30T09:54:07Z</updated>

		<summary type="html">&lt;p&gt;SwHawk: /* Create an anonymous class */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{InfoBox|title=WIP|body=&#039;&#039;&#039;This article is a Work In Progress, please do not refer to it for production purposes&#039;&#039;&#039;}}&lt;br /&gt;
&lt;br /&gt;
This page will cover steps you can take as a BGA developer to make your code more modular and better organized. The way the framework is implemented makes the [[Main game logic: yourgamename.game.php|game logic]] and the [[Game interface logic: yourgamename.js|interface logic]] files very monolithic. While this is not a problem in itself, even simple to moderately complex game may require this files to be over 5k lines of code. Thus you can quickly become lost in all the functions you need to declare, where they are declared, and where they are called.&lt;br /&gt;
&lt;br /&gt;
But there are steps that you can follow to take advantage of PHP&#039;s Object Oriented Code and the dojo toolkit&#039;s AMD loader to organize your code in separate files. Let&#039;s see what&#039;s available:&lt;br /&gt;
&lt;br /&gt;
== Acknowledgements ==&lt;br /&gt;
&lt;br /&gt;
Writing this wiki article wouldn&#039;t have been possible without the help, work and insight of more experienced BGA developers:&lt;br /&gt;
* [https://boardgamearena.com/player?id=83846198 Tisaac]  (Discord user Tisaac Human Expert)&lt;br /&gt;
* [https://boardgamearena.com/player?id=85537631 bennygui] (Discord user bennygui)&lt;br /&gt;
* [https://boardgamearena.com/player?id=84125723 VictoriaLa] (Discord user VictoriaLa)&lt;br /&gt;
* Syarwin and [https://boardgamearena.com/player?id=84554161 quietmint] (for their Welcome To [https://github.com/Syarwin/bga-welcometo repository])&lt;br /&gt;
* [https://boardgamearena.com/player?id=84522426 Mogri] (Discord user Mogri)&lt;br /&gt;
&lt;br /&gt;
== Conventions ==&lt;br /&gt;
In the code blocks, code additions will be displayed in bold and green, and added comments will be displayed in bold and dark grey so that they stand out from the boilerplate code from a scratch project. Part in red should be aapted to reflect your project&#039;s structure.&lt;br /&gt;
&lt;br /&gt;
== On the PHP side ==&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt; vs &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; ===&lt;br /&gt;
Throughout this section, I&#039;ll make heavy use of PHP&#039;s &amp;lt;code&amp;gt;require_once&amp;lt;/code&amp;gt; control structure. Why am I using &amp;lt;code&amp;gt;require(_once)&amp;lt;/code&amp;gt; instead of &amp;lt;code&amp;gt;include_once&amp;lt;/code&amp;gt;? Because if an error exists in a PHP file that you try to &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt;, only a warning will be thrown, but the script will continue in spite of the error. Using &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; if the included file has an error, the script dies when the inclusion takes places, throwing a fatal error (&amp;lt;code&amp;gt;E_COMPILE_ERROR&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
That way, I&#039;m sure the classes, traits or interfaces I&#039;m including are syntax error free.&lt;br /&gt;
&lt;br /&gt;
=== Game logic methods ===&lt;br /&gt;
The way the framework is implemented, your game logic is gathered inside a class (&amp;lt;code&amp;gt;YourProjectName&amp;lt;/code&amp;gt;) extending the [[Table|&amp;lt;code&amp;gt;Table&amp;lt;/code&amp;gt; class]]. You define your methods there so that they may be called from other parts of the framework (as long as they&#039;re public methods obviously).&lt;br /&gt;
&lt;br /&gt;
But you can take advantage of [https://www.php.net/manual/en/language.oop5.traits.php PHP Traits]. In a nutshell, Traits are a collection of methods that can be reused in different classes, to avoid code duplication. Here we&#039;re not going to reuse them anywhere else than in the game class, but this little trick allows us to put methods definitions in other files, and in so doing to avoid monolithic code.&lt;br /&gt;
&lt;br /&gt;
Basically you create a Trait in th &amp;lt;code&amp;gt;/modules/&amp;lt;/code&amp;gt; directory, for instance:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/UtiltityFunctionsTrait.php]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;lt;?php&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;namespace YourProjectNamespace\Modules;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;trait UtilityFunctionsTrait {&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &#039;&#039;&#039;public function myFirstUtilityFunction($args)&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;{&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//Your code here&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;}&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Then you can include it in you project&#039;s &amp;lt;code&amp;gt;X.game.php&amp;lt;/code&amp;gt; file like so:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X_game.php]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;?php&lt;br /&gt;
  /**&lt;br /&gt;
   *------&lt;br /&gt;
   * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
   * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
   * &lt;br /&gt;
   * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
   * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
   * -----&lt;br /&gt;
   * &lt;br /&gt;
   * X.game.php&lt;br /&gt;
   *&lt;br /&gt;
   * This is the main file for your game logic.&lt;br /&gt;
   *&lt;br /&gt;
   * In this PHP file, you are going to defines the rules of the game.&lt;br /&gt;
   *&lt;br /&gt;
   */&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;require_once &#039;modules/UtilityFunctionsTrait.php&#039;; &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;   //Here we require the trait to be loaded when the class is loaded&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;use X\Modules\UtilityFunctionsTrait;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;                 //We import the trait to be used directly as UtilityFunctionsTraits,&#039;&#039;&#039;&lt;br /&gt;
                                                      &#039;&#039;&#039;//otherwise we would have to use the Fully qualified class name&#039;&#039;&#039;&lt;br /&gt;
                                                      &#039;&#039;&#039;//(YourProjectNamespace\Modules\UtilityFunctionsTrait)&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 class X extends Table&lt;br /&gt;
 {&lt;br /&gt;
 //...&lt;br /&gt;
 &lt;br /&gt;
 //////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
 //////////// Utility functions&lt;br /&gt;
 ////////////    &lt;br /&gt;
 &lt;br /&gt;
     /*&lt;br /&gt;
         In this space, you can put any utility methods useful for your game logic&lt;br /&gt;
     */&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;use UtilityFunctionsTrait;&#039;&#039;&#039;&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//Here we actually include the trait inside the class, making all the trait&#039;s methods&#039;&#039;&#039; &lt;br /&gt;
                                &#039;&#039;&#039;//available as class methods, keeping their visibility scope (so a private method&#039;&#039;&#039;&lt;br /&gt;
                                &#039;&#039;&#039;//is still private)&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Support classes ===&lt;br /&gt;
Basically, the same as traits, you put your classes definitions into files that live under the &amp;lt;code&amp;gt;/modules/&amp;lt;/code&amp;gt; directory (don&#039;t forget to namespace your classes), and then require them at the top of &amp;lt;code&amp;gt;X_game.php&amp;lt;/code&amp;gt;, and voilà, you&#039;re done&lt;br /&gt;
&lt;br /&gt;
=== Adding autoloader support ===&lt;br /&gt;
&lt;br /&gt;
==== Coding standards ====&lt;br /&gt;
Even for simple games, you might end up having a dozen of traits and support classes. You can require them all in your &amp;lt;code&amp;gt;X_game.php&amp;lt;/code&amp;gt;. Or you can use an autoloader, which will load the necessary classes and traits at runtime. There are two PSRs dealing with autloading standards (namely [https://www.php-fig.org/psr/psr-0 PSR-0] which is marked as deprecated and [https://www.php-fig.org/psr/psr-4 PSR-4]) which state that your namespaces should be a reflection of the directory structure of your project.&lt;br /&gt;
&lt;br /&gt;
Basically, when creating namespaces, you choose a namespace prefix. For example, you could use your BGA handle and the project name as a namespace prefix (would result in &amp;lt;code&amp;gt;\SwHawk\X&amp;lt;/code&amp;gt; in my case), and then the rest of the namespace would be the directory the file is in. I usually group classes and traits by the function they have in my project, so my &amp;lt;code&amp;gt;/modules/&amp;lt;/code&amp;gt; directory looks like that:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
modules/&lt;br /&gt;
    php/&lt;br /&gt;
        Factory/                      //Holds my factory classes&lt;br /&gt;
            AFactoryClass.php         //The namespace for this file would be \SwHawk\X\Factory, and the fully qualified class name would be \SwHawk\X\Factory\AFactoryClass&lt;br /&gt;
            ...&lt;br /&gt;
        Object/                       //Holds my support classes&lt;br /&gt;
            ObjectA.php               //The namespace for this file would be \SwHawk\X\Object, and the fully qualified class name would be \SwHawk\X\Object\ObjectA&lt;br /&gt;
            ...&lt;br /&gt;
        Traits/                       //Holds my traits&lt;br /&gt;
            UtilityFunctionsTrait.php //The namespace for this file would be \SwHawk\X\Traits, and the fully qualified class name would be \SwHawk\X\Traits\UtilityFunctionsTrait&lt;br /&gt;
            ...&lt;br /&gt;
        ...&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Autoloader function for development ====&lt;br /&gt;
While your project is under development, you usually create, move and remove classes as part of the development process. So you usually need an autoloading function that can handle a lot of flexibility. Basically once you import a class using the &amp;lt;code&amp;gt;use&amp;lt;/code&amp;gt; keyword, the autoloading function will determine which file to &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; using its fully qualified class name, and then &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt;. This function needs to be either defined or included at the top of &amp;lt;code&amp;gt;X_game.php&amp;lt;/code&amp;gt;. Such a function would have the following code (borrowed and adapted from [https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader-examples.md this repository]):&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;spl_autoload_register(function ($class) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// project-specific namespace prefix&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;, adapt to your needs&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;, remember that you must escape \ characters in double-quoted strings (hence the \\)&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$prefix = &#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;SwHawk\\X\\&amp;quot;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// base directory for the namespace prefix, this file would usually reside in the modules/php/includes/ directory, so the base directory for all my classes would be a level higher&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$base_dir = __DIR__ . &#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;&#039;&#039;&#039; &#039;/../&#039; &#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;gt;&#039;&#039;&#039;;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// does the class use the namespace prefix?&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$len = strlen($prefix);&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;if (strncmp($prefix, $class, $len) !== 0) {&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// no, move to the next registered autoloader&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;return;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// get the relative class name&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$relative_class = substr($class, $len);&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;// replace the namespace prefix with the base directory, replace namespace&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;// separators with directory separators in the relative class name, append&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;// with .php&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$file = $base_dir . str_replace(&#039;\\&#039;, &#039;/&#039;, $relative_class) . &#039;.php&#039;;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// if the file exists, require it&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;if (file_exists($file)) {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;require $file;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Autoloader function for production ====&lt;br /&gt;
Once you&#039;re moving your game to production, the autoloader function provided before isn&#039;t optimized. Once in production, the directory tree should not be modified, so you can change the earlier autoloader to a classmap based one. Basically, you build an associative array with the fully qualified classes names as keys and the filepath as the value. An example would look like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;spl_autoload_register(function ($class) {&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;static $classmap = array(&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:red&amp;gt;&amp;quot;SwHawk\\X\\&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;Factory\\AFactoryClass&amp;quot; =&amp;gt; __DIR__ . &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;&amp;quot;/../&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;Factory/AFactoryClass.php&amp;quot;,&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;);&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;if(array_key_exists($class)) {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;require $classmap[$class];&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;} else {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;return;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This autoloader is better suited to production since it won&#039;t use expensive calls like &amp;lt;code&amp;gt;file_exists($filename)&amp;lt;/code&amp;gt;. You can write the classmap by yourself, but it can be quite cumbersome, there is some tools like [https://github.com/hanneskod/classtools this project], or [https://github.com/gnugat/nomo-spaco this one], or even scripts detailed in this [https://stackoverflow.com/questions/22761554/how-to-get-all-class-names-inside-a-particular-namespace StackOverflow topic]&lt;br /&gt;
&lt;br /&gt;
== On the JS side ==&lt;br /&gt;
&lt;br /&gt;
BGA uses the dojo toolkit framework for most of its javascript code. Dojo comes with its own way of loading modules, which you can read about in more detail [https://dojotoolkit.org/documentation/tutorials/1.10/modules/ here] and [https://dojotoolkit.org/documentation/tutorials/1.10/modules_advanced/ here]. To put it simply, there are two ways you can go about this&lt;br /&gt;
&lt;br /&gt;
=== Write plain javascript ===&lt;br /&gt;
&lt;br /&gt;
==== Relying on the dojo toolkit ====&lt;br /&gt;
Should you wan to write plain javascript, you can easily do so. What you need to do is actually load the file like so in &amp;lt;code&amp;gt;X.js&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&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;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&amp;quot;./modules/path/to/firstfile.js&amp;quot;,&amp;lt;/span&amp;gt;        &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;//The first file with your JS code&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&amp;quot;./modules/path/to/secondfile.js&amp;quot;,&amp;lt;/span&amp;gt;       &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;//The second file with another part of your JS code&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
     ...&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
         constructor: function(){&lt;br /&gt;
             ...&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
According to the dojo toolkit documentation, you will then need to directly access what you defined in the files.&lt;br /&gt;
&lt;br /&gt;
==== Alternative method ====&lt;br /&gt;
&lt;br /&gt;
This section has mostly been written by [[User:Mogri|Mogri]].&lt;br /&gt;
&lt;br /&gt;
This approach lets you avoid Dojo and &amp;lt;tt&amp;gt;this&amp;lt;/tt&amp;gt; and allows more modern JS.&lt;br /&gt;
&lt;br /&gt;
First, you&#039;ll need to a a statement at the beginning of the &amp;lt;code&amp;gt;X.js&amp;lt;/code&amp;gt; file:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
 *------&lt;br /&gt;
 * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
 * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
 *&lt;br /&gt;
 * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
 * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
 * -----&lt;br /&gt;
 *&lt;br /&gt;
 * X.js&lt;br /&gt;
 *&lt;br /&gt;
 * X user interface script&lt;br /&gt;
 * &lt;br /&gt;
 * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&gt;
 &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;window.X = {};&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// X = your game, or you can use something more generic&amp;lt;/span&amp;gt;&#039;&#039;&#039;&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;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/whatever.js&amp;quot;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
         constructor: function(){&lt;br /&gt;
             console.log(&#039;X constructor&#039;);&lt;br /&gt;
               &lt;br /&gt;
             // Here, you can init the global variables of your user interface&lt;br /&gt;
             // Example:&lt;br /&gt;
             // this.myGlobalValue = 0;&lt;br /&gt;
 &lt;br /&gt;
         },&lt;br /&gt;
         &lt;br /&gt;
         /*&lt;br /&gt;
             setup:&lt;br /&gt;
             &lt;br /&gt;
             This method must set up the game user interface according to current game situation specified&lt;br /&gt;
             in parameters.&lt;br /&gt;
             &lt;br /&gt;
             The method is called each time the game interface is displayed to a player, ie:&lt;br /&gt;
             _ when the game starts&lt;br /&gt;
             _ when a player refreshes the game page (F5)&lt;br /&gt;
             &lt;br /&gt;
             &amp;quot;gamedatas&amp;quot; argument contains all datas retrieved by your &amp;quot;getAllDatas&amp;quot; PHP method.&lt;br /&gt;
         */&lt;br /&gt;
        &lt;br /&gt;
         setup: function( gamedatas )&lt;br /&gt;
         {&lt;br /&gt;
             &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;X = Object.assign(this, X);&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// This will allow you to use X.method instead of this.method inside modules/whatever.js&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// the rest of your setup goes here&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
         },&lt;br /&gt;
     });&lt;br /&gt;
 });&lt;br /&gt;
&lt;br /&gt;
And then, in your &amp;lt;code&amp;gt;modules/whatever.js&amp;lt;/code&amp;gt; file:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/whatever.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;X = Object.assign(X, {&#039;&#039;&#039;&lt;br /&gt;
   &#039;&#039;&#039;MY_CONSTANT: 1,&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
   &#039;&#039;&#039;myFunction: (arg1, arg2) =&amp;gt; {&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;X.someFunction(X.MY_CONSTANT);&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;return arg1 + arg2;&#039;&#039;&#039;&lt;br /&gt;
   &#039;&#039;&#039;},&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
   &#039;&#039;&#039;someFunction: (x) =&amp;gt; _(&#039;The answer is: &#039;) + x,&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notes on this approach:&lt;br /&gt;
*Aside from setup and any framework-override functions, you can use arrow functions&lt;br /&gt;
*Always use X instead of &amp;lt;tt&amp;gt;this&amp;lt;/tt&amp;gt;&lt;br /&gt;
*As usual, you can use any number of modules this way&lt;br /&gt;
&lt;br /&gt;
=== Write an AMD module ===&lt;br /&gt;
You can take advantage of the toolkit&#039;s module system to declare dependencies between the differents files you&#039;ll be writing (modules in the toolkit&#039;s language). To be identified as modules, your Javascript files will need to have the following structure:&lt;br /&gt;
&lt;br /&gt;
==== Create a named new class ====&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/js/FirstModule.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;gt;&#039;&#039;&#039;define([&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo&amp;quot;,&amp;lt;/span&amp;gt;      &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Needed if you want to be able to use dojo methods such as dojo.place, etc.&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo/_base/declare&amp;quot;,&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;other dependencies...&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;],function(dojo, declare){&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;return declare(&amp;quot;className&amp;quot;,&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/*Parent classes that this class inherits, optional*/&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, {&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;&#039;&#039;&#039;/* static properties */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;let property1 = &amp;quot;value;&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;let property2 = 5;&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;constructor: function (args) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;&#039;&#039;&#039;/* instance properties */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;let property3 = 8;&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;let property4 = [ &amp;quot;arrayValue&amp;quot;, &amp;quot;arrayValue2&amp;quot; ]; &#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;method1: function (args) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;/* your code here */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
         &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;});&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then in the X.js file, you can use your newly created module like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&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;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/js/Firstmodule&amp;quot;,&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
     ...&lt;br /&gt;
     });&lt;br /&gt;
 });&lt;br /&gt;
&lt;br /&gt;
In your code, you can access your module&#039;s class and methods by doing so:&lt;br /&gt;
&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;let object = new className();&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;object.method1();&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;...&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This can lead to namespace collisions if you don&#039;t choose a namespace correctly, so you might want to take the same approach as described earlier for the PHP files for using a namespace.&lt;br /&gt;
&lt;br /&gt;
==== Create an anonymous class ====&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/js/SecondModule.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;gt;&#039;&#039;&#039;define([&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo&amp;quot;,&amp;lt;/span&amp;gt;      &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Needed if you want to be able to use dojo methods such as dojo.place, etc.&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo/_base/declare&amp;quot;,&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;other dependencies...&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;],function(dojo, declare){&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;return declare(&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/*Optional : parent classes that this class inherits, must be required in the array, and in the define callback arguments*/&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, {&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;&#039;&#039;&#039;/* static properties */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;let property1 = &amp;quot;value;&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;let property2 = 5;&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;constructor: function (args) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;&#039;&#039;&#039;/* instance properties */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;let property3 = 8;&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;let property4 = [ &amp;quot;arrayValue&amp;quot;, &amp;quot;arrayValue2&amp;quot; ]; &#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;method1: function (args) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;/* your code here */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
         &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;});&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then in the X.js file, you can use your newly created module like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&gt;
 &lt;br /&gt;
 define([&lt;br /&gt;
     &amp;quot;dojo&amp;quot;,&amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/js/SecondModule&amp;quot;,&#039;&#039;&#039;&amp;lt;/span&amp;gt;      &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//Has to be inserted in the third position as we&#039;ll&#039;&#039;&#039;&lt;br /&gt;
                                       &#039;&#039;&#039;//need an identifier later, and the other modules don&#039;t need it, see code in the preceding subsection.&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
     &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
 &lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, SecondModule&amp;lt;/span&amp;gt;  &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/* insert a reference here that you&#039;ll use throughout the JS file for this module */&amp;lt;/span&amp;gt;&#039;&#039;&#039;) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
     ...&lt;br /&gt;
     });&lt;br /&gt;
 });&lt;br /&gt;
&lt;br /&gt;
In your code, you can access your module&#039;s class and methods by doing so:&lt;br /&gt;
&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;let myObject = new SecondModule();&lt;br /&gt;
     &#039;&#039;&#039;let someValue = myObject.property3&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;myObject.method1();&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;...&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This can lead to namespace collisions if you don&#039;t choose a namespace correctly, so you might want to take the same approach as described earlier for the PHP files for using a namespace.&lt;br /&gt;
&lt;br /&gt;
==== Create a singleton object ====&lt;br /&gt;
&lt;br /&gt;
You can also create singleton objects by creating a module this way:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/js/singletonObject.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;define([&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo&amp;quot;,&amp;lt;/span&amp;gt;      &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Needed if you want to be able to use dojo methods such as dojo.place, etc.&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;], function (dojo) {&#039;&#039;&#039;&lt;br /&gt;
     &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;// Methods and variables defined in this part will not be available anywhere else than in this file&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;let privateVariable = &amp;quot;someValue&amp;quot;;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;let privateFunction = function (args) {&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//some code here&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;return {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;firstMethod: function (args) {&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;privateFunction(args);&#039;&#039;&#039;&lt;br /&gt;
             &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//some other code here&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;};&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To be used in the &amp;lt;code&amp;gt;X.js&amp;lt;/code&amp;gt; file, you must use the same method as in the [[#Create an anonymous class|previous section]]:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&gt;
 &lt;br /&gt;
 define([&lt;br /&gt;
     &amp;quot;dojo&amp;quot;,&amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&amp;quot;./modules/js/SecondModule&amp;quot;,&amp;lt;/span&amp;gt;         &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Has to be inserted in the third position as we&#039;ll need an identifier later, and the other modules don&#039;t need it&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&amp;quot;./modules/js/sigletonObject&amp;quot;,&amp;lt;/span&amp;gt;          &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//see code in the preceding subsection.&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
     &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/js/Firstmodule&amp;quot;,&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, SecondModule&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/* insert a reference here that you&#039;ll use throughout the JS file for this module */&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, singletonObject&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/* same here */&amp;lt;/span&amp;gt;&#039;&#039;&#039;) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
     ...&lt;br /&gt;
     });&lt;br /&gt;
 });&lt;br /&gt;
&lt;br /&gt;
Then you can access your code the same way as described in the [[#Create an anonymous class|previous section]]:&lt;br /&gt;
&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;singletonObject.firstMethod();&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;...&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Putting it all together ==&lt;br /&gt;
As you might have gathered reading this, much of your work will rely on the directory structure your project will follow.&lt;br /&gt;
&lt;br /&gt;
=== Recommended directory structure ===&lt;br /&gt;
&lt;br /&gt;
This is a recommendation, and in no way are you forced to follow it, but then you may have to adapt some of the code snippets shown below. All filenames should be self-explanatory, although there might be comments for some files.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
X/&lt;br /&gt;
  img/&lt;br /&gt;
    ...&lt;br /&gt;
  misc/&lt;br /&gt;
    ...&lt;br /&gt;
  modules/&lt;br /&gt;
    js/&lt;br /&gt;
      utility/&lt;br /&gt;
        FirstUtilityModule.js (defines a [[#Create a singleton object|singleton object]])&lt;br /&gt;
        SecondUtilityModule.js (defines an [[#Create an anonymous class|anonymous class]])&lt;br /&gt;
      notifications/&lt;br /&gt;
        FirstNotificationModule.js (defines a [[#Create a new named class|class with a name]])&lt;br /&gt;
      actions/&lt;br /&gt;
        FirstActionModule.js (plain JS code)&lt;br /&gt;
    php/&lt;br /&gt;
      includes/&lt;br /&gt;
        PNAutoloader.php (contains your autoloader, PN stands for ProjectName, and should be a trigram if possible)&lt;br /&gt;
        Other files to be included into files of the project. For instance splits from material.inc.php.&lt;br /&gt;
      Object/&lt;br /&gt;
         ObjectA.php&lt;br /&gt;
         ObjectB.php&lt;br /&gt;
      Traits/&lt;br /&gt;
         PlayerActions/&lt;br /&gt;
           PlayerActionsFunctionsTrait.php&lt;br /&gt;
         States/&lt;br /&gt;
           Actions/&lt;br /&gt;
             StateActionsFunctionsTrait.php&lt;br /&gt;
           Arguments/&lt;br /&gt;
             StateArgumentFunctionsTrait.php&lt;br /&gt;
         Utility/&lt;br /&gt;
           FirstUtilityFunctionsTrait.php&lt;br /&gt;
           SecondUtilityFunctionsTrait.php&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This directory tree is quite detailed, you&#039;re free to make arrangements with it to suit your project&#039;s requirements.&lt;br /&gt;
&lt;br /&gt;
=== Choosing a namespace prefix ===&lt;br /&gt;
&lt;br /&gt;
==== PHP ====&lt;br /&gt;
As stated earlier, in order to avoid collisions when importing your PHP Classes and Traits, you should define a namespace prefix. We&#039;ll use &amp;lt;code&amp;gt;Username\ProjectName&amp;lt;/code&amp;gt; throughout the remainder of this article.&lt;br /&gt;
&lt;br /&gt;
==== JS ====&lt;br /&gt;
As we&#039;ll create a named class, we should also use a namespace prefix for the JS module. We&#039;ll use &amp;lt;code&amp;gt;username.projectname&amp;lt;/code&amp;gt; throughout the remainder of this article&lt;br /&gt;
&lt;br /&gt;
=== Write the autoloader and include it in the game logic ===&lt;br /&gt;
Even though you may have a lot less PHP classes than stated here, you should really write an autoloader function, and since it&#039;s recommended for the production environment, you should proceed to write a [[#Autoloader function for production|classmap autoloader]] when your classes are pretty much stabilised.&lt;br /&gt;
&lt;br /&gt;
Then you need to include it in your X_game.php like so:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X_game.php]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;?php&lt;br /&gt;
  /**&lt;br /&gt;
   *------&lt;br /&gt;
   * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
   * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
   * &lt;br /&gt;
   * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
   * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
   * -----&lt;br /&gt;
   * &lt;br /&gt;
   * X.game.php&lt;br /&gt;
   *&lt;br /&gt;
   * This is the main file for your game logic.&lt;br /&gt;
   *&lt;br /&gt;
   * In this PHP file, you are going to defines the rules of the game.&lt;br /&gt;
   *&lt;br /&gt;
   */&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;require_once &#039;modules/php/includes/PNAutoloader.php&#039;;&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Here you&#039;ll write the use statements to import your classes and traits using the autoloader&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 class X extends Table&lt;br /&gt;
 {&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Here you can write the use statements to import your traits into the class, or put them in the relevant sections of the file&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Write your Javascript modules and include them ===&lt;br /&gt;
On the JS side of the code, you have multiple alternatives to choose from (see the [[#On the JS side|JS section]]), but all will require you to modify the &amp;lt;code&amp;gt;define&amp;lt;/code&amp;gt; statement at the beginning of the &amp;lt;code&amp;gt;X.js&amp;lt;/code&amp;gt; file. According to the directory structure shown above, the file would look like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&gt;
 &lt;br /&gt;
 define([&lt;br /&gt;
     &amp;quot;dojo&amp;quot;,&amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/js/utility/FirstUtilityModule&amp;quot;,&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;./modules/js/utility/SecondUtilityModule&amp;quot;,&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
     &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/js/actions/FirstActionModule.js&amp;quot;,&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;./modules/js/notifications/FirstNotificationModule&amp;quot;,&amp;lt;/span&amp;gt;&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare, &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;FirstUtilityModule, SecondUtilityModule&amp;lt;/span&amp;gt;&#039;&#039;&#039;) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
         constructor: function(){&lt;br /&gt;
            console.log(&#039;X constructor&#039;);&lt;br /&gt;
              &lt;br /&gt;
            // Here, you can init the global variables of your user interface&lt;br /&gt;
            // Example:&lt;br /&gt;
            // this.myGlobalValue = 0;&lt;br /&gt;
            &lt;br /&gt;
        },&lt;br /&gt;
        &lt;br /&gt;
        /*&lt;br /&gt;
            setup:&lt;br /&gt;
            &lt;br /&gt;
            This method must set up the game user interface according to current game situation specified&lt;br /&gt;
            in parameters.&lt;br /&gt;
            &lt;br /&gt;
            The method is called each time the game interface is displayed to a player, ie:&lt;br /&gt;
            _ when the game starts&lt;br /&gt;
            _ when a player refreshes the game page (F5)&lt;br /&gt;
            &lt;br /&gt;
            &amp;quot;gamedatas&amp;quot; argument contains all datas retrieved by your &amp;quot;getAllDatas&amp;quot; PHP method.&lt;br /&gt;
        */&lt;br /&gt;
        &lt;br /&gt;
        setup: function( gamedatas )&lt;br /&gt;
        {&lt;br /&gt;
            &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;FirstUtilityModule.myMethod();&#039;&#039;&#039;&lt;br /&gt;
            &#039;&#039;&#039;SecondUtilityModule.anotherMethod(gamedatas);&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
            &lt;br /&gt;
        },&lt;br /&gt;
        ...&lt;br /&gt;
        ///////////////////////////////////////////////////&lt;br /&gt;
        //// Reaction to cometD notifications&lt;br /&gt;
 &lt;br /&gt;
        /*&lt;br /&gt;
            setupNotifications:&lt;br /&gt;
            &lt;br /&gt;
            In this method, you associate each of your game notifications with your local method to handle it.&lt;br /&gt;
            &lt;br /&gt;
            Note: game notification names correspond to &amp;quot;notifyAllPlayers&amp;quot; and &amp;quot;notifyPlayer&amp;quot; calls in&lt;br /&gt;
                  your progressevolutiontechnologyswh.game.php file.&lt;br /&gt;
        &lt;br /&gt;
        */&lt;br /&gt;
        setupNotifications: function()&lt;br /&gt;
        {&lt;br /&gt;
            console.log( &#039;notifications subscriptions setup&#039; );&lt;br /&gt;
            &lt;br /&gt;
            // TODO: here, associate your game notifications with local methods&lt;br /&gt;
            &lt;br /&gt;
            // Example 1: standard notification handling&lt;br /&gt;
            // dojo.subscribe( &#039;cardPlayed&#039;, this, &amp;quot;notif_cardPlayed&amp;quot; );&lt;br /&gt;
            &lt;br /&gt;
            // Example 2: standard notification handling + tell the user interface to wait&lt;br /&gt;
            //            during 3 seconds after calling the method in order to let the players&lt;br /&gt;
            //            see what is happening in the game.&lt;br /&gt;
            // dojo.subscribe( &#039;cardPlayed&#039;, this, &amp;quot;notif_cardPlayed&amp;quot; );&lt;br /&gt;
            // this.notifqueue.setSynchronous( &#039;cardPlayed&#039;, 3000 );&lt;br /&gt;
            //&lt;br /&gt;
            // TODO: check module integration with dojo.subscribe&lt;br /&gt;
        },&lt;br /&gt;
     });&lt;br /&gt;
 });&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== See it in a real project ===&lt;br /&gt;
This method has been partially or totally applied on the following projects:&lt;br /&gt;
* [https://gitlab.swhawk.eu/silver/progressevolutiontechnologybga Progress: Evolution of Technology] by [[User:SwHawk|SwHawk]]&lt;br /&gt;
&lt;br /&gt;
If you have successfully applied this method in your project, feel free to add you project to the list by editing this section&lt;/div&gt;</summary>
		<author><name>SwHawk</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=User:SwHawk/Create_Modular_Code&amp;diff=13814</id>
		<title>User:SwHawk/Create Modular Code</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=User:SwHawk/Create_Modular_Code&amp;diff=13814"/>
		<updated>2022-06-30T09:44:21Z</updated>

		<summary type="html">&lt;p&gt;SwHawk: /* Create an anonymous class */ correct erroneous declare statement&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{InfoBox|title=WIP|body=&#039;&#039;&#039;This article is a Work In Progress, please do not refer to it for production purposes&#039;&#039;&#039;}}&lt;br /&gt;
&lt;br /&gt;
This page will cover steps you can take as a BGA developer to make your code more modular and better organized. The way the framework is implemented makes the [[Main game logic: yourgamename.game.php|game logic]] and the [[Game interface logic: yourgamename.js|interface logic]] files very monolithic. While this is not a problem in itself, even simple to moderately complex game may require this files to be over 5k lines of code. Thus you can quickly become lost in all the functions you need to declare, where they are declared, and where they are called.&lt;br /&gt;
&lt;br /&gt;
But there are steps that you can follow to take advantage of PHP&#039;s Object Oriented Code and the dojo toolkit&#039;s AMD loader to organize your code in separate files. Let&#039;s see what&#039;s available:&lt;br /&gt;
&lt;br /&gt;
== Acknowledgements ==&lt;br /&gt;
&lt;br /&gt;
Writing this wiki article wouldn&#039;t have been possible without the help, work and insight of more experienced BGA developers:&lt;br /&gt;
* [https://boardgamearena.com/player?id=83846198 Tisaac]  (Discord user Tisaac Human Expert)&lt;br /&gt;
* [https://boardgamearena.com/player?id=85537631 bennygui] (Discord user bennygui)&lt;br /&gt;
* [https://boardgamearena.com/player?id=84125723 VictoriaLa] (Discord user VictoriaLa)&lt;br /&gt;
* Syarwin and [https://boardgamearena.com/player?id=84554161 quietmint] (for their Welcome To [https://github.com/Syarwin/bga-welcometo repository])&lt;br /&gt;
* [https://boardgamearena.com/player?id=84522426 Mogri] (Discord user Mogri)&lt;br /&gt;
&lt;br /&gt;
== Conventions ==&lt;br /&gt;
In the code blocks, code additions will be displayed in bold and green, and added comments will be displayed in bold and dark grey so that they stand out from the boilerplate code from a scratch project. Part in red should be aapted to reflect your project&#039;s structure.&lt;br /&gt;
&lt;br /&gt;
== On the PHP side ==&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt; vs &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; ===&lt;br /&gt;
Throughout this section, I&#039;ll make heavy use of PHP&#039;s &amp;lt;code&amp;gt;require_once&amp;lt;/code&amp;gt; control structure. Why am I using &amp;lt;code&amp;gt;require(_once)&amp;lt;/code&amp;gt; instead of &amp;lt;code&amp;gt;include_once&amp;lt;/code&amp;gt;? Because if an error exists in a PHP file that you try to &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt;, only a warning will be thrown, but the script will continue in spite of the error. Using &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; if the included file has an error, the script dies when the inclusion takes places, throwing a fatal error (&amp;lt;code&amp;gt;E_COMPILE_ERROR&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
That way, I&#039;m sure the classes, traits or interfaces I&#039;m including are syntax error free.&lt;br /&gt;
&lt;br /&gt;
=== Game logic methods ===&lt;br /&gt;
The way the framework is implemented, your game logic is gathered inside a class (&amp;lt;code&amp;gt;YourProjectName&amp;lt;/code&amp;gt;) extending the [[Table|&amp;lt;code&amp;gt;Table&amp;lt;/code&amp;gt; class]]. You define your methods there so that they may be called from other parts of the framework (as long as they&#039;re public methods obviously).&lt;br /&gt;
&lt;br /&gt;
But you can take advantage of [https://www.php.net/manual/en/language.oop5.traits.php PHP Traits]. In a nutshell, Traits are a collection of methods that can be reused in different classes, to avoid code duplication. Here we&#039;re not going to reuse them anywhere else than in the game class, but this little trick allows us to put methods definitions in other files, and in so doing to avoid monolithic code.&lt;br /&gt;
&lt;br /&gt;
Basically you create a Trait in th &amp;lt;code&amp;gt;/modules/&amp;lt;/code&amp;gt; directory, for instance:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/UtiltityFunctionsTrait.php]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;lt;?php&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;namespace YourProjectNamespace\Modules;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;trait UtilityFunctionsTrait {&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &#039;&#039;&#039;public function myFirstUtilityFunction($args)&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;{&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//Your code here&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;}&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Then you can include it in you project&#039;s &amp;lt;code&amp;gt;X.game.php&amp;lt;/code&amp;gt; file like so:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X_game.php]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;?php&lt;br /&gt;
  /**&lt;br /&gt;
   *------&lt;br /&gt;
   * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
   * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
   * &lt;br /&gt;
   * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
   * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
   * -----&lt;br /&gt;
   * &lt;br /&gt;
   * X.game.php&lt;br /&gt;
   *&lt;br /&gt;
   * This is the main file for your game logic.&lt;br /&gt;
   *&lt;br /&gt;
   * In this PHP file, you are going to defines the rules of the game.&lt;br /&gt;
   *&lt;br /&gt;
   */&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;require_once &#039;modules/UtilityFunctionsTrait.php&#039;; &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;   //Here we require the trait to be loaded when the class is loaded&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;use X\Modules\UtilityFunctionsTrait;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;                 //We import the trait to be used directly as UtilityFunctionsTraits,&#039;&#039;&#039;&lt;br /&gt;
                                                      &#039;&#039;&#039;//otherwise we would have to use the Fully qualified class name&#039;&#039;&#039;&lt;br /&gt;
                                                      &#039;&#039;&#039;//(YourProjectNamespace\Modules\UtilityFunctionsTrait)&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 class X extends Table&lt;br /&gt;
 {&lt;br /&gt;
 //...&lt;br /&gt;
 &lt;br /&gt;
 //////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
 //////////// Utility functions&lt;br /&gt;
 ////////////    &lt;br /&gt;
 &lt;br /&gt;
     /*&lt;br /&gt;
         In this space, you can put any utility methods useful for your game logic&lt;br /&gt;
     */&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;use UtilityFunctionsTrait;&#039;&#039;&#039;&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//Here we actually include the trait inside the class, making all the trait&#039;s methods&#039;&#039;&#039; &lt;br /&gt;
                                &#039;&#039;&#039;//available as class methods, keeping their visibility scope (so a private method&#039;&#039;&#039;&lt;br /&gt;
                                &#039;&#039;&#039;//is still private)&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Support classes ===&lt;br /&gt;
Basically, the same as traits, you put your classes definitions into files that live under the &amp;lt;code&amp;gt;/modules/&amp;lt;/code&amp;gt; directory (don&#039;t forget to namespace your classes), and then require them at the top of &amp;lt;code&amp;gt;X_game.php&amp;lt;/code&amp;gt;, and voilà, you&#039;re done&lt;br /&gt;
&lt;br /&gt;
=== Adding autoloader support ===&lt;br /&gt;
&lt;br /&gt;
==== Coding standards ====&lt;br /&gt;
Even for simple games, you might end up having a dozen of traits and support classes. You can require them all in your &amp;lt;code&amp;gt;X_game.php&amp;lt;/code&amp;gt;. Or you can use an autoloader, which will load the necessary classes and traits at runtime. There are two PSRs dealing with autloading standards (namely [https://www.php-fig.org/psr/psr-0 PSR-0] which is marked as deprecated and [https://www.php-fig.org/psr/psr-4 PSR-4]) which state that your namespaces should be a reflection of the directory structure of your project.&lt;br /&gt;
&lt;br /&gt;
Basically, when creating namespaces, you choose a namespace prefix. For example, you could use your BGA handle and the project name as a namespace prefix (would result in &amp;lt;code&amp;gt;\SwHawk\X&amp;lt;/code&amp;gt; in my case), and then the rest of the namespace would be the directory the file is in. I usually group classes and traits by the function they have in my project, so my &amp;lt;code&amp;gt;/modules/&amp;lt;/code&amp;gt; directory looks like that:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
modules/&lt;br /&gt;
    php/&lt;br /&gt;
        Factory/                      //Holds my factory classes&lt;br /&gt;
            AFactoryClass.php         //The namespace for this file would be \SwHawk\X\Factory, and the fully qualified class name would be \SwHawk\X\Factory\AFactoryClass&lt;br /&gt;
            ...&lt;br /&gt;
        Object/                       //Holds my support classes&lt;br /&gt;
            ObjectA.php               //The namespace for this file would be \SwHawk\X\Object, and the fully qualified class name would be \SwHawk\X\Object\ObjectA&lt;br /&gt;
            ...&lt;br /&gt;
        Traits/                       //Holds my traits&lt;br /&gt;
            UtilityFunctionsTrait.php //The namespace for this file would be \SwHawk\X\Traits, and the fully qualified class name would be \SwHawk\X\Traits\UtilityFunctionsTrait&lt;br /&gt;
            ...&lt;br /&gt;
        ...&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Autoloader function for development ====&lt;br /&gt;
While your project is under development, you usually create, move and remove classes as part of the development process. So you usually need an autoloading function that can handle a lot of flexibility. Basically once you import a class using the &amp;lt;code&amp;gt;use&amp;lt;/code&amp;gt; keyword, the autoloading function will determine which file to &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; using its fully qualified class name, and then &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt;. This function needs to be either defined or included at the top of &amp;lt;code&amp;gt;X_game.php&amp;lt;/code&amp;gt;. Such a function would have the following code (borrowed and adapted from [https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader-examples.md this repository]):&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;spl_autoload_register(function ($class) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// project-specific namespace prefix&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;, adapt to your needs&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;, remember that you must escape \ characters in double-quoted strings (hence the \\)&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$prefix = &#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;SwHawk\\X\\&amp;quot;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// base directory for the namespace prefix, this file would usually reside in the modules/php/includes/ directory, so the base directory for all my classes would be a level higher&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$base_dir = __DIR__ . &#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;&#039;&#039;&#039; &#039;/../&#039; &#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;gt;&#039;&#039;&#039;;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// does the class use the namespace prefix?&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$len = strlen($prefix);&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;if (strncmp($prefix, $class, $len) !== 0) {&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// no, move to the next registered autoloader&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;return;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// get the relative class name&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$relative_class = substr($class, $len);&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;// replace the namespace prefix with the base directory, replace namespace&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;// separators with directory separators in the relative class name, append&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;// with .php&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$file = $base_dir . str_replace(&#039;\\&#039;, &#039;/&#039;, $relative_class) . &#039;.php&#039;;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// if the file exists, require it&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;if (file_exists($file)) {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;require $file;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Autoloader function for production ====&lt;br /&gt;
Once you&#039;re moving your game to production, the autoloader function provided before isn&#039;t optimized. Once in production, the directory tree should not be modified, so you can change the earlier autoloader to a classmap based one. Basically, you build an associative array with the fully qualified classes names as keys and the filepath as the value. An example would look like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;spl_autoload_register(function ($class) {&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;static $classmap = array(&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:red&amp;gt;&amp;quot;SwHawk\\X\\&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;Factory\\AFactoryClass&amp;quot; =&amp;gt; __DIR__ . &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;&amp;quot;/../&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;Factory/AFactoryClass.php&amp;quot;,&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;);&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;if(array_key_exists($class)) {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;require $classmap[$class];&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;} else {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;return;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This autoloader is better suited to production since it won&#039;t use expensive calls like &amp;lt;code&amp;gt;file_exists($filename)&amp;lt;/code&amp;gt;. You can write the classmap by yourself, but it can be quite cumbersome, there is some tools like [https://github.com/hanneskod/classtools this project], or [https://github.com/gnugat/nomo-spaco this one], or even scripts detailed in this [https://stackoverflow.com/questions/22761554/how-to-get-all-class-names-inside-a-particular-namespace StackOverflow topic]&lt;br /&gt;
&lt;br /&gt;
== On the JS side ==&lt;br /&gt;
&lt;br /&gt;
BGA uses the dojo toolkit framework for most of its javascript code. Dojo comes with its own way of loading modules, which you can read about in more detail [https://dojotoolkit.org/documentation/tutorials/1.10/modules/ here] and [https://dojotoolkit.org/documentation/tutorials/1.10/modules_advanced/ here]. To put it simply, there are two ways you can go about this&lt;br /&gt;
&lt;br /&gt;
=== Write plain javascript ===&lt;br /&gt;
&lt;br /&gt;
==== Relying on the dojo toolkit ====&lt;br /&gt;
Should you wan to write plain javascript, you can easily do so. What you need to do is actually load the file like so in &amp;lt;code&amp;gt;X.js&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&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;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&amp;quot;./modules/path/to/firstfile.js&amp;quot;,&amp;lt;/span&amp;gt;        &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;//The first file with your JS code&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&amp;quot;./modules/path/to/secondfile.js&amp;quot;,&amp;lt;/span&amp;gt;       &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;//The second file with another part of your JS code&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
     ...&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
         constructor: function(){&lt;br /&gt;
             ...&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
According to the dojo toolkit documentation, you will then need to directly access what you defined in the files.&lt;br /&gt;
&lt;br /&gt;
==== Alternative method ====&lt;br /&gt;
&lt;br /&gt;
This section has mostly been written by [[User:Mogri|Mogri]].&lt;br /&gt;
&lt;br /&gt;
This approach lets you avoid Dojo and &amp;lt;tt&amp;gt;this&amp;lt;/tt&amp;gt; and allows more modern JS.&lt;br /&gt;
&lt;br /&gt;
First, you&#039;ll need to a a statement at the beginning of the &amp;lt;code&amp;gt;X.js&amp;lt;/code&amp;gt; file:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
 *------&lt;br /&gt;
 * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
 * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
 *&lt;br /&gt;
 * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
 * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
 * -----&lt;br /&gt;
 *&lt;br /&gt;
 * X.js&lt;br /&gt;
 *&lt;br /&gt;
 * X user interface script&lt;br /&gt;
 * &lt;br /&gt;
 * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&gt;
 &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;window.X = {};&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// X = your game, or you can use something more generic&amp;lt;/span&amp;gt;&#039;&#039;&#039;&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;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/whatever.js&amp;quot;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
         constructor: function(){&lt;br /&gt;
             console.log(&#039;X constructor&#039;);&lt;br /&gt;
               &lt;br /&gt;
             // Here, you can init the global variables of your user interface&lt;br /&gt;
             // Example:&lt;br /&gt;
             // this.myGlobalValue = 0;&lt;br /&gt;
 &lt;br /&gt;
         },&lt;br /&gt;
         &lt;br /&gt;
         /*&lt;br /&gt;
             setup:&lt;br /&gt;
             &lt;br /&gt;
             This method must set up the game user interface according to current game situation specified&lt;br /&gt;
             in parameters.&lt;br /&gt;
             &lt;br /&gt;
             The method is called each time the game interface is displayed to a player, ie:&lt;br /&gt;
             _ when the game starts&lt;br /&gt;
             _ when a player refreshes the game page (F5)&lt;br /&gt;
             &lt;br /&gt;
             &amp;quot;gamedatas&amp;quot; argument contains all datas retrieved by your &amp;quot;getAllDatas&amp;quot; PHP method.&lt;br /&gt;
         */&lt;br /&gt;
        &lt;br /&gt;
         setup: function( gamedatas )&lt;br /&gt;
         {&lt;br /&gt;
             &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;X = Object.assign(this, X);&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// This will allow you to use X.method instead of this.method inside modules/whatever.js&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// the rest of your setup goes here&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
         },&lt;br /&gt;
     });&lt;br /&gt;
 });&lt;br /&gt;
&lt;br /&gt;
And then, in your &amp;lt;code&amp;gt;modules/whatever.js&amp;lt;/code&amp;gt; file:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/whatever.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;X = Object.assign(X, {&#039;&#039;&#039;&lt;br /&gt;
   &#039;&#039;&#039;MY_CONSTANT: 1,&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
   &#039;&#039;&#039;myFunction: (arg1, arg2) =&amp;gt; {&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;X.someFunction(X.MY_CONSTANT);&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;return arg1 + arg2;&#039;&#039;&#039;&lt;br /&gt;
   &#039;&#039;&#039;},&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
   &#039;&#039;&#039;someFunction: (x) =&amp;gt; _(&#039;The answer is: &#039;) + x,&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notes on this approach:&lt;br /&gt;
*Aside from setup and any framework-override functions, you can use arrow functions&lt;br /&gt;
*Always use X instead of &amp;lt;tt&amp;gt;this&amp;lt;/tt&amp;gt;&lt;br /&gt;
*As usual, you can use any number of modules this way&lt;br /&gt;
&lt;br /&gt;
=== Write an AMD module ===&lt;br /&gt;
You can take advantage of the toolkit&#039;s module system to declare dependencies between the differents files you&#039;ll be writing (modules in the toolkit&#039;s language). To be identified as modules, your Javascript files will need to have the following structure:&lt;br /&gt;
&lt;br /&gt;
==== Create a named new class ====&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/js/FirstModule.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;gt;&#039;&#039;&#039;define([&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo&amp;quot;,&amp;lt;/span&amp;gt;      &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Needed if you want to be able to use dojo methods such as dojo.place, etc.&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo/_base/declare&amp;quot;,&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;other dependencies...&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;],function(dojo, declare){&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;return declare(&amp;quot;className&amp;quot;,&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/*Parent classes that this class inherits, optional*/&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, {&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;&#039;&#039;&#039;/* static properties */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;let property1 = &amp;quot;value;&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;let property2 = 5;&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;constructor: function (args) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;&#039;&#039;&#039;/* instance properties */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;let property3 = 8;&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;let property4 = [ &amp;quot;arrayValue&amp;quot;, &amp;quot;arrayValue2&amp;quot; ]; &#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;method1: function (args) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;/* your code here */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
         &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;});&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then in the X.js file, you can use your newly created module like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&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;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/js/Firstmodule&amp;quot;,&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
     ...&lt;br /&gt;
     });&lt;br /&gt;
 });&lt;br /&gt;
&lt;br /&gt;
In your code, you can access your module&#039;s class and methods by doing so:&lt;br /&gt;
&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;let object = new className();&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;object.method1();&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;...&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This can lead to namespace collisions if you don&#039;t choose a namespace correctly, so you might want to take the same approach as described earlier for the PHP files for using a namespace.&lt;br /&gt;
&lt;br /&gt;
==== Create an anonymous class ====&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/js/SecondModule.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;gt;&#039;&#039;&#039;define([&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo&amp;quot;,&amp;lt;/span&amp;gt;      &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Needed if you want to be able to use dojo methods such as dojo.place, etc.&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo/_base/declare&amp;quot;,&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;other dependencies...&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;],function(dojo, declare){&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;return declare(&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/*Optional : parent classes that this class inherits, must be required in the array, and in the define callback arguments*/&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, {&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;&#039;&#039;&#039;/* static properties */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;let property1 = &amp;quot;value;&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;let property2 = 5;&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;constructor: function (args) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;&#039;&#039;&#039;/* instance properties */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;let property3 = 8;&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;let property4 = [ &amp;quot;arrayValue&amp;quot;, &amp;quot;arrayValue2&amp;quot; ]; &#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;method1: function (args) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;/* your code here */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
         &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;});&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then in the X.js file, you can use your newly created module like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&gt;
 &lt;br /&gt;
 define([&lt;br /&gt;
     &amp;quot;dojo&amp;quot;,&amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/js/SecondModule&amp;quot;,&#039;&#039;&#039;&amp;lt;/span&amp;gt;      &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//Has to be inserted in the third position as we&#039;ll&#039;&#039;&#039;&lt;br /&gt;
                                       &#039;&#039;&#039;//need an identifier later, and the other modules don&#039;t need it, see code in the preceding subsection.&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
     &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
 &lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, SecondModule&amp;lt;/span&amp;gt;  &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/* insert a reference here that you&#039;ll use throughout the JS file for this module */&amp;lt;/span&amp;gt;&#039;&#039;&#039;) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
     ...&lt;br /&gt;
     });&lt;br /&gt;
 });&lt;br /&gt;
&lt;br /&gt;
In your code, you can access your module&#039;s class and methods by doing so:&lt;br /&gt;
&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;let someValue = SecondModule.property3&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;SecondModule.method1();&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;...&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This can lead to namespace collisions if you don&#039;t choose a namespace correctly, so you might want to take the same approach as described earlier for the PHP files for using a namespace.&lt;br /&gt;
&lt;br /&gt;
==== Create a singleton object ====&lt;br /&gt;
&lt;br /&gt;
You can also create singleton objects by creating a module this way:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/js/singletonObject.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;define([&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo&amp;quot;,&amp;lt;/span&amp;gt;      &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Needed if you want to be able to use dojo methods such as dojo.place, etc.&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;], function (dojo) {&#039;&#039;&#039;&lt;br /&gt;
     &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;// Methods and variables defined in this part will not be available anywhere else than in this file&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;let privateVariable = &amp;quot;someValue&amp;quot;;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;let privateFunction = function (args) {&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//some code here&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;return {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;firstMethod: function (args) {&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;privateFunction(args);&#039;&#039;&#039;&lt;br /&gt;
             &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//some other code here&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;};&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To be used in the &amp;lt;code&amp;gt;X.js&amp;lt;/code&amp;gt; file, you must use the same method as in the [[#Create an anonymous class|previous section]]:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&gt;
 &lt;br /&gt;
 define([&lt;br /&gt;
     &amp;quot;dojo&amp;quot;,&amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&amp;quot;./modules/js/SecondModule&amp;quot;,&amp;lt;/span&amp;gt;         &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Has to be inserted in the third position as we&#039;ll need an identifier later, and the other modules don&#039;t need it&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&amp;quot;./modules/js/sigletonObject&amp;quot;,&amp;lt;/span&amp;gt;          &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//see code in the preceding subsection.&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
     &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/js/Firstmodule&amp;quot;,&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, SecondModule&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/* insert a reference here that you&#039;ll use throughout the JS file for this module */&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, singletonObject&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/* same here */&amp;lt;/span&amp;gt;&#039;&#039;&#039;) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
     ...&lt;br /&gt;
     });&lt;br /&gt;
 });&lt;br /&gt;
&lt;br /&gt;
Then you can access your code the same way as described in the [[#Create an anonymous class|previous section]]:&lt;br /&gt;
&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;singletonObject.firstMethod();&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;...&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Putting it all together ==&lt;br /&gt;
As you might have gathered reading this, much of your work will rely on the directory structure your project will follow.&lt;br /&gt;
&lt;br /&gt;
=== Recommended directory structure ===&lt;br /&gt;
&lt;br /&gt;
This is a recommendation, and in no way are you forced to follow it, but then you may have to adapt some of the code snippets shown below. All filenames should be self-explanatory, although there might be comments for some files.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
X/&lt;br /&gt;
  img/&lt;br /&gt;
    ...&lt;br /&gt;
  misc/&lt;br /&gt;
    ...&lt;br /&gt;
  modules/&lt;br /&gt;
    js/&lt;br /&gt;
      utility/&lt;br /&gt;
        FirstUtilityModule.js (defines a [[#Create a singleton object|singleton object]])&lt;br /&gt;
        SecondUtilityModule.js (defines an [[#Create an anonymous class|anonymous class]])&lt;br /&gt;
      notifications/&lt;br /&gt;
        FirstNotificationModule.js (defines a [[#Create a new named class|class with a name]])&lt;br /&gt;
      actions/&lt;br /&gt;
        FirstActionModule.js (plain JS code)&lt;br /&gt;
    php/&lt;br /&gt;
      includes/&lt;br /&gt;
        PNAutoloader.php (contains your autoloader, PN stands for ProjectName, and should be a trigram if possible)&lt;br /&gt;
        Other files to be included into files of the project. For instance splits from material.inc.php.&lt;br /&gt;
      Object/&lt;br /&gt;
         ObjectA.php&lt;br /&gt;
         ObjectB.php&lt;br /&gt;
      Traits/&lt;br /&gt;
         PlayerActions/&lt;br /&gt;
           PlayerActionsFunctionsTrait.php&lt;br /&gt;
         States/&lt;br /&gt;
           Actions/&lt;br /&gt;
             StateActionsFunctionsTrait.php&lt;br /&gt;
           Arguments/&lt;br /&gt;
             StateArgumentFunctionsTrait.php&lt;br /&gt;
         Utility/&lt;br /&gt;
           FirstUtilityFunctionsTrait.php&lt;br /&gt;
           SecondUtilityFunctionsTrait.php&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This directory tree is quite detailed, you&#039;re free to make arrangements with it to suit your project&#039;s requirements.&lt;br /&gt;
&lt;br /&gt;
=== Choosing a namespace prefix ===&lt;br /&gt;
&lt;br /&gt;
==== PHP ====&lt;br /&gt;
As stated earlier, in order to avoid collisions when importing your PHP Classes and Traits, you should define a namespace prefix. We&#039;ll use &amp;lt;code&amp;gt;Username\ProjectName&amp;lt;/code&amp;gt; throughout the remainder of this article.&lt;br /&gt;
&lt;br /&gt;
==== JS ====&lt;br /&gt;
As we&#039;ll create a named class, we should also use a namespace prefix for the JS module. We&#039;ll use &amp;lt;code&amp;gt;username.projectname&amp;lt;/code&amp;gt; throughout the remainder of this article&lt;br /&gt;
&lt;br /&gt;
=== Write the autoloader and include it in the game logic ===&lt;br /&gt;
Even though you may have a lot less PHP classes than stated here, you should really write an autoloader function, and since it&#039;s recommended for the production environment, you should proceed to write a [[#Autoloader function for production|classmap autoloader]] when your classes are pretty much stabilised.&lt;br /&gt;
&lt;br /&gt;
Then you need to include it in your X_game.php like so:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X_game.php]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;?php&lt;br /&gt;
  /**&lt;br /&gt;
   *------&lt;br /&gt;
   * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
   * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
   * &lt;br /&gt;
   * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
   * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
   * -----&lt;br /&gt;
   * &lt;br /&gt;
   * X.game.php&lt;br /&gt;
   *&lt;br /&gt;
   * This is the main file for your game logic.&lt;br /&gt;
   *&lt;br /&gt;
   * In this PHP file, you are going to defines the rules of the game.&lt;br /&gt;
   *&lt;br /&gt;
   */&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;require_once &#039;modules/php/includes/PNAutoloader.php&#039;;&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Here you&#039;ll write the use statements to import your classes and traits using the autoloader&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 class X extends Table&lt;br /&gt;
 {&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Here you can write the use statements to import your traits into the class, or put them in the relevant sections of the file&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Write your Javascript modules and include them ===&lt;br /&gt;
On the JS side of the code, you have multiple alternatives to choose from (see the [[#On the JS side|JS section]]), but all will require you to modify the &amp;lt;code&amp;gt;define&amp;lt;/code&amp;gt; statement at the beginning of the &amp;lt;code&amp;gt;X.js&amp;lt;/code&amp;gt; file. According to the directory structure shown above, the file would look like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&gt;
 &lt;br /&gt;
 define([&lt;br /&gt;
     &amp;quot;dojo&amp;quot;,&amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/js/utility/FirstUtilityModule&amp;quot;,&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;./modules/js/utility/SecondUtilityModule&amp;quot;,&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
     &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/js/actions/FirstActionModule.js&amp;quot;,&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;./modules/js/notifications/FirstNotificationModule&amp;quot;,&amp;lt;/span&amp;gt;&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare, &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;FirstUtilityModule, SecondUtilityModule&amp;lt;/span&amp;gt;&#039;&#039;&#039;) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
         constructor: function(){&lt;br /&gt;
            console.log(&#039;X constructor&#039;);&lt;br /&gt;
              &lt;br /&gt;
            // Here, you can init the global variables of your user interface&lt;br /&gt;
            // Example:&lt;br /&gt;
            // this.myGlobalValue = 0;&lt;br /&gt;
            &lt;br /&gt;
        },&lt;br /&gt;
        &lt;br /&gt;
        /*&lt;br /&gt;
            setup:&lt;br /&gt;
            &lt;br /&gt;
            This method must set up the game user interface according to current game situation specified&lt;br /&gt;
            in parameters.&lt;br /&gt;
            &lt;br /&gt;
            The method is called each time the game interface is displayed to a player, ie:&lt;br /&gt;
            _ when the game starts&lt;br /&gt;
            _ when a player refreshes the game page (F5)&lt;br /&gt;
            &lt;br /&gt;
            &amp;quot;gamedatas&amp;quot; argument contains all datas retrieved by your &amp;quot;getAllDatas&amp;quot; PHP method.&lt;br /&gt;
        */&lt;br /&gt;
        &lt;br /&gt;
        setup: function( gamedatas )&lt;br /&gt;
        {&lt;br /&gt;
            &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;FirstUtilityModule.myMethod();&#039;&#039;&#039;&lt;br /&gt;
            &#039;&#039;&#039;SecondUtilityModule.anotherMethod(gamedatas);&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
            &lt;br /&gt;
        },&lt;br /&gt;
        ...&lt;br /&gt;
        ///////////////////////////////////////////////////&lt;br /&gt;
        //// Reaction to cometD notifications&lt;br /&gt;
 &lt;br /&gt;
        /*&lt;br /&gt;
            setupNotifications:&lt;br /&gt;
            &lt;br /&gt;
            In this method, you associate each of your game notifications with your local method to handle it.&lt;br /&gt;
            &lt;br /&gt;
            Note: game notification names correspond to &amp;quot;notifyAllPlayers&amp;quot; and &amp;quot;notifyPlayer&amp;quot; calls in&lt;br /&gt;
                  your progressevolutiontechnologyswh.game.php file.&lt;br /&gt;
        &lt;br /&gt;
        */&lt;br /&gt;
        setupNotifications: function()&lt;br /&gt;
        {&lt;br /&gt;
            console.log( &#039;notifications subscriptions setup&#039; );&lt;br /&gt;
            &lt;br /&gt;
            // TODO: here, associate your game notifications with local methods&lt;br /&gt;
            &lt;br /&gt;
            // Example 1: standard notification handling&lt;br /&gt;
            // dojo.subscribe( &#039;cardPlayed&#039;, this, &amp;quot;notif_cardPlayed&amp;quot; );&lt;br /&gt;
            &lt;br /&gt;
            // Example 2: standard notification handling + tell the user interface to wait&lt;br /&gt;
            //            during 3 seconds after calling the method in order to let the players&lt;br /&gt;
            //            see what is happening in the game.&lt;br /&gt;
            // dojo.subscribe( &#039;cardPlayed&#039;, this, &amp;quot;notif_cardPlayed&amp;quot; );&lt;br /&gt;
            // this.notifqueue.setSynchronous( &#039;cardPlayed&#039;, 3000 );&lt;br /&gt;
            //&lt;br /&gt;
            // TODO: check module integration with dojo.subscribe&lt;br /&gt;
        },&lt;br /&gt;
     });&lt;br /&gt;
 });&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== See it in a real project ===&lt;br /&gt;
This method has been partially or totally applied on the following projects:&lt;br /&gt;
* [https://gitlab.swhawk.eu/silver/progressevolutiontechnologybga Progress: Evolution of Technology] by [[User:SwHawk|SwHawk]]&lt;br /&gt;
&lt;br /&gt;
If you have successfully applied this method in your project, feel free to add you project to the list by editing this section&lt;/div&gt;</summary>
		<author><name>SwHawk</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=User:SwHawk/Create_Modular_Code&amp;diff=13725</id>
		<title>User:SwHawk/Create Modular Code</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=User:SwHawk/Create_Modular_Code&amp;diff=13725"/>
		<updated>2022-06-25T23:13:10Z</updated>

		<summary type="html">&lt;p&gt;SwHawk: Missing ) in /* Alternative method */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{InfoBox|title=WIP|body=&#039;&#039;&#039;This article is a Work In Progress, please do not refer to it for production purposes&#039;&#039;&#039;}}&lt;br /&gt;
&lt;br /&gt;
This page will cover steps you can take as a BGA developer to make your code more modular and better organized. The way the framework is implemented makes the [[Main game logic: yourgamename.game.php|game logic]] and the [[Game interface logic: yourgamename.js|interface logic]] files very monolithic. While this is not a problem in itself, even simple to moderately complex game may require this files to be over 5k lines of code. Thus you can quickly become lost in all the functions you need to declare, where they are declared, and where they are called.&lt;br /&gt;
&lt;br /&gt;
But there are steps that you can follow to take advantage of PHP&#039;s Object Oriented Code and the dojo toolkit&#039;s AMD loader to organize your code in separate files. Let&#039;s see what&#039;s available:&lt;br /&gt;
&lt;br /&gt;
== Acknowledgements ==&lt;br /&gt;
&lt;br /&gt;
Writing this wiki article wouldn&#039;t have been possible without the help, work and insight of more experienced BGA developers:&lt;br /&gt;
* [https://boardgamearena.com/player?id=83846198 Tisaac]  (Discord user Tisaac Human Expert)&lt;br /&gt;
* [https://boardgamearena.com/player?id=85537631 bennygui] (Discord user bennygui)&lt;br /&gt;
* [https://boardgamearena.com/player?id=84125723 VictoriaLa] (Discord user VictoriaLa)&lt;br /&gt;
* Syarwin and [https://boardgamearena.com/player?id=84554161 quietmint] (for their Welcome To [https://github.com/Syarwin/bga-welcometo repository])&lt;br /&gt;
* [https://boardgamearena.com/player?id=84522426 Mogri] (Discord user Mogri)&lt;br /&gt;
&lt;br /&gt;
== Conventions ==&lt;br /&gt;
In the code blocks, code additions will be displayed in bold and green, and added comments will be displayed in bold and dark grey so that they stand out from the boilerplate code from a scratch project. Part in red should be aapted to reflect your project&#039;s structure.&lt;br /&gt;
&lt;br /&gt;
== On the PHP side ==&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt; vs &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; ===&lt;br /&gt;
Throughout this section, I&#039;ll make heavy use of PHP&#039;s &amp;lt;code&amp;gt;require_once&amp;lt;/code&amp;gt; control structure. Why am I using &amp;lt;code&amp;gt;require(_once)&amp;lt;/code&amp;gt; instead of &amp;lt;code&amp;gt;include_once&amp;lt;/code&amp;gt;? Because if an error exists in a PHP file that you try to &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt;, only a warning will be thrown, but the script will continue in spite of the error. Using &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; if the included file has an error, the script dies when the inclusion takes places, throwing a fatal error (&amp;lt;code&amp;gt;E_COMPILE_ERROR&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
That way, I&#039;m sure the classes, traits or interfaces I&#039;m including are syntax error free.&lt;br /&gt;
&lt;br /&gt;
=== Game logic methods ===&lt;br /&gt;
The way the framework is implemented, your game logic is gathered inside a class (&amp;lt;code&amp;gt;YourProjectName&amp;lt;/code&amp;gt;) extending the [[Table|&amp;lt;code&amp;gt;Table&amp;lt;/code&amp;gt; class]]. You define your methods there so that they may be called from other parts of the framework (as long as they&#039;re public methods obviously).&lt;br /&gt;
&lt;br /&gt;
But you can take advantage of [https://www.php.net/manual/en/language.oop5.traits.php PHP Traits]. In a nutshell, Traits are a collection of methods that can be reused in different classes, to avoid code duplication. Here we&#039;re not going to reuse them anywhere else than in the game class, but this little trick allows us to put methods definitions in other files, and in so doing to avoid monolithic code.&lt;br /&gt;
&lt;br /&gt;
Basically you create a Trait in th &amp;lt;code&amp;gt;/modules/&amp;lt;/code&amp;gt; directory, for instance:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/UtiltityFunctionsTrait.php]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;lt;?php&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;namespace YourProjectNamespace\Modules;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;trait UtilityFunctionsTrait {&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &#039;&#039;&#039;public function myFirstUtilityFunction($args)&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;{&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//Your code here&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;}&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Then you can include it in you project&#039;s &amp;lt;code&amp;gt;X.game.php&amp;lt;/code&amp;gt; file like so:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X_game.php]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;?php&lt;br /&gt;
  /**&lt;br /&gt;
   *------&lt;br /&gt;
   * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
   * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
   * &lt;br /&gt;
   * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
   * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
   * -----&lt;br /&gt;
   * &lt;br /&gt;
   * X.game.php&lt;br /&gt;
   *&lt;br /&gt;
   * This is the main file for your game logic.&lt;br /&gt;
   *&lt;br /&gt;
   * In this PHP file, you are going to defines the rules of the game.&lt;br /&gt;
   *&lt;br /&gt;
   */&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;require_once &#039;modules/UtilityFunctionsTrait.php&#039;; &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;   //Here we require the trait to be loaded when the class is loaded&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;use X\Modules\UtilityFunctionsTrait;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;                 //We import the trait to be used directly as UtilityFunctionsTraits,&#039;&#039;&#039;&lt;br /&gt;
                                                      &#039;&#039;&#039;//otherwise we would have to use the Fully qualified class name&#039;&#039;&#039;&lt;br /&gt;
                                                      &#039;&#039;&#039;//(YourProjectNamespace\Modules\UtilityFunctionsTrait)&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 class X extends Table&lt;br /&gt;
 {&lt;br /&gt;
 //...&lt;br /&gt;
 &lt;br /&gt;
 //////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
 //////////// Utility functions&lt;br /&gt;
 ////////////    &lt;br /&gt;
 &lt;br /&gt;
     /*&lt;br /&gt;
         In this space, you can put any utility methods useful for your game logic&lt;br /&gt;
     */&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;use UtilityFunctionsTrait;&#039;&#039;&#039;&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//Here we actually include the trait inside the class, making all the trait&#039;s methods&#039;&#039;&#039; &lt;br /&gt;
                                &#039;&#039;&#039;//available as class methods, keeping their visibility scope (so a private method&#039;&#039;&#039;&lt;br /&gt;
                                &#039;&#039;&#039;//is still private)&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Support classes ===&lt;br /&gt;
Basically, the same as traits, you put your classes definitions into files that live under the &amp;lt;code&amp;gt;/modules/&amp;lt;/code&amp;gt; directory (don&#039;t forget to namespace your classes), and then require them at the top of &amp;lt;code&amp;gt;X_game.php&amp;lt;/code&amp;gt;, and voilà, you&#039;re done&lt;br /&gt;
&lt;br /&gt;
=== Adding autoloader support ===&lt;br /&gt;
&lt;br /&gt;
==== Coding standards ====&lt;br /&gt;
Even for simple games, you might end up having a dozen of traits and support classes. You can require them all in your &amp;lt;code&amp;gt;X_game.php&amp;lt;/code&amp;gt;. Or you can use an autoloader, which will load the necessary classes and traits at runtime. There are two PSRs dealing with autloading standards (namely [https://www.php-fig.org/psr/psr-0 PSR-0] which is marked as deprecated and [https://www.php-fig.org/psr/psr-4 PSR-4]) which state that your namespaces should be a reflection of the directory structure of your project.&lt;br /&gt;
&lt;br /&gt;
Basically, when creating namespaces, you choose a namespace prefix. For example, you could use your BGA handle and the project name as a namespace prefix (would result in &amp;lt;code&amp;gt;\SwHawk\X&amp;lt;/code&amp;gt; in my case), and then the rest of the namespace would be the directory the file is in. I usually group classes and traits by the function they have in my project, so my &amp;lt;code&amp;gt;/modules/&amp;lt;/code&amp;gt; directory looks like that:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
modules/&lt;br /&gt;
    php/&lt;br /&gt;
        Factory/                      //Holds my factory classes&lt;br /&gt;
            AFactoryClass.php         //The namespace for this file would be \SwHawk\X\Factory, and the fully qualified class name would be \SwHawk\X\Factory\AFactoryClass&lt;br /&gt;
            ...&lt;br /&gt;
        Object/                       //Holds my support classes&lt;br /&gt;
            ObjectA.php               //The namespace for this file would be \SwHawk\X\Object, and the fully qualified class name would be \SwHawk\X\Object\ObjectA&lt;br /&gt;
            ...&lt;br /&gt;
        Traits/                       //Holds my traits&lt;br /&gt;
            UtilityFunctionsTrait.php //The namespace for this file would be \SwHawk\X\Traits, and the fully qualified class name would be \SwHawk\X\Traits\UtilityFunctionsTrait&lt;br /&gt;
            ...&lt;br /&gt;
        ...&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Autoloader function for development ====&lt;br /&gt;
While your project is under development, you usually create, move and remove classes as part of the development process. So you usually need an autoloading function that can handle a lot of flexibility. Basically once you import a class using the &amp;lt;code&amp;gt;use&amp;lt;/code&amp;gt; keyword, the autoloading function will determine which file to &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; using its fully qualified class name, and then &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt;. This function needs to be either defined or included at the top of &amp;lt;code&amp;gt;X_game.php&amp;lt;/code&amp;gt;. Such a function would have the following code (borrowed and adapted from [https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader-examples.md this repository]):&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;spl_autoload_register(function ($class) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// project-specific namespace prefix&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;, adapt to your needs&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;, remember that you must escape \ characters in double-quoted strings (hence the \\)&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$prefix = &#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;SwHawk\\X\\&amp;quot;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// base directory for the namespace prefix, this file would usually reside in the modules/php/includes/ directory, so the base directory for all my classes would be a level higher&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$base_dir = __DIR__ . &#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;&#039;&#039;&#039; &#039;/../&#039; &#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;gt;&#039;&#039;&#039;;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// does the class use the namespace prefix?&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$len = strlen($prefix);&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;if (strncmp($prefix, $class, $len) !== 0) {&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// no, move to the next registered autoloader&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;return;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// get the relative class name&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$relative_class = substr($class, $len);&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;// replace the namespace prefix with the base directory, replace namespace&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;// separators with directory separators in the relative class name, append&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;// with .php&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$file = $base_dir . str_replace(&#039;\\&#039;, &#039;/&#039;, $relative_class) . &#039;.php&#039;;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// if the file exists, require it&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;if (file_exists($file)) {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;require $file;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Autoloader function for production ====&lt;br /&gt;
Once you&#039;re moving your game to production, the autoloader function provided before isn&#039;t optimized. Once in production, the directory tree should not be modified, so you can change the earlier autoloader to a classmap based one. Basically, you build an associative array with the fully qualified classes names as keys and the filepath as the value. An example would look like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;spl_autoload_register(function ($class) {&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;static $classmap = array(&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:red&amp;gt;&amp;quot;SwHawk\\X\\&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;Factory\\AFactoryClass&amp;quot; =&amp;gt; __DIR__ . &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;&amp;quot;/../&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;Factory/AFactoryClass.php&amp;quot;,&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;);&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;if(array_key_exists($class)) {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;require $classmap[$class];&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;} else {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;return;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This autoloader is better suited to production since it won&#039;t use expensive calls like &amp;lt;code&amp;gt;file_exists($filename)&amp;lt;/code&amp;gt;. You can write the classmap by yourself, but it can be quite cumbersome, there is some tools like [https://github.com/hanneskod/classtools this project], or [https://github.com/gnugat/nomo-spaco this one], or even scripts detailed in this [https://stackoverflow.com/questions/22761554/how-to-get-all-class-names-inside-a-particular-namespace StackOverflow topic]&lt;br /&gt;
&lt;br /&gt;
== On the JS side ==&lt;br /&gt;
&lt;br /&gt;
BGA uses the dojo toolkit framework for most of its javascript code. Dojo comes with its own way of loading modules, which you can read about in more detail [https://dojotoolkit.org/documentation/tutorials/1.10/modules/ here] and [https://dojotoolkit.org/documentation/tutorials/1.10/modules_advanced/ here]. To put it simply, there are two ways you can go about this&lt;br /&gt;
&lt;br /&gt;
=== Write plain javascript ===&lt;br /&gt;
&lt;br /&gt;
==== Relying on the dojo toolkit ====&lt;br /&gt;
Should you wan to write plain javascript, you can easily do so. What you need to do is actually load the file like so in &amp;lt;code&amp;gt;X.js&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&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;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&amp;quot;./modules/path/to/firstfile.js&amp;quot;,&amp;lt;/span&amp;gt;        &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;//The first file with your JS code&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&amp;quot;./modules/path/to/secondfile.js&amp;quot;,&amp;lt;/span&amp;gt;       &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;//The second file with another part of your JS code&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
     ...&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
         constructor: function(){&lt;br /&gt;
             ...&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
According to the dojo toolkit documentation, you will then need to directly access what you defined in the files.&lt;br /&gt;
&lt;br /&gt;
==== Alternative method ====&lt;br /&gt;
&lt;br /&gt;
This section has mostly been written by [[User:Mogri|Mogri]].&lt;br /&gt;
&lt;br /&gt;
This approach lets you avoid Dojo and &amp;lt;tt&amp;gt;this&amp;lt;/tt&amp;gt; and allows more modern JS.&lt;br /&gt;
&lt;br /&gt;
First, you&#039;ll need to a a statement at the beginning of the &amp;lt;code&amp;gt;X.js&amp;lt;/code&amp;gt; file:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
 *------&lt;br /&gt;
 * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
 * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
 *&lt;br /&gt;
 * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
 * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
 * -----&lt;br /&gt;
 *&lt;br /&gt;
 * X.js&lt;br /&gt;
 *&lt;br /&gt;
 * X user interface script&lt;br /&gt;
 * &lt;br /&gt;
 * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&gt;
 &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;window.X = {};&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// X = your game, or you can use something more generic&amp;lt;/span&amp;gt;&#039;&#039;&#039;&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;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/whatever.js&amp;quot;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
         constructor: function(){&lt;br /&gt;
             console.log(&#039;X constructor&#039;);&lt;br /&gt;
               &lt;br /&gt;
             // Here, you can init the global variables of your user interface&lt;br /&gt;
             // Example:&lt;br /&gt;
             // this.myGlobalValue = 0;&lt;br /&gt;
 &lt;br /&gt;
         },&lt;br /&gt;
         &lt;br /&gt;
         /*&lt;br /&gt;
             setup:&lt;br /&gt;
             &lt;br /&gt;
             This method must set up the game user interface according to current game situation specified&lt;br /&gt;
             in parameters.&lt;br /&gt;
             &lt;br /&gt;
             The method is called each time the game interface is displayed to a player, ie:&lt;br /&gt;
             _ when the game starts&lt;br /&gt;
             _ when a player refreshes the game page (F5)&lt;br /&gt;
             &lt;br /&gt;
             &amp;quot;gamedatas&amp;quot; argument contains all datas retrieved by your &amp;quot;getAllDatas&amp;quot; PHP method.&lt;br /&gt;
         */&lt;br /&gt;
        &lt;br /&gt;
         setup: function( gamedatas )&lt;br /&gt;
         {&lt;br /&gt;
             &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;X = Object.assign(this, X);&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// This will allow you to use X.method instead of this.method inside modules/whatever.js&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// the rest of your setup goes here&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
         },&lt;br /&gt;
     });&lt;br /&gt;
 });&lt;br /&gt;
&lt;br /&gt;
And then, in your &amp;lt;code&amp;gt;modules/whatever.js&amp;lt;/code&amp;gt; file:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/whatever.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;X = Object.assign(X, {&#039;&#039;&#039;&lt;br /&gt;
   &#039;&#039;&#039;MY_CONSTANT: 1,&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
   &#039;&#039;&#039;myFunction: (arg1, arg2) =&amp;gt; {&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;X.someFunction(X.MY_CONSTANT);&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;return arg1 + arg2;&#039;&#039;&#039;&lt;br /&gt;
   &#039;&#039;&#039;},&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
   &#039;&#039;&#039;someFunction: (x) =&amp;gt; _(&#039;The answer is: &#039;) + x,&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notes on this approach:&lt;br /&gt;
*Aside from setup and any framework-override functions, you can use arrow functions&lt;br /&gt;
*Always use X instead of &amp;lt;tt&amp;gt;this&amp;lt;/tt&amp;gt;&lt;br /&gt;
*As usual, you can use any number of modules this way&lt;br /&gt;
&lt;br /&gt;
=== Write an AMD module ===&lt;br /&gt;
You can take advantage of the toolkit&#039;s module system to declare dependencies between the differents files you&#039;ll be writing (modules in the toolkit&#039;s language). To be identified as modules, your Javascript files will need to have the following structure:&lt;br /&gt;
&lt;br /&gt;
==== Create a named new class ====&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/js/FirstModule.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;gt;&#039;&#039;&#039;define([&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo&amp;quot;,&amp;lt;/span&amp;gt;      &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Needed if you want to be able to use dojo methods such as dojo.place, etc.&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo/_base/declare&amp;quot;,&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;other dependencies...&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;],function(dojo, declare){&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;return declare(&amp;quot;className&amp;quot;,&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/*Parent classes that this class inherits, optional*/&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, {&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;&#039;&#039;&#039;/* static properties */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;let property1 = &amp;quot;value;&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;let property2 = 5;&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;constructor: function (args) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;&#039;&#039;&#039;/* instance properties */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;let property3 = 8;&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;let property4 = [ &amp;quot;arrayValue&amp;quot;, &amp;quot;arrayValue2&amp;quot; ]; &#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;method1: function (args) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;/* your code here */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
         &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;});&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then in the X.js file, you can use your newly created module like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&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;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/js/Firstmodule&amp;quot;,&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
     ...&lt;br /&gt;
     });&lt;br /&gt;
 });&lt;br /&gt;
&lt;br /&gt;
In your code, you can access your module&#039;s class and methods by doing so:&lt;br /&gt;
&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;let object = new className();&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;object.method1();&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;...&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This can lead to namespace collisions if you don&#039;t choose a namespace correctly, so you might want to take the same approach as described earlier for the PHP files for using a namespace.&lt;br /&gt;
&lt;br /&gt;
==== Create an anonymous class ====&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/js/SecondModule.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;gt;&#039;&#039;&#039;define([&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo&amp;quot;,&amp;lt;/span&amp;gt;      &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Needed if you want to be able to use dojo methods such as dojo.place, etc.&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo/_base/declare&amp;quot;,&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;other dependencies...&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;],function(dojo, declare){&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;return declare(null,&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/*Parent classes that this class inherits, optional*/&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, {&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;&#039;&#039;&#039;/* static properties */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;let property1 = &amp;quot;value;&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;let property2 = 5;&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;constructor: function (args) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;&#039;&#039;&#039;/* instance properties */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;let property3 = 8;&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;let property4 = [ &amp;quot;arrayValue&amp;quot;, &amp;quot;arrayValue2&amp;quot; ]; &#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;method1: function (args) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;/* your code here */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
         &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;});&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then in the X.js file, you can use your newly created module like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&gt;
 &lt;br /&gt;
 define([&lt;br /&gt;
     &amp;quot;dojo&amp;quot;,&amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/js/SecondModule&amp;quot;,&#039;&#039;&#039;&amp;lt;/span&amp;gt;      &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//Has to be inserted in the third position as we&#039;ll&#039;&#039;&#039;&lt;br /&gt;
                                       &#039;&#039;&#039;//need an identifier later, and the other modules don&#039;t need it, see code in the preceding subsection.&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
     &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
 &lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, SecondModule&amp;lt;/span&amp;gt;  &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/* insert a reference here that you&#039;ll use throughout the JS file for this module */&amp;lt;/span&amp;gt;&#039;&#039;&#039;) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
     ...&lt;br /&gt;
     });&lt;br /&gt;
 });&lt;br /&gt;
&lt;br /&gt;
In your code, you can access your module&#039;s class and methods by doing so:&lt;br /&gt;
&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;let someValue = SecondModule.property3&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;SecondModule.method1();&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;...&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This can lead to namespace collisions if you don&#039;t choose a namespace correctly, so you might want to take the same approach as described earlier for the PHP files for using a namespace.&lt;br /&gt;
&lt;br /&gt;
==== Create a singleton object ====&lt;br /&gt;
&lt;br /&gt;
You can also create singleton objects by creating a module this way:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/js/singletonObject.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;define([&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo&amp;quot;,&amp;lt;/span&amp;gt;      &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Needed if you want to be able to use dojo methods such as dojo.place, etc.&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;], function (dojo) {&#039;&#039;&#039;&lt;br /&gt;
     &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;// Methods and variables defined in this part will not be available anywhere else than in this file&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;let privateVariable = &amp;quot;someValue&amp;quot;;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;let privateFunction = function (args) {&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//some code here&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;return {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;firstMethod: function (args) {&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;privateFunction(args);&#039;&#039;&#039;&lt;br /&gt;
             &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//some other code here&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;};&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To be used in the &amp;lt;code&amp;gt;X.js&amp;lt;/code&amp;gt; file, you must use the same method as in the [[#Create an anonymous class|previous section]]:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&gt;
 &lt;br /&gt;
 define([&lt;br /&gt;
     &amp;quot;dojo&amp;quot;,&amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&amp;quot;./modules/js/SecondModule&amp;quot;,&amp;lt;/span&amp;gt;         &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Has to be inserted in the third position as we&#039;ll need an identifier later, and the other modules don&#039;t need it&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&amp;quot;./modules/js/sigletonObject&amp;quot;,&amp;lt;/span&amp;gt;          &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//see code in the preceding subsection.&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
     &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/js/Firstmodule&amp;quot;,&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, SecondModule&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/* insert a reference here that you&#039;ll use throughout the JS file for this module */&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, singletonObject&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/* same here */&amp;lt;/span&amp;gt;&#039;&#039;&#039;) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
     ...&lt;br /&gt;
     });&lt;br /&gt;
 });&lt;br /&gt;
&lt;br /&gt;
Then you can access your code the same way as described in the [[#Create an anonymous class|previous section]]:&lt;br /&gt;
&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;singletonObject.firstMethod();&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;...&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Putting it all together ==&lt;br /&gt;
As you might have gathered reading this, much of your work will rely on the directory structure your project will follow.&lt;br /&gt;
&lt;br /&gt;
=== Recommended directory structure ===&lt;br /&gt;
&lt;br /&gt;
This is a recommendation, and in no way are you forced to follow it, but then you may have to adapt some of the code snippets shown below. All filenames should be self-explanatory, although there might be comments for some files.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
X/&lt;br /&gt;
  img/&lt;br /&gt;
    ...&lt;br /&gt;
  misc/&lt;br /&gt;
    ...&lt;br /&gt;
  modules/&lt;br /&gt;
    js/&lt;br /&gt;
      utility/&lt;br /&gt;
        FirstUtilityModule.js (defines a [[#Create a singleton object|singleton object]])&lt;br /&gt;
        SecondUtilityModule.js (defines an [[#Create an anonymous class|anonymous class]])&lt;br /&gt;
      notifications/&lt;br /&gt;
        FirstNotificationModule.js (defines a [[#Create a new named class|class with a name]])&lt;br /&gt;
      actions/&lt;br /&gt;
        FirstActionModule.js (plain JS code)&lt;br /&gt;
    php/&lt;br /&gt;
      includes/&lt;br /&gt;
        PNAutoloader.php (contains your autoloader, PN stands for ProjectName, and should be a trigram if possible)&lt;br /&gt;
        Other files to be included into files of the project. For instance splits from material.inc.php.&lt;br /&gt;
      Object/&lt;br /&gt;
         ObjectA.php&lt;br /&gt;
         ObjectB.php&lt;br /&gt;
      Traits/&lt;br /&gt;
         PlayerActions/&lt;br /&gt;
           PlayerActionsFunctionsTrait.php&lt;br /&gt;
         States/&lt;br /&gt;
           Actions/&lt;br /&gt;
             StateActionsFunctionsTrait.php&lt;br /&gt;
           Arguments/&lt;br /&gt;
             StateArgumentFunctionsTrait.php&lt;br /&gt;
         Utility/&lt;br /&gt;
           FirstUtilityFunctionsTrait.php&lt;br /&gt;
           SecondUtilityFunctionsTrait.php&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This directory tree is quite detailed, you&#039;re free to make arrangements with it to suit your project&#039;s requirements.&lt;br /&gt;
&lt;br /&gt;
=== Choosing a namespace prefix ===&lt;br /&gt;
&lt;br /&gt;
==== PHP ====&lt;br /&gt;
As stated earlier, in order to avoid collisions when importing your PHP Classes and Traits, you should define a namespace prefix. We&#039;ll use &amp;lt;code&amp;gt;Username\ProjectName&amp;lt;/code&amp;gt; throughout the remainder of this article.&lt;br /&gt;
&lt;br /&gt;
==== JS ====&lt;br /&gt;
As we&#039;ll create a named class, we should also use a namespace prefix for the JS module. We&#039;ll use &amp;lt;code&amp;gt;username.projectname&amp;lt;/code&amp;gt; throughout the remainder of this article&lt;br /&gt;
&lt;br /&gt;
=== Write the autoloader and include it in the game logic ===&lt;br /&gt;
Even though you may have a lot less PHP classes than stated here, you should really write an autoloader function, and since it&#039;s recommended for the production environment, you should proceed to write a [[#Autoloader function for production|classmap autoloader]] when your classes are pretty much stabilised.&lt;br /&gt;
&lt;br /&gt;
Then you need to include it in your X_game.php like so:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X_game.php]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;?php&lt;br /&gt;
  /**&lt;br /&gt;
   *------&lt;br /&gt;
   * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
   * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
   * &lt;br /&gt;
   * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
   * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
   * -----&lt;br /&gt;
   * &lt;br /&gt;
   * X.game.php&lt;br /&gt;
   *&lt;br /&gt;
   * This is the main file for your game logic.&lt;br /&gt;
   *&lt;br /&gt;
   * In this PHP file, you are going to defines the rules of the game.&lt;br /&gt;
   *&lt;br /&gt;
   */&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;require_once &#039;modules/php/includes/PNAutoloader.php&#039;;&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Here you&#039;ll write the use statements to import your classes and traits using the autoloader&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 class X extends Table&lt;br /&gt;
 {&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Here you can write the use statements to import your traits into the class, or put them in the relevant sections of the file&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Write your Javascript modules and include them ===&lt;br /&gt;
On the JS side of the code, you have multiple alternatives to choose from (see the [[#On the JS side|JS section]]), but all will require you to modify the &amp;lt;code&amp;gt;define&amp;lt;/code&amp;gt; statement at the beginning of the &amp;lt;code&amp;gt;X.js&amp;lt;/code&amp;gt; file. According to the directory structure shown above, the file would look like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&gt;
 &lt;br /&gt;
 define([&lt;br /&gt;
     &amp;quot;dojo&amp;quot;,&amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/js/utility/FirstUtilityModule&amp;quot;,&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;./modules/js/utility/SecondUtilityModule&amp;quot;,&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
     &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/js/actions/FirstActionModule.js&amp;quot;,&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;./modules/js/notifications/FirstNotificationModule&amp;quot;,&amp;lt;/span&amp;gt;&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare, &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;FirstUtilityModule, SecondUtilityModule&amp;lt;/span&amp;gt;&#039;&#039;&#039;) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
         constructor: function(){&lt;br /&gt;
            console.log(&#039;X constructor&#039;);&lt;br /&gt;
              &lt;br /&gt;
            // Here, you can init the global variables of your user interface&lt;br /&gt;
            // Example:&lt;br /&gt;
            // this.myGlobalValue = 0;&lt;br /&gt;
            &lt;br /&gt;
        },&lt;br /&gt;
        &lt;br /&gt;
        /*&lt;br /&gt;
            setup:&lt;br /&gt;
            &lt;br /&gt;
            This method must set up the game user interface according to current game situation specified&lt;br /&gt;
            in parameters.&lt;br /&gt;
            &lt;br /&gt;
            The method is called each time the game interface is displayed to a player, ie:&lt;br /&gt;
            _ when the game starts&lt;br /&gt;
            _ when a player refreshes the game page (F5)&lt;br /&gt;
            &lt;br /&gt;
            &amp;quot;gamedatas&amp;quot; argument contains all datas retrieved by your &amp;quot;getAllDatas&amp;quot; PHP method.&lt;br /&gt;
        */&lt;br /&gt;
        &lt;br /&gt;
        setup: function( gamedatas )&lt;br /&gt;
        {&lt;br /&gt;
            &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;FirstUtilityModule.myMethod();&#039;&#039;&#039;&lt;br /&gt;
            &#039;&#039;&#039;SecondUtilityModule.anotherMethod(gamedatas);&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
            &lt;br /&gt;
        },&lt;br /&gt;
        ...&lt;br /&gt;
        ///////////////////////////////////////////////////&lt;br /&gt;
        //// Reaction to cometD notifications&lt;br /&gt;
 &lt;br /&gt;
        /*&lt;br /&gt;
            setupNotifications:&lt;br /&gt;
            &lt;br /&gt;
            In this method, you associate each of your game notifications with your local method to handle it.&lt;br /&gt;
            &lt;br /&gt;
            Note: game notification names correspond to &amp;quot;notifyAllPlayers&amp;quot; and &amp;quot;notifyPlayer&amp;quot; calls in&lt;br /&gt;
                  your progressevolutiontechnologyswh.game.php file.&lt;br /&gt;
        &lt;br /&gt;
        */&lt;br /&gt;
        setupNotifications: function()&lt;br /&gt;
        {&lt;br /&gt;
            console.log( &#039;notifications subscriptions setup&#039; );&lt;br /&gt;
            &lt;br /&gt;
            // TODO: here, associate your game notifications with local methods&lt;br /&gt;
            &lt;br /&gt;
            // Example 1: standard notification handling&lt;br /&gt;
            // dojo.subscribe( &#039;cardPlayed&#039;, this, &amp;quot;notif_cardPlayed&amp;quot; );&lt;br /&gt;
            &lt;br /&gt;
            // Example 2: standard notification handling + tell the user interface to wait&lt;br /&gt;
            //            during 3 seconds after calling the method in order to let the players&lt;br /&gt;
            //            see what is happening in the game.&lt;br /&gt;
            // dojo.subscribe( &#039;cardPlayed&#039;, this, &amp;quot;notif_cardPlayed&amp;quot; );&lt;br /&gt;
            // this.notifqueue.setSynchronous( &#039;cardPlayed&#039;, 3000 );&lt;br /&gt;
            //&lt;br /&gt;
            // TODO: check module integration with dojo.subscribe&lt;br /&gt;
        },&lt;br /&gt;
     });&lt;br /&gt;
 });&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== See it in a real project ===&lt;br /&gt;
This method has been partially or totally applied on the following projects:&lt;br /&gt;
* [https://gitlab.swhawk.eu/silver/progressevolutiontechnologybga Progress: Evolution of Technology] by [[User:SwHawk|SwHawk]]&lt;br /&gt;
&lt;br /&gt;
If you have successfully applied this method in your project, feel free to add you project to the list by editing this section&lt;/div&gt;</summary>
		<author><name>SwHawk</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=User:SwHawk/Create_Modular_Code&amp;diff=13602</id>
		<title>User:SwHawk/Create Modular Code</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=User:SwHawk/Create_Modular_Code&amp;diff=13602"/>
		<updated>2022-06-14T20:47:24Z</updated>

		<summary type="html">&lt;p&gt;SwHawk: /* Write the autoloader and include it in the game logic */ Fixed include path&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{InfoBox|title=WIP|body=&#039;&#039;&#039;This article is a Work In Progress, please do not refer to it for production purposes&#039;&#039;&#039;}}&lt;br /&gt;
&lt;br /&gt;
This page will cover steps you can take as a BGA developer to make your code more modular and better organized. The way the framework is implemented makes the [[Main game logic: yourgamename.game.php|game logic]] and the [[Game interface logic: yourgamename.js|interface logic]] files very monolithic. While this is not a problem in itself, even simple to moderately complex game may require this files to be over 5k lines of code. Thus you can quickly become lost in all the functions you need to declare, where they are declared, and where they are called.&lt;br /&gt;
&lt;br /&gt;
But there are steps that you can follow to take advantage of PHP&#039;s Object Oriented Code and the dojo toolkit&#039;s AMD loader to organize your code in separate files. Let&#039;s see what&#039;s available:&lt;br /&gt;
&lt;br /&gt;
== Acknowledgements ==&lt;br /&gt;
&lt;br /&gt;
Writing this wiki article wouldn&#039;t have been possible without the help, work and insight of more experienced BGA developers:&lt;br /&gt;
* [https://boardgamearena.com/player?id=83846198 Tisaac]  (Discord user Tisaac Human Expert)&lt;br /&gt;
* [https://boardgamearena.com/player?id=85537631 bennygui] (Discord user bennygui)&lt;br /&gt;
* [https://boardgamearena.com/player?id=84125723 VictoriaLa] (Discord user VictoriaLa)&lt;br /&gt;
* Syarwin and [https://boardgamearena.com/player?id=84554161 quietmint] (for their Welcome To [https://github.com/Syarwin/bga-welcometo repository])&lt;br /&gt;
* [https://boardgamearena.com/player?id=84522426 Mogri] (Discord user Mogri)&lt;br /&gt;
&lt;br /&gt;
== Conventions ==&lt;br /&gt;
In the code blocks, code additions will be displayed in bold and green, and added comments will be displayed in bold and dark grey so that they stand out from the boilerplate code from a scratch project. Part in red should be aapted to reflect your project&#039;s structure.&lt;br /&gt;
&lt;br /&gt;
== On the PHP side ==&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt; vs &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; ===&lt;br /&gt;
Throughout this section, I&#039;ll make heavy use of PHP&#039;s &amp;lt;code&amp;gt;require_once&amp;lt;/code&amp;gt; control structure. Why am I using &amp;lt;code&amp;gt;require(_once)&amp;lt;/code&amp;gt; instead of &amp;lt;code&amp;gt;include_once&amp;lt;/code&amp;gt;? Because if an error exists in a PHP file that you try to &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt;, only a warning will be thrown, but the script will continue in spite of the error. Using &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; if the included file has an error, the script dies when the inclusion takes places, throwing a fatal error (&amp;lt;code&amp;gt;E_COMPILE_ERROR&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
That way, I&#039;m sure the classes, traits or interfaces I&#039;m including are syntax error free.&lt;br /&gt;
&lt;br /&gt;
=== Game logic methods ===&lt;br /&gt;
The way the framework is implemented, your game logic is gathered inside a class (&amp;lt;code&amp;gt;YourProjectName&amp;lt;/code&amp;gt;) extending the [[Table|&amp;lt;code&amp;gt;Table&amp;lt;/code&amp;gt; class]]. You define your methods there so that they may be called from other parts of the framework (as long as they&#039;re public methods obviously).&lt;br /&gt;
&lt;br /&gt;
But you can take advantage of [https://www.php.net/manual/en/language.oop5.traits.php PHP Traits]. In a nutshell, Traits are a collection of methods that can be reused in different classes, to avoid code duplication. Here we&#039;re not going to reuse them anywhere else than in the game class, but this little trick allows us to put methods definitions in other files, and in so doing to avoid monolithic code.&lt;br /&gt;
&lt;br /&gt;
Basically you create a Trait in th &amp;lt;code&amp;gt;/modules/&amp;lt;/code&amp;gt; directory, for instance:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/UtiltityFunctionsTrait.php]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;lt;?php&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;namespace YourProjectNamespace\Modules;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;trait UtilityFunctionsTrait {&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &#039;&#039;&#039;public function myFirstUtilityFunction($args)&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;{&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//Your code here&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;}&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Then you can include it in you project&#039;s &amp;lt;code&amp;gt;X.game.php&amp;lt;/code&amp;gt; file like so:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X_game.php]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;?php&lt;br /&gt;
  /**&lt;br /&gt;
   *------&lt;br /&gt;
   * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
   * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
   * &lt;br /&gt;
   * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
   * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
   * -----&lt;br /&gt;
   * &lt;br /&gt;
   * X.game.php&lt;br /&gt;
   *&lt;br /&gt;
   * This is the main file for your game logic.&lt;br /&gt;
   *&lt;br /&gt;
   * In this PHP file, you are going to defines the rules of the game.&lt;br /&gt;
   *&lt;br /&gt;
   */&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;require_once &#039;modules/UtilityFunctionsTrait.php&#039;; &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;   //Here we require the trait to be loaded when the class is loaded&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;use X\Modules\UtilityFunctionsTrait;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;                 //We import the trait to be used directly as UtilityFunctionsTraits,&#039;&#039;&#039;&lt;br /&gt;
                                                      &#039;&#039;&#039;//otherwise we would have to use the Fully qualified class name&#039;&#039;&#039;&lt;br /&gt;
                                                      &#039;&#039;&#039;//(YourProjectNamespace\Modules\UtilityFunctionsTrait)&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 class X extends Table&lt;br /&gt;
 {&lt;br /&gt;
 //...&lt;br /&gt;
 &lt;br /&gt;
 //////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
 //////////// Utility functions&lt;br /&gt;
 ////////////    &lt;br /&gt;
 &lt;br /&gt;
     /*&lt;br /&gt;
         In this space, you can put any utility methods useful for your game logic&lt;br /&gt;
     */&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;use UtilityFunctionsTrait;&#039;&#039;&#039;&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//Here we actually include the trait inside the class, making all the trait&#039;s methods&#039;&#039;&#039; &lt;br /&gt;
                                &#039;&#039;&#039;//available as class methods, keeping their visibility scope (so a private method&#039;&#039;&#039;&lt;br /&gt;
                                &#039;&#039;&#039;//is still private)&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Support classes ===&lt;br /&gt;
Basically, the same as traits, you put your classes definitions into files that live under the &amp;lt;code&amp;gt;/modules/&amp;lt;/code&amp;gt; directory (don&#039;t forget to namespace your classes), and then require them at the top of &amp;lt;code&amp;gt;X_game.php&amp;lt;/code&amp;gt;, and voilà, you&#039;re done&lt;br /&gt;
&lt;br /&gt;
=== Adding autoloader support ===&lt;br /&gt;
&lt;br /&gt;
==== Coding standards ====&lt;br /&gt;
Even for simple games, you might end up having a dozen of traits and support classes. You can require them all in your &amp;lt;code&amp;gt;X_game.php&amp;lt;/code&amp;gt;. Or you can use an autoloader, which will load the necessary classes and traits at runtime. There are two PSRs dealing with autloading standards (namely [https://www.php-fig.org/psr/psr-0 PSR-0] which is marked as deprecated and [https://www.php-fig.org/psr/psr-4 PSR-4]) which state that your namespaces should be a reflection of the directory structure of your project.&lt;br /&gt;
&lt;br /&gt;
Basically, when creating namespaces, you choose a namespace prefix. For example, you could use your BGA handle and the project name as a namespace prefix (would result in &amp;lt;code&amp;gt;\SwHawk\X&amp;lt;/code&amp;gt; in my case), and then the rest of the namespace would be the directory the file is in. I usually group classes and traits by the function they have in my project, so my &amp;lt;code&amp;gt;/modules/&amp;lt;/code&amp;gt; directory looks like that:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
modules/&lt;br /&gt;
    php/&lt;br /&gt;
        Factory/                      //Holds my factory classes&lt;br /&gt;
            AFactoryClass.php         //The namespace for this file would be \SwHawk\X\Factory, and the fully qualified class name would be \SwHawk\X\Factory\AFactoryClass&lt;br /&gt;
            ...&lt;br /&gt;
        Object/                       //Holds my support classes&lt;br /&gt;
            ObjectA.php               //The namespace for this file would be \SwHawk\X\Object, and the fully qualified class name would be \SwHawk\X\Object\ObjectA&lt;br /&gt;
            ...&lt;br /&gt;
        Traits/                       //Holds my traits&lt;br /&gt;
            UtilityFunctionsTrait.php //The namespace for this file would be \SwHawk\X\Traits, and the fully qualified class name would be \SwHawk\X\Traits\UtilityFunctionsTrait&lt;br /&gt;
            ...&lt;br /&gt;
        ...&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Autoloader function for development ====&lt;br /&gt;
While your project is under development, you usually create, move and remove classes as part of the development process. So you usually need an autoloading function that can handle a lot of flexibility. Basically once you import a class using the &amp;lt;code&amp;gt;use&amp;lt;/code&amp;gt; keyword, the autoloading function will determine which file to &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; using its fully qualified class name, and then &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt;. This function needs to be either defined or included at the top of &amp;lt;code&amp;gt;X_game.php&amp;lt;/code&amp;gt;. Such a function would have the following code (borrowed and adapted from [https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader-examples.md this repository]):&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;spl_autoload_register(function ($class) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// project-specific namespace prefix&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;, adapt to your needs&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;, remember that you must escape \ characters in double-quoted strings (hence the \\)&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$prefix = &#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;SwHawk\\X\\&amp;quot;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// base directory for the namespace prefix, this file would usually reside in the modules/php/includes/ directory, so the base directory for all my classes would be a level higher&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$base_dir = __DIR__ . &#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;&#039;&#039;&#039; &#039;/../&#039; &#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;gt;&#039;&#039;&#039;;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// does the class use the namespace prefix?&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$len = strlen($prefix);&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;if (strncmp($prefix, $class, $len) !== 0) {&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// no, move to the next registered autoloader&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;return;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// get the relative class name&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$relative_class = substr($class, $len);&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;// replace the namespace prefix with the base directory, replace namespace&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;// separators with directory separators in the relative class name, append&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;// with .php&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$file = $base_dir . str_replace(&#039;\\&#039;, &#039;/&#039;, $relative_class) . &#039;.php&#039;;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// if the file exists, require it&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;if (file_exists($file)) {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;require $file;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Autoloader function for production ====&lt;br /&gt;
Once you&#039;re moving your game to production, the autoloader function provided before isn&#039;t optimized. Once in production, the directory tree should not be modified, so you can change the earlier autoloader to a classmap based one. Basically, you build an associative array with the fully qualified classes names as keys and the filepath as the value. An example would look like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;spl_autoload_register(function ($class) {&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;static $classmap = array(&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:red&amp;gt;&amp;quot;SwHawk\\X\\&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;Factory\\AFactoryClass&amp;quot; =&amp;gt; __DIR__ . &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;&amp;quot;/../&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;Factory/AFactoryClass.php&amp;quot;,&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;);&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;if(array_key_exists($class)) {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;require $classmap[$class];&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;} else {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;return;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This autoloader is better suited to production since it won&#039;t use expensive calls like &amp;lt;code&amp;gt;file_exists($filename)&amp;lt;/code&amp;gt;. You can write the classmap by yourself, but it can be quite cumbersome, there is some tools like [https://github.com/hanneskod/classtools this project], or [https://github.com/gnugat/nomo-spaco this one], or even scripts detailed in this [https://stackoverflow.com/questions/22761554/how-to-get-all-class-names-inside-a-particular-namespace StackOverflow topic]&lt;br /&gt;
&lt;br /&gt;
== On the JS side ==&lt;br /&gt;
&lt;br /&gt;
BGA uses the dojo toolkit framework for most of its javascript code. Dojo comes with its own way of loading modules, which you can read about in more detail [https://dojotoolkit.org/documentation/tutorials/1.10/modules/ here] and [https://dojotoolkit.org/documentation/tutorials/1.10/modules_advanced/ here]. To put it simply, there are two ways you can go about this&lt;br /&gt;
&lt;br /&gt;
=== Write plain javascript ===&lt;br /&gt;
&lt;br /&gt;
==== Relying on the dojo toolkit ====&lt;br /&gt;
Should you wan to write plain javascript, you can easily do so. What you need to do is actually load the file like so in &amp;lt;code&amp;gt;X.js&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&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;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&amp;quot;./modules/path/to/firstfile.js&amp;quot;,&amp;lt;/span&amp;gt;        &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;//The first file with your JS code&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&amp;quot;./modules/path/to/secondfile.js&amp;quot;,&amp;lt;/span&amp;gt;       &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;//The second file with another part of your JS code&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
     ...&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
         constructor: function(){&lt;br /&gt;
             ...&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
According to the dojo toolkit documentation, you will then need to directly access what you defined in the files.&lt;br /&gt;
&lt;br /&gt;
==== Alternative method ====&lt;br /&gt;
&lt;br /&gt;
This section has mostly been written by [[User:Mogri|Mogri]].&lt;br /&gt;
&lt;br /&gt;
This approach lets you avoid Dojo and &amp;lt;tt&amp;gt;this&amp;lt;/tt&amp;gt; and allows more modern JS.&lt;br /&gt;
&lt;br /&gt;
First, you&#039;ll need to a a statement at the beginning of the &amp;lt;code&amp;gt;X.js&amp;lt;/code&amp;gt; file:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
 *------&lt;br /&gt;
 * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
 * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
 *&lt;br /&gt;
 * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
 * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
 * -----&lt;br /&gt;
 *&lt;br /&gt;
 * X.js&lt;br /&gt;
 *&lt;br /&gt;
 * X user interface script&lt;br /&gt;
 * &lt;br /&gt;
 * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&gt;
 &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;window.X = {};&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// X = your game, or you can use something more generic&amp;lt;/span&amp;gt;&#039;&#039;&#039;&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;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/whatever.js&amp;quot;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
         constructor: function(){&lt;br /&gt;
             console.log(&#039;X constructor&#039;);&lt;br /&gt;
               &lt;br /&gt;
             // Here, you can init the global variables of your user interface&lt;br /&gt;
             // Example:&lt;br /&gt;
             // this.myGlobalValue = 0;&lt;br /&gt;
 &lt;br /&gt;
         },&lt;br /&gt;
         &lt;br /&gt;
         /*&lt;br /&gt;
             setup:&lt;br /&gt;
             &lt;br /&gt;
             This method must set up the game user interface according to current game situation specified&lt;br /&gt;
             in parameters.&lt;br /&gt;
             &lt;br /&gt;
             The method is called each time the game interface is displayed to a player, ie:&lt;br /&gt;
             _ when the game starts&lt;br /&gt;
             _ when a player refreshes the game page (F5)&lt;br /&gt;
             &lt;br /&gt;
             &amp;quot;gamedatas&amp;quot; argument contains all datas retrieved by your &amp;quot;getAllDatas&amp;quot; PHP method.&lt;br /&gt;
         */&lt;br /&gt;
        &lt;br /&gt;
         setup: function( gamedatas )&lt;br /&gt;
         {&lt;br /&gt;
             &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;X = Object.assign(this, X);&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// This will allow you to use X.method instead of this.method inside modules/whatever.js&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// the rest of your setup goes here&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
         },&lt;br /&gt;
     });&lt;br /&gt;
 });&lt;br /&gt;
&lt;br /&gt;
And then, in your &amp;lt;code&amp;gt;modules/whatever.js&amp;lt;/code&amp;gt; file:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/whatever.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;X = Object.assign(X, {&#039;&#039;&#039;&lt;br /&gt;
   &#039;&#039;&#039;MY_CONSTANT: 1,&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
   &#039;&#039;&#039;myFunction: (arg1, arg2) =&amp;gt; {&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;X.someFunction(X.MY_CONSTANT);&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;return arg1 + arg2;&#039;&#039;&#039;&lt;br /&gt;
   &#039;&#039;&#039;},&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
   &#039;&#039;&#039;someFunction: (x) =&amp;gt; _(&#039;The answer is: &#039;) + x,&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;}&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notes on this approach:&lt;br /&gt;
*Aside from setup and any framework-override functions, you can use arrow functions&lt;br /&gt;
*Always use X instead of &amp;lt;tt&amp;gt;this&amp;lt;/tt&amp;gt;&lt;br /&gt;
*As usual, you can use any number of modules this way&lt;br /&gt;
&lt;br /&gt;
=== Write an AMD module ===&lt;br /&gt;
You can take advantage of the toolkit&#039;s module system to declare dependencies between the differents files you&#039;ll be writing (modules in the toolkit&#039;s language). To be identified as modules, your Javascript files will need to have the following structure:&lt;br /&gt;
&lt;br /&gt;
==== Create a named new class ====&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/js/FirstModule.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;gt;&#039;&#039;&#039;define([&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo&amp;quot;,&amp;lt;/span&amp;gt;      &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Needed if you want to be able to use dojo methods such as dojo.place, etc.&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo/_base/declare&amp;quot;,&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;other dependencies...&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;],function(dojo, declare){&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;return declare(&amp;quot;className&amp;quot;,&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/*Parent classes that this class inherits, optional*/&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, {&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;&#039;&#039;&#039;/* static properties */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;let property1 = &amp;quot;value;&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;let property2 = 5;&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;constructor: function (args) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;&#039;&#039;&#039;/* instance properties */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;let property3 = 8;&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;let property4 = [ &amp;quot;arrayValue&amp;quot;, &amp;quot;arrayValue2&amp;quot; ]; &#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;method1: function (args) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;/* your code here */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
         &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;});&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then in the X.js file, you can use your newly created module like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&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;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/js/Firstmodule&amp;quot;,&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
     ...&lt;br /&gt;
     });&lt;br /&gt;
 });&lt;br /&gt;
&lt;br /&gt;
In your code, you can access your module&#039;s class and methods by doing so:&lt;br /&gt;
&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;let object = new className();&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;object.method1();&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;...&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This can lead to namespace collisions if you don&#039;t choose a namespace correctly, so you might want to take the same approach as described earlier for the PHP files for using a namespace.&lt;br /&gt;
&lt;br /&gt;
==== Create an anonymous class ====&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/js/SecondModule.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;gt;&#039;&#039;&#039;define([&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo&amp;quot;,&amp;lt;/span&amp;gt;      &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Needed if you want to be able to use dojo methods such as dojo.place, etc.&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo/_base/declare&amp;quot;,&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;other dependencies...&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;],function(dojo, declare){&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;return declare(null,&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/*Parent classes that this class inherits, optional*/&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, {&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;&#039;&#039;&#039;/* static properties */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;let property1 = &amp;quot;value;&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;let property2 = 5;&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;constructor: function (args) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;&#039;&#039;&#039;/* instance properties */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;let property3 = 8;&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;let property4 = [ &amp;quot;arrayValue&amp;quot;, &amp;quot;arrayValue2&amp;quot; ]; &#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;method1: function (args) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;/* your code here */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
         &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;});&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then in the X.js file, you can use your newly created module like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&gt;
 &lt;br /&gt;
 define([&lt;br /&gt;
     &amp;quot;dojo&amp;quot;,&amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/js/SecondModule&amp;quot;,&#039;&#039;&#039;&amp;lt;/span&amp;gt;      &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//Has to be inserted in the third position as we&#039;ll&#039;&#039;&#039;&lt;br /&gt;
                                       &#039;&#039;&#039;//need an identifier later, and the other modules don&#039;t need it, see code in the preceding subsection.&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
     &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
 &lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, SecondModule&amp;lt;/span&amp;gt;  &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/* insert a reference here that you&#039;ll use throughout the JS file for this module */&amp;lt;/span&amp;gt;&#039;&#039;&#039;) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
     ...&lt;br /&gt;
     });&lt;br /&gt;
 });&lt;br /&gt;
&lt;br /&gt;
In your code, you can access your module&#039;s class and methods by doing so:&lt;br /&gt;
&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;let someValue = SecondModule.property3&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;SecondModule.method1();&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;...&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This can lead to namespace collisions if you don&#039;t choose a namespace correctly, so you might want to take the same approach as described earlier for the PHP files for using a namespace.&lt;br /&gt;
&lt;br /&gt;
==== Create a singleton object ====&lt;br /&gt;
&lt;br /&gt;
You can also create singleton objects by creating a module this way:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/js/singletonObject.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;define([&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo&amp;quot;,&amp;lt;/span&amp;gt;      &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Needed if you want to be able to use dojo methods such as dojo.place, etc.&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;], function (dojo) {&#039;&#039;&#039;&lt;br /&gt;
     &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;// Methods and variables defined in this part will not be available anywhere else than in this file&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;let privateVariable = &amp;quot;someValue&amp;quot;;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;let privateFunction = function (args) {&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//some code here&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;return {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;firstMethod: function (args) {&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;privateFunction(args);&#039;&#039;&#039;&lt;br /&gt;
             &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//some other code here&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;};&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To be used in the &amp;lt;code&amp;gt;X.js&amp;lt;/code&amp;gt; file, you must use the same method as in the [[#Create an anonymous class|previous section]]:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&gt;
 &lt;br /&gt;
 define([&lt;br /&gt;
     &amp;quot;dojo&amp;quot;,&amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&amp;quot;./modules/js/SecondModule&amp;quot;,&amp;lt;/span&amp;gt;         &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Has to be inserted in the third position as we&#039;ll need an identifier later, and the other modules don&#039;t need it&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&amp;quot;./modules/js/sigletonObject&amp;quot;,&amp;lt;/span&amp;gt;          &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//see code in the preceding subsection.&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
     &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/js/Firstmodule&amp;quot;,&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, SecondModule&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/* insert a reference here that you&#039;ll use throughout the JS file for this module */&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, singletonObject&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/* same here */&amp;lt;/span&amp;gt;&#039;&#039;&#039;) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
     ...&lt;br /&gt;
     });&lt;br /&gt;
 });&lt;br /&gt;
&lt;br /&gt;
Then you can access your code the same way as described in the [[#Create an anonymous class|previous section]]:&lt;br /&gt;
&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;singletonObject.firstMethod();&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;...&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Putting it all together ==&lt;br /&gt;
As you might have gathered reading this, much of your work will rely on the directory structure your project will follow.&lt;br /&gt;
&lt;br /&gt;
=== Recommended directory structure ===&lt;br /&gt;
&lt;br /&gt;
This is a recommendation, and in no way are you forced to follow it, but then you may have to adapt some of the code snippets shown below. All filenames should be self-explanatory, although there might be comments for some files.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
X/&lt;br /&gt;
  img/&lt;br /&gt;
    ...&lt;br /&gt;
  misc/&lt;br /&gt;
    ...&lt;br /&gt;
  modules/&lt;br /&gt;
    js/&lt;br /&gt;
      utility/&lt;br /&gt;
        FirstUtilityModule.js (defines a [[#Create a singleton object|singleton object]])&lt;br /&gt;
        SecondUtilityModule.js (defines an [[#Create an anonymous class|anonymous class]])&lt;br /&gt;
      notifications/&lt;br /&gt;
        FirstNotificationModule.js (defines a [[#Create a new named class|class with a name]])&lt;br /&gt;
      actions/&lt;br /&gt;
        FirstActionModule.js (plain JS code)&lt;br /&gt;
    php/&lt;br /&gt;
      includes/&lt;br /&gt;
        PNAutoloader.php (contains your autoloader, PN stands for ProjectName, and should be a trigram if possible)&lt;br /&gt;
        Other files to be included into files of the project. For instance splits from material.inc.php.&lt;br /&gt;
      Object/&lt;br /&gt;
         ObjectA.php&lt;br /&gt;
         ObjectB.php&lt;br /&gt;
      Traits/&lt;br /&gt;
         PlayerActions/&lt;br /&gt;
           PlayerActionsFunctionsTrait.php&lt;br /&gt;
         States/&lt;br /&gt;
           Actions/&lt;br /&gt;
             StateActionsFunctionsTrait.php&lt;br /&gt;
           Arguments/&lt;br /&gt;
             StateArgumentFunctionsTrait.php&lt;br /&gt;
         Utility/&lt;br /&gt;
           FirstUtilityFunctionsTrait.php&lt;br /&gt;
           SecondUtilityFunctionsTrait.php&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This directory tree is quite detailed, you&#039;re free to make arrangements with it to suit your project&#039;s requirements.&lt;br /&gt;
&lt;br /&gt;
=== Choosing a namespace prefix ===&lt;br /&gt;
&lt;br /&gt;
==== PHP ====&lt;br /&gt;
As stated earlier, in order to avoid collisions when importing your PHP Classes and Traits, you should define a namespace prefix. We&#039;ll use &amp;lt;code&amp;gt;Username\ProjectName&amp;lt;/code&amp;gt; throughout the remainder of this article.&lt;br /&gt;
&lt;br /&gt;
==== JS ====&lt;br /&gt;
As we&#039;ll create a named class, we should also use a namespace prefix for the JS module. We&#039;ll use &amp;lt;code&amp;gt;username.projectname&amp;lt;/code&amp;gt; throughout the remainder of this article&lt;br /&gt;
&lt;br /&gt;
=== Write the autoloader and include it in the game logic ===&lt;br /&gt;
Even though you may have a lot less PHP classes than stated here, you should really write an autoloader function, and since it&#039;s recommended for the production environment, you should proceed to write a [[#Autoloader function for production|classmap autoloader]] when your classes are pretty much stabilised.&lt;br /&gt;
&lt;br /&gt;
Then you need to include it in your X_game.php like so:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X_game.php]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;?php&lt;br /&gt;
  /**&lt;br /&gt;
   *------&lt;br /&gt;
   * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
   * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
   * &lt;br /&gt;
   * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
   * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
   * -----&lt;br /&gt;
   * &lt;br /&gt;
   * X.game.php&lt;br /&gt;
   *&lt;br /&gt;
   * This is the main file for your game logic.&lt;br /&gt;
   *&lt;br /&gt;
   * In this PHP file, you are going to defines the rules of the game.&lt;br /&gt;
   *&lt;br /&gt;
   */&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;require_once &#039;modules/php/includes/PNAutoloader.php&#039;;&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Here you&#039;ll write the use statements to import your classes and traits using the autoloader&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 class X extends Table&lt;br /&gt;
 {&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Here you can write the use statements to import your traits into the class, or put them in the relevant sections of the file&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Write your Javascript modules and include them ===&lt;br /&gt;
On the JS side of the code, you have multiple alternatives to choose from (see the [[#On the JS side|JS section]]), but all will require you to modify the &amp;lt;code&amp;gt;define&amp;lt;/code&amp;gt; statement at the beginning of the &amp;lt;code&amp;gt;X.js&amp;lt;/code&amp;gt; file. According to the directory structure shown above, the file would look like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&gt;
 &lt;br /&gt;
 define([&lt;br /&gt;
     &amp;quot;dojo&amp;quot;,&amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/js/utility/FirstUtilityModule&amp;quot;,&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;./modules/js/utility/SecondUtilityModule&amp;quot;,&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
     &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/js/actions/FirstActionModule.js&amp;quot;,&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;./modules/js/notifications/FirstNotificationModule&amp;quot;,&amp;lt;/span&amp;gt;&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare, &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;FirstUtilityModule, SecondUtilityModule&amp;lt;/span&amp;gt;&#039;&#039;&#039;) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
         constructor: function(){&lt;br /&gt;
            console.log(&#039;X constructor&#039;);&lt;br /&gt;
              &lt;br /&gt;
            // Here, you can init the global variables of your user interface&lt;br /&gt;
            // Example:&lt;br /&gt;
            // this.myGlobalValue = 0;&lt;br /&gt;
            &lt;br /&gt;
        },&lt;br /&gt;
        &lt;br /&gt;
        /*&lt;br /&gt;
            setup:&lt;br /&gt;
            &lt;br /&gt;
            This method must set up the game user interface according to current game situation specified&lt;br /&gt;
            in parameters.&lt;br /&gt;
            &lt;br /&gt;
            The method is called each time the game interface is displayed to a player, ie:&lt;br /&gt;
            _ when the game starts&lt;br /&gt;
            _ when a player refreshes the game page (F5)&lt;br /&gt;
            &lt;br /&gt;
            &amp;quot;gamedatas&amp;quot; argument contains all datas retrieved by your &amp;quot;getAllDatas&amp;quot; PHP method.&lt;br /&gt;
        */&lt;br /&gt;
        &lt;br /&gt;
        setup: function( gamedatas )&lt;br /&gt;
        {&lt;br /&gt;
            &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;FirstUtilityModule.myMethod();&#039;&#039;&#039;&lt;br /&gt;
            &#039;&#039;&#039;SecondUtilityModule.anotherMethod(gamedatas);&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
            &lt;br /&gt;
        },&lt;br /&gt;
        ...&lt;br /&gt;
        ///////////////////////////////////////////////////&lt;br /&gt;
        //// Reaction to cometD notifications&lt;br /&gt;
 &lt;br /&gt;
        /*&lt;br /&gt;
            setupNotifications:&lt;br /&gt;
            &lt;br /&gt;
            In this method, you associate each of your game notifications with your local method to handle it.&lt;br /&gt;
            &lt;br /&gt;
            Note: game notification names correspond to &amp;quot;notifyAllPlayers&amp;quot; and &amp;quot;notifyPlayer&amp;quot; calls in&lt;br /&gt;
                  your progressevolutiontechnologyswh.game.php file.&lt;br /&gt;
        &lt;br /&gt;
        */&lt;br /&gt;
        setupNotifications: function()&lt;br /&gt;
        {&lt;br /&gt;
            console.log( &#039;notifications subscriptions setup&#039; );&lt;br /&gt;
            &lt;br /&gt;
            // TODO: here, associate your game notifications with local methods&lt;br /&gt;
            &lt;br /&gt;
            // Example 1: standard notification handling&lt;br /&gt;
            // dojo.subscribe( &#039;cardPlayed&#039;, this, &amp;quot;notif_cardPlayed&amp;quot; );&lt;br /&gt;
            &lt;br /&gt;
            // Example 2: standard notification handling + tell the user interface to wait&lt;br /&gt;
            //            during 3 seconds after calling the method in order to let the players&lt;br /&gt;
            //            see what is happening in the game.&lt;br /&gt;
            // dojo.subscribe( &#039;cardPlayed&#039;, this, &amp;quot;notif_cardPlayed&amp;quot; );&lt;br /&gt;
            // this.notifqueue.setSynchronous( &#039;cardPlayed&#039;, 3000 );&lt;br /&gt;
            //&lt;br /&gt;
            // TODO: check module integration with dojo.subscribe&lt;br /&gt;
        },&lt;br /&gt;
     });&lt;br /&gt;
 });&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== See it in a real project ===&lt;br /&gt;
This method has been partially or totally applied on the following projects:&lt;br /&gt;
* [https://gitlab.swhawk.eu/silver/progressevolutiontechnologybga Progress: Evolution of Technology] by [[User:SwHawk|SwHawk]]&lt;br /&gt;
&lt;br /&gt;
If you have successfully applied this method in your project, feel free to add you project to the list by editing this section&lt;/div&gt;</summary>
		<author><name>SwHawk</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=User:SwHawk/Create_Modular_Code&amp;diff=13601</id>
		<title>User:SwHawk/Create Modular Code</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=User:SwHawk/Create_Modular_Code&amp;diff=13601"/>
		<updated>2022-06-14T20:45:49Z</updated>

		<summary type="html">&lt;p&gt;SwHawk: /* Putting it all together */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{InfoBox|title=WIP|body=&#039;&#039;&#039;This article is a Work In Progress, please do not refer to it for production purposes&#039;&#039;&#039;}}&lt;br /&gt;
&lt;br /&gt;
This page will cover steps you can take as a BGA developer to make your code more modular and better organized. The way the framework is implemented makes the [[Main game logic: yourgamename.game.php|game logic]] and the [[Game interface logic: yourgamename.js|interface logic]] files very monolithic. While this is not a problem in itself, even simple to moderately complex game may require this files to be over 5k lines of code. Thus you can quickly become lost in all the functions you need to declare, where they are declared, and where they are called.&lt;br /&gt;
&lt;br /&gt;
But there are steps that you can follow to take advantage of PHP&#039;s Object Oriented Code and the dojo toolkit&#039;s AMD loader to organize your code in separate files. Let&#039;s see what&#039;s available:&lt;br /&gt;
&lt;br /&gt;
== Acknowledgements ==&lt;br /&gt;
&lt;br /&gt;
Writing this wiki article wouldn&#039;t have been possible without the help, work and insight of more experienced BGA developers:&lt;br /&gt;
* [https://boardgamearena.com/player?id=83846198 Tisaac]  (Discord user Tisaac Human Expert)&lt;br /&gt;
* [https://boardgamearena.com/player?id=85537631 bennygui] (Discord user bennygui)&lt;br /&gt;
* [https://boardgamearena.com/player?id=84125723 VictoriaLa] (Discord user VictoriaLa)&lt;br /&gt;
* Syarwin and [https://boardgamearena.com/player?id=84554161 quietmint] (for their Welcome To [https://github.com/Syarwin/bga-welcometo repository])&lt;br /&gt;
* [https://boardgamearena.com/player?id=84522426 Mogri] (Discord user Mogri)&lt;br /&gt;
&lt;br /&gt;
== Conventions ==&lt;br /&gt;
In the code blocks, code additions will be displayed in bold and green, and added comments will be displayed in bold and dark grey so that they stand out from the boilerplate code from a scratch project. Part in red should be aapted to reflect your project&#039;s structure.&lt;br /&gt;
&lt;br /&gt;
== On the PHP side ==&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt; vs &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; ===&lt;br /&gt;
Throughout this section, I&#039;ll make heavy use of PHP&#039;s &amp;lt;code&amp;gt;require_once&amp;lt;/code&amp;gt; control structure. Why am I using &amp;lt;code&amp;gt;require(_once)&amp;lt;/code&amp;gt; instead of &amp;lt;code&amp;gt;include_once&amp;lt;/code&amp;gt;? Because if an error exists in a PHP file that you try to &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt;, only a warning will be thrown, but the script will continue in spite of the error. Using &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; if the included file has an error, the script dies when the inclusion takes places, throwing a fatal error (&amp;lt;code&amp;gt;E_COMPILE_ERROR&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
That way, I&#039;m sure the classes, traits or interfaces I&#039;m including are syntax error free.&lt;br /&gt;
&lt;br /&gt;
=== Game logic methods ===&lt;br /&gt;
The way the framework is implemented, your game logic is gathered inside a class (&amp;lt;code&amp;gt;YourProjectName&amp;lt;/code&amp;gt;) extending the [[Table|&amp;lt;code&amp;gt;Table&amp;lt;/code&amp;gt; class]]. You define your methods there so that they may be called from other parts of the framework (as long as they&#039;re public methods obviously).&lt;br /&gt;
&lt;br /&gt;
But you can take advantage of [https://www.php.net/manual/en/language.oop5.traits.php PHP Traits]. In a nutshell, Traits are a collection of methods that can be reused in different classes, to avoid code duplication. Here we&#039;re not going to reuse them anywhere else than in the game class, but this little trick allows us to put methods definitions in other files, and in so doing to avoid monolithic code.&lt;br /&gt;
&lt;br /&gt;
Basically you create a Trait in th &amp;lt;code&amp;gt;/modules/&amp;lt;/code&amp;gt; directory, for instance:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/UtiltityFunctionsTrait.php]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;lt;?php&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;namespace YourProjectNamespace\Modules;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;trait UtilityFunctionsTrait {&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &#039;&#039;&#039;public function myFirstUtilityFunction($args)&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;{&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//Your code here&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;}&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Then you can include it in you project&#039;s &amp;lt;code&amp;gt;X.game.php&amp;lt;/code&amp;gt; file like so:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X_game.php]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;?php&lt;br /&gt;
  /**&lt;br /&gt;
   *------&lt;br /&gt;
   * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
   * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
   * &lt;br /&gt;
   * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
   * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
   * -----&lt;br /&gt;
   * &lt;br /&gt;
   * X.game.php&lt;br /&gt;
   *&lt;br /&gt;
   * This is the main file for your game logic.&lt;br /&gt;
   *&lt;br /&gt;
   * In this PHP file, you are going to defines the rules of the game.&lt;br /&gt;
   *&lt;br /&gt;
   */&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;require_once &#039;modules/UtilityFunctionsTrait.php&#039;; &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;   //Here we require the trait to be loaded when the class is loaded&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;use X\Modules\UtilityFunctionsTrait;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;                 //We import the trait to be used directly as UtilityFunctionsTraits,&#039;&#039;&#039;&lt;br /&gt;
                                                      &#039;&#039;&#039;//otherwise we would have to use the Fully qualified class name&#039;&#039;&#039;&lt;br /&gt;
                                                      &#039;&#039;&#039;//(YourProjectNamespace\Modules\UtilityFunctionsTrait)&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 class X extends Table&lt;br /&gt;
 {&lt;br /&gt;
 //...&lt;br /&gt;
 &lt;br /&gt;
 //////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
 //////////// Utility functions&lt;br /&gt;
 ////////////    &lt;br /&gt;
 &lt;br /&gt;
     /*&lt;br /&gt;
         In this space, you can put any utility methods useful for your game logic&lt;br /&gt;
     */&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;use UtilityFunctionsTrait;&#039;&#039;&#039;&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//Here we actually include the trait inside the class, making all the trait&#039;s methods&#039;&#039;&#039; &lt;br /&gt;
                                &#039;&#039;&#039;//available as class methods, keeping their visibility scope (so a private method&#039;&#039;&#039;&lt;br /&gt;
                                &#039;&#039;&#039;//is still private)&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Support classes ===&lt;br /&gt;
Basically, the same as traits, you put your classes definitions into files that live under the &amp;lt;code&amp;gt;/modules/&amp;lt;/code&amp;gt; directory (don&#039;t forget to namespace your classes), and then require them at the top of &amp;lt;code&amp;gt;X_game.php&amp;lt;/code&amp;gt;, and voilà, you&#039;re done&lt;br /&gt;
&lt;br /&gt;
=== Adding autoloader support ===&lt;br /&gt;
&lt;br /&gt;
==== Coding standards ====&lt;br /&gt;
Even for simple games, you might end up having a dozen of traits and support classes. You can require them all in your &amp;lt;code&amp;gt;X_game.php&amp;lt;/code&amp;gt;. Or you can use an autoloader, which will load the necessary classes and traits at runtime. There are two PSRs dealing with autloading standards (namely [https://www.php-fig.org/psr/psr-0 PSR-0] which is marked as deprecated and [https://www.php-fig.org/psr/psr-4 PSR-4]) which state that your namespaces should be a reflection of the directory structure of your project.&lt;br /&gt;
&lt;br /&gt;
Basically, when creating namespaces, you choose a namespace prefix. For example, you could use your BGA handle and the project name as a namespace prefix (would result in &amp;lt;code&amp;gt;\SwHawk\X&amp;lt;/code&amp;gt; in my case), and then the rest of the namespace would be the directory the file is in. I usually group classes and traits by the function they have in my project, so my &amp;lt;code&amp;gt;/modules/&amp;lt;/code&amp;gt; directory looks like that:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
modules/&lt;br /&gt;
    php/&lt;br /&gt;
        Factory/                      //Holds my factory classes&lt;br /&gt;
            AFactoryClass.php         //The namespace for this file would be \SwHawk\X\Factory, and the fully qualified class name would be \SwHawk\X\Factory\AFactoryClass&lt;br /&gt;
            ...&lt;br /&gt;
        Object/                       //Holds my support classes&lt;br /&gt;
            ObjectA.php               //The namespace for this file would be \SwHawk\X\Object, and the fully qualified class name would be \SwHawk\X\Object\ObjectA&lt;br /&gt;
            ...&lt;br /&gt;
        Traits/                       //Holds my traits&lt;br /&gt;
            UtilityFunctionsTrait.php //The namespace for this file would be \SwHawk\X\Traits, and the fully qualified class name would be \SwHawk\X\Traits\UtilityFunctionsTrait&lt;br /&gt;
            ...&lt;br /&gt;
        ...&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Autoloader function for development ====&lt;br /&gt;
While your project is under development, you usually create, move and remove classes as part of the development process. So you usually need an autoloading function that can handle a lot of flexibility. Basically once you import a class using the &amp;lt;code&amp;gt;use&amp;lt;/code&amp;gt; keyword, the autoloading function will determine which file to &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; using its fully qualified class name, and then &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt;. This function needs to be either defined or included at the top of &amp;lt;code&amp;gt;X_game.php&amp;lt;/code&amp;gt;. Such a function would have the following code (borrowed and adapted from [https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader-examples.md this repository]):&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;spl_autoload_register(function ($class) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// project-specific namespace prefix&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;, adapt to your needs&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;, remember that you must escape \ characters in double-quoted strings (hence the \\)&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$prefix = &#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;SwHawk\\X\\&amp;quot;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// base directory for the namespace prefix, this file would usually reside in the modules/php/includes/ directory, so the base directory for all my classes would be a level higher&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$base_dir = __DIR__ . &#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;&#039;&#039;&#039; &#039;/../&#039; &#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;gt;&#039;&#039;&#039;;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// does the class use the namespace prefix?&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$len = strlen($prefix);&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;if (strncmp($prefix, $class, $len) !== 0) {&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// no, move to the next registered autoloader&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;return;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// get the relative class name&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$relative_class = substr($class, $len);&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;// replace the namespace prefix with the base directory, replace namespace&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;// separators with directory separators in the relative class name, append&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;// with .php&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$file = $base_dir . str_replace(&#039;\\&#039;, &#039;/&#039;, $relative_class) . &#039;.php&#039;;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// if the file exists, require it&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;if (file_exists($file)) {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;require $file;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Autoloader function for production ====&lt;br /&gt;
Once you&#039;re moving your game to production, the autoloader function provided before isn&#039;t optimized. Once in production, the directory tree should not be modified, so you can change the earlier autoloader to a classmap based one. Basically, you build an associative array with the fully qualified classes names as keys and the filepath as the value. An example would look like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;spl_autoload_register(function ($class) {&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;static $classmap = array(&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:red&amp;gt;&amp;quot;SwHawk\\X\\&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;Factory\\AFactoryClass&amp;quot; =&amp;gt; __DIR__ . &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;&amp;quot;/../&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;Factory/AFactoryClass.php&amp;quot;,&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;);&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;if(array_key_exists($class)) {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;require $classmap[$class];&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;} else {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;return;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This autoloader is better suited to production since it won&#039;t use expensive calls like &amp;lt;code&amp;gt;file_exists($filename)&amp;lt;/code&amp;gt;. You can write the classmap by yourself, but it can be quite cumbersome, there is some tools like [https://github.com/hanneskod/classtools this project], or [https://github.com/gnugat/nomo-spaco this one], or even scripts detailed in this [https://stackoverflow.com/questions/22761554/how-to-get-all-class-names-inside-a-particular-namespace StackOverflow topic]&lt;br /&gt;
&lt;br /&gt;
== On the JS side ==&lt;br /&gt;
&lt;br /&gt;
BGA uses the dojo toolkit framework for most of its javascript code. Dojo comes with its own way of loading modules, which you can read about in more detail [https://dojotoolkit.org/documentation/tutorials/1.10/modules/ here] and [https://dojotoolkit.org/documentation/tutorials/1.10/modules_advanced/ here]. To put it simply, there are two ways you can go about this&lt;br /&gt;
&lt;br /&gt;
=== Write plain javascript ===&lt;br /&gt;
&lt;br /&gt;
==== Relying on the dojo toolkit ====&lt;br /&gt;
Should you wan to write plain javascript, you can easily do so. What you need to do is actually load the file like so in &amp;lt;code&amp;gt;X.js&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&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;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&amp;quot;./modules/path/to/firstfile.js&amp;quot;,&amp;lt;/span&amp;gt;        &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;//The first file with your JS code&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&amp;quot;./modules/path/to/secondfile.js&amp;quot;,&amp;lt;/span&amp;gt;       &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;//The second file with another part of your JS code&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
     ...&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
         constructor: function(){&lt;br /&gt;
             ...&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
According to the dojo toolkit documentation, you will then need to directly access what you defined in the files.&lt;br /&gt;
&lt;br /&gt;
==== Alternative method ====&lt;br /&gt;
&lt;br /&gt;
This section has mostly been written by [[User:Mogri|Mogri]].&lt;br /&gt;
&lt;br /&gt;
This approach lets you avoid Dojo and &amp;lt;tt&amp;gt;this&amp;lt;/tt&amp;gt; and allows more modern JS.&lt;br /&gt;
&lt;br /&gt;
First, you&#039;ll need to a a statement at the beginning of the &amp;lt;code&amp;gt;X.js&amp;lt;/code&amp;gt; file:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
 *------&lt;br /&gt;
 * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
 * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
 *&lt;br /&gt;
 * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
 * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
 * -----&lt;br /&gt;
 *&lt;br /&gt;
 * X.js&lt;br /&gt;
 *&lt;br /&gt;
 * X user interface script&lt;br /&gt;
 * &lt;br /&gt;
 * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&gt;
 &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;window.X = {};&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// X = your game, or you can use something more generic&amp;lt;/span&amp;gt;&#039;&#039;&#039;&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;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/whatever.js&amp;quot;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
         constructor: function(){&lt;br /&gt;
             console.log(&#039;X constructor&#039;);&lt;br /&gt;
               &lt;br /&gt;
             // Here, you can init the global variables of your user interface&lt;br /&gt;
             // Example:&lt;br /&gt;
             // this.myGlobalValue = 0;&lt;br /&gt;
 &lt;br /&gt;
         },&lt;br /&gt;
         &lt;br /&gt;
         /*&lt;br /&gt;
             setup:&lt;br /&gt;
             &lt;br /&gt;
             This method must set up the game user interface according to current game situation specified&lt;br /&gt;
             in parameters.&lt;br /&gt;
             &lt;br /&gt;
             The method is called each time the game interface is displayed to a player, ie:&lt;br /&gt;
             _ when the game starts&lt;br /&gt;
             _ when a player refreshes the game page (F5)&lt;br /&gt;
             &lt;br /&gt;
             &amp;quot;gamedatas&amp;quot; argument contains all datas retrieved by your &amp;quot;getAllDatas&amp;quot; PHP method.&lt;br /&gt;
         */&lt;br /&gt;
        &lt;br /&gt;
         setup: function( gamedatas )&lt;br /&gt;
         {&lt;br /&gt;
             &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;X = Object.assign(this, X);&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// This will allow you to use X.method instead of this.method inside modules/whatever.js&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// the rest of your setup goes here&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
         },&lt;br /&gt;
     });&lt;br /&gt;
 });&lt;br /&gt;
&lt;br /&gt;
And then, in your &amp;lt;code&amp;gt;modules/whatever.js&amp;lt;/code&amp;gt; file:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/whatever.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;X = Object.assign(X, {&#039;&#039;&#039;&lt;br /&gt;
   &#039;&#039;&#039;MY_CONSTANT: 1,&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
   &#039;&#039;&#039;myFunction: (arg1, arg2) =&amp;gt; {&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;X.someFunction(X.MY_CONSTANT);&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;return arg1 + arg2;&#039;&#039;&#039;&lt;br /&gt;
   &#039;&#039;&#039;},&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
   &#039;&#039;&#039;someFunction: (x) =&amp;gt; _(&#039;The answer is: &#039;) + x,&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;}&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notes on this approach:&lt;br /&gt;
*Aside from setup and any framework-override functions, you can use arrow functions&lt;br /&gt;
*Always use X instead of &amp;lt;tt&amp;gt;this&amp;lt;/tt&amp;gt;&lt;br /&gt;
*As usual, you can use any number of modules this way&lt;br /&gt;
&lt;br /&gt;
=== Write an AMD module ===&lt;br /&gt;
You can take advantage of the toolkit&#039;s module system to declare dependencies between the differents files you&#039;ll be writing (modules in the toolkit&#039;s language). To be identified as modules, your Javascript files will need to have the following structure:&lt;br /&gt;
&lt;br /&gt;
==== Create a named new class ====&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/js/FirstModule.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;gt;&#039;&#039;&#039;define([&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo&amp;quot;,&amp;lt;/span&amp;gt;      &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Needed if you want to be able to use dojo methods such as dojo.place, etc.&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo/_base/declare&amp;quot;,&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;other dependencies...&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;],function(dojo, declare){&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;return declare(&amp;quot;className&amp;quot;,&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/*Parent classes that this class inherits, optional*/&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, {&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;&#039;&#039;&#039;/* static properties */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;let property1 = &amp;quot;value;&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;let property2 = 5;&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;constructor: function (args) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;&#039;&#039;&#039;/* instance properties */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;let property3 = 8;&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;let property4 = [ &amp;quot;arrayValue&amp;quot;, &amp;quot;arrayValue2&amp;quot; ]; &#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;method1: function (args) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;/* your code here */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
         &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;});&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then in the X.js file, you can use your newly created module like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&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;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/js/Firstmodule&amp;quot;,&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
     ...&lt;br /&gt;
     });&lt;br /&gt;
 });&lt;br /&gt;
&lt;br /&gt;
In your code, you can access your module&#039;s class and methods by doing so:&lt;br /&gt;
&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;let object = new className();&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;object.method1();&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;...&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This can lead to namespace collisions if you don&#039;t choose a namespace correctly, so you might want to take the same approach as described earlier for the PHP files for using a namespace.&lt;br /&gt;
&lt;br /&gt;
==== Create an anonymous class ====&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/js/SecondModule.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;gt;&#039;&#039;&#039;define([&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo&amp;quot;,&amp;lt;/span&amp;gt;      &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Needed if you want to be able to use dojo methods such as dojo.place, etc.&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo/_base/declare&amp;quot;,&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;other dependencies...&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;],function(dojo, declare){&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;return declare(null,&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/*Parent classes that this class inherits, optional*/&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, {&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;&#039;&#039;&#039;/* static properties */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;let property1 = &amp;quot;value;&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;let property2 = 5;&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;constructor: function (args) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;&#039;&#039;&#039;/* instance properties */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;let property3 = 8;&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;let property4 = [ &amp;quot;arrayValue&amp;quot;, &amp;quot;arrayValue2&amp;quot; ]; &#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;method1: function (args) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;/* your code here */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
         &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;});&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then in the X.js file, you can use your newly created module like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&gt;
 &lt;br /&gt;
 define([&lt;br /&gt;
     &amp;quot;dojo&amp;quot;,&amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/js/SecondModule&amp;quot;,&#039;&#039;&#039;&amp;lt;/span&amp;gt;      &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//Has to be inserted in the third position as we&#039;ll&#039;&#039;&#039;&lt;br /&gt;
                                       &#039;&#039;&#039;//need an identifier later, and the other modules don&#039;t need it, see code in the preceding subsection.&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
     &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
 &lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, SecondModule&amp;lt;/span&amp;gt;  &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/* insert a reference here that you&#039;ll use throughout the JS file for this module */&amp;lt;/span&amp;gt;&#039;&#039;&#039;) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
     ...&lt;br /&gt;
     });&lt;br /&gt;
 });&lt;br /&gt;
&lt;br /&gt;
In your code, you can access your module&#039;s class and methods by doing so:&lt;br /&gt;
&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;let someValue = SecondModule.property3&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;SecondModule.method1();&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;...&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This can lead to namespace collisions if you don&#039;t choose a namespace correctly, so you might want to take the same approach as described earlier for the PHP files for using a namespace.&lt;br /&gt;
&lt;br /&gt;
==== Create a singleton object ====&lt;br /&gt;
&lt;br /&gt;
You can also create singleton objects by creating a module this way:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/js/singletonObject.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;define([&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo&amp;quot;,&amp;lt;/span&amp;gt;      &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Needed if you want to be able to use dojo methods such as dojo.place, etc.&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;], function (dojo) {&#039;&#039;&#039;&lt;br /&gt;
     &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;// Methods and variables defined in this part will not be available anywhere else than in this file&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;let privateVariable = &amp;quot;someValue&amp;quot;;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;let privateFunction = function (args) {&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//some code here&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;return {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;firstMethod: function (args) {&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;privateFunction(args);&#039;&#039;&#039;&lt;br /&gt;
             &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//some other code here&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;};&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To be used in the &amp;lt;code&amp;gt;X.js&amp;lt;/code&amp;gt; file, you must use the same method as in the [[#Create an anonymous class|previous section]]:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&gt;
 &lt;br /&gt;
 define([&lt;br /&gt;
     &amp;quot;dojo&amp;quot;,&amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&amp;quot;./modules/js/SecondModule&amp;quot;,&amp;lt;/span&amp;gt;         &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Has to be inserted in the third position as we&#039;ll need an identifier later, and the other modules don&#039;t need it&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&amp;quot;./modules/js/sigletonObject&amp;quot;,&amp;lt;/span&amp;gt;          &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//see code in the preceding subsection.&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
     &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/js/Firstmodule&amp;quot;,&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, SecondModule&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/* insert a reference here that you&#039;ll use throughout the JS file for this module */&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, singletonObject&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/* same here */&amp;lt;/span&amp;gt;&#039;&#039;&#039;) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
     ...&lt;br /&gt;
     });&lt;br /&gt;
 });&lt;br /&gt;
&lt;br /&gt;
Then you can access your code the same way as described in the [[#Create an anonymous class|previous section]]:&lt;br /&gt;
&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;singletonObject.firstMethod();&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;...&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Putting it all together ==&lt;br /&gt;
As you might have gathered reading this, much of your work will rely on the directory structure your project will follow.&lt;br /&gt;
&lt;br /&gt;
=== Recommended directory structure ===&lt;br /&gt;
&lt;br /&gt;
This is a recommendation, and in no way are you forced to follow it, but then you may have to adapt some of the code snippets shown below. All filenames should be self-explanatory, although there might be comments for some files.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
X/&lt;br /&gt;
  img/&lt;br /&gt;
    ...&lt;br /&gt;
  misc/&lt;br /&gt;
    ...&lt;br /&gt;
  modules/&lt;br /&gt;
    js/&lt;br /&gt;
      utility/&lt;br /&gt;
        FirstUtilityModule.js (defines a [[#Create a singleton object|singleton object]])&lt;br /&gt;
        SecondUtilityModule.js (defines an [[#Create an anonymous class|anonymous class]])&lt;br /&gt;
      notifications/&lt;br /&gt;
        FirstNotificationModule.js (defines a [[#Create a new named class|class with a name]])&lt;br /&gt;
      actions/&lt;br /&gt;
        FirstActionModule.js (plain JS code)&lt;br /&gt;
    php/&lt;br /&gt;
      includes/&lt;br /&gt;
        PNAutoloader.php (contains your autoloader, PN stands for ProjectName, and should be a trigram if possible)&lt;br /&gt;
        Other files to be included into files of the project. For instance splits from material.inc.php.&lt;br /&gt;
      Object/&lt;br /&gt;
         ObjectA.php&lt;br /&gt;
         ObjectB.php&lt;br /&gt;
      Traits/&lt;br /&gt;
         PlayerActions/&lt;br /&gt;
           PlayerActionsFunctionsTrait.php&lt;br /&gt;
         States/&lt;br /&gt;
           Actions/&lt;br /&gt;
             StateActionsFunctionsTrait.php&lt;br /&gt;
           Arguments/&lt;br /&gt;
             StateArgumentFunctionsTrait.php&lt;br /&gt;
         Utility/&lt;br /&gt;
           FirstUtilityFunctionsTrait.php&lt;br /&gt;
           SecondUtilityFunctionsTrait.php&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This directory tree is quite detailed, you&#039;re free to make arrangements with it to suit your project&#039;s requirements.&lt;br /&gt;
&lt;br /&gt;
=== Choosing a namespace prefix ===&lt;br /&gt;
&lt;br /&gt;
==== PHP ====&lt;br /&gt;
As stated earlier, in order to avoid collisions when importing your PHP Classes and Traits, you should define a namespace prefix. We&#039;ll use &amp;lt;code&amp;gt;Username\ProjectName&amp;lt;/code&amp;gt; throughout the remainder of this article.&lt;br /&gt;
&lt;br /&gt;
==== JS ====&lt;br /&gt;
As we&#039;ll create a named class, we should also use a namespace prefix for the JS module. We&#039;ll use &amp;lt;code&amp;gt;username.projectname&amp;lt;/code&amp;gt; throughout the remainder of this article&lt;br /&gt;
&lt;br /&gt;
=== Write the autoloader and include it in the game logic ===&lt;br /&gt;
Even though you may have a lot less PHP classes than stated here, you should really write an autoloader function, and since it&#039;s recommended for the production environment, you should proceed to write a [[#Autoloader function for production|classmap autoloader]] when your classes are pretty much stabilised.&lt;br /&gt;
&lt;br /&gt;
Then you need to include it in your X_game.php like so:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X_game.php]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;?php&lt;br /&gt;
  /**&lt;br /&gt;
   *------&lt;br /&gt;
   * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
   * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
   * &lt;br /&gt;
   * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
   * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
   * -----&lt;br /&gt;
   * &lt;br /&gt;
   * X.game.php&lt;br /&gt;
   *&lt;br /&gt;
   * This is the main file for your game logic.&lt;br /&gt;
   *&lt;br /&gt;
   * In this PHP file, you are going to defines the rules of the game.&lt;br /&gt;
   *&lt;br /&gt;
   */&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;require_once &#039;modules/php/PNAutoloader.php&#039;;&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Here you&#039;ll write the use statements to import your classes and traits using the autoloader&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 class X extends Table&lt;br /&gt;
 {&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Here you can write the use statements to import your traits into the class, or put them in the relevant sections of the file&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Write your Javascript modules and include them ===&lt;br /&gt;
On the JS side of the code, you have multiple alternatives to choose from (see the [[#On the JS side|JS section]]), but all will require you to modify the &amp;lt;code&amp;gt;define&amp;lt;/code&amp;gt; statement at the beginning of the &amp;lt;code&amp;gt;X.js&amp;lt;/code&amp;gt; file. According to the directory structure shown above, the file would look like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&gt;
 &lt;br /&gt;
 define([&lt;br /&gt;
     &amp;quot;dojo&amp;quot;,&amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/js/utility/FirstUtilityModule&amp;quot;,&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;./modules/js/utility/SecondUtilityModule&amp;quot;,&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
     &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/js/actions/FirstActionModule.js&amp;quot;,&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;./modules/js/notifications/FirstNotificationModule&amp;quot;,&amp;lt;/span&amp;gt;&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare, &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;FirstUtilityModule, SecondUtilityModule&amp;lt;/span&amp;gt;&#039;&#039;&#039;) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
         constructor: function(){&lt;br /&gt;
            console.log(&#039;X constructor&#039;);&lt;br /&gt;
              &lt;br /&gt;
            // Here, you can init the global variables of your user interface&lt;br /&gt;
            // Example:&lt;br /&gt;
            // this.myGlobalValue = 0;&lt;br /&gt;
            &lt;br /&gt;
        },&lt;br /&gt;
        &lt;br /&gt;
        /*&lt;br /&gt;
            setup:&lt;br /&gt;
            &lt;br /&gt;
            This method must set up the game user interface according to current game situation specified&lt;br /&gt;
            in parameters.&lt;br /&gt;
            &lt;br /&gt;
            The method is called each time the game interface is displayed to a player, ie:&lt;br /&gt;
            _ when the game starts&lt;br /&gt;
            _ when a player refreshes the game page (F5)&lt;br /&gt;
            &lt;br /&gt;
            &amp;quot;gamedatas&amp;quot; argument contains all datas retrieved by your &amp;quot;getAllDatas&amp;quot; PHP method.&lt;br /&gt;
        */&lt;br /&gt;
        &lt;br /&gt;
        setup: function( gamedatas )&lt;br /&gt;
        {&lt;br /&gt;
            &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;FirstUtilityModule.myMethod();&#039;&#039;&#039;&lt;br /&gt;
            &#039;&#039;&#039;SecondUtilityModule.anotherMethod(gamedatas);&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
            &lt;br /&gt;
        },&lt;br /&gt;
        ...&lt;br /&gt;
        ///////////////////////////////////////////////////&lt;br /&gt;
        //// Reaction to cometD notifications&lt;br /&gt;
 &lt;br /&gt;
        /*&lt;br /&gt;
            setupNotifications:&lt;br /&gt;
            &lt;br /&gt;
            In this method, you associate each of your game notifications with your local method to handle it.&lt;br /&gt;
            &lt;br /&gt;
            Note: game notification names correspond to &amp;quot;notifyAllPlayers&amp;quot; and &amp;quot;notifyPlayer&amp;quot; calls in&lt;br /&gt;
                  your progressevolutiontechnologyswh.game.php file.&lt;br /&gt;
        &lt;br /&gt;
        */&lt;br /&gt;
        setupNotifications: function()&lt;br /&gt;
        {&lt;br /&gt;
            console.log( &#039;notifications subscriptions setup&#039; );&lt;br /&gt;
            &lt;br /&gt;
            // TODO: here, associate your game notifications with local methods&lt;br /&gt;
            &lt;br /&gt;
            // Example 1: standard notification handling&lt;br /&gt;
            // dojo.subscribe( &#039;cardPlayed&#039;, this, &amp;quot;notif_cardPlayed&amp;quot; );&lt;br /&gt;
            &lt;br /&gt;
            // Example 2: standard notification handling + tell the user interface to wait&lt;br /&gt;
            //            during 3 seconds after calling the method in order to let the players&lt;br /&gt;
            //            see what is happening in the game.&lt;br /&gt;
            // dojo.subscribe( &#039;cardPlayed&#039;, this, &amp;quot;notif_cardPlayed&amp;quot; );&lt;br /&gt;
            // this.notifqueue.setSynchronous( &#039;cardPlayed&#039;, 3000 );&lt;br /&gt;
            //&lt;br /&gt;
            // TODO: check module integration with dojo.subscribe&lt;br /&gt;
        },&lt;br /&gt;
     });&lt;br /&gt;
 });&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== See it in a real project ===&lt;br /&gt;
This method has been partially or totally applied on the following projects:&lt;br /&gt;
* [https://gitlab.swhawk.eu/silver/progressevolutiontechnologybga Progress: Evolution of Technology] by [[User:SwHawk|SwHawk]]&lt;br /&gt;
&lt;br /&gt;
If you have successfully applied this method in your project, feel free to add you project to the list by editing this section&lt;/div&gt;</summary>
		<author><name>SwHawk</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=User:SwHawk/Create_Modular_Code&amp;diff=13598</id>
		<title>User:SwHawk/Create Modular Code</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=User:SwHawk/Create_Modular_Code&amp;diff=13598"/>
		<updated>2022-06-14T19:52:20Z</updated>

		<summary type="html">&lt;p&gt;SwHawk: /* Alternative method */ got rid of personal project name&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{InfoBox|title=WIP|body=&#039;&#039;&#039;This article is a Work In Progress, please do not refer to it for production purposes&#039;&#039;&#039;}}&lt;br /&gt;
&lt;br /&gt;
This page will cover steps you can take as a BGA developer to make your code more modular and better organized. The way the framework is implemented makes the [[Main game logic: yourgamename.game.php|game logic]] and the [[Game interface logic: yourgamename.js|interface logic]] files very monolithic. While this is not a problem in itself, even simple to moderately complex game may require this files to be over 5k lines of code. Thus you can quickly become lost in all the functions you need to declare, where they are declared, and where they are called.&lt;br /&gt;
&lt;br /&gt;
But there are steps that you can follow to take advantage of PHP&#039;s Object Oriented Code and the dojo toolkit&#039;s AMD loader to organize your code in separate files. Let&#039;s see what&#039;s available:&lt;br /&gt;
&lt;br /&gt;
== Acknowledgements ==&lt;br /&gt;
&lt;br /&gt;
Writing this wiki article wouldn&#039;t have been possible without the help, work and insight of more experienced BGA developers:&lt;br /&gt;
* [https://boardgamearena.com/player?id=83846198 Tisaac]  (Discord user Tisaac Human Expert)&lt;br /&gt;
* [https://boardgamearena.com/player?id=85537631 bennygui] (Discord user bennygui)&lt;br /&gt;
* [https://boardgamearena.com/player?id=84125723 VictoriaLa] (Discord user VictoriaLa)&lt;br /&gt;
* Syarwin and [https://boardgamearena.com/player?id=84554161 quietmint] (for their Welcome To [https://github.com/Syarwin/bga-welcometo repository])&lt;br /&gt;
* [https://boardgamearena.com/player?id=84522426 Mogri] (Discord user Mogri)&lt;br /&gt;
&lt;br /&gt;
== Conventions ==&lt;br /&gt;
In the code blocks, code additions will be displayed in bold and green, and added comments will be displayed in bold and dark grey so that they stand out from the boilerplate code from a scratch project. Part in red should be aapted to reflect your project&#039;s structure.&lt;br /&gt;
&lt;br /&gt;
== On the PHP side ==&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt; vs &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; ===&lt;br /&gt;
Throughout this section, I&#039;ll make heavy use of PHP&#039;s &amp;lt;code&amp;gt;require_once&amp;lt;/code&amp;gt; control structure. Why am I using &amp;lt;code&amp;gt;require(_once)&amp;lt;/code&amp;gt; instead of &amp;lt;code&amp;gt;include_once&amp;lt;/code&amp;gt;? Because if an error exists in a PHP file that you try to &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt;, only a warning will be thrown, but the script will continue in spite of the error. Using &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; if the included file has an error, the script dies when the inclusion takes places, throwing a fatal error (&amp;lt;code&amp;gt;E_COMPILE_ERROR&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
That way, I&#039;m sure the classes, traits or interfaces I&#039;m including are syntax error free.&lt;br /&gt;
&lt;br /&gt;
=== Game logic methods ===&lt;br /&gt;
The way the framework is implemented, your game logic is gathered inside a class (&amp;lt;code&amp;gt;YourProjectName&amp;lt;/code&amp;gt;) extending the [[Table|&amp;lt;code&amp;gt;Table&amp;lt;/code&amp;gt; class]]. You define your methods there so that they may be called from other parts of the framework (as long as they&#039;re public methods obviously).&lt;br /&gt;
&lt;br /&gt;
But you can take advantage of [https://www.php.net/manual/en/language.oop5.traits.php PHP Traits]. In a nutshell, Traits are a collection of methods that can be reused in different classes, to avoid code duplication. Here we&#039;re not going to reuse them anywhere else than in the game class, but this little trick allows us to put methods definitions in other files, and in so doing to avoid monolithic code.&lt;br /&gt;
&lt;br /&gt;
Basically you create a Trait in th &amp;lt;code&amp;gt;/modules/&amp;lt;/code&amp;gt; directory, for instance:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/UtiltityFunctionsTrait.php]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;lt;?php&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;namespace YourProjectNamespace\Modules;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;trait UtilityFunctionsTrait {&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &#039;&#039;&#039;public function myFirstUtilityFunction($args)&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;{&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//Your code here&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;}&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Then you can include it in you project&#039;s &amp;lt;code&amp;gt;X.game.php&amp;lt;/code&amp;gt; file like so:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X_game.php]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;?php&lt;br /&gt;
  /**&lt;br /&gt;
   *------&lt;br /&gt;
   * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
   * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
   * &lt;br /&gt;
   * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
   * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
   * -----&lt;br /&gt;
   * &lt;br /&gt;
   * X.game.php&lt;br /&gt;
   *&lt;br /&gt;
   * This is the main file for your game logic.&lt;br /&gt;
   *&lt;br /&gt;
   * In this PHP file, you are going to defines the rules of the game.&lt;br /&gt;
   *&lt;br /&gt;
   */&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;require_once &#039;modules/UtilityFunctionsTrait.php&#039;; &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;   //Here we require the trait to be loaded when the class is loaded&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;use X\Modules\UtilityFunctionsTrait;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;                 //We import the trait to be used directly as UtilityFunctionsTraits,&#039;&#039;&#039;&lt;br /&gt;
                                                      &#039;&#039;&#039;//otherwise we would have to use the Fully qualified class name&#039;&#039;&#039;&lt;br /&gt;
                                                      &#039;&#039;&#039;//(YourProjectNamespace\Modules\UtilityFunctionsTrait)&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 class X extends Table&lt;br /&gt;
 {&lt;br /&gt;
 //...&lt;br /&gt;
 &lt;br /&gt;
 //////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
 //////////// Utility functions&lt;br /&gt;
 ////////////    &lt;br /&gt;
 &lt;br /&gt;
     /*&lt;br /&gt;
         In this space, you can put any utility methods useful for your game logic&lt;br /&gt;
     */&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;use UtilityFunctionsTrait;&#039;&#039;&#039;&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//Here we actually include the trait inside the class, making all the trait&#039;s methods&#039;&#039;&#039; &lt;br /&gt;
                                &#039;&#039;&#039;//available as class methods, keeping their visibility scope (so a private method&#039;&#039;&#039;&lt;br /&gt;
                                &#039;&#039;&#039;//is still private)&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Support classes ===&lt;br /&gt;
Basically, the same as traits, you put your classes definitions into files that live under the &amp;lt;code&amp;gt;/modules/&amp;lt;/code&amp;gt; directory (don&#039;t forget to namespace your classes), and then require them at the top of &amp;lt;code&amp;gt;X_game.php&amp;lt;/code&amp;gt;, and voilà, you&#039;re done&lt;br /&gt;
&lt;br /&gt;
=== Adding autoloader support ===&lt;br /&gt;
&lt;br /&gt;
==== Coding standards ====&lt;br /&gt;
Even for simple games, you might end up having a dozen of traits and support classes. You can require them all in your &amp;lt;code&amp;gt;X_game.php&amp;lt;/code&amp;gt;. Or you can use an autoloader, which will load the necessary classes and traits at runtime. There are two PSRs dealing with autloading standards (namely [https://www.php-fig.org/psr/psr-0 PSR-0] which is marked as deprecated and [https://www.php-fig.org/psr/psr-4 PSR-4]) which state that your namespaces should be a reflection of the directory structure of your project.&lt;br /&gt;
&lt;br /&gt;
Basically, when creating namespaces, you choose a namespace prefix. For example, you could use your BGA handle and the project name as a namespace prefix (would result in &amp;lt;code&amp;gt;\SwHawk\X&amp;lt;/code&amp;gt; in my case), and then the rest of the namespace would be the directory the file is in. I usually group classes and traits by the function they have in my project, so my &amp;lt;code&amp;gt;/modules/&amp;lt;/code&amp;gt; directory looks like that:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
modules/&lt;br /&gt;
    php/&lt;br /&gt;
        Factory/                      //Holds my factory classes&lt;br /&gt;
            AFactoryClass.php         //The namespace for this file would be \SwHawk\X\Factory, and the fully qualified class name would be \SwHawk\X\Factory\AFactoryClass&lt;br /&gt;
            ...&lt;br /&gt;
        Object/                       //Holds my support classes&lt;br /&gt;
            ObjectA.php               //The namespace for this file would be \SwHawk\X\Object, and the fully qualified class name would be \SwHawk\X\Object\ObjectA&lt;br /&gt;
            ...&lt;br /&gt;
        Traits/                       //Holds my traits&lt;br /&gt;
            UtilityFunctionsTrait.php //The namespace for this file would be \SwHawk\X\Traits, and the fully qualified class name would be \SwHawk\X\Traits\UtilityFunctionsTrait&lt;br /&gt;
            ...&lt;br /&gt;
        ...&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Autoloader function for development ====&lt;br /&gt;
While your project is under development, you usually create, move and remove classes as part of the development process. So you usually need an autoloading function that can handle a lot of flexibility. Basically once you import a class using the &amp;lt;code&amp;gt;use&amp;lt;/code&amp;gt; keyword, the autoloading function will determine which file to &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; using its fully qualified class name, and then &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt;. This function needs to be either defined or included at the top of &amp;lt;code&amp;gt;X_game.php&amp;lt;/code&amp;gt;. Such a function would have the following code (borrowed and adapted from [https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader-examples.md this repository]):&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;spl_autoload_register(function ($class) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// project-specific namespace prefix&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;, adapt to your needs&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;, remember that you must escape \ characters in double-quoted strings (hence the \\)&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$prefix = &#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;SwHawk\\X\\&amp;quot;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// base directory for the namespace prefix, this file would usually reside in the modules/php/includes/ directory, so the base directory for all my classes would be a level higher&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$base_dir = __DIR__ . &#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;&#039;&#039;&#039; &#039;/../&#039; &#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;gt;&#039;&#039;&#039;;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// does the class use the namespace prefix?&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$len = strlen($prefix);&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;if (strncmp($prefix, $class, $len) !== 0) {&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// no, move to the next registered autoloader&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;return;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// get the relative class name&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$relative_class = substr($class, $len);&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;// replace the namespace prefix with the base directory, replace namespace&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;// separators with directory separators in the relative class name, append&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;// with .php&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$file = $base_dir . str_replace(&#039;\\&#039;, &#039;/&#039;, $relative_class) . &#039;.php&#039;;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// if the file exists, require it&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;if (file_exists($file)) {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;require $file;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Autoloader function for production ====&lt;br /&gt;
Once you&#039;re moving your game to production, the autoloader function provided before isn&#039;t optimized. Once in production, the directory tree should not be modified, so you can change the earlier autoloader to a classmap based one. Basically, you build an associative array with the fully qualified classes names as keys and the filepath as the value. An example would look like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;spl_autoload_register(function ($class) {&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;static $classmap = array(&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:red&amp;gt;&amp;quot;SwHawk\\X\\&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;Factory\\AFactoryClass&amp;quot; =&amp;gt; __DIR__ . &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;&amp;quot;/../&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;Factory/AFactoryClass.php&amp;quot;,&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;);&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;if(array_key_exists($class)) {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;require $classmap[$class];&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;} else {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;return;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This autoloader is better suited to production since it won&#039;t use expensive calls like &amp;lt;code&amp;gt;file_exists($filename)&amp;lt;/code&amp;gt;. You can write the classmap by yourself, but it can be quite cumbersome, there is some tools like [https://github.com/hanneskod/classtools this project], or [https://github.com/gnugat/nomo-spaco this one], or even scripts detailed in this [https://stackoverflow.com/questions/22761554/how-to-get-all-class-names-inside-a-particular-namespace StackOverflow topic]&lt;br /&gt;
&lt;br /&gt;
== On the JS side ==&lt;br /&gt;
&lt;br /&gt;
BGA uses the dojo toolkit framework for most of its javascript code. Dojo comes with its own way of loading modules, which you can read about in more detail [https://dojotoolkit.org/documentation/tutorials/1.10/modules/ here] and [https://dojotoolkit.org/documentation/tutorials/1.10/modules_advanced/ here]. To put it simply, there are two ways you can go about this&lt;br /&gt;
&lt;br /&gt;
=== Write plain javascript ===&lt;br /&gt;
&lt;br /&gt;
==== Relying on the dojo toolkit ====&lt;br /&gt;
Should you wan to write plain javascript, you can easily do so. What you need to do is actually load the file like so in &amp;lt;code&amp;gt;X.js&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&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;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&amp;quot;./modules/path/to/firstfile.js&amp;quot;,&amp;lt;/span&amp;gt;        &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;//The first file with your JS code&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&amp;quot;./modules/path/to/secondfile.js&amp;quot;,&amp;lt;/span&amp;gt;       &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;//The second file with another part of your JS code&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
     ...&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
         constructor: function(){&lt;br /&gt;
             ...&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
According to the dojo toolkit documentation, you will then need to directly access what you defined in the files.&lt;br /&gt;
&lt;br /&gt;
==== Alternative method ====&lt;br /&gt;
&lt;br /&gt;
This section has mostly been written by [[User:Mogri|Mogri]].&lt;br /&gt;
&lt;br /&gt;
This approach lets you avoid Dojo and &amp;lt;tt&amp;gt;this&amp;lt;/tt&amp;gt; and allows more modern JS.&lt;br /&gt;
&lt;br /&gt;
First, you&#039;ll need to a a statement at the beginning of the &amp;lt;code&amp;gt;X.js&amp;lt;/code&amp;gt; file:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
 *------&lt;br /&gt;
 * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
 * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
 *&lt;br /&gt;
 * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
 * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
 * -----&lt;br /&gt;
 *&lt;br /&gt;
 * X.js&lt;br /&gt;
 *&lt;br /&gt;
 * X user interface script&lt;br /&gt;
 * &lt;br /&gt;
 * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&gt;
 &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;window.X = {};&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// X = your game, or you can use something more generic&amp;lt;/span&amp;gt;&#039;&#039;&#039;&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;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/whatever.js&amp;quot;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
         constructor: function(){&lt;br /&gt;
             console.log(&#039;X constructor&#039;);&lt;br /&gt;
               &lt;br /&gt;
             // Here, you can init the global variables of your user interface&lt;br /&gt;
             // Example:&lt;br /&gt;
             // this.myGlobalValue = 0;&lt;br /&gt;
 &lt;br /&gt;
         },&lt;br /&gt;
         &lt;br /&gt;
         /*&lt;br /&gt;
             setup:&lt;br /&gt;
             &lt;br /&gt;
             This method must set up the game user interface according to current game situation specified&lt;br /&gt;
             in parameters.&lt;br /&gt;
             &lt;br /&gt;
             The method is called each time the game interface is displayed to a player, ie:&lt;br /&gt;
             _ when the game starts&lt;br /&gt;
             _ when a player refreshes the game page (F5)&lt;br /&gt;
             &lt;br /&gt;
             &amp;quot;gamedatas&amp;quot; argument contains all datas retrieved by your &amp;quot;getAllDatas&amp;quot; PHP method.&lt;br /&gt;
         */&lt;br /&gt;
        &lt;br /&gt;
         setup: function( gamedatas )&lt;br /&gt;
         {&lt;br /&gt;
             &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;X = Object.assign(this, X);&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// This will allow you to use X.method instead of this.method inside modules/whatever.js&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// the rest of your setup goes here&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
         },&lt;br /&gt;
     });&lt;br /&gt;
 });&lt;br /&gt;
&lt;br /&gt;
And then, in your &amp;lt;code&amp;gt;modules/whatever.js&amp;lt;/code&amp;gt; file:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/whatever.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;X = Object.assign(X, {&#039;&#039;&#039;&lt;br /&gt;
   &#039;&#039;&#039;MY_CONSTANT: 1,&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
   &#039;&#039;&#039;myFunction: (arg1, arg2) =&amp;gt; {&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;X.someFunction(X.MY_CONSTANT);&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;return arg1 + arg2;&#039;&#039;&#039;&lt;br /&gt;
   &#039;&#039;&#039;},&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
   &#039;&#039;&#039;someFunction: (x) =&amp;gt; _(&#039;The answer is: &#039;) + x,&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;}&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notes on this approach:&lt;br /&gt;
*Aside from setup and any framework-override functions, you can use arrow functions&lt;br /&gt;
*Always use X instead of &amp;lt;tt&amp;gt;this&amp;lt;/tt&amp;gt;&lt;br /&gt;
*As usual, you can use any number of modules this way&lt;br /&gt;
&lt;br /&gt;
=== Write an AMD module ===&lt;br /&gt;
You can take advantage of the toolkit&#039;s module system to declare dependencies between the differents files you&#039;ll be writing (modules in the toolkit&#039;s language). To be identified as modules, your Javascript files will need to have the following structure:&lt;br /&gt;
&lt;br /&gt;
==== Create a named new class ====&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/js/FirstModule.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;gt;&#039;&#039;&#039;define([&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo&amp;quot;,&amp;lt;/span&amp;gt;      &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Needed if you want to be able to use dojo methods such as dojo.place, etc.&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo/_base/declare&amp;quot;,&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;other dependencies...&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;],function(dojo, declare){&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;return declare(&amp;quot;className&amp;quot;,&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/*Parent classes that this class inherits, optional*/&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, {&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;&#039;&#039;&#039;/* static properties */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;let property1 = &amp;quot;value;&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;let property2 = 5;&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;constructor: function (args) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;&#039;&#039;&#039;/* instance properties */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;let property3 = 8;&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;let property4 = [ &amp;quot;arrayValue&amp;quot;, &amp;quot;arrayValue2&amp;quot; ]; &#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;method1: function (args) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;/* your code here */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
         &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;});&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then in the X.js file, you can use your newly created module like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&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;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/js/Firstmodule&amp;quot;,&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
     ...&lt;br /&gt;
     });&lt;br /&gt;
 });&lt;br /&gt;
&lt;br /&gt;
In your code, you can access your module&#039;s class and methods by doing so:&lt;br /&gt;
&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;let object = new className();&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;object.method1();&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;...&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This can lead to namespace collisions if you don&#039;t choose a namespace correctly, so you might want to take the same approach as described earlier for the PHP files for using a namespace.&lt;br /&gt;
&lt;br /&gt;
==== Create an anonymous class ====&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/js/SecondModule.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;gt;&#039;&#039;&#039;define([&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo&amp;quot;,&amp;lt;/span&amp;gt;      &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Needed if you want to be able to use dojo methods such as dojo.place, etc.&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo/_base/declare&amp;quot;,&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;other dependencies...&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;],function(dojo, declare){&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;return declare(null,&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/*Parent classes that this class inherits, optional*/&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, {&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;&#039;&#039;&#039;/* static properties */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;let property1 = &amp;quot;value;&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;let property2 = 5;&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;constructor: function (args) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;&#039;&#039;&#039;/* instance properties */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;let property3 = 8;&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;let property4 = [ &amp;quot;arrayValue&amp;quot;, &amp;quot;arrayValue2&amp;quot; ]; &#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;method1: function (args) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;/* your code here */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
         &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;});&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then in the X.js file, you can use your newly created module like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&gt;
 &lt;br /&gt;
 define([&lt;br /&gt;
     &amp;quot;dojo&amp;quot;,&amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/js/SecondModule&amp;quot;,&#039;&#039;&#039;&amp;lt;/span&amp;gt;      &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//Has to be inserted in the third position as we&#039;ll&#039;&#039;&#039;&lt;br /&gt;
                                       &#039;&#039;&#039;//need an identifier later, and the other modules don&#039;t need it, see code in the preceding subsection.&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
     &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
 &lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, SecondModule&amp;lt;/span&amp;gt;  &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/* insert a reference here that you&#039;ll use throughout the JS file for this module */&amp;lt;/span&amp;gt;&#039;&#039;&#039;) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
     ...&lt;br /&gt;
     });&lt;br /&gt;
 });&lt;br /&gt;
&lt;br /&gt;
In your code, you can access your module&#039;s class and methods by doing so:&lt;br /&gt;
&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;let someValue = SecondModule.property3&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;SecondModule.method1();&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;...&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This can lead to namespace collisions if you don&#039;t choose a namespace correctly, so you might want to take the same approach as described earlier for the PHP files for using a namespace.&lt;br /&gt;
&lt;br /&gt;
==== Create a singleton object ====&lt;br /&gt;
&lt;br /&gt;
You can also create singleton objects by creating a module this way:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/js/singletonObject.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;define([&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo&amp;quot;,&amp;lt;/span&amp;gt;      &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Needed if you want to be able to use dojo methods such as dojo.place, etc.&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;], function (dojo) {&#039;&#039;&#039;&lt;br /&gt;
     &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;// Methods and variables defined in this part will not be available anywhere else than in this file&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;let privateVariable = &amp;quot;someValue&amp;quot;;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;let privateFunction = function (args) {&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//some code here&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;return {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;firstMethod: function (args) {&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;privateFunction(args);&#039;&#039;&#039;&lt;br /&gt;
             &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//some other code here&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;};&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To be used in the &amp;lt;code&amp;gt;X.js&amp;lt;/code&amp;gt; file, you must use the same method as in the [[#Create an anonymous class|previous section]]:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&gt;
 &lt;br /&gt;
 define([&lt;br /&gt;
     &amp;quot;dojo&amp;quot;,&amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&amp;quot;./modules/js/SecondModule&amp;quot;,&amp;lt;/span&amp;gt;         &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Has to be inserted in the third position as we&#039;ll need an identifier later, and the other modules don&#039;t need it&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&amp;quot;./modules/js/sigletonObject&amp;quot;,&amp;lt;/span&amp;gt;          &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//see code in the preceding subsection.&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
     &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/js/Firstmodule&amp;quot;,&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, SecondModule&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/* insert a reference here that you&#039;ll use throughout the JS file for this module */&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, singletonObject&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/* same here */&amp;lt;/span&amp;gt;&#039;&#039;&#039;) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
     ...&lt;br /&gt;
     });&lt;br /&gt;
 });&lt;br /&gt;
&lt;br /&gt;
Then you can access your code the same way as described in the [[#Create an anonymous class|previous section]]:&lt;br /&gt;
&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;singletonObject.firstMethod();&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;...&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Putting it all together ==&lt;br /&gt;
&#039;&#039;&#039;TODO&#039;&#039;&#039;&lt;/div&gt;</summary>
		<author><name>SwHawk</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=User:SwHawk/Create_Modular_Code&amp;diff=13597</id>
		<title>User:SwHawk/Create Modular Code</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=User:SwHawk/Create_Modular_Code&amp;diff=13597"/>
		<updated>2022-06-14T19:48:49Z</updated>

		<summary type="html">&lt;p&gt;SwHawk: /* Write plain javascript */ Added Mogri&amp;#039;s alternative&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{InfoBox|title=WIP|body=&#039;&#039;&#039;This article is a Work In Progress, please do not refer to it for production purposes&#039;&#039;&#039;}}&lt;br /&gt;
&lt;br /&gt;
This page will cover steps you can take as a BGA developer to make your code more modular and better organized. The way the framework is implemented makes the [[Main game logic: yourgamename.game.php|game logic]] and the [[Game interface logic: yourgamename.js|interface logic]] files very monolithic. While this is not a problem in itself, even simple to moderately complex game may require this files to be over 5k lines of code. Thus you can quickly become lost in all the functions you need to declare, where they are declared, and where they are called.&lt;br /&gt;
&lt;br /&gt;
But there are steps that you can follow to take advantage of PHP&#039;s Object Oriented Code and the dojo toolkit&#039;s AMD loader to organize your code in separate files. Let&#039;s see what&#039;s available:&lt;br /&gt;
&lt;br /&gt;
== Acknowledgements ==&lt;br /&gt;
&lt;br /&gt;
Writing this wiki article wouldn&#039;t have been possible without the help, work and insight of more experienced BGA developers:&lt;br /&gt;
* [https://boardgamearena.com/player?id=83846198 Tisaac]  (Discord user Tisaac Human Expert)&lt;br /&gt;
* [https://boardgamearena.com/player?id=85537631 bennygui] (Discord user bennygui)&lt;br /&gt;
* [https://boardgamearena.com/player?id=84125723 VictoriaLa] (Discord user VictoriaLa)&lt;br /&gt;
* Syarwin and [https://boardgamearena.com/player?id=84554161 quietmint] (for their Welcome To [https://github.com/Syarwin/bga-welcometo repository])&lt;br /&gt;
* [https://boardgamearena.com/player?id=84522426 Mogri] (Discord user Mogri)&lt;br /&gt;
&lt;br /&gt;
== Conventions ==&lt;br /&gt;
In the code blocks, code additions will be displayed in bold and green, and added comments will be displayed in bold and dark grey so that they stand out from the boilerplate code from a scratch project. Part in red should be aapted to reflect your project&#039;s structure.&lt;br /&gt;
&lt;br /&gt;
== On the PHP side ==&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt; vs &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; ===&lt;br /&gt;
Throughout this section, I&#039;ll make heavy use of PHP&#039;s &amp;lt;code&amp;gt;require_once&amp;lt;/code&amp;gt; control structure. Why am I using &amp;lt;code&amp;gt;require(_once)&amp;lt;/code&amp;gt; instead of &amp;lt;code&amp;gt;include_once&amp;lt;/code&amp;gt;? Because if an error exists in a PHP file that you try to &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt;, only a warning will be thrown, but the script will continue in spite of the error. Using &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; if the included file has an error, the script dies when the inclusion takes places, throwing a fatal error (&amp;lt;code&amp;gt;E_COMPILE_ERROR&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
That way, I&#039;m sure the classes, traits or interfaces I&#039;m including are syntax error free.&lt;br /&gt;
&lt;br /&gt;
=== Game logic methods ===&lt;br /&gt;
The way the framework is implemented, your game logic is gathered inside a class (&amp;lt;code&amp;gt;YourProjectName&amp;lt;/code&amp;gt;) extending the [[Table|&amp;lt;code&amp;gt;Table&amp;lt;/code&amp;gt; class]]. You define your methods there so that they may be called from other parts of the framework (as long as they&#039;re public methods obviously).&lt;br /&gt;
&lt;br /&gt;
But you can take advantage of [https://www.php.net/manual/en/language.oop5.traits.php PHP Traits]. In a nutshell, Traits are a collection of methods that can be reused in different classes, to avoid code duplication. Here we&#039;re not going to reuse them anywhere else than in the game class, but this little trick allows us to put methods definitions in other files, and in so doing to avoid monolithic code.&lt;br /&gt;
&lt;br /&gt;
Basically you create a Trait in th &amp;lt;code&amp;gt;/modules/&amp;lt;/code&amp;gt; directory, for instance:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/UtiltityFunctionsTrait.php]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;lt;?php&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;namespace YourProjectNamespace\Modules;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;trait UtilityFunctionsTrait {&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &#039;&#039;&#039;public function myFirstUtilityFunction($args)&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;{&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//Your code here&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;}&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Then you can include it in you project&#039;s &amp;lt;code&amp;gt;X.game.php&amp;lt;/code&amp;gt; file like so:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X_game.php]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;?php&lt;br /&gt;
  /**&lt;br /&gt;
   *------&lt;br /&gt;
   * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
   * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
   * &lt;br /&gt;
   * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
   * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
   * -----&lt;br /&gt;
   * &lt;br /&gt;
   * X.game.php&lt;br /&gt;
   *&lt;br /&gt;
   * This is the main file for your game logic.&lt;br /&gt;
   *&lt;br /&gt;
   * In this PHP file, you are going to defines the rules of the game.&lt;br /&gt;
   *&lt;br /&gt;
   */&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;require_once &#039;modules/UtilityFunctionsTrait.php&#039;; &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;   //Here we require the trait to be loaded when the class is loaded&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;use X\Modules\UtilityFunctionsTrait;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;                 //We import the trait to be used directly as UtilityFunctionsTraits,&#039;&#039;&#039;&lt;br /&gt;
                                                      &#039;&#039;&#039;//otherwise we would have to use the Fully qualified class name&#039;&#039;&#039;&lt;br /&gt;
                                                      &#039;&#039;&#039;//(YourProjectNamespace\Modules\UtilityFunctionsTrait)&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 class X extends Table&lt;br /&gt;
 {&lt;br /&gt;
 //...&lt;br /&gt;
 &lt;br /&gt;
 //////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
 //////////// Utility functions&lt;br /&gt;
 ////////////    &lt;br /&gt;
 &lt;br /&gt;
     /*&lt;br /&gt;
         In this space, you can put any utility methods useful for your game logic&lt;br /&gt;
     */&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;use UtilityFunctionsTrait;&#039;&#039;&#039;&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//Here we actually include the trait inside the class, making all the trait&#039;s methods&#039;&#039;&#039; &lt;br /&gt;
                                &#039;&#039;&#039;//available as class methods, keeping their visibility scope (so a private method&#039;&#039;&#039;&lt;br /&gt;
                                &#039;&#039;&#039;//is still private)&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Support classes ===&lt;br /&gt;
Basically, the same as traits, you put your classes definitions into files that live under the &amp;lt;code&amp;gt;/modules/&amp;lt;/code&amp;gt; directory (don&#039;t forget to namespace your classes), and then require them at the top of &amp;lt;code&amp;gt;X_game.php&amp;lt;/code&amp;gt;, and voilà, you&#039;re done&lt;br /&gt;
&lt;br /&gt;
=== Adding autoloader support ===&lt;br /&gt;
&lt;br /&gt;
==== Coding standards ====&lt;br /&gt;
Even for simple games, you might end up having a dozen of traits and support classes. You can require them all in your &amp;lt;code&amp;gt;X_game.php&amp;lt;/code&amp;gt;. Or you can use an autoloader, which will load the necessary classes and traits at runtime. There are two PSRs dealing with autloading standards (namely [https://www.php-fig.org/psr/psr-0 PSR-0] which is marked as deprecated and [https://www.php-fig.org/psr/psr-4 PSR-4]) which state that your namespaces should be a reflection of the directory structure of your project.&lt;br /&gt;
&lt;br /&gt;
Basically, when creating namespaces, you choose a namespace prefix. For example, you could use your BGA handle and the project name as a namespace prefix (would result in &amp;lt;code&amp;gt;\SwHawk\X&amp;lt;/code&amp;gt; in my case), and then the rest of the namespace would be the directory the file is in. I usually group classes and traits by the function they have in my project, so my &amp;lt;code&amp;gt;/modules/&amp;lt;/code&amp;gt; directory looks like that:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
modules/&lt;br /&gt;
    php/&lt;br /&gt;
        Factory/                      //Holds my factory classes&lt;br /&gt;
            AFactoryClass.php         //The namespace for this file would be \SwHawk\X\Factory, and the fully qualified class name would be \SwHawk\X\Factory\AFactoryClass&lt;br /&gt;
            ...&lt;br /&gt;
        Object/                       //Holds my support classes&lt;br /&gt;
            ObjectA.php               //The namespace for this file would be \SwHawk\X\Object, and the fully qualified class name would be \SwHawk\X\Object\ObjectA&lt;br /&gt;
            ...&lt;br /&gt;
        Traits/                       //Holds my traits&lt;br /&gt;
            UtilityFunctionsTrait.php //The namespace for this file would be \SwHawk\X\Traits, and the fully qualified class name would be \SwHawk\X\Traits\UtilityFunctionsTrait&lt;br /&gt;
            ...&lt;br /&gt;
        ...&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Autoloader function for development ====&lt;br /&gt;
While your project is under development, you usually create, move and remove classes as part of the development process. So you usually need an autoloading function that can handle a lot of flexibility. Basically once you import a class using the &amp;lt;code&amp;gt;use&amp;lt;/code&amp;gt; keyword, the autoloading function will determine which file to &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; using its fully qualified class name, and then &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt;. This function needs to be either defined or included at the top of &amp;lt;code&amp;gt;X_game.php&amp;lt;/code&amp;gt;. Such a function would have the following code (borrowed and adapted from [https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader-examples.md this repository]):&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;spl_autoload_register(function ($class) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// project-specific namespace prefix&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;, adapt to your needs&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;, remember that you must escape \ characters in double-quoted strings (hence the \\)&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$prefix = &#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;SwHawk\\X\\&amp;quot;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// base directory for the namespace prefix, this file would usually reside in the modules/php/includes/ directory, so the base directory for all my classes would be a level higher&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$base_dir = __DIR__ . &#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;&#039;&#039;&#039; &#039;/../&#039; &#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;gt;&#039;&#039;&#039;;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// does the class use the namespace prefix?&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$len = strlen($prefix);&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;if (strncmp($prefix, $class, $len) !== 0) {&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// no, move to the next registered autoloader&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;return;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// get the relative class name&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$relative_class = substr($class, $len);&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;// replace the namespace prefix with the base directory, replace namespace&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;// separators with directory separators in the relative class name, append&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;// with .php&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$file = $base_dir . str_replace(&#039;\\&#039;, &#039;/&#039;, $relative_class) . &#039;.php&#039;;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// if the file exists, require it&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;if (file_exists($file)) {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;require $file;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Autoloader function for production ====&lt;br /&gt;
Once you&#039;re moving your game to production, the autoloader function provided before isn&#039;t optimized. Once in production, the directory tree should not be modified, so you can change the earlier autoloader to a classmap based one. Basically, you build an associative array with the fully qualified classes names as keys and the filepath as the value. An example would look like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;spl_autoload_register(function ($class) {&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;static $classmap = array(&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:red&amp;gt;&amp;quot;SwHawk\\X\\&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;Factory\\AFactoryClass&amp;quot; =&amp;gt; __DIR__ . &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;&amp;quot;/../&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;Factory/AFactoryClass.php&amp;quot;,&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;);&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;if(array_key_exists($class)) {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;require $classmap[$class];&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;} else {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;return;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This autoloader is better suited to production since it won&#039;t use expensive calls like &amp;lt;code&amp;gt;file_exists($filename)&amp;lt;/code&amp;gt;. You can write the classmap by yourself, but it can be quite cumbersome, there is some tools like [https://github.com/hanneskod/classtools this project], or [https://github.com/gnugat/nomo-spaco this one], or even scripts detailed in this [https://stackoverflow.com/questions/22761554/how-to-get-all-class-names-inside-a-particular-namespace StackOverflow topic]&lt;br /&gt;
&lt;br /&gt;
== On the JS side ==&lt;br /&gt;
&lt;br /&gt;
BGA uses the dojo toolkit framework for most of its javascript code. Dojo comes with its own way of loading modules, which you can read about in more detail [https://dojotoolkit.org/documentation/tutorials/1.10/modules/ here] and [https://dojotoolkit.org/documentation/tutorials/1.10/modules_advanced/ here]. To put it simply, there are two ways you can go about this&lt;br /&gt;
&lt;br /&gt;
=== Write plain javascript ===&lt;br /&gt;
&lt;br /&gt;
==== Relying on the dojo toolkit ====&lt;br /&gt;
Should you wan to write plain javascript, you can easily do so. What you need to do is actually load the file like so in &amp;lt;code&amp;gt;X.js&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&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;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&amp;quot;./modules/path/to/firstfile.js&amp;quot;,&amp;lt;/span&amp;gt;        &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;//The first file with your JS code&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&amp;quot;./modules/path/to/secondfile.js&amp;quot;,&amp;lt;/span&amp;gt;       &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;//The second file with another part of your JS code&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
     ...&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
         constructor: function(){&lt;br /&gt;
             ...&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
According to the dojo toolkit documentation, you will then need to directly access what you defined in the files.&lt;br /&gt;
&lt;br /&gt;
==== Alternative method ====&lt;br /&gt;
&lt;br /&gt;
This section has mostly been written by [[User:Mogri|Mogri]].&lt;br /&gt;
&lt;br /&gt;
This approach lets you avoid Dojo and &amp;lt;tt&amp;gt;this&amp;lt;/tt&amp;gt; and allows more modern JS.&lt;br /&gt;
&lt;br /&gt;
First, you&#039;ll need to a a statement at the beginning of the &amp;lt;code&amp;gt;X.js&amp;lt;/code&amp;gt; file:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
 *------&lt;br /&gt;
 * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
 * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
 *&lt;br /&gt;
 * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
 * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
 * -----&lt;br /&gt;
 *&lt;br /&gt;
 * X.js&lt;br /&gt;
 *&lt;br /&gt;
 * X user interface script&lt;br /&gt;
 * &lt;br /&gt;
 * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&gt;
 &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;window.X = {};&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// X = your game, or you can use something more generic&amp;lt;/span&amp;gt;&#039;&#039;&#039;&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;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/whatever.js&amp;quot;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.progressevolutiontechnologyswh&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
         constructor: function(){&lt;br /&gt;
             console.log(&#039;progressevolutiontechnologyswh constructor&#039;);&lt;br /&gt;
               &lt;br /&gt;
             // Here, you can init the global variables of your user interface&lt;br /&gt;
             // Example:&lt;br /&gt;
             // this.myGlobalValue = 0;&lt;br /&gt;
 &lt;br /&gt;
         },&lt;br /&gt;
         &lt;br /&gt;
         /*&lt;br /&gt;
             setup:&lt;br /&gt;
             &lt;br /&gt;
             This method must set up the game user interface according to current game situation specified&lt;br /&gt;
             in parameters.&lt;br /&gt;
             &lt;br /&gt;
             The method is called each time the game interface is displayed to a player, ie:&lt;br /&gt;
             _ when the game starts&lt;br /&gt;
             _ when a player refreshes the game page (F5)&lt;br /&gt;
             &lt;br /&gt;
             &amp;quot;gamedatas&amp;quot; argument contains all datas retrieved by your &amp;quot;getAllDatas&amp;quot; PHP method.&lt;br /&gt;
         */&lt;br /&gt;
        &lt;br /&gt;
         setup: function( gamedatas )&lt;br /&gt;
         {&lt;br /&gt;
             &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;X = Object.assign(this, X);&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// This will allow you to use X.method instead of this.method inside modules/whatever.js&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// the rest of your setup goes here&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
         },&lt;br /&gt;
     });&lt;br /&gt;
 });&lt;br /&gt;
&lt;br /&gt;
And then, in your &amp;lt;code&amp;gt;modules/whatever.js&amp;lt;/code&amp;gt; file:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/whatever.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;X = Object.assign(X, {&#039;&#039;&#039;&lt;br /&gt;
   &#039;&#039;&#039;MY_CONSTANT: 1,&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
   &#039;&#039;&#039;myFunction: (arg1, arg2) =&amp;gt; {&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;X.someFunction(X.MY_CONSTANT);&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;return arg1 + arg2;&#039;&#039;&#039;&lt;br /&gt;
   &#039;&#039;&#039;},&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
   &#039;&#039;&#039;someFunction: (x) =&amp;gt; _(&#039;The answer is: &#039;) + x,&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;}&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notes on this approach:&lt;br /&gt;
*Aside from setup and any framework-override functions, you can use arrow functions&lt;br /&gt;
*Always use X instead of &amp;lt;tt&amp;gt;this&amp;lt;/tt&amp;gt;&lt;br /&gt;
*As usual, you can use any number of modules this way&lt;br /&gt;
&lt;br /&gt;
=== Write an AMD module ===&lt;br /&gt;
You can take advantage of the toolkit&#039;s module system to declare dependencies between the differents files you&#039;ll be writing (modules in the toolkit&#039;s language). To be identified as modules, your Javascript files will need to have the following structure:&lt;br /&gt;
&lt;br /&gt;
==== Create a named new class ====&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/js/FirstModule.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;gt;&#039;&#039;&#039;define([&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo&amp;quot;,&amp;lt;/span&amp;gt;      &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Needed if you want to be able to use dojo methods such as dojo.place, etc.&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo/_base/declare&amp;quot;,&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;other dependencies...&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;],function(dojo, declare){&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;return declare(&amp;quot;className&amp;quot;,&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/*Parent classes that this class inherits, optional*/&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, {&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;&#039;&#039;&#039;/* static properties */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;let property1 = &amp;quot;value;&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;let property2 = 5;&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;constructor: function (args) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;&#039;&#039;&#039;/* instance properties */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;let property3 = 8;&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;let property4 = [ &amp;quot;arrayValue&amp;quot;, &amp;quot;arrayValue2&amp;quot; ]; &#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;method1: function (args) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;/* your code here */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
         &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;});&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then in the X.js file, you can use your newly created module like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&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;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/js/Firstmodule&amp;quot;,&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
     ...&lt;br /&gt;
     });&lt;br /&gt;
 });&lt;br /&gt;
&lt;br /&gt;
In your code, you can access your module&#039;s class and methods by doing so:&lt;br /&gt;
&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;let object = new className();&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;object.method1();&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;...&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This can lead to namespace collisions if you don&#039;t choose a namespace correctly, so you might want to take the same approach as described earlier for the PHP files for using a namespace.&lt;br /&gt;
&lt;br /&gt;
==== Create an anonymous class ====&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/js/SecondModule.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;gt;&#039;&#039;&#039;define([&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo&amp;quot;,&amp;lt;/span&amp;gt;      &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Needed if you want to be able to use dojo methods such as dojo.place, etc.&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo/_base/declare&amp;quot;,&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;other dependencies...&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;],function(dojo, declare){&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;return declare(null,&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/*Parent classes that this class inherits, optional*/&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, {&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;&#039;&#039;&#039;/* static properties */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;let property1 = &amp;quot;value;&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;let property2 = 5;&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;constructor: function (args) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;&#039;&#039;&#039;/* instance properties */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;let property3 = 8;&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;let property4 = [ &amp;quot;arrayValue&amp;quot;, &amp;quot;arrayValue2&amp;quot; ]; &#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;method1: function (args) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;/* your code here */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
         &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;});&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then in the X.js file, you can use your newly created module like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&gt;
 &lt;br /&gt;
 define([&lt;br /&gt;
     &amp;quot;dojo&amp;quot;,&amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/js/SecondModule&amp;quot;,&#039;&#039;&#039;&amp;lt;/span&amp;gt;      &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//Has to be inserted in the third position as we&#039;ll&#039;&#039;&#039;&lt;br /&gt;
                                       &#039;&#039;&#039;//need an identifier later, and the other modules don&#039;t need it, see code in the preceding subsection.&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
     &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
 &lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, SecondModule&amp;lt;/span&amp;gt;  &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/* insert a reference here that you&#039;ll use throughout the JS file for this module */&amp;lt;/span&amp;gt;&#039;&#039;&#039;) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
     ...&lt;br /&gt;
     });&lt;br /&gt;
 });&lt;br /&gt;
&lt;br /&gt;
In your code, you can access your module&#039;s class and methods by doing so:&lt;br /&gt;
&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;let someValue = SecondModule.property3&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;SecondModule.method1();&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;...&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This can lead to namespace collisions if you don&#039;t choose a namespace correctly, so you might want to take the same approach as described earlier for the PHP files for using a namespace.&lt;br /&gt;
&lt;br /&gt;
==== Create a singleton object ====&lt;br /&gt;
&lt;br /&gt;
You can also create singleton objects by creating a module this way:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/js/singletonObject.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;define([&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo&amp;quot;,&amp;lt;/span&amp;gt;      &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Needed if you want to be able to use dojo methods such as dojo.place, etc.&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;], function (dojo) {&#039;&#039;&#039;&lt;br /&gt;
     &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;// Methods and variables defined in this part will not be available anywhere else than in this file&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;let privateVariable = &amp;quot;someValue&amp;quot;;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;let privateFunction = function (args) {&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//some code here&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;return {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;firstMethod: function (args) {&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;privateFunction(args);&#039;&#039;&#039;&lt;br /&gt;
             &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//some other code here&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;};&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To be used in the &amp;lt;code&amp;gt;X.js&amp;lt;/code&amp;gt; file, you must use the same method as in the [[#Create an anonymous class|previous section]]:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&gt;
 &lt;br /&gt;
 define([&lt;br /&gt;
     &amp;quot;dojo&amp;quot;,&amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&amp;quot;./modules/js/SecondModule&amp;quot;,&amp;lt;/span&amp;gt;         &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Has to be inserted in the third position as we&#039;ll need an identifier later, and the other modules don&#039;t need it&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&amp;quot;./modules/js/sigletonObject&amp;quot;,&amp;lt;/span&amp;gt;          &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//see code in the preceding subsection.&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
     &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/js/Firstmodule&amp;quot;,&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, SecondModule&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/* insert a reference here that you&#039;ll use throughout the JS file for this module */&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, singletonObject&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/* same here */&amp;lt;/span&amp;gt;&#039;&#039;&#039;) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
     ...&lt;br /&gt;
     });&lt;br /&gt;
 });&lt;br /&gt;
&lt;br /&gt;
Then you can access your code the same way as described in the [[#Create an anonymous class|previous section]]:&lt;br /&gt;
&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;singletonObject.firstMethod();&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;...&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Putting it all together ==&lt;br /&gt;
&#039;&#039;&#039;TODO&#039;&#039;&#039;&lt;/div&gt;</summary>
		<author><name>SwHawk</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=User:SwHawk/Create_Modular_Code&amp;diff=13596</id>
		<title>User:SwHawk/Create Modular Code</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=User:SwHawk/Create_Modular_Code&amp;diff=13596"/>
		<updated>2022-06-14T19:21:24Z</updated>

		<summary type="html">&lt;p&gt;SwHawk: /* Create an anonymous class */ fixed typo&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{InfoBox|title=WIP|body=&#039;&#039;&#039;This article is a Work In Progress, please do not refer to it for production purposes&#039;&#039;&#039;}}&lt;br /&gt;
&lt;br /&gt;
This page will cover steps you can take as a BGA developer to make your code more modular and better organized. The way the framework is implemented makes the [[Main game logic: yourgamename.game.php|game logic]] and the [[Game interface logic: yourgamename.js|interface logic]] files very monolithic. While this is not a problem in itself, even simple to moderately complex game may require this files to be over 5k lines of code. Thus you can quickly become lost in all the functions you need to declare, where they are declared, and where they are called.&lt;br /&gt;
&lt;br /&gt;
But there are steps that you can follow to take advantage of PHP&#039;s Object Oriented Code and the dojo toolkit&#039;s AMD loader to organize your code in separate files. Let&#039;s see what&#039;s available:&lt;br /&gt;
&lt;br /&gt;
== Acknowledgements ==&lt;br /&gt;
&lt;br /&gt;
Writing this wiki article wouldn&#039;t have been possible without the help, work and insight of more experienced BGA developers:&lt;br /&gt;
* [https://boardgamearena.com/player?id=83846198 Tisaac]  (Discord user Tisaac Human Expert)&lt;br /&gt;
* [https://boardgamearena.com/player?id=85537631 bennygui] (Discord user bennygui)&lt;br /&gt;
* [https://boardgamearena.com/player?id=84125723 VictoriaLa] (Discord user VictoriaLa)&lt;br /&gt;
* Syarwin and [https://boardgamearena.com/player?id=84554161 quietmint] (for their Welcome To [https://github.com/Syarwin/bga-welcometo repository])&lt;br /&gt;
* [https://boardgamearena.com/player?id=84522426 Mogri] (Discord user Mogri)&lt;br /&gt;
&lt;br /&gt;
== Conventions ==&lt;br /&gt;
In the code blocks, code additions will be displayed in bold and green, and added comments will be displayed in bold and dark grey so that they stand out from the boilerplate code from a scratch project. Part in red should be aapted to reflect your project&#039;s structure.&lt;br /&gt;
&lt;br /&gt;
== On the PHP side ==&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt; vs &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; ===&lt;br /&gt;
Throughout this section, I&#039;ll make heavy use of PHP&#039;s &amp;lt;code&amp;gt;require_once&amp;lt;/code&amp;gt; control structure. Why am I using &amp;lt;code&amp;gt;require(_once)&amp;lt;/code&amp;gt; instead of &amp;lt;code&amp;gt;include_once&amp;lt;/code&amp;gt;? Because if an error exists in a PHP file that you try to &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt;, only a warning will be thrown, but the script will continue in spite of the error. Using &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; if the included file has an error, the script dies when the inclusion takes places, throwing a fatal error (&amp;lt;code&amp;gt;E_COMPILE_ERROR&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
That way, I&#039;m sure the classes, traits or interfaces I&#039;m including are syntax error free.&lt;br /&gt;
&lt;br /&gt;
=== Game logic methods ===&lt;br /&gt;
The way the framework is implemented, your game logic is gathered inside a class (&amp;lt;code&amp;gt;YourProjectName&amp;lt;/code&amp;gt;) extending the [[Table|&amp;lt;code&amp;gt;Table&amp;lt;/code&amp;gt; class]]. You define your methods there so that they may be called from other parts of the framework (as long as they&#039;re public methods obviously).&lt;br /&gt;
&lt;br /&gt;
But you can take advantage of [https://www.php.net/manual/en/language.oop5.traits.php PHP Traits]. In a nutshell, Traits are a collection of methods that can be reused in different classes, to avoid code duplication. Here we&#039;re not going to reuse them anywhere else than in the game class, but this little trick allows us to put methods definitions in other files, and in so doing to avoid monolithic code.&lt;br /&gt;
&lt;br /&gt;
Basically you create a Trait in th &amp;lt;code&amp;gt;/modules/&amp;lt;/code&amp;gt; directory, for instance:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/UtiltityFunctionsTrait.php]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;lt;?php&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;namespace YourProjectNamespace\Modules;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;trait UtilityFunctionsTrait {&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &#039;&#039;&#039;public function myFirstUtilityFunction($args)&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;{&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//Your code here&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;}&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Then you can include it in you project&#039;s &amp;lt;code&amp;gt;X.game.php&amp;lt;/code&amp;gt; file like so:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X_game.php]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;?php&lt;br /&gt;
  /**&lt;br /&gt;
   *------&lt;br /&gt;
   * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
   * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
   * &lt;br /&gt;
   * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
   * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
   * -----&lt;br /&gt;
   * &lt;br /&gt;
   * X.game.php&lt;br /&gt;
   *&lt;br /&gt;
   * This is the main file for your game logic.&lt;br /&gt;
   *&lt;br /&gt;
   * In this PHP file, you are going to defines the rules of the game.&lt;br /&gt;
   *&lt;br /&gt;
   */&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;require_once &#039;modules/UtilityFunctionsTrait.php&#039;; &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;   //Here we require the trait to be loaded when the class is loaded&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;use X\Modules\UtilityFunctionsTrait;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;                 //We import the trait to be used directly as UtilityFunctionsTraits,&#039;&#039;&#039;&lt;br /&gt;
                                                      &#039;&#039;&#039;//otherwise we would have to use the Fully qualified class name&#039;&#039;&#039;&lt;br /&gt;
                                                      &#039;&#039;&#039;//(YourProjectNamespace\Modules\UtilityFunctionsTrait)&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 class X extends Table&lt;br /&gt;
 {&lt;br /&gt;
 //...&lt;br /&gt;
 &lt;br /&gt;
 //////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
 //////////// Utility functions&lt;br /&gt;
 ////////////    &lt;br /&gt;
 &lt;br /&gt;
     /*&lt;br /&gt;
         In this space, you can put any utility methods useful for your game logic&lt;br /&gt;
     */&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;use UtilityFunctionsTrait;&#039;&#039;&#039;&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//Here we actually include the trait inside the class, making all the trait&#039;s methods&#039;&#039;&#039; &lt;br /&gt;
                                &#039;&#039;&#039;//available as class methods, keeping their visibility scope (so a private method&#039;&#039;&#039;&lt;br /&gt;
                                &#039;&#039;&#039;//is still private)&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Support classes ===&lt;br /&gt;
Basically, the same as traits, you put your classes definitions into files that live under the &amp;lt;code&amp;gt;/modules/&amp;lt;/code&amp;gt; directory (don&#039;t forget to namespace your classes), and then require them at the top of &amp;lt;code&amp;gt;X_game.php&amp;lt;/code&amp;gt;, and voilà, you&#039;re done&lt;br /&gt;
&lt;br /&gt;
=== Adding autoloader support ===&lt;br /&gt;
&lt;br /&gt;
==== Coding standards ====&lt;br /&gt;
Even for simple games, you might end up having a dozen of traits and support classes. You can require them all in your &amp;lt;code&amp;gt;X_game.php&amp;lt;/code&amp;gt;. Or you can use an autoloader, which will load the necessary classes and traits at runtime. There are two PSRs dealing with autloading standards (namely [https://www.php-fig.org/psr/psr-0 PSR-0] which is marked as deprecated and [https://www.php-fig.org/psr/psr-4 PSR-4]) which state that your namespaces should be a reflection of the directory structure of your project.&lt;br /&gt;
&lt;br /&gt;
Basically, when creating namespaces, you choose a namespace prefix. For example, you could use your BGA handle and the project name as a namespace prefix (would result in &amp;lt;code&amp;gt;\SwHawk\X&amp;lt;/code&amp;gt; in my case), and then the rest of the namespace would be the directory the file is in. I usually group classes and traits by the function they have in my project, so my &amp;lt;code&amp;gt;/modules/&amp;lt;/code&amp;gt; directory looks like that:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
modules/&lt;br /&gt;
    php/&lt;br /&gt;
        Factory/                      //Holds my factory classes&lt;br /&gt;
            AFactoryClass.php         //The namespace for this file would be \SwHawk\X\Factory, and the fully qualified class name would be \SwHawk\X\Factory\AFactoryClass&lt;br /&gt;
            ...&lt;br /&gt;
        Object/                       //Holds my support classes&lt;br /&gt;
            ObjectA.php               //The namespace for this file would be \SwHawk\X\Object, and the fully qualified class name would be \SwHawk\X\Object\ObjectA&lt;br /&gt;
            ...&lt;br /&gt;
        Traits/                       //Holds my traits&lt;br /&gt;
            UtilityFunctionsTrait.php //The namespace for this file would be \SwHawk\X\Traits, and the fully qualified class name would be \SwHawk\X\Traits\UtilityFunctionsTrait&lt;br /&gt;
            ...&lt;br /&gt;
        ...&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Autoloader function for development ====&lt;br /&gt;
While your project is under development, you usually create, move and remove classes as part of the development process. So you usually need an autoloading function that can handle a lot of flexibility. Basically once you import a class using the &amp;lt;code&amp;gt;use&amp;lt;/code&amp;gt; keyword, the autoloading function will determine which file to &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; using its fully qualified class name, and then &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt;. This function needs to be either defined or included at the top of &amp;lt;code&amp;gt;X_game.php&amp;lt;/code&amp;gt;. Such a function would have the following code (borrowed and adapted from [https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader-examples.md this repository]):&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;spl_autoload_register(function ($class) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// project-specific namespace prefix&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;, adapt to your needs&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;, remember that you must escape \ characters in double-quoted strings (hence the \\)&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$prefix = &#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;SwHawk\\X\\&amp;quot;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// base directory for the namespace prefix, this file would usually reside in the modules/php/includes/ directory, so the base directory for all my classes would be a level higher&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$base_dir = __DIR__ . &#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;&#039;&#039;&#039; &#039;/../&#039; &#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;gt;&#039;&#039;&#039;;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// does the class use the namespace prefix?&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$len = strlen($prefix);&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;if (strncmp($prefix, $class, $len) !== 0) {&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// no, move to the next registered autoloader&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;return;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// get the relative class name&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$relative_class = substr($class, $len);&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;// replace the namespace prefix with the base directory, replace namespace&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;// separators with directory separators in the relative class name, append&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;// with .php&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$file = $base_dir . str_replace(&#039;\\&#039;, &#039;/&#039;, $relative_class) . &#039;.php&#039;;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// if the file exists, require it&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;if (file_exists($file)) {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;require $file;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Autoloader function for production ====&lt;br /&gt;
Once you&#039;re moving your game to production, the autoloader function provided before isn&#039;t optimized. Once in production, the directory tree should not be modified, so you can change the earlier autoloader to a classmap based one. Basically, you build an associative array with the fully qualified classes names as keys and the filepath as the value. An example would look like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;spl_autoload_register(function ($class) {&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;static $classmap = array(&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:red&amp;gt;&amp;quot;SwHawk\\X\\&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;Factory\\AFactoryClass&amp;quot; =&amp;gt; __DIR__ . &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;&amp;quot;/../&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;Factory/AFactoryClass.php&amp;quot;,&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;);&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;if(array_key_exists($class)) {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;require $classmap[$class];&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;} else {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;return;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This autoloader is better suited to production since it won&#039;t use expensive calls like &amp;lt;code&amp;gt;file_exists($filename)&amp;lt;/code&amp;gt;. You can write the classmap by yourself, but it can be quite cumbersome, there is some tools like [https://github.com/hanneskod/classtools this project], or [https://github.com/gnugat/nomo-spaco this one], or even scripts detailed in this [https://stackoverflow.com/questions/22761554/how-to-get-all-class-names-inside-a-particular-namespace StackOverflow topic]&lt;br /&gt;
&lt;br /&gt;
== On the JS side ==&lt;br /&gt;
&lt;br /&gt;
BGA uses the dojo toolkit framework for most of its javascript code. Dojo comes with its own way of loading modules, which you can read about in more detail [https://dojotoolkit.org/documentation/tutorials/1.10/modules/ here] and [https://dojotoolkit.org/documentation/tutorials/1.10/modules_advanced/ here]. To put it simply, there are two ways you can go about this&lt;br /&gt;
&lt;br /&gt;
=== Write plain javascript ===&lt;br /&gt;
Should you wan to write plain javascript, you can easily do so. What you need to do is actually load the file like so in &amp;lt;code&amp;gt;X.js&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&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;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&amp;quot;./modules/path/to/firstfile.js&amp;quot;,&amp;lt;/span&amp;gt;        &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;//The first file with your JS code&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&amp;quot;./modules/path/to/secondfile.js&amp;quot;,&amp;lt;/span&amp;gt;       &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;//The second file with another part of your JS code&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
     ...&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
         constructor: function(){&lt;br /&gt;
             ...&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
According to the dojo toolkit documentation, you will then need to directly access what you defined in the files.&lt;br /&gt;
&lt;br /&gt;
=== Write an AMD module ===&lt;br /&gt;
You can take advantage of the toolkit&#039;s module system to declare dependencies between the differents files you&#039;ll be writing (modules in the toolkit&#039;s language). To be identified as modules, your Javascript files will need to have the following structure:&lt;br /&gt;
&lt;br /&gt;
==== Create a named new class ====&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/js/FirstModule.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;gt;&#039;&#039;&#039;define([&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo&amp;quot;,&amp;lt;/span&amp;gt;      &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Needed if you want to be able to use dojo methods such as dojo.place, etc.&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo/_base/declare&amp;quot;,&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;other dependencies...&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;],function(dojo, declare){&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;return declare(&amp;quot;className&amp;quot;,&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/*Parent classes that this class inherits, optional*/&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, {&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;&#039;&#039;&#039;/* static properties */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;let property1 = &amp;quot;value;&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;let property2 = 5;&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;constructor: function (args) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;&#039;&#039;&#039;/* instance properties */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;let property3 = 8;&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;let property4 = [ &amp;quot;arrayValue&amp;quot;, &amp;quot;arrayValue2&amp;quot; ]; &#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;method1: function (args) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;/* your code here */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
         &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;});&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then in the X.js file, you can use your newly created module like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&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;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/js/Firstmodule&amp;quot;,&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
     ...&lt;br /&gt;
     });&lt;br /&gt;
 });&lt;br /&gt;
&lt;br /&gt;
In your code, you can access your module&#039;s class and methods by doing so:&lt;br /&gt;
&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;let object = new className();&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;object.method1();&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;...&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This can lead to namespace collisions if you don&#039;t choose a namespace correctly, so you might want to take the same approach as described earlier for the PHP files for using a namespace.&lt;br /&gt;
&lt;br /&gt;
==== Create an anonymous class ====&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/js/SecondModule.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;gt;&#039;&#039;&#039;define([&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo&amp;quot;,&amp;lt;/span&amp;gt;      &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Needed if you want to be able to use dojo methods such as dojo.place, etc.&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo/_base/declare&amp;quot;,&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;other dependencies...&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;],function(dojo, declare){&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;return declare(null,&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/*Parent classes that this class inherits, optional*/&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, {&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;&#039;&#039;&#039;/* static properties */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;let property1 = &amp;quot;value;&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;let property2 = 5;&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;constructor: function (args) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;&#039;&#039;&#039;/* instance properties */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;let property3 = 8;&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;let property4 = [ &amp;quot;arrayValue&amp;quot;, &amp;quot;arrayValue2&amp;quot; ]; &#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;method1: function (args) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;/* your code here */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
         &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;});&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then in the X.js file, you can use your newly created module like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&gt;
 &lt;br /&gt;
 define([&lt;br /&gt;
     &amp;quot;dojo&amp;quot;,&amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/js/SecondModule&amp;quot;,&#039;&#039;&#039;&amp;lt;/span&amp;gt;      &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//Has to be inserted in the third position as we&#039;ll&#039;&#039;&#039;&lt;br /&gt;
                                       &#039;&#039;&#039;//need an identifier later, and the other modules don&#039;t need it, see code in the preceding subsection.&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
     &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
 &lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, SecondModule&amp;lt;/span&amp;gt;  &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/* insert a reference here that you&#039;ll use throughout the JS file for this module */&amp;lt;/span&amp;gt;&#039;&#039;&#039;) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
     ...&lt;br /&gt;
     });&lt;br /&gt;
 });&lt;br /&gt;
&lt;br /&gt;
In your code, you can access your module&#039;s class and methods by doing so:&lt;br /&gt;
&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;let someValue = SecondModule.property3&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;SecondModule.method1();&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;...&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This can lead to namespace collisions if you don&#039;t choose a namespace correctly, so you might want to take the same approach as described earlier for the PHP files for using a namespace.&lt;br /&gt;
&lt;br /&gt;
==== Create a singleton object ====&lt;br /&gt;
&lt;br /&gt;
You can also create singleton objects by creating a module this way:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/js/singletonObject.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;define([&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo&amp;quot;,&amp;lt;/span&amp;gt;      &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Needed if you want to be able to use dojo methods such as dojo.place, etc.&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;], function (dojo) {&#039;&#039;&#039;&lt;br /&gt;
     &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;// Methods and variables defined in this part will not be available anywhere else than in this file&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;let privateVariable = &amp;quot;someValue&amp;quot;;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;let privateFunction = function (args) {&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//some code here&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;return {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;firstMethod: function (args) {&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;privateFunction(args);&#039;&#039;&#039;&lt;br /&gt;
             &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//some other code here&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;};&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To be used in the &amp;lt;code&amp;gt;X.js&amp;lt;/code&amp;gt; file, you must use the same method as in the [[#Create an anonymous class|previous section]]:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&gt;
 &lt;br /&gt;
 define([&lt;br /&gt;
     &amp;quot;dojo&amp;quot;,&amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&amp;quot;./modules/js/SecondModule&amp;quot;,&amp;lt;/span&amp;gt;         &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Has to be inserted in the third position as we&#039;ll need an identifier later, and the other modules don&#039;t need it&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&amp;quot;./modules/js/sigletonObject&amp;quot;,&amp;lt;/span&amp;gt;          &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//see code in the preceding subsection.&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
     &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/js/Firstmodule&amp;quot;,&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, SecondModule&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/* insert a reference here that you&#039;ll use throughout the JS file for this module */&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, singletonObject&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/* same here */&amp;lt;/span&amp;gt;&#039;&#039;&#039;) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
     ...&lt;br /&gt;
     });&lt;br /&gt;
 });&lt;br /&gt;
&lt;br /&gt;
Then you can access your code the same way as described in the [[#Create an anonymous class|previous section]]:&lt;br /&gt;
&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;singletonObject.firstMethod();&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;...&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Putting it all together ==&lt;br /&gt;
&#039;&#039;&#039;TODO&#039;&#039;&#039;&lt;/div&gt;</summary>
		<author><name>SwHawk</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=User:SwHawk/Create_Modular_Code&amp;diff=13595</id>
		<title>User:SwHawk/Create Modular Code</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=User:SwHawk/Create_Modular_Code&amp;diff=13595"/>
		<updated>2022-06-14T19:20:11Z</updated>

		<summary type="html">&lt;p&gt;SwHawk: /* Create a singleton object */ added color to code blocks&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{InfoBox|title=WIP|body=&#039;&#039;&#039;This article is a Work In Progress, please do not refer to it for production purposes&#039;&#039;&#039;}}&lt;br /&gt;
&lt;br /&gt;
This page will cover steps you can take as a BGA developer to make your code more modular and better organized. The way the framework is implemented makes the [[Main game logic: yourgamename.game.php|game logic]] and the [[Game interface logic: yourgamename.js|interface logic]] files very monolithic. While this is not a problem in itself, even simple to moderately complex game may require this files to be over 5k lines of code. Thus you can quickly become lost in all the functions you need to declare, where they are declared, and where they are called.&lt;br /&gt;
&lt;br /&gt;
But there are steps that you can follow to take advantage of PHP&#039;s Object Oriented Code and the dojo toolkit&#039;s AMD loader to organize your code in separate files. Let&#039;s see what&#039;s available:&lt;br /&gt;
&lt;br /&gt;
== Acknowledgements ==&lt;br /&gt;
&lt;br /&gt;
Writing this wiki article wouldn&#039;t have been possible without the help, work and insight of more experienced BGA developers:&lt;br /&gt;
* [https://boardgamearena.com/player?id=83846198 Tisaac]  (Discord user Tisaac Human Expert)&lt;br /&gt;
* [https://boardgamearena.com/player?id=85537631 bennygui] (Discord user bennygui)&lt;br /&gt;
* [https://boardgamearena.com/player?id=84125723 VictoriaLa] (Discord user VictoriaLa)&lt;br /&gt;
* Syarwin and [https://boardgamearena.com/player?id=84554161 quietmint] (for their Welcome To [https://github.com/Syarwin/bga-welcometo repository])&lt;br /&gt;
* [https://boardgamearena.com/player?id=84522426 Mogri] (Discord user Mogri)&lt;br /&gt;
&lt;br /&gt;
== Conventions ==&lt;br /&gt;
In the code blocks, code additions will be displayed in bold and green, and added comments will be displayed in bold and dark grey so that they stand out from the boilerplate code from a scratch project. Part in red should be aapted to reflect your project&#039;s structure.&lt;br /&gt;
&lt;br /&gt;
== On the PHP side ==&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt; vs &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; ===&lt;br /&gt;
Throughout this section, I&#039;ll make heavy use of PHP&#039;s &amp;lt;code&amp;gt;require_once&amp;lt;/code&amp;gt; control structure. Why am I using &amp;lt;code&amp;gt;require(_once)&amp;lt;/code&amp;gt; instead of &amp;lt;code&amp;gt;include_once&amp;lt;/code&amp;gt;? Because if an error exists in a PHP file that you try to &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt;, only a warning will be thrown, but the script will continue in spite of the error. Using &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; if the included file has an error, the script dies when the inclusion takes places, throwing a fatal error (&amp;lt;code&amp;gt;E_COMPILE_ERROR&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
That way, I&#039;m sure the classes, traits or interfaces I&#039;m including are syntax error free.&lt;br /&gt;
&lt;br /&gt;
=== Game logic methods ===&lt;br /&gt;
The way the framework is implemented, your game logic is gathered inside a class (&amp;lt;code&amp;gt;YourProjectName&amp;lt;/code&amp;gt;) extending the [[Table|&amp;lt;code&amp;gt;Table&amp;lt;/code&amp;gt; class]]. You define your methods there so that they may be called from other parts of the framework (as long as they&#039;re public methods obviously).&lt;br /&gt;
&lt;br /&gt;
But you can take advantage of [https://www.php.net/manual/en/language.oop5.traits.php PHP Traits]. In a nutshell, Traits are a collection of methods that can be reused in different classes, to avoid code duplication. Here we&#039;re not going to reuse them anywhere else than in the game class, but this little trick allows us to put methods definitions in other files, and in so doing to avoid monolithic code.&lt;br /&gt;
&lt;br /&gt;
Basically you create a Trait in th &amp;lt;code&amp;gt;/modules/&amp;lt;/code&amp;gt; directory, for instance:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/UtiltityFunctionsTrait.php]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;lt;?php&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;namespace YourProjectNamespace\Modules;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;trait UtilityFunctionsTrait {&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &#039;&#039;&#039;public function myFirstUtilityFunction($args)&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;{&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//Your code here&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;}&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Then you can include it in you project&#039;s &amp;lt;code&amp;gt;X.game.php&amp;lt;/code&amp;gt; file like so:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X_game.php]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;?php&lt;br /&gt;
  /**&lt;br /&gt;
   *------&lt;br /&gt;
   * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
   * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
   * &lt;br /&gt;
   * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
   * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
   * -----&lt;br /&gt;
   * &lt;br /&gt;
   * X.game.php&lt;br /&gt;
   *&lt;br /&gt;
   * This is the main file for your game logic.&lt;br /&gt;
   *&lt;br /&gt;
   * In this PHP file, you are going to defines the rules of the game.&lt;br /&gt;
   *&lt;br /&gt;
   */&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;require_once &#039;modules/UtilityFunctionsTrait.php&#039;; &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;   //Here we require the trait to be loaded when the class is loaded&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;use X\Modules\UtilityFunctionsTrait;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;                 //We import the trait to be used directly as UtilityFunctionsTraits,&#039;&#039;&#039;&lt;br /&gt;
                                                      &#039;&#039;&#039;//otherwise we would have to use the Fully qualified class name&#039;&#039;&#039;&lt;br /&gt;
                                                      &#039;&#039;&#039;//(YourProjectNamespace\Modules\UtilityFunctionsTrait)&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 class X extends Table&lt;br /&gt;
 {&lt;br /&gt;
 //...&lt;br /&gt;
 &lt;br /&gt;
 //////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
 //////////// Utility functions&lt;br /&gt;
 ////////////    &lt;br /&gt;
 &lt;br /&gt;
     /*&lt;br /&gt;
         In this space, you can put any utility methods useful for your game logic&lt;br /&gt;
     */&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;use UtilityFunctionsTrait;&#039;&#039;&#039;&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//Here we actually include the trait inside the class, making all the trait&#039;s methods&#039;&#039;&#039; &lt;br /&gt;
                                &#039;&#039;&#039;//available as class methods, keeping their visibility scope (so a private method&#039;&#039;&#039;&lt;br /&gt;
                                &#039;&#039;&#039;//is still private)&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Support classes ===&lt;br /&gt;
Basically, the same as traits, you put your classes definitions into files that live under the &amp;lt;code&amp;gt;/modules/&amp;lt;/code&amp;gt; directory (don&#039;t forget to namespace your classes), and then require them at the top of &amp;lt;code&amp;gt;X_game.php&amp;lt;/code&amp;gt;, and voilà, you&#039;re done&lt;br /&gt;
&lt;br /&gt;
=== Adding autoloader support ===&lt;br /&gt;
&lt;br /&gt;
==== Coding standards ====&lt;br /&gt;
Even for simple games, you might end up having a dozen of traits and support classes. You can require them all in your &amp;lt;code&amp;gt;X_game.php&amp;lt;/code&amp;gt;. Or you can use an autoloader, which will load the necessary classes and traits at runtime. There are two PSRs dealing with autloading standards (namely [https://www.php-fig.org/psr/psr-0 PSR-0] which is marked as deprecated and [https://www.php-fig.org/psr/psr-4 PSR-4]) which state that your namespaces should be a reflection of the directory structure of your project.&lt;br /&gt;
&lt;br /&gt;
Basically, when creating namespaces, you choose a namespace prefix. For example, you could use your BGA handle and the project name as a namespace prefix (would result in &amp;lt;code&amp;gt;\SwHawk\X&amp;lt;/code&amp;gt; in my case), and then the rest of the namespace would be the directory the file is in. I usually group classes and traits by the function they have in my project, so my &amp;lt;code&amp;gt;/modules/&amp;lt;/code&amp;gt; directory looks like that:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
modules/&lt;br /&gt;
    php/&lt;br /&gt;
        Factory/                      //Holds my factory classes&lt;br /&gt;
            AFactoryClass.php         //The namespace for this file would be \SwHawk\X\Factory, and the fully qualified class name would be \SwHawk\X\Factory\AFactoryClass&lt;br /&gt;
            ...&lt;br /&gt;
        Object/                       //Holds my support classes&lt;br /&gt;
            ObjectA.php               //The namespace for this file would be \SwHawk\X\Object, and the fully qualified class name would be \SwHawk\X\Object\ObjectA&lt;br /&gt;
            ...&lt;br /&gt;
        Traits/                       //Holds my traits&lt;br /&gt;
            UtilityFunctionsTrait.php //The namespace for this file would be \SwHawk\X\Traits, and the fully qualified class name would be \SwHawk\X\Traits\UtilityFunctionsTrait&lt;br /&gt;
            ...&lt;br /&gt;
        ...&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Autoloader function for development ====&lt;br /&gt;
While your project is under development, you usually create, move and remove classes as part of the development process. So you usually need an autoloading function that can handle a lot of flexibility. Basically once you import a class using the &amp;lt;code&amp;gt;use&amp;lt;/code&amp;gt; keyword, the autoloading function will determine which file to &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; using its fully qualified class name, and then &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt;. This function needs to be either defined or included at the top of &amp;lt;code&amp;gt;X_game.php&amp;lt;/code&amp;gt;. Such a function would have the following code (borrowed and adapted from [https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader-examples.md this repository]):&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;spl_autoload_register(function ($class) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// project-specific namespace prefix&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;, adapt to your needs&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;, remember that you must escape \ characters in double-quoted strings (hence the \\)&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$prefix = &#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;SwHawk\\X\\&amp;quot;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// base directory for the namespace prefix, this file would usually reside in the modules/php/includes/ directory, so the base directory for all my classes would be a level higher&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$base_dir = __DIR__ . &#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;&#039;&#039;&#039; &#039;/../&#039; &#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;gt;&#039;&#039;&#039;;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// does the class use the namespace prefix?&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$len = strlen($prefix);&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;if (strncmp($prefix, $class, $len) !== 0) {&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// no, move to the next registered autoloader&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;return;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// get the relative class name&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$relative_class = substr($class, $len);&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;// replace the namespace prefix with the base directory, replace namespace&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;// separators with directory separators in the relative class name, append&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;// with .php&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$file = $base_dir . str_replace(&#039;\\&#039;, &#039;/&#039;, $relative_class) . &#039;.php&#039;;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// if the file exists, require it&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;if (file_exists($file)) {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;require $file;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Autoloader function for production ====&lt;br /&gt;
Once you&#039;re moving your game to production, the autoloader function provided before isn&#039;t optimized. Once in production, the directory tree should not be modified, so you can change the earlier autoloader to a classmap based one. Basically, you build an associative array with the fully qualified classes names as keys and the filepath as the value. An example would look like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;spl_autoload_register(function ($class) {&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;static $classmap = array(&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:red&amp;gt;&amp;quot;SwHawk\\X\\&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;Factory\\AFactoryClass&amp;quot; =&amp;gt; __DIR__ . &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;&amp;quot;/../&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;Factory/AFactoryClass.php&amp;quot;,&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;);&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;if(array_key_exists($class)) {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;require $classmap[$class];&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;} else {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;return;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This autoloader is better suited to production since it won&#039;t use expensive calls like &amp;lt;code&amp;gt;file_exists($filename)&amp;lt;/code&amp;gt;. You can write the classmap by yourself, but it can be quite cumbersome, there is some tools like [https://github.com/hanneskod/classtools this project], or [https://github.com/gnugat/nomo-spaco this one], or even scripts detailed in this [https://stackoverflow.com/questions/22761554/how-to-get-all-class-names-inside-a-particular-namespace StackOverflow topic]&lt;br /&gt;
&lt;br /&gt;
== On the JS side ==&lt;br /&gt;
&lt;br /&gt;
BGA uses the dojo toolkit framework for most of its javascript code. Dojo comes with its own way of loading modules, which you can read about in more detail [https://dojotoolkit.org/documentation/tutorials/1.10/modules/ here] and [https://dojotoolkit.org/documentation/tutorials/1.10/modules_advanced/ here]. To put it simply, there are two ways you can go about this&lt;br /&gt;
&lt;br /&gt;
=== Write plain javascript ===&lt;br /&gt;
Should you wan to write plain javascript, you can easily do so. What you need to do is actually load the file like so in &amp;lt;code&amp;gt;X.js&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&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;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&amp;quot;./modules/path/to/firstfile.js&amp;quot;,&amp;lt;/span&amp;gt;        &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;//The first file with your JS code&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&amp;quot;./modules/path/to/secondfile.js&amp;quot;,&amp;lt;/span&amp;gt;       &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;//The second file with another part of your JS code&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
     ...&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
         constructor: function(){&lt;br /&gt;
             ...&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
According to the dojo toolkit documentation, you will then need to directly access what you defined in the files.&lt;br /&gt;
&lt;br /&gt;
=== Write an AMD module ===&lt;br /&gt;
You can take advantage of the toolkit&#039;s module system to declare dependencies between the differents files you&#039;ll be writing (modules in the toolkit&#039;s language). To be identified as modules, your Javascript files will need to have the following structure:&lt;br /&gt;
&lt;br /&gt;
==== Create a named new class ====&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/js/FirstModule.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;gt;&#039;&#039;&#039;define([&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo&amp;quot;,&amp;lt;/span&amp;gt;      &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Needed if you want to be able to use dojo methods such as dojo.place, etc.&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo/_base/declare&amp;quot;,&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;other dependencies...&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;],function(dojo, declare){&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;return declare(&amp;quot;className&amp;quot;,&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/*Parent classes that this class inherits, optional*/&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, {&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;&#039;&#039;&#039;/* static properties */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;let property1 = &amp;quot;value;&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;let property2 = 5;&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;constructor: function (args) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;&#039;&#039;&#039;/* instance properties */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;let property3 = 8;&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;let property4 = [ &amp;quot;arrayValue&amp;quot;, &amp;quot;arrayValue2&amp;quot; ]; &#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;method1: function (args) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;/* your code here */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
         &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;});&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then in the X.js file, you can use your newly created module like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&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;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/js/Firstmodule&amp;quot;,&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
     ...&lt;br /&gt;
     });&lt;br /&gt;
 });&lt;br /&gt;
&lt;br /&gt;
In your code, you can access your module&#039;s class and methods by doing so:&lt;br /&gt;
&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;let object = new className();&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;object.method1();&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;...&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This can lead to namespace collisions if you don&#039;t choose a namespace correctly, so you might want to take the same approach as described earlier for the PHP files for using a namespace.&lt;br /&gt;
&lt;br /&gt;
==== Create an anonymous class ====&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/js/SecondModule.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;gt;&#039;&#039;&#039;define([&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo&amp;quot;,&amp;lt;/span&amp;gt;      &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Needed if you want to be able to use dojo methods such as dojo.place, etc.&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo/_base/declare&amp;quot;,&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;other dependencies...&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;],function(dojo, declare){&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;return declare(null,&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/*Parent classes that this class inherits, optional*/&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, {&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;&#039;&#039;&#039;/* static properties */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;let property1 = &amp;quot;value;&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;let property2 = 5;&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;constructor: function (args) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;&#039;&#039;&#039;/* instance properties */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;let property3 = 8;&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;let property4 = [ &amp;quot;arrayValue&amp;quot;, &amp;quot;arrayValue2&amp;quot; ]; &#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;method1: function (args) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;/* your code here */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
         &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;});&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then in the X.js file, you can use your newly created module like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&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;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/js/SecondModule&amp;quot;,&#039;&#039;&#039;&amp;lt;/span&amp;gt;      &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//Has to be inserted in the third position as we&#039;ll&#039;&#039;&#039;&lt;br /&gt;
                                             &#039;&#039;&#039;//need an identifier later, and the other modules don&#039;t need it, see code in the preceding subsection.&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, SecondModule&amp;lt;/span&amp;gt;  &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/* insert a reference here that you&#039;ll use throughout the JS file for this module */&amp;lt;/span&amp;gt;&#039;&#039;&#039;) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
     ...&lt;br /&gt;
     });&lt;br /&gt;
 });&lt;br /&gt;
&lt;br /&gt;
In your code, you can access your module&#039;s class and methods by doing so:&lt;br /&gt;
&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;let someValue = SecondModule.property3&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;SecondModule.method1();&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;...&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This can lead to namespace collisions if you don&#039;t choose a namespace correctly, so you might want to take the same approach as described earlier for the PHP files for using a namespace.&lt;br /&gt;
&lt;br /&gt;
==== Create a singleton object ====&lt;br /&gt;
&lt;br /&gt;
You can also create singleton objects by creating a module this way:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/js/singletonObject.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;define([&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo&amp;quot;,&amp;lt;/span&amp;gt;      &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Needed if you want to be able to use dojo methods such as dojo.place, etc.&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;], function (dojo) {&#039;&#039;&#039;&lt;br /&gt;
     &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;// Methods and variables defined in this part will not be available anywhere else than in this file&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;let privateVariable = &amp;quot;someValue&amp;quot;;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;let privateFunction = function (args) {&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//some code here&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;return {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;firstMethod: function (args) {&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;privateFunction(args);&#039;&#039;&#039;&lt;br /&gt;
             &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//some other code here&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;};&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To be used in the &amp;lt;code&amp;gt;X.js&amp;lt;/code&amp;gt; file, you must use the same method as in the [[#Create an anonymous class|previous section]]:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&gt;
 &lt;br /&gt;
 define([&lt;br /&gt;
     &amp;quot;dojo&amp;quot;,&amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&amp;quot;./modules/js/SecondModule&amp;quot;,&amp;lt;/span&amp;gt;         &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Has to be inserted in the third position as we&#039;ll need an identifier later, and the other modules don&#039;t need it&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&amp;quot;./modules/js/sigletonObject&amp;quot;,&amp;lt;/span&amp;gt;          &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//see code in the preceding subsection.&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
     &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/js/Firstmodule&amp;quot;,&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, SecondModule&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/* insert a reference here that you&#039;ll use throughout the JS file for this module */&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, singletonObject&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/* same here */&amp;lt;/span&amp;gt;&#039;&#039;&#039;) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
     ...&lt;br /&gt;
     });&lt;br /&gt;
 });&lt;br /&gt;
&lt;br /&gt;
Then you can access your code the same way as described in the [[#Create an anonymous class|previous section]]:&lt;br /&gt;
&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;singletonObject.firstMethod();&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;...&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Putting it all together ==&lt;br /&gt;
&#039;&#039;&#039;TODO&#039;&#039;&#039;&lt;/div&gt;</summary>
		<author><name>SwHawk</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=User:SwHawk/Create_Modular_Code&amp;diff=13594</id>
		<title>User:SwHawk/Create Modular Code</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=User:SwHawk/Create_Modular_Code&amp;diff=13594"/>
		<updated>2022-06-14T19:10:14Z</updated>

		<summary type="html">&lt;p&gt;SwHawk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{InfoBox|title=WIP|body=&#039;&#039;&#039;This article is a Work In Progress, please do not refer to it for production purposes&#039;&#039;&#039;}}&lt;br /&gt;
&lt;br /&gt;
This page will cover steps you can take as a BGA developer to make your code more modular and better organized. The way the framework is implemented makes the [[Main game logic: yourgamename.game.php|game logic]] and the [[Game interface logic: yourgamename.js|interface logic]] files very monolithic. While this is not a problem in itself, even simple to moderately complex game may require this files to be over 5k lines of code. Thus you can quickly become lost in all the functions you need to declare, where they are declared, and where they are called.&lt;br /&gt;
&lt;br /&gt;
But there are steps that you can follow to take advantage of PHP&#039;s Object Oriented Code and the dojo toolkit&#039;s AMD loader to organize your code in separate files. Let&#039;s see what&#039;s available:&lt;br /&gt;
&lt;br /&gt;
== Acknowledgements ==&lt;br /&gt;
&lt;br /&gt;
Writing this wiki article wouldn&#039;t have been possible without the help, work and insight of more experienced BGA developers:&lt;br /&gt;
* [https://boardgamearena.com/player?id=83846198 Tisaac]  (Discord user Tisaac Human Expert)&lt;br /&gt;
* [https://boardgamearena.com/player?id=85537631 bennygui] (Discord user bennygui)&lt;br /&gt;
* [https://boardgamearena.com/player?id=84125723 VictoriaLa] (Discord user VictoriaLa)&lt;br /&gt;
* Syarwin and [https://boardgamearena.com/player?id=84554161 quietmint] (for their Welcome To [https://github.com/Syarwin/bga-welcometo repository])&lt;br /&gt;
* [https://boardgamearena.com/player?id=84522426 Mogri] (Discord user Mogri)&lt;br /&gt;
&lt;br /&gt;
== Conventions ==&lt;br /&gt;
In the code blocks, code additions will be displayed in bold and green, and added comments will be displayed in bold and dark grey so that they stand out from the boilerplate code from a scratch project. Part in red should be aapted to reflect your project&#039;s structure.&lt;br /&gt;
&lt;br /&gt;
== On the PHP side ==&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt; vs &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; ===&lt;br /&gt;
Throughout this section, I&#039;ll make heavy use of PHP&#039;s &amp;lt;code&amp;gt;require_once&amp;lt;/code&amp;gt; control structure. Why am I using &amp;lt;code&amp;gt;require(_once)&amp;lt;/code&amp;gt; instead of &amp;lt;code&amp;gt;include_once&amp;lt;/code&amp;gt;? Because if an error exists in a PHP file that you try to &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt;, only a warning will be thrown, but the script will continue in spite of the error. Using &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; if the included file has an error, the script dies when the inclusion takes places, throwing a fatal error (&amp;lt;code&amp;gt;E_COMPILE_ERROR&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
That way, I&#039;m sure the classes, traits or interfaces I&#039;m including are syntax error free.&lt;br /&gt;
&lt;br /&gt;
=== Game logic methods ===&lt;br /&gt;
The way the framework is implemented, your game logic is gathered inside a class (&amp;lt;code&amp;gt;YourProjectName&amp;lt;/code&amp;gt;) extending the [[Table|&amp;lt;code&amp;gt;Table&amp;lt;/code&amp;gt; class]]. You define your methods there so that they may be called from other parts of the framework (as long as they&#039;re public methods obviously).&lt;br /&gt;
&lt;br /&gt;
But you can take advantage of [https://www.php.net/manual/en/language.oop5.traits.php PHP Traits]. In a nutshell, Traits are a collection of methods that can be reused in different classes, to avoid code duplication. Here we&#039;re not going to reuse them anywhere else than in the game class, but this little trick allows us to put methods definitions in other files, and in so doing to avoid monolithic code.&lt;br /&gt;
&lt;br /&gt;
Basically you create a Trait in th &amp;lt;code&amp;gt;/modules/&amp;lt;/code&amp;gt; directory, for instance:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/UtiltityFunctionsTrait.php]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;lt;?php&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;namespace YourProjectNamespace\Modules;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;trait UtilityFunctionsTrait {&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &#039;&#039;&#039;public function myFirstUtilityFunction($args)&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;{&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//Your code here&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;}&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Then you can include it in you project&#039;s &amp;lt;code&amp;gt;X.game.php&amp;lt;/code&amp;gt; file like so:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X_game.php]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;?php&lt;br /&gt;
  /**&lt;br /&gt;
   *------&lt;br /&gt;
   * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
   * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
   * &lt;br /&gt;
   * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
   * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
   * -----&lt;br /&gt;
   * &lt;br /&gt;
   * X.game.php&lt;br /&gt;
   *&lt;br /&gt;
   * This is the main file for your game logic.&lt;br /&gt;
   *&lt;br /&gt;
   * In this PHP file, you are going to defines the rules of the game.&lt;br /&gt;
   *&lt;br /&gt;
   */&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;require_once &#039;modules/UtilityFunctionsTrait.php&#039;; &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;   //Here we require the trait to be loaded when the class is loaded&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;use X\Modules\UtilityFunctionsTrait;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;                 //We import the trait to be used directly as UtilityFunctionsTraits,&#039;&#039;&#039;&lt;br /&gt;
                                                      &#039;&#039;&#039;//otherwise we would have to use the Fully qualified class name&#039;&#039;&#039;&lt;br /&gt;
                                                      &#039;&#039;&#039;//(YourProjectNamespace\Modules\UtilityFunctionsTrait)&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 class X extends Table&lt;br /&gt;
 {&lt;br /&gt;
 //...&lt;br /&gt;
 &lt;br /&gt;
 //////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
 //////////// Utility functions&lt;br /&gt;
 ////////////    &lt;br /&gt;
 &lt;br /&gt;
     /*&lt;br /&gt;
         In this space, you can put any utility methods useful for your game logic&lt;br /&gt;
     */&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;use UtilityFunctionsTrait;&#039;&#039;&#039;&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//Here we actually include the trait inside the class, making all the trait&#039;s methods&#039;&#039;&#039; &lt;br /&gt;
                                &#039;&#039;&#039;//available as class methods, keeping their visibility scope (so a private method&#039;&#039;&#039;&lt;br /&gt;
                                &#039;&#039;&#039;//is still private)&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Support classes ===&lt;br /&gt;
Basically, the same as traits, you put your classes definitions into files that live under the &amp;lt;code&amp;gt;/modules/&amp;lt;/code&amp;gt; directory (don&#039;t forget to namespace your classes), and then require them at the top of &amp;lt;code&amp;gt;X_game.php&amp;lt;/code&amp;gt;, and voilà, you&#039;re done&lt;br /&gt;
&lt;br /&gt;
=== Adding autoloader support ===&lt;br /&gt;
&lt;br /&gt;
==== Coding standards ====&lt;br /&gt;
Even for simple games, you might end up having a dozen of traits and support classes. You can require them all in your &amp;lt;code&amp;gt;X_game.php&amp;lt;/code&amp;gt;. Or you can use an autoloader, which will load the necessary classes and traits at runtime. There are two PSRs dealing with autloading standards (namely [https://www.php-fig.org/psr/psr-0 PSR-0] which is marked as deprecated and [https://www.php-fig.org/psr/psr-4 PSR-4]) which state that your namespaces should be a reflection of the directory structure of your project.&lt;br /&gt;
&lt;br /&gt;
Basically, when creating namespaces, you choose a namespace prefix. For example, you could use your BGA handle and the project name as a namespace prefix (would result in &amp;lt;code&amp;gt;\SwHawk\X&amp;lt;/code&amp;gt; in my case), and then the rest of the namespace would be the directory the file is in. I usually group classes and traits by the function they have in my project, so my &amp;lt;code&amp;gt;/modules/&amp;lt;/code&amp;gt; directory looks like that:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
modules/&lt;br /&gt;
    php/&lt;br /&gt;
        Factory/                      //Holds my factory classes&lt;br /&gt;
            AFactoryClass.php         //The namespace for this file would be \SwHawk\X\Factory, and the fully qualified class name would be \SwHawk\X\Factory\AFactoryClass&lt;br /&gt;
            ...&lt;br /&gt;
        Object/                       //Holds my support classes&lt;br /&gt;
            ObjectA.php               //The namespace for this file would be \SwHawk\X\Object, and the fully qualified class name would be \SwHawk\X\Object\ObjectA&lt;br /&gt;
            ...&lt;br /&gt;
        Traits/                       //Holds my traits&lt;br /&gt;
            UtilityFunctionsTrait.php //The namespace for this file would be \SwHawk\X\Traits, and the fully qualified class name would be \SwHawk\X\Traits\UtilityFunctionsTrait&lt;br /&gt;
            ...&lt;br /&gt;
        ...&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Autoloader function for development ====&lt;br /&gt;
While your project is under development, you usually create, move and remove classes as part of the development process. So you usually need an autoloading function that can handle a lot of flexibility. Basically once you import a class using the &amp;lt;code&amp;gt;use&amp;lt;/code&amp;gt; keyword, the autoloading function will determine which file to &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; using its fully qualified class name, and then &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt;. This function needs to be either defined or included at the top of &amp;lt;code&amp;gt;X_game.php&amp;lt;/code&amp;gt;. Such a function would have the following code (borrowed and adapted from [https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader-examples.md this repository]):&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;spl_autoload_register(function ($class) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// project-specific namespace prefix&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;, adapt to your needs&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;, remember that you must escape \ characters in double-quoted strings (hence the \\)&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$prefix = &#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;SwHawk\\X\\&amp;quot;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// base directory for the namespace prefix, this file would usually reside in the modules/php/includes/ directory, so the base directory for all my classes would be a level higher&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$base_dir = __DIR__ . &#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;&#039;&#039;&#039; &#039;/../&#039; &#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;gt;&#039;&#039;&#039;;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// does the class use the namespace prefix?&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$len = strlen($prefix);&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;if (strncmp($prefix, $class, $len) !== 0) {&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// no, move to the next registered autoloader&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;return;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// get the relative class name&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$relative_class = substr($class, $len);&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;// replace the namespace prefix with the base directory, replace namespace&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;// separators with directory separators in the relative class name, append&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;// with .php&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$file = $base_dir . str_replace(&#039;\\&#039;, &#039;/&#039;, $relative_class) . &#039;.php&#039;;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// if the file exists, require it&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;if (file_exists($file)) {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;require $file;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Autoloader function for production ====&lt;br /&gt;
Once you&#039;re moving your game to production, the autoloader function provided before isn&#039;t optimized. Once in production, the directory tree should not be modified, so you can change the earlier autoloader to a classmap based one. Basically, you build an associative array with the fully qualified classes names as keys and the filepath as the value. An example would look like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;spl_autoload_register(function ($class) {&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;static $classmap = array(&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:red&amp;gt;&amp;quot;SwHawk\\X\\&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;Factory\\AFactoryClass&amp;quot; =&amp;gt; __DIR__ . &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;&amp;quot;/../&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;Factory/AFactoryClass.php&amp;quot;,&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;);&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;if(array_key_exists($class)) {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;require $classmap[$class];&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;} else {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;return;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This autoloader is better suited to production since it won&#039;t use expensive calls like &amp;lt;code&amp;gt;file_exists($filename)&amp;lt;/code&amp;gt;. You can write the classmap by yourself, but it can be quite cumbersome, there is some tools like [https://github.com/hanneskod/classtools this project], or [https://github.com/gnugat/nomo-spaco this one], or even scripts detailed in this [https://stackoverflow.com/questions/22761554/how-to-get-all-class-names-inside-a-particular-namespace StackOverflow topic]&lt;br /&gt;
&lt;br /&gt;
== On the JS side ==&lt;br /&gt;
&lt;br /&gt;
BGA uses the dojo toolkit framework for most of its javascript code. Dojo comes with its own way of loading modules, which you can read about in more detail [https://dojotoolkit.org/documentation/tutorials/1.10/modules/ here] and [https://dojotoolkit.org/documentation/tutorials/1.10/modules_advanced/ here]. To put it simply, there are two ways you can go about this&lt;br /&gt;
&lt;br /&gt;
=== Write plain javascript ===&lt;br /&gt;
Should you wan to write plain javascript, you can easily do so. What you need to do is actually load the file like so in &amp;lt;code&amp;gt;X.js&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&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;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&amp;quot;./modules/path/to/firstfile.js&amp;quot;,&amp;lt;/span&amp;gt;        &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;//The first file with your JS code&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&amp;quot;./modules/path/to/secondfile.js&amp;quot;,&amp;lt;/span&amp;gt;       &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;//The second file with another part of your JS code&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
     ...&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
         constructor: function(){&lt;br /&gt;
             ...&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
According to the dojo toolkit documentation, you will then need to directly access what you defined in the files.&lt;br /&gt;
&lt;br /&gt;
=== Write an AMD module ===&lt;br /&gt;
You can take advantage of the toolkit&#039;s module system to declare dependencies between the differents files you&#039;ll be writing (modules in the toolkit&#039;s language). To be identified as modules, your Javascript files will need to have the following structure:&lt;br /&gt;
&lt;br /&gt;
==== Create a named new class ====&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/js/FirstModule.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;gt;&#039;&#039;&#039;define([&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo&amp;quot;,&amp;lt;/span&amp;gt;      &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Needed if you want to be able to use dojo methods such as dojo.place, etc.&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo/_base/declare&amp;quot;,&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;other dependencies...&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;],function(dojo, declare){&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;return declare(&amp;quot;className&amp;quot;,&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/*Parent classes that this class inherits, optional*/&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, {&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;&#039;&#039;&#039;/* static properties */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;let property1 = &amp;quot;value;&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;let property2 = 5;&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;constructor: function (args) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;&#039;&#039;&#039;/* instance properties */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;let property3 = 8;&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;let property4 = [ &amp;quot;arrayValue&amp;quot;, &amp;quot;arrayValue2&amp;quot; ]; &#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;method1: function (args) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;/* your code here */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
         &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;});&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then in the X.js file, you can use your newly created module like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&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;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/js/Firstmodule&amp;quot;,&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
     ...&lt;br /&gt;
     });&lt;br /&gt;
 });&lt;br /&gt;
&lt;br /&gt;
In your code, you can access your module&#039;s class and methods by doing so:&lt;br /&gt;
&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;let object = new className();&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;object.method1();&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;...&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This can lead to namespace collisions if you don&#039;t choose a namespace correctly, so you might want to take the same approach as described earlier for the PHP files for using a namespace.&lt;br /&gt;
&lt;br /&gt;
==== Create an anonymous class ====&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/js/SecondModule.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;gt;&#039;&#039;&#039;define([&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo&amp;quot;,&amp;lt;/span&amp;gt;      &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Needed if you want to be able to use dojo methods such as dojo.place, etc.&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo/_base/declare&amp;quot;,&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;other dependencies...&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;],function(dojo, declare){&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;return declare(null,&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/*Parent classes that this class inherits, optional*/&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, {&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;&#039;&#039;&#039;/* static properties */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;let property1 = &amp;quot;value;&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;let property2 = 5;&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;constructor: function (args) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;&#039;&#039;&#039;/* instance properties */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;let property3 = 8;&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;let property4 = [ &amp;quot;arrayValue&amp;quot;, &amp;quot;arrayValue2&amp;quot; ]; &#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;method1: function (args) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;/* your code here */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
         &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;});&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then in the X.js file, you can use your newly created module like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&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;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/js/SecondModule&amp;quot;,&#039;&#039;&#039;&amp;lt;/span&amp;gt;      &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//Has to be inserted in the third position as we&#039;ll&#039;&#039;&#039;&lt;br /&gt;
                                             &#039;&#039;&#039;//need an identifier later, and the other modules don&#039;t need it, see code in the preceding subsection.&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, SecondModule&amp;lt;/span&amp;gt;  &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/* insert a reference here that you&#039;ll use throughout the JS file for this module */&amp;lt;/span&amp;gt;&#039;&#039;&#039;) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
     ...&lt;br /&gt;
     });&lt;br /&gt;
 });&lt;br /&gt;
&lt;br /&gt;
In your code, you can access your module&#039;s class and methods by doing so:&lt;br /&gt;
&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;let someValue = SecondModule.property3&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;SecondModule.method1();&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;...&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This can lead to namespace collisions if you don&#039;t choose a namespace correctly, so you might want to take the same approach as described earlier for the PHP files for using a namespace.&lt;br /&gt;
&lt;br /&gt;
==== Create a singleton object ====&lt;br /&gt;
&lt;br /&gt;
You can also create singleton objects by creating a module this way:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[[modules/js/singletonObject.js]]&lt;br /&gt;
define([&lt;br /&gt;
    &amp;quot;dojo&amp;quot;,&lt;br /&gt;
    ...&lt;br /&gt;
], function (dojo) {&lt;br /&gt;
    // Methods and variables defined in this part will not be available anywhere else than in this file&lt;br /&gt;
    let privateVariable = &amp;quot;someValue&amp;quot;;&lt;br /&gt;
    let privateFunction = function (args) {&lt;br /&gt;
        //some code here&lt;br /&gt;
    }&lt;br /&gt;
    return {&lt;br /&gt;
        firstMethod: function (args) {&lt;br /&gt;
            privateFunction(args);&lt;br /&gt;
            //some other code here&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To be used in the &amp;lt;code&amp;gt;X.js&amp;lt;/code&amp;gt; file, you must use the same method as in the [[#Create an anonymous class|previous section]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 *------&lt;br /&gt;
 * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
 * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
 *&lt;br /&gt;
 * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
 * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
 * -----&lt;br /&gt;
 *&lt;br /&gt;
 * X.js&lt;br /&gt;
 *&lt;br /&gt;
 * X user interface script&lt;br /&gt;
 * &lt;br /&gt;
 * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&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;./modules/js/SecondModule&amp;quot;,         //Has to be inserted in the third position as we&#039;ll need an identifier later, and the other modules don&#039;t need it, see code in the preceding subsection.&lt;br /&gt;
    &amp;quot;./modules/js/sigletonObject&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;./modules/js/Firstmodule&amp;quot;,&lt;br /&gt;
],&lt;br /&gt;
function (dojo, declare, SecondModule /* insert a reference here that you&#039;ll use throughout the JS file for this module */, singletonObject) {&lt;br /&gt;
    return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
    ...&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then you can access your code the same way as described in the [[#Create an anonymous class|previous section]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    singletonObject.firstMethod();&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Putting it all together ==&lt;br /&gt;
&#039;&#039;&#039;TODO&#039;&#039;&#039;&lt;/div&gt;</summary>
		<author><name>SwHawk</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=User:SwHawk/Create_Modular_Code&amp;diff=13593</id>
		<title>User:SwHawk/Create Modular Code</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=User:SwHawk/Create_Modular_Code&amp;diff=13593"/>
		<updated>2022-06-14T19:10:02Z</updated>

		<summary type="html">&lt;p&gt;SwHawk: /* Create an anonymous new class */ Copy paste error for section title&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{InfoBox|title=WIP|body=&#039;&#039;&#039;This article is a Work In Progress, please do not refer to it for production purposes&#039;&#039;&#039;}}&lt;br /&gt;
&lt;br /&gt;
This page will cover steps you can take as a BGA developer to make your code more modular and better organized. The way the framework is implemented makes the [[Main game logic: yourgamename.game.php|game logic]] and the [[Game interface logic: yourgamename.js|interface logic]] files very monolithic. While this is not a problem in itself, even simple to moderately complex game may require this files to be over 5k lines of code. Thus you can quickly become lost in all the functions you need to declare, where they are declared, and where they are called.&lt;br /&gt;
&lt;br /&gt;
But there are steps that you can follow to take advantage of PHP&#039;s Object Oriented Code and the dojo toolkit&#039;s AMD loader to organize your code in separate files. Let&#039;s see what&#039;s available:&lt;br /&gt;
&lt;br /&gt;
== Acknowledgements ==&lt;br /&gt;
&lt;br /&gt;
Writing this wiki article wouldn&#039;t have been possible without the help, work and insight of more experienced BGA developers:&lt;br /&gt;
* [https://boardgamearena.com/player?id=83846198 Tisaac]  (Discord user Tisaac Human Expert)&lt;br /&gt;
* [https://boardgamearena.com/player?id=85537631 bennygui] (Discord user bennygui)&lt;br /&gt;
* [https://boardgamearena.com/player?id=84125723 VictoriaLa] (Discord user VictoriaLa)&lt;br /&gt;
* Syarwin and [https://boardgamearena.com/player?id=84554161 quietmint] (for their Welcome To [https://github.com/Syarwin/bga-welcometo repository])&lt;br /&gt;
* [https://boardgamearena.com/player?id=84522426 Mogri] (Discord user Mogri)&lt;br /&gt;
&lt;br /&gt;
== Conventions ==&lt;br /&gt;
In the code blocks, code additions will be displayed in bold and green, and added comments will be displayed in bold and dark grey so that they stand out from the boilerplate code from a scratch project. Part in red should be aapted to reflect your project&#039;s structure.&lt;br /&gt;
&lt;br /&gt;
== On the PHP side ==&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt; vs &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; ===&lt;br /&gt;
Throughout this section, I&#039;ll make heavy use of PHP&#039;s &amp;lt;code&amp;gt;require_once&amp;lt;/code&amp;gt; control structure. Why am I using &amp;lt;code&amp;gt;require(_once)&amp;lt;/code&amp;gt; instead of &amp;lt;code&amp;gt;include_once&amp;lt;/code&amp;gt;? Because if an error exists in a PHP file that you try to &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt;, only a warning will be thrown, but the script will continue in spite of the error. Using &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; if the included file has an error, the script dies when the inclusion takes places, throwing a fatal error (&amp;lt;code&amp;gt;E_COMPILE_ERROR&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
That way, I&#039;m sure the classes, traits or interfaces I&#039;m including are syntax error free.&lt;br /&gt;
&lt;br /&gt;
=== Game logic methods ===&lt;br /&gt;
The way the framework is implemented, your game logic is gathered inside a class (&amp;lt;code&amp;gt;YourProjectName&amp;lt;/code&amp;gt;) extending the [[Table|&amp;lt;code&amp;gt;Table&amp;lt;/code&amp;gt; class]]. You define your methods there so that they may be called from other parts of the framework (as long as they&#039;re public methods obviously).&lt;br /&gt;
&lt;br /&gt;
But you can take advantage of [https://www.php.net/manual/en/language.oop5.traits.php PHP Traits]. In a nutshell, Traits are a collection of methods that can be reused in different classes, to avoid code duplication. Here we&#039;re not going to reuse them anywhere else than in the game class, but this little trick allows us to put methods definitions in other files, and in so doing to avoid monolithic code.&lt;br /&gt;
&lt;br /&gt;
Basically you create a Trait in th &amp;lt;code&amp;gt;/modules/&amp;lt;/code&amp;gt; directory, for instance:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/UtiltityFunctionsTrait.php]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;lt;?php&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;namespace YourProjectNamespace\Modules;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;trait UtilityFunctionsTrait {&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &#039;&#039;&#039;public function myFirstUtilityFunction($args)&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;{&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//Your code here&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;}&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Then you can include it in you project&#039;s &amp;lt;code&amp;gt;X.game.php&amp;lt;/code&amp;gt; file like so:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X_game.php]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;?php&lt;br /&gt;
  /**&lt;br /&gt;
   *------&lt;br /&gt;
   * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
   * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
   * &lt;br /&gt;
   * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
   * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
   * -----&lt;br /&gt;
   * &lt;br /&gt;
   * X.game.php&lt;br /&gt;
   *&lt;br /&gt;
   * This is the main file for your game logic.&lt;br /&gt;
   *&lt;br /&gt;
   * In this PHP file, you are going to defines the rules of the game.&lt;br /&gt;
   *&lt;br /&gt;
   */&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;require_once &#039;modules/UtilityFunctionsTrait.php&#039;; &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;   //Here we require the trait to be loaded when the class is loaded&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;use X\Modules\UtilityFunctionsTrait;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;                 //We import the trait to be used directly as UtilityFunctionsTraits,&#039;&#039;&#039;&lt;br /&gt;
                                                      &#039;&#039;&#039;//otherwise we would have to use the Fully qualified class name&#039;&#039;&#039;&lt;br /&gt;
                                                      &#039;&#039;&#039;//(YourProjectNamespace\Modules\UtilityFunctionsTrait)&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 class X extends Table&lt;br /&gt;
 {&lt;br /&gt;
 //...&lt;br /&gt;
 &lt;br /&gt;
 //////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
 //////////// Utility functions&lt;br /&gt;
 ////////////    &lt;br /&gt;
 &lt;br /&gt;
     /*&lt;br /&gt;
         In this space, you can put any utility methods useful for your game logic&lt;br /&gt;
     */&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;use UtilityFunctionsTrait;&#039;&#039;&#039;&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//Here we actually include the trait inside the class, making all the trait&#039;s methods&#039;&#039;&#039; &lt;br /&gt;
                                &#039;&#039;&#039;//available as class methods, keeping their visibility scope (so a private method&#039;&#039;&#039;&lt;br /&gt;
                                &#039;&#039;&#039;//is still private)&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Support classes ===&lt;br /&gt;
Basically, the same as traits, you put your classes definitions into files that live under the &amp;lt;code&amp;gt;/modules/&amp;lt;/code&amp;gt; directory (don&#039;t forget to namespace your classes), and then require them at the top of &amp;lt;code&amp;gt;X_game.php&amp;lt;/code&amp;gt;, and voilà, you&#039;re done&lt;br /&gt;
&lt;br /&gt;
=== Adding autoloader support ===&lt;br /&gt;
&lt;br /&gt;
==== Coding standards ====&lt;br /&gt;
Even for simple games, you might end up having a dozen of traits and support classes. You can require them all in your &amp;lt;code&amp;gt;X_game.php&amp;lt;/code&amp;gt;. Or you can use an autoloader, which will load the necessary classes and traits at runtime. There are two PSRs dealing with autloading standards (namely [https://www.php-fig.org/psr/psr-0 PSR-0] which is marked as deprecated and [https://www.php-fig.org/psr/psr-4 PSR-4]) which state that your namespaces should be a reflection of the directory structure of your project.&lt;br /&gt;
&lt;br /&gt;
Basically, when creating namespaces, you choose a namespace prefix. For example, you could use your BGA handle and the project name as a namespace prefix (would result in &amp;lt;code&amp;gt;\SwHawk\X&amp;lt;/code&amp;gt; in my case), and then the rest of the namespace would be the directory the file is in. I usually group classes and traits by the function they have in my project, so my &amp;lt;code&amp;gt;/modules/&amp;lt;/code&amp;gt; directory looks like that:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
modules/&lt;br /&gt;
    php/&lt;br /&gt;
        Factory/                      //Holds my factory classes&lt;br /&gt;
            AFactoryClass.php         //The namespace for this file would be \SwHawk\X\Factory, and the fully qualified class name would be \SwHawk\X\Factory\AFactoryClass&lt;br /&gt;
            ...&lt;br /&gt;
        Object/                       //Holds my support classes&lt;br /&gt;
            ObjectA.php               //The namespace for this file would be \SwHawk\X\Object, and the fully qualified class name would be \SwHawk\X\Object\ObjectA&lt;br /&gt;
            ...&lt;br /&gt;
        Traits/                       //Holds my traits&lt;br /&gt;
            UtilityFunctionsTrait.php //The namespace for this file would be \SwHawk\X\Traits, and the fully qualified class name would be \SwHawk\X\Traits\UtilityFunctionsTrait&lt;br /&gt;
            ...&lt;br /&gt;
        ...&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Autoloader function for development ====&lt;br /&gt;
While your project is under development, you usually create, move and remove classes as part of the development process. So you usually need an autoloading function that can handle a lot of flexibility. Basically once you import a class using the &amp;lt;code&amp;gt;use&amp;lt;/code&amp;gt; keyword, the autoloading function will determine which file to &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; using its fully qualified class name, and then &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt;. This function needs to be either defined or included at the top of &amp;lt;code&amp;gt;X_game.php&amp;lt;/code&amp;gt;. Such a function would have the following code (borrowed and adapted from [https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader-examples.md this repository]):&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;spl_autoload_register(function ($class) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// project-specific namespace prefix&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;, adapt to your needs&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;, remember that you must escape \ characters in double-quoted strings (hence the \\)&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$prefix = &#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;SwHawk\\X\\&amp;quot;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// base directory for the namespace prefix, this file would usually reside in the modules/php/includes/ directory, so the base directory for all my classes would be a level higher&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$base_dir = __DIR__ . &#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;&#039;&#039;&#039; &#039;/../&#039; &#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;gt;&#039;&#039;&#039;;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// does the class use the namespace prefix?&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$len = strlen($prefix);&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;if (strncmp($prefix, $class, $len) !== 0) {&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// no, move to the next registered autoloader&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;return;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// get the relative class name&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$relative_class = substr($class, $len);&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;// replace the namespace prefix with the base directory, replace namespace&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;// separators with directory separators in the relative class name, append&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;// with .php&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$file = $base_dir . str_replace(&#039;\\&#039;, &#039;/&#039;, $relative_class) . &#039;.php&#039;;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// if the file exists, require it&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;if (file_exists($file)) {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;require $file;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Autoloader function for production ====&lt;br /&gt;
Once you&#039;re moving your game to production, the autoloader function provided before isn&#039;t optimized. Once in production, the directory tree should not be modified, so you can change the earlier autoloader to a classmap based one. Basically, you build an associative array with the fully qualified classes names as keys and the filepath as the value. An example would look like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;spl_autoload_register(function ($class) {&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;static $classmap = array(&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:red&amp;gt;&amp;quot;SwHawk\\X\\&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;Factory\\AFactoryClass&amp;quot; =&amp;gt; __DIR__ . &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;&amp;quot;/../&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;Factory/AFactoryClass.php&amp;quot;,&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;);&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;if(array_key_exists($class)) {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;require $classmap[$class];&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;} else {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;return;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This autoloader is better suited to production since it won&#039;t use expensive calls like &amp;lt;code&amp;gt;file_exists($filename)&amp;lt;/code&amp;gt;. You can write the classmap by yourself, but it can be quite cumbersome, there is some tools like [https://github.com/hanneskod/classtools this project], or [https://github.com/gnugat/nomo-spaco this one], or even scripts detailed in this [https://stackoverflow.com/questions/22761554/how-to-get-all-class-names-inside-a-particular-namespace StackOverflow topic]&lt;br /&gt;
&lt;br /&gt;
== On the JS side ==&lt;br /&gt;
&lt;br /&gt;
BGA uses the dojo toolkit framework for most of its javascript code. Dojo comes with its own way of loading modules, which you can read about in more detail [https://dojotoolkit.org/documentation/tutorials/1.10/modules/ here] and [https://dojotoolkit.org/documentation/tutorials/1.10/modules_advanced/ here]. To put it simply, there are two ways you can go about this&lt;br /&gt;
&lt;br /&gt;
=== Write plain javascript ===&lt;br /&gt;
Should you wan to write plain javascript, you can easily do so. What you need to do is actually load the file like so in &amp;lt;code&amp;gt;X.js&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&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;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&amp;quot;./modules/path/to/firstfile.js&amp;quot;,&amp;lt;/span&amp;gt;        &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;//The first file with your JS code&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&amp;quot;./modules/path/to/secondfile.js&amp;quot;,&amp;lt;/span&amp;gt;       &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;//The second file with another part of your JS code&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
     ...&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
         constructor: function(){&lt;br /&gt;
             ...&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
According to the dojo toolkit documentation, you will then need to directly access what you defined in the files.&lt;br /&gt;
&lt;br /&gt;
=== Write an AMD module ===&lt;br /&gt;
You can take advantage of the toolkit&#039;s module system to declare dependencies between the differents files you&#039;ll be writing (modules in the toolkit&#039;s language). To be identified as modules, your Javascript files will need to have the following structure:&lt;br /&gt;
&lt;br /&gt;
==== Create a named new class ====&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/js/FirstModule.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;gt;&#039;&#039;&#039;define([&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo&amp;quot;,&amp;lt;/span&amp;gt;      &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Needed if you want to be able to use dojo methods such as dojo.place, etc.&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo/_base/declare&amp;quot;,&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;other dependencies...&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;],function(dojo, declare){&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;return declare(&amp;quot;className&amp;quot;,&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/*Parent classes that this class inherits, optional*/&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, {&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;&#039;&#039;&#039;/* static properties */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;let property1 = &amp;quot;value;&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;let property2 = 5;&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;constructor: function (args) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;&#039;&#039;&#039;/* instance properties */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;let property3 = 8;&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;let property4 = [ &amp;quot;arrayValue&amp;quot;, &amp;quot;arrayValue2&amp;quot; ]; &#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;method1: function (args) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;/* your code here */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
         &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;});&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then in the X.js file, you can use your newly created module like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&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;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/js/Firstmodule&amp;quot;,&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
     ...&lt;br /&gt;
     });&lt;br /&gt;
 });&lt;br /&gt;
&lt;br /&gt;
In your code, you can access your module&#039;s class and methods by doing so:&lt;br /&gt;
&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;let object = new className();&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;object.method1();&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;...&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This can lead to namespace collisions if you don&#039;t choose a namespace correctly, so you might want to take the same approach as described earlier for the PHP files for using a namespace.&lt;br /&gt;
&lt;br /&gt;
==== Create an anonymous ====&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/js/SecondModule.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;gt;&#039;&#039;&#039;define([&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo&amp;quot;,&amp;lt;/span&amp;gt;      &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Needed if you want to be able to use dojo methods such as dojo.place, etc.&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo/_base/declare&amp;quot;,&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;other dependencies...&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;],function(dojo, declare){&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;return declare(null,&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/*Parent classes that this class inherits, optional*/&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, {&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;&#039;&#039;&#039;/* static properties */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;let property1 = &amp;quot;value;&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;let property2 = 5;&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;constructor: function (args) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;&#039;&#039;&#039;/* instance properties */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;let property3 = 8;&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;let property4 = [ &amp;quot;arrayValue&amp;quot;, &amp;quot;arrayValue2&amp;quot; ]; &#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;method1: function (args) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;/* your code here */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
         &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;});&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then in the X.js file, you can use your newly created module like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&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;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/js/SecondModule&amp;quot;,&#039;&#039;&#039;&amp;lt;/span&amp;gt;      &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//Has to be inserted in the third position as we&#039;ll&#039;&#039;&#039;&lt;br /&gt;
                                             &#039;&#039;&#039;//need an identifier later, and the other modules don&#039;t need it, see code in the preceding subsection.&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, SecondModule&amp;lt;/span&amp;gt;  &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/* insert a reference here that you&#039;ll use throughout the JS file for this module */&amp;lt;/span&amp;gt;&#039;&#039;&#039;) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
     ...&lt;br /&gt;
     });&lt;br /&gt;
 });&lt;br /&gt;
&lt;br /&gt;
In your code, you can access your module&#039;s class and methods by doing so:&lt;br /&gt;
&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;let someValue = SecondModule.property3&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;SecondModule.method1();&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;...&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This can lead to namespace collisions if you don&#039;t choose a namespace correctly, so you might want to take the same approach as described earlier for the PHP files for using a namespace.&lt;br /&gt;
&lt;br /&gt;
==== Create a singleton object ====&lt;br /&gt;
&lt;br /&gt;
You can also create singleton objects by creating a module this way:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[[modules/js/singletonObject.js]]&lt;br /&gt;
define([&lt;br /&gt;
    &amp;quot;dojo&amp;quot;,&lt;br /&gt;
    ...&lt;br /&gt;
], function (dojo) {&lt;br /&gt;
    // Methods and variables defined in this part will not be available anywhere else than in this file&lt;br /&gt;
    let privateVariable = &amp;quot;someValue&amp;quot;;&lt;br /&gt;
    let privateFunction = function (args) {&lt;br /&gt;
        //some code here&lt;br /&gt;
    }&lt;br /&gt;
    return {&lt;br /&gt;
        firstMethod: function (args) {&lt;br /&gt;
            privateFunction(args);&lt;br /&gt;
            //some other code here&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To be used in the &amp;lt;code&amp;gt;X.js&amp;lt;/code&amp;gt; file, you must use the same method as in the [[#Create an anonymous class|previous section]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 *------&lt;br /&gt;
 * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
 * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
 *&lt;br /&gt;
 * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
 * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
 * -----&lt;br /&gt;
 *&lt;br /&gt;
 * X.js&lt;br /&gt;
 *&lt;br /&gt;
 * X user interface script&lt;br /&gt;
 * &lt;br /&gt;
 * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&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;./modules/js/SecondModule&amp;quot;,         //Has to be inserted in the third position as we&#039;ll need an identifier later, and the other modules don&#039;t need it, see code in the preceding subsection.&lt;br /&gt;
    &amp;quot;./modules/js/sigletonObject&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;./modules/js/Firstmodule&amp;quot;,&lt;br /&gt;
],&lt;br /&gt;
function (dojo, declare, SecondModule /* insert a reference here that you&#039;ll use throughout the JS file for this module */, singletonObject) {&lt;br /&gt;
    return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
    ...&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then you can access your code the same way as described in the [[#Create an anonymous class|previous section]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    singletonObject.firstMethod();&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Putting it all together ==&lt;br /&gt;
&#039;&#039;&#039;TODO&#039;&#039;&#039;&lt;/div&gt;</summary>
		<author><name>SwHawk</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=User:SwHawk/Create_Modular_Code&amp;diff=13592</id>
		<title>User:SwHawk/Create Modular Code</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=User:SwHawk/Create_Modular_Code&amp;diff=13592"/>
		<updated>2022-06-14T19:09:21Z</updated>

		<summary type="html">&lt;p&gt;SwHawk: /* Create an anonymous class */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{InfoBox|title=WIP|body=&#039;&#039;&#039;This article is a Work In Progress, please do not refer to it for production purposes&#039;&#039;&#039;}}&lt;br /&gt;
&lt;br /&gt;
This page will cover steps you can take as a BGA developer to make your code more modular and better organized. The way the framework is implemented makes the [[Main game logic: yourgamename.game.php|game logic]] and the [[Game interface logic: yourgamename.js|interface logic]] files very monolithic. While this is not a problem in itself, even simple to moderately complex game may require this files to be over 5k lines of code. Thus you can quickly become lost in all the functions you need to declare, where they are declared, and where they are called.&lt;br /&gt;
&lt;br /&gt;
But there are steps that you can follow to take advantage of PHP&#039;s Object Oriented Code and the dojo toolkit&#039;s AMD loader to organize your code in separate files. Let&#039;s see what&#039;s available:&lt;br /&gt;
&lt;br /&gt;
== Acknowledgements ==&lt;br /&gt;
&lt;br /&gt;
Writing this wiki article wouldn&#039;t have been possible without the help, work and insight of more experienced BGA developers:&lt;br /&gt;
* [https://boardgamearena.com/player?id=83846198 Tisaac]  (Discord user Tisaac Human Expert)&lt;br /&gt;
* [https://boardgamearena.com/player?id=85537631 bennygui] (Discord user bennygui)&lt;br /&gt;
* [https://boardgamearena.com/player?id=84125723 VictoriaLa] (Discord user VictoriaLa)&lt;br /&gt;
* Syarwin and [https://boardgamearena.com/player?id=84554161 quietmint] (for their Welcome To [https://github.com/Syarwin/bga-welcometo repository])&lt;br /&gt;
* [https://boardgamearena.com/player?id=84522426 Mogri] (Discord user Mogri)&lt;br /&gt;
&lt;br /&gt;
== Conventions ==&lt;br /&gt;
In the code blocks, code additions will be displayed in bold and green, and added comments will be displayed in bold and dark grey so that they stand out from the boilerplate code from a scratch project. Part in red should be aapted to reflect your project&#039;s structure.&lt;br /&gt;
&lt;br /&gt;
== On the PHP side ==&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt; vs &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; ===&lt;br /&gt;
Throughout this section, I&#039;ll make heavy use of PHP&#039;s &amp;lt;code&amp;gt;require_once&amp;lt;/code&amp;gt; control structure. Why am I using &amp;lt;code&amp;gt;require(_once)&amp;lt;/code&amp;gt; instead of &amp;lt;code&amp;gt;include_once&amp;lt;/code&amp;gt;? Because if an error exists in a PHP file that you try to &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt;, only a warning will be thrown, but the script will continue in spite of the error. Using &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; if the included file has an error, the script dies when the inclusion takes places, throwing a fatal error (&amp;lt;code&amp;gt;E_COMPILE_ERROR&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
That way, I&#039;m sure the classes, traits or interfaces I&#039;m including are syntax error free.&lt;br /&gt;
&lt;br /&gt;
=== Game logic methods ===&lt;br /&gt;
The way the framework is implemented, your game logic is gathered inside a class (&amp;lt;code&amp;gt;YourProjectName&amp;lt;/code&amp;gt;) extending the [[Table|&amp;lt;code&amp;gt;Table&amp;lt;/code&amp;gt; class]]. You define your methods there so that they may be called from other parts of the framework (as long as they&#039;re public methods obviously).&lt;br /&gt;
&lt;br /&gt;
But you can take advantage of [https://www.php.net/manual/en/language.oop5.traits.php PHP Traits]. In a nutshell, Traits are a collection of methods that can be reused in different classes, to avoid code duplication. Here we&#039;re not going to reuse them anywhere else than in the game class, but this little trick allows us to put methods definitions in other files, and in so doing to avoid monolithic code.&lt;br /&gt;
&lt;br /&gt;
Basically you create a Trait in th &amp;lt;code&amp;gt;/modules/&amp;lt;/code&amp;gt; directory, for instance:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/UtiltityFunctionsTrait.php]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;lt;?php&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;namespace YourProjectNamespace\Modules;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;trait UtilityFunctionsTrait {&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &#039;&#039;&#039;public function myFirstUtilityFunction($args)&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;{&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//Your code here&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;}&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Then you can include it in you project&#039;s &amp;lt;code&amp;gt;X.game.php&amp;lt;/code&amp;gt; file like so:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X_game.php]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;?php&lt;br /&gt;
  /**&lt;br /&gt;
   *------&lt;br /&gt;
   * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
   * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
   * &lt;br /&gt;
   * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
   * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
   * -----&lt;br /&gt;
   * &lt;br /&gt;
   * X.game.php&lt;br /&gt;
   *&lt;br /&gt;
   * This is the main file for your game logic.&lt;br /&gt;
   *&lt;br /&gt;
   * In this PHP file, you are going to defines the rules of the game.&lt;br /&gt;
   *&lt;br /&gt;
   */&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;require_once &#039;modules/UtilityFunctionsTrait.php&#039;; &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;   //Here we require the trait to be loaded when the class is loaded&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;use X\Modules\UtilityFunctionsTrait;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;                 //We import the trait to be used directly as UtilityFunctionsTraits,&#039;&#039;&#039;&lt;br /&gt;
                                                      &#039;&#039;&#039;//otherwise we would have to use the Fully qualified class name&#039;&#039;&#039;&lt;br /&gt;
                                                      &#039;&#039;&#039;//(YourProjectNamespace\Modules\UtilityFunctionsTrait)&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 class X extends Table&lt;br /&gt;
 {&lt;br /&gt;
 //...&lt;br /&gt;
 &lt;br /&gt;
 //////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
 //////////// Utility functions&lt;br /&gt;
 ////////////    &lt;br /&gt;
 &lt;br /&gt;
     /*&lt;br /&gt;
         In this space, you can put any utility methods useful for your game logic&lt;br /&gt;
     */&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;use UtilityFunctionsTrait;&#039;&#039;&#039;&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//Here we actually include the trait inside the class, making all the trait&#039;s methods&#039;&#039;&#039; &lt;br /&gt;
                                &#039;&#039;&#039;//available as class methods, keeping their visibility scope (so a private method&#039;&#039;&#039;&lt;br /&gt;
                                &#039;&#039;&#039;//is still private)&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Support classes ===&lt;br /&gt;
Basically, the same as traits, you put your classes definitions into files that live under the &amp;lt;code&amp;gt;/modules/&amp;lt;/code&amp;gt; directory (don&#039;t forget to namespace your classes), and then require them at the top of &amp;lt;code&amp;gt;X_game.php&amp;lt;/code&amp;gt;, and voilà, you&#039;re done&lt;br /&gt;
&lt;br /&gt;
=== Adding autoloader support ===&lt;br /&gt;
&lt;br /&gt;
==== Coding standards ====&lt;br /&gt;
Even for simple games, you might end up having a dozen of traits and support classes. You can require them all in your &amp;lt;code&amp;gt;X_game.php&amp;lt;/code&amp;gt;. Or you can use an autoloader, which will load the necessary classes and traits at runtime. There are two PSRs dealing with autloading standards (namely [https://www.php-fig.org/psr/psr-0 PSR-0] which is marked as deprecated and [https://www.php-fig.org/psr/psr-4 PSR-4]) which state that your namespaces should be a reflection of the directory structure of your project.&lt;br /&gt;
&lt;br /&gt;
Basically, when creating namespaces, you choose a namespace prefix. For example, you could use your BGA handle and the project name as a namespace prefix (would result in &amp;lt;code&amp;gt;\SwHawk\X&amp;lt;/code&amp;gt; in my case), and then the rest of the namespace would be the directory the file is in. I usually group classes and traits by the function they have in my project, so my &amp;lt;code&amp;gt;/modules/&amp;lt;/code&amp;gt; directory looks like that:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
modules/&lt;br /&gt;
    php/&lt;br /&gt;
        Factory/                      //Holds my factory classes&lt;br /&gt;
            AFactoryClass.php         //The namespace for this file would be \SwHawk\X\Factory, and the fully qualified class name would be \SwHawk\X\Factory\AFactoryClass&lt;br /&gt;
            ...&lt;br /&gt;
        Object/                       //Holds my support classes&lt;br /&gt;
            ObjectA.php               //The namespace for this file would be \SwHawk\X\Object, and the fully qualified class name would be \SwHawk\X\Object\ObjectA&lt;br /&gt;
            ...&lt;br /&gt;
        Traits/                       //Holds my traits&lt;br /&gt;
            UtilityFunctionsTrait.php //The namespace for this file would be \SwHawk\X\Traits, and the fully qualified class name would be \SwHawk\X\Traits\UtilityFunctionsTrait&lt;br /&gt;
            ...&lt;br /&gt;
        ...&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Autoloader function for development ====&lt;br /&gt;
While your project is under development, you usually create, move and remove classes as part of the development process. So you usually need an autoloading function that can handle a lot of flexibility. Basically once you import a class using the &amp;lt;code&amp;gt;use&amp;lt;/code&amp;gt; keyword, the autoloading function will determine which file to &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; using its fully qualified class name, and then &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt;. This function needs to be either defined or included at the top of &amp;lt;code&amp;gt;X_game.php&amp;lt;/code&amp;gt;. Such a function would have the following code (borrowed and adapted from [https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader-examples.md this repository]):&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;spl_autoload_register(function ($class) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// project-specific namespace prefix&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;, adapt to your needs&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;, remember that you must escape \ characters in double-quoted strings (hence the \\)&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$prefix = &#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;SwHawk\\X\\&amp;quot;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// base directory for the namespace prefix, this file would usually reside in the modules/php/includes/ directory, so the base directory for all my classes would be a level higher&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$base_dir = __DIR__ . &#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;&#039;&#039;&#039; &#039;/../&#039; &#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;gt;&#039;&#039;&#039;;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// does the class use the namespace prefix?&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$len = strlen($prefix);&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;if (strncmp($prefix, $class, $len) !== 0) {&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// no, move to the next registered autoloader&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;return;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// get the relative class name&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$relative_class = substr($class, $len);&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;// replace the namespace prefix with the base directory, replace namespace&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;// separators with directory separators in the relative class name, append&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;// with .php&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$file = $base_dir . str_replace(&#039;\\&#039;, &#039;/&#039;, $relative_class) . &#039;.php&#039;;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// if the file exists, require it&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;if (file_exists($file)) {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;require $file;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Autoloader function for production ====&lt;br /&gt;
Once you&#039;re moving your game to production, the autoloader function provided before isn&#039;t optimized. Once in production, the directory tree should not be modified, so you can change the earlier autoloader to a classmap based one. Basically, you build an associative array with the fully qualified classes names as keys and the filepath as the value. An example would look like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;spl_autoload_register(function ($class) {&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;static $classmap = array(&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:red&amp;gt;&amp;quot;SwHawk\\X\\&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;Factory\\AFactoryClass&amp;quot; =&amp;gt; __DIR__ . &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;&amp;quot;/../&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;Factory/AFactoryClass.php&amp;quot;,&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;);&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;if(array_key_exists($class)) {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;require $classmap[$class];&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;} else {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;return;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This autoloader is better suited to production since it won&#039;t use expensive calls like &amp;lt;code&amp;gt;file_exists($filename)&amp;lt;/code&amp;gt;. You can write the classmap by yourself, but it can be quite cumbersome, there is some tools like [https://github.com/hanneskod/classtools this project], or [https://github.com/gnugat/nomo-spaco this one], or even scripts detailed in this [https://stackoverflow.com/questions/22761554/how-to-get-all-class-names-inside-a-particular-namespace StackOverflow topic]&lt;br /&gt;
&lt;br /&gt;
== On the JS side ==&lt;br /&gt;
&lt;br /&gt;
BGA uses the dojo toolkit framework for most of its javascript code. Dojo comes with its own way of loading modules, which you can read about in more detail [https://dojotoolkit.org/documentation/tutorials/1.10/modules/ here] and [https://dojotoolkit.org/documentation/tutorials/1.10/modules_advanced/ here]. To put it simply, there are two ways you can go about this&lt;br /&gt;
&lt;br /&gt;
=== Write plain javascript ===&lt;br /&gt;
Should you wan to write plain javascript, you can easily do so. What you need to do is actually load the file like so in &amp;lt;code&amp;gt;X.js&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&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;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&amp;quot;./modules/path/to/firstfile.js&amp;quot;,&amp;lt;/span&amp;gt;        &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;//The first file with your JS code&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&amp;quot;./modules/path/to/secondfile.js&amp;quot;,&amp;lt;/span&amp;gt;       &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;//The second file with another part of your JS code&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
     ...&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
         constructor: function(){&lt;br /&gt;
             ...&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
According to the dojo toolkit documentation, you will then need to directly access what you defined in the files.&lt;br /&gt;
&lt;br /&gt;
=== Write an AMD module ===&lt;br /&gt;
You can take advantage of the toolkit&#039;s module system to declare dependencies between the differents files you&#039;ll be writing (modules in the toolkit&#039;s language). To be identified as modules, your Javascript files will need to have the following structure:&lt;br /&gt;
&lt;br /&gt;
==== Create a named new class ====&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/js/FirstModule.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;gt;&#039;&#039;&#039;define([&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo&amp;quot;,&amp;lt;/span&amp;gt;      &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Needed if you want to be able to use dojo methods such as dojo.place, etc.&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo/_base/declare&amp;quot;,&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;other dependencies...&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;],function(dojo, declare){&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;return declare(&amp;quot;className&amp;quot;,&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/*Parent classes that this class inherits, optional*/&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, {&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;&#039;&#039;&#039;/* static properties */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;let property1 = &amp;quot;value;&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;let property2 = 5;&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;constructor: function (args) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;&#039;&#039;&#039;/* instance properties */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;let property3 = 8;&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;let property4 = [ &amp;quot;arrayValue&amp;quot;, &amp;quot;arrayValue2&amp;quot; ]; &#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;method1: function (args) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;/* your code here */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
         &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;});&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then in the X.js file, you can use your newly created module like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&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;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/js/Firstmodule&amp;quot;,&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
     ...&lt;br /&gt;
     });&lt;br /&gt;
 });&lt;br /&gt;
&lt;br /&gt;
In your code, you can access your module&#039;s class and methods by doing so:&lt;br /&gt;
&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;let object = new className();&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;object.method1();&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;...&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This can lead to namespace collisions if you don&#039;t choose a namespace correctly, so you might want to take the same approach as described earlier for the PHP files for using a namespace.&lt;br /&gt;
&lt;br /&gt;
==== Create a named new class ====&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/js/SecondModule.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;gt;&#039;&#039;&#039;define([&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo&amp;quot;,&amp;lt;/span&amp;gt;      &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Needed if you want to be able to use dojo methods such as dojo.place, etc.&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo/_base/declare&amp;quot;,&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;other dependencies...&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;],function(dojo, declare){&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;return declare(null,&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/*Parent classes that this class inherits, optional*/&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, {&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;&#039;&#039;&#039;/* static properties */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;let property1 = &amp;quot;value;&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;let property2 = 5;&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;constructor: function (args) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;&#039;&#039;&#039;/* instance properties */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;let property3 = 8;&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;let property4 = [ &amp;quot;arrayValue&amp;quot;, &amp;quot;arrayValue2&amp;quot; ]; &#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;method1: function (args) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;/* your code here */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
         &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;});&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then in the X.js file, you can use your newly created module like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&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;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/js/SecondModule&amp;quot;,&#039;&#039;&#039;&amp;lt;/span&amp;gt;      &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//Has to be inserted in the third position as we&#039;ll&#039;&#039;&#039;&lt;br /&gt;
                                             &#039;&#039;&#039;//need an identifier later, and the other modules don&#039;t need it, see code in the preceding subsection.&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, SecondModule&amp;lt;/span&amp;gt;  &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/* insert a reference here that you&#039;ll use throughout the JS file for this module */&amp;lt;/span&amp;gt;&#039;&#039;&#039;) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
     ...&lt;br /&gt;
     });&lt;br /&gt;
 });&lt;br /&gt;
&lt;br /&gt;
In your code, you can access your module&#039;s class and methods by doing so:&lt;br /&gt;
&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;let someValue = SecondModule.property3&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;SecondModule.method1();&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;...&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This can lead to namespace collisions if you don&#039;t choose a namespace correctly, so you might want to take the same approach as described earlier for the PHP files for using a namespace.&lt;br /&gt;
&lt;br /&gt;
==== Create a singleton object ====&lt;br /&gt;
&lt;br /&gt;
You can also create singleton objects by creating a module this way:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[[modules/js/singletonObject.js]]&lt;br /&gt;
define([&lt;br /&gt;
    &amp;quot;dojo&amp;quot;,&lt;br /&gt;
    ...&lt;br /&gt;
], function (dojo) {&lt;br /&gt;
    // Methods and variables defined in this part will not be available anywhere else than in this file&lt;br /&gt;
    let privateVariable = &amp;quot;someValue&amp;quot;;&lt;br /&gt;
    let privateFunction = function (args) {&lt;br /&gt;
        //some code here&lt;br /&gt;
    }&lt;br /&gt;
    return {&lt;br /&gt;
        firstMethod: function (args) {&lt;br /&gt;
            privateFunction(args);&lt;br /&gt;
            //some other code here&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To be used in the &amp;lt;code&amp;gt;X.js&amp;lt;/code&amp;gt; file, you must use the same method as in the [[#Create an anonymous class|previous section]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 *------&lt;br /&gt;
 * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
 * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
 *&lt;br /&gt;
 * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
 * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
 * -----&lt;br /&gt;
 *&lt;br /&gt;
 * X.js&lt;br /&gt;
 *&lt;br /&gt;
 * X user interface script&lt;br /&gt;
 * &lt;br /&gt;
 * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&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;./modules/js/SecondModule&amp;quot;,         //Has to be inserted in the third position as we&#039;ll need an identifier later, and the other modules don&#039;t need it, see code in the preceding subsection.&lt;br /&gt;
    &amp;quot;./modules/js/sigletonObject&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;./modules/js/Firstmodule&amp;quot;,&lt;br /&gt;
],&lt;br /&gt;
function (dojo, declare, SecondModule /* insert a reference here that you&#039;ll use throughout the JS file for this module */, singletonObject) {&lt;br /&gt;
    return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
    ...&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then you can access your code the same way as described in the [[#Create an anonymous class|previous section]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    singletonObject.firstMethod();&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Putting it all together ==&lt;br /&gt;
&#039;&#039;&#039;TODO&#039;&#039;&#039;&lt;/div&gt;</summary>
		<author><name>SwHawk</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=User:SwHawk/Create_Modular_Code&amp;diff=13591</id>
		<title>User:SwHawk/Create Modular Code</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=User:SwHawk/Create_Modular_Code&amp;diff=13591"/>
		<updated>2022-06-14T19:03:37Z</updated>

		<summary type="html">&lt;p&gt;SwHawk: /* Create a named new class */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{InfoBox|title=WIP|body=&#039;&#039;&#039;This article is a Work In Progress, please do not refer to it for production purposes&#039;&#039;&#039;}}&lt;br /&gt;
&lt;br /&gt;
This page will cover steps you can take as a BGA developer to make your code more modular and better organized. The way the framework is implemented makes the [[Main game logic: yourgamename.game.php|game logic]] and the [[Game interface logic: yourgamename.js|interface logic]] files very monolithic. While this is not a problem in itself, even simple to moderately complex game may require this files to be over 5k lines of code. Thus you can quickly become lost in all the functions you need to declare, where they are declared, and where they are called.&lt;br /&gt;
&lt;br /&gt;
But there are steps that you can follow to take advantage of PHP&#039;s Object Oriented Code and the dojo toolkit&#039;s AMD loader to organize your code in separate files. Let&#039;s see what&#039;s available:&lt;br /&gt;
&lt;br /&gt;
== Acknowledgements ==&lt;br /&gt;
&lt;br /&gt;
Writing this wiki article wouldn&#039;t have been possible without the help, work and insight of more experienced BGA developers:&lt;br /&gt;
* [https://boardgamearena.com/player?id=83846198 Tisaac]  (Discord user Tisaac Human Expert)&lt;br /&gt;
* [https://boardgamearena.com/player?id=85537631 bennygui] (Discord user bennygui)&lt;br /&gt;
* [https://boardgamearena.com/player?id=84125723 VictoriaLa] (Discord user VictoriaLa)&lt;br /&gt;
* Syarwin and [https://boardgamearena.com/player?id=84554161 quietmint] (for their Welcome To [https://github.com/Syarwin/bga-welcometo repository])&lt;br /&gt;
* [https://boardgamearena.com/player?id=84522426 Mogri] (Discord user Mogri)&lt;br /&gt;
&lt;br /&gt;
== Conventions ==&lt;br /&gt;
In the code blocks, code additions will be displayed in bold and green, and added comments will be displayed in bold and dark grey so that they stand out from the boilerplate code from a scratch project. Part in red should be aapted to reflect your project&#039;s structure.&lt;br /&gt;
&lt;br /&gt;
== On the PHP side ==&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt; vs &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; ===&lt;br /&gt;
Throughout this section, I&#039;ll make heavy use of PHP&#039;s &amp;lt;code&amp;gt;require_once&amp;lt;/code&amp;gt; control structure. Why am I using &amp;lt;code&amp;gt;require(_once)&amp;lt;/code&amp;gt; instead of &amp;lt;code&amp;gt;include_once&amp;lt;/code&amp;gt;? Because if an error exists in a PHP file that you try to &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt;, only a warning will be thrown, but the script will continue in spite of the error. Using &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; if the included file has an error, the script dies when the inclusion takes places, throwing a fatal error (&amp;lt;code&amp;gt;E_COMPILE_ERROR&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
That way, I&#039;m sure the classes, traits or interfaces I&#039;m including are syntax error free.&lt;br /&gt;
&lt;br /&gt;
=== Game logic methods ===&lt;br /&gt;
The way the framework is implemented, your game logic is gathered inside a class (&amp;lt;code&amp;gt;YourProjectName&amp;lt;/code&amp;gt;) extending the [[Table|&amp;lt;code&amp;gt;Table&amp;lt;/code&amp;gt; class]]. You define your methods there so that they may be called from other parts of the framework (as long as they&#039;re public methods obviously).&lt;br /&gt;
&lt;br /&gt;
But you can take advantage of [https://www.php.net/manual/en/language.oop5.traits.php PHP Traits]. In a nutshell, Traits are a collection of methods that can be reused in different classes, to avoid code duplication. Here we&#039;re not going to reuse them anywhere else than in the game class, but this little trick allows us to put methods definitions in other files, and in so doing to avoid monolithic code.&lt;br /&gt;
&lt;br /&gt;
Basically you create a Trait in th &amp;lt;code&amp;gt;/modules/&amp;lt;/code&amp;gt; directory, for instance:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/UtiltityFunctionsTrait.php]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;lt;?php&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;namespace YourProjectNamespace\Modules;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;trait UtilityFunctionsTrait {&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &#039;&#039;&#039;public function myFirstUtilityFunction($args)&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;{&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//Your code here&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;}&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Then you can include it in you project&#039;s &amp;lt;code&amp;gt;X.game.php&amp;lt;/code&amp;gt; file like so:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X_game.php]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;?php&lt;br /&gt;
  /**&lt;br /&gt;
   *------&lt;br /&gt;
   * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
   * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
   * &lt;br /&gt;
   * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
   * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
   * -----&lt;br /&gt;
   * &lt;br /&gt;
   * X.game.php&lt;br /&gt;
   *&lt;br /&gt;
   * This is the main file for your game logic.&lt;br /&gt;
   *&lt;br /&gt;
   * In this PHP file, you are going to defines the rules of the game.&lt;br /&gt;
   *&lt;br /&gt;
   */&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;require_once &#039;modules/UtilityFunctionsTrait.php&#039;; &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;   //Here we require the trait to be loaded when the class is loaded&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;use X\Modules\UtilityFunctionsTrait;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;                 //We import the trait to be used directly as UtilityFunctionsTraits,&#039;&#039;&#039;&lt;br /&gt;
                                                      &#039;&#039;&#039;//otherwise we would have to use the Fully qualified class name&#039;&#039;&#039;&lt;br /&gt;
                                                      &#039;&#039;&#039;//(YourProjectNamespace\Modules\UtilityFunctionsTrait)&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 class X extends Table&lt;br /&gt;
 {&lt;br /&gt;
 //...&lt;br /&gt;
 &lt;br /&gt;
 //////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
 //////////// Utility functions&lt;br /&gt;
 ////////////    &lt;br /&gt;
 &lt;br /&gt;
     /*&lt;br /&gt;
         In this space, you can put any utility methods useful for your game logic&lt;br /&gt;
     */&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;use UtilityFunctionsTrait;&#039;&#039;&#039;&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//Here we actually include the trait inside the class, making all the trait&#039;s methods&#039;&#039;&#039; &lt;br /&gt;
                                &#039;&#039;&#039;//available as class methods, keeping their visibility scope (so a private method&#039;&#039;&#039;&lt;br /&gt;
                                &#039;&#039;&#039;//is still private)&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Support classes ===&lt;br /&gt;
Basically, the same as traits, you put your classes definitions into files that live under the &amp;lt;code&amp;gt;/modules/&amp;lt;/code&amp;gt; directory (don&#039;t forget to namespace your classes), and then require them at the top of &amp;lt;code&amp;gt;X_game.php&amp;lt;/code&amp;gt;, and voilà, you&#039;re done&lt;br /&gt;
&lt;br /&gt;
=== Adding autoloader support ===&lt;br /&gt;
&lt;br /&gt;
==== Coding standards ====&lt;br /&gt;
Even for simple games, you might end up having a dozen of traits and support classes. You can require them all in your &amp;lt;code&amp;gt;X_game.php&amp;lt;/code&amp;gt;. Or you can use an autoloader, which will load the necessary classes and traits at runtime. There are two PSRs dealing with autloading standards (namely [https://www.php-fig.org/psr/psr-0 PSR-0] which is marked as deprecated and [https://www.php-fig.org/psr/psr-4 PSR-4]) which state that your namespaces should be a reflection of the directory structure of your project.&lt;br /&gt;
&lt;br /&gt;
Basically, when creating namespaces, you choose a namespace prefix. For example, you could use your BGA handle and the project name as a namespace prefix (would result in &amp;lt;code&amp;gt;\SwHawk\X&amp;lt;/code&amp;gt; in my case), and then the rest of the namespace would be the directory the file is in. I usually group classes and traits by the function they have in my project, so my &amp;lt;code&amp;gt;/modules/&amp;lt;/code&amp;gt; directory looks like that:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
modules/&lt;br /&gt;
    php/&lt;br /&gt;
        Factory/                      //Holds my factory classes&lt;br /&gt;
            AFactoryClass.php         //The namespace for this file would be \SwHawk\X\Factory, and the fully qualified class name would be \SwHawk\X\Factory\AFactoryClass&lt;br /&gt;
            ...&lt;br /&gt;
        Object/                       //Holds my support classes&lt;br /&gt;
            ObjectA.php               //The namespace for this file would be \SwHawk\X\Object, and the fully qualified class name would be \SwHawk\X\Object\ObjectA&lt;br /&gt;
            ...&lt;br /&gt;
        Traits/                       //Holds my traits&lt;br /&gt;
            UtilityFunctionsTrait.php //The namespace for this file would be \SwHawk\X\Traits, and the fully qualified class name would be \SwHawk\X\Traits\UtilityFunctionsTrait&lt;br /&gt;
            ...&lt;br /&gt;
        ...&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Autoloader function for development ====&lt;br /&gt;
While your project is under development, you usually create, move and remove classes as part of the development process. So you usually need an autoloading function that can handle a lot of flexibility. Basically once you import a class using the &amp;lt;code&amp;gt;use&amp;lt;/code&amp;gt; keyword, the autoloading function will determine which file to &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; using its fully qualified class name, and then &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt;. This function needs to be either defined or included at the top of &amp;lt;code&amp;gt;X_game.php&amp;lt;/code&amp;gt;. Such a function would have the following code (borrowed and adapted from [https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader-examples.md this repository]):&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;spl_autoload_register(function ($class) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// project-specific namespace prefix&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;, adapt to your needs&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;, remember that you must escape \ characters in double-quoted strings (hence the \\)&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$prefix = &#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;SwHawk\\X\\&amp;quot;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// base directory for the namespace prefix, this file would usually reside in the modules/php/includes/ directory, so the base directory for all my classes would be a level higher&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$base_dir = __DIR__ . &#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;&#039;&#039;&#039; &#039;/../&#039; &#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;gt;&#039;&#039;&#039;;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// does the class use the namespace prefix?&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$len = strlen($prefix);&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;if (strncmp($prefix, $class, $len) !== 0) {&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// no, move to the next registered autoloader&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;return;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// get the relative class name&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$relative_class = substr($class, $len);&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;// replace the namespace prefix with the base directory, replace namespace&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;// separators with directory separators in the relative class name, append&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;// with .php&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$file = $base_dir . str_replace(&#039;\\&#039;, &#039;/&#039;, $relative_class) . &#039;.php&#039;;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// if the file exists, require it&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;if (file_exists($file)) {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;require $file;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Autoloader function for production ====&lt;br /&gt;
Once you&#039;re moving your game to production, the autoloader function provided before isn&#039;t optimized. Once in production, the directory tree should not be modified, so you can change the earlier autoloader to a classmap based one. Basically, you build an associative array with the fully qualified classes names as keys and the filepath as the value. An example would look like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;spl_autoload_register(function ($class) {&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;static $classmap = array(&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:red&amp;gt;&amp;quot;SwHawk\\X\\&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;Factory\\AFactoryClass&amp;quot; =&amp;gt; __DIR__ . &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;&amp;quot;/../&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;Factory/AFactoryClass.php&amp;quot;,&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;);&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;if(array_key_exists($class)) {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;require $classmap[$class];&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;} else {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;return;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This autoloader is better suited to production since it won&#039;t use expensive calls like &amp;lt;code&amp;gt;file_exists($filename)&amp;lt;/code&amp;gt;. You can write the classmap by yourself, but it can be quite cumbersome, there is some tools like [https://github.com/hanneskod/classtools this project], or [https://github.com/gnugat/nomo-spaco this one], or even scripts detailed in this [https://stackoverflow.com/questions/22761554/how-to-get-all-class-names-inside-a-particular-namespace StackOverflow topic]&lt;br /&gt;
&lt;br /&gt;
== On the JS side ==&lt;br /&gt;
&lt;br /&gt;
BGA uses the dojo toolkit framework for most of its javascript code. Dojo comes with its own way of loading modules, which you can read about in more detail [https://dojotoolkit.org/documentation/tutorials/1.10/modules/ here] and [https://dojotoolkit.org/documentation/tutorials/1.10/modules_advanced/ here]. To put it simply, there are two ways you can go about this&lt;br /&gt;
&lt;br /&gt;
=== Write plain javascript ===&lt;br /&gt;
Should you wan to write plain javascript, you can easily do so. What you need to do is actually load the file like so in &amp;lt;code&amp;gt;X.js&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&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;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&amp;quot;./modules/path/to/firstfile.js&amp;quot;,&amp;lt;/span&amp;gt;        &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;//The first file with your JS code&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&amp;quot;./modules/path/to/secondfile.js&amp;quot;,&amp;lt;/span&amp;gt;       &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;//The second file with another part of your JS code&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
     ...&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
         constructor: function(){&lt;br /&gt;
             ...&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
According to the dojo toolkit documentation, you will then need to directly access what you defined in the files.&lt;br /&gt;
&lt;br /&gt;
=== Write an AMD module ===&lt;br /&gt;
You can take advantage of the toolkit&#039;s module system to declare dependencies between the differents files you&#039;ll be writing (modules in the toolkit&#039;s language). To be identified as modules, your Javascript files will need to have the following structure:&lt;br /&gt;
&lt;br /&gt;
==== Create a named new class ====&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/js/FirstModule.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;gt;&#039;&#039;&#039;define([&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo&amp;quot;,&amp;lt;/span&amp;gt;      &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;//Needed if you want to be able to use dojo methods such as dojo.place, etc.&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;&amp;quot;dojo/_base/declare&amp;quot;,&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;other dependencies...&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;],function(dojo, declare){&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;return declare(&amp;quot;className&amp;quot;,&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;/*Parent classes that this class inherits, optional*/&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;, {&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;&#039;&#039;&#039;/* static properties */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;let property1 = &amp;quot;value;&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;let property2 = 5;&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;constructor: function (args) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;&#039;&#039;&#039;/* instance properties */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;let property3 = 8;&#039;&#039;&#039;&lt;br /&gt;
             &#039;&#039;&#039;let property4 = [ &amp;quot;arrayValue&amp;quot;, &amp;quot;arrayValue2&amp;quot; ]; &#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;method1: function (args) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;/* your code here */&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
         &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;});&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then in the X.js file, you can use your newly created module like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&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;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;./modules/js/Firstmodule&amp;quot;,&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
     ...&lt;br /&gt;
     });&lt;br /&gt;
 });&lt;br /&gt;
&lt;br /&gt;
In your code, you can access your module&#039;s class and methods by doing so:&lt;br /&gt;
&lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;let object = new className();&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;object.method1();&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;...&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This can lead to namespace collisions if you don&#039;t choose a namespace correctly, so you might want to take the same approach as described earlier for the PHP files for using a namespace.&lt;br /&gt;
&lt;br /&gt;
==== Create an anonymous class ====&lt;br /&gt;
&lt;br /&gt;
This is the recommended way according to the dojo toolkit documentation, but it requires a bit more modification than the previous method:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[[modules/js/SecondModule.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
define([&lt;br /&gt;
    &amp;quot;dojo&amp;quot;,&lt;br /&gt;
    &amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
    other dependencies...&lt;br /&gt;
],function(dojo, declare){&lt;br /&gt;
    return declare(null, /*Parent classes that this class inherits, optional*/, {&lt;br /&gt;
        /* static properties */&lt;br /&gt;
        let property1 = &amp;quot;value;&lt;br /&gt;
        let property2 = 5;&lt;br /&gt;
        constructor: function (args) {&lt;br /&gt;
            /* instance properties */&lt;br /&gt;
            let property3 = 8;&lt;br /&gt;
            let property4 = [ &amp;quot;arrayValue&amp;quot;, &amp;quot;arrayValue2&amp;quot; ]; &lt;br /&gt;
        }&lt;br /&gt;
        method1: function (args) {&lt;br /&gt;
            /* your code here */&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;
Then in the X.js file, you can use your newly created module like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 *------&lt;br /&gt;
 * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
 * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
 *&lt;br /&gt;
 * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
 * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
 * -----&lt;br /&gt;
 *&lt;br /&gt;
 * X.js&lt;br /&gt;
 *&lt;br /&gt;
 * X user interface script&lt;br /&gt;
 * &lt;br /&gt;
 * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&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;./modules/js/SecondModule&amp;quot;,         //Has to be inserted in the third position as we&#039;ll need an identifier later, and the other modules don&#039;t need it, see code in the preceding subsection. &lt;br /&gt;
    &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
    &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
    &amp;quot;./modules/js/Firstmodule&amp;quot;,&lt;br /&gt;
],&lt;br /&gt;
function (dojo, declare, SecondModule /* insert a reference here that you&#039;ll use throughout the JS file for this module */) {&lt;br /&gt;
    return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
    ...&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In your code, you can then access your module&#039;s class and methods by doing so:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    let someValue = SecondModule.property3&lt;br /&gt;
    SecondModule.method1();&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Create a singleton object ====&lt;br /&gt;
&lt;br /&gt;
You can also create singleton objects by creating a module this way:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[[modules/js/singletonObject.js]]&lt;br /&gt;
define([&lt;br /&gt;
    &amp;quot;dojo&amp;quot;,&lt;br /&gt;
    ...&lt;br /&gt;
], function (dojo) {&lt;br /&gt;
    // Methods and variables defined in this part will not be available anywhere else than in this file&lt;br /&gt;
    let privateVariable = &amp;quot;someValue&amp;quot;;&lt;br /&gt;
    let privateFunction = function (args) {&lt;br /&gt;
        //some code here&lt;br /&gt;
    }&lt;br /&gt;
    return {&lt;br /&gt;
        firstMethod: function (args) {&lt;br /&gt;
            privateFunction(args);&lt;br /&gt;
            //some other code here&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To be used in the &amp;lt;code&amp;gt;X.js&amp;lt;/code&amp;gt; file, you must use the same method as in the [[#Create an anonymous class|previous section]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 *------&lt;br /&gt;
 * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
 * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
 *&lt;br /&gt;
 * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
 * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
 * -----&lt;br /&gt;
 *&lt;br /&gt;
 * X.js&lt;br /&gt;
 *&lt;br /&gt;
 * X user interface script&lt;br /&gt;
 * &lt;br /&gt;
 * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&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;./modules/js/SecondModule&amp;quot;,         //Has to be inserted in the third position as we&#039;ll need an identifier later, and the other modules don&#039;t need it, see code in the preceding subsection.&lt;br /&gt;
    &amp;quot;./modules/js/sigletonObject&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;./modules/js/Firstmodule&amp;quot;,&lt;br /&gt;
],&lt;br /&gt;
function (dojo, declare, SecondModule /* insert a reference here that you&#039;ll use throughout the JS file for this module */, singletonObject) {&lt;br /&gt;
    return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
    ...&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then you can access your code the same way as described in the [[#Create an anonymous class|previous section]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    singletonObject.firstMethod();&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Putting it all together ==&lt;br /&gt;
&#039;&#039;&#039;TODO&#039;&#039;&#039;&lt;/div&gt;</summary>
		<author><name>SwHawk</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=User:SwHawk/Create_Modular_Code&amp;diff=13590</id>
		<title>User:SwHawk/Create Modular Code</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=User:SwHawk/Create_Modular_Code&amp;diff=13590"/>
		<updated>2022-06-14T18:54:24Z</updated>

		<summary type="html">&lt;p&gt;SwHawk: /* Write plain javascript */ Color in code block&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{InfoBox|title=WIP|body=&#039;&#039;&#039;This article is a Work In Progress, please do not refer to it for production purposes&#039;&#039;&#039;}}&lt;br /&gt;
&lt;br /&gt;
This page will cover steps you can take as a BGA developer to make your code more modular and better organized. The way the framework is implemented makes the [[Main game logic: yourgamename.game.php|game logic]] and the [[Game interface logic: yourgamename.js|interface logic]] files very monolithic. While this is not a problem in itself, even simple to moderately complex game may require this files to be over 5k lines of code. Thus you can quickly become lost in all the functions you need to declare, where they are declared, and where they are called.&lt;br /&gt;
&lt;br /&gt;
But there are steps that you can follow to take advantage of PHP&#039;s Object Oriented Code and the dojo toolkit&#039;s AMD loader to organize your code in separate files. Let&#039;s see what&#039;s available:&lt;br /&gt;
&lt;br /&gt;
== Acknowledgements ==&lt;br /&gt;
&lt;br /&gt;
Writing this wiki article wouldn&#039;t have been possible without the help, work and insight of more experienced BGA developers:&lt;br /&gt;
* [https://boardgamearena.com/player?id=83846198 Tisaac]  (Discord user Tisaac Human Expert)&lt;br /&gt;
* [https://boardgamearena.com/player?id=85537631 bennygui] (Discord user bennygui)&lt;br /&gt;
* [https://boardgamearena.com/player?id=84125723 VictoriaLa] (Discord user VictoriaLa)&lt;br /&gt;
* Syarwin and [https://boardgamearena.com/player?id=84554161 quietmint] (for their Welcome To [https://github.com/Syarwin/bga-welcometo repository])&lt;br /&gt;
* [https://boardgamearena.com/player?id=84522426 Mogri] (Discord user Mogri)&lt;br /&gt;
&lt;br /&gt;
== Conventions ==&lt;br /&gt;
In the code blocks, code additions will be displayed in bold and green, and added comments will be displayed in bold and dark grey so that they stand out from the boilerplate code from a scratch project. Part in red should be aapted to reflect your project&#039;s structure.&lt;br /&gt;
&lt;br /&gt;
== On the PHP side ==&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt; vs &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; ===&lt;br /&gt;
Throughout this section, I&#039;ll make heavy use of PHP&#039;s &amp;lt;code&amp;gt;require_once&amp;lt;/code&amp;gt; control structure. Why am I using &amp;lt;code&amp;gt;require(_once)&amp;lt;/code&amp;gt; instead of &amp;lt;code&amp;gt;include_once&amp;lt;/code&amp;gt;? Because if an error exists in a PHP file that you try to &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt;, only a warning will be thrown, but the script will continue in spite of the error. Using &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; if the included file has an error, the script dies when the inclusion takes places, throwing a fatal error (&amp;lt;code&amp;gt;E_COMPILE_ERROR&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
That way, I&#039;m sure the classes, traits or interfaces I&#039;m including are syntax error free.&lt;br /&gt;
&lt;br /&gt;
=== Game logic methods ===&lt;br /&gt;
The way the framework is implemented, your game logic is gathered inside a class (&amp;lt;code&amp;gt;YourProjectName&amp;lt;/code&amp;gt;) extending the [[Table|&amp;lt;code&amp;gt;Table&amp;lt;/code&amp;gt; class]]. You define your methods there so that they may be called from other parts of the framework (as long as they&#039;re public methods obviously).&lt;br /&gt;
&lt;br /&gt;
But you can take advantage of [https://www.php.net/manual/en/language.oop5.traits.php PHP Traits]. In a nutshell, Traits are a collection of methods that can be reused in different classes, to avoid code duplication. Here we&#039;re not going to reuse them anywhere else than in the game class, but this little trick allows us to put methods definitions in other files, and in so doing to avoid monolithic code.&lt;br /&gt;
&lt;br /&gt;
Basically you create a Trait in th &amp;lt;code&amp;gt;/modules/&amp;lt;/code&amp;gt; directory, for instance:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/UtiltityFunctionsTrait.php]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;lt;?php&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;namespace YourProjectNamespace\Modules;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;trait UtilityFunctionsTrait {&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &#039;&#039;&#039;public function myFirstUtilityFunction($args)&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;{&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//Your code here&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;}&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Then you can include it in you project&#039;s &amp;lt;code&amp;gt;X.game.php&amp;lt;/code&amp;gt; file like so:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X_game.php]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;?php&lt;br /&gt;
  /**&lt;br /&gt;
   *------&lt;br /&gt;
   * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
   * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
   * &lt;br /&gt;
   * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
   * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
   * -----&lt;br /&gt;
   * &lt;br /&gt;
   * X.game.php&lt;br /&gt;
   *&lt;br /&gt;
   * This is the main file for your game logic.&lt;br /&gt;
   *&lt;br /&gt;
   * In this PHP file, you are going to defines the rules of the game.&lt;br /&gt;
   *&lt;br /&gt;
   */&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;require_once &#039;modules/UtilityFunctionsTrait.php&#039;; &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;   //Here we require the trait to be loaded when the class is loaded&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;use X\Modules\UtilityFunctionsTrait;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;                 //We import the trait to be used directly as UtilityFunctionsTraits,&#039;&#039;&#039;&lt;br /&gt;
                                                      &#039;&#039;&#039;//otherwise we would have to use the Fully qualified class name&#039;&#039;&#039;&lt;br /&gt;
                                                      &#039;&#039;&#039;//(YourProjectNamespace\Modules\UtilityFunctionsTrait)&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 class X extends Table&lt;br /&gt;
 {&lt;br /&gt;
 //...&lt;br /&gt;
 &lt;br /&gt;
 //////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
 //////////// Utility functions&lt;br /&gt;
 ////////////    &lt;br /&gt;
 &lt;br /&gt;
     /*&lt;br /&gt;
         In this space, you can put any utility methods useful for your game logic&lt;br /&gt;
     */&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;use UtilityFunctionsTrait;&#039;&#039;&#039;&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//Here we actually include the trait inside the class, making all the trait&#039;s methods&#039;&#039;&#039; &lt;br /&gt;
                                &#039;&#039;&#039;//available as class methods, keeping their visibility scope (so a private method&#039;&#039;&#039;&lt;br /&gt;
                                &#039;&#039;&#039;//is still private)&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Support classes ===&lt;br /&gt;
Basically, the same as traits, you put your classes definitions into files that live under the &amp;lt;code&amp;gt;/modules/&amp;lt;/code&amp;gt; directory (don&#039;t forget to namespace your classes), and then require them at the top of &amp;lt;code&amp;gt;X_game.php&amp;lt;/code&amp;gt;, and voilà, you&#039;re done&lt;br /&gt;
&lt;br /&gt;
=== Adding autoloader support ===&lt;br /&gt;
&lt;br /&gt;
==== Coding standards ====&lt;br /&gt;
Even for simple games, you might end up having a dozen of traits and support classes. You can require them all in your &amp;lt;code&amp;gt;X_game.php&amp;lt;/code&amp;gt;. Or you can use an autoloader, which will load the necessary classes and traits at runtime. There are two PSRs dealing with autloading standards (namely [https://www.php-fig.org/psr/psr-0 PSR-0] which is marked as deprecated and [https://www.php-fig.org/psr/psr-4 PSR-4]) which state that your namespaces should be a reflection of the directory structure of your project.&lt;br /&gt;
&lt;br /&gt;
Basically, when creating namespaces, you choose a namespace prefix. For example, you could use your BGA handle and the project name as a namespace prefix (would result in &amp;lt;code&amp;gt;\SwHawk\X&amp;lt;/code&amp;gt; in my case), and then the rest of the namespace would be the directory the file is in. I usually group classes and traits by the function they have in my project, so my &amp;lt;code&amp;gt;/modules/&amp;lt;/code&amp;gt; directory looks like that:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
modules/&lt;br /&gt;
    php/&lt;br /&gt;
        Factory/                      //Holds my factory classes&lt;br /&gt;
            AFactoryClass.php         //The namespace for this file would be \SwHawk\X\Factory, and the fully qualified class name would be \SwHawk\X\Factory\AFactoryClass&lt;br /&gt;
            ...&lt;br /&gt;
        Object/                       //Holds my support classes&lt;br /&gt;
            ObjectA.php               //The namespace for this file would be \SwHawk\X\Object, and the fully qualified class name would be \SwHawk\X\Object\ObjectA&lt;br /&gt;
            ...&lt;br /&gt;
        Traits/                       //Holds my traits&lt;br /&gt;
            UtilityFunctionsTrait.php //The namespace for this file would be \SwHawk\X\Traits, and the fully qualified class name would be \SwHawk\X\Traits\UtilityFunctionsTrait&lt;br /&gt;
            ...&lt;br /&gt;
        ...&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Autoloader function for development ====&lt;br /&gt;
While your project is under development, you usually create, move and remove classes as part of the development process. So you usually need an autoloading function that can handle a lot of flexibility. Basically once you import a class using the &amp;lt;code&amp;gt;use&amp;lt;/code&amp;gt; keyword, the autoloading function will determine which file to &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; using its fully qualified class name, and then &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt;. This function needs to be either defined or included at the top of &amp;lt;code&amp;gt;X_game.php&amp;lt;/code&amp;gt;. Such a function would have the following code (borrowed and adapted from [https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader-examples.md this repository]):&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;spl_autoload_register(function ($class) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// project-specific namespace prefix&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;, adapt to your needs&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;, remember that you must escape \ characters in double-quoted strings (hence the \\)&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$prefix = &#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;SwHawk\\X\\&amp;quot;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// base directory for the namespace prefix, this file would usually reside in the modules/php/includes/ directory, so the base directory for all my classes would be a level higher&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$base_dir = __DIR__ . &#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;&#039;&#039;&#039; &#039;/../&#039; &#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;gt;&#039;&#039;&#039;;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// does the class use the namespace prefix?&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$len = strlen($prefix);&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;if (strncmp($prefix, $class, $len) !== 0) {&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// no, move to the next registered autoloader&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;return;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// get the relative class name&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$relative_class = substr($class, $len);&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;// replace the namespace prefix with the base directory, replace namespace&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;// separators with directory separators in the relative class name, append&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;// with .php&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$file = $base_dir . str_replace(&#039;\\&#039;, &#039;/&#039;, $relative_class) . &#039;.php&#039;;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// if the file exists, require it&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;if (file_exists($file)) {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;require $file;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Autoloader function for production ====&lt;br /&gt;
Once you&#039;re moving your game to production, the autoloader function provided before isn&#039;t optimized. Once in production, the directory tree should not be modified, so you can change the earlier autoloader to a classmap based one. Basically, you build an associative array with the fully qualified classes names as keys and the filepath as the value. An example would look like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;spl_autoload_register(function ($class) {&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;static $classmap = array(&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:red&amp;gt;&amp;quot;SwHawk\\X\\&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;Factory\\AFactoryClass&amp;quot; =&amp;gt; __DIR__ . &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;&amp;quot;/../&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;Factory/AFactoryClass.php&amp;quot;,&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;);&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;if(array_key_exists($class)) {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;require $classmap[$class];&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;} else {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;return;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This autoloader is better suited to production since it won&#039;t use expensive calls like &amp;lt;code&amp;gt;file_exists($filename)&amp;lt;/code&amp;gt;. You can write the classmap by yourself, but it can be quite cumbersome, there is some tools like [https://github.com/hanneskod/classtools this project], or [https://github.com/gnugat/nomo-spaco this one], or even scripts detailed in this [https://stackoverflow.com/questions/22761554/how-to-get-all-class-names-inside-a-particular-namespace StackOverflow topic]&lt;br /&gt;
&lt;br /&gt;
== On the JS side ==&lt;br /&gt;
&lt;br /&gt;
BGA uses the dojo toolkit framework for most of its javascript code. Dojo comes with its own way of loading modules, which you can read about in more detail [https://dojotoolkit.org/documentation/tutorials/1.10/modules/ here] and [https://dojotoolkit.org/documentation/tutorials/1.10/modules_advanced/ here]. To put it simply, there are two ways you can go about this&lt;br /&gt;
&lt;br /&gt;
=== Write plain javascript ===&lt;br /&gt;
Should you wan to write plain javascript, you can easily do so. What you need to do is actually load the file like so in &amp;lt;code&amp;gt;X.js&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  *&lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  *&lt;br /&gt;
  * X.js&lt;br /&gt;
  *&lt;br /&gt;
  * X user interface script&lt;br /&gt;
  * &lt;br /&gt;
  * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&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;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&amp;quot;./modules/path/to/firstfile.js&amp;quot;,&amp;lt;/span&amp;gt;        &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;//The first file with your JS code&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&amp;quot;./modules/path/to/secondfile.js&amp;quot;,&amp;lt;/span&amp;gt;       &amp;lt;span style=&amp;quot;color:dimgrey&amp;gt;//The second file with another part of your JS code&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
     ...&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
         constructor: function(){&lt;br /&gt;
             ...&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
According to the dojo toolkit documentation, you will then need to directly access what you defined in the files.&lt;br /&gt;
&lt;br /&gt;
=== Write an AMD module ===&lt;br /&gt;
You can take advantage of the toolkit&#039;s module system to declare dependencies between the differents files you&#039;ll be writing (modules in the toolkit&#039;s language). To be identified as modules, your Javascript files will need to have the following structure:&lt;br /&gt;
&lt;br /&gt;
==== Create a named new class ====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[[modules/js/FirstModule.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
define([&lt;br /&gt;
    &amp;quot;dojo&amp;quot;,&lt;br /&gt;
    &amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
    other dependencies...&lt;br /&gt;
],function(dojo, declare){&lt;br /&gt;
    return declare(&amp;quot;className&amp;quot;, /*Parent classes that this class inherits, optional*/, {&lt;br /&gt;
        /* static properties */&lt;br /&gt;
        let property1 = &amp;quot;value;&lt;br /&gt;
        let property2 = 5;&lt;br /&gt;
        constructor: function (args) {&lt;br /&gt;
            /* instance properties */&lt;br /&gt;
            let property3 = 8;&lt;br /&gt;
            let property4 = [ &amp;quot;arrayValue&amp;quot;, &amp;quot;arrayValue2&amp;quot; ]; &lt;br /&gt;
        }&lt;br /&gt;
        method1: function (args) {&lt;br /&gt;
            /* your code here */&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;
Then in the X.js file, you can use your newly created module like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 *------&lt;br /&gt;
 * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
 * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
 *&lt;br /&gt;
 * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
 * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
 * -----&lt;br /&gt;
 *&lt;br /&gt;
 * X.js&lt;br /&gt;
 *&lt;br /&gt;
 * X user interface script&lt;br /&gt;
 * &lt;br /&gt;
 * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&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;./modules/js/Firstmodule&amp;quot;,&lt;br /&gt;
],&lt;br /&gt;
function (dojo, declare) {&lt;br /&gt;
    return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
    ...&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In your code, you can access your module&#039;s class and methods by doing so:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    let object = new className();&lt;br /&gt;
    object.method1();&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This can lead to namespace collisions if you don&#039;t choose a namespace correctly, so you might want to take the same approach as described earlier for the PHP files for using a namespace.&lt;br /&gt;
&lt;br /&gt;
==== Create an anonymous class ====&lt;br /&gt;
&lt;br /&gt;
This is the recommended way according to the dojo toolkit documentation, but it requires a bit more modification than the previous method:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[[modules/js/SecondModule.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
define([&lt;br /&gt;
    &amp;quot;dojo&amp;quot;,&lt;br /&gt;
    &amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
    other dependencies...&lt;br /&gt;
],function(dojo, declare){&lt;br /&gt;
    return declare(null, /*Parent classes that this class inherits, optional*/, {&lt;br /&gt;
        /* static properties */&lt;br /&gt;
        let property1 = &amp;quot;value;&lt;br /&gt;
        let property2 = 5;&lt;br /&gt;
        constructor: function (args) {&lt;br /&gt;
            /* instance properties */&lt;br /&gt;
            let property3 = 8;&lt;br /&gt;
            let property4 = [ &amp;quot;arrayValue&amp;quot;, &amp;quot;arrayValue2&amp;quot; ]; &lt;br /&gt;
        }&lt;br /&gt;
        method1: function (args) {&lt;br /&gt;
            /* your code here */&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;
Then in the X.js file, you can use your newly created module like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 *------&lt;br /&gt;
 * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
 * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
 *&lt;br /&gt;
 * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
 * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
 * -----&lt;br /&gt;
 *&lt;br /&gt;
 * X.js&lt;br /&gt;
 *&lt;br /&gt;
 * X user interface script&lt;br /&gt;
 * &lt;br /&gt;
 * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&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;./modules/js/SecondModule&amp;quot;,         //Has to be inserted in the third position as we&#039;ll need an identifier later, and the other modules don&#039;t need it, see code in the preceding subsection. &lt;br /&gt;
    &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
    &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
    &amp;quot;./modules/js/Firstmodule&amp;quot;,&lt;br /&gt;
],&lt;br /&gt;
function (dojo, declare, SecondModule /* insert a reference here that you&#039;ll use throughout the JS file for this module */) {&lt;br /&gt;
    return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
    ...&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In your code, you can then access your module&#039;s class and methods by doing so:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    let someValue = SecondModule.property3&lt;br /&gt;
    SecondModule.method1();&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Create a singleton object ====&lt;br /&gt;
&lt;br /&gt;
You can also create singleton objects by creating a module this way:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[[modules/js/singletonObject.js]]&lt;br /&gt;
define([&lt;br /&gt;
    &amp;quot;dojo&amp;quot;,&lt;br /&gt;
    ...&lt;br /&gt;
], function (dojo) {&lt;br /&gt;
    // Methods and variables defined in this part will not be available anywhere else than in this file&lt;br /&gt;
    let privateVariable = &amp;quot;someValue&amp;quot;;&lt;br /&gt;
    let privateFunction = function (args) {&lt;br /&gt;
        //some code here&lt;br /&gt;
    }&lt;br /&gt;
    return {&lt;br /&gt;
        firstMethod: function (args) {&lt;br /&gt;
            privateFunction(args);&lt;br /&gt;
            //some other code here&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To be used in the &amp;lt;code&amp;gt;X.js&amp;lt;/code&amp;gt; file, you must use the same method as in the [[#Create an anonymous class|previous section]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 *------&lt;br /&gt;
 * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
 * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
 *&lt;br /&gt;
 * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
 * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
 * -----&lt;br /&gt;
 *&lt;br /&gt;
 * X.js&lt;br /&gt;
 *&lt;br /&gt;
 * X user interface script&lt;br /&gt;
 * &lt;br /&gt;
 * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&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;./modules/js/SecondModule&amp;quot;,         //Has to be inserted in the third position as we&#039;ll need an identifier later, and the other modules don&#039;t need it, see code in the preceding subsection.&lt;br /&gt;
    &amp;quot;./modules/js/sigletonObject&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;./modules/js/Firstmodule&amp;quot;,&lt;br /&gt;
],&lt;br /&gt;
function (dojo, declare, SecondModule /* insert a reference here that you&#039;ll use throughout the JS file for this module */, singletonObject) {&lt;br /&gt;
    return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
    ...&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then you can access your code the same way as described in the [[#Create an anonymous class|previous section]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    singletonObject.firstMethod();&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Putting it all together ==&lt;br /&gt;
&#039;&#039;&#039;TODO&#039;&#039;&#039;&lt;/div&gt;</summary>
		<author><name>SwHawk</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=User:SwHawk/Create_Modular_Code&amp;diff=13589</id>
		<title>User:SwHawk/Create Modular Code</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=User:SwHawk/Create_Modular_Code&amp;diff=13589"/>
		<updated>2022-06-14T18:35:33Z</updated>

		<summary type="html">&lt;p&gt;SwHawk: Added corrections and color for PHP code blocks&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{InfoBox|title=WIP|body=&#039;&#039;&#039;This article is a Work In Progress, please do not refer to it for production purposes&#039;&#039;&#039;}}&lt;br /&gt;
&lt;br /&gt;
This page will cover steps you can take as a BGA developer to make your code more modular and better organized. The way the framework is implemented makes the [[Main game logic: yourgamename.game.php|game logic]] and the [[Game interface logic: yourgamename.js|interface logic]] files very monolithic. While this is not a problem in itself, even simple to moderately complex game may require this files to be over 5k lines of code. Thus you can quickly become lost in all the functions you need to declare, where they are declared, and where they are called.&lt;br /&gt;
&lt;br /&gt;
But there are steps that you can follow to take advantage of PHP&#039;s Object Oriented Code and the dojo toolkit&#039;s AMD loader to organize your code in separate files. Let&#039;s see what&#039;s available:&lt;br /&gt;
&lt;br /&gt;
== Acknowledgements ==&lt;br /&gt;
&lt;br /&gt;
Writing this wiki article wouldn&#039;t have been possible without the help, work and insight of more experienced BGA developers:&lt;br /&gt;
* [https://boardgamearena.com/player?id=83846198 Tisaac]  (Discord user Tisaac Human Expert)&lt;br /&gt;
* [https://boardgamearena.com/player?id=85537631 bennygui] (Discord user bennygui)&lt;br /&gt;
* [https://boardgamearena.com/player?id=84125723 VictoriaLa] (Discord user VictoriaLa)&lt;br /&gt;
* Syarwin and [https://boardgamearena.com/player?id=84554161 quietmint] (for their Welcome To [https://github.com/Syarwin/bga-welcometo repository])&lt;br /&gt;
* [https://boardgamearena.com/player?id=84522426 Mogri] (Discord user Mogri)&lt;br /&gt;
&lt;br /&gt;
== Conventions ==&lt;br /&gt;
In the code blocks, code additions will be displayed in bold and green, and added comments will be displayed in bold and dark grey so that they stand out from the boilerplate code from a scratch project. Part in red should be aapted to reflect your project&#039;s structure.&lt;br /&gt;
&lt;br /&gt;
== On the PHP side ==&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt; vs &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; ===&lt;br /&gt;
Throughout this section, I&#039;ll make heavy use of PHP&#039;s &amp;lt;code&amp;gt;require_once&amp;lt;/code&amp;gt; control structure. Why am I using &amp;lt;code&amp;gt;require(_once)&amp;lt;/code&amp;gt; instead of &amp;lt;code&amp;gt;include_once&amp;lt;/code&amp;gt;? Because if an error exists in a PHP file that you try to &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt;, only a warning will be thrown, but the script will continue in spite of the error. Using &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; if the included file has an error, the script dies when the inclusion takes places, throwing a fatal error (&amp;lt;code&amp;gt;E_COMPILE_ERROR&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
That way, I&#039;m sure the classes, traits or interfaces I&#039;m including are syntax error free.&lt;br /&gt;
&lt;br /&gt;
=== Game logic methods ===&lt;br /&gt;
The way the framework is implemented, your game logic is gathered inside a class (&amp;lt;code&amp;gt;YourProjectName&amp;lt;/code&amp;gt;) extending the [[Table|&amp;lt;code&amp;gt;Table&amp;lt;/code&amp;gt; class]]. You define your methods there so that they may be called from other parts of the framework (as long as they&#039;re public methods obviously).&lt;br /&gt;
&lt;br /&gt;
But you can take advantage of [https://www.php.net/manual/en/language.oop5.traits.php PHP Traits]. In a nutshell, Traits are a collection of methods that can be reused in different classes, to avoid code duplication. Here we&#039;re not going to reuse them anywhere else than in the game class, but this little trick allows us to put methods definitions in other files, and in so doing to avoid monolithic code.&lt;br /&gt;
&lt;br /&gt;
Basically you create a Trait in th &amp;lt;code&amp;gt;/modules/&amp;lt;/code&amp;gt; directory, for instance:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[modules/UtiltityFunctionsTrait.php]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;lt;?php&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;namespace YourProjectNamespace\Modules;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;trait UtilityFunctionsTrait {&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &#039;&#039;&#039;public function myFirstUtilityFunction($args)&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;{&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//Your code here&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;}&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Then you can include it in you project&#039;s &amp;lt;code&amp;gt;X.game.php&amp;lt;/code&amp;gt; file like so:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X_game.php]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;?php&lt;br /&gt;
  /**&lt;br /&gt;
   *------&lt;br /&gt;
   * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
   * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
   * &lt;br /&gt;
   * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
   * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
   * -----&lt;br /&gt;
   * &lt;br /&gt;
   * X.game.php&lt;br /&gt;
   *&lt;br /&gt;
   * This is the main file for your game logic.&lt;br /&gt;
   *&lt;br /&gt;
   * In this PHP file, you are going to defines the rules of the game.&lt;br /&gt;
   *&lt;br /&gt;
   */&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;require_once &#039;modules/UtilityFunctionsTrait.php&#039;; &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;   //Here we require the trait to be loaded when the class is loaded&amp;lt;/span&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;use X\Modules\UtilityFunctionsTrait;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;                 //We import the trait to be used directly as UtilityFunctionsTraits,&#039;&#039;&#039;&lt;br /&gt;
                                                      &#039;&#039;&#039;//otherwise we would have to use the Fully qualified class name&#039;&#039;&#039;&lt;br /&gt;
                                                      &#039;&#039;&#039;//(YourProjectNamespace\Modules\UtilityFunctionsTrait)&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 class X extends Table&lt;br /&gt;
 {&lt;br /&gt;
 //...&lt;br /&gt;
 &lt;br /&gt;
 //////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
 //////////// Utility functions&lt;br /&gt;
 ////////////    &lt;br /&gt;
 &lt;br /&gt;
     /*&lt;br /&gt;
         In this space, you can put any utility methods useful for your game logic&lt;br /&gt;
     */&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;use UtilityFunctionsTrait;&#039;&#039;&#039;&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;//Here we actually include the trait inside the class, making all the trait&#039;s methods&#039;&#039;&#039; &lt;br /&gt;
                                &#039;&#039;&#039;//available as class methods, keeping their visibility scope (so a private method&#039;&#039;&#039;&lt;br /&gt;
                                &#039;&#039;&#039;//is still private)&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Support classes ===&lt;br /&gt;
Basically, the same as traits, you put your classes definitions into files that live under the &amp;lt;code&amp;gt;/modules/&amp;lt;/code&amp;gt; directory (don&#039;t forget to namespace your classes), and then require them at the top of &amp;lt;code&amp;gt;X_game.php&amp;lt;/code&amp;gt;, and voilà, you&#039;re done&lt;br /&gt;
&lt;br /&gt;
=== Adding autoloader support ===&lt;br /&gt;
&lt;br /&gt;
==== Coding standards ====&lt;br /&gt;
Even for simple games, you might end up having a dozen of traits and support classes. You can require them all in your &amp;lt;code&amp;gt;X_game.php&amp;lt;/code&amp;gt;. Or you can use an autoloader, which will load the necessary classes and traits at runtime. There are two PSRs dealing with autloading standards (namely [https://www.php-fig.org/psr/psr-0 PSR-0] which is marked as deprecated and [https://www.php-fig.org/psr/psr-4 PSR-4]) which state that your namespaces should be a reflection of the directory structure of your project.&lt;br /&gt;
&lt;br /&gt;
Basically, when creating namespaces, you choose a namespace prefix. For example, you could use your BGA handle and the project name as a namespace prefix (would result in &amp;lt;code&amp;gt;\SwHawk\X&amp;lt;/code&amp;gt; in my case), and then the rest of the namespace would be the directory the file is in. I usually group classes and traits by the function they have in my project, so my &amp;lt;code&amp;gt;/modules/&amp;lt;/code&amp;gt; directory looks like that:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
modules/&lt;br /&gt;
    php/&lt;br /&gt;
        Factory/                      //Holds my factory classes&lt;br /&gt;
            AFactoryClass.php         //The namespace for this file would be \SwHawk\X\Factory, and the fully qualified class name would be \SwHawk\X\Factory\AFactoryClass&lt;br /&gt;
            ...&lt;br /&gt;
        Object/                       //Holds my support classes&lt;br /&gt;
            ObjectA.php               //The namespace for this file would be \SwHawk\X\Object, and the fully qualified class name would be \SwHawk\X\Object\ObjectA&lt;br /&gt;
            ...&lt;br /&gt;
        Traits/                       //Holds my traits&lt;br /&gt;
            UtilityFunctionsTrait.php //The namespace for this file would be \SwHawk\X\Traits, and the fully qualified class name would be \SwHawk\X\Traits\UtilityFunctionsTrait&lt;br /&gt;
            ...&lt;br /&gt;
        ...&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Autoloader function for development ====&lt;br /&gt;
While your project is under development, you usually create, move and remove classes as part of the development process. So you usually need an autoloading function that can handle a lot of flexibility. Basically once you import a class using the &amp;lt;code&amp;gt;use&amp;lt;/code&amp;gt; keyword, the autoloading function will determine which file to &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; using its fully qualified class name, and then &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt;. This function needs to be either defined or included at the top of &amp;lt;code&amp;gt;X_game.php&amp;lt;/code&amp;gt;. Such a function would have the following code (borrowed and adapted from [https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader-examples.md this repository]):&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;spl_autoload_register(function ($class) {&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// project-specific namespace prefix&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;, adapt to your needs&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;, remember that you must escape \ characters in double-quoted strings (hence the \\)&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$prefix = &#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;&#039;&#039;&#039;&amp;quot;SwHawk\\X\\&amp;quot;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;;&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
     &#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// base directory for the namespace prefix, this file would usually reside in the modules/php/includes/ directory, so the base directory for all my classes would be a level higher&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$base_dir = __DIR__ . &#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;&#039;&#039;&#039; &#039;/../&#039; &#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;gt;&#039;&#039;&#039;;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// does the class use the namespace prefix?&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$len = strlen($prefix);&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;if (strncmp($prefix, $class, $len) !== 0) {&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// no, move to the next registered autoloader&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;return;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// get the relative class name&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$relative_class = substr($class, $len);&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;&#039;&#039;&#039;// replace the namespace prefix with the base directory, replace namespace&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;// separators with directory separators in the relative class name, append&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;// with .php&#039;&#039;&#039;&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;$file = $base_dir . str_replace(&#039;\\&#039;, &#039;/&#039;, $relative_class) . &#039;.php&#039;;&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:dimgrey&amp;quot;&amp;gt;// if the file exists, require it&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
     &#039;&#039;&#039;if (file_exists($file)) {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;require $file;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;});&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Autoloader function for production ====&lt;br /&gt;
Once you&#039;re moving your game to production, the autoloader function provided before isn&#039;t optimized. Once in production, the directory tree should not be modified, so you can change the earlier autoloader to a classmap based one. Basically, you build an associative array with the fully qualified classes names as keys and the filepath as the value. An example would look like so:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;spl_autoload_register(function ($class) {&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;static $classmap = array(&#039;&#039;&#039;&lt;br /&gt;
         &amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:red&amp;gt;&amp;quot;SwHawk\\X\\&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;Factory\\AFactoryClass&amp;quot; =&amp;gt; __DIR__ . &amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;&amp;quot;/../&amp;lt;/span&amp;gt;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;Factory/AFactoryClass.php&amp;quot;,&amp;lt;/span&amp;gt;&#039;&#039;&#039;&amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&lt;br /&gt;
         &#039;&#039;&#039;...&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;);&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;if(array_key_exists($class)) {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;require $classmap[$class];&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;} else {&#039;&#039;&#039;&lt;br /&gt;
         &#039;&#039;&#039;return;&#039;&#039;&#039;&lt;br /&gt;
     &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
 &#039;&#039;&#039;}&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This autoloader is better suited to production since it won&#039;t use expensive calls like &amp;lt;code&amp;gt;file_exists($filename)&amp;lt;/code&amp;gt;. You can write the classmap by yourself, but it can be quite cumbersome, there is some tools like [https://github.com/hanneskod/classtools this project], or [https://github.com/gnugat/nomo-spaco this one], or even scripts detailed in this [https://stackoverflow.com/questions/22761554/how-to-get-all-class-names-inside-a-particular-namespace StackOverflow topic]&lt;br /&gt;
&lt;br /&gt;
== On the JS side ==&lt;br /&gt;
&lt;br /&gt;
BGA uses the dojo toolkit framework for most of its javascript code. Dojo comes with its own way of loading modules, which you can read about in more detail [https://dojotoolkit.org/documentation/tutorials/1.10/modules/ here] and [https://dojotoolkit.org/documentation/tutorials/1.10/modules_advanced/ here]. To put it simply, there are two ways you can go about this&lt;br /&gt;
&lt;br /&gt;
=== Write plain javascript ===&lt;br /&gt;
Should you wan to write plain javascript, you can easily do so. What you need to do is actually load the file like so in &amp;lt;code&amp;gt;X.js&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 *------&lt;br /&gt;
 * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
 * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
 *&lt;br /&gt;
 * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
 * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
 * -----&lt;br /&gt;
 *&lt;br /&gt;
 * X.js&lt;br /&gt;
 *&lt;br /&gt;
 * X user interface script&lt;br /&gt;
 * &lt;br /&gt;
 * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&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;./modules/path/to/firstfile.js&amp;quot;,        //The first file with your JS code&lt;br /&gt;
    &amp;quot;./modules/path/to/secondfile.js&amp;quot;,       //The second file with another part of your JS code&lt;br /&gt;
    ...&lt;br /&gt;
],&lt;br /&gt;
function (dojo, declare) {&lt;br /&gt;
    return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
        constructor: function(){&lt;br /&gt;
            ...&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
According to the dojo toolkit documentation, you will then need to directly access what you defined in the files.&lt;br /&gt;
&lt;br /&gt;
=== Write an AMD module ===&lt;br /&gt;
You can take advantage of the toolkit&#039;s module system to declare dependencies between the differents files you&#039;ll be writing (modules in the toolkit&#039;s language). To be identified as modules, your Javascript files will need to have the following structure:&lt;br /&gt;
&lt;br /&gt;
==== Create a named new class ====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[[modules/js/FirstModule.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
define([&lt;br /&gt;
    &amp;quot;dojo&amp;quot;,&lt;br /&gt;
    &amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
    other dependencies...&lt;br /&gt;
],function(dojo, declare){&lt;br /&gt;
    return declare(&amp;quot;className&amp;quot;, /*Parent classes that this class inherits, optional*/, {&lt;br /&gt;
        /* static properties */&lt;br /&gt;
        let property1 = &amp;quot;value;&lt;br /&gt;
        let property2 = 5;&lt;br /&gt;
        constructor: function (args) {&lt;br /&gt;
            /* instance properties */&lt;br /&gt;
            let property3 = 8;&lt;br /&gt;
            let property4 = [ &amp;quot;arrayValue&amp;quot;, &amp;quot;arrayValue2&amp;quot; ]; &lt;br /&gt;
        }&lt;br /&gt;
        method1: function (args) {&lt;br /&gt;
            /* your code here */&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;
Then in the X.js file, you can use your newly created module like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 *------&lt;br /&gt;
 * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
 * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
 *&lt;br /&gt;
 * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
 * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
 * -----&lt;br /&gt;
 *&lt;br /&gt;
 * X.js&lt;br /&gt;
 *&lt;br /&gt;
 * X user interface script&lt;br /&gt;
 * &lt;br /&gt;
 * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&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;./modules/js/Firstmodule&amp;quot;,&lt;br /&gt;
],&lt;br /&gt;
function (dojo, declare) {&lt;br /&gt;
    return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
    ...&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In your code, you can access your module&#039;s class and methods by doing so:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    let object = new className();&lt;br /&gt;
    object.method1();&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This can lead to namespace collisions if you don&#039;t choose a namespace correctly, so you might want to take the same approach as described earlier for the PHP files for using a namespace.&lt;br /&gt;
&lt;br /&gt;
==== Create an anonymous class ====&lt;br /&gt;
&lt;br /&gt;
This is the recommended way according to the dojo toolkit documentation, but it requires a bit more modification than the previous method:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[[modules/js/SecondModule.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
define([&lt;br /&gt;
    &amp;quot;dojo&amp;quot;,&lt;br /&gt;
    &amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
    other dependencies...&lt;br /&gt;
],function(dojo, declare){&lt;br /&gt;
    return declare(null, /*Parent classes that this class inherits, optional*/, {&lt;br /&gt;
        /* static properties */&lt;br /&gt;
        let property1 = &amp;quot;value;&lt;br /&gt;
        let property2 = 5;&lt;br /&gt;
        constructor: function (args) {&lt;br /&gt;
            /* instance properties */&lt;br /&gt;
            let property3 = 8;&lt;br /&gt;
            let property4 = [ &amp;quot;arrayValue&amp;quot;, &amp;quot;arrayValue2&amp;quot; ]; &lt;br /&gt;
        }&lt;br /&gt;
        method1: function (args) {&lt;br /&gt;
            /* your code here */&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;
Then in the X.js file, you can use your newly created module like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 *------&lt;br /&gt;
 * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
 * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
 *&lt;br /&gt;
 * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
 * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
 * -----&lt;br /&gt;
 *&lt;br /&gt;
 * X.js&lt;br /&gt;
 *&lt;br /&gt;
 * X user interface script&lt;br /&gt;
 * &lt;br /&gt;
 * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&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;./modules/js/SecondModule&amp;quot;,         //Has to be inserted in the third position as we&#039;ll need an identifier later, and the other modules don&#039;t need it, see code in the preceding subsection. &lt;br /&gt;
    &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
    &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
    &amp;quot;./modules/js/Firstmodule&amp;quot;,&lt;br /&gt;
],&lt;br /&gt;
function (dojo, declare, SecondModule /* insert a reference here that you&#039;ll use throughout the JS file for this module */) {&lt;br /&gt;
    return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
    ...&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In your code, you can then access your module&#039;s class and methods by doing so:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    let someValue = SecondModule.property3&lt;br /&gt;
    SecondModule.method1();&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Create a singleton object ====&lt;br /&gt;
&lt;br /&gt;
You can also create singleton objects by creating a module this way:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[[modules/js/singletonObject.js]]&lt;br /&gt;
define([&lt;br /&gt;
    &amp;quot;dojo&amp;quot;,&lt;br /&gt;
    ...&lt;br /&gt;
], function (dojo) {&lt;br /&gt;
    // Methods and variables defined in this part will not be available anywhere else than in this file&lt;br /&gt;
    let privateVariable = &amp;quot;someValue&amp;quot;;&lt;br /&gt;
    let privateFunction = function (args) {&lt;br /&gt;
        //some code here&lt;br /&gt;
    }&lt;br /&gt;
    return {&lt;br /&gt;
        firstMethod: function (args) {&lt;br /&gt;
            privateFunction(args);&lt;br /&gt;
            //some other code here&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To be used in the &amp;lt;code&amp;gt;X.js&amp;lt;/code&amp;gt; file, you must use the same method as in the [[#Create an anonymous class|previous section]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 *------&lt;br /&gt;
 * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
 * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
 *&lt;br /&gt;
 * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
 * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
 * -----&lt;br /&gt;
 *&lt;br /&gt;
 * X.js&lt;br /&gt;
 *&lt;br /&gt;
 * X user interface script&lt;br /&gt;
 * &lt;br /&gt;
 * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&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;./modules/js/SecondModule&amp;quot;,         //Has to be inserted in the third position as we&#039;ll need an identifier later, and the other modules don&#039;t need it, see code in the preceding subsection.&lt;br /&gt;
    &amp;quot;./modules/js/sigletonObject&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;./modules/js/Firstmodule&amp;quot;,&lt;br /&gt;
],&lt;br /&gt;
function (dojo, declare, SecondModule /* insert a reference here that you&#039;ll use throughout the JS file for this module */, singletonObject) {&lt;br /&gt;
    return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
    ...&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then you can access your code the same way as described in the [[#Create an anonymous class|previous section]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    singletonObject.firstMethod();&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Putting it all together ==&lt;br /&gt;
&#039;&#039;&#039;TODO&#039;&#039;&#039;&lt;/div&gt;</summary>
		<author><name>SwHawk</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=User_talk:SwHawk/Create_Modular_Code&amp;diff=13588</id>
		<title>User talk:SwHawk/Create Modular Code</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=User_talk:SwHawk/Create_Modular_Code&amp;diff=13588"/>
		<updated>2022-06-14T18:01:52Z</updated>

		<summary type="html">&lt;p&gt;SwHawk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Please sign your comments using this syntax &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;-- ~~~~&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; so that I may credit your additions to the article.&lt;br /&gt;
&lt;br /&gt;
==User names==&lt;br /&gt;
&amp;quot;Tisaac Human Expert&amp;quot; -&amp;gt; Tisaac&lt;br /&gt;
&lt;br /&gt;
&amp;quot;VictoriaLia&amp;quot; -&amp;gt; VictoriaLa&lt;br /&gt;
&lt;br /&gt;
-- [[User:Mogri|Mogri]] ([[User_talk:Mogri|talk]]) 18:08, 14 June 2022 (CEST)&lt;br /&gt;
&lt;br /&gt;
: Thanks for the corrections -- [[User:SwHawk|SwHawk]] ([[User talk:SwHawk|talk]]) 19:45, 14 June 2022 (CEST)&lt;br /&gt;
==A non-dojo JS approach==&lt;br /&gt;
&lt;br /&gt;
Dojo is old and kinda bad. This approach lets you avoid Dojo and &amp;lt;tt&amp;gt;this&amp;lt;/tt&amp;gt; and allows more modern JS.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[X.js]&lt;br /&gt;
window.X = {}; // X = your game, or you can use something more generic&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
setup: function (gameData) { // this cannot be an arrow function due to dojo&lt;br /&gt;
   X = Object.assign(this, X);&lt;br /&gt;
   // the rest of your setup goes here&lt;br /&gt;
},&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[modules/whatever.js]&lt;br /&gt;
X = Object.assign(X, {&lt;br /&gt;
  MY_CONSTANT: 1,&lt;br /&gt;
&lt;br /&gt;
  myFunction: (arg1, arg2) =&amp;gt; {&lt;br /&gt;
    X.someFunction(X.MY_CONSTANT);&lt;br /&gt;
    return arg1 + arg2;&lt;br /&gt;
  },&lt;br /&gt;
&lt;br /&gt;
  someFunction: (x) =&amp;gt; _(&#039;The answer is: &#039;) + x,&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notes on this approach:&lt;br /&gt;
*Aside from setup and any framework-override functions, you should be using arrow functions&lt;br /&gt;
*Always use X instead of this&lt;br /&gt;
*As usual, you can use any number of modules this way&lt;br /&gt;
&lt;br /&gt;
-- [[User:Mogri|Mogri]] ([[User_talk:Mogri|talk]]) 18:08, 14 June 2022 (CEST)&lt;br /&gt;
&lt;br /&gt;
: While I agree that most of the components of the framework (be it PHP or JS) are old, there are some advantages to using its loader: dependencies management for instance. Also I&#039;m not sure that changing every function definition to an arrow function offers better readability but that&#039;s a personal opinion, as I&#039;m more used to languages where function keywords exists. -- [[User:SwHawk|SwHawk]] ([[User talk:SwHawk|talk]]) 19:45, 14 June 2022 (CEST)&lt;br /&gt;
&lt;br /&gt;
== Highlight lines added in code blocks ==&lt;br /&gt;
&lt;br /&gt;
The code blocks are rather long right now with all of the comments, however I do think it is worth keeping them so they look like the starter files.&lt;br /&gt;
&lt;br /&gt;
You could consider coloring or emphasising the lines added in some way.&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X_game.php]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;?php&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  * &lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  * &lt;br /&gt;
  * X.game.php&lt;br /&gt;
  *&lt;br /&gt;
  * This is the main file for your game logic.&lt;br /&gt;
  *&lt;br /&gt;
  * In this PHP file, you are going to defines the rules of the game.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;require_once &#039;modules/UtilityFunctionsTrait.php&#039;;&#039;&#039;&#039; //Here we require the trait to be loaded when the class is loaded&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;use YourProjectNamespace\Modules\UtilityFunctionsTrait;&amp;lt;/span&amp;gt; //We import the trait to be used directly as UtilityFunctionsTraits, otherwise we would have to use the Fully qualified  class name (YourProjectNamespace\Modules\UtilityFunctionsTrait)&lt;br /&gt;
 &lt;br /&gt;
 class YourProjectName extends Table&lt;br /&gt;
 {&lt;br /&gt;
 //...&lt;br /&gt;
 &lt;br /&gt;
 //////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
 //////////// Utility functions&lt;br /&gt;
 ////////////    &lt;br /&gt;
 &lt;br /&gt;
    /*&lt;br /&gt;
        In this space, you can put any utility methods useful for your game logic&lt;br /&gt;
    */&lt;br /&gt;
 &lt;br /&gt;
    &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;use UtilityFunctionsTrait;&#039;&#039;&#039;&amp;lt;/span&amp;gt; //Here we actually include the trait inside the class, making all the trait&#039;s methods available as class methods, keeping their visibility scope (so a private method is still private)&lt;br /&gt;
 }&lt;br /&gt;
-- [[User:Thenmal|Thenmal]] ([[User_talk:Thenmal|Thenmal]]) 19:04, 14 June 2022 (CEST)&lt;br /&gt;
&lt;br /&gt;
: Well thanks for that, I looked into the formatting guide, but I must have overlooked that part, thanks for showing me how to do it! -- [[User:SwHawk|SwHawk]] ([[User talk:SwHawk|talk]]) 19:45, 14 June 2022 (CEST)&lt;/div&gt;</summary>
		<author><name>SwHawk</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=User_talk:SwHawk/Create_Modular_Code&amp;diff=13587</id>
		<title>User talk:SwHawk/Create Modular Code</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=User_talk:SwHawk/Create_Modular_Code&amp;diff=13587"/>
		<updated>2022-06-14T17:45:37Z</updated>

		<summary type="html">&lt;p&gt;SwHawk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Please sign your comments using this syntax &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;-- ~~~~&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; so that I may credit your additions to the article.&lt;br /&gt;
&lt;br /&gt;
==User names==&lt;br /&gt;
&amp;quot;Tisaac Human Expert&amp;quot; -&amp;gt; Tisaac&lt;br /&gt;
&lt;br /&gt;
&amp;quot;VictoriaLia&amp;quot; -&amp;gt; VictoriaLa&lt;br /&gt;
&lt;br /&gt;
-- [[User:Mogri|Mogri]] ([[User_talk:Mogri|talk]]) 18:08, 14 June 2022 (CEST)&lt;br /&gt;
&lt;br /&gt;
: Thanks for the corrections -- [[User:SwHawk|SwHawk]] ([[User talk:SwHawk|talk]]) 19:45, 14 June 2022 (CEST)&lt;br /&gt;
==A non-dojo JS approach==&lt;br /&gt;
&lt;br /&gt;
Dojo is old and kinda bad. This approach lets you avoid Dojo and &amp;lt;tt&amp;gt;this&amp;lt;/tt&amp;gt; and allows more modern JS.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[X.js]&lt;br /&gt;
window.X = {}; // X = your game, or you can use something more generic&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
setup: function (gameData) { // this cannot be an arrow function due to dojo&lt;br /&gt;
   X = Object.assign(this, X);&lt;br /&gt;
   // the rest of your setup goes here&lt;br /&gt;
},&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[modules/whatever.js]&lt;br /&gt;
X = Object.assign(X, {&lt;br /&gt;
  MY_CONSTANT: 1,&lt;br /&gt;
&lt;br /&gt;
  myFunction: (arg1, arg2) =&amp;gt; {&lt;br /&gt;
    X.someFunction(X.MY_CONSTANT);&lt;br /&gt;
    return arg1 + arg2;&lt;br /&gt;
  },&lt;br /&gt;
&lt;br /&gt;
  someFunction: (x) =&amp;gt; _(&#039;The answer is: &#039;) + x,&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notes on this approach:&lt;br /&gt;
*Aside from setup and any framework-override functions, you should be using arrow functions&lt;br /&gt;
*Always use X instead of this&lt;br /&gt;
*As usual, you can use any number of modules this way&lt;br /&gt;
&lt;br /&gt;
-- [[User:Mogri|Mogri]] ([[User_talk:Mogri|talk]]) 18:08, 14 June 2022 (CEST)&lt;br /&gt;
&lt;br /&gt;
: While I agree that most of the components of the framework (be it PHP or JS) are old, there are some advantages to using its loader: dependencies management for instance. Also I&#039;m not sure that changing every function definition to an arrow function offers better readability but that&#039;s a personal opinion, as I&#039;m more used to languages where function keywords exists. -- [[User:SwHawk|SwHawk]] ([[User talk:SwHawk|talk]]) 19:45, 14 June 2022 (CEST)&lt;br /&gt;
&lt;br /&gt;
== Highlight lines added in code blocks ==&lt;br /&gt;
&lt;br /&gt;
The code blocks are rather long right now with all of the comments, however I do think it is worth keeping them so they look like the starter files.&lt;br /&gt;
&lt;br /&gt;
You could consider coloring or emphasising the lines added in some way.&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;[[X_game.php]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;?php&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  * &lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  * &lt;br /&gt;
  * X.game.php&lt;br /&gt;
  *&lt;br /&gt;
  * This is the main file for your game logic.&lt;br /&gt;
  *&lt;br /&gt;
  * In this PHP file, you are going to defines the rules of the game.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;&#039;require_once &#039;modules/UtilityFunctionsTrait.php&#039;;&#039;&#039;&#039; //Here we require the trait to be loaded when the class is loaded&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;use YourProjectNamespace\Modules\UtilityFunctionsTrait;&amp;lt;/span&amp;gt; //We import the trait to be used directly as UtilityFunctionsTraits, otherwise we would have to use the Fully qualified  class name (YourProjectNamespace\Modules\UtilityFunctionsTrait)&lt;br /&gt;
 &lt;br /&gt;
 class YourProjectName extends Table&lt;br /&gt;
 {&lt;br /&gt;
 //...&lt;br /&gt;
 &lt;br /&gt;
 //////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
 //////////// Utility functions&lt;br /&gt;
 ////////////    &lt;br /&gt;
 &lt;br /&gt;
    /*&lt;br /&gt;
        In this space, you can put any utility methods useful for your game logic&lt;br /&gt;
    */&lt;br /&gt;
 &lt;br /&gt;
    &amp;lt;span style=&amp;quot;color:green&amp;quot;&amp;gt;&#039;&#039;&#039;use UtilityFunctionsTrait;&#039;&#039;&#039;&amp;lt;/span&amp;gt; //Here we actually include the trait inside the class, making all the trait&#039;s methods available as class methods, keeping their visibility scope (so a private method is still private)&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
: Well thanks for that, I looked into the formatting guide, but I must have overlooked that part, thanks for showing me how to do it! -- [[User:SwHawk|SwHawk]] ([[User talk:SwHawk|talk]]) 19:45, 14 June 2022 (CEST)&lt;/div&gt;</summary>
		<author><name>SwHawk</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=User:SwHawk/Create_Modular_Code&amp;diff=13581</id>
		<title>User:SwHawk/Create Modular Code</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=User:SwHawk/Create_Modular_Code&amp;diff=13581"/>
		<updated>2022-06-14T15:39:18Z</updated>

		<summary type="html">&lt;p&gt;SwHawk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{InfoBox|title=WIP|body=&#039;&#039;&#039;This article is a Work In Progress, please do not refer to it for production purposes&#039;&#039;&#039;}}&lt;br /&gt;
&lt;br /&gt;
This page will cover steps you can take as a BGA developer to make your code more modular and better organized. The way the framework is implemented makes the [[Main game logic: yourgamename.game.php|game logic]] and the [[Game interface logic: yourgamename.js|interface logic]] files very monolithic. While this is not a problem in itself, even simple to moderately complex game may require this files to be over 5k lines of code. Thus you can quickly become lost in all the functions you need to declare, where they are declared, and where they are called.&lt;br /&gt;
&lt;br /&gt;
But there are steps that you can follow to take advantage of PHP&#039;s Object Oriented Code and the dojo toolkit&#039;s AMD loader to organize your code in separate files. Let&#039;s see what&#039;s available:&lt;br /&gt;
&lt;br /&gt;
== Acknowledgements ==&lt;br /&gt;
&lt;br /&gt;
Writing this wiki article wouldn&#039;t have been possible without the help, work and insight of more experienced BGA developers:&lt;br /&gt;
* Tisaac Human Expert (Discord user)&lt;br /&gt;
* bennygui (Discord user)&lt;br /&gt;
* VictoriaLia&lt;br /&gt;
* Syarwin and quietmint (for their Welcome To [https://github.com/Syarwin/bga-welcometo repository])&lt;br /&gt;
&lt;br /&gt;
== On the PHP side ==&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt; vs &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; ===&lt;br /&gt;
Throughout this section, I&#039;ll make heavy use of PHP&#039;s &amp;lt;code&amp;gt;require_once&amp;lt;/code&amp;gt; control structure. Why am I using &amp;lt;code&amp;gt;require(_once)&amp;lt;/code&amp;gt; instead of &amp;lt;code&amp;gt;include_once&amp;lt;/code&amp;gt;? Because if an error exists in a PHP file that you try to &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt;, only a warning will be thrown, but the script will continue in spite of the error. Using &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; if the included file has an error, the script dies when the inclusion takes places, throwing a fatal error (&amp;lt;code&amp;gt;E_COMPILE_ERROR&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
That way, I&#039;m sure the classes, traits or interfaces I&#039;m including are syntax error free.&lt;br /&gt;
&lt;br /&gt;
=== Game logic methods ===&lt;br /&gt;
The way the framework is implemented, your game logic is gathered inside a class (&amp;lt;code&amp;gt;YourProjectName&amp;lt;/code&amp;gt;) extending the [[Table|&amp;lt;code&amp;gt;Table&amp;lt;/code&amp;gt; class]]. You define your methods there so that they may be called from other parts of the framework (as long as they&#039;re public methods obviously).&lt;br /&gt;
&lt;br /&gt;
But you can take advantage of [https://www.php.net/manual/en/language.oop5.traits.php PHP Traits]. In a nutshell, Traits are a collection of methods that can be reused in different classes, to avoid code duplication. Here we&#039;re not going to reuse them anywhere else than in the game class, but this little trick allows us to put methods definitions in other files, and in so doing to avoid monolithic code.&lt;br /&gt;
&lt;br /&gt;
Basically you create a Trait in th &amp;lt;code&amp;gt;/modules/&amp;lt;/code&amp;gt; directory, for instance:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;[[modules/UtiltityFunctionsTrait.php]]&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
namespace YourProjectNamespace\Modules;&lt;br /&gt;
&lt;br /&gt;
trait UtilityFunctionsTrait {&lt;br /&gt;
&lt;br /&gt;
    public function myFirstUtilityFunction($args)&lt;br /&gt;
    {&lt;br /&gt;
        //Your code here&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then you can include it in you project&#039;s &amp;lt;code&amp;gt;X.game.php&amp;lt;/code&amp;gt; file like so:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;[[X_game.php]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  * &lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  * &lt;br /&gt;
  * X.game.php&lt;br /&gt;
  *&lt;br /&gt;
  * This is the main file for your game logic.&lt;br /&gt;
  *&lt;br /&gt;
  * In this PHP file, you are going to defines the rules of the game.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&gt;
&lt;br /&gt;
require_once &#039;modules/UtilityFunctionsTrait.php&#039;; //Here we require the trait to be loaded when the class is loaded&lt;br /&gt;
&lt;br /&gt;
use YourProjectNamespace\Modules\UtilityFunctionsTrait; //We import the trait to be used directly as UtilityFunctionsTraits, otherwise we would have to use the Fully qualified class name (YourProjectNamespace\Modules\UtilityFunctionsTrait)&lt;br /&gt;
&lt;br /&gt;
class YourProjectName extends Table&lt;br /&gt;
{&lt;br /&gt;
//...&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
//////////// Utility functions&lt;br /&gt;
////////////    &lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
        In this space, you can put any utility methods useful for your game logic&lt;br /&gt;
    */&lt;br /&gt;
&lt;br /&gt;
    use UtilityFunctionsTrait; //Here we actually include the trait inside the class, making all the trait&#039;s methods available as class methods, keeping their visibility scope (so a private method is still private)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Support classes ===&lt;br /&gt;
Basically, the same as traits, you put your classes definitions into files that live under the &amp;lt;code&amp;gt;/modules/&amp;lt;/code&amp;gt; directory (don&#039;t forget to namespace your classes), and then require them at the top of &amp;lt;code&amp;gt;X_game.php&amp;lt;/code&amp;gt;, and voilà, you&#039;re done&lt;br /&gt;
&lt;br /&gt;
=== Adding autoloader support ===&lt;br /&gt;
&lt;br /&gt;
==== Coding standards ====&lt;br /&gt;
Even for simple games, you might end up having a dozen of traits and support classes. You can require them all in your &amp;lt;code&amp;gt;X_game.php&amp;lt;/code&amp;gt;. Or you can use an autoloader, which will load the necessary classes and traits at runtime. There are two PSRs dealing with autloading standards (namely [https://www.php-fig.org/psr/psr-0 PSR-0] which is marked as deprecated and [https://www.php-fig.org/psr/psr-4 PSR-4]) which state that your namespaces should be a reflection of the directory structure of your project.&lt;br /&gt;
&lt;br /&gt;
Basically, when creating namespaces, you choose a namespace prefix. For example, you could use your BGA handle and the project name as a namespace prefix (would result in &amp;lt;code&amp;gt;\SwHawk\X&amp;lt;/code&amp;gt; in my case), and then the rest of the namespace would be the directory the file is in. I usually group classes and traits by the function they have in my project, so my &amp;lt;code&amp;gt;/modules/&amp;lt;/code&amp;gt; directory looks like that:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
modules/&lt;br /&gt;
    php/&lt;br /&gt;
        Factory/                      //Holds my factory classes&lt;br /&gt;
            AFactoryClass.php         //The namespace for this file would be \SwHawk\X\Factory, and the fully qualified class name would be \SwHawk\X\Factory\AFactoryClass&lt;br /&gt;
            ...&lt;br /&gt;
        Object/                       //Holds my support classes&lt;br /&gt;
            ObjectA.php               //The namespace for this file would be \SwHawk\X\Object, and the fully qualified class name would be \SwHawk\X\Object\ObjectA&lt;br /&gt;
            ...&lt;br /&gt;
        Traits/                       //Holds my traits&lt;br /&gt;
            UtilityFunctionsTrait.php //The namespace for this file would be \SwHawk\X\Traits, and the fully qualified class name would be \SwHawk\X\Traits\UtilityFunctionsTrait&lt;br /&gt;
            ...&lt;br /&gt;
        ...&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Autoloader function for development ====&lt;br /&gt;
While your project is under development, you usually create, move and remove classes as part of the development process. So you usually need an autoloading function that can handle a lot of flexibility. Basically once you import a class using the &amp;lt;code&amp;gt;use&amp;lt;/code&amp;gt; keyword, the autoloading function will determine which file to &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; using its fully qualified class name, and then &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt;. Such a function would have the following code (borrowed and adapted from [https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader-examples.md this repository]):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
spl_autoload_register(function ($class) {&lt;br /&gt;
&lt;br /&gt;
    // project-specific namespace prefix, adapt to your needs, remember that you must escape \ characters in double-quoted strings (hence the \\)&lt;br /&gt;
    $prefix = &#039;SwHawk\\X\\&#039;;&lt;br /&gt;
&lt;br /&gt;
    // base directory for the namespace prefix, this file would usually reside in the modules/php/includes/ directory, so the base directory for all my classes would be a level higher&lt;br /&gt;
    $base_dir = __DIR__ . &#039;/../&#039;;&lt;br /&gt;
&lt;br /&gt;
    // does the class use the namespace prefix?&lt;br /&gt;
    $len = strlen($prefix);&lt;br /&gt;
    if (strncmp($prefix, $class, $len) !== 0) {&lt;br /&gt;
        // no, move to the next registered autoloader&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // get the relative class name&lt;br /&gt;
    $relative_class = substr($class, $len);&lt;br /&gt;
&lt;br /&gt;
    // replace the namespace prefix with the base directory, replace namespace&lt;br /&gt;
    // separators with directory separators in the relative class name, append&lt;br /&gt;
    // with .php&lt;br /&gt;
    $file = $base_dir . str_replace(&#039;\\&#039;, &#039;/&#039;, $relative_class) . &#039;.php&#039;;&lt;br /&gt;
&lt;br /&gt;
    // if the file exists, require it&lt;br /&gt;
    if (file_exists($file)) {&lt;br /&gt;
        require $file;&lt;br /&gt;
    }&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
==== Autoloader function for production ====&lt;br /&gt;
Once you&#039;re moving your game to production, the autoloader function provided before isn&#039;t optimized. Once in production, the directory tree should not be modified, so you can change the earlier autoloader to a classmap based one. Basically, you build an associative array with the fully qualified classes names as keys and the filepath as the value. An example would look like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
spl_autoload_register(function ($class) {&lt;br /&gt;
    static $classmap = array(&lt;br /&gt;
        &amp;quot;SwHawk\\X\\Factory\\AFactoryClass&amp;quot; =&amp;gt; __DIR__ . &amp;quot;/../Factory/AFactoryClass.php&amp;quot;,&lt;br /&gt;
        ...&lt;br /&gt;
    );&lt;br /&gt;
    if(array_key_exists($class)) {&lt;br /&gt;
        require $classmap[$class];&lt;br /&gt;
    } else {&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This autoloader is better suited to production since it won&#039;t use expensive calls like &amp;lt;code&amp;gt;file_exists($filename)&amp;lt;/code&amp;gt;. You can write the classmap by yourself, but it can be quite cumbersome, there is some tools like [https://github.com/hanneskod/classtools this project], or [https://github.com/gnugat/nomo-spaco this one], or even scripts detailed in this [https://stackoverflow.com/questions/22761554/how-to-get-all-class-names-inside-a-particular-namespace StackOverflow topic]&lt;br /&gt;
&lt;br /&gt;
== On the JS side ==&lt;br /&gt;
&lt;br /&gt;
BGA uses the dojo toolkit framework for most of its javascript code. Dojo comes with its own way of loading modules, which you can read about in more detail [https://dojotoolkit.org/documentation/tutorials/1.10/modules/ here] and [https://dojotoolkit.org/documentation/tutorials/1.10/modules_advanced/ here]. To put it simply, there are two ways you can go about this&lt;br /&gt;
&lt;br /&gt;
=== Write plain javascript ===&lt;br /&gt;
Should you wan to write plain javascript, you can easily do so. What you need to do is actually load the file like so in &amp;lt;code&amp;gt;X.js&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 *------&lt;br /&gt;
 * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
 * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
 *&lt;br /&gt;
 * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
 * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
 * -----&lt;br /&gt;
 *&lt;br /&gt;
 * X.js&lt;br /&gt;
 *&lt;br /&gt;
 * X user interface script&lt;br /&gt;
 * &lt;br /&gt;
 * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&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;./modules/path/to/firstfile.js&amp;quot;,        //The first file with your JS code&lt;br /&gt;
    &amp;quot;./modules/path/to/secondfile.js&amp;quot;,       //The second file with another part of your JS code&lt;br /&gt;
    ...&lt;br /&gt;
],&lt;br /&gt;
function (dojo, declare) {&lt;br /&gt;
    return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
        constructor: function(){&lt;br /&gt;
            ...&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
According to the dojo toolkit documentation, you will then need to directly access what you defined in the files.&lt;br /&gt;
&lt;br /&gt;
=== Write an AMD module ===&lt;br /&gt;
You can take advantage of the toolkit&#039;s module system to declare dependencies between the differents files you&#039;ll be writing (modules in the toolkit&#039;s language). To be identified as modules, your Javascript files will need to have the following structure:&lt;br /&gt;
&lt;br /&gt;
==== Create a named new class ====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[[modules/js/FirstModule.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
define([&lt;br /&gt;
    &amp;quot;dojo&amp;quot;,&lt;br /&gt;
    &amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
    other dependencies...&lt;br /&gt;
],function(dojo, declare){&lt;br /&gt;
    return declare(&amp;quot;className&amp;quot;, /*Parent classes that this class inherits, optional*/, {&lt;br /&gt;
        /* static properties */&lt;br /&gt;
        let property1 = &amp;quot;value;&lt;br /&gt;
        let property2 = 5;&lt;br /&gt;
        constructor: function (args) {&lt;br /&gt;
            /* instance properties */&lt;br /&gt;
            let property3 = 8;&lt;br /&gt;
            let property4 = [ &amp;quot;arrayValue&amp;quot;, &amp;quot;arrayValue2&amp;quot; ]; &lt;br /&gt;
        }&lt;br /&gt;
        method1: function (args) {&lt;br /&gt;
            /* your code here */&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;
Then in the X.js file, you can use your newly created module like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 *------&lt;br /&gt;
 * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
 * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
 *&lt;br /&gt;
 * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
 * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
 * -----&lt;br /&gt;
 *&lt;br /&gt;
 * X.js&lt;br /&gt;
 *&lt;br /&gt;
 * X user interface script&lt;br /&gt;
 * &lt;br /&gt;
 * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&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;./modules/js/Firstmodule&amp;quot;,&lt;br /&gt;
],&lt;br /&gt;
function (dojo, declare) {&lt;br /&gt;
    return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
    ...&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In your code, you can access your module&#039;s class and methods by doing so:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    let object = new className();&lt;br /&gt;
    object.method1();&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This can lead to namespace collisions if you don&#039;t choose a namespace correctly, so you might want to take the same approach as described earlier for the PHP files for using a namespace.&lt;br /&gt;
&lt;br /&gt;
==== Create an anonymous class ====&lt;br /&gt;
&lt;br /&gt;
This is the recommended way according to the dojo toolkit documentation, but it requires a bit more modification than the previous method:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[[modules/js/SecondModule.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
define([&lt;br /&gt;
    &amp;quot;dojo&amp;quot;,&lt;br /&gt;
    &amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
    other dependencies...&lt;br /&gt;
],function(dojo, declare){&lt;br /&gt;
    return declare(null, /*Parent classes that this class inherits, optional*/, {&lt;br /&gt;
        /* static properties */&lt;br /&gt;
        let property1 = &amp;quot;value;&lt;br /&gt;
        let property2 = 5;&lt;br /&gt;
        constructor: function (args) {&lt;br /&gt;
            /* instance properties */&lt;br /&gt;
            let property3 = 8;&lt;br /&gt;
            let property4 = [ &amp;quot;arrayValue&amp;quot;, &amp;quot;arrayValue2&amp;quot; ]; &lt;br /&gt;
        }&lt;br /&gt;
        method1: function (args) {&lt;br /&gt;
            /* your code here */&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;
Then in the X.js file, you can use your newly created module like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 *------&lt;br /&gt;
 * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
 * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
 *&lt;br /&gt;
 * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
 * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
 * -----&lt;br /&gt;
 *&lt;br /&gt;
 * X.js&lt;br /&gt;
 *&lt;br /&gt;
 * X user interface script&lt;br /&gt;
 * &lt;br /&gt;
 * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&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;./modules/js/SecondModule&amp;quot;,         //Has to be inserted in the third position as we&#039;ll need an identifier later, and the other modules don&#039;t need it, see code in the preceding subsection. &lt;br /&gt;
    &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
    &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
    &amp;quot;./modules/js/Firstmodule&amp;quot;,&lt;br /&gt;
],&lt;br /&gt;
function (dojo, declare, SecondModule /* insert a reference here that you&#039;ll use throughout the JS file for this module */) {&lt;br /&gt;
    return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
    ...&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In your code, you can then access your module&#039;s class and methods by doing so:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    let someValue = SecondModule.property3&lt;br /&gt;
    SecondModule.method1();&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Create a singleton object ====&lt;br /&gt;
&lt;br /&gt;
You can also create singleton objects by creating a module this way:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[[modules/js/singletonObject.js]]&lt;br /&gt;
define([&lt;br /&gt;
    &amp;quot;dojo&amp;quot;,&lt;br /&gt;
    ...&lt;br /&gt;
], function (dojo) {&lt;br /&gt;
    // Methods and variables defined in this part will not be available anywhere else than in this file&lt;br /&gt;
    let privateVariable = &amp;quot;someValue&amp;quot;;&lt;br /&gt;
    let privateFunction = function (args) {&lt;br /&gt;
        //some code here&lt;br /&gt;
    }&lt;br /&gt;
    return {&lt;br /&gt;
        firstMethod: function (args) {&lt;br /&gt;
            privateFunction(args);&lt;br /&gt;
            //some other code here&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To be used in the &amp;lt;code&amp;gt;X.js&amp;lt;/code&amp;gt; file, you must use the same method as in the [[#Create an anonymous class|previous section]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 *------&lt;br /&gt;
 * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
 * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
 *&lt;br /&gt;
 * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
 * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
 * -----&lt;br /&gt;
 *&lt;br /&gt;
 * X.js&lt;br /&gt;
 *&lt;br /&gt;
 * X user interface script&lt;br /&gt;
 * &lt;br /&gt;
 * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&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;./modules/js/SecondModule&amp;quot;,         //Has to be inserted in the third position as we&#039;ll need an identifier later, and the other modules don&#039;t need it, see code in the preceding subsection.&lt;br /&gt;
    &amp;quot;./modules/js/sigletonObject&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;./modules/js/Firstmodule&amp;quot;,&lt;br /&gt;
],&lt;br /&gt;
function (dojo, declare, SecondModule /* insert a reference here that you&#039;ll use throughout the JS file for this module */, singletonObject) {&lt;br /&gt;
    return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
    ...&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then you can access your code the same way as described in the [[#Create an anonymous class|previous section]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    singletonObject.firstMethod();&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Putting it all together ==&lt;br /&gt;
&#039;&#039;&#039;TODO&#039;&#039;&#039;&lt;/div&gt;</summary>
		<author><name>SwHawk</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=User:SwHawk/Create_Modular_Code&amp;diff=13580</id>
		<title>User:SwHawk/Create Modular Code</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=User:SwHawk/Create_Modular_Code&amp;diff=13580"/>
		<updated>2022-06-14T15:20:01Z</updated>

		<summary type="html">&lt;p&gt;SwHawk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{InfoBox|title=WIP|body=&#039;&#039;&#039;This article is a Work In Progress, please do not refer to it for production purposes&#039;&#039;&#039;}}&lt;br /&gt;
&lt;br /&gt;
This page will cover steps you can take as a BGA developer to make your code more modular and better organized. The way the framework is implemented makes the [[Main game logic: yourgamename.game.php|game logic]] and the [[Game interface logic: yourgamename.js|interface logic]] files very monolithic. While this is not a problem in itself, even simple to moderately complex game may require this files to be over 5k lines of code. Thus you can quickly become lost in all the functions you need to declare, where they are declared, and where they are called.&lt;br /&gt;
&lt;br /&gt;
But there are steps that you can follow to take advantage of PHP&#039;s Object Oriented Code and the dojo toolkit&#039;s AMD loader to organize your code in separate files. Let&#039;s see what&#039;s available:&lt;br /&gt;
&lt;br /&gt;
== On the PHP side ==&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt; vs &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; ===&lt;br /&gt;
Throughout this section, I&#039;ll make heavy use of PHP&#039;s &amp;lt;code&amp;gt;require_once&amp;lt;/code&amp;gt; control structure. Why am I using &amp;lt;code&amp;gt;require(_once)&amp;lt;/code&amp;gt; instead of &amp;lt;code&amp;gt;include_once&amp;lt;/code&amp;gt;? Because if an error exists in a PHP file that you try to &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt;, only a warning will be thrown, but the script will continue in spite of the error. Using &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; if the included file has an error, the script dies when the inclusion takes places, throwing a fatal error (&amp;lt;code&amp;gt;E_COMPILE_ERROR&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
That way, I&#039;m sure the classes, traits or interfaces I&#039;m including are syntax error free.&lt;br /&gt;
&lt;br /&gt;
=== Game logic methods ===&lt;br /&gt;
The way the framework is implemented, your game logic is gathered inside a class (&amp;lt;code&amp;gt;YourProjectName&amp;lt;/code&amp;gt;) extending the [[Table|&amp;lt;code&amp;gt;Table&amp;lt;/code&amp;gt; class]]. You define your methods there so that they may be called from other parts of the framework (as long as they&#039;re public methods obviously).&lt;br /&gt;
&lt;br /&gt;
But you can take advantage of [https://www.php.net/manual/en/language.oop5.traits.php PHP Traits]. In a nutshell, Traits are a collection of methods that can be reused in different classes, to avoid code duplication. Here we&#039;re not going to reuse them anywhere else than in the game class, but this little trick allows us to put methods definitions in other files, and in so doing to avoid monolithic code.&lt;br /&gt;
&lt;br /&gt;
Basically you create a Trait in th &amp;lt;code&amp;gt;/modules/&amp;lt;/code&amp;gt; directory, for instance:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;[[modules/UtiltityFunctionsTrait.php]]&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
namespace YourProjectNamespace\Modules;&lt;br /&gt;
&lt;br /&gt;
trait UtilityFunctionsTrait {&lt;br /&gt;
&lt;br /&gt;
    public function myFirstUtilityFunction($args)&lt;br /&gt;
    {&lt;br /&gt;
        //Your code here&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then you can include it in you project&#039;s &amp;lt;code&amp;gt;X.game.php&amp;lt;/code&amp;gt; file like so:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;[[X_game.php]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  * &lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  * &lt;br /&gt;
  * X.game.php&lt;br /&gt;
  *&lt;br /&gt;
  * This is the main file for your game logic.&lt;br /&gt;
  *&lt;br /&gt;
  * In this PHP file, you are going to defines the rules of the game.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&gt;
&lt;br /&gt;
require_once &#039;modules/UtilityFunctionsTrait.php&#039;; //Here we require the trait to be loaded when the class is loaded&lt;br /&gt;
&lt;br /&gt;
use YourProjectNamespace\Modules\UtilityFunctionsTrait; //We import the trait to be used directly as UtilityFunctionsTraits, otherwise we would have to use the Fully qualified class name (YourProjectNamespace\Modules\UtilityFunctionsTrait)&lt;br /&gt;
&lt;br /&gt;
class YourProjectName extends Table&lt;br /&gt;
{&lt;br /&gt;
//...&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
//////////// Utility functions&lt;br /&gt;
////////////    &lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
        In this space, you can put any utility methods useful for your game logic&lt;br /&gt;
    */&lt;br /&gt;
&lt;br /&gt;
    use UtilityFunctionsTrait; //Here we actually include the trait inside the class, making all the trait&#039;s methods available as class methods, keeping their visibility scope (so a private method is still private)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Support classes ===&lt;br /&gt;
Basically, the same as traits, you put your classes definitions into files that live under the &amp;lt;code&amp;gt;/modules/&amp;lt;/code&amp;gt; directory (don&#039;t forget to namespace your classes), and then require them at the top of &amp;lt;code&amp;gt;X_game.php&amp;lt;/code&amp;gt;, and voilà, you&#039;re done&lt;br /&gt;
&lt;br /&gt;
=== Adding autoloader support ===&lt;br /&gt;
&lt;br /&gt;
==== Coding standards ====&lt;br /&gt;
Even for simple games, you might end up having a dozen of traits and support classes. You can require them all in your &amp;lt;code&amp;gt;X_game.php&amp;lt;/code&amp;gt;. Or you can use an autoloader, which will load the necessary classes and traits at runtime. There are two PSRs dealing with autloading standards (namely [https://www.php-fig.org/psr/psr-0 PSR-0] which is marked as deprecated and [https://www.php-fig.org/psr/psr-4 PSR-4]) which state that your namespaces should be a reflection of the directory structure of your project.&lt;br /&gt;
&lt;br /&gt;
Basically, when creating namespaces, you choose a namespace prefix. For example, you could use your BGA handle and the project name as a namespace prefix (would result in &amp;lt;code&amp;gt;\SwHawk\X&amp;lt;/code&amp;gt; in my case), and then the rest of the namespace would be the directory the file is in. I usually group classes and traits by the function they have in my project, so my &amp;lt;code&amp;gt;/modules/&amp;lt;/code&amp;gt; directory looks like that:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
modules/&lt;br /&gt;
    php/&lt;br /&gt;
        Factory/                      //Holds my factory classes&lt;br /&gt;
            AFactoryClass.php         //The namespace for this file would be \SwHawk\X\Factory, and the fully qualified class name would be \SwHawk\X\Factory\AFactoryClass&lt;br /&gt;
            ...&lt;br /&gt;
        Object/                       //Holds my support classes&lt;br /&gt;
            ObjectA.php               //The namespace for this file would be \SwHawk\X\Object, and the fully qualified class name would be \SwHawk\X\Object\ObjectA&lt;br /&gt;
            ...&lt;br /&gt;
        Traits/                       //Holds my traits&lt;br /&gt;
            UtilityFunctionsTrait.php //The namespace for this file would be \SwHawk\X\Traits, and the fully qualified class name would be \SwHawk\X\Traits\UtilityFunctionsTrait&lt;br /&gt;
            ...&lt;br /&gt;
        ...&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Autoloader function for development ====&lt;br /&gt;
While your project is under development, you usually create, move and remove classes as part of the development process. So you usually need an autoloading function that can handle a lot of flexibility. Basically once you import a class using the &amp;lt;code&amp;gt;use&amp;lt;/code&amp;gt; keyword, the autoloading function will determine which file to &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; using its fully qualified class name, and then &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt;. Such a function would have the following code (borrowed and adapted from [https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader-examples.md this repository]):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
spl_autoload_register(function ($class) {&lt;br /&gt;
&lt;br /&gt;
    // project-specific namespace prefix, adapt to your needs, remember that you must escape \ characters in double-quoted strings (hence the \\)&lt;br /&gt;
    $prefix = &#039;SwHawk\\X\\&#039;;&lt;br /&gt;
&lt;br /&gt;
    // base directory for the namespace prefix, this file would usually reside in the modules/php/includes/ directory, so the base directory for all my classes would be a level higher&lt;br /&gt;
    $base_dir = __DIR__ . &#039;/../&#039;;&lt;br /&gt;
&lt;br /&gt;
    // does the class use the namespace prefix?&lt;br /&gt;
    $len = strlen($prefix);&lt;br /&gt;
    if (strncmp($prefix, $class, $len) !== 0) {&lt;br /&gt;
        // no, move to the next registered autoloader&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // get the relative class name&lt;br /&gt;
    $relative_class = substr($class, $len);&lt;br /&gt;
&lt;br /&gt;
    // replace the namespace prefix with the base directory, replace namespace&lt;br /&gt;
    // separators with directory separators in the relative class name, append&lt;br /&gt;
    // with .php&lt;br /&gt;
    $file = $base_dir . str_replace(&#039;\\&#039;, &#039;/&#039;, $relative_class) . &#039;.php&#039;;&lt;br /&gt;
&lt;br /&gt;
    // if the file exists, require it&lt;br /&gt;
    if (file_exists($file)) {&lt;br /&gt;
        require $file;&lt;br /&gt;
    }&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
==== Autoloader function for production ====&lt;br /&gt;
Once you&#039;re moving your game to production, the autoloader function provided before isn&#039;t optimized. Once in production, the directory tree should not be modified, so you can change the earlier autoloader to a classmap based one. Basically, you build an associative array with the fully qualified classes names as keys and the filepath as the value. An example would look like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
spl_autoload_register(function ($class) {&lt;br /&gt;
    static $classmap = array(&lt;br /&gt;
        &amp;quot;SwHawk\\X\\Factory\\AFactoryClass&amp;quot; =&amp;gt; __DIR__ . &amp;quot;/../Factory/AFactoryClass.php&amp;quot;,&lt;br /&gt;
        ...&lt;br /&gt;
    );&lt;br /&gt;
    if(array_key_exists($class)) {&lt;br /&gt;
        require $classmap[$class];&lt;br /&gt;
    } else {&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This autoloader is better suited to production since it won&#039;t use expensive calls like &amp;lt;code&amp;gt;file_exists($filename)&amp;lt;/code&amp;gt;. You can write the classmap by yourself, but it can be quite cumbersome, there is some tools like [https://github.com/hanneskod/classtools this project], or [https://github.com/gnugat/nomo-spaco this one], or even scripts detailed in this [https://stackoverflow.com/questions/22761554/how-to-get-all-class-names-inside-a-particular-namespace StackOverflow topic]&lt;br /&gt;
&lt;br /&gt;
== On the JS side ==&lt;br /&gt;
&lt;br /&gt;
BGA uses the dojo toolkit framework for most of its javascript code. Dojo comes with its own way of loading modules, which you can read about in more detail [https://dojotoolkit.org/documentation/tutorials/1.10/modules/ here] and [https://dojotoolkit.org/documentation/tutorials/1.10/modules_advanced/ here]. To put it simply, there are two ways you can go about this&lt;br /&gt;
&lt;br /&gt;
=== Write plain javascript ===&lt;br /&gt;
Should you wan to write plain javascript, you can easily do so. What you need to do is actually load the file like so in &amp;lt;code&amp;gt;X.js&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 *------&lt;br /&gt;
 * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
 * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
 *&lt;br /&gt;
 * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
 * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
 * -----&lt;br /&gt;
 *&lt;br /&gt;
 * X.js&lt;br /&gt;
 *&lt;br /&gt;
 * X user interface script&lt;br /&gt;
 * &lt;br /&gt;
 * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&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;./modules/path/to/firstfile.js&amp;quot;,        //The first file with your JS code&lt;br /&gt;
    &amp;quot;./modules/path/to/secondfile.js&amp;quot;,       //The second file with another part of your JS code&lt;br /&gt;
    ...&lt;br /&gt;
],&lt;br /&gt;
function (dojo, declare) {&lt;br /&gt;
    return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
        constructor: function(){&lt;br /&gt;
            ...&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
According to the dojo toolkit documentation, you will then need to directly access what you defined in the files.&lt;br /&gt;
&lt;br /&gt;
=== Write an AMD module ===&lt;br /&gt;
You can take advantage of the toolkit&#039;s module system to declare dependencies between the differents files you&#039;ll be writing (modules in the toolkit&#039;s language). To be identified as modules, your Javascript files will need to have the following structure:&lt;br /&gt;
&lt;br /&gt;
==== Create a named new class ====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[[modules/js/FirstModule.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
define([&lt;br /&gt;
    &amp;quot;dojo&amp;quot;,&lt;br /&gt;
    &amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
    other dependencies...&lt;br /&gt;
],function(dojo, declare){&lt;br /&gt;
    return declare(&amp;quot;className&amp;quot;, /*Parent classes that this class inherits, optional*/, {&lt;br /&gt;
        /* static properties */&lt;br /&gt;
        let property1 = &amp;quot;value;&lt;br /&gt;
        let property2 = 5;&lt;br /&gt;
        constructor: function (args) {&lt;br /&gt;
            /* instance properties */&lt;br /&gt;
            let property3 = 8;&lt;br /&gt;
            let property4 = [ &amp;quot;arrayValue&amp;quot;, &amp;quot;arrayValue2&amp;quot; ]; &lt;br /&gt;
        }&lt;br /&gt;
        method1: function (args) {&lt;br /&gt;
            /* your code here */&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;
Then in the X.js file, you can use your newly created module like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 *------&lt;br /&gt;
 * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
 * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
 *&lt;br /&gt;
 * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
 * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
 * -----&lt;br /&gt;
 *&lt;br /&gt;
 * X.js&lt;br /&gt;
 *&lt;br /&gt;
 * X user interface script&lt;br /&gt;
 * &lt;br /&gt;
 * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&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;./modules/js/Firstmodule&amp;quot;,&lt;br /&gt;
],&lt;br /&gt;
function (dojo, declare) {&lt;br /&gt;
    return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
    ...&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In your code, you can access your module&#039;s class and methods by doing so:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    let object = new className();&lt;br /&gt;
    object.method1();&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This can lead to namespace collisions if you don&#039;t choose a namespace correctly, so you might want to take the same approach as described earlier for the PHP files for using a namespace.&lt;br /&gt;
&lt;br /&gt;
==== Create an anonymous class ====&lt;br /&gt;
&lt;br /&gt;
This is the recommended way according to the dojo toolkit documentation, but it requires a bit more modification than the previous method:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[[modules/js/SecondModule.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
define([&lt;br /&gt;
    &amp;quot;dojo&amp;quot;,&lt;br /&gt;
    &amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
    other dependencies...&lt;br /&gt;
],function(dojo, declare){&lt;br /&gt;
    return declare(null, /*Parent classes that this class inherits, optional*/, {&lt;br /&gt;
        /* static properties */&lt;br /&gt;
        let property1 = &amp;quot;value;&lt;br /&gt;
        let property2 = 5;&lt;br /&gt;
        constructor: function (args) {&lt;br /&gt;
            /* instance properties */&lt;br /&gt;
            let property3 = 8;&lt;br /&gt;
            let property4 = [ &amp;quot;arrayValue&amp;quot;, &amp;quot;arrayValue2&amp;quot; ]; &lt;br /&gt;
        }&lt;br /&gt;
        method1: function (args) {&lt;br /&gt;
            /* your code here */&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;
Then in the X.js file, you can use your newly created module like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 *------&lt;br /&gt;
 * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
 * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
 *&lt;br /&gt;
 * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
 * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
 * -----&lt;br /&gt;
 *&lt;br /&gt;
 * X.js&lt;br /&gt;
 *&lt;br /&gt;
 * X user interface script&lt;br /&gt;
 * &lt;br /&gt;
 * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&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;./modules/js/SecondModule&amp;quot;,         //Has to be inserted in the third position as we&#039;ll need an identifier later, and the other modules don&#039;t need it, see code in the preceding subsection. &lt;br /&gt;
    &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
    &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
    &amp;quot;./modules/js/Firstmodule&amp;quot;,&lt;br /&gt;
],&lt;br /&gt;
function (dojo, declare, SecondModule /* insert a reference here that you&#039;ll use throughout the JS file for this module */) {&lt;br /&gt;
    return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
    ...&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In your code, you can then access your module&#039;s class and methods by doing so:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    let someValue = SecondModule.property3&lt;br /&gt;
    SecondModule.method1();&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Create a singleton object ====&lt;br /&gt;
&lt;br /&gt;
You can also create singleton objects by creating a module this way:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[[modules/js/singletonObject.js]]&lt;br /&gt;
define([&lt;br /&gt;
    &amp;quot;dojo&amp;quot;,&lt;br /&gt;
    ...&lt;br /&gt;
], function (dojo) {&lt;br /&gt;
    // Methods and variables defined in this part will not be available anywhere else than in this file&lt;br /&gt;
    let privateVariable = &amp;quot;someValue&amp;quot;;&lt;br /&gt;
    let privateFunction = function (args) {&lt;br /&gt;
        //some code here&lt;br /&gt;
    }&lt;br /&gt;
    return {&lt;br /&gt;
        firstMethod: function (args) {&lt;br /&gt;
            privateFunction(args);&lt;br /&gt;
            //some other code here&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To be used in the &amp;lt;code&amp;gt;X.js&amp;lt;/code&amp;gt; file, you must use the same method as in the [[#Create an anonymous class|previous section]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[[X.js]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 *------&lt;br /&gt;
 * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
 * X implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
 *&lt;br /&gt;
 * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
 * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
 * -----&lt;br /&gt;
 *&lt;br /&gt;
 * X.js&lt;br /&gt;
 *&lt;br /&gt;
 * X user interface script&lt;br /&gt;
 * &lt;br /&gt;
 * In this file, you are describing the logic of your user interface, in Javascript language.&lt;br /&gt;
 *&lt;br /&gt;
 */&lt;br /&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;./modules/js/SecondModule&amp;quot;,         //Has to be inserted in the third position as we&#039;ll need an identifier later, and the other modules don&#039;t need it, see code in the preceding subsection.&lt;br /&gt;
    &amp;quot;./modules/js/sigletonObject&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;./modules/js/Firstmodule&amp;quot;,&lt;br /&gt;
],&lt;br /&gt;
function (dojo, declare, SecondModule /* insert a reference here that you&#039;ll use throughout the JS file for this module */, singletonObject) {&lt;br /&gt;
    return declare(&amp;quot;bgagame.X&amp;quot;, ebg.core.gamegui, {&lt;br /&gt;
    ...&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then you can access your code the same way as described in the [[#Create an anonymous class|previous section]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    singletonObject.firstMethod();&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Putting it all together ==&lt;/div&gt;</summary>
		<author><name>SwHawk</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=User:SwHawk/Create_Modular_Code&amp;diff=13579</id>
		<title>User:SwHawk/Create Modular Code</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=User:SwHawk/Create_Modular_Code&amp;diff=13579"/>
		<updated>2022-06-14T13:53:59Z</updated>

		<summary type="html">&lt;p&gt;SwHawk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{InfoBox|title=WIP|body=&#039;&#039;&#039;This article is a Work In Progress, please do not refer to it for production purposes&#039;&#039;&#039;}}&lt;br /&gt;
&lt;br /&gt;
This page will cover steps you can take as a BGA developer to make your code more modular and better organized. The way the framework is implemented makes the [[Main game logic: yourgamename.game.php|game logic]] and the [[Game interface logic: yourgamename.js|interface logic]] files very monolithic. While this is not a problem in itself, even simple to moderately complex game may require this files to be over 5k lines of code. Thus you can quickly become lost in all the functions you need to declare, where they are declared, and where they are called.&lt;br /&gt;
&lt;br /&gt;
But there are steps that you can follow to take advantage of PHP&#039;s Object Oriented Code and the dojo toolkit&#039;s AMD loader to organize your code in separate files. Let&#039;s see what&#039;s available:&lt;br /&gt;
&lt;br /&gt;
== On the PHP side ==&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt; vs &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; ===&lt;br /&gt;
Throughout this section, I&#039;ll make heavy use of PHP&#039;s &amp;lt;code&amp;gt;require_once&amp;lt;/code&amp;gt; control structure. Why am I using &amp;lt;code&amp;gt;require(_once)&amp;lt;/code&amp;gt; instead of &amp;lt;code&amp;gt;include_once&amp;lt;/code&amp;gt;? Because if an error exists in a PHP file that you try to &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt;, only a warning will be thrown, but the script will continue in spite of the error. Using &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; if the included file has an error, the script dies when the inclusion takes places, throwing a fatal error (E_COMPILE_ERROR).&lt;br /&gt;
&lt;br /&gt;
That way, I&#039;m sure the classes, traits or interfaces I&#039;m including are syntax error free.&lt;br /&gt;
&lt;br /&gt;
=== Game logic methods ===&lt;br /&gt;
The way the framework is implemented, your game logic is gathered inside a class (`YourProjectName`) extending the [[Table|`Table` class]]. You define your methods there so that they may be called from other parts of the framework (as long as they&#039;re public methods obviously).&lt;br /&gt;
&lt;br /&gt;
But you can take advantage of [https://www.php.net/manual/en/language.oop5.traits.php PHP Traits]. In a nutshell, Traits are a collection of methods that can be reused in different classes, to avoid code duplication. Here we&#039;re not going to reuse them anywhere else than in the game class, but this little trick allows us to put methods definitions in other files, and in so doing to avoid monolithic code.&lt;br /&gt;
&lt;br /&gt;
Basically you create a Trait in th &amp;lt;code&amp;gt;/modules/&amp;lt;/code&amp;gt; directory, for instance:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;[[modules/UtiltityFunctionsTrait.php]]&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
namespace YourProjectNamespace\Modules;&lt;br /&gt;
&lt;br /&gt;
trait UtilityFunctionsTrait {&lt;br /&gt;
&lt;br /&gt;
    public function myFirstUtilityFunction($args)&lt;br /&gt;
    {&lt;br /&gt;
        //Your code here&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then you can include it in you project&#039;s `game.php` file like so:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;[[X_game.php]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * ProgressEvolutionTechnologySwH implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  * &lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  * &lt;br /&gt;
  * progressevolutiontechnologyswh.game.php&lt;br /&gt;
  *&lt;br /&gt;
  * This is the main file for your game logic.&lt;br /&gt;
  *&lt;br /&gt;
  * In this PHP file, you are going to defines the rules of the game.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&gt;
&lt;br /&gt;
require_once &#039;modules/UtilityFunctionsTrait.php&#039;; //Here we require the trait to be loaded when the class is loaded&lt;br /&gt;
&lt;br /&gt;
use YourProjectNamespace\Modules\UtilityFunctionsTrait; //We import the trait to be used directly as UtilityFunctionsTraits, otherwise we would have to use the Fully qualified class name (YourProjectNamespace\Modules\UtilityFunctionsTrait)&lt;br /&gt;
&lt;br /&gt;
class YourProjectName extends Table&lt;br /&gt;
{&lt;br /&gt;
//...&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
//////////// Utility functions&lt;br /&gt;
////////////    &lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
        In this space, you can put any utility methods useful for your game logic&lt;br /&gt;
    */&lt;br /&gt;
&lt;br /&gt;
    use UtilityFunctionsTrait; //Here we actually include the trait inside the class, making all the trait&#039;s methods available as class methods, keeping their visibility scope (so a private method is still private)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Support classes ===&lt;br /&gt;
Basically, the same as traits, you put your classes definitions into files that live under the &amp;lt;code&amp;gt;/modules/&amp;lt;/code&amp;gt; directory (don&#039;t forget to namespace your classes), and then require them at the top of &amp;lt;code&amp;gt;X_game.php&amp;lt;/code&amp;gt;, and voilà, you&#039;re done&lt;br /&gt;
&lt;br /&gt;
=== Adding autoloader support ===&lt;br /&gt;
&lt;br /&gt;
==== Coding standards ====&lt;br /&gt;
Even for simple games, you might end up having a dozen of traits and support classes. You can require them all in your &amp;lt;code&amp;gt;X_game.php&amp;lt;/code&amp;gt;. Or you can use an autoloader, which will load the necessary classes and traits at runtime. There are two PSRs dealing with autloading standards (namely [https://www.php-fig.org/psr/psr-0 PSR-0] which is marked as deprecated and [https://www.php-fig.org/psr/psr-4 PSR-4]) which state that your namespaces should be a reflection of the directory structure of your project.&lt;br /&gt;
&lt;br /&gt;
Basically, when creating namespaces, you choose a namespace prefix. For example, you could use your BGA handle and the project name as a namespace prefix (would result in &amp;lt;code&amp;gt;\SwHawk\X&amp;lt;/code&amp;gt; in my case), and then the rest of the namespace would be the directory the file is in. I usually group classes and traits by the function they have in my project, so my &amp;lt;code&amp;gt;/modules/&amp;lt;/code&amp;gt; directory looks like that:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
modules/&lt;br /&gt;
    php/&lt;br /&gt;
        Factory/                      //Holds my factory classes&lt;br /&gt;
            AFactoryClass.php         //The namespace for this file would be \SwHawk\X\Factory, and the fully qualified class name would be \SwHawk\X\Factory\AFactoryClass&lt;br /&gt;
            ...&lt;br /&gt;
        Object/                       //Holds my support classes&lt;br /&gt;
            ObjectA.php               //The namespace for this file would be \SwHawk\X\Object, and the fully qualified class name would be \SwHawk\X\Object\ObjectA&lt;br /&gt;
            ...&lt;br /&gt;
        Traits/                       //Holds my traits&lt;br /&gt;
            UtilityFunctionsTrait.php //The namespace for this file would be \SwHawk\X\Traits, and the fully qualified class name would be \SwHawk\X\Traits\UtilityFunctionsTrait&lt;br /&gt;
            ...&lt;br /&gt;
        ...&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Autoloader function for development ====&lt;br /&gt;
While your project is under development, you usually create, move and remove classes as part of the development process. So you usually need an autoloading function that can handle a lot of flexibility. Basically once you import a class using the &amp;lt;code&amp;gt;use&amp;lt;/code&amp;gt;, the autoloading function will determine which file to &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; using its fully qualified class name, and then &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt;. Such a function would have the following code (borrowed and adapted from [https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader-examples.md]):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
spl_autoload_register(function ($class) {&lt;br /&gt;
&lt;br /&gt;
    // project-specific namespace prefix, adapt to your needs&lt;br /&gt;
    $prefix = &#039;SwHawk\\X\\&#039;;&lt;br /&gt;
&lt;br /&gt;
    // base directory for the namespace prefix, this file would usually reside in the modules/php/includes/ directory, so the base directory for all my classes would be a level higher&lt;br /&gt;
    $base_dir = __DIR__ . &#039;/../&#039;;&lt;br /&gt;
&lt;br /&gt;
    // does the class use the namespace prefix?&lt;br /&gt;
    $len = strlen($prefix);&lt;br /&gt;
    if (strncmp($prefix, $class, $len) !== 0) {&lt;br /&gt;
        // no, move to the next registered autoloader&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // get the relative class name&lt;br /&gt;
    $relative_class = substr($class, $len);&lt;br /&gt;
&lt;br /&gt;
    // replace the namespace prefix with the base directory, replace namespace&lt;br /&gt;
    // separators with directory separators in the relative class name, append&lt;br /&gt;
    // with .php&lt;br /&gt;
    $file = $base_dir . str_replace(&#039;\\&#039;, &#039;/&#039;, $relative_class) . &#039;.php&#039;;&lt;br /&gt;
&lt;br /&gt;
    // if the file exists, require it&lt;br /&gt;
    if (file_exists($file)) {&lt;br /&gt;
        require $file;&lt;br /&gt;
    }&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
==== Autoloader function for production ====&lt;br /&gt;
Once you&#039;re moving your game to production, the autoloader function provided before isn&#039;t optimized. Once in production, the directory tree should not be modified, so you can change the earlier autoloader to a classmap based one. Basically, you build an associative array with the fully qualified classes names as keys and the filepath as the value. An example would look like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
spl_autoload_register(function ($class) {&lt;br /&gt;
    static $classmap = array(&lt;br /&gt;
        &amp;quot;SwHawk\\X\\Factory\\AFactoryClass&amp;quot; =&amp;gt; __DIR__ . &amp;quot;/../Factory/AFactoryClass.php&amp;quot;,&lt;br /&gt;
        ...&lt;br /&gt;
    );&lt;br /&gt;
    if(array_key_exists($class)) {&lt;br /&gt;
        require $classmap[$class];&lt;br /&gt;
    } else {&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This autoloader is better suited to production since it won&#039;t use expensive calls like &amp;lt;code&amp;gt;file_exists($filename)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== On the JS side ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Putting it all together ==&lt;/div&gt;</summary>
		<author><name>SwHawk</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=User:SwHawk/Create_Modular_Code&amp;diff=13574</id>
		<title>User:SwHawk/Create Modular Code</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=User:SwHawk/Create_Modular_Code&amp;diff=13574"/>
		<updated>2022-06-13T14:55:58Z</updated>

		<summary type="html">&lt;p&gt;SwHawk: WIP: started PHP section&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{InfoBox|title=WIP|body=&#039;&#039;&#039;This article is a Work In Progress, please do not refer to it for production purposes&#039;&#039;&#039;}}&lt;br /&gt;
&lt;br /&gt;
This page will cover steps you can take as a BGA developer to make your code more modular and better organized. The way the framework is implemented makes the [[Main game logic: yourgamename.game.php|game logic]] and the [[Game interface logic: yourgamename.js|interface logic]] files very monolithic. While this is not a problem in itself, even simple to moderately complex game may require this files to be over 5k lines of code. Thus you can quickly become lost in all the functions you need to declare, where they are declared, and where they are called.&lt;br /&gt;
&lt;br /&gt;
But there are steps that you can follow to take advantage of PHP&#039;s Object Oriented Code and the dojo toolkit&#039;s AMD loader to organize your code in separate files. Let&#039;s see what&#039;s available:&lt;br /&gt;
&lt;br /&gt;
== On the PHP side ==&lt;br /&gt;
&lt;br /&gt;
=== Game logic methods ===&lt;br /&gt;
The way the framework is implemented, your game logic is gathered inside a class (`YourProjectName`) extending the [[Table|`Table` class]]. You define your methods there so that they may be called from other parts of the framework (as long as they&#039;re public methods obviously).&lt;br /&gt;
&lt;br /&gt;
But you can take advantage of [https://www.php.net/manual/en/language.oop5.traits.php PHP Traits]. In a nutshell, Traits are a collection of methods that can be reused in different classes, to avoid code duplication. Here we&#039;re not going to reuse them anywhere else than in the game class, but this little trick allows us to put methods definitions in other files, and in so doing to avoid monolithic code.&lt;br /&gt;
&lt;br /&gt;
Basically you create a Trait in the `modules` directory, for instance:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;[[modules\UtiltityFunctionsTrait.php]]&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
namespace YourProjectNamespace\Modules;&lt;br /&gt;
&lt;br /&gt;
trait UtilityFunctionsTrait {&lt;br /&gt;
&lt;br /&gt;
    public function myFirstUtilityFunction($args)&lt;br /&gt;
    {&lt;br /&gt;
        //Your code here&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then you can include it in you project&#039;s `game.php` file like so:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;[[X_game.php]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
 /**&lt;br /&gt;
  *------&lt;br /&gt;
  * BGA framework: © Gregory Isabelli &amp;lt;gisabelli@boardgamearena.com&amp;gt; &amp;amp; Emmanuel Colin &amp;lt;ecolin@boardgamearena.com&amp;gt;&lt;br /&gt;
  * ProgressEvolutionTechnologySwH implementation : © &amp;lt;Your name here&amp;gt; &amp;lt;Your email address here&amp;gt;&lt;br /&gt;
  * &lt;br /&gt;
  * This code has been produced on the BGA studio platform for use on http://boardgamearena.com.&lt;br /&gt;
  * See http://en.boardgamearena.com/#!doc/Studio for more information.&lt;br /&gt;
  * -----&lt;br /&gt;
  * &lt;br /&gt;
  * progressevolutiontechnologyswh.game.php&lt;br /&gt;
  *&lt;br /&gt;
  * This is the main file for your game logic.&lt;br /&gt;
  *&lt;br /&gt;
  * In this PHP file, you are going to defines the rules of the game.&lt;br /&gt;
  *&lt;br /&gt;
  */&lt;br /&gt;
&lt;br /&gt;
require_once &#039;modules/UtilityFunctionsTrait.php&#039;; //Here we require the trait to be loaded when the class is loaded&lt;br /&gt;
&lt;br /&gt;
use YourProjectNamespace\Modules\UtilityFunctionsTrait; //We import the trait to be used directly as UtilityFunctionsTraits, otherwise we would have to use the Fully qualified class name (YourProjectNamespace\Modules\UtilityFunctionsTrait)&lt;br /&gt;
&lt;br /&gt;
class YourProjectName extends Table&lt;br /&gt;
{&lt;br /&gt;
//...&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
//////////// Utility functions&lt;br /&gt;
////////////    &lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
        In this space, you can put any utility methods useful for your game logic&lt;br /&gt;
    */&lt;br /&gt;
&lt;br /&gt;
    use UtilityFunctionsTrait; //Here we actually include the trait inside the class, making all the trait&#039;s methods available as class methods, keeping their visibility scope (so a private method is still private)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Support classes ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Adding autoloader support ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== On the JS side ==&lt;/div&gt;</summary>
		<author><name>SwHawk</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Studio&amp;diff=13330</id>
		<title>Studio</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Studio&amp;diff=13330"/>
		<updated>2022-05-21T20:35:39Z</updated>

		<summary type="html">&lt;p&gt;SwHawk: /* PHP Extensions Used */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Studio_Framework_Navigation}}&lt;br /&gt;
&lt;br /&gt;
[[File:Bga_studio_small.jpg]]&lt;br /&gt;
&lt;br /&gt;
Note: Please DO NOT translate Studio Documentation, so that there can be one place where you can find the latest information available.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== What is Board Game Arena Studio? ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Board Game Arena Studio&#039;&#039;&#039; is a platform to build online board game adaptations using the Board Game Arena platform.&lt;br /&gt;
&lt;br /&gt;
It is open to any gamer with software development skills :)&lt;br /&gt;
&lt;br /&gt;
BGA Studio website: https://studio.boardgamearena.com&lt;br /&gt;
&lt;br /&gt;
Original announcement on BGA forum: https://forum.boardgamearena.com/viewtopic.php?f=10&amp;amp;t=1973&lt;br /&gt;
&lt;br /&gt;
== Discover BGA Studio in 5 presentations ==&lt;br /&gt;
&lt;br /&gt;
Why, how, what... to start discovering BGA Studio, we prepared 5 &amp;quot;powerpoint&amp;quot; presentations for you:&lt;br /&gt;
&lt;br /&gt;
* [http://www.slideshare.net/boardgamearena/5-reasons-why-you-should-use-bga-studio-for-your-online-board-game 5 reasons why you should use BGA Studio for your online board game] (or [http://en.doc.boardgamearena.com/images/5/58/1-why-developing.pdf ‎Download as PDF])&lt;br /&gt;
* [http://www.slideshare.net/boardgamearena/the-8-steps-to-create-a-board-game-on-board-game-arena The 8 steps to create a board game on Board Game Arena] (or [http://en.doc.boardgamearena.com/images/1/1e/2-8-steps-to-realize.pdf Download as PDF])&lt;br /&gt;
* [http://www.slideshare.net/boardgamearena/the-bga-framework-at-a-glance The BGA Framework at a glance] (or [http://en.doc.boardgamearena.com/images/7/79/3-thebgaframework.pdf Download as PDF])&lt;br /&gt;
* [http://www.slideshare.net/boardgamearena/bga-studio-focus-on-bga-game-state-machine Focus on BGA game state machine] (or [http://en.doc.boardgamearena.com/images/9/98/4-gamestates.pdf Download as PDF])&lt;br /&gt;
* [http://www.slideshare.net/boardgamearena/bga-studio-guidelines BGA developers guidelines] (or [http://en.doc.boardgamearena.com/images/7/76/5-guidelines.pdf ‎Download as PDF])&lt;br /&gt;
&lt;br /&gt;
== How to join the BGA developer team? ==&lt;br /&gt;
&lt;br /&gt;
Please see this page: [[How to join BGA developer team?]]&lt;br /&gt;
&lt;br /&gt;
== Great, I&#039;m in! ... How should I start? ==&lt;br /&gt;
&lt;br /&gt;
If you didn&#039;t already, check the presentations at the top of this page to get the basics.&lt;br /&gt;
&lt;br /&gt;
Then, you should checkout the [[First steps with BGA Studio]] to make sure that runs fine.&lt;br /&gt;
&lt;br /&gt;
After that, we strongly advise you to take one of these game creation tutorials:&lt;br /&gt;
* [[Tutorial reversi]] - an abstract strategy game played on an 8×8 uncheckered board for 2 players&lt;br /&gt;
* [[Tutorial gomoku]] - an abstract strategy game tic-tac-toe style for 2 players&lt;br /&gt;
* [[Tutorial hearts]] - a card game for 4 players&lt;br /&gt;
&lt;br /&gt;
Then start editing files and see what happens! ;)&lt;br /&gt;
&lt;br /&gt;
Once you&#039;re done with tutorials, you can start a real game (or join existing project)&lt;br /&gt;
* [[Create a game in BGA Studio: Complete Walkthrough]] &lt;br /&gt;
&lt;br /&gt;
If you have any questions, please check out the [[Studio FAQ]] or [[Contact BGA Studio]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To search wiki pages on studio enter this text in search bar: &lt;br /&gt;
  &amp;quot;Category:Studio&amp;quot; white rabbit &lt;br /&gt;
That is if you want to search for white rabbit&lt;br /&gt;
&lt;br /&gt;
== BGA Studio documentation ==&lt;br /&gt;
&lt;br /&gt;
=== BGA Studio Framework reference ===&lt;br /&gt;
&lt;br /&gt;
This part of the documentation focuses on the development framework itself: functions and methods available to build your game.&lt;br /&gt;
&lt;br /&gt;
[[Studio file reference|File structure of a BGA game]]&lt;br /&gt;
&lt;br /&gt;
==== Game logic (Server side) ====&lt;br /&gt;
&lt;br /&gt;
* [[Main game logic: yourgamename.game.php]]&lt;br /&gt;
* [[Your game state machine: states.inc.php]]&lt;br /&gt;
* [[Game database model: dbmodel.sql]]&lt;br /&gt;
* [[Players actions: yourgamename.action.php]]&lt;br /&gt;
* [[Game material description: material.inc.php]]&lt;br /&gt;
* [[Game statistics: stats.inc.php]]&lt;br /&gt;
&lt;br /&gt;
==== Game interface (Client side) ====&lt;br /&gt;
&lt;br /&gt;
* [[Game interface logic: yourgamename.js]]&lt;br /&gt;
* [[Game art: img directory]]&lt;br /&gt;
* [[Game interface stylesheet: yourgamename.css]]&lt;br /&gt;
* [[Game layout: view and template: yourgamename.view.php and yourgamename_yourgamename.tpl]]&lt;br /&gt;
* [[Your game mobile version]]&lt;br /&gt;
&lt;br /&gt;
==== Other components ====&lt;br /&gt;
&lt;br /&gt;
* [[Translations]] (how to make your game translatable)&lt;br /&gt;
* [[Game options and preferences: gameoptions.inc.php]]&lt;br /&gt;
* [[Game meta-information: gameinfos.inc.php]]&lt;br /&gt;
* [[Game replay]]&lt;br /&gt;
* [[3D]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== BGA Studio game components reference ===&lt;br /&gt;
&lt;br /&gt;
Game components are useful tools you can use in your game adaptations.&lt;br /&gt;
&lt;br /&gt;
JS:&lt;br /&gt;
&lt;br /&gt;
* [[Counter]]: a JS component to manage a counter that can increase/decrease (ex: player&#039;s score).&lt;br /&gt;
* [[Scrollmap]]: a JS component to manage a scrollable game area (useful when the game area can be infinite. Examples:  Saboteur or Takenoko games).&lt;br /&gt;
* [[Stock]]: a JS component to manage and display a set of game elements displayed at a position.&lt;br /&gt;
* [[Zone]]: a JS component to manage a zone of the board where several game elements can come and leave, but should be well displayed together (See for example: token&#039;s places at Can&#039;t Stop).&lt;br /&gt;
* [[Draggable]]: a JS component to manage drag&#039;n&#039;drop actions.&lt;br /&gt;
* [[ExpandableSection]]: a JS component to manage a rectangular block of HTML than can be displayed/hidden.&lt;br /&gt;
* [[Anti-Stock]]:Code snippets in ValinaJS/HTML5 to do what stock does (that is if you cannot beat Stock into submission)&lt;br /&gt;
&lt;br /&gt;
PHP:&lt;br /&gt;
* [[Deck]]: a PHP component to manage cards (deck, hands, picking cards, moving cards, shuffle deck, ...).&lt;br /&gt;
&lt;br /&gt;
Reference for classes in game class hierarchy&lt;br /&gt;
&lt;br /&gt;
* [[Table]]: a PHP class that you inherit from for the game php&lt;br /&gt;
&lt;br /&gt;
=== BGA Studio user guide ===&lt;br /&gt;
&lt;br /&gt;
This part of the documentation is a user guide for the BGA Studio online development environment.&lt;br /&gt;
&lt;br /&gt;
Lifecycle&lt;br /&gt;
&lt;br /&gt;
* [[BGA game Lifecycle]]&lt;br /&gt;
* [[Create a game in BGA Studio: Complete Walkthrough]]&lt;br /&gt;
* [[Pre-release checklist]] - Go throught this list if you think you done development&lt;br /&gt;
* [[Post-release phase]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Tools and Advice&lt;br /&gt;
* [[BGA Studio Guidelines]]&lt;br /&gt;
* [[I wish I knew this when I started]] - one liners on most common missed features, mistakes, etc with further doc references&lt;br /&gt;
* [[Tools and tips of BGA Studio]] - Tips and instructions on setting up development environment&lt;br /&gt;
** [[Practical debugging]] - Tips focused on debugging&lt;br /&gt;
** [[Studio logs]] - Instructions for log access&lt;br /&gt;
** [[Troubleshooting]] - Most common &amp;quot;I am really stuck&amp;quot; situations&lt;br /&gt;
* [[BGA Studio Cookbook]] - Tips and instructions on using API&#039;s, libraries and frameworks&lt;br /&gt;
** [[Using Vue]] - work-in-progress guide on using the modern framework Vue.js to create a game&lt;br /&gt;
** [[Using Typescript and Scss]] - How to auto-build Typescript and SCSS files to make your code cleaner&lt;br /&gt;
** [[Bots and Artificial Intelligence]] - How to add AI/Bots to the game&lt;br /&gt;
* [[Studio FAQ]]&lt;br /&gt;
&lt;br /&gt;
Sharing&lt;br /&gt;
* [[Common board game elements image resources]] - Dice, meeples, cubes, etc&lt;br /&gt;
* [[BGA Code Sharing]] - Shared resources, projects on git hub, common code, other links&lt;br /&gt;
&lt;br /&gt;
== Other resources ==&lt;br /&gt;
&lt;br /&gt;
[http://forum.boardgamearena.com/viewforum.php?f=12 Development forum]&lt;br /&gt;
&lt;br /&gt;
[https://studio.boardgamearena.com/bugs Bug tracking system FOR STUDIO issues and APIs]&lt;br /&gt;
&lt;br /&gt;
DISCORD chat server/room invite link https://discord.gg/YxEUacY if it does not work check this topic https://forum.boardgamearena.com/viewtopic.php?f=12&amp;amp;t=17403&amp;amp;hilit=discord&lt;br /&gt;
&lt;br /&gt;
Developer BLOGS https://bga-devs.github.io/blog/&lt;br /&gt;
&lt;br /&gt;
[[Contact BGA Studio]]&lt;br /&gt;
&lt;br /&gt;
== Software Versions ==&lt;br /&gt;
&lt;br /&gt;
Versions currently used by BGA framework:&lt;br /&gt;
&lt;br /&gt;
* Dojo Toolkit 1.15&lt;br /&gt;
* PHP: 7.4&lt;br /&gt;
* SQL: MySQL 5.7&lt;br /&gt;
* JS/CSS/HTML: limited by what minimization tools support [[Game_interface_logic:_yourgamename.js#Javascript_minimization_.28after_July_2020.29]]&lt;br /&gt;
* Font Awesome: 4.7 https://fontawesome.com/v4.7/icons/&lt;br /&gt;
&lt;br /&gt;
=== PHP Extensions Used ===&lt;br /&gt;
&lt;br /&gt;
The following PHP extensions are - as of May 8th, 2022 - in use in BGA Studio and available:&lt;br /&gt;
&lt;br /&gt;
* date&lt;br /&gt;
* libxml&lt;br /&gt;
* openssl&lt;br /&gt;
* pcre&lt;br /&gt;
* zlib&lt;br /&gt;
* filter&lt;br /&gt;
* hash&lt;br /&gt;
* Reflection&lt;br /&gt;
* SPL&lt;br /&gt;
* session&lt;br /&gt;
* standard&lt;br /&gt;
* sodium&lt;br /&gt;
* apache2handler&lt;br /&gt;
* mysqlnd&lt;br /&gt;
* PDO&lt;br /&gt;
* xml&lt;br /&gt;
* apcu&lt;br /&gt;
* bz2&lt;br /&gt;
* calendar&lt;br /&gt;
* ctype&lt;br /&gt;
* curl&lt;br /&gt;
* dom&lt;br /&gt;
* mbstring&lt;br /&gt;
* FFI&lt;br /&gt;
* fileinfo&lt;br /&gt;
* ftp&lt;br /&gt;
* gd&lt;br /&gt;
* gettext&lt;br /&gt;
* gmp&lt;br /&gt;
* iconv&lt;br /&gt;
* igbinary&lt;br /&gt;
* json&lt;br /&gt;
* exif&lt;br /&gt;
* msgpack&lt;br /&gt;
* mysqli&lt;br /&gt;
* pdo_mysql&lt;br /&gt;
* apc&lt;br /&gt;
* posix&lt;br /&gt;
* readline&lt;br /&gt;
* shmop&lt;br /&gt;
* SimpleXML&lt;br /&gt;
* sockets&lt;br /&gt;
* sysvmsg&lt;br /&gt;
* sysvsem&lt;br /&gt;
* sysvshm&lt;br /&gt;
* tokenizer&lt;br /&gt;
* v8js&lt;br /&gt;
* xmlreader&lt;br /&gt;
* xmlwriter&lt;br /&gt;
* xsl&lt;br /&gt;
* zip&lt;br /&gt;
* Phar&lt;br /&gt;
* memcached&lt;br /&gt;
* Zend OPcache&lt;br /&gt;
&lt;br /&gt;
[[Category:Studio]]&lt;/div&gt;</summary>
		<author><name>SwHawk</name></author>
	</entry>
</feed>