<?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=User+Already+Exists</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=User+Already+Exists"/>
	<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/Special:Contributions/User_Already_Exists"/>
	<updated>2026-10-06T18:18:01Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.39.0</generator>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Tips_hex&amp;diff=16166</id>
		<title>Tips hex</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Tips_hex&amp;diff=16166"/>
		<updated>2023-02-25T15:21:29Z</updated>

		<summary type="html">&lt;p&gt;User Already Exists: /* Experts and beyond */ updated wording&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
&lt;br /&gt;
Although the rules of Hex are very simple, its strategy is quite rich and has many layers. The good news is that there are many clever and satisfying strategy concepts that can be learned by players of all levels.&lt;br /&gt;
&lt;br /&gt;
== Strategy concepts by level ==&lt;br /&gt;
&lt;br /&gt;
The following is an approximate attempt to match up strategy skills with Elo levels.&lt;br /&gt;
&lt;br /&gt;
=== Beginners ===&lt;br /&gt;
&lt;br /&gt;
To reach level 100, you should learn about templates, especially the [https://www.hexwiki.net/index.php/Bridge bridge] and the [https://www.hexwiki.net/index.php/Ziggurat ziggurat]. You should also learn basic [https://www.hexwiki.net/index.php/Blocking blocking]. You might try a few dozen of Matthew Seymour&#039;s [http://www.mseymour.ca/hex_puzzle/ Hex puzzles].&lt;br /&gt;
&lt;br /&gt;
=== Average players ===&lt;br /&gt;
&lt;br /&gt;
To reach level 200, you should learn about [https://www.hexwiki.net/index.php/Ladder_handling ladder handling], especially [https://www.hexwiki.net/index.php/Ladder_escape ladder escapes]. You should learn more [https://www.hexwiki.net/index.php/Edge_templates_everybody_should_know templates]. You should solve more [http://www.mseymour.ca/hex_puzzle/ Hex puzzles].&lt;br /&gt;
&lt;br /&gt;
=== Good players ===&lt;br /&gt;
&lt;br /&gt;
To reach level 300, you should learn about [https://www.hexwiki.net/index.php/Climbing pivoting and climbing]. You should use template intrusions to steal territory and help you connect. You should recognize what is connected and what is not, to avoid defending the indefensible or attacking what is solid. You should also learn [https://www.hexwiki.net/index.php/Swap when to swap]. &lt;br /&gt;
&lt;br /&gt;
=== Strong players ===&lt;br /&gt;
&lt;br /&gt;
To reach level 400, you should learn some advanced ways of connecting, such as [https://www.hexwiki.net/index.php/Switchback switchbacks], [https://www.hexwiki.net/index.php/Foldback foldbacks], and [https://www.hexwiki.net/index.php/Tom%27s_move Tom&#039;s move]. You should learn to [https://www.hexwiki.net/index.php/Foiling foil], and especially, how to counter fishing moves. You should start to use [https://www.hexwiki.net/index.php/Minimax minimaxing], such as building [https://www.hexwiki.net/index.php/Wall walls]. You should play [https://www.hexwiki.net/index.php/Corner_move corner moves] in the opening. &lt;br /&gt;
&lt;br /&gt;
To reach level 500, you should consistently use [https://www.hexwiki.net/index.php/Minimax minimaxing], choosing from among several possible moves to gain small advantages. You should play [https://www.hexwiki.net/index.php/Tidiness tidily]. You should know when to respond locally and when to play elsewhere. You should learn more theory, such as the [https://www.hexwiki.net/index.php/Mustplay_region mustplay region] and [https://www.hexwiki.net/index.php/Ladder_creation_template ladder creation templates]. You should play [https://www.hexwiki.net/index.php/Joseki josekis].&lt;br /&gt;
&lt;br /&gt;
=== Experts and beyond ===&lt;br /&gt;
&lt;br /&gt;
To reach level 600, you should study different [https://www.hexwiki.net/index.php/Opening openings] and the best responses to them. You should know how to use [https://www.hexwiki.net/index.php/Flank flanks] and [https://www.hexwiki.net/index.php/Pivoting_template pivoting templates]. You should learn about [https://www.hexwiki.net/index.php/Captured_cell capture] and [https://www.hexwiki.net/index.php/Dominated_cell domination] to play locally optimal moves.&lt;br /&gt;
&lt;br /&gt;
To go beyond level 600, you no longer need this strategy guide. Read the [https://www.hexwiki.net HexWiki]. Learn from players who are better than you. Play a lot and watch a lot of games. Develop your own tactics.&lt;br /&gt;
&lt;br /&gt;
== Resources ==&lt;br /&gt;
&lt;br /&gt;
* Matthew Seymour&#039;s online book [http://www.mseymour.ca/hex_book/ Hex: A Strategy Guide]. A good starting point for learning Hex strategy.&lt;br /&gt;
&lt;br /&gt;
* Matthew Seymour&#039;s [http://www.mseymour.ca/hex_puzzle/ Hex puzzles]. Fun and very addictive! You will become a better player.&lt;br /&gt;
&lt;br /&gt;
* The [https://www.hexwiki.net/ HexWiki]. Too much information for beginners, as it is difficult to know what to read first. It is better to start with Seymour&#039;s book. However, the Wiki is a great resource once you&#039;ve mastered the basics.&lt;/div&gt;</summary>
		<author><name>User Already Exists</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Stock&amp;diff=16092</id>
		<title>Stock</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Stock&amp;diff=16092"/>
		<updated>2023-02-14T00:35:32Z</updated>

		<summary type="html">&lt;p&gt;User Already Exists: /* Using stock: a simple example */ typo&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Studio_Framework_Navigation}}&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Stock&#039;&#039;&#039; is a javascript component that you can use in your game interface to display a set of elements of the same size that need to be arranged in single or multiple lines.&lt;br /&gt;
&lt;br /&gt;
Stock is very flexible and is the most used component in BGA games.&lt;br /&gt;
&lt;br /&gt;
Examples of stock use cases:&lt;br /&gt;
&lt;br /&gt;
* Display a set of cards, typically hands (examples: &#039;&#039;Hearts&#039;&#039;, &#039;&#039;Seasons&#039;&#039;, &#039;&#039;The Boss&#039;&#039;, &#039;&#039;Race for the Galaxy&#039;&#039;).&lt;br /&gt;
* Display items in player panels (examples: &#039;&#039;Takenoko&#039;&#039;, &#039;&#039;Amyitis&#039;&#039;, ...)&lt;br /&gt;
* ... Many other situations. For example, black dice and cubes on cards in &#039;&#039;Troyes&#039;&#039; are displayed with stock components.&lt;br /&gt;
&lt;br /&gt;
Using stock:&lt;br /&gt;
&lt;br /&gt;
* Your items are arranged nicely and sorted by type.&lt;br /&gt;
* When adding or removing items to a set, all items slide smoothly to their new position in the set.&lt;br /&gt;
* Selecting and unselecting items are built-in functions.&lt;br /&gt;
* You don&#039;t have to worry about inserting/removing HTML code; the entire life cycle of the stock is managed by the component.&lt;br /&gt;
&lt;br /&gt;
== Using stock: a simple example ==&lt;br /&gt;
&lt;br /&gt;
Let&#039;s have a look at how the stock is used in the game &#039;&#039;Hearts&#039;&#039; to display a hand of standard cards.&lt;br /&gt;
&lt;br /&gt;
First, don&#039;t forget to add &amp;quot;ebg/stock&amp;quot; as a dependency in your js file:&lt;br /&gt;
&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;==== HERE&lt;br /&gt;
],&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The stock is initialized in the Javascript &amp;quot;setup&amp;quot; method like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    // Player hand&lt;br /&gt;
    this.playerHand = new ebg.stock();&lt;br /&gt;
    this.playerHand.create( this, $(&#039;myhand&#039;), this.cardwidth, this.cardheight );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Explanations:&lt;br /&gt;
* We create a new stock object for the player hand.&lt;br /&gt;
* As parameters of the &amp;quot;create&amp;quot; method, we provide the width/height of an item (a card), and the div container &amp;quot;myhand&amp;quot; - which is a simple empty &amp;quot;div&amp;quot; element defined in our HTML template (.tpl).&lt;br /&gt;
&lt;br /&gt;
Then, we must tell the stock what items it is going to display during its life: the 52 cards of a standard card game. Of course, we did not create 52 different images, but a &amp;quot;CSS sprite&amp;quot; image named &amp;quot;cards.jpg&amp;quot; with the cards arranged in 4 rows and 13 columns.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s how we tell stock what items to display:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    // Specify that there are 13 images per row in the CSS sprite image&lt;br /&gt;
    this.playerHand.image_items_per_row = 13;&lt;br /&gt;
&lt;br /&gt;
    // Create card types:&lt;br /&gt;
    for( var color=1;color&amp;lt;=4;color++ )&lt;br /&gt;
    {&lt;br /&gt;
        for( var value=2;value&amp;lt;=14;value++ )&lt;br /&gt;
        {&lt;br /&gt;
            // Build card type id&lt;br /&gt;
            var card_type_id = this.getCardUniqueId( color, value );&lt;br /&gt;
            this.playerHand.addItemType( card_type_id, card_type_id, g_gamethemeurl+&#039;img/cards.jpg&#039;, card_type_id );&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Explanation:&lt;br /&gt;
&lt;br /&gt;
* First, we tell the stock component that our CSS sprite contains 13 items per row. This way, it can find the correct image for each card type id.&lt;br /&gt;
* Then for the 4x13 cards, we call the &amp;quot;addItemType&amp;quot; method that creates the type. The arguments are the type id, the weight of the card (for sorting purpose), the URL of our CSS sprite, and the position of our card image in the CSS sprite.&lt;br /&gt;
&lt;br /&gt;
Note: In this specific example we need to generate a unique ID for each type of card based on its color and value. This is the only purpose of &amp;quot;getCardUniqueId&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
From now on, if we need to add a card - for example, the 5 of Hearts - to a player&#039;s hand, we can do this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
this.playerHand.addToStock( this.getCardUniqueId( 2 /* 2=hearts */, 5 ) );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In reality, cards have some IDs, which are useful to manipulate them. This is the reason we are using &amp;quot;addToStockWithId&amp;quot; instead:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
this.playerHand.addToStockWithId( this.getCardUniqueId( 2 /* 2=hearts */, 5 ), my_card_id );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If afterwards we want to remove this card from the stock:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
this.playerHand.removeFromStockById( my_card_id );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Complete stock component reference ==&lt;br /&gt;
&lt;br /&gt;
for interest, the source is available here : https://x.boardgamearena.net/data/themereleases/220811-1000/js/modules/stock.js (this link may change with new release)&lt;br /&gt;
&lt;br /&gt;
In the reference below the type StockItem refers to a record { id: number, type: number }, i.e. {id: 22, type: 3}&lt;br /&gt;
&lt;br /&gt;
And StockItemType is record {weight: number, image: string, image_position: number}&lt;br /&gt;
&lt;br /&gt;
=== Creation ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;create( page, container_div, item_width, item_height ):&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
With create, you create a new stock component.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
* page: the container page. Usually: &amp;quot;this&amp;quot;.&lt;br /&gt;
* container_div: the container &amp;quot;div&amp;quot; element. Its not an id, if you have id you can pass $(id). It must exists.&lt;br /&gt;
* width and height (in pixels) for the stock component.&lt;br /&gt;
&lt;br /&gt;
(See &#039;&#039;Hearts&#039;&#039; example above).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;addItemType(type: number, weight: number, image: string, image_position: number ): void&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Define a new type of item (StockItemtType) and add it to the stock with given type id.&lt;br /&gt;
&lt;br /&gt;
This is mandatory to define a new item type before adding it to the stock. Example: if you want to have a stock contain cubes of 3 different colors, you must add 3 item types (one for each color).&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
* type: id of the type to add. You can choose any positive integer. All item types must have distinct IDs.&lt;br /&gt;
* weight: weight of items of this type. Weight value is used to sort items of the stock during the display. Note that you can specify the same weight for all items; in this case, they are not sorted and their order might change randomly at any time.&lt;br /&gt;
* image: URL of item image. Most of the time, you will use a CSS sprite for stock items, so you have to specify CSS sprite image here.&lt;br /&gt;
&lt;br /&gt;
Be careful: you must specify the image url as this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  g_gamethemeurl+&#039;img/yourimage.png&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* image_position: if &amp;quot;image&amp;quot; specify the URL of a CSS sprite, you must specify the position of the item image in this CSS sprite. For example, if you have a CSS sprite with 3 cubes with a size of 20x20 pixels each (so your CSS image has for example a size of 20x60 or 60x20), you specify &amp;quot;0&amp;quot; for the first cube image, 1 for the second, 2 for the third.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Important&#039;&#039;: if there is more than one line of items in your CSS sprite,  you must specify how many items per line you have in your CSS sprite, see image_items_per_row below:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;image_items_per_row&#039;&#039;&#039;&lt;br /&gt;
Class member to set number of columns in css sprite (or how many items per row). I.e. if you sprite is 4 cards horizontally and 6 vertically, you have to set it to 4.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    // Specify that there are 10 image items per row in images used in &amp;quot;myStockObject&amp;quot; control.&lt;br /&gt;
    this.myStockObject.image_items_per_row = 4;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Add/Remove items ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;addToStock( type, from )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Add an item to the stock, with the specified type, but without a unique ID.&lt;br /&gt;
&lt;br /&gt;
To make your life easier, in most cases we suggest you use &#039;&#039;&#039;addToStockWithId&#039;&#039;&#039; in order to give an ID to the item added. &#039;&#039;&#039;addToStock&#039;&#039;&#039; is suitable when you are using a stock to control items that are generic game materials that don&#039;t need to be tracked individually (example: a bunch of money tokens).&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
* type: ID of the item type to use (as specified in &amp;quot;addItemType&amp;quot;)&lt;br /&gt;
* from: OPTIONAL: if you specify an HTML item here, the item will appear on this item and will be slid to its position on the stock item.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  // Add a money token to the &amp;quot;player money&amp;quot; stock.&lt;br /&gt;
  // The money token will appear on &amp;quot;player_id&amp;quot; player panel and will move to its position.&lt;br /&gt;
  this.playerMoney.addToStock( MONEY_TOKEN, &#039;overall_player_board_&#039;+player_id );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Important: for a given stock control, you must use either &#039;&#039;&#039;addToStock&#039;&#039;&#039; or &#039;&#039;&#039;addToStockWithId&#039;&#039;&#039;, but NEVER BOTH OF THEM.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;addToStockWithId( type, id, from )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This is the same method as &#039;&#039;&#039;addToStock&#039;&#039;&#039;, except that it also associates an ID with the newly created item.&lt;br /&gt;
&lt;br /&gt;
This is especially useful:&lt;br /&gt;
&lt;br /&gt;
* When you need to know which item(s) have been selected by the user (see &#039;&#039;&#039;getSelectedItems&#039;&#039;&#039;).&lt;br /&gt;
* When you need to remove a specific item from the stock with &#039;&#039;&#039;removeFromStockById&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;removeFromStock( type, to, noupdate )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Remove an item of the specific type from the stock.&lt;br /&gt;
&lt;br /&gt;
&#039;to&#039; is an optional parameter. If &amp;quot;to&amp;quot; contains the ID of an HTML element, the item removed from the Stock slides to this HTML element before it disappears. Note that this method does not expose the associated animation object, however, so it&#039;s not possible to trigger other actions when it finishes, for example. If you need to do that, use Dojo&#039;s slideToObject() instead.&lt;br /&gt;
&lt;br /&gt;
&#039;noupdate&#039; is an optional parameter. If set to &amp;quot;true&amp;quot; it will prevent the Stock display from changing. This is useful when multiple (but not all) items are removed at the same time, to avoid ghost items appearing briefly. If you pass noupdate you have to call updateDisplay() after all items are removed.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;removeFromStockById( id, to, noupdate )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Remove an item with a specific ID from the stock.&lt;br /&gt;
&lt;br /&gt;
&#039;to&#039; is an optional parameter. If &amp;quot;to&amp;quot; contains the ID of an HTML element, the item removed from the Stock slides to this HTML element before it disappears. Note that this method does not expose the associated animation object, however, so it&#039;s not possible to trigger other actions when it finishes, for example. If you need to do that, use Dojo&#039;s slideToObject() instead.&lt;br /&gt;
&lt;br /&gt;
&#039;noupdate&#039; is an optional parameter. If set to &amp;quot;true&amp;quot; it will prevent the Stock display from changing. This is useful when multiple (but not all) items are removed at the same time, to avoid ghost items appearing briefly. If you pass noupdate you have to call updateDisplay() after all items are removed.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;removeAll()&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Remove all items from the stock.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;removeAllTo( to )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Remove all items from the stock. If &amp;quot;to&amp;quot; contains the ID of an HTML element, the item removed from the stock slides to this HTML element before it disappears.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Getters ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;getPresentTypeList()&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Return an array with all the types of items present in the stock right now.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    this.myStockControl.removeAll();&lt;br /&gt;
    this.myStockControl.addToStock( 65 );&lt;br /&gt;
    this.myStockControl.addToStock( 34 );&lt;br /&gt;
    this.myStockControl.addToStock( 89 );&lt;br /&gt;
    this.myStockControl.addToStock( 65 );&lt;br /&gt;
    &lt;br /&gt;
    // The following returns: { 34:1,  65:1,  89:1  }&lt;br /&gt;
    var item_types = this.myStockControl.getPresentTypeList();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;count():&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Return the total number of items in the stock right now.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;getAllItems()&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Get all items (same format as getSelectedItems and getUnselectedItems).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;getItemDivId(id)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Get the div id using the stock item id (to manipulate element properties directly).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;getItemById(id)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Get the Stock item with the id in parameter&lt;br /&gt;
ex : return the object { type:1,  id:  1001 }&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;getItemWeightById(id: number): number|null&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Returns item weigh given id. or null if not found&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;container_div&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Member containing div of the stock container in dom (container_div.id would be it&#039;s id)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;control_name&#039;&#039;&#039;&lt;br /&gt;
Its id of container_div above&lt;br /&gt;
&lt;br /&gt;
=== Selection ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;setSelectionMode( mode )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For each stock control, you can specify a selection mode:&lt;br /&gt;
* 0: no item can be selected by the player.&lt;br /&gt;
* 1: a maximum of one item can be selected by the player at a time.&lt;br /&gt;
* 2 (default): multiple items can be selected by the player at the same time.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;setSelectionAppearance( type )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For each stock control, you can specify a selection highlighting type:&lt;br /&gt;
* &#039;border&#039;: there will be a red border around selected items (this is the default). The attribute &#039;apparenceBorderWidth&#039; can be used to manage the width of the border (in pixels).&lt;br /&gt;
* &#039;disappear&#039;: the selected item will fade out and disappear. This is useful when the selection has the effect of destroying the item.&lt;br /&gt;
* &#039;class&#039;: there will be an extra &#039;&#039;&#039;stockitem_selected&#039;&#039;&#039; css class added to the element when it is selected (and removed when unselected). The name of the class can be changed by using the &#039;&#039;&#039;selectionClass&#039;&#039;&#039; attribute. You can also override the default class in the css file for your game but beware of the &#039;&#039;&#039;!important&#039;&#039;&#039; keyword.&lt;br /&gt;
&lt;br /&gt;
By default this class definition is:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.stockitem_selected {&lt;br /&gt;
	border: 2px solid red ! important;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want to override it (for example, to change the border color) add this in your &amp;lt;game&amp;gt;.css file:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.stockitem_selected {&lt;br /&gt;
	border: 2px solid orange ! important;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;isSelected( id )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Return a boolean indicating whether the specified item id has been selected.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;selectItem( id )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Select the specified item.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;unselectItem( id )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Unselect the specified item.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;unselectAll()&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Unselect all items of the stock.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;selectItemsByType(type: number): void&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Selectes all items in a stock with given type (in addition to previous selection)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;unselectItemsByType(type: number): void&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Unselects all items in a stock with given type&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;onChangeSelection&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This callback method is called when the player selects/unselects an item of the stock.&lt;br /&gt;
&lt;br /&gt;
You can connect this to one of your methods like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    dojo.connect( this.myStockControl, &#039;onChangeSelection&#039;, this, &#039;onMyMethodToCall&#039; );&lt;br /&gt;
    &lt;br /&gt;
    (...)&lt;br /&gt;
    &lt;br /&gt;
    onMyMethodToCall: function( control_name, item_id )&lt;br /&gt;
    {&lt;br /&gt;
        // This method is called when myStockControl selected items changed&lt;br /&gt;
        var items = this.myStockControl.getSelectedItems();&lt;br /&gt;
        &lt;br /&gt;
        // (do something)&lt;br /&gt;
    },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nota bene: &lt;br /&gt;
- The &amp;quot;control_name&amp;quot; argument is the ID (the &amp;quot;DOM&amp;quot; id) of the &amp;quot;div&amp;quot; container of your stock control. Using &amp;quot;control_name&amp;quot;, you can use the same callback method for different Stock control and see which one trigger the method.&lt;br /&gt;
- The &amp;quot;item_id&amp;quot; argument is the stock ID (index) of the stock item that has just been selected/unselected.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;getSelectedItems()&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Return the list of selected items, as an array with the following format:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[&lt;br /&gt;
   { type:1,  id:  1001 },&lt;br /&gt;
   { type:1,  id:  1002 },&lt;br /&gt;
   { type:3,  id:  1003 }&lt;br /&gt;
   ...&lt;br /&gt;
]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;getUnselectedItems()&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Same as the previous one, but return unselected item instead of seleted ones.&lt;br /&gt;
&lt;br /&gt;
=== Layout ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;resetItemsPosition()&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
If you moved an item from the stock control manually (ex: after a drag&#039;n&#039;drop) and want to reset their positions to their original ones, you can call this method.&lt;br /&gt;
Note: it is the same as updateDisplay() without arugment, not sure why there are two methods.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;updateDisplay(from)&#039;&#039;&#039;&lt;br /&gt;
Update the display completely (if &#039;from&#039; is defined: moves new items from this location).&lt;br /&gt;
&lt;br /&gt;
Example code if you change the underlying stock item, or otherwise want to make the stock item refresh:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    this.myStockControl.updateDisplay();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;item_margin&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
By default, there is a margin of 5px between the items of a stock. You can change the member variable &amp;quot;item_margin&amp;quot; to change this.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     this.myStockControl.item_margin=5;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;changeItemsWeight( newWeights )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
With this method you can change dynamically the weight of the item types in a stock control.&lt;br /&gt;
&lt;br /&gt;
Items are immediately re-sorted with the new weight.&lt;br /&gt;
&lt;br /&gt;
Example: with a stock control that contains classic cards, you can order them by value or by color. Using changeItemsWeight you can switch from one sort method to another when a player request this.&lt;br /&gt;
&lt;br /&gt;
newWeights is an associative array: item type id =&amp;gt; new weight.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    // Item type 1 gets a new weight of 10, 2 a new weight of 20, 3 a new weight of 30.&lt;br /&gt;
    this.myStockControl.changeItemsWeight( { 1: 10, 2: 20, 3: 30 } );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example2:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    // Be careful with object initialisers with variables, use the bracket notation.&lt;br /&gt;
    // Item type 1 gets a new weight of 10&lt;br /&gt;
    var card_type = 1;&lt;br /&gt;
    this.myStockControl.changeItemsWeight( { [card_type]: 10 } );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;centerItems&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Center the stock items in the middle of the stock container.&lt;br /&gt;
e.g. this.myStock.centerItems = true; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;setOverlap( horizontal_percent, vertical_percent )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This functions sents stock horizontal_overlap and vertical_overlap, the calls updateDisplay(). See what overlap means below&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;horizontal_overlap&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Make items of the stock control &amp;quot;overlap&amp;quot; each other, to save space. By default, horizontal_overlap is 0 (but there is also &#039;&#039;&#039;item_margin&#039;&#039;&#039; which affects spacing&#039;&#039;&#039;)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
When horizontal_overlap=20, it means that a stock item will overlap to only show 20% of the width of all the previous items. horizontal_overlap can&#039;t be greater than 100.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;vertical_overlap&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
There is two modes, in one mode it used to adjust every 2nd item (See the games &amp;quot;Jaipur&amp;quot; or &amp;quot;Koryŏ&amp;quot;), second mode when setting use_vertical_overlap_as_offset=false is more/less normal overlap with vertical layout except its perentage of overlap (opposite of horizontal_overlap).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is example of vertical stock with overlap&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
stock.container_div.width = &amp;quot;60px&amp;quot;; // enought just for 1 card&lt;br /&gt;
stock.autowidth = false; // this is required so it obeys the width set above&lt;br /&gt;
stock.use_vertical_overlap_as_offset = false; // this is to use normal vertical_overlap&lt;br /&gt;
stock.vertical_overlap = 20; // overlap&lt;br /&gt;
stock.horizontal_overlap  = -1; // current bug in stock - this is needed to enable z-index on overlapping items&lt;br /&gt;
stock.item_margin = 0; // has to be 0 if using overlap&lt;br /&gt;
stock.updateDisplay(); // re-layout&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
[[File:StockV.png]] [[File:StockHV.png]]  [[File:StockMixed.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;autowidth&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Stock does not play well if you attempt to inline-block it with other blocks, to fix that you have to set this flag which will calculate width properly&lt;br /&gt;
   mystock.autowidth = true;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;resizeItems( width, height, background_width, background_height )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
background_width is an optional argument.&lt;br /&gt;
&lt;br /&gt;
background_height is an optional argument.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; stock.resizeItems(100, 120, 150, 170);&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Customize Appearance ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;extraClasses&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Can be set to a list of class names (separated by space) on stock object, so when div is created these are added, i.e.&lt;br /&gt;
&lt;br /&gt;
  this.playerHand.extraClasses=&#039;mycard&#039;;&lt;br /&gt;
&lt;br /&gt;
Note that it is the same list for all items.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;onItemCreate&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Using onItemCreate, you can trigger a method each time a new item is added to the Stock, in order to customize it.&lt;br /&gt;
&lt;br /&gt;
Complete example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    // During &amp;quot;setup&amp;quot; phase, we associate our method &amp;quot;setupNewCard&amp;quot; with the creation of a new stock item:&lt;br /&gt;
    this.myStockItem.onItemCreate = dojo.hitch( this, &#039;setupNewCard&#039; ); &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    // And here is our &amp;quot;setupNewCard&amp;quot;:&lt;br /&gt;
    setupNewCard: function( card_div, card_type_id, card_id )&lt;br /&gt;
    {&lt;br /&gt;
       // Add a special tooltip on the card:&lt;br /&gt;
       this.addTooltip( card_div.id, _(&amp;quot;Some nice tooltip for this item&amp;quot;), &#039;&#039; );&lt;br /&gt;
&lt;br /&gt;
       // Note that &amp;quot;card_type_id&amp;quot; contains the type of the item, so you can do special actions depending on the item type&lt;br /&gt;
&lt;br /&gt;
       // Add some custom HTML content INSIDE the Stock item:&lt;br /&gt;
       dojo.place( this.format_block( &#039;jstpl_my_card_content&#039;, {&lt;br /&gt;
                                ....&lt;br /&gt;
                           } ), card_div.id );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;onItemDelete&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Function handler called when div is removed&lt;br /&gt;
&lt;br /&gt;
   this.myStock.onItemDelete = (card_div, card_type_id, card_id) =&amp;gt; { console.log(&amp;quot;card deleted from myStock: &amp;quot;+card_id); };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;jstpl_stock_item&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Override default HTML template, this is the default:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  mystock.jstpl_stock_item =&#039;&amp;lt;div id=&amp;quot;${id}&amp;quot; class=&amp;quot;stockitem ${extra_classes}&amp;quot; style=&amp;quot;top:${top}px;left:${left}px;width:${width}px;height:${height}px;${position};background-image:url(\&#039;${image}\&#039;);${additional_style}&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
            &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: variable ${position} normally resolve to nothing or z-index: X - depending on overlap variables, and additional_style resolves to `background-size: ${this.backgroundSize}` if it is set&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;custom CSS images&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
If you want to use your own css styles for images on the items (i.e. not grid), you can do it as following, use customize template, then modify onItemCreate to add slyle which is based on type&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 mystock.jstpl_stock_item =  &#039;&amp;lt;div id=&amp;quot;${id}&amp;quot; class=&amp;quot;stockitem card&amp;quot; style=&amp;quot;top:${top}px;left:${left}px;${position};&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
 mystock.onItemCreate = (card_div, card_type_id, card_id ) =&amp;gt; { dojo.addClass(card_div, &#039;card_type_&#039;+card_type_id); }&lt;br /&gt;
 for (var type = 0; type &amp;lt;= 48; type++) {&lt;br /&gt;
   mystock.addItemType(type, type); // we skipped image and image position here&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: in this case your CSS must define all styles require for these stock items such as width, heigh, image and image positioning for every type&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.card {&lt;br /&gt;
  width: 50px;&lt;br /&gt;
  height: 80px;&lt;br /&gt;
  background-image: url(img/cards.jpg);&lt;br /&gt;
  background-size: 600% auto;&lt;br /&gt;
}&lt;br /&gt;
.card_type_1 {&lt;br /&gt;
  background-postion: 20% 0%;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tips when adding/removing items to/from Stock components ==&lt;br /&gt;
&lt;br /&gt;
Most cases will be one of the following situations:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Situation A&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
When you add a card to a stock item, and this card is &#039;&#039;&#039;not&#039;&#039;&#039; coming from another stock:&lt;br /&gt;
&lt;br /&gt;
* Use &#039;&#039;&#039;addToStockWithId&#039;&#039;&#039; with a &amp;quot;from&amp;quot; argument set to the element of your interface where the card should come from (i.e. div id). For example if you want to &amp;quot;reveal&amp;quot; card from player hand and it is not an interface element you can set from to be &#039;player_board_&#039;+activePlayerId (where activePlayerId is player who played that card).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Situation B&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
When you add a card to a stock item, and this card is coming from another stock:&lt;br /&gt;
&lt;br /&gt;
* On the destination Stock, use &#039;&#039;&#039;addToStockWithId&#039;&#039;&#039; with a &amp;quot;from&amp;quot; argument which is the HTML id of the corresponding item in the source Stock. For example, if the source stock id is &amp;quot;myHand&amp;quot;, then the HTML id of card 48 is &amp;quot;myHand_item_48&amp;quot;.&lt;br /&gt;
* Then, remove the source item with &#039;&#039;&#039;removeFromStockById&#039;&#039;&#039;. Note: do NOT set the &#039;to&#039; argument in this call, otherwise you&#039;ll get two animations.&lt;br /&gt;
&lt;br /&gt;
(Note that it&#039;s important to do things in this order, because the source item must still exist when you use it as the origin of the slide.)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Situation C&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
When you move a card from a stock item to something that is not a stock item:&lt;br /&gt;
&lt;br /&gt;
* Insert the card as a classic HTML template (dojo.place / this.format_block).&lt;br /&gt;
* Place it on the Stock item with &#039;&#039;&#039;this.placeOnObject&#039;&#039;&#039;, using the Stock item HTML id (see above).&lt;br /&gt;
* Slide it to its new position with &#039;&#039;&#039;this.slideToObject&#039;&#039;&#039;.&lt;br /&gt;
* Remove the card from the Stock item with &#039;&#039;&#039;removeFromStockById&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Using the methods above, your cards should slide to, from, and between your Stock controls smoothly.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Known issues ==&lt;br /&gt;
&lt;br /&gt;
==== Incorrectly displayed sprites on Safari ====&lt;br /&gt;
&lt;br /&gt;
As mentioned above, stock displays its images using &amp;quot;sprites&amp;quot; consisting of a portion of a larger image. To accomplish this, it uses the CSS background-position attribute in negative multiples of 100%. For example, the first element of the first row would be 0% 0%. The second element of the first row would be -100% 0%, etc.&lt;br /&gt;
&lt;br /&gt;
This works fine except in Safari, which sometimes slightly modifies the width of elements at smaller screen sizes (usually when minimum width of &#039;game_interface_width&#039; is not null) in game. For example, you might get a ~49.99px x ~49.99px div instead of the 50px x 50px specified by CSS width/height. Combined with using percentages in background-position, this can cause sprites to be slightly off-center.&lt;br /&gt;
&lt;br /&gt;
Using pixels in background-position is probably the easiest way to fix this problem, but that would require modifying the stock code itself. As a developer, you can also work around the problem by specifying a background-size attribute based on the size in elements of your source image. For example, if you have a source image that contains 5 rows of 28 sprites, you should specify &amp;quot;background-size: 2800% 500%;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
You can add background-size to your stock items by using the extraClasses attribute as explained above and then specifying the values in your game.css file.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Studio]]&lt;/div&gt;</summary>
		<author><name>User Already Exists</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Tips_hex&amp;diff=14773</id>
		<title>Tips hex</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Tips_hex&amp;diff=14773"/>
		<updated>2022-09-19T17:03:33Z</updated>

		<summary type="html">&lt;p&gt;User Already Exists: /* Experts and beyond */ wording&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
&lt;br /&gt;
Although the rules of Hex are very simple, its strategy is quite rich and has many layers. The good news is that there are many clever and satisfying strategy concepts that can be learned by players of all levels.&lt;br /&gt;
&lt;br /&gt;
== Strategy concepts by level ==&lt;br /&gt;
&lt;br /&gt;
The following is an approximate attempt to match up strategy skills with Elo levels.&lt;br /&gt;
&lt;br /&gt;
=== Beginners ===&lt;br /&gt;
&lt;br /&gt;
To reach level 100, you should learn about templates, especially the [https://www.hexwiki.net/index.php/Bridge bridge] and the [https://www.hexwiki.net/index.php/Ziggurat ziggurat]. You should also learn basic [https://www.hexwiki.net/index.php/Blocking blocking]. You might try a few dozen of Matthew Seymour&#039;s [http://www.mseymour.ca/hex_puzzle/ Hex puzzles].&lt;br /&gt;
&lt;br /&gt;
=== Average players ===&lt;br /&gt;
&lt;br /&gt;
To reach level 200, you should learn about [https://www.hexwiki.net/index.php/Ladder_handling ladder handling], especially [https://www.hexwiki.net/index.php/Ladder_escape ladder escapes]. You should learn more [https://www.hexwiki.net/index.php/Edge_templates_everybody_should_know templates]. You should solve more [http://www.mseymour.ca/hex_puzzle/ Hex puzzles].&lt;br /&gt;
&lt;br /&gt;
=== Good players ===&lt;br /&gt;
&lt;br /&gt;
To reach level 300, you should learn about [https://www.hexwiki.net/index.php/Climbing pivoting and climbing]. You should use template intrusions to steal territory and help you connect. You should recognize what is connected and what is not, to avoid defending the indefensible or attacking what is solid. You should also learn [https://www.hexwiki.net/index.php/Swap when to swap]. &lt;br /&gt;
&lt;br /&gt;
=== Strong players ===&lt;br /&gt;
&lt;br /&gt;
To reach level 400, you should learn some advanced ways of connecting, such as [https://www.hexwiki.net/index.php/Switchback switchbacks], [https://www.hexwiki.net/index.php/Foldback foldbacks], and [https://www.hexwiki.net/index.php/Tom%27s_move Tom&#039;s move]. You should learn to [https://www.hexwiki.net/index.php/Foiling foil], and especially, how to counter fishing moves. You should start to use [https://www.hexwiki.net/index.php/Minimax minimaxing], such as building [https://www.hexwiki.net/index.php/Wall walls]. You should play [https://www.hexwiki.net/index.php/Corner_move corner moves] in the opening. &lt;br /&gt;
&lt;br /&gt;
To reach level 500, you should consistently use [https://www.hexwiki.net/index.php/Minimax minimaxing], choosing from among several possible moves to gain small advantages. You should play [https://www.hexwiki.net/index.php/Tidiness tidily]. You should know when to respond locally and when to play elsewhere. You should learn more theory, such as the [https://www.hexwiki.net/index.php/Mustplay_region mustplay region] and [https://www.hexwiki.net/index.php/Ladder_creation_template ladder creation templates]. You should play [https://www.hexwiki.net/index.php/Joseki josekis].&lt;br /&gt;
&lt;br /&gt;
=== Experts and beyond ===&lt;br /&gt;
&lt;br /&gt;
To reach level 600, you should study different [https://www.hexwiki.net/index.php/Opening openings] and the best responses to them. You should know how to use [https://www.hexwiki.net/index.php/Flank flanks] and [https://www.hexwiki.net/index.php/Pivoting_template pivoting templates]. You should learn about [https://www.hexwiki.net/index.php/Captured_cell capture] and [https://www.hexwiki.net/index.php/Dominated_cell domination] to play locally optimal moves.&lt;br /&gt;
&lt;br /&gt;
To go beyond level 600, you no longer need this strategy guide. Read the [https://www.hexwiki.net HexWiki]. Learn from players who are better than you. Play a lot and watch a lot of games. Develop your own theories.&lt;br /&gt;
&lt;br /&gt;
== Resources ==&lt;br /&gt;
&lt;br /&gt;
* Matthew Seymour&#039;s online book [http://www.mseymour.ca/hex_book/ Hex: A Strategy Guide]. A good starting point for learning Hex strategy.&lt;br /&gt;
&lt;br /&gt;
* Matthew Seymour&#039;s [http://www.mseymour.ca/hex_puzzle/ Hex puzzles]. Fun and very addictive! You will become a better player.&lt;br /&gt;
&lt;br /&gt;
* The [https://www.hexwiki.net/ HexWiki]. Too much information for beginners, as it is difficult to know what to read first. It is better to start with Seymour&#039;s book. However, the Wiki is a great resource once you&#039;ve mastered the basics.&lt;/div&gt;</summary>
		<author><name>User Already Exists</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Gamehelphex&amp;diff=14214</id>
		<title>Gamehelphex</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Gamehelphex&amp;diff=14214"/>
		<updated>2022-07-31T21:00:19Z</updated>

		<summary type="html">&lt;p&gt;User Already Exists: Copy-edited the introductory paragraph.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The game of Hex was invented by Piet Hein in Denmark in 1942, and later rediscovered and popularized by John Nash. The game is attractive because it has extremely simple rules, yet a surprising amount of strategic depth. Other interesting aspects are that the game can&#039;t end in a tie, and that when playing without the swap rule, the first player is known to have a theoretical winning strategy, although nobody knows what that strategy is.&lt;br /&gt;
&lt;br /&gt;
== Rules ==&lt;br /&gt;
&lt;br /&gt;
=== Goal ===&lt;br /&gt;
&lt;br /&gt;
The board has two red edges and two blue edges. Each player&#039;s goal is to connect their two edges by stones of their color.&lt;br /&gt;
&lt;br /&gt;
=== Turns ===&lt;br /&gt;
&lt;br /&gt;
The players alternately place a stone of their own color on the board, with Red going first. A stone can be placed on any empty cell. Once placed, stones are never moved or removed.&lt;br /&gt;
&lt;br /&gt;
=== The swap rule ===&lt;br /&gt;
&lt;br /&gt;
To make sure the first player does not have an unfair advantage, the swap rule is used. After the first player opens with a red stone, the second player has the option to &amp;quot;swap&amp;quot;, or steal the opponent&#039;s first move. In this case, Red&#039;s initial stone is replaced by a blue stone and mirrored about the long diagonal. After this, it is Red&#039;s turn.&lt;br /&gt;
&lt;br /&gt;
=== Game end ===&lt;br /&gt;
&lt;br /&gt;
The game ends when one of the players has connected their edges with a path of stones of their color. The game can&#039;t end in a tie. When it is clear to both players who will win, it is customary for the losing player to resign.&lt;br /&gt;
&lt;br /&gt;
== Game options and interface ==&lt;br /&gt;
&lt;br /&gt;
=== Board size ===&lt;br /&gt;
&lt;br /&gt;
The game can be played on boards of several different sizes. The 6x6 board is designed to help beginners understand the basic rules and discover simple game patterns. The 11x11 board is a more classic size and was used by Piet Hein. The 12x12 board was added because some players like even-sized boards. The 13x13 board is preferred by many experts. The 14x14 board was recommended by John Nash, and the 15x15 board allows even longer plays.&lt;br /&gt;
&lt;br /&gt;
The 6x6 board size is only available in training mode.&lt;br /&gt;
&lt;br /&gt;
=== Moves and swapping ===&lt;br /&gt;
&lt;br /&gt;
To make a move, click on an empty cell. To guard against accidental misclicks, you have to confirm each move by clicking on the stone a second time (or use the &amp;quot;confirm&amp;quot; or &amp;quot;cancel&amp;quot; buttons above the play area).&lt;br /&gt;
&lt;br /&gt;
On the second move of the game, you have the option to swap. To do so, click on the &amp;quot;swap&amp;quot; button above the play area. If you do not want to swap, simply make a normal move.&lt;br /&gt;
&lt;br /&gt;
=== Resigning ===&lt;br /&gt;
&lt;br /&gt;
Players can resign at any time (whether or not it is their turn). The resign button is found in the &amp;quot;additional game controls&amp;quot; menu, which is marked by three dots &amp;quot;...&amp;quot; in the upper right corner of the play area. &lt;br /&gt;
&lt;br /&gt;
=== Passing ===&lt;br /&gt;
&lt;br /&gt;
Passing (i.e., skipping a move) is rarely done in Hex. The reason is that passing never benefits a player: if you can win by passing, you can also win by making a random move. Nevertheless, the ability to pass has been included in the Board Game Arena implementation of Hex. It has certain specialized uses, such as teaching, giving handicap (i.e., giving an advantage to the weaker player), or setting up an initial board position.&lt;br /&gt;
&lt;br /&gt;
The option to pass is found in the &amp;quot;additional game controls&amp;quot; menu, which is marked by three dots &amp;quot;...&amp;quot; in the upper right corner of the play area. If your opponent passes and you do not want to allow it for some reason, simply pass yourself, which effectively returns the game to its previous state. Three passes in a row are not permitted, so if both players have passed, the next player must make a proper move.&lt;br /&gt;
&lt;br /&gt;
=== Accessibility ===&lt;br /&gt;
&lt;br /&gt;
The shades of red and blue that Hex uses by default can be difficult to distinguish for colorblind people. To compensate for this, there is a game display option for color blindness in the Options menu below the game board.&lt;/div&gt;</summary>
		<author><name>User Already Exists</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Gamehelphex&amp;diff=14201</id>
		<title>Gamehelphex</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Gamehelphex&amp;diff=14201"/>
		<updated>2022-07-30T02:06:26Z</updated>

		<summary type="html">&lt;p&gt;User Already Exists: Added 12x12&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The game of Hex was invented and popularized in Denmark by Piet Hein in 1942, and later independently rediscovered by John Nash in 1947. The game is attractive because it has extremely simple rules, yet a surprising amount of strategic depth. Another interesting aspect is that the game can&#039;t end in a tie.&lt;br /&gt;
&lt;br /&gt;
== Rules ==&lt;br /&gt;
&lt;br /&gt;
=== Goal ===&lt;br /&gt;
&lt;br /&gt;
The board has two red edges and two blue edges. Each player&#039;s goal is to connect their two edges by stones of their color.&lt;br /&gt;
&lt;br /&gt;
=== Turns ===&lt;br /&gt;
&lt;br /&gt;
The players alternately place a stone of their own color on the board, with Red going first. A stone can be placed on any empty cell. Once placed, stones are never moved or removed.&lt;br /&gt;
&lt;br /&gt;
=== The swap rule ===&lt;br /&gt;
&lt;br /&gt;
To make sure the first player does not have an unfair advantage, the swap rule is used. After the first player opens with a red stone, the second player has the option to &amp;quot;swap&amp;quot;, or steal the opponent&#039;s first move. In this case, Red&#039;s initial stone is replaced by a blue stone and mirrored about the long diagonal. After this, it is Red&#039;s turn.&lt;br /&gt;
&lt;br /&gt;
=== Game end ===&lt;br /&gt;
&lt;br /&gt;
The game ends when one of the players has connected their edges with a path of stones of their color. The game can&#039;t end in a tie. When it is clear to both players who will win, it is customary for the losing player to resign.&lt;br /&gt;
&lt;br /&gt;
== Game options and interface ==&lt;br /&gt;
&lt;br /&gt;
=== Board size ===&lt;br /&gt;
&lt;br /&gt;
The game can be played on boards of several different sizes. The 6x6 board is designed to help beginners understand the basic rules and discover simple game patterns. The 11x11 board is a more classic size and was used by Piet Hein. The 12x12 board was added because some players like even-sized boards. The 13x13 board is preferred by many experts. The 14x14 board was recommended by John Nash, and the 15x15 board allows even longer plays.&lt;br /&gt;
&lt;br /&gt;
The 6x6 board size is only available in training mode.&lt;br /&gt;
&lt;br /&gt;
=== Moves and swapping ===&lt;br /&gt;
&lt;br /&gt;
To make a move, click on an empty cell. To guard against accidental misclicks, you have to confirm each move by clicking on the stone a second time (or use the &amp;quot;confirm&amp;quot; or &amp;quot;cancel&amp;quot; buttons above the play area).&lt;br /&gt;
&lt;br /&gt;
On the second move of the game, you have the option to swap. To do so, click on the &amp;quot;swap&amp;quot; button above the play area. If you do not want to swap, simply make a normal move.&lt;br /&gt;
&lt;br /&gt;
=== Resigning ===&lt;br /&gt;
&lt;br /&gt;
Players can resign at any time (whether or not it is their turn). The resign button is found in the &amp;quot;additional game controls&amp;quot; menu, which is marked by three dots &amp;quot;...&amp;quot; in the upper right corner of the play area. &lt;br /&gt;
&lt;br /&gt;
=== Passing ===&lt;br /&gt;
&lt;br /&gt;
Passing (i.e., skipping a move) is rarely done in Hex. The reason is that passing never benefits a player: if you can win by passing, you can also win by making a random move. Nevertheless, the ability to pass has been included in the Board Game Arena implementation of Hex. It has certain specialized uses, such as teaching, giving handicap (i.e., giving an advantage to the weaker player), or setting up an initial board position.&lt;br /&gt;
&lt;br /&gt;
The option to pass is found in the &amp;quot;additional game controls&amp;quot; menu, which is marked by three dots &amp;quot;...&amp;quot; in the upper right corner of the play area. If your opponent passes and you do not want to allow it for some reason, simply pass yourself, which effectively returns the game to its previous state. Three passes in a row are not permitted, so if both players have passed, the next player must make a proper move.&lt;br /&gt;
&lt;br /&gt;
=== Accessibility ===&lt;br /&gt;
&lt;br /&gt;
The shades of red and blue that Hex uses by default can be difficult to distinguish for colorblind people. To compensate for this, there is a game display option for color blindness in the Options menu below the game board.&lt;/div&gt;</summary>
		<author><name>User Already Exists</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Gamehelphex&amp;diff=12381</id>
		<title>Gamehelphex</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Gamehelphex&amp;diff=12381"/>
		<updated>2022-03-22T02:51:35Z</updated>

		<summary type="html">&lt;p&gt;User Already Exists: /* Accessibility */ Removed &amp;quot;now&amp;quot;, since that option has been there for several months.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The game of Hex was invented and popularized in Denmark by Piet Hein in 1942, and later independently rediscovered by John Nash in 1947. The game is attractive because it has extremely simple rules, yet a surprising amount of strategic depth. Another interesting aspect is that the game can&#039;t end in a tie.&lt;br /&gt;
&lt;br /&gt;
== Rules ==&lt;br /&gt;
&lt;br /&gt;
=== Goal ===&lt;br /&gt;
&lt;br /&gt;
The board has two red edges and two blue edges. Each player&#039;s goal is to connect their two edges by stones of their color.&lt;br /&gt;
&lt;br /&gt;
=== Turns ===&lt;br /&gt;
&lt;br /&gt;
The players alternately place a stone of their own color on the board, with Red going first. A stone can be placed on any empty cell. Once placed, stones are never moved or removed.&lt;br /&gt;
&lt;br /&gt;
=== The swap rule ===&lt;br /&gt;
&lt;br /&gt;
To make sure the first player does not have an unfair advantage, the swap rule is used. After the first player opens with a red stone, the second player has the option to &amp;quot;swap&amp;quot;, or steal the opponent&#039;s first move. In this case, Red&#039;s initial stone is replaced by a blue stone and mirrored about the long diagonal. After this, it is Red&#039;s turn.&lt;br /&gt;
&lt;br /&gt;
=== Game end ===&lt;br /&gt;
&lt;br /&gt;
The game ends when one of the players has connected their edges with a path of stones of their color. The game can&#039;t end in a tie. When it is clear to both players who will win, it is customary for the losing player to resign.&lt;br /&gt;
&lt;br /&gt;
== Game options and interface ==&lt;br /&gt;
&lt;br /&gt;
=== Board size ===&lt;br /&gt;
&lt;br /&gt;
The game can be played on boards of several different sizes. The 6x6 board is designed to help beginners understand the basic rules and discover simple game patterns. The 11x11 board is a more classic size and was used by Piet Hein. The 13x13 board is preferred by many experts. The 14x14 board was recommended by John Nash, and the 15x15 board allows even longer plays.&lt;br /&gt;
&lt;br /&gt;
The 6x6 board size is only available in training mode.&lt;br /&gt;
&lt;br /&gt;
=== Moves and swapping ===&lt;br /&gt;
&lt;br /&gt;
To make a move, click on an empty cell. To guard against accidental misclicks, you have to confirm each move by clicking on the stone a second time (or use the &amp;quot;confirm&amp;quot; or &amp;quot;cancel&amp;quot; buttons above the play area).&lt;br /&gt;
&lt;br /&gt;
On the second move of the game, you have the option to swap. To do so, click on the &amp;quot;swap&amp;quot; button above the play area. If you do not want to swap, simply make a normal move.&lt;br /&gt;
&lt;br /&gt;
=== Resigning ===&lt;br /&gt;
&lt;br /&gt;
Players can resign at any time (whether or not it is their turn). The resign button is found in the &amp;quot;additional game controls&amp;quot; menu, which is marked by three dots &amp;quot;...&amp;quot; in the upper right corner of the play area. &lt;br /&gt;
&lt;br /&gt;
=== Passing ===&lt;br /&gt;
&lt;br /&gt;
Passing (i.e., skipping a move) is rarely done in Hex. The reason is that passing never benefits a player: if you can win by passing, you can also win by making a random move. Nevertheless, the ability to pass has been included in the Board Game Arena implementation of Hex. It has certain specialized uses, such as teaching, giving handicap (i.e., giving an advantage to the weaker player), or setting up an initial board position.&lt;br /&gt;
&lt;br /&gt;
The option to pass is found in the &amp;quot;additional game controls&amp;quot; menu, which is marked by three dots &amp;quot;...&amp;quot; in the upper right corner of the play area. If your opponent passes and you do not want to allow it for some reason, simply pass yourself, which effectively returns the game to its previous state. Three passes in a row are not permitted, so if both players have passed, the next player must make a proper move.&lt;br /&gt;
&lt;br /&gt;
=== Accessibility ===&lt;br /&gt;
&lt;br /&gt;
The shades of red and blue that Hex uses by default can be difficult to distinguish for colorblind people. To compensate for this, there is a game display option for color blindness in the Options menu below the game board.&lt;/div&gt;</summary>
		<author><name>User Already Exists</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Tips_hex&amp;diff=12121</id>
		<title>Tips hex</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Tips_hex&amp;diff=12121"/>
		<updated>2022-03-02T22:48:49Z</updated>

		<summary type="html">&lt;p&gt;User Already Exists: Minor wording&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
&lt;br /&gt;
Although the rules of Hex are very simple, its strategy is quite rich and has many layers. The good news is that there are many clever and satisfying strategy concepts that can be learned by players of all levels.&lt;br /&gt;
&lt;br /&gt;
== Strategy concepts by level ==&lt;br /&gt;
&lt;br /&gt;
The following is an approximate attempt to match up strategy skills with Elo levels.&lt;br /&gt;
&lt;br /&gt;
=== Beginners ===&lt;br /&gt;
&lt;br /&gt;
To reach level 100, you should learn about templates, especially the [https://www.hexwiki.net/index.php/Bridge bridge] and the [https://www.hexwiki.net/index.php/Ziggurat ziggurat]. You should also learn basic [https://www.hexwiki.net/index.php/Blocking blocking]. You might try a few dozen of Matthew Seymour&#039;s [http://www.mseymour.ca/hex_puzzle/ Hex puzzles].&lt;br /&gt;
&lt;br /&gt;
=== Average players ===&lt;br /&gt;
&lt;br /&gt;
To reach level 200, you should learn about [https://www.hexwiki.net/index.php/Ladder_handling ladder handling], especially [https://www.hexwiki.net/index.php/Ladder_escape ladder escapes]. You should learn more [https://www.hexwiki.net/index.php/Edge_templates_everybody_should_know templates]. You should solve more [http://www.mseymour.ca/hex_puzzle/ Hex puzzles].&lt;br /&gt;
&lt;br /&gt;
=== Good players ===&lt;br /&gt;
&lt;br /&gt;
To reach level 300, you should learn about [https://www.hexwiki.net/index.php/Climbing pivoting and climbing]. You should use template intrusions to steal territory and help you connect. You should recognize what is connected and what is not, to avoid defending the indefensible or attacking what is solid. You should also learn [https://www.hexwiki.net/index.php/Swap when to swap]. &lt;br /&gt;
&lt;br /&gt;
=== Strong players ===&lt;br /&gt;
&lt;br /&gt;
To reach level 400, you should learn some advanced ways of connecting, such as [https://www.hexwiki.net/index.php/Switchback switchbacks], [https://www.hexwiki.net/index.php/Foldback foldbacks], and [https://www.hexwiki.net/index.php/Tom%27s_move Tom&#039;s move]. You should learn to [https://www.hexwiki.net/index.php/Foiling foil], and especially, how to counter fishing moves. You should start to use [https://www.hexwiki.net/index.php/Minimax minimaxing], such as building [https://www.hexwiki.net/index.php/Wall walls]. You should play [https://www.hexwiki.net/index.php/Corner_move corner moves] in the opening. &lt;br /&gt;
&lt;br /&gt;
To reach level 500, you should consistently use [https://www.hexwiki.net/index.php/Minimax minimaxing], choosing from among several possible moves to gain small advantages. You should play [https://www.hexwiki.net/index.php/Tidiness tidily]. You should know when to respond locally and when to play elsewhere. You should learn more theory, such as the [https://www.hexwiki.net/index.php/Mustplay_region mustplay region] and [https://www.hexwiki.net/index.php/Ladder_creation_template ladder creation templates]. You should play [https://www.hexwiki.net/index.php/Joseki josekis].&lt;br /&gt;
&lt;br /&gt;
=== Experts and beyond ===&lt;br /&gt;
&lt;br /&gt;
To reach level 600, you should study different [https://www.hexwiki.net/index.php/Opening openings] and the best responses to them. You should know how to use [https://www.hexwiki.net/index.php/Flank flanks] and [https://www.hexwiki.net/index.php/Pivoting_template pivoting templates]. You should learn about [https://www.hexwiki.net/index.php/Captured_cell capture] and [https://www.hexwiki.net/index.php/Dominated_cell domination] to play locally optimal moves.&lt;br /&gt;
&lt;br /&gt;
To go beyond level 600, you no longer need this strategy guide. Read the [https://www.hexwiki.net HexWiki]. Learn from players who are better than you. Play a lot and watch a lot of games. Develop your own theory.&lt;br /&gt;
&lt;br /&gt;
== Resources ==&lt;br /&gt;
&lt;br /&gt;
* Matthew Seymour&#039;s online book [http://www.mseymour.ca/hex_book/ Hex: A Strategy Guide]. A good starting point for learning Hex strategy.&lt;br /&gt;
&lt;br /&gt;
* Matthew Seymour&#039;s [http://www.mseymour.ca/hex_puzzle/ Hex puzzles]. Fun and very addictive! You will become a better player.&lt;br /&gt;
&lt;br /&gt;
* The [https://www.hexwiki.net/ HexWiki]. Too much information for beginners, as it is difficult to know what to read first. It is better to start with Seymour&#039;s book. However, the Wiki is a great resource once you&#039;ve mastered the basics.&lt;/div&gt;</summary>
		<author><name>User Already Exists</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Tips_hex&amp;diff=12105</id>
		<title>Tips hex</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Tips_hex&amp;diff=12105"/>
		<updated>2022-02-27T13:23:46Z</updated>

		<summary type="html">&lt;p&gt;User Already Exists: /* Strategy concepts by level */ Added disclaimer&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
&lt;br /&gt;
Although the rules of Hex are very simple, its strategy is quite rich and has many layers. The good news is that there are many clever and satisfying strategy concepts that can be learned by players of all levels.&lt;br /&gt;
&lt;br /&gt;
== Strategy concepts by level ==&lt;br /&gt;
&lt;br /&gt;
The following is an attempt to match up strategy skills with Elo levels. It is of course approximate.&lt;br /&gt;
&lt;br /&gt;
=== Beginners ===&lt;br /&gt;
&lt;br /&gt;
To reach level 100, you should learn about templates, especially the [https://www.hexwiki.net/index.php/Bridge bridge] and the [https://www.hexwiki.net/index.php/Ziggurat ziggurat]. You should also learn basic [https://www.hexwiki.net/index.php/Blocking blocking]. You might try a few dozen of Matthew Seymour&#039;s [http://www.mseymour.ca/hex_puzzle/ Hex puzzles].&lt;br /&gt;
&lt;br /&gt;
=== Average players ===&lt;br /&gt;
&lt;br /&gt;
To reach level 200, you should learn about [https://www.hexwiki.net/index.php/Ladder_handling ladder handling], especially [https://www.hexwiki.net/index.php/Ladder_escape ladder escapes]. You should learn more [https://www.hexwiki.net/index.php/Edge_templates_everybody_should_know templates]. You should solve more [http://www.mseymour.ca/hex_puzzle/ Hex puzzles].&lt;br /&gt;
&lt;br /&gt;
=== Good players ===&lt;br /&gt;
&lt;br /&gt;
To reach level 300, you should learn about [https://www.hexwiki.net/index.php/Climbing pivoting and climbing]. You should use template intrusions to steal territory and help you connect. You should recognize what is connected and what is not, to avoid defending the indefensible or attacking what is solid. You should also learn [https://www.hexwiki.net/index.php/Swap when to swap]. &lt;br /&gt;
&lt;br /&gt;
=== Strong players ===&lt;br /&gt;
&lt;br /&gt;
To reach level 400, you should learn some advanced ways of connecting, such as [https://www.hexwiki.net/index.php/Switchback switchbacks], [https://www.hexwiki.net/index.php/Foldback foldbacks], and [https://www.hexwiki.net/index.php/Tom%27s_move Tom&#039;s move]. You should learn to [https://www.hexwiki.net/index.php/Foiling foil], and especially, how to counter fishing moves. You should start to use [https://www.hexwiki.net/index.php/Minimax minimaxing], such as building [https://www.hexwiki.net/index.php/Wall walls]. You should play [https://www.hexwiki.net/index.php/Corner_move corner moves] in the opening. &lt;br /&gt;
&lt;br /&gt;
To reach level 500, you should consistently use [https://www.hexwiki.net/index.php/Minimax minimaxing], choosing from among several possible moves to gain small advantages. You should play [https://www.hexwiki.net/index.php/Tidiness tidily]. You should know when to respond locally and when to play elsewhere. You should learn more theory, such as the [https://www.hexwiki.net/index.php/Mustplay_region mustplay region] and [https://www.hexwiki.net/index.php/Ladder_creation_template ladder creation templates]. You should play [https://www.hexwiki.net/index.php/Joseki josekis].&lt;br /&gt;
&lt;br /&gt;
=== Experts and beyond ===&lt;br /&gt;
&lt;br /&gt;
To reach level 600, you should study different [https://www.hexwiki.net/index.php/Opening openings] and the best responses to them. You should know how to use [https://www.hexwiki.net/index.php/Flank flanks] and [https://www.hexwiki.net/index.php/Pivoting_template pivoting templates]. You should learn about [https://www.hexwiki.net/index.php/Captured_cell capture] and [https://www.hexwiki.net/index.php/Dominated_cell domination] to play locally optimal moves.&lt;br /&gt;
&lt;br /&gt;
To go beyond level 600, you no longer need this strategy guide. Read the [https://www.hexwiki.net HexWiki]. Learn from players who are better than you. Play a lot and watch a lot of games. Develop your own theory.&lt;br /&gt;
&lt;br /&gt;
== Resources ==&lt;br /&gt;
&lt;br /&gt;
* Matthew Seymour&#039;s online book [http://www.mseymour.ca/hex_book/ Hex: A Strategy Guide]. A good starting point for learning Hex strategy.&lt;br /&gt;
&lt;br /&gt;
* Matthew Seymour&#039;s [http://www.mseymour.ca/hex_puzzle/ Hex puzzles]. Fun and very addictive! You will become a better player.&lt;br /&gt;
&lt;br /&gt;
* The [https://www.hexwiki.net/ HexWiki]. Too much information for beginners, as it is difficult to know what to read first. It is better to start with Seymour&#039;s book. However, the Wiki is a great resource once you&#039;ve mastered the basics.&lt;/div&gt;</summary>
		<author><name>User Already Exists</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Tips_hex&amp;diff=12103</id>
		<title>Tips hex</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Tips_hex&amp;diff=12103"/>
		<updated>2022-02-27T02:20:09Z</updated>

		<summary type="html">&lt;p&gt;User Already Exists: Re-calibrated the topics by level. Probably still not completely accurate&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
&lt;br /&gt;
Although the rules of Hex are very simple, its strategy is quite rich and has many layers. The good news is that there are many clever and satisfying strategy concepts that can be learned by players of all levels.&lt;br /&gt;
&lt;br /&gt;
== Strategy concepts by level ==&lt;br /&gt;
&lt;br /&gt;
=== Beginners ===&lt;br /&gt;
&lt;br /&gt;
To reach level 100, you should learn about templates, especially the [https://www.hexwiki.net/index.php/Bridge bridge] and the [https://www.hexwiki.net/index.php/Ziggurat ziggurat]. You should also learn basic [https://www.hexwiki.net/index.php/Blocking blocking]. You might try a few dozen of Matthew Seymour&#039;s [http://www.mseymour.ca/hex_puzzle/ Hex puzzles].&lt;br /&gt;
&lt;br /&gt;
=== Average players ===&lt;br /&gt;
&lt;br /&gt;
To reach level 200, you should learn about [https://www.hexwiki.net/index.php/Ladder_handling ladder handling], especially [https://www.hexwiki.net/index.php/Ladder_escape ladder escapes]. You should learn more [https://www.hexwiki.net/index.php/Edge_templates_everybody_should_know templates]. You should solve more [http://www.mseymour.ca/hex_puzzle/ Hex puzzles].&lt;br /&gt;
&lt;br /&gt;
=== Good players ===&lt;br /&gt;
&lt;br /&gt;
To reach level 300, you should learn about [https://www.hexwiki.net/index.php/Climbing pivoting and climbing]. You should use template intrusions to steal territory and help you connect. You should recognize what is connected and what is not, to avoid defending the indefensible or attacking what is solid. You should also learn [https://www.hexwiki.net/index.php/Swap when to swap]. &lt;br /&gt;
&lt;br /&gt;
=== Strong players ===&lt;br /&gt;
&lt;br /&gt;
To reach level 400, you should learn some advanced ways of connecting, such as [https://www.hexwiki.net/index.php/Switchback switchbacks], [https://www.hexwiki.net/index.php/Foldback foldbacks], and [https://www.hexwiki.net/index.php/Tom%27s_move Tom&#039;s move]. You should learn to [https://www.hexwiki.net/index.php/Foiling foil], and especially, how to counter fishing moves. You should start to use [https://www.hexwiki.net/index.php/Minimax minimaxing], such as building [https://www.hexwiki.net/index.php/Wall walls]. You should play [https://www.hexwiki.net/index.php/Corner_move corner moves] in the opening. &lt;br /&gt;
&lt;br /&gt;
To reach level 500, you should consistently use [https://www.hexwiki.net/index.php/Minimax minimaxing], choosing from among several possible moves to gain small advantages. You should play [https://www.hexwiki.net/index.php/Tidiness tidily]. You should know when to respond locally and when to play elsewhere. You should learn more theory, such as the [https://www.hexwiki.net/index.php/Mustplay_region mustplay region] and [https://www.hexwiki.net/index.php/Ladder_creation_template ladder creation templates]. You should play [https://www.hexwiki.net/index.php/Joseki josekis].&lt;br /&gt;
&lt;br /&gt;
=== Experts ===&lt;br /&gt;
&lt;br /&gt;
To reach level 600, you should study different [https://www.hexwiki.net/index.php/Opening openings] and the best responses to them. You should know how to use [https://www.hexwiki.net/index.php/Flank flanks] and [https://www.hexwiki.net/index.php/Pivoting_template pivoting templates]. You should learn about [https://www.hexwiki.net/index.php/Captured_cell capture] and [https://www.hexwiki.net/index.php/Dominated_cell domination] to play locally optimal moves.&lt;br /&gt;
&lt;br /&gt;
To go beyond level 600, you no longer need this strategy guide. Read the [https://www.hexwiki.net HexWiki]. Learn from players who are better than you. Play a lot and watch a lot of games. Develop your own theory. &lt;br /&gt;
&lt;br /&gt;
== Resources ==&lt;br /&gt;
&lt;br /&gt;
* Matthew Seymour&#039;s online book [http://www.mseymour.ca/hex_book/ Hex: A Strategy Guide]. A good starting point for learning Hex strategy.&lt;br /&gt;
&lt;br /&gt;
* Matthew Seymour&#039;s [http://www.mseymour.ca/hex_puzzle/ Hex puzzles]. Fun and very addictive! You will become a better player.&lt;br /&gt;
&lt;br /&gt;
* The [https://www.hexwiki.net/ HexWiki]. Too much information for beginners, as it is difficult to know what to read first. It is better to start with Seymour&#039;s book. However, the Wiki is a great resource once you&#039;ve mastered the basics.&lt;/div&gt;</summary>
		<author><name>User Already Exists</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Tips_hex&amp;diff=12076</id>
		<title>Tips hex</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Tips_hex&amp;diff=12076"/>
		<updated>2022-02-24T19:09:07Z</updated>

		<summary type="html">&lt;p&gt;User Already Exists: /* Good players */ Added foiling.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
&lt;br /&gt;
Although the rules of Hex are very simple, its strategy is quite rich and has many layers. The good news is that there are many clever and satisfying strategy concepts that can be learned by players of all levels.&lt;br /&gt;
&lt;br /&gt;
=== Beginners ===&lt;br /&gt;
&lt;br /&gt;
To reach level 100, you should learn about templates, especially the [https://www.hexwiki.net/index.php/Bridge bridge] and the [https://www.hexwiki.net/index.php/Ziggurat ziggurat]. You should also learn basic [https://www.hexwiki.net/index.php/Blocking blocking]. You might try a few dozen of Matthew Seymour&#039;s [http://www.mseymour.ca/hex_puzzle/ Hex puzzles].&lt;br /&gt;
&lt;br /&gt;
=== Average players ===&lt;br /&gt;
&lt;br /&gt;
To reach level 200, you should learn about [https://www.hexwiki.net/index.php/Ladder_handling ladder handling], especially [https://www.hexwiki.net/index.php/Ladder_escape ladder escapes], and [https://www.hexwiki.net/index.php/Climbing pivoting and climbing]. You should learn more [https://www.hexwiki.net/index.php/Edge_templates_everybody_should_know templates]. You should also begin to use template intrusions to steal territory and help you connect. You should also learn [https://www.hexwiki.net/index.php/Swap when to swap]. You should solve more [http://www.mseymour.ca/hex_puzzle/ Hex puzzles].&lt;br /&gt;
&lt;br /&gt;
=== Good players ===&lt;br /&gt;
&lt;br /&gt;
To reach level 300, you should learn some advanced ways of connecting, such as [https://www.hexwiki.net/index.php/Tom%27s_move Tom&#039;s move], [https://www.hexwiki.net/index.php/Switchback switchbacks], and [https://www.hexwiki.net/index.php/Foldback foldbacks]. You should learn to [https://www.hexwiki.net/index.php/Foiling foil], and especially, how to counter fishing moves. You should learn about the [https://www.hexwiki.net/index.php/Mustplay_region mustplay region] and to recognize what is connected and what is not, to avoid defending the indefensible or attacking what is solid. You should start to use [https://www.hexwiki.net/index.php/Minimax minimaxing], such as building [https://www.hexwiki.net/index.php/Wall walls]. You should learn some [https://www.hexwiki.net/index.php/Ladder_creation_template ladder creation templates]. You should also start playing  [https://www.hexwiki.net/index.php/Corner_move corner moves].&lt;br /&gt;
&lt;br /&gt;
=== Strong players ===&lt;br /&gt;
&lt;br /&gt;
To reach level 400, you should consistently use [https://www.hexwiki.net/index.php/Minimax minimaxing]. You should learn to choose from among several possible moves to gain small advantages. You should learn to [https://www.hexwiki.net/index.php/Tidiness tidy up]. You should play [https://www.hexwiki.net/index.php/Joseki josekis]. &lt;br /&gt;
&lt;br /&gt;
To reach level 500, you should study different [https://www.hexwiki.net/index.php/Opening openings] and the best responses to them. You should know about [https://www.hexwiki.net/index.php/Flank flanks] and [https://www.hexwiki.net/index.php/Pivoting_template pivoting templates]. You should learn about [https://www.hexwiki.net/index.php/Captured_cell capture] and [https://www.hexwiki.net/index.php/Dominated_cell domination] to play locally optimal moves.&lt;br /&gt;
&lt;br /&gt;
=== Experts ===&lt;br /&gt;
&lt;br /&gt;
To go beyond level 500, you no longer need this strategy guide. Read the [https://www.hexwiki.net HexWiki]. Learn from players who are better than you. Play a lot and watch a lot of games. Develop your own theory. &lt;br /&gt;
&lt;br /&gt;
== Resources ==&lt;br /&gt;
&lt;br /&gt;
* Matthew Seymour&#039;s online book [http://www.mseymour.ca/hex_book/ Hex: A Strategy Guide]. A good starting point for learning Hex strategy.&lt;br /&gt;
&lt;br /&gt;
* Matthew Seymour&#039;s [http://www.mseymour.ca/hex_puzzle/ Hex puzzles]. Fun and very addictive! You will become a better player.&lt;br /&gt;
&lt;br /&gt;
* The [https://www.hexwiki.net/ HexWiki]. Too much information for beginners, as it is difficult to know what to read first. It is better to start with Seymour&#039;s book. However, the Wiki is a great resource once you&#039;ve mastered the basics.&lt;/div&gt;</summary>
		<author><name>User Already Exists</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Tips_hex&amp;diff=12075</id>
		<title>Tips hex</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Tips_hex&amp;diff=12075"/>
		<updated>2022-02-24T19:06:48Z</updated>

		<summary type="html">&lt;p&gt;User Already Exists: Created a page with strategy tips (more like a collection of links).&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
&lt;br /&gt;
Although the rules of Hex are very simple, its strategy is quite rich and has many layers. The good news is that there are many clever and satisfying strategy concepts that can be learned by players of all levels.&lt;br /&gt;
&lt;br /&gt;
=== Beginners ===&lt;br /&gt;
&lt;br /&gt;
To reach level 100, you should learn about templates, especially the [https://www.hexwiki.net/index.php/Bridge bridge] and the [https://www.hexwiki.net/index.php/Ziggurat ziggurat]. You should also learn basic [https://www.hexwiki.net/index.php/Blocking blocking]. You might try a few dozen of Matthew Seymour&#039;s [http://www.mseymour.ca/hex_puzzle/ Hex puzzles].&lt;br /&gt;
&lt;br /&gt;
=== Average players ===&lt;br /&gt;
&lt;br /&gt;
To reach level 200, you should learn about [https://www.hexwiki.net/index.php/Ladder_handling ladder handling], especially [https://www.hexwiki.net/index.php/Ladder_escape ladder escapes], and [https://www.hexwiki.net/index.php/Climbing pivoting and climbing]. You should learn more [https://www.hexwiki.net/index.php/Edge_templates_everybody_should_know templates]. You should also begin to use template intrusions to steal territory and help you connect. You should also learn [https://www.hexwiki.net/index.php/Swap when to swap]. You should solve more [http://www.mseymour.ca/hex_puzzle/ Hex puzzles].&lt;br /&gt;
&lt;br /&gt;
=== Good players ===&lt;br /&gt;
&lt;br /&gt;
To reach level 300, you should learn some advanced ways of connecting, such as [https://www.hexwiki.net/index.php/Tom%27s_move Tom&#039;s move], [https://www.hexwiki.net/index.php/Switchback switchbacks], and [https://www.hexwiki.net/index.php/Foldback foldbacks]. You should learn about the [https://www.hexwiki.net/index.php/Mustplay_region mustplay region] and to recognize what is connected and what is not, to avoid defending the indefensible or attacking what is solid. You should start to use [https://www.hexwiki.net/index.php/Minimax minimaxing], such as building [https://www.hexwiki.net/index.php/Wall walls]. You should learn some [https://www.hexwiki.net/index.php/Ladder_creation_template ladder creation templates]. You should also start playing  [https://www.hexwiki.net/index.php/Corner_move corner moves].&lt;br /&gt;
&lt;br /&gt;
=== Strong players ===&lt;br /&gt;
&lt;br /&gt;
To reach level 400, you should consistently use [https://www.hexwiki.net/index.php/Minimax minimaxing]. You should learn to choose from among several possible moves to gain small advantages. You should learn to [https://www.hexwiki.net/index.php/Tidiness tidy up]. You should play [https://www.hexwiki.net/index.php/Joseki josekis]. &lt;br /&gt;
&lt;br /&gt;
To reach level 500, you should study different [https://www.hexwiki.net/index.php/Opening openings] and the best responses to them. You should know about [https://www.hexwiki.net/index.php/Flank flanks] and [https://www.hexwiki.net/index.php/Pivoting_template pivoting templates]. You should learn about [https://www.hexwiki.net/index.php/Captured_cell capture] and [https://www.hexwiki.net/index.php/Dominated_cell domination] to play locally optimal moves.&lt;br /&gt;
&lt;br /&gt;
=== Experts ===&lt;br /&gt;
&lt;br /&gt;
To go beyond level 500, you no longer need this strategy guide. Read the [https://www.hexwiki.net HexWiki]. Learn from players who are better than you. Play a lot and watch a lot of games. Develop your own theory. &lt;br /&gt;
&lt;br /&gt;
== Resources ==&lt;br /&gt;
&lt;br /&gt;
* Matthew Seymour&#039;s online book [http://www.mseymour.ca/hex_book/ Hex: A Strategy Guide]. A good starting point for learning Hex strategy.&lt;br /&gt;
&lt;br /&gt;
* Matthew Seymour&#039;s [http://www.mseymour.ca/hex_puzzle/ Hex puzzles]. Fun and very addictive! You will become a better player.&lt;br /&gt;
&lt;br /&gt;
* The [https://www.hexwiki.net/ HexWiki]. Too much information for beginners, as it is difficult to know what to read first. It is better to start with Seymour&#039;s book. However, the Wiki is a great resource once you&#039;ve mastered the basics.&lt;/div&gt;</summary>
		<author><name>User Already Exists</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Tips_connectfour&amp;diff=12066</id>
		<title>Tips connectfour</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Tips_connectfour&amp;diff=12066"/>
		<updated>2022-02-24T17:44:32Z</updated>

		<summary type="html">&lt;p&gt;User Already Exists: Added more strategy hints&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== The first moves ==&lt;br /&gt;
&lt;br /&gt;
The best starting move for you is to place a piece right at the center. To counter this move, place your piece on top of it.&lt;br /&gt;
&lt;br /&gt;
== Watch out for traps ==&lt;br /&gt;
&lt;br /&gt;
A common trap is for your opponent to have two adjacent discs on the bottom row, with empty space on both sides. You must move on the bottom row directly next to your opponent&#039;s discs, or else your opponent will get 3 in a row with spaces on both sides, which you can no longer block.&lt;br /&gt;
&lt;br /&gt;
Another common trap on the bottom row is when the opponent has two discs with one empty space between them, and empty spaces on both sides. You must move in the middle between the two discs, or directly next to one of them, or else your opponent will get 3 in a row that you can no longer block.&lt;br /&gt;
&lt;br /&gt;
Another common trap is the shape that looks like a sideways &amp;quot;V&amp;quot;, with one horizontal and one diagonal leg. Your opponent can make 4 in a row in two different ways, which you cannot block. You will lose unless you manage to connect four elsewhere first.&lt;br /&gt;
&lt;br /&gt;
== Keep an eye on diagonals ==&lt;br /&gt;
&lt;br /&gt;
One of the best strategies in this game is to look at all the pieces and evaluate multiple ways of connecting four pieces in a straight line. Remember that there are only three ways to do so: vertically (which is easy to see and block), horizontally, and diagonally. On the 6x7 board, all horizontal and diagonal lines require the center column, which is why it is so important to occupy the center. &lt;br /&gt;
&lt;br /&gt;
Watch out for diagonals. Four pieces placed diagonally are the most common way in which people often win.&lt;br /&gt;
&lt;br /&gt;
== Counting ==&lt;br /&gt;
&lt;br /&gt;
Often the game comes down to counting: when there are a number of columns that you cannot move in without losing, then you are forced to fill up the remaining columns. If there are an even number of spaces in the remaining columns, then it will be your turn again when they are filled up, and you will lose (unless you manage to connect four while filling up those columns!).&lt;br /&gt;
&lt;br /&gt;
When it comes to counting, spaces on the 1st, 3rd, and 5th row (from the bottom) generally favour Red, and spaces on the 2nd, 4th, and 6th row generally favour Yellow. Therefore, if you are Yellow, try to arrange your traps so that the last remaining spot is on an even row; if you are Red, try to do so with an odd row. This way, if the column in question is the last one to fill up, you will win.&lt;/div&gt;</summary>
		<author><name>User Already Exists</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Tips_connectfour&amp;diff=12065</id>
		<title>Tips connectfour</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Tips_connectfour&amp;diff=12065"/>
		<updated>2022-02-24T17:31:10Z</updated>

		<summary type="html">&lt;p&gt;User Already Exists: Some punctuation, capitalization&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The best starting move for you is to place a piece right at the center. To counter this move, place your piece on top of it. One of the best strategies in this game is to look at all the pieces and evaluate multiple ways of connecting four pieces in a straight line. Remember to watch out for diagonals. Four pieces placed diagonally are the most common way in which people often win.&lt;/div&gt;</summary>
		<author><name>User Already Exists</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Gamehelpconnectfour&amp;diff=11890</id>
		<title>Gamehelpconnectfour</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Gamehelpconnectfour&amp;diff=11890"/>
		<updated>2022-02-14T23:55:31Z</updated>

		<summary type="html">&lt;p&gt;User Already Exists: Edited for language and clarity.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Objective==&lt;br /&gt;
Connect Four is a two-player connection game. The objective is to connect four of your colored discs in a straight line while preventing your opponent from doing the same.&lt;br /&gt;
&lt;br /&gt;
==Game play==&lt;br /&gt;
The players take turns dropping one colored disc from the top into a vertically suspended grid. The discs fall straight down, occupying the lowest available space within the column.&lt;br /&gt;
&lt;br /&gt;
The game ends when one player forms a horizontal, vertical, or diagonal line of four of their own  discs. If the entire board fills up before either player achieves four in a row, then the game ends in a tie.&lt;br /&gt;
&lt;br /&gt;
==Board sizes==&lt;br /&gt;
Four board sizes (6x7, 8x9, 9x9, and 10x10) are available in the BGA implementation.&lt;br /&gt;
&lt;br /&gt;
==Opening rule==&lt;br /&gt;
Two optional opening rules are implemented to eliminate first player advantage.&lt;br /&gt;
&lt;br /&gt;
* Pie rule: After the first player&#039;s first move, the second player may switch colors.&lt;br /&gt;
&lt;br /&gt;
* Swap rule: The first player places three discs - a red disc, a yellow disc, and another red disc. After the first 3 discs are placed, the second player may switch colors.&lt;br /&gt;
&lt;br /&gt;
==Arena mode==&lt;br /&gt;
The 6x7 board size is unavailable in Arena mode because the game is too easily solved.&lt;br /&gt;
&lt;br /&gt;
The opening rule is locked as the swap rule, to allow various opening moves to be played and to remove any potential first/second player advantage.&lt;br /&gt;
&lt;br /&gt;
Currently (since Oct. 2021), the board size option rotates as the season passes (9x9 → 8x9 → 9x9 → 8x9 → ...).&lt;br /&gt;
&lt;br /&gt;
Gurus, &#039;&#039;do not vote for a 6x7 board size or non-swap openings!&#039;&#039;&lt;/div&gt;</summary>
		<author><name>User Already Exists</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Gamehelphex&amp;diff=10168</id>
		<title>Gamehelphex</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Gamehelphex&amp;diff=10168"/>
		<updated>2021-11-13T14:07:10Z</updated>

		<summary type="html">&lt;p&gt;User Already Exists: /* Accessibility */ wording&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The game of Hex was invented and popularized in Denmark by Piet Hein in 1942, and later independently rediscovered by John Nash in 1947. The game is attractive because it has extremely simple rules, yet a surprising amount of strategic depth. Another interesting aspect is that the game can&#039;t end in a tie.&lt;br /&gt;
&lt;br /&gt;
== Rules ==&lt;br /&gt;
&lt;br /&gt;
=== Goal ===&lt;br /&gt;
&lt;br /&gt;
The board has two red edges and two blue edges. Each player&#039;s goal is to connect their two edges by stones of their color.&lt;br /&gt;
&lt;br /&gt;
=== Turns ===&lt;br /&gt;
&lt;br /&gt;
The players alternately place a stone of their own color on the board, with Red going first. A stone can be placed on any empty cell. Once placed, stones are never moved or removed.&lt;br /&gt;
&lt;br /&gt;
=== The swap rule ===&lt;br /&gt;
&lt;br /&gt;
To make sure the first player does not have an unfair advantage, the swap rule is used. After the first player opens with a red stone, the second player has the option to &amp;quot;swap&amp;quot;, or steal the opponent&#039;s first move. In this case, Red&#039;s initial stone is replaced by a blue stone and mirrored about the long diagonal. After this, it is Red&#039;s turn.&lt;br /&gt;
&lt;br /&gt;
=== Game end ===&lt;br /&gt;
&lt;br /&gt;
The game ends when one of the players has connected their edges with a path of stones of their color. The game can&#039;t end in a tie. When it is clear to both players who will win, it is customary for the losing player to resign.&lt;br /&gt;
&lt;br /&gt;
== Game options and interface ==&lt;br /&gt;
&lt;br /&gt;
=== Board size ===&lt;br /&gt;
&lt;br /&gt;
The game can be played on boards of several different sizes. The 6x6 board is designed to help beginners understand the basic rules and discover simple game patterns. The 11x11 board is a more classic size and was used by Piet Hein. The 13x13 board is preferred by many experts. The 14x14 board was recommended by John Nash, and the 15x15 board allows even longer plays.&lt;br /&gt;
&lt;br /&gt;
The 6x6 board size is only available in training mode.&lt;br /&gt;
&lt;br /&gt;
=== Moves and swapping ===&lt;br /&gt;
&lt;br /&gt;
To make a move, click on an empty cell. To guard against accidental misclicks, you have to confirm each move by clicking on the stone a second time (or use the &amp;quot;confirm&amp;quot; or &amp;quot;cancel&amp;quot; buttons above the play area).&lt;br /&gt;
&lt;br /&gt;
On the second move of the game, you have the option to swap. To do so, click on the &amp;quot;swap&amp;quot; button above the play area. If you do not want to swap, simply make a normal move.&lt;br /&gt;
&lt;br /&gt;
=== Resigning ===&lt;br /&gt;
&lt;br /&gt;
Players can resign at any time (whether or not it is their turn). The resign button is found in the &amp;quot;additional game controls&amp;quot; menu, which is marked by three dots &amp;quot;...&amp;quot; in the upper right corner of the play area. &lt;br /&gt;
&lt;br /&gt;
=== Passing ===&lt;br /&gt;
&lt;br /&gt;
Passing (i.e., skipping a move) is rarely done in Hex. The reason is that passing never benefits a player: if you can win by passing, you can also win by making a random move. Nevertheless, the ability to pass has been included in the Board Game Arena implementation of Hex. It has certain specialized uses, such as teaching, giving handicap (i.e., giving an advantage to the weaker player), or setting up an initial board position.&lt;br /&gt;
&lt;br /&gt;
The option to pass is found in the &amp;quot;additional game controls&amp;quot; menu, which is marked by three dots &amp;quot;...&amp;quot; in the upper right corner of the play area. If your opponent passes and you do not want to allow it for some reason, simply pass yourself, which effectively returns the game to its previous state. Three passes in a row are not permitted, so if both players have passed, the next player must make a proper move.&lt;br /&gt;
&lt;br /&gt;
=== Accessibility ===&lt;br /&gt;
&lt;br /&gt;
The shades of red and blue that Hex uses by default can be difficult to distinguish for colorblind people. To compensate for this, there is now a game display option for color blindness in the Options menu below the game board.&lt;/div&gt;</summary>
		<author><name>User Already Exists</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Gamehelphex&amp;diff=10162</id>
		<title>Gamehelphex</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Gamehelphex&amp;diff=10162"/>
		<updated>2021-11-12T18:40:38Z</updated>

		<summary type="html">&lt;p&gt;User Already Exists: /* Accessibility */ Removed limitation.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The game of Hex was invented and popularized in Denmark by Piet Hein in 1942, and later independently rediscovered by John Nash in 1947. The game is attractive because it has extremely simple rules, yet a surprising amount of strategic depth. Another interesting aspect is that the game can&#039;t end in a tie.&lt;br /&gt;
&lt;br /&gt;
== Rules ==&lt;br /&gt;
&lt;br /&gt;
=== Goal ===&lt;br /&gt;
&lt;br /&gt;
The board has two red edges and two blue edges. Each player&#039;s goal is to connect their two edges by stones of their color.&lt;br /&gt;
&lt;br /&gt;
=== Turns ===&lt;br /&gt;
&lt;br /&gt;
The players alternately place a stone of their own color on the board, with Red going first. A stone can be placed on any empty cell. Once placed, stones are never moved or removed.&lt;br /&gt;
&lt;br /&gt;
=== The swap rule ===&lt;br /&gt;
&lt;br /&gt;
To make sure the first player does not have an unfair advantage, the swap rule is used. After the first player opens with a red stone, the second player has the option to &amp;quot;swap&amp;quot;, or steal the opponent&#039;s first move. In this case, Red&#039;s initial stone is replaced by a blue stone and mirrored about the long diagonal. After this, it is Red&#039;s turn.&lt;br /&gt;
&lt;br /&gt;
=== Game end ===&lt;br /&gt;
&lt;br /&gt;
The game ends when one of the players has connected their edges with a path of stones of their color. The game can&#039;t end in a tie. When it is clear to both players who will win, it is customary for the losing player to resign.&lt;br /&gt;
&lt;br /&gt;
== Game options and interface ==&lt;br /&gt;
&lt;br /&gt;
=== Board size ===&lt;br /&gt;
&lt;br /&gt;
The game can be played on boards of several different sizes. The 6x6 board is designed to help beginners understand the basic rules and discover simple game patterns. The 11x11 board is a more classic size and was used by Piet Hein. The 13x13 board is preferred by many experts. The 14x14 board was recommended by John Nash, and the 15x15 board allows even longer plays.&lt;br /&gt;
&lt;br /&gt;
The 6x6 board size is only available in training mode.&lt;br /&gt;
&lt;br /&gt;
=== Moves and swapping ===&lt;br /&gt;
&lt;br /&gt;
To make a move, click on an empty cell. To guard against accidental misclicks, you have to confirm each move by clicking on the stone a second time (or use the &amp;quot;confirm&amp;quot; or &amp;quot;cancel&amp;quot; buttons above the play area).&lt;br /&gt;
&lt;br /&gt;
On the second move of the game, you have the option to swap. To do so, click on the &amp;quot;swap&amp;quot; button above the play area. If you do not want to swap, simply make a normal move.&lt;br /&gt;
&lt;br /&gt;
=== Resigning ===&lt;br /&gt;
&lt;br /&gt;
Players can resign at any time (whether or not it is their turn). The resign button is found in the &amp;quot;additional game controls&amp;quot; menu, which is marked by three dots &amp;quot;...&amp;quot; in the upper right corner of the play area. &lt;br /&gt;
&lt;br /&gt;
=== Passing ===&lt;br /&gt;
&lt;br /&gt;
Passing (i.e., skipping a move) is rarely done in Hex. The reason is that passing never benefits a player: if you can win by passing, you can also win by making a random move. Nevertheless, the ability to pass has been included in the Board Game Arena implementation of Hex. It has certain specialized uses, such as teaching, giving handicap (i.e., giving an advantage to the weaker player), or setting up an initial board position.&lt;br /&gt;
&lt;br /&gt;
The option to pass is found in the &amp;quot;additional game controls&amp;quot; menu, which is marked by three dots &amp;quot;...&amp;quot; in the upper right corner of the play area. If your opponent passes and you do not want to allow it for some reason, simply pass yourself, which effectively returns the game to its previous state. Three passes in a row are not permitted, so if both players have passed, the next player must make a proper move.&lt;br /&gt;
&lt;br /&gt;
=== Accessibility ===&lt;br /&gt;
&lt;br /&gt;
The shades of red and blue that Hex uses by default can be difficult to distinguish for colorblind people. To compensate for this, select Game Display: Color blindness in the Options menu below the game board.&lt;/div&gt;</summary>
		<author><name>User Already Exists</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Gamehelphex&amp;diff=10121</id>
		<title>Gamehelphex</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Gamehelphex&amp;diff=10121"/>
		<updated>2021-11-10T04:01:29Z</updated>

		<summary type="html">&lt;p&gt;User Already Exists: /* Accessibility */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The game of Hex was invented and popularized in Denmark by Piet Hein in 1942, and later independently rediscovered by John Nash in 1947. The game is attractive because it has extremely simple rules, yet a surprising amount of strategic depth. Another interesting aspect is that the game can&#039;t end in a tie.&lt;br /&gt;
&lt;br /&gt;
== Rules ==&lt;br /&gt;
&lt;br /&gt;
=== Goal ===&lt;br /&gt;
&lt;br /&gt;
The board has two red edges and two blue edges. Each player&#039;s goal is to connect their two edges by stones of their color.&lt;br /&gt;
&lt;br /&gt;
=== Turns ===&lt;br /&gt;
&lt;br /&gt;
The players alternately place a stone of their own color on the board, with Red going first. A stone can be placed on any empty cell. Once placed, stones are never moved or removed.&lt;br /&gt;
&lt;br /&gt;
=== The swap rule ===&lt;br /&gt;
&lt;br /&gt;
To make sure the first player does not have an unfair advantage, the swap rule is used. After the first player opens with a red stone, the second player has the option to &amp;quot;swap&amp;quot;, or steal the opponent&#039;s first move. In this case, Red&#039;s initial stone is replaced by a blue stone and mirrored about the long diagonal. After this, it is Red&#039;s turn.&lt;br /&gt;
&lt;br /&gt;
=== Game end ===&lt;br /&gt;
&lt;br /&gt;
The game ends when one of the players has connected their edges with a path of stones of their color. The game can&#039;t end in a tie. When it is clear to both players who will win, it is customary for the losing player to resign.&lt;br /&gt;
&lt;br /&gt;
== Game options and interface ==&lt;br /&gt;
&lt;br /&gt;
=== Board size ===&lt;br /&gt;
&lt;br /&gt;
The game can be played on boards of several different sizes. The 6x6 board is designed to help beginners understand the basic rules and discover simple game patterns. The 11x11 board is a more classic size and was used by Piet Hein. The 13x13 board is preferred by many experts. The 14x14 board was recommended by John Nash, and the 15x15 board allows even longer plays.&lt;br /&gt;
&lt;br /&gt;
The 6x6 board size is only available in training mode.&lt;br /&gt;
&lt;br /&gt;
=== Moves and swapping ===&lt;br /&gt;
&lt;br /&gt;
To make a move, click on an empty cell. To guard against accidental misclicks, you have to confirm each move by clicking on the stone a second time (or use the &amp;quot;confirm&amp;quot; or &amp;quot;cancel&amp;quot; buttons above the play area).&lt;br /&gt;
&lt;br /&gt;
On the second move of the game, you have the option to swap. To do so, click on the &amp;quot;swap&amp;quot; button above the play area. If you do not want to swap, simply make a normal move.&lt;br /&gt;
&lt;br /&gt;
=== Resigning ===&lt;br /&gt;
&lt;br /&gt;
Players can resign at any time (whether or not it is their turn). The resign button is found in the &amp;quot;additional game controls&amp;quot; menu, which is marked by three dots &amp;quot;...&amp;quot; in the upper right corner of the play area. &lt;br /&gt;
&lt;br /&gt;
=== Passing ===&lt;br /&gt;
&lt;br /&gt;
Passing (i.e., skipping a move) is rarely done in Hex. The reason is that passing never benefits a player: if you can win by passing, you can also win by making a random move. Nevertheless, the ability to pass has been included in the Board Game Arena implementation of Hex. It has certain specialized uses, such as teaching, giving handicap (i.e., giving an advantage to the weaker player), or setting up an initial board position.&lt;br /&gt;
&lt;br /&gt;
The option to pass is found in the &amp;quot;additional game controls&amp;quot; menu, which is marked by three dots &amp;quot;...&amp;quot; in the upper right corner of the play area. If your opponent passes and you do not want to allow it for some reason, simply pass yourself, which effectively returns the game to its previous state. Three passes in a row are not permitted, so if both players have passed, the next player must make a proper move.&lt;br /&gt;
&lt;br /&gt;
=== Accessibility ===&lt;br /&gt;
&lt;br /&gt;
The shades of red and blue that Hex uses by default can be difficult to distinguish for colorblind people. To compensate for this, there is now a &amp;quot;Color blindness&amp;quot; setting in the &amp;quot;Options&amp;quot; below the game board. It changes the colors to be more easily distinguishable. (Limitation: this currently only works for games in progress, and not during replay).&lt;/div&gt;</summary>
		<author><name>User Already Exists</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Gamehelphex&amp;diff=10112</id>
		<title>Gamehelphex</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Gamehelphex&amp;diff=10112"/>
		<updated>2021-11-09T04:09:42Z</updated>

		<summary type="html">&lt;p&gt;User Already Exists: /* Game options and interface */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The game of Hex was invented and popularized in Denmark by Piet Hein in 1942, and later independently rediscovered by John Nash in 1947. The game is attractive because it has extremely simple rules, yet a surprising amount of strategic depth. Another interesting aspect is that the game can&#039;t end in a tie.&lt;br /&gt;
&lt;br /&gt;
== Rules ==&lt;br /&gt;
&lt;br /&gt;
=== Goal ===&lt;br /&gt;
&lt;br /&gt;
The board has two red edges and two blue edges. Each player&#039;s goal is to connect their two edges by stones of their color.&lt;br /&gt;
&lt;br /&gt;
=== Turns ===&lt;br /&gt;
&lt;br /&gt;
The players alternately place a stone of their own color on the board, with Red going first. A stone can be placed on any empty cell. Once placed, stones are never moved or removed.&lt;br /&gt;
&lt;br /&gt;
=== The swap rule ===&lt;br /&gt;
&lt;br /&gt;
To make sure the first player does not have an unfair advantage, the swap rule is used. After the first player opens with a red stone, the second player has the option to &amp;quot;swap&amp;quot;, or steal the opponent&#039;s first move. In this case, Red&#039;s initial stone is replaced by a blue stone and mirrored about the long diagonal. After this, it is Red&#039;s turn.&lt;br /&gt;
&lt;br /&gt;
=== Game end ===&lt;br /&gt;
&lt;br /&gt;
The game ends when one of the players has connected their edges with a path of stones of their color. The game can&#039;t end in a tie. When it is clear to both players who will win, it is customary for the losing player to resign.&lt;br /&gt;
&lt;br /&gt;
== Game options and interface ==&lt;br /&gt;
&lt;br /&gt;
=== Board size ===&lt;br /&gt;
&lt;br /&gt;
The game can be played on boards of several different sizes. The 6x6 board is designed to help beginners understand the basic rules and discover simple game patterns. The 11x11 board is a more classic size and was used by Piet Hein. The 13x13 board is preferred by many experts. The 14x14 board was recommended by John Nash, and the 15x15 board allows even longer plays.&lt;br /&gt;
&lt;br /&gt;
The 6x6 board size is only available in training mode.&lt;br /&gt;
&lt;br /&gt;
=== Moves and swapping ===&lt;br /&gt;
&lt;br /&gt;
To make a move, click on an empty cell. To guard against accidental misclicks, you have to confirm each move by clicking on the stone a second time (or use the &amp;quot;confirm&amp;quot; or &amp;quot;cancel&amp;quot; buttons above the play area).&lt;br /&gt;
&lt;br /&gt;
On the second move of the game, you have the option to swap. To do so, click on the &amp;quot;swap&amp;quot; button above the play area. If you do not want to swap, simply make a normal move.&lt;br /&gt;
&lt;br /&gt;
=== Resigning ===&lt;br /&gt;
&lt;br /&gt;
Players can resign at any time (whether or not it is their turn). The resign button is found in the &amp;quot;additional game controls&amp;quot; menu, which is marked by three dots &amp;quot;...&amp;quot; in the upper right corner of the play area. &lt;br /&gt;
&lt;br /&gt;
=== Passing ===&lt;br /&gt;
&lt;br /&gt;
Passing (i.e., skipping a move) is rarely done in Hex. The reason is that passing never benefits a player: if you can win by passing, you can also win by making a random move. Nevertheless, the ability to pass has been included in the Board Game Arena implementation of Hex. It has certain specialized uses, such as teaching, giving handicap (i.e., giving an advantage to the weaker player), or setting up an initial board position.&lt;br /&gt;
&lt;br /&gt;
The option to pass is found in the &amp;quot;additional game controls&amp;quot; menu, which is marked by three dots &amp;quot;...&amp;quot; in the upper right corner of the play area. If your opponent passes and you do not want to allow it for some reason, simply pass yourself, which effectively returns the game to its previous state. Three passes in a row are not permitted, so if both players have passed, the next player must make a proper move.&lt;br /&gt;
&lt;br /&gt;
=== Accessibility ===&lt;br /&gt;
&lt;br /&gt;
The shades of red and blue that Hex uses by default can be difficult to distinguish for colorblind people. To fix this, go to the Preferences in the BGA menu in the upper right corner of the screen and change &amp;quot;Game display&amp;quot; to &amp;quot;Color blindness&amp;quot;. (Limitation: this currently only works for games in progress, and not during replay).&lt;/div&gt;</summary>
		<author><name>User Already Exists</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Gamehelphex&amp;diff=10075</id>
		<title>Gamehelphex</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Gamehelphex&amp;diff=10075"/>
		<updated>2021-11-06T14:54:33Z</updated>

		<summary type="html">&lt;p&gt;User Already Exists: Added a description of the game controls; copy-editing.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The game of Hex was invented and popularized in Denmark by Piet Hein in 1942, and later independently rediscovered by John Nash in 1947. The game is attractive because it has extremely simple rules, yet a surprising amount of strategic depth. Another interesting aspect is that the game can&#039;t end in a tie.&lt;br /&gt;
&lt;br /&gt;
== Rules ==&lt;br /&gt;
&lt;br /&gt;
=== Goal ===&lt;br /&gt;
&lt;br /&gt;
The board has two red edges and two blue edges. Each player&#039;s goal is to connect their two edges by stones of their color.&lt;br /&gt;
&lt;br /&gt;
=== Turns ===&lt;br /&gt;
&lt;br /&gt;
The players alternately place a stone of their own color on the board, with Red going first. A stone can be placed on any empty cell. Once placed, stones are never moved or removed.&lt;br /&gt;
&lt;br /&gt;
=== The swap rule ===&lt;br /&gt;
&lt;br /&gt;
To make sure the first player does not have an unfair advantage, the swap rule is used. After the first player opens with a red stone, the second player has the option to &amp;quot;swap&amp;quot;, or steal the opponent&#039;s first move. In this case, Red&#039;s initial stone is replaced by a blue stone and mirrored about the long diagonal. After this, it is Red&#039;s turn.&lt;br /&gt;
&lt;br /&gt;
=== Game end ===&lt;br /&gt;
&lt;br /&gt;
The game ends when one of the players has connected their edges with a path of stones of their color. The game can&#039;t end in a tie. When it is clear to both players who will win, it is customary for the losing player to resign.&lt;br /&gt;
&lt;br /&gt;
== Game options and interface ==&lt;br /&gt;
&lt;br /&gt;
=== Board size ===&lt;br /&gt;
&lt;br /&gt;
The game can be played on boards of several different sizes. The 6x6 board is designed to help beginners understand the basic rules and discover simple game patterns. The 11x11 board is a more classic size and was used by Piet Hein. The 13x13 board is preferred by many experts. The 14x14 board was recommended by John Nash, and the 15x15 board allows even longer plays.&lt;br /&gt;
&lt;br /&gt;
The 6x6 board size is only available in training mode.&lt;br /&gt;
&lt;br /&gt;
=== Moves and swapping ===&lt;br /&gt;
&lt;br /&gt;
To make a move, click on an empty cell. To guard against accidental misclicks, you have to confirm each move by clicking on the stone a second time (or use the &amp;quot;confirm&amp;quot; or &amp;quot;cancel&amp;quot; buttons above the play area).&lt;br /&gt;
&lt;br /&gt;
On the second move of the game, you have the option to swap. To do so, click on the &amp;quot;swap&amp;quot; button above the play area. If you do not want to swap, simply make a normal move.&lt;br /&gt;
&lt;br /&gt;
=== Resigning ===&lt;br /&gt;
&lt;br /&gt;
Players can resign at any time (whether or not it is their turn). The resign button is found in the &amp;quot;additional game controls&amp;quot; menu, which is marked by three dots &amp;quot;...&amp;quot; in the upper right corner of the play area. &lt;br /&gt;
&lt;br /&gt;
=== Passing ===&lt;br /&gt;
&lt;br /&gt;
Passing (i.e., skipping a move) is rarely done in Hex. The reason is that passing never benefits a player: if you can win by passing, you can also win by making a random move. Nevertheless, the ability to pass has been included in the Board Game Arena implementation of Hex. It has certain specialized uses, such as teaching, giving handicap (i.e., giving an advantage to the weaker player), or setting up an initial board position.&lt;br /&gt;
&lt;br /&gt;
The option to pass is found in the &amp;quot;additional game controls&amp;quot; menu, which is marked by three dots &amp;quot;...&amp;quot; in the upper right corner of the play area. If your opponent passes and you do not want to allow it for some reason, simply pass yourself, which effectively returns the game to its previous state. Three passes in a row are not permitted, so if both players have passed, the next player must make a proper move.&lt;/div&gt;</summary>
		<author><name>User Already Exists</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Gamehelphex&amp;diff=10047</id>
		<title>Gamehelphex</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Gamehelphex&amp;diff=10047"/>
		<updated>2021-11-04T12:20:34Z</updated>

		<summary type="html">&lt;p&gt;User Already Exists: Updated rules for new release.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== INTRODUCTION ===&lt;br /&gt;
&lt;br /&gt;
The game of Hex was invented and popularized in Denmark by Piet Hein in 1942, and later independently rediscovered by John Nash in 1947. The game is attractive because it has extremely simple rules, yet a surprising amount of strategic depth. Another interesting aspect is that the game can&#039;t end in a tie.&lt;br /&gt;
&lt;br /&gt;
=== GOAL ===&lt;br /&gt;
&lt;br /&gt;
The board has two red edges and two blue edges. Each player&#039;s goal is to connect their two edges by stones of their color.&lt;br /&gt;
&lt;br /&gt;
=== TURNS ===&lt;br /&gt;
&lt;br /&gt;
The players alternately place a stone of their own color on the board, with Red going first. A stone can be placed on any empty cell. Once placed, stones are never moved or removed.&lt;br /&gt;
&lt;br /&gt;
=== THE SWAP RULE ===&lt;br /&gt;
&lt;br /&gt;
To make sure the first player does not have an unfair advantage, the swap rule is used. After the first player opens with a red stone, the second player can either&lt;br /&gt;
* continue to play normally, by placing a blue stone, or&lt;br /&gt;
* &amp;quot;swap&amp;quot;, or steal the opponent&#039;s first move. In this case, Red&#039;s initial stone is replaced by a blue stone and mirrored about the long diagonal. After this, it is Red&#039;s turn.&lt;br /&gt;
&lt;br /&gt;
=== GAME END ===&lt;br /&gt;
&lt;br /&gt;
The game ends when one of the players has connected their edges with a path of stones of their color. The game can&#039;t end in a tie. It is customary for the losing player to resign when it is clear to both players who will win. The option to resign is in a menu indicated by three dots in the upper right corner of the play area.&lt;br /&gt;
&lt;br /&gt;
=== BOARD SIZES ===&lt;br /&gt;
&lt;br /&gt;
The game can be played on boards of several different sizes. The 6x6 board is designed to help beginners understand the basic rules and discover simple game patterns. The 11x11 board is a more classic size and was used by Piet Hein. The 13x13 board is preferred by many experts. The 14x14 board was recommended by John Nash, and the 15x15 board allows even longer plays.&lt;br /&gt;
&lt;br /&gt;
The 6x6 board size is only available in training mode.&lt;/div&gt;</summary>
		<author><name>User Already Exists</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Gamehelphex&amp;diff=8525</id>
		<title>Gamehelphex</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Gamehelphex&amp;diff=8525"/>
		<updated>2021-06-15T23:11:34Z</updated>

		<summary type="html">&lt;p&gt;User Already Exists: Minor copy-edits&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== INTRODUCTION ===&lt;br /&gt;
&lt;br /&gt;
The game of Hex was invented and popularized in Denmark by Piet Hein in 1942, and later independently rediscovered by John Nash in 1947. The game is attractive because it has extremely simple rules, yet a surprising amount of strategic depth. Another interesting aspect is that the game can&#039;t end in a tie.&lt;br /&gt;
&lt;br /&gt;
=== GOAL ===&lt;br /&gt;
&lt;br /&gt;
The board has two red edges and two blue edges. Each player&#039;s goal is to connect their two edges by stones of their color.&lt;br /&gt;
&lt;br /&gt;
=== TURNS ===&lt;br /&gt;
&lt;br /&gt;
The players alternately place a stone of their own color on the board, with Red going first. A stone can be placed on any empty cell. Once placed, stones are never moved or removed.&lt;br /&gt;
&lt;br /&gt;
=== THE SWAP RULE ===&lt;br /&gt;
&lt;br /&gt;
To make sure the first player does not have an unfair advantage, the swap rule is used. After the first player opens with a red stone, the second player can either&lt;br /&gt;
* continue to play normally, by placing a blue stone, or&lt;br /&gt;
* decide to switch colors. In that case, the second player becomes Red, the first player becomes Blue, and the first move is kept. After this, the game continues normally, i.e., it is the first player&#039;s turn to play a blue stone. &lt;br /&gt;
&lt;br /&gt;
Alternatively, the swap rule can also be implemented in such a way that the players keep their original colors. In that case, if Blue wants to swap, Red&#039;s initial stone is replaced by a blue stone and mirrored about the long diagonal. After this, it is Red&#039;s turn.&lt;br /&gt;
&lt;br /&gt;
=== GAME END ===&lt;br /&gt;
&lt;br /&gt;
The game ends when one of the players has connected their edges with a path of stones of their color. The game can&#039;t end in a tie. It is customary for the losing player to resign when it is clear to both players who will win.&lt;br /&gt;
&lt;br /&gt;
=== BOARD SIZES ===&lt;br /&gt;
&lt;br /&gt;
The game can be played on boards of several different sizes. The 6x6 board is designed to help beginners understand the basic rules and discover simple game patterns. The 11x11 board is a more classic size and was used by Piet Hein. The 13x13 board is preferred by many experts. The 14x14 board was recommended by John Nash, and the 15x15 board allows even longer plays.&lt;/div&gt;</summary>
		<author><name>User Already Exists</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Pre-release_checklist&amp;diff=8455</id>
		<title>Pre-release checklist</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Pre-release_checklist&amp;diff=8455"/>
		<updated>2021-06-06T06:26:07Z</updated>

		<summary type="html">&lt;p&gt;User Already Exists: typo&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Studio_Framework_Navigation}}&lt;br /&gt;
&lt;br /&gt;
If you think your game is ready to be reviewed by by BGA admins and/or Publisher please consult this checklist first&lt;br /&gt;
&lt;br /&gt;
* Metadata and graphics&lt;br /&gt;
** [[Game_meta-information: gameinfos.inc.php]] has correct and up to date information about the game&lt;br /&gt;
** Game box graphics is 3D version of the game box (if available) and publisher icon is correct (see [[Game art: img directory]]). Space around the box has to be transparent, not white.&lt;br /&gt;
** You have added a game_banner.jpg and some game_displayX.jpg images to make the game page pretty (NB: on the studio, you have to create a build for these images to appear on the studio game page)&lt;br /&gt;
** There are no images in the img directory that are not needed anymore&lt;br /&gt;
** Multiple images (i.e. cards) are compressed in &amp;quot;Sprite&amp;quot; (see [[Game art: img directory]])&lt;br /&gt;
** Each image should not exceed 4M&lt;br /&gt;
** Total size should not exceed 10M, image compression should be used otherwise&lt;br /&gt;
** If you use extra fonts, they should be freeware (please include a .txt with the licence information)&lt;br /&gt;
* Server side&lt;br /&gt;
** When giving their turn to a player, you give them some extra time with the giveExtraTime() function&lt;br /&gt;
** Game progression is implemented (getGameProgression() in php)&lt;br /&gt;
** Zombie turn is implemented (zombieTurn() in php). Note: it can only be tested if you explicitly click on the quit button to create a zombie. If you are expelled it does not generated a Zombie.&lt;br /&gt;
** You have defined and implemented some meaningful statistics for your game (i.e. total points, point from source A, B, C...)&lt;br /&gt;
** Game has meaningful notification messages (but don&#039;t overkill it, more user logs will slow down the loading)&lt;br /&gt;
** You implemented tiebreaking (using aux score field) and updated tiebreaker description in meta-data&lt;br /&gt;
* Client side&lt;br /&gt;
** Please check that you use ajaxcall only on player actions and never programmatically. Otherwise, your code will very likely create race conditions resulting in deadlocks or other errors.&lt;br /&gt;
* Special testing&lt;br /&gt;
** Game is tested with spectator (non player observer): change the testuser in the URL to see the game as another user (same URL as when clicking on red arrow). As a spectator, you should be able to see the game as if you were sitting beside of the players at a real table: all public information, no private information.&lt;br /&gt;
** Game is tested with in-game replay from last move feature (by clicking on notification log items)&lt;br /&gt;
** Game works in Chrome and Firefox browsers at least. Also very recommended to test in IE 11 and Edge.&lt;br /&gt;
** Game works on mobile device (if you don&#039;t have mobile device to test at least test in Chrome with smaller screen, they have a mode for that)&lt;br /&gt;
** Test your game in realtime mode. Usually people will run out of time if you use default times unless you add call giveExtraTime($active_player_id) before each turn&lt;br /&gt;
** Test your game in 3D mode (if it makes sense; 3D mode can also be disabled through the &#039;enable_3d&#039; parameter for gameinfos.inc.php, but if it &amp;quot;mostly works&amp;quot;, it can be nice to keep it activated even if 2D is more appropriate for the game, just because it&#039;s fun to look at)&lt;br /&gt;
** Check your game against the waiting screen, otherwise game start can fail. See [[Practical_debugging#Debugging_an_issue_with_the_waiting_screen]]&lt;br /&gt;
* Cleanup&lt;br /&gt;
** Remove all extra console.log from your js code&lt;br /&gt;
** Remove all unnecessary debug logging from your php code&lt;br /&gt;
** Copyright headers in all source files have your name&lt;br /&gt;
* User Interface&lt;br /&gt;
** Review BGA UI design Guidelines [[BGA_Studio_Guidelines]]&lt;br /&gt;
** Check all your English messages for proper use of punctuation, capitalization, usage of present tense in notification (not past) and gender neutrality. See [[Translations]] for English rules.&lt;br /&gt;
** If the elements in your game zone don&#039;t occupy all the available horizontal space, &#039;&#039;&#039;they should be centered&#039;&#039;&#039;.&lt;br /&gt;
** If your game elements become blurry or pixellated when using the browser zoom, you may want to consider [[Game_art:_img_directory#Use_background-size | higher resolution images with background-size]]&lt;br /&gt;
** Non-self explanatory graphic elements should have tooltips&lt;br /&gt;
** If graphic elements appear in notification log they should have titles (i.e. title attribute of div) so can be read in non rendered form (i.e. as text only)&lt;br /&gt;
** Strings in your source code are ready for translation. See [[Translations]]. You can generate dummy translations for checking that everything is ready for translation from your &amp;quot;Manage game&amp;quot; page.&lt;br /&gt;
** A prefix for example a trigram for your game that you prepend to all the css classes to avoid namespace conflicts, i.e. vla_selected vs selected&lt;br /&gt;
** If you are looking for advice on design and some 3rd party testing you can post a message on the developers forum, and ask other developers, there are a lot of people who will gladly do it.&lt;br /&gt;
* Finally move to Alpha status&lt;br /&gt;
** If possible (meaning if there is not already a project with that name) copy your project to a new project &#039;&#039;&#039;matching exactly the name of the game&#039;&#039;&#039; (no prefix or suffix). If not possible move on to the next steps, admin will have to retrieve the other project and overwrite it.&lt;br /&gt;
** Create a build for your game from the &amp;quot;manage game&amp;quot; page (using the &#039;&#039;&#039;Build a new release version&#039;&#039;&#039; section) and check the log to make sure that everything builds fine (after a successful build, you should see a new version in &amp;quot;Versions available for production&amp;quot;).&lt;br /&gt;
** Send an e-mail to studio@boardgamearena.com asking to move the project forward for review. You cannot deploy yourself from the &amp;quot;manage game&amp;quot; page until a first deploy has been done by the admins. Please note that &#039;&#039;&#039;everything must be OK on the licensing&#039;&#039;&#039; side for a project to be moved to production.&lt;br /&gt;
** When admins publish (push to alpha) they will send an email to the developer with all relevant information about the next steps.&lt;/div&gt;</summary>
		<author><name>User Already Exists</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Pre-release_checklist&amp;diff=8454</id>
		<title>Pre-release checklist</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Pre-release_checklist&amp;diff=8454"/>
		<updated>2021-06-06T05:12:37Z</updated>

		<summary type="html">&lt;p&gt;User Already Exists: typos&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Studio_Framework_Navigation}}&lt;br /&gt;
&lt;br /&gt;
If you think your game is ready to be reviewed by by BGA admins and/or Publisher please consult this checklist first&lt;br /&gt;
&lt;br /&gt;
* Metadata and graphics&lt;br /&gt;
** [[Game_meta-information: gameinfos.inc.php]] has correct and up to date information about the game&lt;br /&gt;
** Game box graphics is 3D version of the game box (if available) and publisher icon is correct (see [[Game art: img directory]]). Space around the box has to be transparent, not white.&lt;br /&gt;
** You have added a game_banner.jpg and some game_displayX.jpg images to make the game page pretty (NB: on the studio, you have to create a build for these images to appear on the studio game page)&lt;br /&gt;
** There are no images in the img directory that are not needed anymore&lt;br /&gt;
** Multiple images (i.e. cards) are compressed in &amp;quot;Sprite&amp;quot; (see [[Game art: img directory]])&lt;br /&gt;
** Each image should not exceed 4M&lt;br /&gt;
** Total size should not exceed 10M, image compression should be used otherwise&lt;br /&gt;
** If you use extra fonts, they should be freeware (please include a .txt with the licence information)&lt;br /&gt;
* Server side&lt;br /&gt;
** When giving their turn to a player, you give them some extra time with the giveExtraTime() function&lt;br /&gt;
** Game progression is implemented (getGameProgression() in php)&lt;br /&gt;
** Zombie turn is implemented (zombieTurn() in php). Note: it can only be tested if you explicitly click on the quit button to create a zombie. If you are expelled it does not generated a Zombie.&lt;br /&gt;
** You have defined and implemented some meaningful statistics for your game (i.e. total points, point from source A, B, C...)&lt;br /&gt;
** Game has meaningful notification messages (but don&#039;t overkill it, more user logs will slow down the loading)&lt;br /&gt;
** You implemented tiebreaking (using aux score field) and updated tiebreaker description in meta-data&lt;br /&gt;
* Client side&lt;br /&gt;
** Please check that you use ajaxcall only on player actions and never programmatically. Otherwise, your code will very likely create race conditions resulting in deadlocks or other errors.&lt;br /&gt;
* Special testing&lt;br /&gt;
** Game is tested with spectator (non player observer): change the testuser in the URL to see the game as another user (same URL as when clicking on red arrow). As a spectator, you should be able to see the game as if you were sitting beside of the players at a real table: all public information, no private information.&lt;br /&gt;
** Game is tested with in-game replay from last move feature (by clicking on notification log items)&lt;br /&gt;
** Game works in Chrome and Firefox browsers at least. Also very recommended to test in IE 11 and Edge.&lt;br /&gt;
** Game works on mobile device (if you don&#039;t have mobile device to test at least test in Chrome with smaller screen, they have a mode for that)&lt;br /&gt;
** Test your game in realtime mode. Usually people will run out of time if you use default times unless you add call giveExtraTime($active_player_id) before each turn&lt;br /&gt;
** Test your game in 3D mode (if it makes sense; 3D mode can also be disabled through the &#039;enable_3d&#039; parameter for gameinfos.inc.php, but if it &amp;quot;mostly works&amp;quot;, it can be nice to keep it activated even if 2D is more appropriate for the game, just because it&#039;s fun to look at)&lt;br /&gt;
** Check your game against the waiting screen, otherwise game start can fail. See [[Practical_debugging#Debugging_an_issue_with_the_waiting_screen]]&lt;br /&gt;
* Cleanup&lt;br /&gt;
** Remove all extra console.log from your js code&lt;br /&gt;
** Remove all unnecessary debug logging from your php code&lt;br /&gt;
** Copyright headers in all source files have your name&lt;br /&gt;
* User Interface&lt;br /&gt;
** Review BGA UI design Guidelines [[BGA_Studio_Guidelines]]&lt;br /&gt;
** Check all your English messages for proper use of punctuation, capitalization, usage of present tense in notification (not past) and gender neutrality. See [[Translations]] for English rules.&lt;br /&gt;
** If the elements in your game zone don&#039;t occupy all the available horizontal space, &#039;&#039;&#039;they should be centered&#039;&#039;&#039;.&lt;br /&gt;
** If your game elements become blurry or pixellated when using the browser zoom, you may want to consider [[Game_art:_img_directory#Use_background-size | higher resolution images with background-size]]&lt;br /&gt;
** Non-self explanatory graphic elements should have tooltips&lt;br /&gt;
** If graphic elements appear in notification log they should have titles (i.e. title attribute of div) so can be read in non rendered form (i.e. as text only)&lt;br /&gt;
** Strings in your source code are ready for translation. See [[Translations]]. You can generate dummy translations for checking that everything is ready for translation from your &amp;quot;Manage game&amp;quot; page.&lt;br /&gt;
** A prefix for example a trigram for your game that you append to all the css classes to avoid namespace conflicts, i.e. vla_selected vs selected&lt;br /&gt;
** If you are looking for advice on design and some 3rd party testing you can post a message on the developers forum, and ask other developers, there are a lot of people who will gladly do it.&lt;br /&gt;
* Finally move to Alpha status&lt;br /&gt;
** If possible (meaning if there is not already a project with that name) copy your project to a new project &#039;&#039;&#039;matching exactly the name of the game&#039;&#039;&#039; (no prefix or suffix). If not possible move on to the next steps, admin will have to retrieve the other project and overwrite it.&lt;br /&gt;
** Create a build for your game from the &amp;quot;manage game&amp;quot; page (using the &#039;&#039;&#039;Build a new release version&#039;&#039;&#039; section) and check the log to make sure that everything builds fine (after a successful build, you should see a new version in &amp;quot;Versions available for production&amp;quot;).&lt;br /&gt;
** Send an e-mail to studio@boardgamearena.com asking to move the project forward for review. You cannot deploy yourself from the &amp;quot;manage game&amp;quot; page until a first deploy has been done by the admins. Please note that &#039;&#039;&#039;everything must be OK on the licensing&#039;&#039;&#039; side for a project to be moved to production.&lt;br /&gt;
** When admins publish (push to alpha) they will send an email to the developer with all relevant information about the next steps.&lt;/div&gt;</summary>
		<author><name>User Already Exists</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Pre-release_checklist&amp;diff=8453</id>
		<title>Pre-release checklist</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Pre-release_checklist&amp;diff=8453"/>
		<updated>2021-06-06T05:12:07Z</updated>

		<summary type="html">&lt;p&gt;User Already Exists: Fixed typos&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Studio_Framework_Navigation}}&lt;br /&gt;
&lt;br /&gt;
If you think your game is ready to be reviewed by by BGA admins and/or Publisher please consult this checklist first&lt;br /&gt;
&lt;br /&gt;
* Metadata and graphics&lt;br /&gt;
** [[Game_meta-information: gameinfos.inc.php]] has correct and up to date information about the game&lt;br /&gt;
** Game box graphics is 3D version of the game box (if available) and publisher icon is correct (see [[Game art: img directory]]). Space around the box has to be transparent, not white.&lt;br /&gt;
** You have added a game_banner.jpg and some game_displayX.jpg images to make the game page pretty (NB: on the studio, you have to create a build for these images to appear on the studio game page)&lt;br /&gt;
** There is no images in img directory which are not needed anymore&lt;br /&gt;
** Multiple images (i.e. cards) are compressed in &amp;quot;Sprite&amp;quot; (see [[Game art: img directory]])&lt;br /&gt;
** Each image should not exceed 4M&lt;br /&gt;
** Total size should not exceed 10M, image compression should be used otherwise&lt;br /&gt;
** If you use extra fonts, they should be freeware (please include a .txt with the licence information)&lt;br /&gt;
* Server side&lt;br /&gt;
** When giving their turn to a player, you give them some extra time with the giveExtraTime() function&lt;br /&gt;
** Game progression is implemented (getGameProgression() in php)&lt;br /&gt;
** Zombie turn is implemented (zombieTurn() in php). Note: it can only be tested if you explicitly click on the quit button to create a zombie. If you are expelled it does not generated a Zombie.&lt;br /&gt;
** You have defined and implemented some meaningful statistics for your game (i.e. total points, point from source A, B, C...)&lt;br /&gt;
** Game has meaningful notification messages (but don&#039;t overkill it, more user logs will slow down the loading)&lt;br /&gt;
** You implemented tiebreaking (using aux score field) and updated tiebreaker description in meta-data&lt;br /&gt;
* Client side&lt;br /&gt;
** Please check that you use ajaxcall only on player actions and never programmatically. Otherwise, your code will very likely create race conditions resulting in deadlocks or other errors.&lt;br /&gt;
* Special testing&lt;br /&gt;
** Game is tested with spectator (non player observer): change the testuser in the URL to see the game as another user (same URL as when clicking on red arrow). As a spectator, you should be able to see the game as if you were sitting beside of the players at a real table: all public information, no private information.&lt;br /&gt;
** Game is tested with in-game replay from last move feature (by clicking on notification log items)&lt;br /&gt;
** Game works in Chrome and Firefox browsers at least. Also very recommended to test in IE 11 and Edge.&lt;br /&gt;
** Game works on mobile device (if you don&#039;t have mobile device to test at least test in Chrome with smaller screen, they have a mode for that)&lt;br /&gt;
** Test your game in realtime mode. Usually people will run out of time if you use default times unless you add call giveExtraTime($active_player_id) before each turn&lt;br /&gt;
** Test your game in 3D mode (if it makes sense; 3D mode can also be disabled through the &#039;enable_3d&#039; parameter for gameinfos.inc.php, but if it &amp;quot;mostly works&amp;quot;, it can be nice to keep it activated even if 2D is more appropriate for the game, just because it&#039;s fun to look at)&lt;br /&gt;
** Check your game against the waiting screen, otherwise game start can fail. See [[Practical_debugging#Debugging_an_issue_with_the_waiting_screen]]&lt;br /&gt;
* Cleanup&lt;br /&gt;
** Remove all extra console.log from your js code&lt;br /&gt;
** Remove all unnecessary debug logging from your php code&lt;br /&gt;
** Copyright headers in all source files have your name&lt;br /&gt;
* User Interface&lt;br /&gt;
** Review BGA UI design Guidelines [[BGA_Studio_Guidelines]]&lt;br /&gt;
** Check all your English messages for proper use of punctuation, capitalization, usage of present tense in notification (not past) and gender neutrality. See [[Translations]] for English rules.&lt;br /&gt;
** If the elements in your game zone don&#039;t occupy all the available horizontal space, &#039;&#039;&#039;they should be centered&#039;&#039;&#039;.&lt;br /&gt;
** If your game elements become blurry or pixellated when using the browser zoom, you may want to consider [[Game_art:_img_directory#Use_background-size | higher resolution images with background-size]]&lt;br /&gt;
** Non-self explanatory graphic elements should have tooltips&lt;br /&gt;
** If graphic elements appear in notification log they should have titles (i.e. title attribute of div) so can be read in non rendered form (i.e. as text only)&lt;br /&gt;
** Strings in your source code are ready for translation. See [[Translations]]. You can generate dummy translations for checking that everything is ready for translation from your &amp;quot;Manage game&amp;quot; page.&lt;br /&gt;
** A prefix for example a trigram for your game that you append to all the css classes to avoid namespace conflicts, i.e. vla_selected vs selected&lt;br /&gt;
** If you are looking for advice on design and some 3rd party testing you can post a message on the developers forum, and ask other developers, there are a lot of people who will gladly do it.&lt;br /&gt;
* Finally move to Alpha status&lt;br /&gt;
** If possible (meaning if there is not already a project with that name) copy your project to a new project &#039;&#039;&#039;matching exactly the name of the game&#039;&#039;&#039; (no prefix or suffix). If not possible move on to the next steps, admin will have to retrieve the other project and overwrite it.&lt;br /&gt;
** Create a build for your game from the &amp;quot;manage game&amp;quot; page (using the &#039;&#039;&#039;Build a new release version&#039;&#039;&#039; section) and check the log to make sure that everything builds fine (after a successful build, you should see a new version in &amp;quot;Versions available for production&amp;quot;).&lt;br /&gt;
** Send an e-mail to studio@boardgamearena.com asking to move the project forward for review. You cannot deploy yourself from the &amp;quot;manage game&amp;quot; page until a first deploy has been done by the admins. Please note that &#039;&#039;&#039;everything must be OK on the licensing&#039;&#039;&#039; side for a project to be moved to production.&lt;br /&gt;
** When admins publish (push to alpha) they will send an email to the developer with all relevant information about the next steps.&lt;/div&gt;</summary>
		<author><name>User Already Exists</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Translation_guidelines&amp;diff=8451</id>
		<title>Translation guidelines</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Translation_guidelines&amp;diff=8451"/>
		<updated>2021-06-05T21:48:32Z</updated>

		<summary type="html">&lt;p&gt;User Already Exists: /* When will the site be made available in a new language it is being translated into? */ typo&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;border:3px solid red; background-color: #FF6666; color: white; font-weight:normal; padding: 1em;&amp;quot;&amp;gt;&lt;br /&gt;
This content is deprecated. Please refer to the up to date &amp;quot;Frequently Asked Questions&amp;quot; page at this address: https://boardgamearena.com/#!faq&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The [http://en.boardgamearena.com/#!translationhq collaborative translation system] is meant to make it possible to translate Board Game Arena into any language, in order to enable more people to discover and play board games, even when not knowing English or French. For example, if you want to play &#039;Dragonheart&#039; with your 10-year-old nephew and he doesn&#039;t speak English yet, no problem! Just help us translate Board Game Arena into your language!&lt;br /&gt;
&lt;br /&gt;
== What can be translated? ==&lt;br /&gt;
&lt;br /&gt;
Every string of text for the main site interface and for the games&#039; interfaces are &#039;internationalized&#039; and can be translated.&lt;br /&gt;
For now, forum posts and articles of the website (such as this one), cannot be translated. Maybe sometime later...&lt;br /&gt;
&lt;br /&gt;
== Who should translate? ==&lt;br /&gt;
&lt;br /&gt;
This is important: only translate text into a given language if you are a native speaker of the language.&lt;br /&gt;
When translating a game, the translator should know the game thoroughly and if possible have a box and rulebook of the game in the destination language to check for consistency. Translators should take into account the level of language and the formal/informal pronominal rules usual for the gaming audience of their country.&lt;br /&gt;
&lt;br /&gt;
The source/reference language for translation is English, since the site and games development is made in English. &lt;br /&gt;
&lt;br /&gt;
English is not necessarily the mother tongue of all developers, so the English strings are open for review and correction by native English speakers under the same conditions as the other languages, with a warning indicating that the change affects the source language and asking for confirmation.&lt;br /&gt;
&lt;br /&gt;
== About context ==&lt;br /&gt;
&lt;br /&gt;
Some strings can be translated differently depending upon the context. When this is the case, you should use the most obvious translation. Then when the site has been released in your language, native speakers will spot incorrect forms (if any) while playing and be able to correct them.&lt;br /&gt;
&lt;br /&gt;
Also, you can ask us for context in the [http://forum.boardgamearena.com/viewforum.php?f=11 translation forum] (in English or in French), and we will try to look it up and provide the information.&lt;br /&gt;
&lt;br /&gt;
== When will the site be made available in a new language it is being translated into? ==&lt;br /&gt;
&lt;br /&gt;
As soon as a sufficient number of the strings have been translated into the new language in order for the site to make sense in that language, the Board Game Area team will make the site available in the language.&lt;br /&gt;
&lt;br /&gt;
== I fixed some translations, but they don&#039;t appear to have changed on the site ==&lt;br /&gt;
&lt;br /&gt;
Translation files are updated nightly, so you just have to wait till tomorrow for your changes to appear on the site.&lt;br /&gt;
&lt;br /&gt;
== How long will it be possible to change the translations? ==&lt;br /&gt;
&lt;br /&gt;
The first translations may not be perfect (as explained in the &#039;about context&#039; section).&lt;br /&gt;
So they can be modified until they are &#039;validated&#039;. Validation occurs when a translation has not been modified for 30 days straight. It is then considered stable and valid (golden icon) and cannot be changed anymore.&lt;br /&gt;
&lt;br /&gt;
== Is there some reward for translating? ==&lt;br /&gt;
&lt;br /&gt;
Yes! Every translator that gets 100 translations validated (golden icon) will get one free month of &#039;Board Game Arena Club&#039; membership (and one more month for every batch of 100 new translations validated).&lt;br /&gt;
&lt;br /&gt;
This is of course only a symbolic gesture of thanks for people participating in making BGA accessible to more and more people. The possibility to enjoy board games with people from many countries is the greatest reward of all!&lt;br /&gt;
&lt;br /&gt;
== Translation tips ==&lt;br /&gt;
&lt;br /&gt;
* Use the &#039;TAB&#039; key to go from one text box to another. This is easier than clicking.&lt;br /&gt;
&lt;br /&gt;
* Strings such as ${SOMETHING}, %SOMETHING, &amp;lt;SOMETHING&amp;gt; are markup strings for formatting or substituting text and must be left as is. Their position in the overall string can be changed as appropriate in a given language (for example for pronouns such as ${you}).&lt;br /&gt;
&lt;br /&gt;
* When in doubt, leave a comment for the next translator.&lt;br /&gt;
&lt;br /&gt;
* When you fix someone&#039;s translation, leave a comment if the reason for the change is not obvious.&lt;br /&gt;
&lt;br /&gt;
* When the translation can depend on context which is not explicit, go with the most straightforward translation. If it is not correct, it will be spotted and fixed later by native speakers while playing.&lt;/div&gt;</summary>
		<author><name>User Already Exists</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Game_interface_logic:_Game.js&amp;diff=8359</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=8359"/>
		<updated>2021-05-26T19:19:54Z</updated>

		<summary type="html">&lt;p&gt;User Already Exists: /* Confirmation dialog */ grammar&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 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;
&lt;br /&gt;
== File structure ==&lt;br /&gt;
&lt;br /&gt;
The details of how the file is structured are described below with comments on 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;
&lt;br /&gt;
;onEnteringState(stateName, args)&lt;br /&gt;
This method is called each time we are entering into 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 arg* method use args.args.&lt;br /&gt;
Typically you would do something only for active player, using this.isCurrentPlayerActive() check.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Warning&#039;&#039;&#039;: for multipleactiveplayer states:&lt;br /&gt;
the active players are NOT actives yet so you must use onUpdateActionButtons to perform the client side operation which depends on a player active/unactive status.&lt;br /&gt;
If you are doing initialization of some structure which do not depend on active player, you can just replace	&lt;br /&gt;
  if (this.isCurrentPlayerActive()) {&lt;br /&gt;
into&lt;br /&gt;
  if (!this.isSpectator) {&lt;br /&gt;
for the main switch in that method.&lt;br /&gt;
&lt;br /&gt;
;onLeavingState(stateName)&lt;br /&gt;
This method is called each time we are leaving a game state.&lt;br /&gt;
You can use this method to perform some user interface changes at this moment.&lt;br /&gt;
&lt;br /&gt;
;onUpdateActionButtons(stateName, args)&lt;br /&gt;
In this method you can manage &amp;quot;action buttons&amp;quot; that are displayed in the action status bar.&lt;br /&gt;
To access state arguments passed via calling arg* method use args parameter. Note: args can be null! For game states and when you don&#039;t supply state args function it is null.&lt;br /&gt;
This method is called when active or multiactive player changes. In 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 call would depends on either you get into that from transition 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#Diffrence_between_Single_active_and_Multi_active_states]]&lt;br /&gt;
&lt;br /&gt;
== General tips ==&lt;br /&gt;
&lt;br /&gt;
; this.player_id&lt;br /&gt;
: ID of the player on whose browser the code is running.&lt;br /&gt;
&lt;br /&gt;
; this.isSpectator&lt;br /&gt;
: Flag set to true if the user at the table is a spectator (not a player).&lt;br /&gt;
: Note: This is a variable, not a function.&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;
; this.gamedatas&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. (Most of the time this is unnecessary).&lt;br /&gt;
&lt;br /&gt;
; this.isCurrentPlayerActive()&lt;br /&gt;
: Returns true if the player on whose browser the code is running is currently active (it&#039;s his turn to play).&lt;br /&gt;
&lt;br /&gt;
; this.getActivePlayerId()&lt;br /&gt;
: Return the ID of the active player, or null if we are not in an &amp;quot;activeplayer&amp;quot; type state.&lt;br /&gt;
&lt;br /&gt;
; this.getActivePlayers()&lt;br /&gt;
: Return an array with the IDs of players who are currently active (or an empty array if there are none).&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;
; typeof g_replayFrom != &#039;undefined&#039;&lt;br /&gt;
: 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;
; 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;
---&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:&lt;br /&gt;
&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;
== 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 (before July 2020) ==&lt;br /&gt;
&lt;br /&gt;
For performance reasons, when deploying a game the js code is minimized using ShrinkSafe (based on ECMASCRIPT version 3). Some advanced syntax may not be compatible with this process. In particular:&lt;br /&gt;
* You should not use reserved keywords from the javascript language as variables.&lt;br /&gt;
* You should not declare default argument values in function declarations. The following syntax is invalid for ShrinkSafe: &#039;&#039;&#039;function myFunc(requiredArg, optionalArg = &#039;defaultValue&#039;) {}&#039;&#039;&#039;&lt;br /&gt;
* You should not use &#039;&#039;&#039;let&#039;&#039;&#039; or &#039;&#039;&#039;const&#039;&#039;&#039; to declare variables.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Tip:&#039;&#039;&#039; a developer encountering some problems with this has successfully used [http://plugins.netbeans.org/plugin/58580/jshint JSHint] on NetBeans to evaluate code to make it compatible for ECMAScript 3. With the plugin installed, set the below options in &#039;&#039;&#039;.jshintrc&#039;&#039;&#039; file, and then open &#039;&#039;&#039;Action Items&#039;&#039;&#039; window (in NetBeans):&amp;lt;pre&amp;gt;{ &amp;quot;maxerr&amp;quot;: 999, &amp;quot;esversion&amp;quot;: 3 }&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Tip:&#039;&#039;&#039; some online tools also allow to convert between different versions of javascript, such as https://www.typescriptlang.org/play or https://babeljs.io/ or https://extendsclass.com/javascript-fiddle.html&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 and manipulating the DOM ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;$(&#039;some_html_element_id&#039;)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The $() function is used to get an HTML element using its &amp;quot;id&amp;quot; attribute.&lt;br /&gt;
&lt;br /&gt;
Example 1: modify the content of a &amp;quot;span&amp;quot; element:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
In your HTML code:&lt;br /&gt;
   &amp;lt;span id=&amp;quot;a_value_in_the_game_interface&amp;quot;&amp;gt;1234&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In your Javascript code:&lt;br /&gt;
   $(&#039;a_value_in_the_game_interface&#039;).innerHTML = &amp;quot;9999&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: $() is the standard method to access some HTML element with 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;
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;dojo.style&#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: you must always use dojo.style to modify the CSS properties of HTML elements.&lt;br /&gt;
&lt;br /&gt;
Note²: if you have to modify several CSS properties of an element, or if you have a complex CSS transformation to do, you should consider using dojo.addClass/dojo.removeClass (see below).&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;
&#039;&#039;&#039;dojo.addClass&#039;&#039;&#039;, &#039;&#039;&#039;dojo.removeClass&#039;&#039;&#039;, &#039;&#039;&#039;dojo.hasClass&#039;&#039;&#039;, &#039;&#039;&#039;dojo.toggleClass&#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;
Conclusion: We encourage you to use &#039;&#039;&#039;dojo.addClass&#039;&#039;&#039;, &#039;&#039;&#039;dojo.removeClass&#039;&#039;&#039; and &#039;&#039;&#039;dojo.hasClass&#039;&#039;&#039; to make your life easier :)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;dojo.attr&#039;&#039;&#039;&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;
&lt;br /&gt;
&#039;&#039;&#039;dojo.query&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
With dojo.query, you can query a bunch of HTML elements with a single function, with a &amp;quot;CSS selector&amp;quot; style.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     // All elements with class &amp;quot;possibleMove&amp;quot;:&lt;br /&gt;
     var elements = dojo.query( &#039;.possibleMove&#039; );&lt;br /&gt;
&lt;br /&gt;
     // Count number of tokens (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;
&#039;&#039;&#039;dojo.place&#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;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     // Insert your HTML code as a child of a container element&lt;br /&gt;
     dojo.place( &amp;quot;&amp;lt;your html code&amp;gt;&amp;quot;, &amp;quot;your_container_element_id&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
     // Replace the container element with your new html&lt;br /&gt;
     dojo.place( &amp;quot;&amp;lt;your html code&amp;gt;&amp;quot;, &amp;quot;your_container_element_id&amp;quot;, &amp;quot;replace&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The third parameter of dojo.place can take various interesting values:&lt;br /&gt;
&lt;br /&gt;
&amp;quot;replace&amp;quot; : (see description above).&lt;br /&gt;
&lt;br /&gt;
&amp;quot;first&amp;quot; : Places the node as a child of the reference node. The node is placed as the first child.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;last&amp;quot; (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;
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;dojo.empty&#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&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Remove the element&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&#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;
&#039;&#039;&#039;addStyleToClass: function( cssClassName, cssProperty, propertyValue )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Same as dojo.style(), but for all the nodes set with the specified cssClassName&lt;br /&gt;
&lt;br /&gt;
=== Animations ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Dojo Animations&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
BGA animations is based on Dojo Animation ([http://dojotoolkit.org/documentation/tutorials/1.8/animation/ see tutorial here]).&lt;br /&gt;
&lt;br /&gt;
However, most of the time, you can just use methods below, which are built on top of Dojo Animation.&lt;br /&gt;
&lt;br /&gt;
Note: one interesting method from Dojo that could be useful from time to time is &amp;quot;Dojo.Animation&amp;quot;. It allows you to make any CSS property &amp;quot;slide&amp;quot; from one value to another.&lt;br /&gt;
&lt;br /&gt;
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;
&#039;&#039;&#039;this.slideToObject( mobile_obj, target_obj, duration, delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You can use slideToObject to &amp;quot;slide&amp;quot; an element to a target position.&lt;br /&gt;
&lt;br /&gt;
Sliding element on the game area is the recommended and the most used way to animate your game interface. Using slides allow players to figure out what is happening on the game, as if they were playing with the real boardgame.&lt;br /&gt;
&lt;br /&gt;
The parameters are:&lt;br /&gt;
* mobile_obj: the ID of the object to move. This object must be &amp;quot;relative&amp;quot; or &amp;quot;absolute&amp;quot; positioned.&lt;br /&gt;
* target_obj: the ID of the target object. This object must be &amp;quot;relative&amp;quot; or &amp;quot;absolute&amp;quot; positioned. Note that it is not mandatory that mobile_obj and target_obj have the same size. If their size are different, the system slides the center of mobile_obj to the center of target_obj.&lt;br /&gt;
* duration: (optional) defines the duration in millisecond of the slide. The default is 500 milliseconds.&lt;br /&gt;
* delay: (optional). If you defines a delay, the slide will start only after this delay. This is particularly useful when you want to slide several object from the same position to the same position: you can give a 0ms delay to the first object, a 100ms delay to the second one, a 200ms delay to the third one, ... this way they won&#039;t be superposed during the slide.&lt;br /&gt;
&lt;br /&gt;
BE CAREFUL: The method returns an dojo.fx animation, so you can combine it with other animation if you want to. It means that you have to call the &amp;quot;play()&amp;quot; method, otherwise the animation WON&#039;T START.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   this.slideToObject( &amp;quot;some_token&amp;quot;, &amp;quot;some_place_on_board&amp;quot; ).play();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.slideToObjectPos( mobile_obj, target_obj, target_x, target_y, duration, delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This method does exactly the same as &amp;quot;slideToObject&amp;quot;, except than you can specify some (x,y) coordinates. This way, &amp;quot;mobile_obj&amp;quot; will slide to the specified x,y position relatively to &amp;quot;target_obj&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Example: slide a token to some place on the board, 10 pixels to the bottom:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   this.slideToObjectPos( &amp;quot;some_token&amp;quot;, &amp;quot;some_place_on_board&amp;quot;, 0, 10 ).play();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.slideTemporaryObject( mobile_obj_html, mobile_obj_parent, from, to, duration, delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This method is useful when you want to slide a temporary HTML object from one place to another. As this object does not exists before the animation and won&#039;t remain after, it could be complex to create this object (with dojo.place), to place it at its origin (with placeOnObject) to slide it (with slideToObject) and to make it disappear at the end.&lt;br /&gt;
&lt;br /&gt;
slideTemporaryObject does all of this for you:&lt;br /&gt;
* mobile_obj_html is a piece of HTML code that represent the object to slide.&lt;br /&gt;
* mobile_obj_parent is the ID of an HTML element of your interface that will be the parent of this temporary HTML object.&lt;br /&gt;
* from is the ID of the origin of the slide.&lt;br /&gt;
* to is the ID of the target of the slide.&lt;br /&gt;
* duration/delay works exactly like in &amp;quot;slideToObject&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
this.slideTemporaryObject( &#039;&amp;lt;div class=&amp;quot;token_icon&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;, &#039;tokens&#039;, &#039;my_origin_div&#039;, &#039;my_target_div&#039; ).play();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.slideToObjectAndDestroy: function( node, to, time, delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This method is a handy shortcut to slide an existing HTML object to some place then destroy it upon arrival. It can be used for example to move a victory token or a card from the board to the player panel to show that the player earns it, then destroy it when we don&#039;t need to keep it visible on the player panel.&lt;br /&gt;
&lt;br /&gt;
It works the same as this.slideToObject and takes the same arguments, but it starts the animation. &lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
this.slideToObjectAndDestroy( &amp;quot;some_token&amp;quot;, &amp;quot;some_place_on_board&amp;quot;, 1000, 0 );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.fadeOutAndDestroy( node, duration, delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This function fade out the target HTML node, then destroy it. Its starts the animation.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   this.fadeOutAndDestroy( &amp;quot;a_card_that_must_disappear&amp;quot; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
CAREFUL: the HTML node still exists until during few milliseconds, until the fadeOut has been completed.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Rotating elements&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You can check here [http://jimfulton.info/demos/dojo-animated-rotate.html an example of use] of Dojo to make an element rotate.&lt;br /&gt;
&lt;br /&gt;
This example combines &amp;quot;Dojo.Animation&amp;quot; method and a CSS3 property that allow you to rotate the element.&lt;br /&gt;
&lt;br /&gt;
IMPORTANT: to asses browser compatibility, you must select the CSS property to use just like in the example (see sourcecode below):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        var transform;&lt;br /&gt;
        dojo.forEach(&lt;br /&gt;
            [&#039;transform&#039;, &#039;WebkitTransform&#039;, &#039;msTransform&#039;,&lt;br /&gt;
             &#039;MozTransform&#039;, &#039;OTransform&#039;],&lt;br /&gt;
            function (name) {&lt;br /&gt;
                if (typeof dojo.body().style[name] != &#039;undefined&#039;) {&lt;br /&gt;
                    transform = name;&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        // ... and then use &amp;quot;transform&amp;quot; as the name of your CSS property for rotation&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: This wiki was probably written 10 years ago - now all modern broser support &#039;transform&#039; so just ignore this and use transform.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Animation Callbacks&#039;&#039;&#039;&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.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
var animation_id = this.slideToObject( mobile_obj, target_obj, duration, delay );&lt;br /&gt;
dojo.connect(animation_id, &#039;onEnd&#039;, dojo.hitch(this, &#039;callback_function&#039;, parameters));&lt;br /&gt;
animation_id.play();&lt;br /&gt;
&lt;br /&gt;
…&lt;br /&gt;
&lt;br /&gt;
callback_function: function(params) {&lt;br /&gt;
   // this will be called after the animation ends&lt;br /&gt;
},&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;
=== Moving elements ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.placeOnObject( mobile_obj, target_obj )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
placeOnObject works exactly like &amp;quot;slideToObject&amp;quot;, except that the effect is immediate.&lt;br /&gt;
&lt;br /&gt;
This is not really an animation, but placeOnObject is frequently used before starting an animation.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  // (We just created an object &amp;quot;my_new_token&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
  // Place the new token on current player board&lt;br /&gt;
  this.placeOnObject( &amp;quot;my_new_token&amp;quot;, &amp;quot;overall_player_board_&amp;quot;+this.player_id );&lt;br /&gt;
  &lt;br /&gt;
  // Then slide it to its position on the board&lt;br /&gt;
  this.slideToObject( &amp;quot;my_new_token&amp;quot;, &amp;quot;a_place_on_board&amp;quot; ).play();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.placeOnObjectPos( mobile_obj, target_obj, target_x, target_y )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This method works exactly like placeOnObject, except than you can specify some (x,y) coordinates. This way, &amp;quot;mobile_obj&amp;quot; will be placed to the specified x,y position relatively to &amp;quot;target_obj&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.attachToNewParent( mobile_obj, target_obj )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
With this method, you change the HTML parent of &amp;quot;mobile_obj&amp;quot; element. &amp;quot;target_obj&amp;quot; is the new parent of this element. The beauty of &lt;br /&gt;
attachToNewParent is that the mobile_obj element DOES NOT MOVE during this process.&lt;br /&gt;
&lt;br /&gt;
Note: what happens is that the method calculate a relative position of mobile_obj to make sure it does not move after the HTML parent changes.&lt;br /&gt;
&lt;br /&gt;
Why using this method?&lt;br /&gt;
&lt;br /&gt;
Changing the HTML parent of an element can be useful for the following reasons:&lt;br /&gt;
* When the HTML parent moves, all its child are moving with them. If some game elements is no more linked with a parent HTML object, you may want to attach it to another place.&lt;br /&gt;
* The z_order (vertical order of display) depends on the position in the DOM, so you may need to change the parent of some game elements when they are moving in your game area.&lt;br /&gt;
&lt;br /&gt;
CAREFUL: this function destroys original object and places a clone onto a new parent, this will break all references to this HTML element (ex: dojo.connect).&lt;br /&gt;
&lt;br /&gt;
== Players input ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;dojo.connect&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Used to associate a player event with one of your notification 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;
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: the methods described here are the only correct ways to associate a player input event to your code, and you should not use anything else.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.connect&#039;&#039;&#039;&lt;br /&gt;
function(element, event, handler)&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;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.connectClass&#039;&#039;&#039;&lt;br /&gt;
function( cssClassName, event, handler )&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;
&#039;&#039;&#039;this.disconnect&#039;&#039;&#039;&lt;br /&gt;
function( element, event )&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;
&#039;&#039;&#039;this.disconnectAll&#039;&#039;&#039;&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;
&#039;&#039;&#039;this.checkAction&#039;&#039;&#039;&lt;br /&gt;
function( action, nomessage )&lt;br /&gt;
&lt;br /&gt;
Check if player can do the specified action by taking into account:&lt;br /&gt;
* current game state&lt;br /&gt;
* interface locking (a player can&#039;t do any action if an action is already in progress)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
return true if action is authorized (i.e: the action is listed as a &amp;quot;possibleaction&amp;quot; in current game state).&lt;br /&gt;
&lt;br /&gt;
return false and display an error message if not authorized (display no message if nomessage parameter is true). &lt;br /&gt;
The displayed error message could be either &amp;quot;This move is not allowed at this moment&amp;quot; or &amp;quot;An action is already in progress&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  function onClickOnGameElement( evt )  {&lt;br /&gt;
     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;this.checkPossibleActions&#039;&#039;&#039;&lt;br /&gt;
function( action, nomessage )&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. &lt;br /&gt;
&lt;br /&gt;
Check if player can do the specified action by taking into account:&lt;br /&gt;
* current game state&lt;br /&gt;
* interface locking (a player can&#039;t do any action if an action is already in progress)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.ajaxcall( url, parameters, obj_callback, callback, callback_error )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This method must be used to send a player input to the game server. &#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.&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.&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: a function to trigger when the server returns and everything went fine (not used, as all data handling is done via notifications).&lt;br /&gt;
* callback_error: (optional and rarely used) a function to trigger when the server returns an error.  if no error this function is called with parameter value false.&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
this.ajaxcall( &#039;/mygame/mygame/myaction.html&#039;, { lock: true, &lt;br /&gt;
   arg1: myarg1, &lt;br /&gt;
   arg2: myarg2, &lt;br /&gt;
   ...&lt;br /&gt;
}, this, function( result ) {&lt;br /&gt;
   // Do some stuff after a successful call&lt;br /&gt;
   // NB : usually not needed as changes must be handled by notifications&lt;br /&gt;
   // You should NOT modify the interface in a callback or it will most likely break the framework replays (or make it inaccurate)&lt;br /&gt;
   // You should NOT make another ajaxcall in a callback in order not to create race conditions&lt;br /&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,// &lt;br /&gt;
					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;this.isInterfaceLocked()&#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.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.addActionButton( id, label, method, (opt)destination, (opt)blinking, (opt)color )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You can use this method to add an action button in the main action status bar.&lt;br /&gt;
&lt;br /&gt;
Arguments:&lt;br /&gt;
* id: an element ID that should be unique in your HTML DOM document.&lt;br /&gt;
* label: the text of the button. Should be translatable (use _() function).&lt;br /&gt;
* method: the name of your method that must be triggered when the player clicks on this button.&lt;br /&gt;
* destination (optional): deprecated, do not use this. Use &#039;&#039;&#039;null&#039;&#039;&#039; as value if you need to specify other arguments.&lt;br /&gt;
* blinking (optional): if set to &#039;&#039;&#039;true&#039;&#039;&#039;, the button is going blink to catch player&#039;s attention. Please don&#039;t abuse of blinking button.&lt;br /&gt;
* color: could be &#039;&#039;&#039;blue&#039;&#039;&#039; (default), &#039;&#039;&#039;red&#039;&#039;&#039; or &#039;&#039;&#039;gray&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
You should only use this method in your &amp;quot;onUpdateActionButtons&amp;quot; method. Usually, you use it like this (from Hearts example):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        onUpdateActionButtons: function( stateName, args ) {&lt;br /&gt;
                      &lt;br /&gt;
            if (this.isCurrentPlayerActive()) {            &lt;br /&gt;
                switch( stateName ) {&lt;br /&gt;
                case &#039;giveCards&#039;:&lt;br /&gt;
                    this.addActionButton( &#039;giveCards_button&#039;, _(&#039;Give selected cards&#039;), &#039;onGiveCards&#039; ); &lt;br /&gt;
                    break;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        },   &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the example above, we are adding a &amp;quot;Give selected cards&amp;quot; button in the case we are on game state &amp;quot;giveCards&amp;quot;. When player clicks on this button, it triggers our &amp;quot;onGiveCards&amp;quot; method.&lt;br /&gt;
&lt;br /&gt;
Example using blinking red button:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     this.addActionButton( &#039;commit_button&#039;, _(&#039;Confirm&#039;), &#039;onConfirm&#039;, null, true, &#039;red&#039;); &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: at least in studio example above will make button huge, because it sets it display of blinking things to &#039;&#039;&#039;block&#039;&#039;&#039;, &lt;br /&gt;
if you don&#039;t like it you have to change css display value&lt;br /&gt;
of the button to inline-block (the id of the button is the first argument, i.e &#039;commit_button&#039; in example above)&lt;br /&gt;
&lt;br /&gt;
== Translations ==&lt;br /&gt;
&lt;br /&gt;
See [[Translations]]&lt;br /&gt;
&lt;br /&gt;
== Notifications ==&lt;br /&gt;
&lt;br /&gt;
When something happens on the server side, your game interface Javascript logic received a notification.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s how you can handle these notifications on the client side.&lt;br /&gt;
&lt;br /&gt;
=== Subscribe to notifications ===&lt;br /&gt;
&lt;br /&gt;
Your Javascript &amp;quot;setupNotifications&amp;quot; method is the place where you can subscribe to notifications from your PHP code.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s how you associate one of your Javascript method to a notification &amp;quot;playDisc&amp;quot; (from Reversi example):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   // In setupNotifications method:&lt;br /&gt;
   dojo.subscribe( &#039;playDisc&#039;, this, &amp;quot;notif_playDisc&amp;quot; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: the &amp;quot;playDisc&amp;quot; corresponds to the name of the notification you define it in your PHP code, in your &amp;quot;notifyAllPlayers&amp;quot; or &amp;quot;notifyPlayer&amp;quot; method.&lt;br /&gt;
&lt;br /&gt;
Then, you have to define your &amp;quot;notif_playDisc&amp;quot; method:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        notif_playDisc: function( notif )&lt;br /&gt;
        {&lt;br /&gt;
            // Remove current possible moves (makes the board more clear)&lt;br /&gt;
            dojo.query( &#039;.possibleMove&#039; ).removeClass( &#039;possibleMove&#039; );        &lt;br /&gt;
        &lt;br /&gt;
            this.addDiscOnBoard( notif.args.x, notif.args.y, notif.args.player_id );&lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In a notification handler like our &amp;quot;notif_playDisc&amp;quot; method, you can access to all notifications arguments with &amp;quot;notif.args&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    // If you did this on PHP side:&lt;br /&gt;
    self::notifyAllPlayers( &amp;quot;myNotification&amp;quot;, &#039;&#039;, array( &amp;quot;myArgument&amp;quot; =&amp;gt; 3 ) );&lt;br /&gt;
&lt;br /&gt;
    // On Javascript side, you can access the &amp;quot;myArgument&amp;quot; like this:&lt;br /&gt;
    notif_myNotification: function( notif )&lt;br /&gt;
    {&lt;br /&gt;
       alert( &amp;quot;myArgument = &amp;quot; + notif.args.myArgument );&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Synchronous notifications ===&lt;br /&gt;
&lt;br /&gt;
When several notifications are received by your game interface, these notifications are processed immediately, one after the other, in the same exact order they have been generated in your PHP game logic.&lt;br /&gt;
&lt;br /&gt;
However, sometimes, you need to give some time to the players to figure out what happened on the game before jumping to the next notification. Indeed, in many games, they are a lot of automatic actions, and the computer is going to resolve all these actions very fast if you don&#039;t tell it not to do so.&lt;br /&gt;
&lt;br /&gt;
As an example, for Reversi, when someone is playing a disc, we want to wait 500 milliseconds before doing anything else in order the opponent player can figure out what move has been played.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s how we do this, right after our subscription:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    dojo.subscribe( &#039;playDisc&#039;, this, &amp;quot;notif_playDisc&amp;quot; );&lt;br /&gt;
    this.notifqueue.setSynchronous( &#039;playDisc&#039;, 500 );   // Wait 500 milliseconds after executing the playDisc handler&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
-----&lt;br /&gt;
&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;
=== 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. Similar to setting a synchronous notification above, you can set up a check whether a notification should be ignored:&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;
&#039;&#039;&#039;setIgnoreNotificationCheck(notificationId, predicate)&#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;
* notificationId: before dispatching any notification of this type, the framework will call predicate to check whether notification should be ignored&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;
NOTE: You can think that it could be possible to send generic notification to all other players with notifyAllPlayers and it will seem to work. The problem is that table spectators would miss this notification and their user interface (and game log) wouldn&#039;t be updated.&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 preserve it as explained [[Main_game_logic:_yourgamename.game.php#Notify_players|here]].&lt;br /&gt;
&lt;br /&gt;
=== Pre-defined notification types ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;tableWindow&#039;&#039;&#039; - This defines notification to display [[Game_interface_logic:_yourgamename.js#Scoring_dialogs|Scoring Dialogs]], see below.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;message&#039;&#039;&#039; - This defines notification that shows on players log and have no other effect&lt;br /&gt;
&lt;br /&gt;
   // You can call this on php side without doing anything on client side&lt;br /&gt;
    self::notifyAllPlayers( &#039;message&#039;, &#039;hello&#039;, [] );&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;
== Tooltips ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.addTooltip( nodeId, _( helpString ), _( actionString ), delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Add a simple text tooltip to the DOM node.&lt;br /&gt;
&lt;br /&gt;
Specify &#039;helpString&#039; to display some information about &amp;quot;what is this game element?&amp;quot;.&lt;br /&gt;
Specify &#039;actionString&#039; to display some information about &amp;quot;what happens when I click on this element?&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
You must specify both helpString and actionString. Most of the time, you should use only one and specify a void string (&amp;quot;&amp;quot;) for the other one.&lt;br /&gt;
&lt;br /&gt;
Usually, _() must be used for the text to be marked for translation.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Delay&amp;quot; is an optional parameter. Usually, it is primarily used to specify a zero delay for some game element when the tooltip gives really important information for the game - but remember: no essential information must be placed in tooltips as they won&#039;t be displayed in some 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;
&#039;&#039;&#039;this.addTooltipHtml( nodeId, html, delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Add an HTML tooltip to the DOM node (for more elaborate content such as presenting a bigger version of a card).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.addTooltipToClass( cssClass, _( helpString ), _( actionString ), delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Add a simple text tooltip to all the DOM nodes set with this cssClass. &lt;br /&gt;
&lt;br /&gt;
IMPORTANT: all concerned nodes must have IDs to get tooltips.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.addTooltipHtmlToClass( cssClass, html, delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Add an HTML tooltip to to all the DOM nodes set with this cssClass (for more elaborate content such as presenting a bigger version of a card).&lt;br /&gt;
&lt;br /&gt;
IMPORTANT: all concerned nodes must have IDs to get tooltips&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.removeTooltip( nodeId )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Remove a tooltip from the DOM node.&lt;br /&gt;
&lt;br /&gt;
== Dialogs, warning messages, confirmation dialogs, ... ==&lt;br /&gt;
&lt;br /&gt;
=== Warning messages ===&lt;br /&gt;
&lt;br /&gt;
Sometimes, there is something important that is happening 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;this.showMessage( msg, type )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
showMessage shows a message in a big rectangular area on the top of the screen of the current player.&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;msg&amp;quot; is the string to display. It should be translated.&lt;br /&gt;
* &amp;quot;type&amp;quot; can be set to &amp;quot;info&amp;quot;, &amp;quot;error&amp;quot;, or &amp;quot;only_to_log&amp;quot;. If set to &amp;quot;info&amp;quot;, the message will be an informative message on a white background. If set to &amp;quot;error&amp;quot;, the message will be an error message on a red background. 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;
&lt;br /&gt;
Important: the normal way to inform players about the progression of the game is the game log. &amp;quot;showMessage&amp;quot; is intrusive and should not be used often.&lt;br /&gt;
&lt;br /&gt;
=== Confirmation dialog ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;confirmationDialog( message, yesHandler, noHandler )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When an important action with a lot of consequences is triggered by the player, you may want to propose a confirmation dialog.&lt;br /&gt;
&lt;br /&gt;
CAREFUL: the general 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;
How to display a confirmation dialog:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        this.confirmationDialog( _(&#039;Are you sure you want to bake the pie?&#039;), dojo.hitch( this, function() {&lt;br /&gt;
            this.bakeThePie();&lt;br /&gt;
        } ) ); &lt;br /&gt;
        return; // nothing should be called or done after calling this, all action must be done in the handler  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Multiple choice dialog ===&lt;br /&gt;
You can use this dialog to give user a choice with small amount of options:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        var keys = [1,5,10];&lt;br /&gt;
        this.multipleChoiceDialog(&lt;br /&gt;
          _(&#039;How many bugs to fix?&#039;), keys, &lt;br /&gt;
            dojo.hitch(this, function(choice) {&lt;br /&gt;
                            var bugchoice = keys[choice];&lt;br /&gt;
                            console.log(&#039;dialog callback with &#039;+bugchoice);&lt;br /&gt;
                            this.ajaxcall( &#039;/mygame/mygame/fixBugs.html&#039;, { bugs: bugchoice}, this, function( result ) {} );                        }));&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Dialogs ===&lt;br /&gt;
&lt;br /&gt;
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;
&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, function(evt){&lt;br /&gt;
                evt.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( function() { ... } );&lt;br /&gt;
&lt;br /&gt;
=== Scoring dialogs ===&lt;br /&gt;
&lt;br /&gt;
Sometimes at the end of a round you want to display a big table that details the points wins in each section of the game.&lt;br /&gt;
&lt;br /&gt;
Example: in Hearts game, we display at the end of each round the number of &amp;quot;heart&amp;quot; cards collected by each player, the player who collected the Queen of Spades, and the total number of points loose by each player.&lt;br /&gt;
&lt;br /&gt;
Scoring dialogs are managed entirely on &#039;&#039;&#039;PHP side&#039;&#039;&#039;, but they are described here as their effects are visible only on client side.&lt;br /&gt;
&lt;br /&gt;
Displaying a scoring dialog is quite simple and is using a special notification type: &amp;quot;tableWindow&amp;quot;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  // on PHP side:&lt;br /&gt;
  $this-&amp;gt;notifyAllPlayers( &amp;quot;tableWindow&amp;quot;, &#039;&#039;, array(&lt;br /&gt;
            &amp;quot;id&amp;quot; =&amp;gt; &#039;finalScoring&#039;,&lt;br /&gt;
            &amp;quot;title&amp;quot; =&amp;gt; clienttranslate(&amp;quot;Title of the scoring dialog&amp;quot;),&lt;br /&gt;
            &amp;quot;table&amp;quot; =&amp;gt; $table&lt;br /&gt;
        ) ); &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;table&amp;quot; argument is a 2 dimensional PHP array that describe the table you want to display, line by line and column by column.&lt;br /&gt;
&lt;br /&gt;
Example: display an 3x3 array of strings&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   $table = array(&lt;br /&gt;
      array( &amp;quot;one&amp;quot;, &amp;quot;two&amp;quot;, &amp;quot;three&amp;quot; ),    // This is my first line&lt;br /&gt;
      array( &amp;quot;four&amp;quot;, &amp;quot;five&amp;quot;, &amp;quot;six&amp;quot; ),    // This is my second line&lt;br /&gt;
      array( &amp;quot;seven&amp;quot;, &amp;quot;height&amp;quot;, &amp;quot;nine&amp;quot; )    // This is my third line&lt;br /&gt;
   );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As you can see above, in each &amp;quot;cell&amp;quot; of your array you can display a simple string value. But you can also display a complex value with a template and associated arguments like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   $table = array(&lt;br /&gt;
      array( &amp;quot;one&amp;quot;, &amp;quot;two&amp;quot;, array( &amp;quot;str&amp;quot; =&amp;gt; clienttranslate(&amp;quot;a string with an ${argument}&amp;quot;), &amp;quot;args&amp;quot; =&amp;gt; array( &#039;argument&#039; =&amp;gt; &#039;argument_value&#039; )  ) ),&lt;br /&gt;
      array( &amp;quot;four&amp;quot;, &amp;quot;five&amp;quot;, &amp;quot;six&amp;quot; ), &lt;br /&gt;
      array( &amp;quot;seven&amp;quot;, &amp;quot;height&amp;quot;, &amp;quot;nine&amp;quot; )&lt;br /&gt;
   );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is especially useful when you want to display player names with colors. Example from &amp;quot;Hearts&amp;quot;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        $firstRow = array( &#039;&#039; );&lt;br /&gt;
        foreach( $players as $player_id =&amp;gt; $player )&lt;br /&gt;
        {&lt;br /&gt;
            $firstRow[] = array( &#039;str&#039; =&amp;gt; &#039;${player_name}&#039;,&lt;br /&gt;
                                 &#039;args&#039; =&amp;gt; array( &#039;player_name&#039; =&amp;gt; $player[&#039;player_name&#039;] ),&lt;br /&gt;
                                 &#039;type&#039; =&amp;gt; &#039;header&#039;&lt;br /&gt;
                               );&lt;br /&gt;
        }&lt;br /&gt;
        $table[] = $firstRow;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also use three extra attributes in the parameter array for the notification:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   $this-&amp;gt;notifyAllPlayers( &amp;quot;tableWindow&amp;quot;, &#039;&#039;, array(&lt;br /&gt;
            &amp;quot;id&amp;quot; =&amp;gt; &#039;finalScoring&#039;,&lt;br /&gt;
            &amp;quot;title&amp;quot; =&amp;gt; clienttranslate(&amp;quot;Title of the scoring dialog&amp;quot;),&lt;br /&gt;
            &amp;quot;table&amp;quot; =&amp;gt; $table,&lt;br /&gt;
            &amp;quot;header&amp;quot; =&amp;gt; array(&#039;str&#039; =&amp;gt; clienttranslate(&#039;Table header with parameter ${number}&#039;),&lt;br /&gt;
                                 &#039;args&#039; =&amp;gt; array( &#039;number&#039; =&amp;gt; 3 ),&lt;br /&gt;
                               ),&lt;br /&gt;
            &amp;quot;footer&amp;quot; =&amp;gt; &#039;&amp;lt;div&amp;gt;Some footer&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
            &amp;quot;closing&amp;quot; =&amp;gt; clienttranslate( &amp;quot;Closing button label&amp;quot; )&lt;br /&gt;
        ) ); &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;header&#039;&#039;&#039;: the content for this parameter will display before the table (also, the html will be parsed and player names will be colored according to the current game colors). &lt;br /&gt;
*&#039;&#039;&#039;footer&#039;&#039;&#039;: the content for this parameter will display after the table (no parsing for coloring the player names)&lt;br /&gt;
*&#039;&#039;&#039;closing&#039;&#039;&#039;: if this parameter is used, a button will be displayed with this label at the bottom of the popup and will allow players to close it (more easily than by clicking the top right &#039;cross&#039; icon).&lt;br /&gt;
&lt;br /&gt;
=== Scoring animated display ===&lt;br /&gt;
&lt;br /&gt;
Sometimes (Terra Mystica final scoring for example), you may want to display a score value over an element to make the scoring easier to follow for the players.&lt;br /&gt;
You can do it with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   this.displayScoring( anchor_id, color, score, duration, offset_x, offset_y );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;anchor_id&#039;&#039;&#039;: ID of the 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;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;duration&#039;&#039;&#039;: animation duration in milliseconds&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. 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;
&lt;br /&gt;
=== Speech bubble ===&lt;br /&gt;
&lt;br /&gt;
For better interactivity in some games (Love Letter for example), you may use comic book style speech bubbles to express the players voices.&lt;br /&gt;
This is done with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   this.showBubble(anchor_id, text, delay, duration, custom_class)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
text - what to put in bubble, can be html actually not just text&lt;br /&gt;
&lt;br /&gt;
delay - in milliseconds is optional (default 0)&lt;br /&gt;
&lt;br /&gt;
duration -  in milliseconds is optional (default 3000)&lt;br /&gt;
&lt;br /&gt;
custom_class - extra class to add to bubble is optional, if you need to override the default bubble style&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;
== 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 &amp;lt;gamename&amp;gt;.js setup() function. However this score must be updated as the game progresses through player notifications (notifs).&lt;br /&gt;
&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;
== Players panels ==&lt;br /&gt;
&lt;br /&gt;
=== Adding stuff to player&#039;s panel ===&lt;br /&gt;
&lt;br /&gt;
At first, create a new &amp;quot;JS template&amp;quot; string in your template (tpl) file:&lt;br /&gt;
&lt;br /&gt;
(from Gomoku example)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
var jstpl_player_board = &#039;\&amp;lt;div class=&amp;quot;cp_board&amp;quot;&amp;gt;\&lt;br /&gt;
    &amp;lt;div id=&amp;quot;stoneicon_p${id}&amp;quot; class=&amp;quot;gmk_stoneicon gmk_stoneicon_${color}&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;span id=&amp;quot;stonecount_p${id}&amp;quot;&amp;gt;0&amp;lt;/span&amp;gt;\&lt;br /&gt;
&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then, you add this piece of code in your JS file to add this template to each player panel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
            // Setting up player boards&lt;br /&gt;
            for( var player_id in gamedatas.players )&lt;br /&gt;
            {&lt;br /&gt;
                var player = gamedatas.players[player_id];&lt;br /&gt;
                         &lt;br /&gt;
                // Setting up players boards if needed&lt;br /&gt;
                var player_board_div = $(&#039;player_board_&#039;+player_id);&lt;br /&gt;
                dojo.place( this.format_block(&#039;jstpl_player_board&#039;, player ), player_board_div );&lt;br /&gt;
            }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Note: the code above is of course from your &amp;quot;setup&amp;quot; function in your Javascript).&lt;br /&gt;
&lt;br /&gt;
Very often, you have to distinguish current player and others players. In this case, you just have to create another JS template (ex: jstpl_otherplayer_board) and use it when &amp;quot;player_id&amp;quot; is different than &amp;quot;this.player_id&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Player&#039;s panel disabling/enabling ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.disablePlayerPanel( player_id )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Disable given player panel (the panel background become gray).&lt;br /&gt;
&lt;br /&gt;
Usually, this is used to signal that this played passes, or will be inactive during a while.&lt;br /&gt;
&lt;br /&gt;
Note that the only effect of this is visual. There are no consequences on the behaviour of the panel itself.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.enablePlayerPanel( player_id )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Enable a player panel that has been disabled before.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.enableAllPlayerPanels()&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Enable all player panels that has been disabled before.&lt;br /&gt;
&lt;br /&gt;
== Image loading ==&lt;br /&gt;
&lt;br /&gt;
See also [[Game_art:_img_directory]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Be careful&#039;&#039;&#039;: by default, ALL images of your img directory are loaded on a player&#039;s browser when he loads the game. For this reason, don&#039;t let in your img directory images that are not useful, otherwise it&#039;s going to slowdown the game load.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;dontPreloadImage( image_file_name )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Using dontPreloadImage, you tell the interface to not preload a specific image in your img directory.&lt;br /&gt;
&lt;br /&gt;
Example of use:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
this.dontPreloadImage( &#039;cards.png&#039; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is particularly useful if for example you have 2 different themes for a game. To accelerate the loading of the game, you can specify to not preload images corresponding to the other theme.&lt;br /&gt;
&lt;br /&gt;
Another example of use: in &amp;quot;Gosu&amp;quot; game with Kamakor extension, you play with 5 sets of cards among 10 available. Cards images are organized by sets, and we only preload the images corresponding to the 5 current sets with &#039;&#039;&#039;ensureSpecificGameImageLoading( image_file_names_array )&#039;&#039;&#039;.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// By default, do not preload anything&lt;br /&gt;
this.dontPreloadImage( &#039;cards.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan1.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan2.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan3.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan4.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan5.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan6.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan7.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan8.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan9.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan10.png&#039; );&lt;br /&gt;
var to_preload = [];&lt;br /&gt;
for( i in this.gamedatas.clans )&lt;br /&gt;
{&lt;br /&gt;
	var clan_id = this.gamedatas.clans[i];&lt;br /&gt;
	to_preload.push( &#039;clan&#039;+clan_id+&#039;.png&#039; );&lt;br /&gt;
}&lt;br /&gt;
if( to_preload.length == 5 )&lt;br /&gt;
{&lt;br /&gt;
	this.ensureSpecificGameImageLoading( to_preload );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; You don&#039;t need to specify to not preload game box images (game_box.png, game_box75.png...) since they are not preloaded by default.&lt;br /&gt;
&lt;br /&gt;
== Other useful stuff ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;dojo.hitch&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
With dojo.hitch, you can create a callback function that will run with your game object context whatever happen.&lt;br /&gt;
&lt;br /&gt;
Typical example: display a BGA confirmation dialog with a callback function created with dojo.hitch:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        this.confirmationDialog( _(&#039;Are you sure you want to make this?&#039;), dojo.hitch( this, function() {&lt;br /&gt;
            this.ajaxcall( &#039;/mygame/mygame/makeThis.html&#039;, { lock:true }, this, function( result ) {} );&lt;br /&gt;
        } ) );   &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the example above, using dojo.hitch, we 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;
; updateCounters(counters)&lt;br /&gt;
: Useful for updating game counters in the player panel (such as resources). &lt;br /&gt;
: &#039;counters&#039; arg is an associative array [counter_name_value =&amp;gt; [ &#039;counter_name&#039; =&amp;gt; counter_name_value, &#039;counter_value&#039; =&amp;gt; counter_value_value], ... ]&lt;br /&gt;
: All counters must be referenced in this.gamedatas.counters and will be updated.&lt;br /&gt;
: DOM objects referenced by &#039;counter_name&#039; will have their innerHTML updated with &#039;counter_value&#039;.&lt;br /&gt;
&lt;br /&gt;
&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;
;&#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. If the current game state description this.gamedatas.gamestate.descriptionmyturn is modified before :calling the function, it allows to update the turn description without changing state.&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;
== 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;
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;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    &amp;lt;a href=&amp;quot;#&amp;quot; id=&amp;quot;my_button_id&amp;quot; class=&amp;quot;bgabutton bgabutton_gray&amp;quot;&amp;gt;&amp;lt;span&amp;gt;My gray button&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    &amp;lt;a href=&amp;quot;#&amp;quot; id=&amp;quot;my_button_id&amp;quot; class=&amp;quot;bgabutton bgabutton_red&amp;quot;&amp;gt;&amp;lt;span&amp;gt;My red button&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    &amp;lt;a href=&amp;quot;#&amp;quot; id=&amp;quot;my_button_id&amp;quot; class=&amp;quot;bgabutton bgabutton_red bgabutton_big&amp;quot;&amp;gt;&amp;lt;span&amp;gt;My big red button&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#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;
&lt;br /&gt;
&#039;&#039;&#039;Disabling:&#039;&#039;&#039;&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;this.addActionButton( &#039;play_button_id&#039;, _(&#039;Play 1 to 3 cards&#039;), &#039;playFunctionButton&#039;, null, false, &#039;blue&#039; ); //Create a blue button&lt;br /&gt;
if (Condition == true)&lt;br /&gt;
{&lt;br /&gt;
	dojo.addClass( &#039;play_button_id&#039;, &#039;disabled&#039;);//disable the button&lt;br /&gt;
}&amp;lt;/pre&amp;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.&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;);             &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;/div&gt;</summary>
		<author><name>User Already Exists</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Game_interface_logic:_Game.js&amp;diff=8358</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=8358"/>
		<updated>2021-05-26T19:18:00Z</updated>

		<summary type="html">&lt;p&gt;User Already Exists: /* Warning messages */ grammar&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 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;
&lt;br /&gt;
== File structure ==&lt;br /&gt;
&lt;br /&gt;
The details of how the file is structured are described below with comments on 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;
&lt;br /&gt;
;onEnteringState(stateName, args)&lt;br /&gt;
This method is called each time we are entering into 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 arg* method use args.args.&lt;br /&gt;
Typically you would do something only for active player, using this.isCurrentPlayerActive() check.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Warning&#039;&#039;&#039;: for multipleactiveplayer states:&lt;br /&gt;
the active players are NOT actives yet so you must use onUpdateActionButtons to perform the client side operation which depends on a player active/unactive status.&lt;br /&gt;
If you are doing initialization of some structure which do not depend on active player, you can just replace	&lt;br /&gt;
  if (this.isCurrentPlayerActive()) {&lt;br /&gt;
into&lt;br /&gt;
  if (!this.isSpectator) {&lt;br /&gt;
for the main switch in that method.&lt;br /&gt;
&lt;br /&gt;
;onLeavingState(stateName)&lt;br /&gt;
This method is called each time we are leaving a game state.&lt;br /&gt;
You can use this method to perform some user interface changes at this moment.&lt;br /&gt;
&lt;br /&gt;
;onUpdateActionButtons(stateName, args)&lt;br /&gt;
In this method you can manage &amp;quot;action buttons&amp;quot; that are displayed in the action status bar.&lt;br /&gt;
To access state arguments passed via calling arg* method use args parameter. Note: args can be null! For game states and when you don&#039;t supply state args function it is null.&lt;br /&gt;
This method is called when active or multiactive player changes. In 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 call would depends on either you get into that from transition 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#Diffrence_between_Single_active_and_Multi_active_states]]&lt;br /&gt;
&lt;br /&gt;
== General tips ==&lt;br /&gt;
&lt;br /&gt;
; this.player_id&lt;br /&gt;
: ID of the player on whose browser the code is running.&lt;br /&gt;
&lt;br /&gt;
; this.isSpectator&lt;br /&gt;
: Flag set to true if the user at the table is a spectator (not a player).&lt;br /&gt;
: Note: This is a variable, not a function.&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;
; this.gamedatas&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. (Most of the time this is unnecessary).&lt;br /&gt;
&lt;br /&gt;
; this.isCurrentPlayerActive()&lt;br /&gt;
: Returns true if the player on whose browser the code is running is currently active (it&#039;s his turn to play).&lt;br /&gt;
&lt;br /&gt;
; this.getActivePlayerId()&lt;br /&gt;
: Return the ID of the active player, or null if we are not in an &amp;quot;activeplayer&amp;quot; type state.&lt;br /&gt;
&lt;br /&gt;
; this.getActivePlayers()&lt;br /&gt;
: Return an array with the IDs of players who are currently active (or an empty array if there are none).&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;
; typeof g_replayFrom != &#039;undefined&#039;&lt;br /&gt;
: 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;
; 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;
---&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:&lt;br /&gt;
&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;
== 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 (before July 2020) ==&lt;br /&gt;
&lt;br /&gt;
For performance reasons, when deploying a game the js code is minimized using ShrinkSafe (based on ECMASCRIPT version 3). Some advanced syntax may not be compatible with this process. In particular:&lt;br /&gt;
* You should not use reserved keywords from the javascript language as variables.&lt;br /&gt;
* You should not declare default argument values in function declarations. The following syntax is invalid for ShrinkSafe: &#039;&#039;&#039;function myFunc(requiredArg, optionalArg = &#039;defaultValue&#039;) {}&#039;&#039;&#039;&lt;br /&gt;
* You should not use &#039;&#039;&#039;let&#039;&#039;&#039; or &#039;&#039;&#039;const&#039;&#039;&#039; to declare variables.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Tip:&#039;&#039;&#039; a developer encountering some problems with this has successfully used [http://plugins.netbeans.org/plugin/58580/jshint JSHint] on NetBeans to evaluate code to make it compatible for ECMAScript 3. With the plugin installed, set the below options in &#039;&#039;&#039;.jshintrc&#039;&#039;&#039; file, and then open &#039;&#039;&#039;Action Items&#039;&#039;&#039; window (in NetBeans):&amp;lt;pre&amp;gt;{ &amp;quot;maxerr&amp;quot;: 999, &amp;quot;esversion&amp;quot;: 3 }&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Tip:&#039;&#039;&#039; some online tools also allow to convert between different versions of javascript, such as https://www.typescriptlang.org/play or https://babeljs.io/ or https://extendsclass.com/javascript-fiddle.html&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 and manipulating the DOM ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;$(&#039;some_html_element_id&#039;)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The $() function is used to get an HTML element using its &amp;quot;id&amp;quot; attribute.&lt;br /&gt;
&lt;br /&gt;
Example 1: modify the content of a &amp;quot;span&amp;quot; element:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
In your HTML code:&lt;br /&gt;
   &amp;lt;span id=&amp;quot;a_value_in_the_game_interface&amp;quot;&amp;gt;1234&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In your Javascript code:&lt;br /&gt;
   $(&#039;a_value_in_the_game_interface&#039;).innerHTML = &amp;quot;9999&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: $() is the standard method to access some HTML element with 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;
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;dojo.style&#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: you must always use dojo.style to modify the CSS properties of HTML elements.&lt;br /&gt;
&lt;br /&gt;
Note²: if you have to modify several CSS properties of an element, or if you have a complex CSS transformation to do, you should consider using dojo.addClass/dojo.removeClass (see below).&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;
&#039;&#039;&#039;dojo.addClass&#039;&#039;&#039;, &#039;&#039;&#039;dojo.removeClass&#039;&#039;&#039;, &#039;&#039;&#039;dojo.hasClass&#039;&#039;&#039;, &#039;&#039;&#039;dojo.toggleClass&#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;
Conclusion: We encourage you to use &#039;&#039;&#039;dojo.addClass&#039;&#039;&#039;, &#039;&#039;&#039;dojo.removeClass&#039;&#039;&#039; and &#039;&#039;&#039;dojo.hasClass&#039;&#039;&#039; to make your life easier :)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;dojo.attr&#039;&#039;&#039;&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;
&lt;br /&gt;
&#039;&#039;&#039;dojo.query&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
With dojo.query, you can query a bunch of HTML elements with a single function, with a &amp;quot;CSS selector&amp;quot; style.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     // All elements with class &amp;quot;possibleMove&amp;quot;:&lt;br /&gt;
     var elements = dojo.query( &#039;.possibleMove&#039; );&lt;br /&gt;
&lt;br /&gt;
     // Count number of tokens (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;
&#039;&#039;&#039;dojo.place&#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;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     // Insert your HTML code as a child of a container element&lt;br /&gt;
     dojo.place( &amp;quot;&amp;lt;your html code&amp;gt;&amp;quot;, &amp;quot;your_container_element_id&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
     // Replace the container element with your new html&lt;br /&gt;
     dojo.place( &amp;quot;&amp;lt;your html code&amp;gt;&amp;quot;, &amp;quot;your_container_element_id&amp;quot;, &amp;quot;replace&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The third parameter of dojo.place can take various interesting values:&lt;br /&gt;
&lt;br /&gt;
&amp;quot;replace&amp;quot; : (see description above).&lt;br /&gt;
&lt;br /&gt;
&amp;quot;first&amp;quot; : Places the node as a child of the reference node. The node is placed as the first child.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;last&amp;quot; (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;
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;dojo.empty&#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&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Remove the element&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&#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;
&#039;&#039;&#039;addStyleToClass: function( cssClassName, cssProperty, propertyValue )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Same as dojo.style(), but for all the nodes set with the specified cssClassName&lt;br /&gt;
&lt;br /&gt;
=== Animations ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Dojo Animations&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
BGA animations is based on Dojo Animation ([http://dojotoolkit.org/documentation/tutorials/1.8/animation/ see tutorial here]).&lt;br /&gt;
&lt;br /&gt;
However, most of the time, you can just use methods below, which are built on top of Dojo Animation.&lt;br /&gt;
&lt;br /&gt;
Note: one interesting method from Dojo that could be useful from time to time is &amp;quot;Dojo.Animation&amp;quot;. It allows you to make any CSS property &amp;quot;slide&amp;quot; from one value to another.&lt;br /&gt;
&lt;br /&gt;
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;
&#039;&#039;&#039;this.slideToObject( mobile_obj, target_obj, duration, delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You can use slideToObject to &amp;quot;slide&amp;quot; an element to a target position.&lt;br /&gt;
&lt;br /&gt;
Sliding element on the game area is the recommended and the most used way to animate your game interface. Using slides allow players to figure out what is happening on the game, as if they were playing with the real boardgame.&lt;br /&gt;
&lt;br /&gt;
The parameters are:&lt;br /&gt;
* mobile_obj: the ID of the object to move. This object must be &amp;quot;relative&amp;quot; or &amp;quot;absolute&amp;quot; positioned.&lt;br /&gt;
* target_obj: the ID of the target object. This object must be &amp;quot;relative&amp;quot; or &amp;quot;absolute&amp;quot; positioned. Note that it is not mandatory that mobile_obj and target_obj have the same size. If their size are different, the system slides the center of mobile_obj to the center of target_obj.&lt;br /&gt;
* duration: (optional) defines the duration in millisecond of the slide. The default is 500 milliseconds.&lt;br /&gt;
* delay: (optional). If you defines a delay, the slide will start only after this delay. This is particularly useful when you want to slide several object from the same position to the same position: you can give a 0ms delay to the first object, a 100ms delay to the second one, a 200ms delay to the third one, ... this way they won&#039;t be superposed during the slide.&lt;br /&gt;
&lt;br /&gt;
BE CAREFUL: The method returns an dojo.fx animation, so you can combine it with other animation if you want to. It means that you have to call the &amp;quot;play()&amp;quot; method, otherwise the animation WON&#039;T START.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   this.slideToObject( &amp;quot;some_token&amp;quot;, &amp;quot;some_place_on_board&amp;quot; ).play();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.slideToObjectPos( mobile_obj, target_obj, target_x, target_y, duration, delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This method does exactly the same as &amp;quot;slideToObject&amp;quot;, except than you can specify some (x,y) coordinates. This way, &amp;quot;mobile_obj&amp;quot; will slide to the specified x,y position relatively to &amp;quot;target_obj&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Example: slide a token to some place on the board, 10 pixels to the bottom:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   this.slideToObjectPos( &amp;quot;some_token&amp;quot;, &amp;quot;some_place_on_board&amp;quot;, 0, 10 ).play();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.slideTemporaryObject( mobile_obj_html, mobile_obj_parent, from, to, duration, delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This method is useful when you want to slide a temporary HTML object from one place to another. As this object does not exists before the animation and won&#039;t remain after, it could be complex to create this object (with dojo.place), to place it at its origin (with placeOnObject) to slide it (with slideToObject) and to make it disappear at the end.&lt;br /&gt;
&lt;br /&gt;
slideTemporaryObject does all of this for you:&lt;br /&gt;
* mobile_obj_html is a piece of HTML code that represent the object to slide.&lt;br /&gt;
* mobile_obj_parent is the ID of an HTML element of your interface that will be the parent of this temporary HTML object.&lt;br /&gt;
* from is the ID of the origin of the slide.&lt;br /&gt;
* to is the ID of the target of the slide.&lt;br /&gt;
* duration/delay works exactly like in &amp;quot;slideToObject&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
this.slideTemporaryObject( &#039;&amp;lt;div class=&amp;quot;token_icon&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;, &#039;tokens&#039;, &#039;my_origin_div&#039;, &#039;my_target_div&#039; ).play();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.slideToObjectAndDestroy: function( node, to, time, delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This method is a handy shortcut to slide an existing HTML object to some place then destroy it upon arrival. It can be used for example to move a victory token or a card from the board to the player panel to show that the player earns it, then destroy it when we don&#039;t need to keep it visible on the player panel.&lt;br /&gt;
&lt;br /&gt;
It works the same as this.slideToObject and takes the same arguments, but it starts the animation. &lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
this.slideToObjectAndDestroy( &amp;quot;some_token&amp;quot;, &amp;quot;some_place_on_board&amp;quot;, 1000, 0 );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.fadeOutAndDestroy( node, duration, delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This function fade out the target HTML node, then destroy it. Its starts the animation.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   this.fadeOutAndDestroy( &amp;quot;a_card_that_must_disappear&amp;quot; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
CAREFUL: the HTML node still exists until during few milliseconds, until the fadeOut has been completed.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Rotating elements&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You can check here [http://jimfulton.info/demos/dojo-animated-rotate.html an example of use] of Dojo to make an element rotate.&lt;br /&gt;
&lt;br /&gt;
This example combines &amp;quot;Dojo.Animation&amp;quot; method and a CSS3 property that allow you to rotate the element.&lt;br /&gt;
&lt;br /&gt;
IMPORTANT: to asses browser compatibility, you must select the CSS property to use just like in the example (see sourcecode below):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        var transform;&lt;br /&gt;
        dojo.forEach(&lt;br /&gt;
            [&#039;transform&#039;, &#039;WebkitTransform&#039;, &#039;msTransform&#039;,&lt;br /&gt;
             &#039;MozTransform&#039;, &#039;OTransform&#039;],&lt;br /&gt;
            function (name) {&lt;br /&gt;
                if (typeof dojo.body().style[name] != &#039;undefined&#039;) {&lt;br /&gt;
                    transform = name;&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        // ... and then use &amp;quot;transform&amp;quot; as the name of your CSS property for rotation&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: This wiki was probably written 10 years ago - now all modern broser support &#039;transform&#039; so just ignore this and use transform.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Animation Callbacks&#039;&#039;&#039;&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.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
var animation_id = this.slideToObject( mobile_obj, target_obj, duration, delay );&lt;br /&gt;
dojo.connect(animation_id, &#039;onEnd&#039;, dojo.hitch(this, &#039;callback_function&#039;, parameters));&lt;br /&gt;
animation_id.play();&lt;br /&gt;
&lt;br /&gt;
…&lt;br /&gt;
&lt;br /&gt;
callback_function: function(params) {&lt;br /&gt;
   // this will be called after the animation ends&lt;br /&gt;
},&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;
=== Moving elements ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.placeOnObject( mobile_obj, target_obj )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
placeOnObject works exactly like &amp;quot;slideToObject&amp;quot;, except that the effect is immediate.&lt;br /&gt;
&lt;br /&gt;
This is not really an animation, but placeOnObject is frequently used before starting an animation.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  // (We just created an object &amp;quot;my_new_token&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
  // Place the new token on current player board&lt;br /&gt;
  this.placeOnObject( &amp;quot;my_new_token&amp;quot;, &amp;quot;overall_player_board_&amp;quot;+this.player_id );&lt;br /&gt;
  &lt;br /&gt;
  // Then slide it to its position on the board&lt;br /&gt;
  this.slideToObject( &amp;quot;my_new_token&amp;quot;, &amp;quot;a_place_on_board&amp;quot; ).play();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.placeOnObjectPos( mobile_obj, target_obj, target_x, target_y )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This method works exactly like placeOnObject, except than you can specify some (x,y) coordinates. This way, &amp;quot;mobile_obj&amp;quot; will be placed to the specified x,y position relatively to &amp;quot;target_obj&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.attachToNewParent( mobile_obj, target_obj )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
With this method, you change the HTML parent of &amp;quot;mobile_obj&amp;quot; element. &amp;quot;target_obj&amp;quot; is the new parent of this element. The beauty of &lt;br /&gt;
attachToNewParent is that the mobile_obj element DOES NOT MOVE during this process.&lt;br /&gt;
&lt;br /&gt;
Note: what happens is that the method calculate a relative position of mobile_obj to make sure it does not move after the HTML parent changes.&lt;br /&gt;
&lt;br /&gt;
Why using this method?&lt;br /&gt;
&lt;br /&gt;
Changing the HTML parent of an element can be useful for the following reasons:&lt;br /&gt;
* When the HTML parent moves, all its child are moving with them. If some game elements is no more linked with a parent HTML object, you may want to attach it to another place.&lt;br /&gt;
* The z_order (vertical order of display) depends on the position in the DOM, so you may need to change the parent of some game elements when they are moving in your game area.&lt;br /&gt;
&lt;br /&gt;
CAREFUL: this function destroys original object and places a clone onto a new parent, this will break all references to this HTML element (ex: dojo.connect).&lt;br /&gt;
&lt;br /&gt;
== Players input ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;dojo.connect&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Used to associate a player event with one of your notification 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;
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: the methods described here are the only correct ways to associate a player input event to your code, and you should not use anything else.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.connect&#039;&#039;&#039;&lt;br /&gt;
function(element, event, handler)&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;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.connectClass&#039;&#039;&#039;&lt;br /&gt;
function( cssClassName, event, handler )&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;
&#039;&#039;&#039;this.disconnect&#039;&#039;&#039;&lt;br /&gt;
function( element, event )&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;
&#039;&#039;&#039;this.disconnectAll&#039;&#039;&#039;&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;
&#039;&#039;&#039;this.checkAction&#039;&#039;&#039;&lt;br /&gt;
function( action, nomessage )&lt;br /&gt;
&lt;br /&gt;
Check if player can do the specified action by taking into account:&lt;br /&gt;
* current game state&lt;br /&gt;
* interface locking (a player can&#039;t do any action if an action is already in progress)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
return true if action is authorized (i.e: the action is listed as a &amp;quot;possibleaction&amp;quot; in current game state).&lt;br /&gt;
&lt;br /&gt;
return false and display an error message if not authorized (display no message if nomessage parameter is true). &lt;br /&gt;
The displayed error message could be either &amp;quot;This move is not allowed at this moment&amp;quot; or &amp;quot;An action is already in progress&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  function onClickOnGameElement( evt )  {&lt;br /&gt;
     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;this.checkPossibleActions&#039;&#039;&#039;&lt;br /&gt;
function( action, nomessage )&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. &lt;br /&gt;
&lt;br /&gt;
Check if player can do the specified action by taking into account:&lt;br /&gt;
* current game state&lt;br /&gt;
* interface locking (a player can&#039;t do any action if an action is already in progress)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.ajaxcall( url, parameters, obj_callback, callback, callback_error )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This method must be used to send a player input to the game server. &#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.&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.&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: a function to trigger when the server returns and everything went fine (not used, as all data handling is done via notifications).&lt;br /&gt;
* callback_error: (optional and rarely used) a function to trigger when the server returns an error.  if no error this function is called with parameter value false.&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
this.ajaxcall( &#039;/mygame/mygame/myaction.html&#039;, { lock: true, &lt;br /&gt;
   arg1: myarg1, &lt;br /&gt;
   arg2: myarg2, &lt;br /&gt;
   ...&lt;br /&gt;
}, this, function( result ) {&lt;br /&gt;
   // Do some stuff after a successful call&lt;br /&gt;
   // NB : usually not needed as changes must be handled by notifications&lt;br /&gt;
   // You should NOT modify the interface in a callback or it will most likely break the framework replays (or make it inaccurate)&lt;br /&gt;
   // You should NOT make another ajaxcall in a callback in order not to create race conditions&lt;br /&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,// &lt;br /&gt;
					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;this.isInterfaceLocked()&#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.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.addActionButton( id, label, method, (opt)destination, (opt)blinking, (opt)color )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You can use this method to add an action button in the main action status bar.&lt;br /&gt;
&lt;br /&gt;
Arguments:&lt;br /&gt;
* id: an element ID that should be unique in your HTML DOM document.&lt;br /&gt;
* label: the text of the button. Should be translatable (use _() function).&lt;br /&gt;
* method: the name of your method that must be triggered when the player clicks on this button.&lt;br /&gt;
* destination (optional): deprecated, do not use this. Use &#039;&#039;&#039;null&#039;&#039;&#039; as value if you need to specify other arguments.&lt;br /&gt;
* blinking (optional): if set to &#039;&#039;&#039;true&#039;&#039;&#039;, the button is going blink to catch player&#039;s attention. Please don&#039;t abuse of blinking button.&lt;br /&gt;
* color: could be &#039;&#039;&#039;blue&#039;&#039;&#039; (default), &#039;&#039;&#039;red&#039;&#039;&#039; or &#039;&#039;&#039;gray&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
You should only use this method in your &amp;quot;onUpdateActionButtons&amp;quot; method. Usually, you use it like this (from Hearts example):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        onUpdateActionButtons: function( stateName, args ) {&lt;br /&gt;
                      &lt;br /&gt;
            if (this.isCurrentPlayerActive()) {            &lt;br /&gt;
                switch( stateName ) {&lt;br /&gt;
                case &#039;giveCards&#039;:&lt;br /&gt;
                    this.addActionButton( &#039;giveCards_button&#039;, _(&#039;Give selected cards&#039;), &#039;onGiveCards&#039; ); &lt;br /&gt;
                    break;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        },   &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the example above, we are adding a &amp;quot;Give selected cards&amp;quot; button in the case we are on game state &amp;quot;giveCards&amp;quot;. When player clicks on this button, it triggers our &amp;quot;onGiveCards&amp;quot; method.&lt;br /&gt;
&lt;br /&gt;
Example using blinking red button:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     this.addActionButton( &#039;commit_button&#039;, _(&#039;Confirm&#039;), &#039;onConfirm&#039;, null, true, &#039;red&#039;); &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: at least in studio example above will make button huge, because it sets it display of blinking things to &#039;&#039;&#039;block&#039;&#039;&#039;, &lt;br /&gt;
if you don&#039;t like it you have to change css display value&lt;br /&gt;
of the button to inline-block (the id of the button is the first argument, i.e &#039;commit_button&#039; in example above)&lt;br /&gt;
&lt;br /&gt;
== Translations ==&lt;br /&gt;
&lt;br /&gt;
See [[Translations]]&lt;br /&gt;
&lt;br /&gt;
== Notifications ==&lt;br /&gt;
&lt;br /&gt;
When something happens on the server side, your game interface Javascript logic received a notification.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s how you can handle these notifications on the client side.&lt;br /&gt;
&lt;br /&gt;
=== Subscribe to notifications ===&lt;br /&gt;
&lt;br /&gt;
Your Javascript &amp;quot;setupNotifications&amp;quot; method is the place where you can subscribe to notifications from your PHP code.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s how you associate one of your Javascript method to a notification &amp;quot;playDisc&amp;quot; (from Reversi example):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   // In setupNotifications method:&lt;br /&gt;
   dojo.subscribe( &#039;playDisc&#039;, this, &amp;quot;notif_playDisc&amp;quot; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: the &amp;quot;playDisc&amp;quot; corresponds to the name of the notification you define it in your PHP code, in your &amp;quot;notifyAllPlayers&amp;quot; or &amp;quot;notifyPlayer&amp;quot; method.&lt;br /&gt;
&lt;br /&gt;
Then, you have to define your &amp;quot;notif_playDisc&amp;quot; method:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        notif_playDisc: function( notif )&lt;br /&gt;
        {&lt;br /&gt;
            // Remove current possible moves (makes the board more clear)&lt;br /&gt;
            dojo.query( &#039;.possibleMove&#039; ).removeClass( &#039;possibleMove&#039; );        &lt;br /&gt;
        &lt;br /&gt;
            this.addDiscOnBoard( notif.args.x, notif.args.y, notif.args.player_id );&lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In a notification handler like our &amp;quot;notif_playDisc&amp;quot; method, you can access to all notifications arguments with &amp;quot;notif.args&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    // If you did this on PHP side:&lt;br /&gt;
    self::notifyAllPlayers( &amp;quot;myNotification&amp;quot;, &#039;&#039;, array( &amp;quot;myArgument&amp;quot; =&amp;gt; 3 ) );&lt;br /&gt;
&lt;br /&gt;
    // On Javascript side, you can access the &amp;quot;myArgument&amp;quot; like this:&lt;br /&gt;
    notif_myNotification: function( notif )&lt;br /&gt;
    {&lt;br /&gt;
       alert( &amp;quot;myArgument = &amp;quot; + notif.args.myArgument );&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Synchronous notifications ===&lt;br /&gt;
&lt;br /&gt;
When several notifications are received by your game interface, these notifications are processed immediately, one after the other, in the same exact order they have been generated in your PHP game logic.&lt;br /&gt;
&lt;br /&gt;
However, sometimes, you need to give some time to the players to figure out what happened on the game before jumping to the next notification. Indeed, in many games, they are a lot of automatic actions, and the computer is going to resolve all these actions very fast if you don&#039;t tell it not to do so.&lt;br /&gt;
&lt;br /&gt;
As an example, for Reversi, when someone is playing a disc, we want to wait 500 milliseconds before doing anything else in order the opponent player can figure out what move has been played.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s how we do this, right after our subscription:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    dojo.subscribe( &#039;playDisc&#039;, this, &amp;quot;notif_playDisc&amp;quot; );&lt;br /&gt;
    this.notifqueue.setSynchronous( &#039;playDisc&#039;, 500 );   // Wait 500 milliseconds after executing the playDisc handler&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
-----&lt;br /&gt;
&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;
=== 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. Similar to setting a synchronous notification above, you can set up a check whether a notification should be ignored:&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;
&#039;&#039;&#039;setIgnoreNotificationCheck(notificationId, predicate)&#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;
* notificationId: before dispatching any notification of this type, the framework will call predicate to check whether notification should be ignored&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;
NOTE: You can think that it could be possible to send generic notification to all other players with notifyAllPlayers and it will seem to work. The problem is that table spectators would miss this notification and their user interface (and game log) wouldn&#039;t be updated.&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 preserve it as explained [[Main_game_logic:_yourgamename.game.php#Notify_players|here]].&lt;br /&gt;
&lt;br /&gt;
=== Pre-defined notification types ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;tableWindow&#039;&#039;&#039; - This defines notification to display [[Game_interface_logic:_yourgamename.js#Scoring_dialogs|Scoring Dialogs]], see below.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;message&#039;&#039;&#039; - This defines notification that shows on players log and have no other effect&lt;br /&gt;
&lt;br /&gt;
   // You can call this on php side without doing anything on client side&lt;br /&gt;
    self::notifyAllPlayers( &#039;message&#039;, &#039;hello&#039;, [] );&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;
== Tooltips ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.addTooltip( nodeId, _( helpString ), _( actionString ), delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Add a simple text tooltip to the DOM node.&lt;br /&gt;
&lt;br /&gt;
Specify &#039;helpString&#039; to display some information about &amp;quot;what is this game element?&amp;quot;.&lt;br /&gt;
Specify &#039;actionString&#039; to display some information about &amp;quot;what happens when I click on this element?&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
You must specify both helpString and actionString. Most of the time, you should use only one and specify a void string (&amp;quot;&amp;quot;) for the other one.&lt;br /&gt;
&lt;br /&gt;
Usually, _() must be used for the text to be marked for translation.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Delay&amp;quot; is an optional parameter. Usually, it is primarily used to specify a zero delay for some game element when the tooltip gives really important information for the game - but remember: no essential information must be placed in tooltips as they won&#039;t be displayed in some 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;
&#039;&#039;&#039;this.addTooltipHtml( nodeId, html, delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Add an HTML tooltip to the DOM node (for more elaborate content such as presenting a bigger version of a card).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.addTooltipToClass( cssClass, _( helpString ), _( actionString ), delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Add a simple text tooltip to all the DOM nodes set with this cssClass. &lt;br /&gt;
&lt;br /&gt;
IMPORTANT: all concerned nodes must have IDs to get tooltips.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.addTooltipHtmlToClass( cssClass, html, delay )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Add an HTML tooltip to to all the DOM nodes set with this cssClass (for more elaborate content such as presenting a bigger version of a card).&lt;br /&gt;
&lt;br /&gt;
IMPORTANT: all concerned nodes must have IDs to get tooltips&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.removeTooltip( nodeId )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Remove a tooltip from the DOM node.&lt;br /&gt;
&lt;br /&gt;
== Dialogs, warning messages, confirmation dialogs, ... ==&lt;br /&gt;
&lt;br /&gt;
=== Warning messages ===&lt;br /&gt;
&lt;br /&gt;
Sometimes, there is something important that is happening 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;this.showMessage( msg, type )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
showMessage shows a message in a big rectangular area on the top of the screen of the current player.&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;msg&amp;quot; is the string to display. It should be translated.&lt;br /&gt;
* &amp;quot;type&amp;quot; can be set to &amp;quot;info&amp;quot;, &amp;quot;error&amp;quot;, or &amp;quot;only_to_log&amp;quot;. If set to &amp;quot;info&amp;quot;, the message will be an informative message on a white background. If set to &amp;quot;error&amp;quot;, the message will be an error message on a red background. 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;
&lt;br /&gt;
Important: the normal way to inform players about the progression of the game is the game log. &amp;quot;showMessage&amp;quot; is intrusive and should not be used often.&lt;br /&gt;
&lt;br /&gt;
=== Confirmation dialog ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;confirmationDialog( message, yesHandler, noHandler )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When an important action with a lot of consequences is triggered by the player, you may want to propose a confirmation dialog.&lt;br /&gt;
&lt;br /&gt;
CAREFUL: the general guidelines of BGA is to AVOID the use of confirmation dialog. Confirmation dialogs slow down the game and bother players. The players knows that they have to pay attention about each move when they are playing online.&lt;br /&gt;
&lt;br /&gt;
The situation where you should use a confirmation dialog are the following:&lt;br /&gt;
* It must not happen very often during a game.&lt;br /&gt;
* It must be linked to an action that can really &amp;quot;kill a game&amp;quot; if the player do not pay attention.&lt;br /&gt;
* It must be something that can be done by mistake (ex: a link on the action status bar).&lt;br /&gt;
&lt;br /&gt;
How to display a confirmation dialog:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        this.confirmationDialog( _(&#039;Are you sure you want to bake the pie?&#039;), dojo.hitch( this, function() {&lt;br /&gt;
            this.bakeThePie();&lt;br /&gt;
        } ) ); &lt;br /&gt;
        return; // nothing should be called or done after calling this, all action must be done in the handler  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Multiple choice dialog ===&lt;br /&gt;
You can use this dialog to give user a choice with small amount of options:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        var keys = [1,5,10];&lt;br /&gt;
        this.multipleChoiceDialog(&lt;br /&gt;
          _(&#039;How many bugs to fix?&#039;), keys, &lt;br /&gt;
            dojo.hitch(this, function(choice) {&lt;br /&gt;
                            var bugchoice = keys[choice];&lt;br /&gt;
                            console.log(&#039;dialog callback with &#039;+bugchoice);&lt;br /&gt;
                            this.ajaxcall( &#039;/mygame/mygame/fixBugs.html&#039;, { bugs: bugchoice}, this, function( result ) {} );                        }));&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Dialogs ===&lt;br /&gt;
&lt;br /&gt;
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;
&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, function(evt){&lt;br /&gt;
                evt.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( function() { ... } );&lt;br /&gt;
&lt;br /&gt;
=== Scoring dialogs ===&lt;br /&gt;
&lt;br /&gt;
Sometimes at the end of a round you want to display a big table that details the points wins in each section of the game.&lt;br /&gt;
&lt;br /&gt;
Example: in Hearts game, we display at the end of each round the number of &amp;quot;heart&amp;quot; cards collected by each player, the player who collected the Queen of Spades, and the total number of points loose by each player.&lt;br /&gt;
&lt;br /&gt;
Scoring dialogs are managed entirely on &#039;&#039;&#039;PHP side&#039;&#039;&#039;, but they are described here as their effects are visible only on client side.&lt;br /&gt;
&lt;br /&gt;
Displaying a scoring dialog is quite simple and is using a special notification type: &amp;quot;tableWindow&amp;quot;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  // on PHP side:&lt;br /&gt;
  $this-&amp;gt;notifyAllPlayers( &amp;quot;tableWindow&amp;quot;, &#039;&#039;, array(&lt;br /&gt;
            &amp;quot;id&amp;quot; =&amp;gt; &#039;finalScoring&#039;,&lt;br /&gt;
            &amp;quot;title&amp;quot; =&amp;gt; clienttranslate(&amp;quot;Title of the scoring dialog&amp;quot;),&lt;br /&gt;
            &amp;quot;table&amp;quot; =&amp;gt; $table&lt;br /&gt;
        ) ); &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;table&amp;quot; argument is a 2 dimensional PHP array that describe the table you want to display, line by line and column by column.&lt;br /&gt;
&lt;br /&gt;
Example: display an 3x3 array of strings&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   $table = array(&lt;br /&gt;
      array( &amp;quot;one&amp;quot;, &amp;quot;two&amp;quot;, &amp;quot;three&amp;quot; ),    // This is my first line&lt;br /&gt;
      array( &amp;quot;four&amp;quot;, &amp;quot;five&amp;quot;, &amp;quot;six&amp;quot; ),    // This is my second line&lt;br /&gt;
      array( &amp;quot;seven&amp;quot;, &amp;quot;height&amp;quot;, &amp;quot;nine&amp;quot; )    // This is my third line&lt;br /&gt;
   );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As you can see above, in each &amp;quot;cell&amp;quot; of your array you can display a simple string value. But you can also display a complex value with a template and associated arguments like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   $table = array(&lt;br /&gt;
      array( &amp;quot;one&amp;quot;, &amp;quot;two&amp;quot;, array( &amp;quot;str&amp;quot; =&amp;gt; clienttranslate(&amp;quot;a string with an ${argument}&amp;quot;), &amp;quot;args&amp;quot; =&amp;gt; array( &#039;argument&#039; =&amp;gt; &#039;argument_value&#039; )  ) ),&lt;br /&gt;
      array( &amp;quot;four&amp;quot;, &amp;quot;five&amp;quot;, &amp;quot;six&amp;quot; ), &lt;br /&gt;
      array( &amp;quot;seven&amp;quot;, &amp;quot;height&amp;quot;, &amp;quot;nine&amp;quot; )&lt;br /&gt;
   );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is especially useful when you want to display player names with colors. Example from &amp;quot;Hearts&amp;quot;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        $firstRow = array( &#039;&#039; );&lt;br /&gt;
        foreach( $players as $player_id =&amp;gt; $player )&lt;br /&gt;
        {&lt;br /&gt;
            $firstRow[] = array( &#039;str&#039; =&amp;gt; &#039;${player_name}&#039;,&lt;br /&gt;
                                 &#039;args&#039; =&amp;gt; array( &#039;player_name&#039; =&amp;gt; $player[&#039;player_name&#039;] ),&lt;br /&gt;
                                 &#039;type&#039; =&amp;gt; &#039;header&#039;&lt;br /&gt;
                               );&lt;br /&gt;
        }&lt;br /&gt;
        $table[] = $firstRow;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also use three extra attributes in the parameter array for the notification:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   $this-&amp;gt;notifyAllPlayers( &amp;quot;tableWindow&amp;quot;, &#039;&#039;, array(&lt;br /&gt;
            &amp;quot;id&amp;quot; =&amp;gt; &#039;finalScoring&#039;,&lt;br /&gt;
            &amp;quot;title&amp;quot; =&amp;gt; clienttranslate(&amp;quot;Title of the scoring dialog&amp;quot;),&lt;br /&gt;
            &amp;quot;table&amp;quot; =&amp;gt; $table,&lt;br /&gt;
            &amp;quot;header&amp;quot; =&amp;gt; array(&#039;str&#039; =&amp;gt; clienttranslate(&#039;Table header with parameter ${number}&#039;),&lt;br /&gt;
                                 &#039;args&#039; =&amp;gt; array( &#039;number&#039; =&amp;gt; 3 ),&lt;br /&gt;
                               ),&lt;br /&gt;
            &amp;quot;footer&amp;quot; =&amp;gt; &#039;&amp;lt;div&amp;gt;Some footer&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
            &amp;quot;closing&amp;quot; =&amp;gt; clienttranslate( &amp;quot;Closing button label&amp;quot; )&lt;br /&gt;
        ) ); &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;header&#039;&#039;&#039;: the content for this parameter will display before the table (also, the html will be parsed and player names will be colored according to the current game colors). &lt;br /&gt;
*&#039;&#039;&#039;footer&#039;&#039;&#039;: the content for this parameter will display after the table (no parsing for coloring the player names)&lt;br /&gt;
*&#039;&#039;&#039;closing&#039;&#039;&#039;: if this parameter is used, a button will be displayed with this label at the bottom of the popup and will allow players to close it (more easily than by clicking the top right &#039;cross&#039; icon).&lt;br /&gt;
&lt;br /&gt;
=== Scoring animated display ===&lt;br /&gt;
&lt;br /&gt;
Sometimes (Terra Mystica final scoring for example), you may want to display a score value over an element to make the scoring easier to follow for the players.&lt;br /&gt;
You can do it with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   this.displayScoring( anchor_id, color, score, duration, offset_x, offset_y );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;anchor_id&#039;&#039;&#039;: ID of the 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;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;duration&#039;&#039;&#039;: animation duration in milliseconds&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. 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;
&lt;br /&gt;
=== Speech bubble ===&lt;br /&gt;
&lt;br /&gt;
For better interactivity in some games (Love Letter for example), you may use comic book style speech bubbles to express the players voices.&lt;br /&gt;
This is done with:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   this.showBubble(anchor_id, text, delay, duration, custom_class)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
text - what to put in bubble, can be html actually not just text&lt;br /&gt;
&lt;br /&gt;
delay - in milliseconds is optional (default 0)&lt;br /&gt;
&lt;br /&gt;
duration -  in milliseconds is optional (default 3000)&lt;br /&gt;
&lt;br /&gt;
custom_class - extra class to add to bubble is optional, if you need to override the default bubble style&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;
== 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 &amp;lt;gamename&amp;gt;.js setup() function. However this score must be updated as the game progresses through player notifications (notifs).&lt;br /&gt;
&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;
== Players panels ==&lt;br /&gt;
&lt;br /&gt;
=== Adding stuff to player&#039;s panel ===&lt;br /&gt;
&lt;br /&gt;
At first, create a new &amp;quot;JS template&amp;quot; string in your template (tpl) file:&lt;br /&gt;
&lt;br /&gt;
(from Gomoku example)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
var jstpl_player_board = &#039;\&amp;lt;div class=&amp;quot;cp_board&amp;quot;&amp;gt;\&lt;br /&gt;
    &amp;lt;div id=&amp;quot;stoneicon_p${id}&amp;quot; class=&amp;quot;gmk_stoneicon gmk_stoneicon_${color}&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;span id=&amp;quot;stonecount_p${id}&amp;quot;&amp;gt;0&amp;lt;/span&amp;gt;\&lt;br /&gt;
&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then, you add this piece of code in your JS file to add this template to each player panel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
            // Setting up player boards&lt;br /&gt;
            for( var player_id in gamedatas.players )&lt;br /&gt;
            {&lt;br /&gt;
                var player = gamedatas.players[player_id];&lt;br /&gt;
                         &lt;br /&gt;
                // Setting up players boards if needed&lt;br /&gt;
                var player_board_div = $(&#039;player_board_&#039;+player_id);&lt;br /&gt;
                dojo.place( this.format_block(&#039;jstpl_player_board&#039;, player ), player_board_div );&lt;br /&gt;
            }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Note: the code above is of course from your &amp;quot;setup&amp;quot; function in your Javascript).&lt;br /&gt;
&lt;br /&gt;
Very often, you have to distinguish current player and others players. In this case, you just have to create another JS template (ex: jstpl_otherplayer_board) and use it when &amp;quot;player_id&amp;quot; is different than &amp;quot;this.player_id&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Player&#039;s panel disabling/enabling ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.disablePlayerPanel( player_id )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Disable given player panel (the panel background become gray).&lt;br /&gt;
&lt;br /&gt;
Usually, this is used to signal that this played passes, or will be inactive during a while.&lt;br /&gt;
&lt;br /&gt;
Note that the only effect of this is visual. There are no consequences on the behaviour of the panel itself.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.enablePlayerPanel( player_id )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Enable a player panel that has been disabled before.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;this.enableAllPlayerPanels()&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Enable all player panels that has been disabled before.&lt;br /&gt;
&lt;br /&gt;
== Image loading ==&lt;br /&gt;
&lt;br /&gt;
See also [[Game_art:_img_directory]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Be careful&#039;&#039;&#039;: by default, ALL images of your img directory are loaded on a player&#039;s browser when he loads the game. For this reason, don&#039;t let in your img directory images that are not useful, otherwise it&#039;s going to slowdown the game load.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;dontPreloadImage( image_file_name )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Using dontPreloadImage, you tell the interface to not preload a specific image in your img directory.&lt;br /&gt;
&lt;br /&gt;
Example of use:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
this.dontPreloadImage( &#039;cards.png&#039; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is particularly useful if for example you have 2 different themes for a game. To accelerate the loading of the game, you can specify to not preload images corresponding to the other theme.&lt;br /&gt;
&lt;br /&gt;
Another example of use: in &amp;quot;Gosu&amp;quot; game with Kamakor extension, you play with 5 sets of cards among 10 available. Cards images are organized by sets, and we only preload the images corresponding to the 5 current sets with &#039;&#039;&#039;ensureSpecificGameImageLoading( image_file_names_array )&#039;&#039;&#039;.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// By default, do not preload anything&lt;br /&gt;
this.dontPreloadImage( &#039;cards.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan1.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan2.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan3.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan4.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan5.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan6.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan7.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan8.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan9.png&#039; );&lt;br /&gt;
this.dontPreloadImage( &#039;clan10.png&#039; );&lt;br /&gt;
var to_preload = [];&lt;br /&gt;
for( i in this.gamedatas.clans )&lt;br /&gt;
{&lt;br /&gt;
	var clan_id = this.gamedatas.clans[i];&lt;br /&gt;
	to_preload.push( &#039;clan&#039;+clan_id+&#039;.png&#039; );&lt;br /&gt;
}&lt;br /&gt;
if( to_preload.length == 5 )&lt;br /&gt;
{&lt;br /&gt;
	this.ensureSpecificGameImageLoading( to_preload );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; You don&#039;t need to specify to not preload game box images (game_box.png, game_box75.png...) since they are not preloaded by default.&lt;br /&gt;
&lt;br /&gt;
== Other useful stuff ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;dojo.hitch&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
With dojo.hitch, you can create a callback function that will run with your game object context whatever happen.&lt;br /&gt;
&lt;br /&gt;
Typical example: display a BGA confirmation dialog with a callback function created with dojo.hitch:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        this.confirmationDialog( _(&#039;Are you sure you want to make this?&#039;), dojo.hitch( this, function() {&lt;br /&gt;
            this.ajaxcall( &#039;/mygame/mygame/makeThis.html&#039;, { lock:true }, this, function( result ) {} );&lt;br /&gt;
        } ) );   &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the example above, using dojo.hitch, we 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;
; updateCounters(counters)&lt;br /&gt;
: Useful for updating game counters in the player panel (such as resources). &lt;br /&gt;
: &#039;counters&#039; arg is an associative array [counter_name_value =&amp;gt; [ &#039;counter_name&#039; =&amp;gt; counter_name_value, &#039;counter_value&#039; =&amp;gt; counter_value_value], ... ]&lt;br /&gt;
: All counters must be referenced in this.gamedatas.counters and will be updated.&lt;br /&gt;
: DOM objects referenced by &#039;counter_name&#039; will have their innerHTML updated with &#039;counter_value&#039;.&lt;br /&gt;
&lt;br /&gt;
&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;
;&#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. If the current game state description this.gamedatas.gamestate.descriptionmyturn is modified before :calling the function, it allows to update the turn description without changing state.&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;
== 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;
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;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    &amp;lt;a href=&amp;quot;#&amp;quot; id=&amp;quot;my_button_id&amp;quot; class=&amp;quot;bgabutton bgabutton_gray&amp;quot;&amp;gt;&amp;lt;span&amp;gt;My gray button&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    &amp;lt;a href=&amp;quot;#&amp;quot; id=&amp;quot;my_button_id&amp;quot; class=&amp;quot;bgabutton bgabutton_red&amp;quot;&amp;gt;&amp;lt;span&amp;gt;My red button&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    &amp;lt;a href=&amp;quot;#&amp;quot; id=&amp;quot;my_button_id&amp;quot; class=&amp;quot;bgabutton bgabutton_red bgabutton_big&amp;quot;&amp;gt;&amp;lt;span&amp;gt;My big red button&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#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;
&lt;br /&gt;
&#039;&#039;&#039;Disabling:&#039;&#039;&#039;&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;this.addActionButton( &#039;play_button_id&#039;, _(&#039;Play 1 to 3 cards&#039;), &#039;playFunctionButton&#039;, null, false, &#039;blue&#039; ); //Create a blue button&lt;br /&gt;
if (Condition == true)&lt;br /&gt;
{&lt;br /&gt;
	dojo.addClass( &#039;play_button_id&#039;, &#039;disabled&#039;);//disable the button&lt;br /&gt;
}&amp;lt;/pre&amp;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.&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;);             &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;/div&gt;</summary>
		<author><name>User Already Exists</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Gamehelphex&amp;diff=8339</id>
		<title>Gamehelphex</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Gamehelphex&amp;diff=8339"/>
		<updated>2021-05-25T04:34:29Z</updated>

		<summary type="html">&lt;p&gt;User Already Exists: Copy-editing, updated Hex terminology&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===INTRODUCTION===&lt;br /&gt;
&lt;br /&gt;
The game of Hex was invented and popularized in Denmark by Piet Hein in 1942, and later independently discovered by John Nash in 1947. The game is attractive because it has extremely simple rules, yet a surprising amount of strategic depth. Another interesting aspect is that the game can&#039;t end in a tie.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===GOAL===&lt;br /&gt;
&lt;br /&gt;
The board has two red edges and two blue edges. Each player&#039;s goal is to connect their two edges by stones of their color.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===TURNS===&lt;br /&gt;
&lt;br /&gt;
The players alternately place a stone of their own color on the board, with Red going first. A stone can be placed on any empty cell. Once placed, stones are never moved or removed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===THE SWAP RULE===&lt;br /&gt;
&lt;br /&gt;
To make sure the first player does not have an unfair advantage, the swap rule is used. After the first player opens with a red stone, the second player can either&lt;br /&gt;
* continue to play normally, by placing a blue stone, or&lt;br /&gt;
* decide to switch colors. In that case, the second player becomes Red, the first player becomes Blue, and the first move is kept. After this, the game continues normally, i.e., it is the first player&#039;s turn to play a blue stone. &lt;br /&gt;
&lt;br /&gt;
Alternatively, the swap rule can also be implemented in such a way that the players keep their original colors. In that case, if Blue wants to swap, Red&#039;s initial stone is replaced by a blue stone and mirrored about the long diagonal. After this, it is Red&#039;s turn.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===GAME END===&lt;br /&gt;
&lt;br /&gt;
The game ends when one of the players has connected their edges with a path of stones of their color. The game can&#039;t end in a tie. It is customary for the losing player to resign when it is clear to both players who will win.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===BOARD SIZES===&lt;br /&gt;
&lt;br /&gt;
The game can be played on boards of several different sizes. The 6x6 board is designed to help beginners understand the basic rules and discover simple game patterns. The 11x11 board is a more classic size and was used by Piet Hein. The 13x13 board is preferred by many experts. The 14x14 board is the one recommended by John Nash, and the 15x15 board allows even longer plays.&lt;/div&gt;</summary>
		<author><name>User Already Exists</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Game_art:_img_directory&amp;diff=8293</id>
		<title>Game art: img directory</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Game_art:_img_directory&amp;diff=8293"/>
		<updated>2021-05-18T23:46:55Z</updated>

		<summary type="html">&lt;p&gt;User Already Exists: /* Images naming constraints */ typo&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Studio_Framework_Navigation}}&lt;br /&gt;
&lt;br /&gt;
== Requested images ==&lt;br /&gt;
&lt;br /&gt;
The following images are requested by BGA:&lt;br /&gt;
&lt;br /&gt;
;game_box.png&lt;br /&gt;
* It is displayed on the main site on the game description page and when creating a table (280x280 px).&lt;br /&gt;
* It should be a 3D image of a physical copy of the game box as it appears in an online shop.&lt;br /&gt;
* It is better to take the version of the game that is coherent with the game art used in the adaptation, and from the original publisher of the game.&lt;br /&gt;
* The background of the image must be transparent.&lt;br /&gt;
* If you don&#039;t have a 3D version of the game box, you can use the following website to create one: http://www.3d-pack.com/&lt;br /&gt;
&lt;br /&gt;
;game_box180.png&lt;br /&gt;
;game_box75.png&lt;br /&gt;
&lt;br /&gt;
* Don&#039;t modify these images, they are auto generated by &amp;quot;Reload game box image&amp;quot; action. If you have another copy of your source make sure you update you copy of these files after they have been generated and not override with old copied.&lt;br /&gt;
&lt;br /&gt;
;game_icon.png&lt;br /&gt;
&lt;br /&gt;
* It is the icon displayed in the lists of games and tables (50x50 px).&lt;br /&gt;
* The objective of this icon is to make the game recognizable among the other games. A good idea is to take a part of the game cover that is distinctive (ex: the game title).&lt;br /&gt;
* This one  does not have to be transparent. This image should not have a border &lt;br /&gt;
&lt;br /&gt;
;publisher.png&lt;br /&gt;
* It is the logo of the publisher of the game, displayed on the game description page.&lt;br /&gt;
* The width must be 150 px. The height can be anything (reasonable). The image could be transparent.&lt;br /&gt;
&lt;br /&gt;
;publisher2.png (optional)&lt;br /&gt;
* If the game has been co-published by 2 publishers, you should upload a second image named &amp;quot;publisher2.png&amp;quot; (same characteristics as the first one).&lt;br /&gt;
&lt;br /&gt;
;game_banner.jpg&lt;br /&gt;
* size 1386x400px&lt;br /&gt;
* should not contain any text; representative of the atmosphere of the game such as a cover element or communication image; the box image covering the banner on the left should stand out&lt;br /&gt;
&lt;br /&gt;
;game_displayX.jpg (X an integer between 0 and 9)&lt;br /&gt;
* height between 400px and 760px, width maximum 1.5 x height;&lt;br /&gt;
* the idea is to make players want to play the game, so it could be a zoomed card, some detail of the board, an overview of an ongoing physical game... but NOT a screenshot of the BGA adaptation since there is already the &amp;quot;see game in action&amp;quot; replay for that&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important&#039;&#039;&#039;: when you modify these images, you MUST click on &amp;quot;Reload game box image&amp;quot; from the Control Panel in order your update can be taken into account.&lt;br /&gt;
&lt;br /&gt;
== Game art ==&lt;br /&gt;
&lt;br /&gt;
You must upload in img directory all images of your game interface.&lt;br /&gt;
&lt;br /&gt;
=== Images naming constraints ===&lt;br /&gt;
&lt;br /&gt;
To be correctly deployed your images file names should not contain spaces or parentheses.&lt;br /&gt;
&lt;br /&gt;
=== Images loading ===&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;
Note that you can tune the way images are loaded with Javascript method &amp;quot;dontPreloadImage&amp;quot; (see [[Game_interface_logic:_yourgamename.js|Game Interface Logic]]).&lt;br /&gt;
&lt;br /&gt;
General recommendation it to have no more than dozen of image files, 2Mb max each. However if there is heavy game resources specific to a player (i.e. player board of specific color or set of cards) it is better to separate them and &amp;quot;don&#039;t pre-load&amp;quot; since in any given game only some of them will be used.&lt;br /&gt;
&lt;br /&gt;
=== Images format ===&lt;br /&gt;
&lt;br /&gt;
You can use these image formats while building your game interface:&lt;br /&gt;
;jpg images&lt;br /&gt;
&lt;br /&gt;
should be used for non-transparent images. Jpg are usually lighter than Pngs, so please choose Jpg for big pictures (ex: game board, cards) when you don&#039;t need transparency to accelerate game load. You don&#039;t need transparency for rounded card corners, it can be done using css.&lt;br /&gt;
&lt;br /&gt;
;png images&lt;br /&gt;
&lt;br /&gt;
should be used for images with transparency, such as non-square tokens, meeples, etc (combined into sprite).&lt;br /&gt;
&lt;br /&gt;
;gif images&lt;br /&gt;
&lt;br /&gt;
can be used for animated images. This is not recommended to use gif animated images as they can upset players, but for some specific interface element this could be useful.&lt;br /&gt;
&lt;br /&gt;
;svg images&lt;br /&gt;
&lt;br /&gt;
svg images can be really efficient for icons or abstract images&lt;br /&gt;
&lt;br /&gt;
=== Use background-size ===&lt;br /&gt;
&lt;br /&gt;
In order to allow for players to use the browser zoom without your images becoming pixelated, it&#039;s recommended to use higher resolution images than needed for the normal display of your interface, and to use the css property &#039;&#039;&#039;background-size&#039;&#039;&#039; to fit the image to the size you need for your interface.&lt;br /&gt;
&lt;br /&gt;
=== Use CSS Sprites ===&lt;br /&gt;
&lt;br /&gt;
To limit the number of images load and make the game load faster, you must use CSS sprites, i.e. you must gather several images in a single one. However, there are limitations. Do not make any CSS image sprite with dimensions that exceed 4096x4096 pixels or it will not work on mobile devices (Android max texture size is 4096 pixels, test your own browser at [http://webglreport.com/ WebGL Report]).&lt;br /&gt;
&lt;br /&gt;
To learn more on CSS Sprites:&lt;br /&gt;
* [http://www.w3schools.com/css/css_image_sprites.asp CSS sprites (W3C documentation)].&lt;br /&gt;
* [[Game interface stylesheet: yourgamename.css]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important:&#039;&#039;&#039; the maximum image size should be 4096x4096 (otherwise, some devices may not display parts of the image, see https://stackoverflow.com/questions/34682482/what-is-the-maximum-sprite-sheet-size-i-can-use-for-android-devices)&lt;br /&gt;
&lt;br /&gt;
Tools:&lt;br /&gt;
* Sprite Generator https://www.toptal.com/developers/css/sprite-generator/&lt;br /&gt;
&lt;br /&gt;
=== Shrink images ===&lt;br /&gt;
&lt;br /&gt;
If you get high resolution images from publisher you need to shrink them since web display requires much lower resolution than printing.&lt;br /&gt;
&lt;br /&gt;
* Shrink images without loss of quality https://tinypng.com/ or http://www.iloveimg.com/&lt;br /&gt;
&lt;br /&gt;
== Image Manipulation Tools ==&lt;br /&gt;
&lt;br /&gt;
You have no choice but to use one of the image manipulating tools to create a successful game adaptation, you would have to&lt;br /&gt;
deal with&lt;br /&gt;
* Converting to supported formats&lt;br /&gt;
* Adding transparency &lt;br /&gt;
* Stitching&lt;br /&gt;
* Shrinking with no quality loss&lt;br /&gt;
* Resizing&lt;br /&gt;
&lt;br /&gt;
For that you need a good tools, recommended tools (if you know more add them here)&lt;br /&gt;
* Gimp (all platforms) - general GUI image editor&lt;br /&gt;
* Paint.net (Windows) - general GUI image editor&lt;br /&gt;
* ImageMagic (All platforms) - https://www.imagemagick.org/script/download.php - command line image editor, great for mass manipulations and scripting&lt;/div&gt;</summary>
		<author><name>User Already Exists</name></author>
	</entry>
</feed>