<?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=Morgalad</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=Morgalad"/>
	<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/Special:Contributions/Morgalad"/>
	<updated>2026-10-28T04:24:19Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.11</generator>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Gamehelpcarnegie&amp;diff=6258</id>
		<title>Gamehelpcarnegie</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Gamehelpcarnegie&amp;diff=6258"/>
		<updated>2020-11-26T15:00:48Z</updated>

		<summary type="html">&lt;p&gt;Morgalad: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Introducing Carnegie ==&lt;br /&gt;
=== NOTICE ===&lt;br /&gt;
These rules are a WORK IN PROGRESS and are subject to change.  They are intended to enable Alpha testing.  Please do not contact the designer or publisher about the rules posted here.&lt;br /&gt;
&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
This game is inspired by the life of Andrew Carnegie. Carnegie was born in Scotland in 1835; he and his parents emigrated to the United States in 1848. Although Carnegie started his career as a telegraph operator, his role as a major player in the rise of the United States’ steel industry made him one of the richest men in the world and an icon of the American dream.&amp;lt;br/&amp;gt;&lt;br /&gt;
Carnegie was also a benefactor and philanthropist. Upon his death in 1919, more than $350 million of his wealth was bequeathed to various foundations, with another $30 million going to various charities. His endowments created nearly 2,500 free public libraries that bear his name: the Carnegie libraries.&amp;lt;br/&amp;gt;&lt;br /&gt;
In Carnegie, players will recruit employees and expand their businesses by investing in real estate, producing goods, developing transport technology, and creating transport chains across the United States. Perhaps they will even become illustrious benefactors who contribute to the country’s greatness through their deeds and generosity!&amp;lt;br/&amp;gt;&lt;br /&gt;
The game takes place over 20 rounds, with players each having one turn per round. In each round the active player will choose one of four actions, which the other players will follow.&lt;br /&gt;
The success of a player’s Company is represented by their victory points (VP), and the player with the most VP at the end of the game will be declared the winner, known forevermore for their philanthropic works.&lt;br /&gt;
=== Game Setup ===&lt;br /&gt;
# Shuffle the 8 Timeline tiles. Draw 4 of these at random and place them in a row on the table. These tiles are double-sided; select sides at random. Add the Start and End tiles to the respective ends of the row, and return the 4 unused Timeline tiles to the box.&lt;br /&gt;
# Place one action disc on each of the 4 starting positions on the far left of the Timeline.&lt;br /&gt;
# Place the Department tiles on the table, next to the main game board.&lt;br /&gt;
# Place the Department tiles on the Department board. With 4 players, use all 32 tiles (2 tiles of each type). With 2 or 3 players, first shuffle these tiles face-down and randomly remove 16 or 8 of them (for 2 or 3 players, respectively) from the game.&lt;br /&gt;
# Create a supply of goods cubes and money tokens near the main game board. &lt;br /&gt;
# Provide each player with:&lt;br /&gt;
##4 Goods cubes and $12.&lt;br /&gt;
##1 Company board and its 4 project tabs. Slide each tab under the right side of the individual game board, with its first (rightmost) spot exposed.&lt;br /&gt;
##15 Employee figurines. Each player places 1 employee standing up on each of their Company board’s 5 Departments, with another 5 employees lying down in the Company&#039;s Lobby. Set the remaining 5 employees aside; they will not be available at the beginning of the game.&lt;br /&gt;
##30 player pawns. Each player places:&lt;br /&gt;
##*1 pawn on the “0” position of the score track&lt;br /&gt;
##*1 pawn on the first space of each of the 4 regional transport tracks&lt;br /&gt;
##*1 pawn on each of the 3 available locations on their project tabs (Housing, Commerce, Industry). &lt;br /&gt;
##*The remaining 22 pawns form the player’s personal supply.&lt;br /&gt;
#In a 4-player game, give each player an Action Choice tile. In a 3-player game, only the third player receives an Action Choice tile. There are no Action Choice tiles in a 2-player game.&lt;br /&gt;
#Beginning with the player sitting to the right of the first player and going counter-clockwise, each player will place the project pawn on their Housing tab on a medium or major city on the map.&lt;br /&gt;
#Finally, starting with the first player and going in clockwise order, each player may move their employees up to total 6 steps on their own Company boards. Each movement must be made to an orthogonally adjacent (not diagonal) space. After these movements, employees can be activated.&lt;br /&gt;
=== Company Basics ===&lt;br /&gt;
==== Company Organization ====&lt;br /&gt;
Each Company is organized into four different Departments, which correspond to the four different types of actions, as follows:&lt;br /&gt;
* Human Resources: allows players to move employees to different Departments within their Companies.&lt;br /&gt;
* Management: allows players to acquire goods and money, and to build new Departments. Each Company begins the game with two Management Departments.&lt;br /&gt;
* Construction: allows players to build projects developed by their R&amp;amp;D Departments.&lt;br /&gt;
* Research &amp;amp; Development (“R&amp;amp;D”) allows players to design new projects and develop their transport networks.&lt;br /&gt;
At the beginning of the game, each Company has 1 Lobby and 5 Departments. During the game, players will be able to expand their Companies by building new Departments. Each Department may hold 1-3 employees; this is represented by the number of employee spaces illustrated on that Department. A Department cannot be used unless it contains at least one active employee. A Department may be used once for each active employee that it contains.&lt;br /&gt;
==== Recruiting Employees ====&lt;br /&gt;
Employees can be either active (standing) or inactive (lying down).&amp;lt;br/&amp;gt;&lt;br /&gt;
When an employee first enters a Company board, it always does so lying down. When an inactive (laid down) employee moves, it remains inactive. If an active (standing) employee is moved, it must be laid down. A Department may hold any number of inactive employees.&amp;lt;br/&amp;gt;&lt;br /&gt;
Employee activations always happen at the end of a player’s turn.&amp;lt;br/&amp;gt;&lt;br /&gt;
Many employee spaces on department tiles are marked with dollar values, representing the costs of that employee’s salary and training. To activate an employee, a player must pay the cost indicated and then place the employee in an upright (standing) position.&lt;br /&gt;
==== Sending an Employee on a Mission ====&lt;br /&gt;
Some departments require sending an active employee on a &#039;&#039;&#039;Mission&#039;&#039;&#039;.  An employee on a Mission is moved from its Department onto one of the four Mission zones on the map; employees sent on Missions are not considered to be active.&amp;lt;br/&amp;gt;&lt;br /&gt;
A player cannot send an employee on a Mission if they are unable to meet the requirements of that action.&lt;br /&gt;
==== Recovering Employees from Missions ====&lt;br /&gt;
When an employee returns from a Mission it must be placed in its Company’s Lobby, lying down. Returned employees are not immediately active; they must be moved and activated with the Human Resources action.&amp;lt;br/&amp;gt;&lt;br /&gt;
Employees return from Missions as action discs advance along the Timeline; this is explained in detail in the next chapter.&lt;br /&gt;
&lt;br /&gt;
== Playing the Game ==&lt;br /&gt;
The game takes place over 20 rounds. Each round consists of four parts, which take place in the following order:&lt;br /&gt;
# Select Action&lt;br /&gt;
# Events&lt;br /&gt;
# Use Departments&lt;br /&gt;
# End of Round – Activate Employees&lt;br /&gt;
=== Select Action ===&lt;br /&gt;
The first player selects the action they wish to perform: Human Resources, Management, Construction, or R&amp;amp;D, and then places the GEAR timeline token on that action’s row on the Timeline, immediately to the right of that row’s action disc.&amp;lt;br/&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Note: A player may choose any action, even if that action’s disc has reached the last space of its Timeline.&#039;&#039;&#039; In this case, the first player must still place the GEAR timeline token to the right of the chosen action disc. The first player must then also turn another action disc face-down; that action disc must still be able to move forward. When an action disc is turned face-down, it triggers an event as though it were the chosen action. At the end of the round, this second disc is turned face-up again and advanced along its Timeline.&amp;lt;br/&amp;gt;&lt;br /&gt;
Placing the hat will trigger an event. There are two possible events: Take Income or Make a Donation.&lt;br /&gt;
==== Take Income ====&lt;br /&gt;
If the hat is placed on a Timeline space illustrated with a region of the United States, that region becomes the active region. Starting with the first player and going clockwise, each player with one or more employees in the active region’s Mission area may:&lt;br /&gt;
# Return 1 or more of their employees from the active region to their Company’s Lobby. In this case, the player receives income from each project they have already built, from anywhere. These revenues are collected only once per player, per round (even if a player returns more than 1 employee to their Company’s Lobby, they only receive this income once).&lt;br /&gt;
# Generate a transport bonus for each recovered employee, according to how far they have developed their transport in the active region. At the beginning of the game, the transport bonus for each region is $1. &lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; If a player cannot (or does not want to) return an employee to their Company’s Lobby, that player does not receive any income or transport bonuses for that round.&amp;lt;br/&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; A player&#039;s transport bonus corresponds to their level of development in the active region. A player may not choose a bonus lower than that of the level they have reached.&amp;lt;br/&amp;gt;&lt;br /&gt;
==== Make a Donation ====&lt;br /&gt;
If the hat is placed on a “donation” symbol, the first player may choose to Make a Donation. Then, going in clockwise order, the other players may choose to make their own donations.&lt;br /&gt;
A player’s first donation costs $5; each donation that player makes in the future will increase in price by $5 (ex: a second donation will cost $10; a third will cost $15). Donations are explained in more detail below.&lt;br /&gt;
=== Use Departments ===&lt;br /&gt;
The first player may use any of their Departments that correspond to their chosen action, in any order. Each Department may be used once for each active (standing) employee present in that Department.&lt;br /&gt;
Then, going in clockwise order, the other players may take the same action. As with the first player, these players may use any of their Departments that correspond to the chosen action once for each active employee in that Department.&amp;lt;br/&amp;gt;&lt;br /&gt;
All uses of a Department must be done as part of a single action; a player cannot return to a Department they have already used on that turn.&amp;lt;br/&amp;gt;&lt;br /&gt;
Example: Thomas has two active employees in his Commerce &amp;amp; Finance Department, and one in his Strategic Planning Department. He uses his Commerce &amp;amp; Finance Department once, and then uses his Strategic Planning Department. He cannot then take a second Commerce &amp;amp; Finance Action.&amp;lt;br/&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Note: By spending an Action Choice tile, a player can choose to take a different action and activate any of their Departments that correspond to this new action. Then, the Action Choice tile is discarded.&#039;&#039;&#039;&lt;br /&gt;
Players begin the game with a Lobby and 5 Departments, which are described below.&lt;br /&gt;
==== Human Resources ====&lt;br /&gt;
The Human Resources Department allows players to train employees and assign them to different Departments. When choosing this action, a player carries out the following steps, in order:&lt;br /&gt;
# Calculate the total number of possible moves that player’s employees can make. Each active employee in Human Resources provides 3 moves (right arrow symbol). This Department features a permanent active employee (employees may not be activated in this space); thus, each player is always entitled to a minimum of 3 moves.&lt;br /&gt;
# Move employees within the Company (including from the Company’s Lobby and any space that does not contain a Department) up to the total number of possible moves. Each move must be made orthogonally (horizontal or vertical, never diagonal), from Department to Department. Moving an active (standing) employee returns it to an inactive (laying down) state.&lt;br /&gt;
# At the end of a player’s turn, that player can activate (stand up) any inactive (laid down) employees on free spots in any of their Departments. The player must pay any costs associated with those activations.&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; Inactive (laid down) employees are considered to be “in training”. A player may only activate employees at the end of their turn, after all other actions have been taken.&amp;lt;br/&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; The total number of possible moves is calculated at the beginning of a player’s turn. Moving an active employee from Human Resources during a turn will not reduce a player’s total number of possible moves for that turn.&lt;br /&gt;
==== Management ====&lt;br /&gt;
At the start of the game, each Company has two Management Departments; these help to generate resources and build new Departments that expand the Company. The first Management Department, &amp;quot;Commerce and Finance,&amp;quot; provides one of the following for each active employee on this space:&lt;br /&gt;
* Receive $3;&lt;br /&gt;
* Receive a goods cube;&lt;br /&gt;
* Send the employee on a Mission and receive $6;&lt;br /&gt;
* Send the employee on a Mission and receive 2 goods cubes.&lt;br /&gt;
The second Management Department, “Strategic Planning,” makes it possible to build new Departments. This Department provides one of the following for each active employee on this space:&lt;br /&gt;
* Pay 1 goods cube and place a new Department on a free space (one that does not already contain a Department) of the player’s Company board; that space must already contain at least one employee;&lt;br /&gt;
* Pay 2 goods cubes and place the new Department on a free space of the player’s Company board.&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; A Company may never contain two identical Departments.&lt;br /&gt;
==== Construction ====&lt;br /&gt;
The Construction Department allows players to carry out projects in the following areas: Housing, Commerce, Industry, and Public Infrastructure. When this action is chosen, the player who uses this Department:&lt;br /&gt;
# Sends an employee to the Mission area of the region where he wishes to build.&lt;br /&gt;
# Pays 1 or 2 goods cubes, then moves a pawn from one of their tabs onto a construction site in the same region.&lt;br /&gt;
# If a player builds a project in a small city, that player immediately receives a transport bonus according to their position on that region’s transport track.&lt;br /&gt;
&#039;&#039;&#039;Notes:&#039;&#039;&#039;&lt;br /&gt;
* If more than one pawn is available on a project tab, the player must build the one farthest to the right.&lt;br /&gt;
* The project must be built:&lt;br /&gt;
** in the region where the employee was sent on a Mission, AND&lt;br /&gt;
** on a spot matching the chosen project type (with a symbol of Housing, Commerce, Industry or Public Infrastructure), OR in a small town that accepts all types of projects;&lt;br /&gt;
&lt;br /&gt;
==== Research &amp;amp; Development ====&lt;br /&gt;
The R&amp;amp;D Department allows players to develop new construction projects in Housing, Commerce, Industry, Public Infrastructure, and Transport. When this action is chosen, each player will receive study points for each of their active employees in their R&amp;amp;D Departments.&amp;lt;br/&amp;gt;&lt;br /&gt;
Study points can be spent in two different ways:&lt;br /&gt;
* A player may move one of their project tabs one place to the right and place a construction pawn on the tab’s just-revealed space (circle), OR&lt;br /&gt;
* A player may move one of their transport cubes on a regional transport track one space to the right.&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; A player may advance tabs or transport cubes more than one step in a turn. At the end of the turn, any unused study points are lost.&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; If a player advances a tab beyond the spaces for construction projects, they will receive the VP indicated on that tab at the end of the game. &lt;br /&gt;
=== End of Round - Activate Employees ===&lt;br /&gt;
At the end of each player’s turn, that player can activate inactive employees in any of their Departments; any associated activation costs must be paid at this time.&amp;lt;br/&amp;gt;&lt;br /&gt;
Once each player has taken a turn, the first player must move the action disc on the Timeline one space to the right (displacing the GEAR timeline token). Then, the first player must pass the GEAR timeline token and first-player marker to the next player in clockwise order. A new round can now begin.&lt;br /&gt;
=== End of the Game ===&lt;br /&gt;
==== Connections between Major Cities ====&lt;br /&gt;
At the end of the game, players can each earn up to 36 VP for establishing connections between the 4 major cities of New York, Chicago, New Orleans, and San Francisco. To gain these points, a player must have connected at least two major cities through a continuous line of their own construction pawns. Each player counts how many major cities they have connected as part of an uninterrupted line; to earn this bonus, a player must connect at least 2 major cities. If San Francisco is connected to at least one other major city, count it twice.&lt;br /&gt;
Players will earn these points based on the number of major cities connected AND the lowest level of transportation among all regions in which a major city is part of this network.&lt;br /&gt;
This scoring is illustrated on the game board. If a player has two unconnected networks of connections between major cities (for instance, San Francisco to Chicago and New Orleans to New York), only the highest-scoring connection will count for that player’s score.&amp;lt;br/&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Example:&#039;&#039;&#039;&lt;br /&gt;
Yellow player has reached these levels on transport development tracks:&lt;br /&gt;
* Midwest: Train&lt;br /&gt;
* West: Train&lt;br /&gt;
* South: Stagecoach&amp;lt;br/&amp;gt;&lt;br /&gt;
Different situations can occur for Yellow player :&lt;br /&gt;
* If a link exists between SF and Chicago (2+1 = 3 links - Train), Yellow gets 18 points.  It doesn&#039;t matter if Yellow goes through the South region to make the link between SF and Chicago. In other words, if the connection exists, we only take into account the Transport development track of Regions of connected Major Cities.&lt;br /&gt;
* If a link exists between SF, Chicago and New Orleans (2+1+1 = 4 links - Stagecoach), Yellow gets 18 points.&lt;br /&gt;
* If a link exists between SF and New Orleans (2+1 = 3 links - Stagecoach), Yellow gets 12 points.&lt;br /&gt;
* If a link exists between Chicago and New Orleans (1+1 = 2 links - Stagecoach), Yellow gets 6 points.&lt;br /&gt;
&lt;br /&gt;
==== Final Scoring ====&lt;br /&gt;
The game ends after 20 rounds. Once all 4 action discs have reached the final boxes of their Timelines and all players have finished their actions, victory points (VP) can be tallied as described below. &lt;br /&gt;
Scoring includes:&lt;br /&gt;
* VP earned during the game;&lt;br /&gt;
* 1 VP for each active (standing) employee, to a maximum of 15 VP;&lt;br /&gt;
* Departments built during the game are worth 2 or 3 VP each, depending on their locations. Each Department in a Company’s first line (top) scores 3 VP, while every other Department built during the game scores 2 VP, to a maximum of 24 VP;&lt;br /&gt;
* Any VP earned from project tabs, to a maximum of 42 VP;&lt;br /&gt;
* VP earned from connections between major cities, to a maximum of 36 VP, as explained above;&lt;br /&gt;
* 0-3 VP for each Construction project built in a small, medium or major city (as indicated on the map), with a maximum of 45 VP;&lt;br /&gt;
* VP provided by donations (max. 12 VP per donation).&lt;br /&gt;
* 3 VP for an unused Action Choice tile.&lt;br /&gt;
The player with the most points is the winner of the game. There are no tiebreakers; tied players must shake hands and savor their shared victory.&lt;br /&gt;
&lt;br /&gt;
== Transport Tracks, Donations, and Departments ==&lt;br /&gt;
=== Transportation Development Tracks ===&lt;br /&gt;
Each region of the country has a transport track that players can develop over the course of the game.&amp;lt;br/&amp;gt;&lt;br /&gt;
At the beginning of the game, players’ transport tracks in the South, Midwest, and Far West start at the “Cart” level; in the East, they start at &amp;quot;Stagecoach.&amp;quot; By progressing along each region’s transport track, players can reach “Railroad” level or beyond.&amp;lt;br/&amp;gt;&lt;br /&gt;
Whenever a player reaches the final box of a transport track, they immediately receive a special reward of 3 goods cubes OR $10.&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; Only one player may occupy the final box of each transport track.&lt;br /&gt;
==== Transport Bonus ====&lt;br /&gt;
Boxes on transportation tracks that are occupied by players’ transport discs indicate which transport bonuses those players receive every time they recover an employee who has gone on a Mission in the corresponding region.&lt;br /&gt;
=== Donation Chart ===&lt;br /&gt;
As we saw in the “Playing the Game” section, if a donation symbol is present on the space where the active player placed the GEAR timeline token, starting with the first player and going in clockwise order, each player may make one donation.&amp;lt;br/&amp;gt;&lt;br /&gt;
Donations represent players’ support of various financial, material, and technical projects; they help to increase players’ reputations, as well as those of their Companies.&amp;lt;br/&amp;gt;&lt;br /&gt;
To Make a Donation:&lt;br /&gt;
* A player must place a pawn on an unoccupied space of the donation chart (on the top of the game board), then pay:&lt;br /&gt;
** $5 for their 1st donation. Each subsequent donation costs an additional $5, so:&lt;br /&gt;
** $10 for their 2nd donation, &lt;br /&gt;
** $15 for their 3rd donation, and so on.&lt;br /&gt;
At the end of the game, donations earn VP according to certain factors. These may include projects built, actions taken, Company development, and accumulated wealth. A maximum of 12 VP may be earned for each donation.&lt;br /&gt;
=== The Department Board ===&lt;br /&gt;
There are 16 different Departments that players can add to their Companies&lt;br /&gt;
==== Training and Partnerships ====&lt;br /&gt;
This Department is a powerful way to bring more flexibility in allocating employees. It also allows its owner to supplement their financial resources.&amp;lt;br/&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Rules:&#039;&#039;&#039; To use this Department, the player must send an active employee from this Department on a Mission (move it to a Mission area on the map). The player then receives any combination of $ and employee moves, to a maximum of 8. (For example, a player could take $2 and 6 employee moves, $4 and 4 employee moves, $7 and 1 employee move, etc., as long at the total is no greater than 8.)&lt;br /&gt;
==== Recruiting ====&lt;br /&gt;
This Department offers a very efficient way to reach the maximum of 15 employees.&amp;lt;br/&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Rules:&#039;&#039;&#039; To use this Department, the player must send an active employee from this Department on a Mission (move it to a Mission area on the map). Then, that player immediately places a new employee from the supply into their Company’s Lobby. This Department has no further effect once the player has recruited all 5 employees from the supply.&lt;br /&gt;
==== Safety and Quality ====&lt;br /&gt;
This Department helps to ensure the quality of manufacturing processes and products, as well as ensuring employees’ safety and well-being.&amp;lt;br/&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Rules:&#039;&#039;&#039; To use this Department, the player must send an active employee from this Department on a Mission (move it to a Mission area on the map). Then, the player receives 1 VP for every two active employees in their Company, rounded down.&lt;br /&gt;
==== New Lobby ====&lt;br /&gt;
A new Lobby allows faster access to certain Departments, minimizing the need for moves.&amp;lt;br/&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Rules:&#039;&#039;&#039; Once this Department has been built, it can hold new recruits and returning employees; employees can be divided between the two Lobbies as desired. This Department has an ongoing effect; it functions without an active employee.&lt;br /&gt;
==== Purchasing ====&lt;br /&gt;
This Department makes it possible to produce a large quantity of goods quickly, and free of charge.&amp;lt;br/&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Rules:&#039;&#039;&#039; To use this Department, the player must send an active employee from this Department on a Mission (move it to a Mission area on the map). The player may then take 3 goods cubes from the supply.&lt;br /&gt;
==== Sales ====&lt;br /&gt;
If a Company produces a lot of goods, this Department can sell them for the best price.&amp;lt;br/&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Rules:&#039;&#039;&#039; Each time a player uses this Department, they may pay 1 to 3 goods cubes to the supply. For each cube paid in this way, the player receives $5.&lt;br /&gt;
==== Logistics ====&lt;br /&gt;
This Department improves a Company’s reliability and delivery time.&amp;lt;br/&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Rules:&#039;&#039;&#039; Each time a player uses this Department, they may pay 1 to 3 goods cubes to the supply. For each cube paid in this way, the player receives $3 and 1 VP.&lt;br /&gt;
==== Property Management ====&lt;br /&gt;
This Department allows a player to immediately assign an employee to a newly-built Department.&amp;lt;br/&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Rules:&#039;&#039;&#039; This Department has an ongoing effect as long as it contains an active employee. When a player adds a new Department to their Company, they may immediately move one of their employees from any Department to the new Department. This employee can be activated at the end of the turn, as normal.&lt;br /&gt;
==== Construction ====&lt;br /&gt;
This Department provides new construction capabilities and reduces building costs.&amp;lt;br/&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Rules:&#039;&#039;&#039; To use this Department, the player must send an active employee from this Department on a Mission (move it to a Mission area on the map). That player then pays only 1 goods cube to build a new project (even if it is an Industry or Public Infrastructure project, which normally cost 2 goods cubes).&lt;br /&gt;
==== Construction Outsourcing ====&lt;br /&gt;
This Department allows a player to build without sending an employee on a Mission.&amp;lt;br/&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Rules:&#039;&#039;&#039; Whenever a player uses this Department, they may pay $4 and 1-2 goods cubes to build a new project, depending on the type of project being built.&lt;br /&gt;
==== Supply Chain ====&lt;br /&gt;
This Department makes it possible to buy goods at a reduced cost.&amp;lt;br/&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Rules:&#039;&#039;&#039; Whenever a player uses this Department, they may purchase up to 3 goods cubes at a cost of $1 each.&lt;br /&gt;
==== Communications ====&lt;br /&gt;
This Department increases the efficiency of donations.&amp;lt;br/&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Rules:&#039;&#039;&#039; This Department has an ongoing effect as long as it contains an active employee. The cost of new donations is calculated on the basis of $3 per donation, instead of $5. &lt;br /&gt;
Example: Before building the Communications Department, Thomas had already made 2 donations. The next donation he makes will cost him $9 (3 x $3), instead of $15 (3 x $5).&lt;br /&gt;
==== Advanced Research ====&lt;br /&gt;
This Department is an effective way to accelerate employees’ studies.&amp;lt;br/&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Rules:&#039;&#039;&#039; To use this Department, the player must send an active employee from this Department on a Mission (move it to a Mission area on the map). The player then gains 8 study points.&lt;br /&gt;
==== Advanced Design ====&lt;br /&gt;
A new design Department allows improves a Company’s study efficiency.&amp;lt;br/&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Rules:&#039;&#039;&#039; Whenever this Department is used, its owner gains 4 study points for each active employee.&lt;br /&gt;
==== Charitable Giving ====&lt;br /&gt;
This Department allows a player to duplicate a donation that another player has already made.&amp;lt;br/&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Rules:&#039;&#039;&#039; To use this Department, the player must send an active employee from this Department on a Mission (move it to a Mission area on the map). After paying the appropriate donation cost, the player may then place one of their donation pawns on top of another player’s donation pawn, rather than on an unoccupied space; a player may not make the same donation twice.&lt;br /&gt;
==== Telegraph Operators ====&lt;br /&gt;
This Department reduces the costs of transport development.&amp;lt;br/&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Rules:&#039;&#039;&#039; This Department has an ongoing effect – as long as it contains an active employee. The player’s study-point costs to progress along transport tracks are reduced by 1 (to a minimum of 0).&lt;br /&gt;
&lt;br /&gt;
== SOLO mode ==&lt;br /&gt;
In a solo game, Andrew Carnegie himself will be the virtual opponent; it goes without saying that it will be difficult to win against him.&lt;br /&gt;
=== Setup ===&lt;br /&gt;
The player setup is identical to that of the normal game. As in a 2-player game, there are only 16 Departments available to build at the start of the game.&lt;br /&gt;
Once player setup is done, set the game up for Andrew. Andrew does not use employees, VP, money, goods cubes, or study points during the game. He also does not use an individual Company board. Andrew always has enough money, resources, and study points. &lt;br /&gt;
# Andrew starts the game with all of his pawns available for construction. However, Andrew does not place a pawn on the board during setup (as in step 9 of a multiplayer game).&lt;br /&gt;
# Andrew places one pawn on each of the 4 regional transport tracks, as though here were a normal player.&lt;br /&gt;
# The five victory-point cards are aligned in numerical order from left to right, with the 0 VP card on the far left and the 10VP card on the far right.&lt;br /&gt;
# The action cards are shuffled to form a draw pile, which is placed to the left of the 0 VP card.&lt;br /&gt;
# Place the first-player disc face-up (hat visible), next to the VP cards.&lt;br /&gt;
==== Playing the Game against Andrew ====&lt;br /&gt;
During the game, the player and Andrew will alternate in choosing round actions.&lt;br /&gt;
The first-player disc is used to indicate whose turn it is to choose the action for the round. When the “hat” side is visible, the player decides the action for the round; when the black side is visible, Andrew decides. Flip the first-player disc over at the end of each round.&lt;br /&gt;
The player always chooses the action for the first round (hat side visible).&lt;br /&gt;
A round in the solo game is divided into 5 steps:&lt;br /&gt;
* New Action Card: The player takes the top action card for Andrew, and without looking at it, slides it face-down under the 0VP card.&lt;br /&gt;
=== Choice of Action ===&lt;br /&gt;
==== First-player Disc Face-up ====&lt;br /&gt;
If the first-player disc is face-up (hat visible), the player chooses the action for the round. He places the GEAR timeline token on right action line, immediately to the right of the action disc.&lt;br /&gt;
Tip: Before choosing his action, the player should look at:&lt;br /&gt;
* The back of that round’s action card, as it will indicate which action is currently Andrew’s strongest. Avoiding this action can help prevent Andrew from gaining too many points,&lt;br /&gt;
* The top card of the draw pile, which indicates which action Andrew will choose in the next round. This can also be valuable in helping to make a choice.&lt;br /&gt;
==== First-player Disc Face-down ====&lt;br /&gt;
If the first-player disc is face-down (hat not visible), the action symbol (on the back of the action card) indicates which action Andrew has chosen. As in the normal game, the GEAR timeline token is placed on the Timeline to the right of this action’s disc.&lt;br /&gt;
** Note: When an action disc reaches the last space of that action’s Timeline, Andrew will place the GEAR timeline token to the right of the chosen action disc. In addition, Andrew will also turn over the action disc on the line immediately below that of the chosen action (or the top line (Human Resources) if the chosen action is R&amp;amp;D). However, the turned-over action disc must be one that can still move forward. If necessary, turn over the action disc on the next line below, instead. This turned-over action disc triggers an event as though it were the chosen action. At the end of the round, turn this disc face-up and advance it one space along its Timeline.&lt;br /&gt;
=== Andrew’s Turn ===&lt;br /&gt;
Flip the current round’s action card face-up.&lt;br /&gt;
==== Event ====&lt;br /&gt;
* If the hat is placed on a space that represents a region of the United States, nothing happens for Andrew. &lt;br /&gt;
* If the hat is placed on a donation symbol, Andrew puts a pawn on the space indicated at the top of the current round’s action card. If the indicated space is already occupied, Andrew does not place a pawn.&lt;br /&gt;
==== Resolve Andrew&#039;s Action ====&lt;br /&gt;
* Human Resources: slide the current round’s action card the indicated number of positions to the right;&lt;br /&gt;
* Management: Andrew takes a tile from each Department whose number appears on the current round’s action card. For each Department that is mentioned on the card but not available on the board, the player slides Andrew&#039;s action card one position to the right;&lt;br /&gt;
* Construction: The player places Andrew&#039;s construction pawns in each city whose name appears on the current round’s action card. These pawns should be placed on house symbols; if no Housing space is available, the pawn is placed on a $ symbol (Commerce), instead. If not available, then place the pawn on a factory (Industry) or, finally, a bridge (Public Infrastructure). For each pawn that cannot be placed, slide the card by one position to the right;&lt;br /&gt;
* R&amp;amp;D: The player moves Andrew’s transport cube in the region indicated on the action card to the right on its track by 1-3 spaces, as indicated on the action card. For each cube’s move that cannot be made, slide the action card by one position to the right.&lt;br /&gt;
Note: Remember that only one player’s cube may occupy the last box of any transport track.&lt;br /&gt;
=== Player’s Turn ===&lt;br /&gt;
The player resolves events as in the normal game: Take Income or Make a Donation. &lt;br /&gt;
Note: As the normal game, if the hat is placed on the last (rightmost) position of the Timeline, the player may choose to do one or both of the following: Take Income and/or Make a Donation.&lt;br /&gt;
The player then performs their action, activating Departments belonging to the same type as the action chosen.&lt;br /&gt;
=== End of Round ===&lt;br /&gt;
The current round’s action card is turned face-down. If the action card has not moved, it is placed to the right of the draw pile, in the &amp;quot;0 VP&amp;quot; position. &lt;br /&gt;
Finally, the first-player disc is turned over.&lt;br /&gt;
=== End of Game and Scoring ===&lt;br /&gt;
When the game ends, Andrew&#039;s points are calculated as follows:&lt;br /&gt;
* Each action card is worth from 0 to 10 (VP), depending on its position;&lt;br /&gt;
* All Department tiles that Andrew has acquired are worth 2 VP each.&lt;br /&gt;
* For each of Andrew’s transport cubes that reached the last position of a transport track, Andrew earns 6VP (Andrew does not earn points for connected cities);&lt;br /&gt;
* Andrew’s construction discs are each worth the VP of the city where they are built (from 0 to 3VP, as indicated on the map);&lt;br /&gt;
* Andrew’s donations are scored according to the player’s efforts. In other words, Andrew scores for what the player did. For example, if the player has built 5 buildings in the Far West, Andrew would score 10 VP (5 x 2) if he had placed a donation token that awards 2 VP for each Far West construction.&lt;br /&gt;
Tip: Players may find it unfair that Andrew receives points for what they have done during the game, but businessmen of Andrew’s caliber don’t care. Once Andrew has placed a donation token, the player knows that they can no longer make that particular donation, and may thus wish to avoid taking actions that would reward Andrew.&lt;br /&gt;
Compare Andrew’s score with that of the player; the highest total score wins!&lt;/div&gt;</summary>
		<author><name>Morgalad</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Gamehelpdragonkeeper&amp;diff=2930</id>
		<title>Gamehelpdragonkeeper</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Gamehelpdragonkeeper&amp;diff=2930"/>
		<updated>2018-03-06T20:51:07Z</updated>

		<summary type="html">&lt;p&gt;Morgalad: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Type of mechanics&lt;br /&gt;
 &lt;br /&gt;
Dragon Keeper could be considered as a cooperative game, but with all the players being traitors. Each participant plays for himself, but they can be defeated together!&lt;br /&gt;
&lt;br /&gt;
This game consists in collecting and placing tiles. At each of your turns, you get a tile and give one to the preceding player. The tile that the following player will get depends on the position of the tile you have given, thus creating a strong interaction. The original guilds are secret, so you must deduce which ones are your opponents, to penalize them as much as possible.&lt;/div&gt;</summary>
		<author><name>Morgalad</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Gamehelpdragonkeeper&amp;diff=2929</id>
		<title>Gamehelpdragonkeeper</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Gamehelpdragonkeeper&amp;diff=2929"/>
		<updated>2018-03-06T20:50:45Z</updated>

		<summary type="html">&lt;p&gt;Morgalad: Created page with &amp;quot;Type of mechanics   dk boite photo rondeDragon Keeper could be considered as a cooperative game, but with all the players being traitors. Each participant plays for himself, b...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Type of mechanics&lt;br /&gt;
 &lt;br /&gt;
dk boite photo rondeDragon Keeper could be considered as a cooperative game, but with all the players being traitors. Each participant plays for himself, but they can be defeated together!&lt;br /&gt;
&lt;br /&gt;
This game consists in collecting and placing tiles. At each of your turns, you get a tile and give one to the preceding player. The tile that the following player will get depends on the position of the tile you have given, thus creating a strong interaction. The original guilds are secret, so you must deduce which ones are your opponents, to penalize them as much as possible.&lt;/div&gt;</summary>
		<author><name>Morgalad</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=3D&amp;diff=2534</id>
		<title>3D</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=3D&amp;diff=2534"/>
		<updated>2017-07-07T15:20:08Z</updated>

		<summary type="html">&lt;p&gt;Morgalad: /* Setting the default point of view and enabling 3d by default */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= Overview =&lt;br /&gt;
&lt;br /&gt;
Board Game Arena is using CSS 3D features to provide a basic 3D view of the games.&lt;br /&gt;
&lt;br /&gt;
This is not a &amp;quot;100% real&amp;quot; 3D as this is very difficult to play with real 3D model with CSS, but most of the time it provides a satisfying 3D view of the game.&lt;br /&gt;
&lt;br /&gt;
The objective of 3D is to provide a nice view of the game : 90% of the time, 2D is more suitable for playing. So we don&#039;t force developers to make sure games can be played in 3D : this is just a &amp;quot;bonus&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
= Enabling 3D =&lt;br /&gt;
&lt;br /&gt;
3D is enabled by default for your game.&lt;br /&gt;
&lt;br /&gt;
You can click on the &amp;quot;3D&amp;quot; button at the top right and see your game in 3D.&lt;br /&gt;
&lt;br /&gt;
If you don&#039;t want to allow players to use 3D with your game, you can add this to you &amp;quot;gameinfos.inc.php&amp;quot; file :&lt;br /&gt;
&lt;br /&gt;
&#039;enable_3d&#039; =&amp;gt; false,&lt;br /&gt;
&lt;br /&gt;
= Detecting 3D =&lt;br /&gt;
&lt;br /&gt;
When 3D is &amp;quot;on&amp;quot;, BGA adds CSS class &amp;quot;mode_3d&amp;quot; to the body element.&lt;br /&gt;
&lt;br /&gt;
In CSS, you should prefix all your 3D mode specific directives by &amp;quot;.mode_3d&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 .mode_3d .board {&lt;br /&gt;
	overflow: visible;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In Javascript, you can detect 3D by using the following :&lt;br /&gt;
&lt;br /&gt;
  if( this.control3dmode3d )&lt;br /&gt;
  {&lt;br /&gt;
     // Only executed in 3d mode&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
= Built-in 3D enhancements =&lt;br /&gt;
&lt;br /&gt;
BGA is doing some built-in 3D enhancements with your 3D adaptations, so your adaptation will have some 3D effects without any efforts :&lt;br /&gt;
&lt;br /&gt;
* When executing a slideToObject, a slideToObjectPos or a slideTemporaryObject, BGA is moving the objects vertically (up, then down).&lt;br /&gt;
* It also happens when moving elements of a Stock module, or to a Zone module.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Enhance your adaptation for 3D =&lt;br /&gt;
&lt;br /&gt;
== Use Z axis ==&lt;br /&gt;
&lt;br /&gt;
Using CSS transform: translateZ, you can translate your HTML elements along the Z axis. Example :&lt;br /&gt;
&lt;br /&gt;
  .floating_element {&lt;br /&gt;
      transform: translateZ( 20px );  /* This element is going to float 20px above the surface */&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
The framework will add the following to all your divs:&lt;br /&gt;
      transform-style: preserve-3d; &lt;br /&gt;
&lt;br /&gt;
So they will keep their position in 3D space relative to other elemens with the transformation defined.  Note that some CSS artifacts can break the css inheritance of the &amp;quot;preserve-3d&amp;quot; like &amp;quot;overflow:auto&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
At any moment, you can know the Z position of an element from javascript using :&lt;br /&gt;
&lt;br /&gt;
  this.getComputedTranslateZ( html_element );&lt;br /&gt;
&lt;br /&gt;
== Use pre-build BGA 3D CSS classes ==&lt;br /&gt;
&lt;br /&gt;
By adding the following classes to your objects, they will look nicer in 3D:&lt;br /&gt;
&lt;br /&gt;
* thickness: add a (3px) black thickness to your HTML element.&lt;br /&gt;
  &lt;br /&gt;
* roundthickness: (to be used with thickness) if your element is a circle, you should add roundthickness so your element thickness can be a circle too.&lt;br /&gt;
  &lt;br /&gt;
* whitethickness: (to be used with thickness) if you prefer to have a whitethickness instead of black.&lt;br /&gt;
  &lt;br /&gt;
* floatingabove: make your element &amp;quot;float&amp;quot; 10px above the surface, with a nice shadow.&lt;br /&gt;
  &lt;br /&gt;
* roundfloatingabove: (to be used with floatingabove) if your element is a circle, use roundfloatingabove in addition to floatingabove.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note: if you found some generic CSS that may help some other developers for 3D enhancements, please send it to us so we can add it there.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Setting the default point of view and enabling 3d by default ==&lt;br /&gt;
&lt;br /&gt;
Your game may require to use 3D mode enabled by default and also with a certain custom default PoinOfView. You can achieve this setting in your constructor section of your game:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        if (!dojo.hasClass(&amp;quot;ebd-body&amp;quot;, &amp;quot;mode_3d&amp;quot;)) {&lt;br /&gt;
        dojo.addClass(&amp;quot;ebd-body&amp;quot;, &amp;quot;mode_3d&amp;quot;);&lt;br /&gt;
        dojo.addClass(&amp;quot;ebd-body&amp;quot;, &amp;quot;enableTransitions&amp;quot;);&lt;br /&gt;
        $(&amp;quot;globalaction_3d&amp;quot;).innerHTML = &amp;quot;2D&amp;quot;;   // controls the upper right button &lt;br /&gt;
        this.control3dxaxis = 30;  // rotation in degrees of x axis (it has a limit of 0 to 80 degrees in the frameword so users cannot turn it upsidedown)&lt;br /&gt;
        this.control3dzaxis = 0;   // rotation in degrees of z axis&lt;br /&gt;
        this.control3dxpos = 100;   // center of screen in pixels&lt;br /&gt;
        this.control3dypos = 300;   // center of screen in pixels&lt;br /&gt;
        this.control3dscale = 1.4;   // zoom level, 1 is default 2 is double normal size, &lt;br /&gt;
        this.control3dmode3d = true ;  			// is the 3d enabled	&lt;br /&gt;
        $(&amp;quot;game_play_area&amp;quot;).style.transform = &amp;quot;rotatex(&amp;quot; + this.control3dxaxis + &amp;quot;deg) translate(&amp;quot; + this.control3dypos + &amp;quot;px,&amp;quot; + this.control3dxpos + &amp;quot;px) rotateZ(&amp;quot; + this.control3dzaxis + &amp;quot;deg) scale3d(&amp;quot; + this.control3dscale + &amp;quot;,&amp;quot; + this.control3dscale + &amp;quot;,&amp;quot; + this.control3dscale + &amp;quot;)&amp;quot;;&lt;br /&gt;
			}&lt;/div&gt;</summary>
		<author><name>Morgalad</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=3D&amp;diff=2533</id>
		<title>3D</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=3D&amp;diff=2533"/>
		<updated>2017-07-07T15:19:27Z</updated>

		<summary type="html">&lt;p&gt;Morgalad: /* Setting the default point of view and enabling 3d by default */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= Overview =&lt;br /&gt;
&lt;br /&gt;
Board Game Arena is using CSS 3D features to provide a basic 3D view of the games.&lt;br /&gt;
&lt;br /&gt;
This is not a &amp;quot;100% real&amp;quot; 3D as this is very difficult to play with real 3D model with CSS, but most of the time it provides a satisfying 3D view of the game.&lt;br /&gt;
&lt;br /&gt;
The objective of 3D is to provide a nice view of the game : 90% of the time, 2D is more suitable for playing. So we don&#039;t force developers to make sure games can be played in 3D : this is just a &amp;quot;bonus&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
= Enabling 3D =&lt;br /&gt;
&lt;br /&gt;
3D is enabled by default for your game.&lt;br /&gt;
&lt;br /&gt;
You can click on the &amp;quot;3D&amp;quot; button at the top right and see your game in 3D.&lt;br /&gt;
&lt;br /&gt;
If you don&#039;t want to allow players to use 3D with your game, you can add this to you &amp;quot;gameinfos.inc.php&amp;quot; file :&lt;br /&gt;
&lt;br /&gt;
&#039;enable_3d&#039; =&amp;gt; false,&lt;br /&gt;
&lt;br /&gt;
= Detecting 3D =&lt;br /&gt;
&lt;br /&gt;
When 3D is &amp;quot;on&amp;quot;, BGA adds CSS class &amp;quot;mode_3d&amp;quot; to the body element.&lt;br /&gt;
&lt;br /&gt;
In CSS, you should prefix all your 3D mode specific directives by &amp;quot;.mode_3d&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 .mode_3d .board {&lt;br /&gt;
	overflow: visible;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In Javascript, you can detect 3D by using the following :&lt;br /&gt;
&lt;br /&gt;
  if( this.control3dmode3d )&lt;br /&gt;
  {&lt;br /&gt;
     // Only executed in 3d mode&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
= Built-in 3D enhancements =&lt;br /&gt;
&lt;br /&gt;
BGA is doing some built-in 3D enhancements with your 3D adaptations, so your adaptation will have some 3D effects without any efforts :&lt;br /&gt;
&lt;br /&gt;
* When executing a slideToObject, a slideToObjectPos or a slideTemporaryObject, BGA is moving the objects vertically (up, then down).&lt;br /&gt;
* It also happens when moving elements of a Stock module, or to a Zone module.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Enhance your adaptation for 3D =&lt;br /&gt;
&lt;br /&gt;
== Use Z axis ==&lt;br /&gt;
&lt;br /&gt;
Using CSS transform: translateZ, you can translate your HTML elements along the Z axis. Example :&lt;br /&gt;
&lt;br /&gt;
  .floating_element {&lt;br /&gt;
      transform: translateZ( 20px );  /* This element is going to float 20px above the surface */&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
The framework will add the following to all your divs:&lt;br /&gt;
      transform-style: preserve-3d; &lt;br /&gt;
&lt;br /&gt;
So they will keep their position in 3D space relative to other elemens with the transformation defined.  Note that some CSS artifacts can break the css inheritance of the &amp;quot;preserve-3d&amp;quot; like &amp;quot;overflow:auto&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
At any moment, you can know the Z position of an element from javascript using :&lt;br /&gt;
&lt;br /&gt;
  this.getComputedTranslateZ( html_element );&lt;br /&gt;
&lt;br /&gt;
== Use pre-build BGA 3D CSS classes ==&lt;br /&gt;
&lt;br /&gt;
By adding the following classes to your objects, they will look nicer in 3D:&lt;br /&gt;
&lt;br /&gt;
* thickness: add a (3px) black thickness to your HTML element.&lt;br /&gt;
  &lt;br /&gt;
* roundthickness: (to be used with thickness) if your element is a circle, you should add roundthickness so your element thickness can be a circle too.&lt;br /&gt;
  &lt;br /&gt;
* whitethickness: (to be used with thickness) if you prefer to have a whitethickness instead of black.&lt;br /&gt;
  &lt;br /&gt;
* floatingabove: make your element &amp;quot;float&amp;quot; 10px above the surface, with a nice shadow.&lt;br /&gt;
  &lt;br /&gt;
* roundfloatingabove: (to be used with floatingabove) if your element is a circle, use roundfloatingabove in addition to floatingabove.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note: if you found some generic CSS that may help some other developers for 3D enhancements, please send it to us so we can add it there.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Setting the default point of view and enabling 3d by default ==&lt;br /&gt;
&lt;br /&gt;
Your game may require to use 3D mode enabled by default and also with a certain custom default PoinOfView. You can achieve this setting in your constructor section of your game:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        if (!dojo.hasClass(&amp;quot;ebd-body&amp;quot;, &amp;quot;mode_3d&amp;quot;)) {&lt;br /&gt;
            dojo.addClass(&amp;quot;ebd-body&amp;quot;, &amp;quot;mode_3d&amp;quot;);&lt;br /&gt;
            dojo.addClass(&amp;quot;ebd-body&amp;quot;, &amp;quot;enableTransitions&amp;quot;);&lt;br /&gt;
	    $(&amp;quot;globalaction_3d&amp;quot;).innerHTML = &amp;quot;2D&amp;quot;;   // controls the upper right button &lt;br /&gt;
	    this.control3dxaxis = 30;  // rotation in degrees of x axis (it has a limit of 0 to 80 degrees in the frameword so users cannot turn it upsidedown)&lt;br /&gt;
	    this.control3dzaxis = 0;   // rotation in degrees of z axis&lt;br /&gt;
	    this.control3dxpos = 100;   // center of screen in pixels&lt;br /&gt;
            this.control3dypos = 300;   // center of screen in pixels&lt;br /&gt;
	    this.control3dscale = 1.4;   // zoom level, 1 is default 2 is double normal size, &lt;br /&gt;
            this.control3dmode3d = true ;  			// is the 3d enabled	&lt;br /&gt;
            $(&amp;quot;game_play_area&amp;quot;).style.transform = &amp;quot;rotatex(&amp;quot; + this.control3dxaxis + &amp;quot;deg) translate(&amp;quot; + this.control3dypos + &amp;quot;px,&amp;quot; + this.control3dxpos + &amp;quot;px) rotateZ(&amp;quot; + this.control3dzaxis + &amp;quot;deg) scale3d(&amp;quot; + this.control3dscale + &amp;quot;,&amp;quot; + this.control3dscale + &amp;quot;,&amp;quot; + this.control3dscale + &amp;quot;)&amp;quot;;&lt;br /&gt;
			}&lt;/div&gt;</summary>
		<author><name>Morgalad</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=3D&amp;diff=2532</id>
		<title>3D</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=3D&amp;diff=2532"/>
		<updated>2017-07-07T15:18:56Z</updated>

		<summary type="html">&lt;p&gt;Morgalad: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= Overview =&lt;br /&gt;
&lt;br /&gt;
Board Game Arena is using CSS 3D features to provide a basic 3D view of the games.&lt;br /&gt;
&lt;br /&gt;
This is not a &amp;quot;100% real&amp;quot; 3D as this is very difficult to play with real 3D model with CSS, but most of the time it provides a satisfying 3D view of the game.&lt;br /&gt;
&lt;br /&gt;
The objective of 3D is to provide a nice view of the game : 90% of the time, 2D is more suitable for playing. So we don&#039;t force developers to make sure games can be played in 3D : this is just a &amp;quot;bonus&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
= Enabling 3D =&lt;br /&gt;
&lt;br /&gt;
3D is enabled by default for your game.&lt;br /&gt;
&lt;br /&gt;
You can click on the &amp;quot;3D&amp;quot; button at the top right and see your game in 3D.&lt;br /&gt;
&lt;br /&gt;
If you don&#039;t want to allow players to use 3D with your game, you can add this to you &amp;quot;gameinfos.inc.php&amp;quot; file :&lt;br /&gt;
&lt;br /&gt;
&#039;enable_3d&#039; =&amp;gt; false,&lt;br /&gt;
&lt;br /&gt;
= Detecting 3D =&lt;br /&gt;
&lt;br /&gt;
When 3D is &amp;quot;on&amp;quot;, BGA adds CSS class &amp;quot;mode_3d&amp;quot; to the body element.&lt;br /&gt;
&lt;br /&gt;
In CSS, you should prefix all your 3D mode specific directives by &amp;quot;.mode_3d&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 .mode_3d .board {&lt;br /&gt;
	overflow: visible;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In Javascript, you can detect 3D by using the following :&lt;br /&gt;
&lt;br /&gt;
  if( this.control3dmode3d )&lt;br /&gt;
  {&lt;br /&gt;
     // Only executed in 3d mode&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
= Built-in 3D enhancements =&lt;br /&gt;
&lt;br /&gt;
BGA is doing some built-in 3D enhancements with your 3D adaptations, so your adaptation will have some 3D effects without any efforts :&lt;br /&gt;
&lt;br /&gt;
* When executing a slideToObject, a slideToObjectPos or a slideTemporaryObject, BGA is moving the objects vertically (up, then down).&lt;br /&gt;
* It also happens when moving elements of a Stock module, or to a Zone module.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Enhance your adaptation for 3D =&lt;br /&gt;
&lt;br /&gt;
== Use Z axis ==&lt;br /&gt;
&lt;br /&gt;
Using CSS transform: translateZ, you can translate your HTML elements along the Z axis. Example :&lt;br /&gt;
&lt;br /&gt;
  .floating_element {&lt;br /&gt;
      transform: translateZ( 20px );  /* This element is going to float 20px above the surface */&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
The framework will add the following to all your divs:&lt;br /&gt;
      transform-style: preserve-3d; &lt;br /&gt;
&lt;br /&gt;
So they will keep their position in 3D space relative to other elemens with the transformation defined.  Note that some CSS artifacts can break the css inheritance of the &amp;quot;preserve-3d&amp;quot; like &amp;quot;overflow:auto&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
At any moment, you can know the Z position of an element from javascript using :&lt;br /&gt;
&lt;br /&gt;
  this.getComputedTranslateZ( html_element );&lt;br /&gt;
&lt;br /&gt;
== Use pre-build BGA 3D CSS classes ==&lt;br /&gt;
&lt;br /&gt;
By adding the following classes to your objects, they will look nicer in 3D:&lt;br /&gt;
&lt;br /&gt;
* thickness: add a (3px) black thickness to your HTML element.&lt;br /&gt;
  &lt;br /&gt;
* roundthickness: (to be used with thickness) if your element is a circle, you should add roundthickness so your element thickness can be a circle too.&lt;br /&gt;
  &lt;br /&gt;
* whitethickness: (to be used with thickness) if you prefer to have a whitethickness instead of black.&lt;br /&gt;
  &lt;br /&gt;
* floatingabove: make your element &amp;quot;float&amp;quot; 10px above the surface, with a nice shadow.&lt;br /&gt;
  &lt;br /&gt;
* roundfloatingabove: (to be used with floatingabove) if your element is a circle, use roundfloatingabove in addition to floatingabove.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note: if you found some generic CSS that may help some other developers for 3D enhancements, please send it to us so we can add it there.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Setting the default point of view and enabling 3d by default ==&lt;br /&gt;
&lt;br /&gt;
Your game may require to use 3D mode enabled by default and also with a certain custom default PoinOfView. You can achieve this setting in your constructor section of your game:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        if (!dojo.hasClass(&amp;quot;ebd-body&amp;quot;, &amp;quot;mode_3d&amp;quot;)) {&lt;br /&gt;
            dojo.addClass(&amp;quot;ebd-body&amp;quot;, &amp;quot;mode_3d&amp;quot;);&lt;br /&gt;
            dojo.addClass(&amp;quot;ebd-body&amp;quot;, &amp;quot;enableTransitions&amp;quot;);&lt;br /&gt;
	    $(&amp;quot;globalaction_3d&amp;quot;).innerHTML = &amp;quot;2D&amp;quot;;   // controls the upper right button &lt;br /&gt;
	    this.control3dxaxis = 30;  // rotation in degrees of x axis (it has a limit of 0 to 80 degrees in the frameword so users cannot turn it upsidedown)&lt;br /&gt;
	    this.control3dzaxis = 0;   // rotation in degrees of z axis&lt;br /&gt;
	    this.control3dxpos = 100;   // center of screen in pixels&lt;br /&gt;
         	this.control3dypos = 300;   // center of screen in pixels&lt;br /&gt;
				this.control3dscale = 1.4;   // zoom level, 1 is default 2 is double normal size, &lt;br /&gt;
				this.control3dmode3d = true ;  			// is the 3d enabled	&lt;br /&gt;
	  $(&amp;quot;game_play_area&amp;quot;).style.transform = &amp;quot;rotatex(&amp;quot; + this.control3dxaxis + &amp;quot;deg) translate(&amp;quot; + this.control3dypos + &amp;quot;px,&amp;quot; + this.control3dxpos + &amp;quot;px) rotateZ(&amp;quot; + this.control3dzaxis + &amp;quot;deg) scale3d(&amp;quot; + this.control3dscale + &amp;quot;,&amp;quot; + this.control3dscale + &amp;quot;,&amp;quot; + this.control3dscale + &amp;quot;)&amp;quot;;&lt;br /&gt;
			}&lt;/div&gt;</summary>
		<author><name>Morgalad</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=3D&amp;diff=2515</id>
		<title>3D</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=3D&amp;diff=2515"/>
		<updated>2017-06-22T15:44:43Z</updated>

		<summary type="html">&lt;p&gt;Morgalad: /* Use Z axis */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= Overview =&lt;br /&gt;
&lt;br /&gt;
Board Game Arena is using CSS 3D features to provide a basic 3D view of the games.&lt;br /&gt;
&lt;br /&gt;
This is not a &amp;quot;100% real&amp;quot; 3D as this is very difficult to play with real 3D model with CSS, but most of the time it provides a satisfying 3D view of the game.&lt;br /&gt;
&lt;br /&gt;
The objective of 3D is to provide a nice view of the game : 90% of the time, 2D is more suitable for playing. So we don&#039;t force developers to make sure games can be played in 3D : this is just a &amp;quot;bonus&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
= Enabling 3D =&lt;br /&gt;
&lt;br /&gt;
3D is enabled by default for your game.&lt;br /&gt;
&lt;br /&gt;
You can click on the &amp;quot;3D&amp;quot; button at the top right and see your game in 3D.&lt;br /&gt;
&lt;br /&gt;
If you don&#039;t want to allow players to use 3D with your game, you can add this to you &amp;quot;gameinfos.inc.php&amp;quot; file :&lt;br /&gt;
&lt;br /&gt;
&#039;enable_3d&#039; =&amp;gt; false,&lt;br /&gt;
&lt;br /&gt;
= Detecting 3D =&lt;br /&gt;
&lt;br /&gt;
When 3D is &amp;quot;on&amp;quot;, BGA adds CSS class &amp;quot;mode_3d&amp;quot; to the body element.&lt;br /&gt;
&lt;br /&gt;
In CSS, you should prefix all your 3D mode specific directives by &amp;quot;.mode_3d&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 .mode_3d .board {&lt;br /&gt;
	overflow: visible;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In Javascript, you can detect 3D by using the following :&lt;br /&gt;
&lt;br /&gt;
  if( this.control3dmode3d )&lt;br /&gt;
  {&lt;br /&gt;
     // Only executed in 3d mode&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
= Built-in 3D enhancements =&lt;br /&gt;
&lt;br /&gt;
BGA is doing some built-in 3D enhancements with your 3D adaptations, so your adaptation will have some 3D effects without any efforts :&lt;br /&gt;
&lt;br /&gt;
* When executing a slideToObject, a slideToObjectPos or a slideTemporaryObject, BGA is moving the objects vertically (up, then down).&lt;br /&gt;
* It also happens when moving elements of a Stock module, or to a Zone module.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Enhance your adaptation for 3D =&lt;br /&gt;
&lt;br /&gt;
== Use Z axis ==&lt;br /&gt;
&lt;br /&gt;
Using CSS transform: translateZ, you can translate your HTML elements along the Z axis. Example :&lt;br /&gt;
&lt;br /&gt;
  .floating_element {&lt;br /&gt;
      transform: translateZ( 20px );  /* This element is going to float 20px above the surface */&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
The framework will add the following to all your divs:&lt;br /&gt;
      transform-style: preserve-3d; &lt;br /&gt;
&lt;br /&gt;
So they will keep their position in 3D space relative to other elemens with the transformation defined.  Note that some CSS artifacts can break the css inheritance of the &amp;quot;preserve-3d&amp;quot; like &amp;quot;overflow:auto&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
At any moment, you can know the Z position of an element from javascript using :&lt;br /&gt;
&lt;br /&gt;
  this.getComputedTranslateZ( html_element );&lt;br /&gt;
&lt;br /&gt;
== Use pre-build BGA 3D CSS classes ==&lt;br /&gt;
&lt;br /&gt;
By adding the following classes to your objects, they will look nicer in 3D:&lt;br /&gt;
&lt;br /&gt;
* thickness: add a (3px) black thickness to your HTML element.&lt;br /&gt;
  &lt;br /&gt;
* roundthickness: (to be used with thickness) if your element is a circle, you should add roundthickness so your element thickness can be a circle too.&lt;br /&gt;
  &lt;br /&gt;
* whitethickness: (to be used with thickness) if you prefer to have a whitethickness instead of black.&lt;br /&gt;
  &lt;br /&gt;
* floatingabove: make your element &amp;quot;float&amp;quot; 10px above the surface, with a nice shadow.&lt;br /&gt;
  &lt;br /&gt;
* roundfloatingabove: (to be used with floatingabove) if your element is a circle, use roundfloatingabove in addition to floatingabove.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note: if you found some generic CSS that may help some other developers for 3D enhancements, please send it to us so we can add it there.&lt;/div&gt;</summary>
		<author><name>Morgalad</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=3D&amp;diff=2514</id>
		<title>3D</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=3D&amp;diff=2514"/>
		<updated>2017-06-22T15:38:36Z</updated>

		<summary type="html">&lt;p&gt;Morgalad: /* Use pre-build BGA 3D classes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= Overview =&lt;br /&gt;
&lt;br /&gt;
Board Game Arena is using CSS 3D features to provide a basic 3D view of the games.&lt;br /&gt;
&lt;br /&gt;
This is not a &amp;quot;100% real&amp;quot; 3D as this is very difficult to play with real 3D model with CSS, but most of the time it provides a satisfying 3D view of the game.&lt;br /&gt;
&lt;br /&gt;
The objective of 3D is to provide a nice view of the game : 90% of the time, 2D is more suitable for playing. So we don&#039;t force developers to make sure games can be played in 3D : this is just a &amp;quot;bonus&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
= Enabling 3D =&lt;br /&gt;
&lt;br /&gt;
3D is enabled by default for your game.&lt;br /&gt;
&lt;br /&gt;
You can click on the &amp;quot;3D&amp;quot; button at the top right and see your game in 3D.&lt;br /&gt;
&lt;br /&gt;
If you don&#039;t want to allow players to use 3D with your game, you can add this to you &amp;quot;gameinfos.inc.php&amp;quot; file :&lt;br /&gt;
&lt;br /&gt;
&#039;enable_3d&#039; =&amp;gt; false,&lt;br /&gt;
&lt;br /&gt;
= Detecting 3D =&lt;br /&gt;
&lt;br /&gt;
When 3D is &amp;quot;on&amp;quot;, BGA adds CSS class &amp;quot;mode_3d&amp;quot; to the body element.&lt;br /&gt;
&lt;br /&gt;
In CSS, you should prefix all your 3D mode specific directives by &amp;quot;.mode_3d&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 .mode_3d .board {&lt;br /&gt;
	overflow: visible;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In Javascript, you can detect 3D by using the following :&lt;br /&gt;
&lt;br /&gt;
  if( this.control3dmode3d )&lt;br /&gt;
  {&lt;br /&gt;
     // Only executed in 3d mode&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
= Built-in 3D enhancements =&lt;br /&gt;
&lt;br /&gt;
BGA is doing some built-in 3D enhancements with your 3D adaptations, so your adaptation will have some 3D effects without any efforts :&lt;br /&gt;
&lt;br /&gt;
* When executing a slideToObject, a slideToObjectPos or a slideTemporaryObject, BGA is moving the objects vertically (up, then down).&lt;br /&gt;
* It also happens when moving elements of a Stock module, or to a Zone module.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Enhance your adaptation for 3D =&lt;br /&gt;
&lt;br /&gt;
== Use Z axis ==&lt;br /&gt;
&lt;br /&gt;
Using CSS transform: translateZ, you can translate your HTML elements along the Z axis. Example :&lt;br /&gt;
&lt;br /&gt;
  .floating_element {&lt;br /&gt;
      transform: translateZ( 20px );  /* This element is going to float 20px above the surface */&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
At any moment, you can know the Z position of an element from javascript using :&lt;br /&gt;
&lt;br /&gt;
  this.getComputedTranslateZ( html_element );&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Use pre-build BGA 3D CSS classes ==&lt;br /&gt;
&lt;br /&gt;
By adding the following classes to your objects, they will look nicer in 3D:&lt;br /&gt;
&lt;br /&gt;
* thickness: add a (3px) black thickness to your HTML element.&lt;br /&gt;
  &lt;br /&gt;
* roundthickness: (to be used with thickness) if your element is a circle, you should add roundthickness so your element thickness can be a circle too.&lt;br /&gt;
  &lt;br /&gt;
* whitethickness: (to be used with thickness) if you prefer to have a whitethickness instead of black.&lt;br /&gt;
  &lt;br /&gt;
* floatingabove: make your element &amp;quot;float&amp;quot; 10px above the surface, with a nice shadow.&lt;br /&gt;
  &lt;br /&gt;
* roundfloatingabove: (to be used with floatingabove) if your element is a circle, use roundfloatingabove in addition to floatingabove.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note: if you found some generic CSS that may help some other developers for 3D enhancements, please send it to us so we can add it there.&lt;/div&gt;</summary>
		<author><name>Morgalad</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Tutorial_reversi&amp;diff=2467</id>
		<title>Tutorial reversi</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Tutorial_reversi&amp;diff=2467"/>
		<updated>2017-06-13T10:55:21Z</updated>

		<summary type="html">&lt;p&gt;Morgalad: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
Using this tutorial, you can build a complete working game on the BGA environment: Reversi.&lt;br /&gt;
&lt;br /&gt;
Before you read this tutorial, you must:&lt;br /&gt;
* Read the overall presentations of the BGA Framework ([[Studio|see here]]).&lt;br /&gt;
* Know the [http://en.wikipedia.org/wiki/Reversi#Rules rules of Reversi].&lt;br /&gt;
* Know the languages used on BGA: PHP, SQL, HTML, CSS, Javascript&lt;br /&gt;
* Setup you development environment [http://en.doc.boardgamearena.com/First_steps_with_BGA_Studio First Steps with BGA Studio]&lt;br /&gt;
&lt;br /&gt;
== Create your first game ==&lt;br /&gt;
&lt;br /&gt;
With the initial skeleton of code provided initially, you can already start a game from the BGA Studio. For now, we are going to work with 1 player only. Most of the time this is simpler to proceed with only one player during the early phase of development of your game, as it&#039;s easy and fast to start/stop games.&lt;br /&gt;
&lt;br /&gt;
Thus, you can start a &amp;quot;Reversi&amp;quot; game, and arrive on a void, empty game. Yeah.&lt;br /&gt;
&lt;br /&gt;
== Let it look like Reversi ==&lt;br /&gt;
&lt;br /&gt;
It&#039;s always a good idea to start with a little bit of graphic work. Why? Because this helps to figure out how the final game will be, and issues that may appear later.&lt;br /&gt;
&lt;br /&gt;
Be careful designing the layout of your game: you must always keep in mind that players with a 1024px screen width must be able to play. Usually, it means that the width of the play area can be 750px (in the worst case).&lt;br /&gt;
&lt;br /&gt;
For Reversi, it&#039;s useless to have a 750x750px board - much too big, so we choose this one which fit perfectly (536x528):&lt;br /&gt;
&lt;br /&gt;
[[File:Board.jpg]]&lt;br /&gt;
&lt;br /&gt;
Note that we are using a jpg file. Jpg are lighter than png, so faster to load. Later we are going to use PNGs for discs for transparency purpose.&lt;br /&gt;
&lt;br /&gt;
Now, let&#039;s make it appears on our game:&lt;br /&gt;
* upload board.jpg in your &amp;quot;img/&amp;quot; directory.&lt;br /&gt;
* edit &amp;quot;reversi_reversi.tpl&amp;quot; to add a &#039;div&#039; for your board:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;board&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* edit your reversi.css file to transform it into a visible board:&lt;br /&gt;
&lt;br /&gt;
 #board {&lt;br /&gt;
    width: 536px;&lt;br /&gt;
    height: 528px;&lt;br /&gt;
    background-image: url(&#039;img/board.jpg&#039;);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Refresh your page. Here&#039;s your board:&lt;br /&gt;
&lt;br /&gt;
[[File:reversi1.jpg]]&lt;br /&gt;
&lt;br /&gt;
== Make the squares appears ==&lt;br /&gt;
&lt;br /&gt;
Now, what we need is to create some invisible HTML elements where squares are. These elements will be used as position references for white and black discs. &lt;br /&gt;
Obviously, we need 64 squares. To avoid writing 64 &#039;div&#039; elements on our template, we are going to use the &amp;quot;block&amp;quot; feature.&lt;br /&gt;
&lt;br /&gt;
Let&#039;s modify our template like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 &amp;lt;div id=&amp;quot;board&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;!-- BEGIN square --&amp;gt;&lt;br /&gt;
        &amp;lt;div id=&amp;quot;square_{X}_{Y}&amp;quot; class=&amp;quot;square&amp;quot; style=&amp;quot;left: {LEFT}px; top: {TOP}px;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;!-- END square --&amp;gt;&lt;br /&gt;
 &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As you can see, we created a &amp;quot;square&amp;quot; block, with 4 variable elements: X, Y, LEFT and TOP. Obviously, we are going to use this block 64 times during page load.&lt;br /&gt;
&lt;br /&gt;
Let&#039;s do it in our &amp;quot;reversi.view.php&amp;quot; file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        $this-&amp;gt;page-&amp;gt;begin_block( &amp;quot;reversi_reversi&amp;quot;, &amp;quot;square&amp;quot; );&lt;br /&gt;
        &lt;br /&gt;
        $hor_scale = 64.8;&lt;br /&gt;
        $ver_scale = 64.4;&lt;br /&gt;
        for( $x=1; $x&amp;lt;=8; $x++ )&lt;br /&gt;
        {&lt;br /&gt;
            for( $y=1; $y&amp;lt;=8; $y++ )&lt;br /&gt;
            {&lt;br /&gt;
                $this-&amp;gt;page-&amp;gt;insert_block( &amp;quot;square&amp;quot;, array(&lt;br /&gt;
                    &#039;X&#039; =&amp;gt; $x,&lt;br /&gt;
                    &#039;Y&#039; =&amp;gt; $y,&lt;br /&gt;
                    &#039;LEFT&#039; =&amp;gt; round( ($x-1)*$hor_scale+10 ),&lt;br /&gt;
                    &#039;TOP&#039; =&amp;gt; round( ($y-1)*$ver_scale+7 )&lt;br /&gt;
                ) );&lt;br /&gt;
            }        &lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: as you can see, squares in our &amp;quot;board.jpg&amp;quot; files does not have an exact width/height in pixel, and that&#039;s the reason we are using floating point numbers here.&lt;br /&gt;
&lt;br /&gt;
Now, to finish our work and check if everything works fine, we are going to style our square a little bit in our CSS stylesheet:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#board {&lt;br /&gt;
    width: 536px;&lt;br /&gt;
    height: 528px;&lt;br /&gt;
    background-image: url(&#039;img/board.jpg&#039;);&lt;br /&gt;
    position: relative;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.square {&lt;br /&gt;
    width: 62px;&lt;br /&gt;
    height: 62px;&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    background-color: red;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Explanations:&lt;br /&gt;
* With &amp;quot;position: relative&amp;quot; on board, we ensure square elements are positioned relatively to board.&lt;br /&gt;
* For the test, we use a red background color for the square. This is a useful tip to figure out if everything is fine with invisible elements.&lt;br /&gt;
&lt;br /&gt;
Let&#039;s refresh and check our our (beautiful) squares:&lt;br /&gt;
&lt;br /&gt;
[[File:reversi2.jpg]]&lt;br /&gt;
&lt;br /&gt;
== The discs ==&lt;br /&gt;
&lt;br /&gt;
Now, our board is ready to receive some disc tokens!&lt;br /&gt;
&lt;br /&gt;
At first, we introduce a new &#039;div&#039; element as a child of &amp;quot;board&amp;quot; to host all these tokens (in our template):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    &amp;lt;!-- END square --&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
    &amp;lt;div id=&amp;quot;tokens&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then, let&#039;s introduce a new piece of art with the discs. We need some transparency here so we are using a png file:&lt;br /&gt;
&lt;br /&gt;
[[File:tokens.png]]&lt;br /&gt;
&lt;br /&gt;
Upload this image file &amp;quot;tokens.png&amp;quot; in your &amp;quot;img/&amp;quot; directory.&lt;br /&gt;
&lt;br /&gt;
Important: we are using ONE file for both discs. It&#039;s really important that you use a minimum number of graphic files for your game with this &amp;quot;CSS sprite&amp;quot; technique, because it makes the game loading faster and more reliable. [http://www.w3schools.com/css/css_image_sprites.asp Read more about CSS sprites].&lt;br /&gt;
&lt;br /&gt;
Now, let&#039;s separate the disc with some CSS stuff:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
.token {&lt;br /&gt;
    width: 56px;&lt;br /&gt;
    height: 56px;&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    background-image: url(&#039;img/tokens.png&#039;);&lt;br /&gt;
}&lt;br /&gt;
.tokencolor_ffffff { background-position: 0px 0px;   }&lt;br /&gt;
.tokencolor_000000 { background-position: -56px 0px;   }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With this CSS code, we apply the classes &amp;quot;token&amp;quot; and &amp;quot;tokencolor_ffffff&amp;quot; to a div element and we&#039;ve got a white token. Yeah.&lt;br /&gt;
&lt;br /&gt;
Note the &amp;quot;position: absolute&amp;quot; which allows us to position tokens on the board and make them &amp;quot;slide&amp;quot; to their positions.&lt;br /&gt;
&lt;br /&gt;
Now, let&#039;s make a first token appear on our board. Disc tokens are not visible at the beginning of the game: they appear dynamically during the game. For this reason, we are going to make them appear from our Javascript code, with a BGA Framework technique called &amp;quot;JS template&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
In our template file (reversi_reversi.tpl), let&#039;s create the piece of HTML needed to display our token:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Templates&lt;br /&gt;
&lt;br /&gt;
var jstpl_token=&#039;&amp;lt;div class=&amp;quot;token tokencolor_${color}&amp;quot; id=&amp;quot;token_${x_y}&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: we already created the &amp;quot;templates&amp;quot; section for you in the game skeleton.&lt;br /&gt;
&lt;br /&gt;
As you can see, we defined a JS template named &amp;quot;jstpl_token&amp;quot; with a piece of HTML and two variables: the color of the token and its x/y coordinates. Note that the syntax of the argument is different for template block variables (brackets) and JS template variables (dollar and brackets).&lt;br /&gt;
&lt;br /&gt;
Now, let&#039;s create a method in our Javascript code that will make a token appear on the board, using this template:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        addTokenOnBoard: function( x, y, player )&lt;br /&gt;
        {&lt;br /&gt;
            dojo.place( this.format_block( &#039;jstpl_token&#039;, {&lt;br /&gt;
                x_y: x+&#039;_&#039;+y,&lt;br /&gt;
                color: this.gamedatas.players[ player ].color&lt;br /&gt;
            } ) , &#039;tokens&#039; );&lt;br /&gt;
            &lt;br /&gt;
            this.placeOnObject( &#039;token_&#039;+x+&#039;_&#039;+y, &#039;overall_player_board_&#039;+player );&lt;br /&gt;
            this.slideToObject( &#039;token_&#039;+x+&#039;_&#039;+y, &#039;square_&#039;+x+&#039;_&#039;+y ).play();&lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
At first, with &amp;quot;dojo.place&amp;quot; and &amp;quot;this.format_block&amp;quot; methods, we create a HTML piece of code and insert it as a new child of &amp;quot;tokens&amp;quot; div element.&lt;br /&gt;
&lt;br /&gt;
Then, with BGA &amp;quot;this.placeOnObject&amp;quot; method, we place this element over the panel of some player. Immediately after, using BGA &amp;quot;this.slideToObject&amp;quot; method, we make the disc slide to the &amp;quot;square&amp;quot; element, its final destination.&lt;br /&gt;
&lt;br /&gt;
Note: don&#039;t forget to call the &amp;quot;play()&amp;quot;, otherwise the token remains at its original location.&lt;br /&gt;
&lt;br /&gt;
Note: note that during all the process, the parent of the new disc HTML element will remain &amp;quot;tokens&amp;quot;. placeOnObject and slideToObject methods are only moving the position of elements on screen, and they are not modifying the HTML tree.&lt;br /&gt;
&lt;br /&gt;
Before we can show a token, we need to set the player colors in the setupNewGame function in reversi.game.php:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        $default_colors = array( &amp;quot;ffffff&amp;quot;, &amp;quot;000000&amp;quot; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, to test if everything works fine, just add &amp;quot;this.addTokenOnBoard( 2, 2, [player_id] )&amp;quot; in the &amp;quot;setup&amp;quot; Javascript method in reversi.js, and reload the page.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A token should appear and slide immediately to its position, like this:&lt;br /&gt;
&lt;br /&gt;
[[File:reversi3.jpg]]&lt;br /&gt;
&lt;br /&gt;
== The database ==&lt;br /&gt;
&lt;br /&gt;
We did most of the client-side programming, so let&#039;s have a look on the other side now.&lt;br /&gt;
&lt;br /&gt;
To design the database model of our game, the best thing to do is to follow the &amp;quot;Go to game database&amp;quot; link at the bottom of our game, to access the database directly with a [http://www.phpmyadmin.net/ PhpMyAdmin] instance.&lt;br /&gt;
&lt;br /&gt;
Then, you can create the tables you need for your table (do not remove existing tables!), and report every SQL command used in your &amp;quot;dbmodel.sql&amp;quot; file.&lt;br /&gt;
&lt;br /&gt;
[[File:reversi4.jpg]]&lt;br /&gt;
&lt;br /&gt;
The database model of Reversi is very simple: just one table with the squares of the board. In our dbmodel.sql, we have this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE TABLE IF NOT EXISTS `board` (&lt;br /&gt;
  `board_x` smallint(5) unsigned NOT NULL,&lt;br /&gt;
  `board_y` smallint(5) unsigned NOT NULL,&lt;br /&gt;
  `board_player` int(10) unsigned DEFAULT NULL,&lt;br /&gt;
  PRIMARY KEY (`board_x`,`board_y`)&lt;br /&gt;
) ENGINE=InnoDB;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, a new database with a &amp;quot;board&amp;quot; table will be created each time we start a Reversi game. This is why after modifying our dbmodel.sql it&#039;s a good time to stop &amp;amp; start again our game.&lt;br /&gt;
&lt;br /&gt;
== Setup the initial game position ==&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;setupNewGame&amp;quot; method of our reversi.game.php is called during initial setup: this is the place to initialize our data and to place the initial tokens on the board (initially, there are 4 tokens on the board).&lt;br /&gt;
&lt;br /&gt;
Let&#039;s do this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        // Init the board&lt;br /&gt;
        $sql = &amp;quot;INSERT INTO board (board_x,board_y,board_player) VALUES &amp;quot;;&lt;br /&gt;
        $sql_values = array();&lt;br /&gt;
        list( $blackplayer_id, $whiteplayer_id ) = array_keys( $players );&lt;br /&gt;
        for( $x=1; $x&amp;lt;=8; $x++ )&lt;br /&gt;
        {&lt;br /&gt;
            for( $y=1; $y&amp;lt;=8; $y++ )&lt;br /&gt;
            {&lt;br /&gt;
                $token_value = &amp;quot;NULL&amp;quot;;&lt;br /&gt;
                if( ($x==4 &amp;amp;&amp;amp; $y==4) || ($x==5 &amp;amp;&amp;amp; $y==5) )  // Initial positions of white player&lt;br /&gt;
                    $token_value = &amp;quot;&#039;$whiteplayer_id&#039;&amp;quot;;&lt;br /&gt;
                else if( ($x==4 &amp;amp;&amp;amp; $y==5) || ($x==5 &amp;amp;&amp;amp; $y==4) )  // Initial positions of black player&lt;br /&gt;
                    $token_value = &amp;quot;&#039;$blackplayer_id&#039;&amp;quot;;&lt;br /&gt;
                    &lt;br /&gt;
                $sql_values[] = &amp;quot;(&#039;$x&#039;,&#039;$y&#039;,$token_value)&amp;quot;;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        $sql .= implode( $sql_values, &#039;,&#039; );&lt;br /&gt;
        self::DbQuery( $sql );&lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
        // Active first player&lt;br /&gt;
        self::activeNextPlayer();  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As you can see, we create one table entry for each square, with a &amp;quot;NULL&amp;quot; value which means &amp;quot;empty square&amp;quot;. Of course, for 4 specific squares, we place an initial token.&lt;br /&gt;
&lt;br /&gt;
At the end, we call activeNextPlayer to make the first player active at the beginning of the game.&lt;br /&gt;
&lt;br /&gt;
Now, we need to make these tokens appear on the client side. To achieve this, the first step is to return the token positions with our &amp;quot;getAllDatas&amp;quot; PHP method (called during each page reload):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        // Get reversi board token&lt;br /&gt;
        $result[&#039;board&#039;] = self::getObjectListFromDB( &amp;quot;SELECT board_x x, board_y y, board_player player&lt;br /&gt;
                                                       FROM board&lt;br /&gt;
                                                       WHERE board_player IS NOT NULL&amp;quot; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As you can see, we are using the BGA framework &amp;quot;getObjectListFromDB&amp;quot; method that formats the result of this SQL query in a PHP array with x, y and player attributes.&lt;br /&gt;
&lt;br /&gt;
The last thing we need to do is to process this array client side, and place a disc token on the board for each array item. Of course, we are doing this is our Javascript &amp;quot;setup&amp;quot; method:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
            for( var i in gamedatas.board )&lt;br /&gt;
            {&lt;br /&gt;
                var square = gamedatas.board[i];&lt;br /&gt;
                &lt;br /&gt;
                if( square.player !== null )&lt;br /&gt;
                {&lt;br /&gt;
                    this.addTokenOnBoard( square.x, square.y, square.player );&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As you can see, our &amp;quot;board&amp;quot; entry created in &amp;quot;getAllDatas&amp;quot; can be used here as &amp;quot;gamedatas.board&amp;quot; in our Javascript. We are using our previously developed &amp;quot;addTokenOnBoard&amp;quot; method.&lt;br /&gt;
&lt;br /&gt;
Reload... and here we are:&lt;br /&gt;
&lt;br /&gt;
[[File:reversi5.jpg]]&lt;br /&gt;
&lt;br /&gt;
It starts to smell Reversi here...&lt;br /&gt;
&lt;br /&gt;
== The game state machine ==&lt;br /&gt;
&lt;br /&gt;
Now, let&#039;s stop our game again, because we are going to start the core game logic.&lt;br /&gt;
&lt;br /&gt;
You already read the &amp;quot;Focus on BGA game state machine&amp;quot;, so you know that this is the heart of your game logic. For reversi, it&#039;s very simple although. Here&#039;s a diagram of our game state machine:&lt;br /&gt;
&lt;br /&gt;
[[File:reversi6.jpg]]&lt;br /&gt;
&lt;br /&gt;
And here&#039;s our &amp;quot;states.inc.php&amp;quot;, according to this diagram:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$machinestates = array(&lt;br /&gt;
&lt;br /&gt;
    1 =&amp;gt; array(&lt;br /&gt;
        &amp;quot;name&amp;quot; =&amp;gt; &amp;quot;gameSetup&amp;quot;,&lt;br /&gt;
        &amp;quot;description&amp;quot; =&amp;gt; clienttranslate(&amp;quot;Game setup&amp;quot;),&lt;br /&gt;
        &amp;quot;type&amp;quot; =&amp;gt; &amp;quot;manager&amp;quot;,&lt;br /&gt;
        &amp;quot;action&amp;quot; =&amp;gt; &amp;quot;stGameSetup&amp;quot;,&lt;br /&gt;
        &amp;quot;transitions&amp;quot; =&amp;gt; array( &amp;quot;&amp;quot; =&amp;gt; 10 )&lt;br /&gt;
    ),&lt;br /&gt;
    &lt;br /&gt;
    10 =&amp;gt; array(&lt;br /&gt;
        &amp;quot;name&amp;quot; =&amp;gt; &amp;quot;playerTurn&amp;quot;,&lt;br /&gt;
		&amp;quot;description&amp;quot; =&amp;gt; clienttranslate(&#039;${actplayer} must play a disc&#039;),&lt;br /&gt;
		&amp;quot;descriptionmyturn&amp;quot; =&amp;gt; clienttranslate(&#039;${you} must play a disc&#039;),&lt;br /&gt;
        &amp;quot;type&amp;quot; =&amp;gt; &amp;quot;activeplayer&amp;quot;,&lt;br /&gt;
        &amp;quot;args&amp;quot; =&amp;gt; &amp;quot;argPlayerTurn&amp;quot;,&lt;br /&gt;
        &amp;quot;possibleactions&amp;quot; =&amp;gt; array( &#039;playDisc&#039; ),&lt;br /&gt;
        &amp;quot;transitions&amp;quot; =&amp;gt; array( &amp;quot;playDisc&amp;quot; =&amp;gt; 11, &amp;quot;zombiePass&amp;quot; =&amp;gt; 11 )&lt;br /&gt;
    ),&lt;br /&gt;
    &lt;br /&gt;
    11 =&amp;gt; array(&lt;br /&gt;
        &amp;quot;name&amp;quot; =&amp;gt; &amp;quot;nextPlayer&amp;quot;,&lt;br /&gt;
        &amp;quot;type&amp;quot; =&amp;gt; &amp;quot;game&amp;quot;,&lt;br /&gt;
        &amp;quot;action&amp;quot; =&amp;gt; &amp;quot;stNextPlayer&amp;quot;,&lt;br /&gt;
        &amp;quot;updateGameProgression&amp;quot; =&amp;gt; true,        &lt;br /&gt;
        &amp;quot;transitions&amp;quot; =&amp;gt; array( &amp;quot;nextTurn&amp;quot; =&amp;gt; 10, &amp;quot;cantPlay&amp;quot; =&amp;gt; 11, &amp;quot;endGame&amp;quot; =&amp;gt; 99 )&lt;br /&gt;
    ),&lt;br /&gt;
   &lt;br /&gt;
    99 =&amp;gt; array(&lt;br /&gt;
        &amp;quot;name&amp;quot; =&amp;gt; &amp;quot;gameEnd&amp;quot;,&lt;br /&gt;
        &amp;quot;description&amp;quot; =&amp;gt; clienttranslate(&amp;quot;End of game&amp;quot;),&lt;br /&gt;
        &amp;quot;type&amp;quot; =&amp;gt; &amp;quot;manager&amp;quot;,&lt;br /&gt;
        &amp;quot;action&amp;quot; =&amp;gt; &amp;quot;stGameEnd&amp;quot;,&lt;br /&gt;
        &amp;quot;args&amp;quot; =&amp;gt; &amp;quot;argGameEnd&amp;quot;&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, let&#039;s create in reversi.game.php the methods that are declared in this game states description file:&lt;br /&gt;
* argPlayerTurn&lt;br /&gt;
* stNextPlayer&lt;br /&gt;
&lt;br /&gt;
... and start a new Reversi game.&lt;br /&gt;
&lt;br /&gt;
As you can see on the screen capture below, the BGA framework makes the game jump to our first game state &amp;quot;playerTurn&amp;quot; right after the initial setup. That&#039;s why the status bar contains the description of playerTurn state (&amp;quot;XXXX must play a disc&amp;quot;):&lt;br /&gt;
&lt;br /&gt;
[[File:reversi7.jpg]]&lt;br /&gt;
&lt;br /&gt;
== The rules ==&lt;br /&gt;
&lt;br /&gt;
Now, what we would like to do is to indicate to the current player where she is allowed to play. The idea is to build a &amp;quot;getPossibleMoves&amp;quot; PHP method that return a list of coordinates where she is allowed to play. This method will be used in particular:&lt;br /&gt;
* As we just said, to help the player to see where she can play.&lt;br /&gt;
* When the player plays, to check if she has the right to play here.&lt;br /&gt;
&lt;br /&gt;
This is pure PHP programming here, and there are no special things from the BGA framework that can be used. This is why we won&#039;t go into details here. The overall idea is:&lt;br /&gt;
* Create a &amp;quot;getTurnedOverDiscs(x,y)&amp;quot; method that return coordinates of discs that would be turned over if a token would be played at x,y.&lt;br /&gt;
* Loop through all free squares of the board, call the &amp;quot;getTurnedOverDiscs&amp;quot; method on each of them. If at least 1 token is turned over, this is a valid move.&lt;br /&gt;
&lt;br /&gt;
One important thing to keep in mind is the following: making a database query is slow, so please don&#039;t load the entire game board with a SQL query multiple time. In our implementation, we load the entire board once at the beginning of &amp;quot;getPossibleMoves&amp;quot;, and then pass the board as an argument to all methods.&lt;br /&gt;
&lt;br /&gt;
If you want to look into details, please look at the &amp;quot;utility method&amp;quot; sections of reversi.game.php.&lt;br /&gt;
&lt;br /&gt;
== Display allowed moves ==&lt;br /&gt;
&lt;br /&gt;
Now, what we want to do is highlight the squares where the player can place a disc.&lt;br /&gt;
&lt;br /&gt;
To do this, we are using the &amp;quot;argPlayerTurn&amp;quot; method. This method is called each time we enter into &amp;quot;playerTurn&amp;quot; game state, and its result is transfered automatically to the client-side:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    function argPlayerTurn()&lt;br /&gt;
    {&lt;br /&gt;
        return array(&lt;br /&gt;
            &#039;possibleMoves&#039; =&amp;gt; self::getPossibleMoves( self::getActivePlayerId() )&lt;br /&gt;
        );&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We are of course using the &amp;quot;getPossibleMoves&amp;quot; method we just developed.&lt;br /&gt;
&lt;br /&gt;
Now, let&#039;s go to the client side to use the data returned by the method above. We are using the &amp;quot;onEnteringState&amp;quot; Javascript method that is called each time we enter into a new game state:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        onEnteringState: function( stateName, args )&lt;br /&gt;
        {&lt;br /&gt;
           console.log( &#039;Entering state: &#039;+stateName );&lt;br /&gt;
            &lt;br /&gt;
            switch( stateName )&lt;br /&gt;
            {&lt;br /&gt;
            case &#039;playerTurn&#039;:&lt;br /&gt;
                this.updatePossibleMoves( args.args.possibleMoves );&lt;br /&gt;
                break;&lt;br /&gt;
            }&lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So, when we are entering into &amp;quot;playerTurn&amp;quot; game state, we are calling our &amp;quot;updatePossibleMoves&amp;quot; method. This method looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        updatePossibleMoves: function( possibleMoves )&lt;br /&gt;
        {&lt;br /&gt;
            // Remove current possible moves&lt;br /&gt;
            dojo.query( &#039;.possibleMove&#039; ).removeClass( &#039;possibleMove&#039; );&lt;br /&gt;
&lt;br /&gt;
            for( var x in possibleMoves )&lt;br /&gt;
            {&lt;br /&gt;
                for( var y in possibleMoves[ x ] )&lt;br /&gt;
                {&lt;br /&gt;
                    // x,y is a possible move&lt;br /&gt;
                    dojo.addClass( &#039;square_&#039;+x+&#039;_&#039;+y, &#039;possibleMove&#039; );&lt;br /&gt;
                }            &lt;br /&gt;
            }&lt;br /&gt;
                        &lt;br /&gt;
            this.addTooltipToClass( &#039;possibleMove&#039;, &#039;&#039;, _(&#039;Place a disc here&#039;) );&lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The idea here is that we&#039;ve created a CSS class (&amp;quot;possibleMove&amp;quot;) that can be applied to a &amp;quot;square&amp;quot; element to highlight it:&lt;br /&gt;
&amp;lt;pre&amp;gt;&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;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
At first, we remove all &amp;quot;possibleMove&amp;quot; classes currently applied with the very useful combination of &amp;quot;dojo.query&amp;quot; and &amp;quot;removeClass&amp;quot; method.&lt;br /&gt;
&lt;br /&gt;
Then we loop through all possible moves our PHP &amp;quot;updatePossibleMoves&amp;quot; function created for us, and add the &amp;quot;possibleMove&amp;quot; class to each corresponding square.&lt;br /&gt;
&lt;br /&gt;
Finally, we use the BGA framework &amp;quot;addTooltipToClass&amp;quot; method to associate a tooltip to all those highlighted squares so that players can understand their meaning.&lt;br /&gt;
&lt;br /&gt;
And here we are:&lt;br /&gt;
&lt;br /&gt;
[[File:reversi8.jpg.jpg]]&lt;br /&gt;
&lt;br /&gt;
== Let&#039;s play ==&lt;br /&gt;
&lt;br /&gt;
From now, it&#039;s better to restart a game with 2 players, because we are going to implement a complete Reversi turn. The summary of what we are going to do is:&lt;br /&gt;
* When we click on a &amp;quot;possibleMove&amp;quot; square, send the move to the server.&lt;br /&gt;
* Server side, check the move is correct, apply Reversi rules and jump to next player.&lt;br /&gt;
* Client side, change the disc position to reflect the move.&lt;br /&gt;
&lt;br /&gt;
Thus, what we do first is associate each click on a square to one of our method. We are doing this in our Javascript &amp;quot;setup&amp;quot; method:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
            dojo.query( &#039;.square&#039; ).connect( &#039;onclick&#039;, this, &#039;onPlayDisc&#039; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note the use of the &amp;quot;dojo.query&amp;quot; method to get all HTML elements with &amp;quot;square&amp;quot; class in just one function call. Now, our &amp;quot;onPlayDisc&amp;quot; method is called each time someone clicks on a square.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s our &amp;quot;onPlayDisc&amp;quot; method below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        onPlayDisc: function( evt )&lt;br /&gt;
        {&lt;br /&gt;
            // Stop this event propagation&lt;br /&gt;
            dojo.stopEvent( evt );&lt;br /&gt;
&lt;br /&gt;
            // Get the cliqued square x and y&lt;br /&gt;
            // Note: square id format is &amp;quot;square_X_Y&amp;quot;&lt;br /&gt;
            var coords = evt.currentTarget.id.split(&#039;_&#039;);&lt;br /&gt;
            var x = coords[1];&lt;br /&gt;
            var y = coords[2];&lt;br /&gt;
&lt;br /&gt;
            if( ! dojo.hasClass( &#039;square_&#039;+x+&#039;_&#039;+y, &#039;possibleMove&#039; ) )&lt;br /&gt;
            {&lt;br /&gt;
                // This is not a possible move =&amp;gt; the click does nothing&lt;br /&gt;
                return ;&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
            if( this.checkAction( &#039;playDisc&#039; ) )    // Check that this action is possible at this moment&lt;br /&gt;
            {            &lt;br /&gt;
                this.ajaxcall( &amp;quot;/reversi/reversi/playDisc.html&amp;quot;, {&lt;br /&gt;
                    x:x,&lt;br /&gt;
                    y:y&lt;br /&gt;
                }, this, function( result ) {} );&lt;br /&gt;
            }            &lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
What we do here is:&lt;br /&gt;
* We stop the propagation of the Javascript &amp;quot;onclick&amp;quot; event. Otherwise, it can lead to random behavior so it&#039;s always a good idea.&lt;br /&gt;
* We get the x/y coordinates of the square by using &amp;quot;evt.currentTarget.id&amp;quot;.&lt;br /&gt;
* We check that clicked square has the &amp;quot;possibleMove&amp;quot; class, otherwise we know for sure that we can&#039;t play there.&lt;br /&gt;
* We check that &amp;quot;playDisc&amp;quot; action is possible, according to current game state (see &amp;quot;possibleactions&amp;quot; entry in our &amp;quot;playerTurn&amp;quot; game state defined above). This check is important to avoid issues if a player double clicks on a square.&lt;br /&gt;
* Finally, we make a call to the server using BGA &amp;quot;ajaxcall&amp;quot; method with argument x and y.&lt;br /&gt;
&lt;br /&gt;
Now, we have to manage this &amp;quot;playDisc&amp;quot; action on the server side. At first, we introduce a &amp;quot;playDisc&amp;quot; entry point in our &amp;quot;reversi.action.php&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    public function playDisc()&lt;br /&gt;
    {&lt;br /&gt;
        self::setAjaxMode();     &lt;br /&gt;
        $x = self::getArg( &amp;quot;x&amp;quot;, AT_posint, true );&lt;br /&gt;
        $y = self::getArg( &amp;quot;y&amp;quot;, AT_posint, true );&lt;br /&gt;
        $result = $this-&amp;gt;game-&amp;gt;playDisc( $x, $y );&lt;br /&gt;
        self::ajaxResponse( );&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As you can see, we get the 2 arguments x and y from the javascript call, and call a corresponding &amp;quot;playDisc&amp;quot; method in our game logic.&lt;br /&gt;
&lt;br /&gt;
Now, let&#039;s have a look of this playDisc method:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    function playDisc( $x, $y )&lt;br /&gt;
    {&lt;br /&gt;
        // Check that this player is active and that this action is possible at this moment&lt;br /&gt;
        self::checkAction( &#039;playDisc&#039; );  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
... at first, we check that this action is possible according to current game state (see &amp;quot;possible action&amp;quot;). We already did it on client side, but it&#039;s important to do it on server side too (otherwise it would be possible to cheat).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        // Now, check if this is a possible move&lt;br /&gt;
        $board = self::getBoard();&lt;br /&gt;
        $player_id = self::getActivePlayerId();&lt;br /&gt;
        $turnedOverDiscs = self::getTurnedOverDiscs( $x, $y, $player_id, $board );&lt;br /&gt;
        &lt;br /&gt;
        if( count( $turnedOverDiscs ) &amp;gt; 0 )&lt;br /&gt;
        {&lt;br /&gt;
            // This move is possible!&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
...now, we are using the &amp;quot;getTurnedOverDiscs&amp;quot; method again to check that this move is possible.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
            // Let&#039;s place a disc at x,y and return all &amp;quot;$returned&amp;quot; discs to the active player&lt;br /&gt;
            &lt;br /&gt;
            $sql = &amp;quot;UPDATE board SET board_player=&#039;$player_id&#039;&lt;br /&gt;
                    WHERE ( board_x, board_y) IN ( &amp;quot;;&lt;br /&gt;
            &lt;br /&gt;
            foreach( $turnedOverDiscs as $turnedOver )&lt;br /&gt;
            {&lt;br /&gt;
                $sql .= &amp;quot;(&#039;&amp;quot;.$turnedOver[&#039;x&#039;].&amp;quot;&#039;,&#039;&amp;quot;.$turnedOver[&#039;y&#039;].&amp;quot;&#039;),&amp;quot;;&lt;br /&gt;
            }&lt;br /&gt;
            $sql .= &amp;quot;(&#039;$x&#039;,&#039;$y&#039;) ) &amp;quot;;&lt;br /&gt;
                       &lt;br /&gt;
            self::DbQuery( $sql );&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
... we update the database to change the color of all turned over disc + the disc we just placed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
            // Update scores according to the number of disc on board&lt;br /&gt;
            $sql = &amp;quot;UPDATE player&lt;br /&gt;
                    SET player_score = (&lt;br /&gt;
                    SELECT COUNT( board_x ) FROM board WHERE board_player=player_id&lt;br /&gt;
                    )&amp;quot;;&lt;br /&gt;
            self::DbQuery( $sql );&lt;br /&gt;
            &lt;br /&gt;
            // Statistics&lt;br /&gt;
            self::incStat( count( $turnedOverDiscs ), &amp;quot;turnedOver&amp;quot;, $player_id );&lt;br /&gt;
            if( ($x==1 &amp;amp;&amp;amp; $y==1) || ($x==8 &amp;amp;&amp;amp; $y==1) || ($x==1 &amp;amp;&amp;amp; $y==8) || ($x==8 &amp;amp;&amp;amp; $y==8) )&lt;br /&gt;
                self::incStat( 1, &#039;discPlayedOnCorner&#039;, $player_id );&lt;br /&gt;
            else if( $x==1 || $x==8 || $y==1 || $y==8 )&lt;br /&gt;
                self::incStat( 1, &#039;discPlayedOnBorder&#039;, $player_id );&lt;br /&gt;
            else if( $x&amp;gt;=3 &amp;amp;&amp;amp; $x&amp;lt;=6 &amp;amp;&amp;amp; $y&amp;gt;=3 &amp;amp;&amp;amp; $y&amp;lt;=6 )&lt;br /&gt;
                self::incStat( 1, &#039;discPlayedOnCenter&#039;, $player_id );&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
... now, we update both player score by counting all disc, and we manage game statistics.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
            // Notify&lt;br /&gt;
            self::notifyAllPlayers( &amp;quot;playDisc&amp;quot;, clienttranslate( &#039;${player_name} plays a disc and turns over ${returned_nbr} disc(s)&#039; ), array(&lt;br /&gt;
                &#039;player_id&#039; =&amp;gt; $player_id,&lt;br /&gt;
                &#039;player_name&#039; =&amp;gt; self::getActivePlayerName(),&lt;br /&gt;
                &#039;returned_nbr&#039; =&amp;gt; count( $turnedOverDiscs ),&lt;br /&gt;
                &#039;x&#039; =&amp;gt; $x,&lt;br /&gt;
                &#039;y&#039; =&amp;gt; $y&lt;br /&gt;
            ) );&lt;br /&gt;
&lt;br /&gt;
            self::notifyAllPlayers( &amp;quot;turnOverDiscs&amp;quot;, &#039;&#039;, array(&lt;br /&gt;
                &#039;player_id&#039; =&amp;gt; $player_id,&lt;br /&gt;
                &#039;turnedOver&#039; =&amp;gt; $turnedOverDiscs&lt;br /&gt;
            ) );&lt;br /&gt;
            &lt;br /&gt;
            $newScores = self::getCollectionFromDb( &amp;quot;SELECT player_id, player_score FROM player&amp;quot;, true );&lt;br /&gt;
            self::notifyAllPlayers( &amp;quot;newScores&amp;quot;, &amp;quot;&amp;quot;, array(&lt;br /&gt;
                &amp;quot;scores&amp;quot; =&amp;gt; $newScores&lt;br /&gt;
            ) );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
... then we notify about all these changes. We are using for that 3 notifications (&#039;playDisc&#039;, &#039;turnOverDiscs&#039; and &#039;newScores&#039; that we are going to implement on client side later). Note that the description of the &#039;playDisc&#039; notification will be logged in the game log.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
            // Then, go to the next state&lt;br /&gt;
            $this-&amp;gt;gamestate-&amp;gt;nextState( &#039;playDisc&#039; );&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            throw new feException( &amp;quot;Impossible move&amp;quot; );&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
... finally, we jump to the next game state if everything goes fine (&#039;playDisc&#039; is also the name of a transition in the &#039;playerTurn&#039; game state description above).&lt;br /&gt;
To make the statistics work, we have to initialize them in stats.inc.php:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    // Statistics existing for each player&lt;br /&gt;
    &amp;quot;player&amp;quot; =&amp;gt; array(&lt;br /&gt;
    &lt;br /&gt;
        &amp;quot;discPlayedOnCorner&amp;quot; =&amp;gt; array(   &amp;quot;id&amp;quot;=&amp;gt; 10,&lt;br /&gt;
                                &amp;quot;name&amp;quot; =&amp;gt; totranslate(&amp;quot;Discs played on a corner&amp;quot;), &lt;br /&gt;
                                &amp;quot;type&amp;quot; =&amp;gt; &amp;quot;int&amp;quot; ),&lt;br /&gt;
                                &lt;br /&gt;
        &amp;quot;discPlayedOnBorder&amp;quot; =&amp;gt; array(   &amp;quot;id&amp;quot;=&amp;gt; 11,&lt;br /&gt;
                                &amp;quot;name&amp;quot; =&amp;gt; totranslate(&amp;quot;Discs played on a border&amp;quot;), &lt;br /&gt;
                                &amp;quot;type&amp;quot; =&amp;gt; &amp;quot;int&amp;quot; ),&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;discPlayedOnCenter&amp;quot; =&amp;gt; array(   &amp;quot;id&amp;quot;=&amp;gt; 12,&lt;br /&gt;
                                &amp;quot;name&amp;quot; =&amp;gt; totranslate(&amp;quot;Discs played on board center part&amp;quot;), &lt;br /&gt;
                                &amp;quot;type&amp;quot; =&amp;gt; &amp;quot;int&amp;quot; ),&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;turnedOver&amp;quot; =&amp;gt; array(   &amp;quot;id&amp;quot;=&amp;gt; 13,&lt;br /&gt;
                                &amp;quot;name&amp;quot; =&amp;gt; totranslate(&amp;quot;Number of discs turned over&amp;quot;), &lt;br /&gt;
                                &amp;quot;type&amp;quot; =&amp;gt; &amp;quot;int&amp;quot; )    &lt;br /&gt;
    )&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A last thing to do on the server side is to activate the next player when we enter the &amp;quot;nextPlayer&amp;quot; game state:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    function stNextPlayer()&lt;br /&gt;
    {&lt;br /&gt;
        // Activate next player&lt;br /&gt;
        $player_id = self::activeNextPlayer();&lt;br /&gt;
        &lt;br /&gt;
        self::giveExtraTime( $player_id );&lt;br /&gt;
        $this-&amp;gt;gamestate-&amp;gt;nextState( &#039;nextTurn&#039; );&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, when we play a disc, the rules are checked and the disc appears in the database.&lt;br /&gt;
&lt;br /&gt;
[[File:reversi9.jpg]]&lt;br /&gt;
&lt;br /&gt;
Of course, as we don&#039;t manage notifications on client side, we need to press F5 after each move to see the changes on the board.&lt;br /&gt;
&lt;br /&gt;
== Make the move appear automatically ==&lt;br /&gt;
&lt;br /&gt;
Now, what we have to do is process the notifications sent by the server and make the move appear on the interface.&lt;br /&gt;
&lt;br /&gt;
In our &amp;quot;setupNotifications&amp;quot; method, we register 2 methods for the 2 notifications we created at the previous step (&#039;playDisc&#039; and &#039;turnOverDiscs&#039;):&lt;br /&gt;
&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 );&lt;br /&gt;
            dojo.subscribe( &#039;turnOverDiscs&#039;, this, &amp;quot;notif_turnOverDiscs&amp;quot; );&lt;br /&gt;
            this.notifqueue.setSynchronous( &#039;turnOverDiscs&#039;, 1500 );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As you can see, we associate our 2 notifications with 2 methods with the &amp;quot;notif_&amp;quot; prefix. At the same time, we define these notifications as &amp;quot;synchronous&amp;quot;, with a duration in millisecond (500 for the first one, and 1500 for the second one). It tells the user interface to wait some time after executing the notification, to let the animation end before starting the next notification. In our specific case, the animation will be the following:&lt;br /&gt;
* Make a disc slide from the player panel to its place on the board&lt;br /&gt;
* (wait 500ms)&lt;br /&gt;
* Make all turned over discs blink (and of course turned them over)&lt;br /&gt;
* (wait 1500ms)&lt;br /&gt;
* Let the next player play.&lt;br /&gt;
&lt;br /&gt;
Let&#039;s have a look now on the &amp;quot;playDisc&amp;quot; notification handler 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.addTokenOnBoard( 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;
No surprise here, we re-used some existing stuff to:&lt;br /&gt;
* Remove the highlighted squares.&lt;br /&gt;
* Add a new disc on board, coming from player panel.&lt;br /&gt;
&lt;br /&gt;
Now, here&#039;s the method that handles the turnOverDiscs notification:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        notif_turnOverDiscs: function( notif )&lt;br /&gt;
        {&lt;br /&gt;
            // Get the color of the player who is returning the discs&lt;br /&gt;
            var targetColor = this.gamedatas.players[ notif.args.player_id ].color;&lt;br /&gt;
&lt;br /&gt;
            // Make these discs blink and set them to the specified color&lt;br /&gt;
            for( var i in notif.args.turnedOver )&lt;br /&gt;
            {&lt;br /&gt;
                var token = notif.args.turnedOver[ i ];&lt;br /&gt;
                &lt;br /&gt;
                // Make the token blink 2 times&lt;br /&gt;
                var anim = dojo.fx.chain( [&lt;br /&gt;
                    dojo.fadeOut( { node: &#039;token_&#039;+token.x+&#039;_&#039;+token.y } ),&lt;br /&gt;
                    dojo.fadeIn( { node: &#039;token_&#039;+token.x+&#039;_&#039;+token.y } ),&lt;br /&gt;
                    dojo.fadeOut( { &lt;br /&gt;
                                    node: &#039;token_&#039;+token.x+&#039;_&#039;+token.y,&lt;br /&gt;
                                    onEnd: function( node ) {&lt;br /&gt;
&lt;br /&gt;
                                        // Remove any color class&lt;br /&gt;
                                        dojo.removeClass( node, [ &#039;tokencolor_000000&#039;, &#039;tokencolor_ffffff&#039; ] );&lt;br /&gt;
                                        // ... and add the good one&lt;br /&gt;
                                        dojo.addClass( node, &#039;tokencolor_&#039;+targetColor );&lt;br /&gt;
                                                             &lt;br /&gt;
                                    } &lt;br /&gt;
                                  } ),&lt;br /&gt;
                    dojo.fadeIn( { node: &#039;token_&#039;+token.x+&#039;_&#039;+token.y  } )&lt;br /&gt;
                                 &lt;br /&gt;
                ] ); // end of dojo.fx.chain&lt;br /&gt;
&lt;br /&gt;
                // ... and launch the animation&lt;br /&gt;
                anim.play();                &lt;br /&gt;
            }&lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The list of the discs to be turned over has been made available by our server side code in &amp;quot;notif.args.turnedOver&amp;quot; (see previous paragraph). We loop through all these discs, and create a complex animation using dojo.Animation for each of them. The complete documentation on dojo animations [http://dojotoolkit.org/documentation/tutorials/1.6/animation/ can be found here].&lt;br /&gt;
&lt;br /&gt;
And Also the notification to update the scores:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
notif_newScores: function( notif )&lt;br /&gt;
        {&lt;br /&gt;
            for( var player_id in notif.args.scores )&lt;br /&gt;
            {&lt;br /&gt;
                var newScore = notif.args.scores[ player_id ];&lt;br /&gt;
                this.scoreCtrl[ player_id ].toValue( newScore );&lt;br /&gt;
            }&lt;br /&gt;
        },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In few words: we create a chain of 4 animations to make the disc fade out, fade in, fade out again, and fade in again. At the end of the second fade out, we change the color of the disc. Finally, we launch the animation with &amp;quot;play()&amp;quot;.&lt;/div&gt;</summary>
		<author><name>Morgalad</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Gamehelpincangold&amp;diff=2408</id>
		<title>Gamehelpincangold</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Gamehelpincangold&amp;diff=2408"/>
		<updated>2017-06-01T06:55:53Z</updated>

		<summary type="html">&lt;p&gt;Morgalad: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The expedition deck is composed of the following cards:&lt;br /&gt;
&lt;br /&gt;
* 14 &#039;&#039;&#039;Treasure&#039;&#039;&#039; cards (1, 2, 3, 4, 5, 5, 7, 7, 9, 11, 11, 13, 14, 15 gems)&lt;br /&gt;
* 15 &#039;&#039;&#039;Hazard&#039;&#039;&#039; cards (3 each of fire, mummy, rocks, snakes, and spiders)&lt;br /&gt;
* 5 &#039;&#039;&#039;Artifact&#039;&#039;&#039; cards&lt;br /&gt;
&lt;br /&gt;
At the start of the game, all Treasure and Hazard cards are shuffled into the deck, but none of the Artifacts are in the deck.&lt;br /&gt;
&lt;br /&gt;
The game is divided into five expeditions. After five expeditions, the player with the most points wins. All expeditions are played in the same fashion.&lt;br /&gt;
&lt;br /&gt;
At the start of an expedition, one Artifact card is added into the deck, then the deck is shuffled. All players will start going into the expedition. Then the expedition plays in several rounds.&lt;br /&gt;
&lt;br /&gt;
Each round, a card from the deck is revealed. One of the following can happen:&lt;br /&gt;
&lt;br /&gt;
* A &#039;&#039;&#039;Treasure&#039;&#039;&#039; card is revealed. The Treasure card shows a number of gems. Divide them equally to the players still in the expedition; any leftovers are left on the card.&lt;br /&gt;
* A &#039;&#039;&#039;Hazard&#039;&#039;&#039; card is revealed. If it&#039;s the first Hazard card of the kind during the expedition, nothing happens. If it&#039;s the second, then the expedition fails; see below.&lt;br /&gt;
* An &#039;&#039;&#039;Artifact&#039;&#039;&#039; card is revealed. Nothing happens.&lt;br /&gt;
&lt;br /&gt;
After that, if the expedition doesn&#039;t fail yet (due to two Hazards of the same kind), each player will make a decision whether to &#039;&#039;&#039;stay&#039;&#039;&#039; in the expedition or &#039;&#039;&#039;retire&#039;&#039;&#039; back to the camp. They make the decision secretly, and the decisions are revealed simultaneously.&lt;br /&gt;
&lt;br /&gt;
People that choose to &#039;&#039;&#039;retire&#039;&#039;&#039; no longer participate in the expedition. First, they take the leftover gems (the remainders when Treasure cards are revealed and not all can be divided equally). They distribute them equally among the people that retire; any leftover gems are still left on the cards. All the gems claimed during the expedition and at this time are now safe and cannot be lost. Moreover, if there is exactly one person that retires, they also take &#039;&#039;&#039;all&#039;&#039;&#039; the Artifact cards revealed during the expedition.&lt;br /&gt;
&lt;br /&gt;
Once a player retires, their gems are brought into their tent. The contents of each player&#039;s tent are hidden, so it&#039;s best to memorize each player&#039;s winnings.&lt;br /&gt;
&lt;br /&gt;
After this, if there are still some people in the expedition, continue with the next round. Otherwise, the expedition ends.&lt;br /&gt;
&lt;br /&gt;
The expedition can end prematurely if two Hazard cards of the same kind is revealed. In this case, everyone still in the expedition gets &#039;&#039;&#039;no&#039;&#039;&#039; gems from the expedition. One of the two identical Hazard cards is &#039;&#039;&#039;removed&#039;&#039;&#039; from the deck permanently, so the rest of the game will have one less card of that kind of Hazard.&lt;br /&gt;
&lt;br /&gt;
Regardless of whether an expedition ends by all people retiring or two Hazard cards of the same kind are revealed, any Artifact not claimed are &#039;&#039;&#039;removed&#039;&#039;&#039; from the deck permanently.&lt;br /&gt;
&lt;br /&gt;
After five expeditions, the final scoring occurs. Each gem successfully brought back (not lost during the expedition) is worth 1 point. The Artifacts are worth 5 points each, and when collecting the last two Artifacts you get 5 extra gems. The player with the most points wins (and as tie breaker the player with the most artifacts wins).&lt;/div&gt;</summary>
		<author><name>Morgalad</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=BGA_Code_Sharing&amp;diff=2308</id>
		<title>BGA Code Sharing</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=BGA_Code_Sharing&amp;diff=2308"/>
		<updated>2017-04-08T00:09:29Z</updated>

		<summary type="html">&lt;p&gt;Morgalad: /* Projects on github */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is for listing of externally hosted bga projects, tools and resources, as well as internal project&lt;br /&gt;
intended for sharing&lt;br /&gt;
&lt;br /&gt;
== Projects on github ==&lt;br /&gt;
&lt;br /&gt;
See the table a link and nickname of the developer on bga (same as used for dev forum), and short description&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important notice about artwork on BGA Open Source projects: original hi-resolution images from publishers must not be published on the repositories. In addition, this is better to specify that the images derivated from publishers artwork are copyrighted and cannot be licensed under a free license like Creative Commons.&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! NAME&lt;br /&gt;
! CODE LINK&lt;br /&gt;
! DEVELOPER&lt;br /&gt;
|-&lt;br /&gt;
| Shared Code (not a game)&lt;br /&gt;
| https://github.com/elaskavaia/bga-sharedcode&lt;br /&gt;
| Victoria_La&lt;br /&gt;
|-&lt;br /&gt;
| Eruption&lt;br /&gt;
| https://github.com/AndyKerrison/bga-eruption&lt;br /&gt;
| Andy_K&lt;br /&gt;
|-&lt;br /&gt;
| Nile&lt;br /&gt;
| https://github.com/AndyKerrison/bga-nile&lt;br /&gt;
| Andy_K&lt;br /&gt;
|-&lt;br /&gt;
| Assyria &lt;br /&gt;
| https://github.com/sebastien-prudhomme/bga-assyria&lt;br /&gt;
| daikinee &lt;br /&gt;
|-&lt;br /&gt;
| Florenza: The Card Game&lt;br /&gt;
| https://github.com/alberto-bottarini/bga-florenza&lt;br /&gt;
| tarini &lt;br /&gt;
|-&lt;br /&gt;
| Incan Gold&lt;br /&gt;
| https://github.com/AntonioSoler/bga-incangold&lt;br /&gt;
| Morgalad &lt;br /&gt;
|-&lt;br /&gt;
| Marco Polo&lt;br /&gt;
| https://github.com/rcitaliano/MarcoPolo&lt;br /&gt;
| rcitaliano&lt;br /&gt;
|-&lt;br /&gt;
| Bonbons&lt;br /&gt;
| https://github.com/AntonioSoler/bga-bonbons&lt;br /&gt;
| Morgalad &lt;br /&gt;
|-&lt;br /&gt;
| Takara Island&lt;br /&gt;
| https://github.com/AntonioSoler/bga-takaraisland&lt;br /&gt;
| Morgalad&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Projects on studio ==&lt;br /&gt;
&lt;br /&gt;
Links to studio project which owner will share as read only if you request.&lt;br /&gt;
Project owner please add you project here, dev nickname and short description if you would like to share it.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! NAME&lt;br /&gt;
! CODE LINK&lt;br /&gt;
! DEVELOPER&lt;br /&gt;
|-&lt;br /&gt;
| Shared Code (ask for access)&lt;br /&gt;
| http://en.studio.boardgamearena.com/#!studiogame?game=sharedcode&lt;br /&gt;
| Victoria_La&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Other useful resources ==&lt;br /&gt;
&lt;br /&gt;
* Archive of tutorial projects https://www.dropbox.com/s/rsd5r4v49xudpp0/Studio.zip?dl=0&lt;br /&gt;
* Website with bunch of textures and sounds http://www.grsites.com/archive/textures/&lt;br /&gt;
* Shrink images without loss of quality https://tinypng.com/ or http://www.iloveimg.com/ (recommended by Gregory Isabelli)&lt;/div&gt;</summary>
		<author><name>Morgalad</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Stock&amp;diff=2283</id>
		<title>Stock</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Stock&amp;diff=2283"/>
		<updated>2017-03-15T21:18:05Z</updated>

		<summary type="html">&lt;p&gt;Morgalad: /* Tips when adding/removing items to/from Stock components */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&amp;quot;Stock&amp;quot; is a javascript component that you can use on your game interface to display a set of elements of the same size that need to be arranged in one or several 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;
Stock is used for example:&lt;br /&gt;
* To display set of cards, typically hands (ex: in Hearts, Seasons, The Boss, Race for the Galaxy, ...).&lt;br /&gt;
* To display items in player panels (ex: Takenoko, Amyitis, ...)&lt;br /&gt;
* ... in many other situations. For example, black dice and cubes on cards in Troyes are displayed with stock components.&lt;br /&gt;
&lt;br /&gt;
Using stock:&lt;br /&gt;
* Your items are arranged nicely and sorted by type.&lt;br /&gt;
* When adding (or removing) items to the set. All items slide smoothly to their new position in the set to host the new one.&lt;br /&gt;
* Select/unselect items is a built-in functionnality.&lt;br /&gt;
* You don&#039;t have to care about inserting/removing HTML piece of code: the entire life 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 on how the stock is used in game &amp;quot;Hearts&amp;quot; to display a hand of standard cards.&lt;br /&gt;
&lt;br /&gt;
At first, don&#039;t forget to add &amp;quot;ebg/stock&amp;quot; as a dependency:&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 Javascript &amp;quot;setup&amp;quot; method like this:&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 container div &amp;quot;myhand&amp;quot; - which is a simple void &amp;quot;div&amp;quot; element defines in our HTML template (.tpl).&lt;br /&gt;
&lt;br /&gt;
Then, we must tell the stock what are the 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 create a &amp;quot;CSS sprite&amp;quot; image named &amp;quot;cards.jpg&amp;quot; with all the cards arranged in 4 rows and 13 columns.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s how we tell stock what are the items type to display:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    // Explain 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 cards 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;
Explanations:&lt;br /&gt;
* At 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 &amp;quot;addItemType&amp;quot; method that create 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, if we need to add - for example - the 5 of Heart to player&#039;s hand, we can do this.&lt;br /&gt;
this.playerHand.addToStock( this.getCardUniqueId( 2 /* 2=hearts */, 5 ) );&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;
this.playerHand.addToStock( this.getCardUniqueId( 2 /* 2=hearts */, 5 ), my_card_id );&lt;br /&gt;
&lt;br /&gt;
If afterwards we want to remove this card from the stock:&lt;br /&gt;
this.playerHand.removeFromStockById( my_card_id );&lt;br /&gt;
&lt;br /&gt;
== Complete stock component reference ==&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;
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 (a void div element in your template, with an id).&lt;br /&gt;
* a stock item width and height, in pixels.&lt;br /&gt;
&lt;br /&gt;
(See &amp;quot;Hearts&amp;quot; example above).&lt;br /&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;addItemType( type, weight, image, image_position ):&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Define a new type of item to the stock.&lt;br /&gt;
&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 control that can contains 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 item, 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;
&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;
* 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;
Important: there are more than one line of items in your CSS sprite,  you must specify how many items per line you have in your CSS sprite like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    // Specify that there is 10 image items per row in images used in &amp;quot;myStockObject&amp;quot; control.&lt;br /&gt;
    this.myStockObject.image_items_per_row = 10;&lt;br /&gt;
&amp;lt;/pre&amp;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.&lt;br /&gt;
&lt;br /&gt;
To make your life easy, in most of the case we suggest you to use &amp;quot;addToStockWithId&amp;quot; in order to give an ID to the item added. &amp;quot;addToStock&amp;quot; is perfect when you are using a stock controls with items that are generic game material that does not need to be addressed individually (ex: 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: OPTIONNAL: if you specify a HTML item here, the item will appear on this item and will be slided 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 addToStock or addToStockWithId, 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 exactly the same method than &amp;quot;addToStock&amp;quot;, except that you associate an ID to the newly created item.&lt;br /&gt;
&lt;br /&gt;
This is especially useful:&lt;br /&gt;
* When you need to know which item(s) has been selected by the user (see &amp;quot;getSelectedItems&amp;quot;).&lt;br /&gt;
* When you need to remove a specific item from the stock with &amp;quot;removeFromStockById&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Important: for a given stock control, you must use either addToStock or addToStockWithId, but NEVER BOTH OF THEM.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;removeFromStock( type, to )&#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;
&amp;quot;to&amp;quot; is an optional parameter. If &amp;quot;to&amp;quot; contains the ID of an HTML element, the item removed from the stock is slided to this HTML element before it disappear.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;removeFromStockById( id, to )&#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;
&amp;quot;to&amp;quot; is an optional parameter. If &amp;quot;to&amp;quot; contains the ID of an HTML element, the item removed from the stock is slided to this HTML element before it disappear.&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;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;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 position to their original ones, you can call this method.&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;
&#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 the same time.&lt;br /&gt;
* 2 (default): several 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;stockitem_selecte&#039; css class added to the element when it is selected (and removed when unselected). You can override this class in the css file for your game.&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;
NB: the &#039;class&#039; highlighting type has not yet been deployed on the studio - 24/02/2014. This warning will be removed after the next upgrade.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;isSelected( id )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Return true/false wether the specified item id has been selected or not.&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;onChangeSelection&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This callback method is called when the player select/unselect an item of the stock.&lt;br /&gt;
&lt;br /&gt;
You can connect this to one of your method like this:&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 )&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;
Note: 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;
&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;
&#039;&#039;&#039;getAllItems()&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Get all items (same format than getSelectedItems and getUnselectedItems).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;setOverlap( horizontal_percent, vertical_percent )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Make items on the stock control &amp;quot;overlap&amp;quot; on each other, to save space.&lt;br /&gt;
&lt;br /&gt;
By default, horizontal_overlap and vertical_overlap are 0.&lt;br /&gt;
&lt;br /&gt;
When horizontal_overlap=20, it means that a stock item must overlap on 20% of the width of the previous item. horizontal_overlap can&#039;t be over 100.&lt;br /&gt;
&lt;br /&gt;
vertical_overlap works differently: one items on two are shifted up.&lt;br /&gt;
&lt;br /&gt;
See &amp;quot;Jaipur&amp;quot; game to see an example to use of this function.&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 you can 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;
&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;
== Tips when adding/removing items to/from Stock components ==&lt;br /&gt;
&lt;br /&gt;
The usual way is the following:&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: use &amp;quot;addToStockWithId&amp;quot; with a &amp;quot;from&amp;quot; argument set to the element of your interface where card should come from.&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;
* on the destination Stock, use &amp;quot;addToStockWithId&amp;quot; with a &amp;quot;from&amp;quot; equals to 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 &amp;quot;removeFromStockById&amp;quot;.&lt;br /&gt;
(note that it&#039;s important to do things in this order, because source item must still exists 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;
* insert the card as a classic HTML template (dojo.place / this.format_block).&lt;br /&gt;
* place it on the Stock item with &amp;quot;this.placeOnObject&amp;quot;, using Stock item HTML id (see above).&lt;br /&gt;
* slide it to its new position with &amp;quot;this.slideToObject&amp;quot;&lt;br /&gt;
* remove the card from the Stock item with &amp;quot;removeFromStockById&amp;quot;.&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;
You can customize this (showing the default value):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
this.mystock.jstpl_stock_item= &amp;quot;&amp;lt;div id=\&amp;quot;${id}\&amp;quot; class=\&amp;quot;stockitem\&amp;quot; style=\&amp;quot;top:${top}px;left:${left}px;width:${width}px;height:${height}px;z-index:${position};background-image:url(&#039;${image}&#039;);\&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
To produce a different type of stock item&lt;/div&gt;</summary>
		<author><name>Morgalad</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Stock&amp;diff=2282</id>
		<title>Stock</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Stock&amp;diff=2282"/>
		<updated>2017-03-15T21:15:46Z</updated>

		<summary type="html">&lt;p&gt;Morgalad: /* Tips when adding/removing items to/from Stock components */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&amp;quot;Stock&amp;quot; is a javascript component that you can use on your game interface to display a set of elements of the same size that need to be arranged in one or several 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;
Stock is used for example:&lt;br /&gt;
* To display set of cards, typically hands (ex: in Hearts, Seasons, The Boss, Race for the Galaxy, ...).&lt;br /&gt;
* To display items in player panels (ex: Takenoko, Amyitis, ...)&lt;br /&gt;
* ... in many other situations. For example, black dice and cubes on cards in Troyes are displayed with stock components.&lt;br /&gt;
&lt;br /&gt;
Using stock:&lt;br /&gt;
* Your items are arranged nicely and sorted by type.&lt;br /&gt;
* When adding (or removing) items to the set. All items slide smoothly to their new position in the set to host the new one.&lt;br /&gt;
* Select/unselect items is a built-in functionnality.&lt;br /&gt;
* You don&#039;t have to care about inserting/removing HTML piece of code: the entire life 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 on how the stock is used in game &amp;quot;Hearts&amp;quot; to display a hand of standard cards.&lt;br /&gt;
&lt;br /&gt;
At first, don&#039;t forget to add &amp;quot;ebg/stock&amp;quot; as a dependency:&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 Javascript &amp;quot;setup&amp;quot; method like this:&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 container div &amp;quot;myhand&amp;quot; - which is a simple void &amp;quot;div&amp;quot; element defines in our HTML template (.tpl).&lt;br /&gt;
&lt;br /&gt;
Then, we must tell the stock what are the 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 create a &amp;quot;CSS sprite&amp;quot; image named &amp;quot;cards.jpg&amp;quot; with all the cards arranged in 4 rows and 13 columns.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s how we tell stock what are the items type to display:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    // Explain 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 cards 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;
Explanations:&lt;br /&gt;
* At 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 &amp;quot;addItemType&amp;quot; method that create 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, if we need to add - for example - the 5 of Heart to player&#039;s hand, we can do this.&lt;br /&gt;
this.playerHand.addToStock( this.getCardUniqueId( 2 /* 2=hearts */, 5 ) );&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;
this.playerHand.addToStock( this.getCardUniqueId( 2 /* 2=hearts */, 5 ), my_card_id );&lt;br /&gt;
&lt;br /&gt;
If afterwards we want to remove this card from the stock:&lt;br /&gt;
this.playerHand.removeFromStockById( my_card_id );&lt;br /&gt;
&lt;br /&gt;
== Complete stock component reference ==&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;
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 (a void div element in your template, with an id).&lt;br /&gt;
* a stock item width and height, in pixels.&lt;br /&gt;
&lt;br /&gt;
(See &amp;quot;Hearts&amp;quot; example above).&lt;br /&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;addItemType( type, weight, image, image_position ):&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Define a new type of item to the stock.&lt;br /&gt;
&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 control that can contains 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 item, 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;
&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;
* 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;
Important: there are more than one line of items in your CSS sprite,  you must specify how many items per line you have in your CSS sprite like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    // Specify that there is 10 image items per row in images used in &amp;quot;myStockObject&amp;quot; control.&lt;br /&gt;
    this.myStockObject.image_items_per_row = 10;&lt;br /&gt;
&amp;lt;/pre&amp;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.&lt;br /&gt;
&lt;br /&gt;
To make your life easy, in most of the case we suggest you to use &amp;quot;addToStockWithId&amp;quot; in order to give an ID to the item added. &amp;quot;addToStock&amp;quot; is perfect when you are using a stock controls with items that are generic game material that does not need to be addressed individually (ex: 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: OPTIONNAL: if you specify a HTML item here, the item will appear on this item and will be slided 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 addToStock or addToStockWithId, 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 exactly the same method than &amp;quot;addToStock&amp;quot;, except that you associate an ID to the newly created item.&lt;br /&gt;
&lt;br /&gt;
This is especially useful:&lt;br /&gt;
* When you need to know which item(s) has been selected by the user (see &amp;quot;getSelectedItems&amp;quot;).&lt;br /&gt;
* When you need to remove a specific item from the stock with &amp;quot;removeFromStockById&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Important: for a given stock control, you must use either addToStock or addToStockWithId, but NEVER BOTH OF THEM.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;removeFromStock( type, to )&#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;
&amp;quot;to&amp;quot; is an optional parameter. If &amp;quot;to&amp;quot; contains the ID of an HTML element, the item removed from the stock is slided to this HTML element before it disappear.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;removeFromStockById( id, to )&#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;
&amp;quot;to&amp;quot; is an optional parameter. If &amp;quot;to&amp;quot; contains the ID of an HTML element, the item removed from the stock is slided to this HTML element before it disappear.&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;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;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 position to their original ones, you can call this method.&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;
&#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 the same time.&lt;br /&gt;
* 2 (default): several 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;stockitem_selecte&#039; css class added to the element when it is selected (and removed when unselected). You can override this class in the css file for your game.&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;
NB: the &#039;class&#039; highlighting type has not yet been deployed on the studio - 24/02/2014. This warning will be removed after the next upgrade.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;isSelected( id )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Return true/false wether the specified item id has been selected or not.&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;onChangeSelection&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This callback method is called when the player select/unselect an item of the stock.&lt;br /&gt;
&lt;br /&gt;
You can connect this to one of your method like this:&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 )&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;
Note: 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;
&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;
&#039;&#039;&#039;getAllItems()&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Get all items (same format than getSelectedItems and getUnselectedItems).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;setOverlap( horizontal_percent, vertical_percent )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Make items on the stock control &amp;quot;overlap&amp;quot; on each other, to save space.&lt;br /&gt;
&lt;br /&gt;
By default, horizontal_overlap and vertical_overlap are 0.&lt;br /&gt;
&lt;br /&gt;
When horizontal_overlap=20, it means that a stock item must overlap on 20% of the width of the previous item. horizontal_overlap can&#039;t be over 100.&lt;br /&gt;
&lt;br /&gt;
vertical_overlap works differently: one items on two are shifted up.&lt;br /&gt;
&lt;br /&gt;
See &amp;quot;Jaipur&amp;quot; game to see an example to use of this function.&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 you can 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;
&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;
== Tips when adding/removing items to/from Stock components ==&lt;br /&gt;
&lt;br /&gt;
The usual way is the following:&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: use &amp;quot;addToStockWithId&amp;quot; with a &amp;quot;from&amp;quot; argument set to the element of your interface where card should come from.&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;
* on the destination Stock, use &amp;quot;addToStockWithId&amp;quot; with a &amp;quot;from&amp;quot; equals to 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 &amp;quot;removeFromStockById&amp;quot;.&lt;br /&gt;
(note that it&#039;s important to do things in this order, because source item must still exists 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;
* insert the card as a classic HTML template (dojo.place / this.format_block).&lt;br /&gt;
* place it on the Stock item with &amp;quot;this.placeOnObject&amp;quot;, using Stock item HTML id (see above).&lt;br /&gt;
* slide it to its new position with &amp;quot;this.slideToObject&amp;quot;&lt;br /&gt;
* remove the card from the Stock item with &amp;quot;removeFromStockById&amp;quot;.&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;
You can customize this (showing the default value):&lt;br /&gt;
&lt;br /&gt;
this.mystock.jstpl_stock_item= &amp;quot;&amp;lt;div id=\&amp;quot;${id}\&amp;quot; class=\&amp;quot;stockitem\&amp;quot; style=\&amp;quot;top:${top}px;left:${left}px;width:${width}px;height:${height}px;z-index:${position};background-image:url(&#039;${image}&#039;);\&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
To produce a different type of stock item&lt;/div&gt;</summary>
		<author><name>Morgalad</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=BGA_Code_Sharing&amp;diff=2269</id>
		<title>BGA Code Sharing</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=BGA_Code_Sharing&amp;diff=2269"/>
		<updated>2017-03-06T11:50:42Z</updated>

		<summary type="html">&lt;p&gt;Morgalad: /* Projects on github */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is for listing of externally hosted bga projects, tools and resources, as well as internal project&lt;br /&gt;
intended for sharing&lt;br /&gt;
&lt;br /&gt;
== Projects on github ==&lt;br /&gt;
&lt;br /&gt;
See the table a link and nickname of the developer on bga (same as used for dev forum), and short description&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! NAME&lt;br /&gt;
! CODE LINK&lt;br /&gt;
! DEVELOPER&lt;br /&gt;
|-&lt;br /&gt;
| Shared Code (not a game)&lt;br /&gt;
| https://github.com/elaskavaia/bga-sharedcode&lt;br /&gt;
| Victoria_La&lt;br /&gt;
|-&lt;br /&gt;
| Eruption&lt;br /&gt;
| https://github.com/AndyKerrison/bga-eruption&lt;br /&gt;
| Andy_K&lt;br /&gt;
|-&lt;br /&gt;
| Nile&lt;br /&gt;
| https://github.com/AndyKerrison/bga-nile&lt;br /&gt;
| Andy_K&lt;br /&gt;
|-&lt;br /&gt;
| Assyria &lt;br /&gt;
| https://github.com/sebastien-prudhomme/bga-assyria&lt;br /&gt;
| daikinee &lt;br /&gt;
|-&lt;br /&gt;
| Florenza: The Card Game&lt;br /&gt;
| https://github.com/alberto-bottarini/bga-florenza&lt;br /&gt;
| tarini &lt;br /&gt;
|-&lt;br /&gt;
| Incan Gold&lt;br /&gt;
| https://github.com/AntonioSoler/bga-incangold&lt;br /&gt;
| Morgalad &lt;br /&gt;
|-&lt;br /&gt;
| Marco Polo&lt;br /&gt;
| https://github.com/rcitaliano/MarcoPolo&lt;br /&gt;
| rcitaliano&lt;br /&gt;
|-&lt;br /&gt;
| Bonbons&lt;br /&gt;
| https://github.com/AntonioSoler/bga-bonbons&lt;br /&gt;
| Morgalad &lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Projects on studio ==&lt;br /&gt;
&lt;br /&gt;
Links to studio project which owner will share as read only if you request.&lt;br /&gt;
Project owner please add you project here, dev nickname and short description if you would like to share it.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! NAME&lt;br /&gt;
! CODE LINK&lt;br /&gt;
! DEVELOPER&lt;br /&gt;
|-&lt;br /&gt;
| Shared Code (ask for access)&lt;br /&gt;
| http://en.studio.boardgamearena.com/#!studiogame?game=sharedcode&lt;br /&gt;
| Victoria_La&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Other useful resources ==&lt;br /&gt;
&lt;br /&gt;
* Archive of tutorial projects https://www.dropbox.com/s/rsd5r4v49xudpp0/Studio.zip?dl=0&lt;/div&gt;</summary>
		<author><name>Morgalad</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Gamehelpbonbons&amp;diff=2265</id>
		<title>Gamehelpbonbons</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Gamehelpbonbons&amp;diff=2265"/>
		<updated>2017-03-02T13:53:17Z</updated>

		<summary type="html">&lt;p&gt;Morgalad: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
On his turn, a player generally turns over one square tile and one round tile.&lt;br /&gt;
&lt;br /&gt;
If the two tiles are 100% identical (same candy of the same &lt;br /&gt;
color), they are left in place and visible. The same player &lt;br /&gt;
can play again.&lt;br /&gt;
&lt;br /&gt;
If they are not identical, they are turned face down again &lt;br /&gt;
and the player to his left takes his turn.&lt;br /&gt;
It is permissible to turn a round tile over first and then  &lt;br /&gt;
a square tile.&lt;br /&gt;
&lt;br /&gt;
After turning a square tile over for which you don’t expect &lt;br /&gt;
to find the match, you have the option to turn nothing &lt;br /&gt;
further over, to avoid the risk of theft.&lt;br /&gt;
If you think you know an opponent’s tile, you can try to find &lt;br /&gt;
a pair that includes one of his round tiles. If you succeed, &lt;br /&gt;
you steal the tile from him, and you give him one of yours in &lt;br /&gt;
return. &lt;br /&gt;
&lt;br /&gt;
His tile is placed face up in front of you, and your tile is placed &lt;br /&gt;
face down in front of him.&lt;br /&gt;
&lt;br /&gt;
Shuffle the 32 round tiles and deal 4 to each player. &lt;br /&gt;
&lt;br /&gt;
32 square tiles, with the same types of candy, 3 money tiles 1 empty package tile.&lt;br /&gt;
&lt;br /&gt;
The game ends when a player finishes his turn with all the &lt;br /&gt;
round tiles in front of him face up. He wins&lt;/div&gt;</summary>
		<author><name>Morgalad</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Gamehelpbonbons&amp;diff=2264</id>
		<title>Gamehelpbonbons</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Gamehelpbonbons&amp;diff=2264"/>
		<updated>2017-03-02T13:51:50Z</updated>

		<summary type="html">&lt;p&gt;Morgalad: Created page with &amp;quot; On his turn, a player generally turns over one square tile and one round tile.  If the two tiles are 100% identical (same candy of the same  color), they are left in place an...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
On his turn, a player generally turns over one square tile and one round tile.&lt;br /&gt;
&lt;br /&gt;
If the two tiles are 100% identical (same candy of the same &lt;br /&gt;
color), they are left in place and visible. The same player &lt;br /&gt;
can play again.&lt;br /&gt;
&lt;br /&gt;
If they are not identical, they are turned face down again &lt;br /&gt;
and the player to his left takes his turn.&lt;br /&gt;
It is permissible to turn a round tile over first and then  &lt;br /&gt;
a square tile.&lt;br /&gt;
&lt;br /&gt;
After turning a square tile over for which you don’t expect &lt;br /&gt;
to find the match, you have the option to turn nothing &lt;br /&gt;
further over, to avoid the risk of theft.&lt;br /&gt;
If you think you know an opponent’s tile, you can try to find &lt;br /&gt;
a pair that includes one of his round tiles. If you succeed, &lt;br /&gt;
you steal the tile from him, and you give him one of yours in &lt;br /&gt;
return. &lt;br /&gt;
&lt;br /&gt;
His tile is placed face up in front of you, and your tile is placed &lt;br /&gt;
face down in front of him.&lt;br /&gt;
Shuffle the 32 round tiles and deal 4 to each player. Without &lt;br /&gt;
looking at them, everyone puts their tiles face down in front &lt;br /&gt;
of them. The rest of the tiles are set aside.&lt;br /&gt;
Here’s what a 3-player game might look like.&lt;br /&gt;
32 square tiles, with the same types of candy.&lt;br /&gt;
3 &lt;br /&gt;
money&lt;br /&gt;
 tiles&lt;br /&gt;
1 &lt;br /&gt;
empty package&lt;br /&gt;
 tile&lt;br /&gt;
The game ends when a player finishes his turn with all the &lt;br /&gt;
round tiles in front of him face up. He wins&lt;/div&gt;</summary>
		<author><name>Morgalad</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Practical_debugging&amp;diff=2256</id>
		<title>Practical debugging</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Practical_debugging&amp;diff=2256"/>
		<updated>2017-02-25T00:01:09Z</updated>

		<summary type="html">&lt;p&gt;Morgalad: /* Add traces in your code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This page gives you practical tips to debug your game during the development. Don&#039;t hesitate to share with us your difficulties in order we can improve this section.&lt;br /&gt;
&lt;br /&gt;
== Tools ==&lt;br /&gt;
&lt;br /&gt;
To work on BGA Studio, we recommend you to use [www.google.com/chrome Google Chrome] as it&#039;s the current fastest browser for BGA platform, and it&#039;s available in all OS.&lt;br /&gt;
&lt;br /&gt;
Another reason to use Chrome is that it embed all tools you need to work on BGA Studio. You can see them by pressing &amp;quot;F12&amp;quot; or from the menu (&amp;quot;Tools &amp;gt; Development tools&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
A good practice is to use a second browser to develop the game, in order to check that your game is working fine on this browser too.&lt;br /&gt;
&lt;br /&gt;
To debug with Firefox browser, we advise you to use these 2 extensions:&lt;br /&gt;
* [https://addons.mozilla.org/firefox/addon/firebug/ Firebug]&lt;br /&gt;
* [https://addons.mozilla.org/firefox/addon/web-developer/ Web developper]&lt;br /&gt;
&lt;br /&gt;
To debug with Internet Explorer, we advise you to use one of the most recent version (ex: IE9). Last versions of Internet Explorer have way better development tools than the previous ones...&lt;br /&gt;
&lt;br /&gt;
== General tip for debugging ==&lt;br /&gt;
&lt;br /&gt;
In general for debugging, think of using the &#039;[[Tools_and_tips_of_BGA_Studio#Save_.26_restore_state|save &amp;amp; restore]] state&#039; functionality. It enables you to save the state of your game just before the issue you are investigating, then come back to that point with one click as many times as needed to understand what is going wrong.&lt;br /&gt;
&lt;br /&gt;
You can save up to 3 different states.&lt;br /&gt;
&lt;br /&gt;
== Debugging my game when it cannot start ==&lt;br /&gt;
&lt;br /&gt;
If your game don&#039;t start because of an error, you are probably in one of these situations:&lt;br /&gt;
* There is a SQL error in your dbmodel.sql file.&lt;br /&gt;
* You have a syntax error in your PHP file.&lt;br /&gt;
* Your PHP &amp;quot;setup&amp;quot; - or any method used during the game initial states - generates an exception.&lt;br /&gt;
&lt;br /&gt;
If the error is not explicitly displayed when you click on &amp;quot;Express start&amp;quot;, you should check the &amp;quot;Gameserver error log&amp;quot; as per [[Studio logs]].&lt;br /&gt;
&lt;br /&gt;
== Debugging my PHP game logic (or my view) ==&lt;br /&gt;
&lt;br /&gt;
Most of the time, debugging PHP is quite easy. Here&#039;s what I do when I want to develop/debug some game logic that is triggered by some game action:&lt;br /&gt;
&lt;br /&gt;
* At first, I make sure that I can reproduce the needed game situation in one click. To do this, I use the &amp;quot;[[Tools_and_tips_of_BGA_Studio#Save_.26_restore_state|save &amp;amp; restore]]&amp;quot; function.&lt;br /&gt;
* Another possibility for this is to place a &#039;&#039;&#039;die(&#039;ok&#039;);&#039;&#039;&#039; PHP statement right after the PHP I am developing/debugging. This way, I make sure that every request will fail and then nothing will be commited to the database, anyway.&lt;br /&gt;
* Then, I use &#039;&#039;&#039;var_dump&#039;&#039;&#039; function to dump PHP variables and check what&#039;s wrong, until it works.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// (...my code to debug)&lt;br /&gt;
&lt;br /&gt;
var_dump( $my_variable );&lt;br /&gt;
die(&#039;ok&#039;);&lt;br /&gt;
&lt;br /&gt;
// (...my code to debug)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Add traces to your code ===&lt;br /&gt;
&lt;br /&gt;
You can use the following functions in your game to add server side logging:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;self::debug( $message );&#039;&#039;&#039;  // debug level logging, goes to [[Studio_logs|BGA request&amp;amp;SQL logs]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;self::trace( $message );&#039;&#039;&#039;  // info level logging, goes to [[Studio_logs|BGA request&amp;amp;SQL logs]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;self::warn( $message );&#039;&#039;&#039;   // warning level logging, goes to [[Studio_logs#BGA_unexpected_exceptions_logs|BGA unexpected exceptions log]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;self::error( $message );&#039;&#039;&#039;  // error level logging, goes to [[Studio_logs#BGA_unexpected_exceptions_logs|BGA unexpected exceptions log]]&lt;br /&gt;
&lt;br /&gt;
Check [[Studio logs]] for more details on how to access your logs.&lt;br /&gt;
&lt;br /&gt;
This can be useful when you need to follow the flow of your code and not just stop it to see how it goes at some point.&lt;br /&gt;
&lt;br /&gt;
Only the error log level will appear in production. This level should be used only for critical problems. &lt;br /&gt;
Other levels will show only in the development environment and can be used as you see fit.&lt;br /&gt;
&lt;br /&gt;
== Debugging my HTML/CSS layout ==&lt;br /&gt;
&lt;br /&gt;
Situation examples:&lt;br /&gt;
* why my game element doesn&#039;t show up in the interface?&lt;br /&gt;
* why my CSS property hasn&#039;t been applied to this element?&lt;br /&gt;
* why this game element is displayed at this position?&lt;br /&gt;
&lt;br /&gt;
A first useful tip when an element does not show up in the interface is to give it a red background:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#my_element {&lt;br /&gt;
  ... some CSS definitions ...&lt;br /&gt;
  background-color: red;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This way, you know if the element is not visible because of some of its CSS property or because of anything else.&lt;br /&gt;
&lt;br /&gt;
Another tip: sometimes, you change a CSS property with no visible effect on your interface. In that case, add a &amp;quot;display:none&amp;quot; property. If your element does not disappear, the bug probably comes from your CSS selector and not from your CSS property.&lt;br /&gt;
&lt;br /&gt;
Using Chrome &amp;quot;Elements&amp;quot; tab (thre first one), you can:&lt;br /&gt;
* See the CURRENT HTML of your page. Remember that the classical &amp;quot;show page source&amp;quot; is inefficient with BGA as you are modifying the page source with your Javascript code.&lt;br /&gt;
* Using the &amp;quot;magnifying glass&amp;quot;, you can click on any part of your game interface and check it&#039;s HTML code and associated CSS styles.&lt;br /&gt;
* You can even modify directly some CSS property and see if how it looks immediately on the game interface.&lt;br /&gt;
&lt;br /&gt;
== Debugging my Javascript game interface logic ==&lt;br /&gt;
&lt;br /&gt;
Compare to PHP debugging, Javascript debugging can sometimes be painful.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s are some tips to make your life easier while developing and debugging Javascript:&lt;br /&gt;
&lt;br /&gt;
=== Do complex things on PHP side ===&lt;br /&gt;
&lt;br /&gt;
PHP side is more reliable and simpler to debug than Javascript. Then, when you need to perform a complex operation, check first it you can&#039;t write it on server side first.&lt;br /&gt;
&lt;br /&gt;
The most frequent case is the following: you want to compute possible moves in a game situation. Doing it in Javascript is a nightmare. Then, do it on PHP, and transfer the result to your client interface using the &amp;quot;args&amp;quot; game state property.&lt;br /&gt;
&lt;br /&gt;
Note: check Reversi example for this.&lt;br /&gt;
&lt;br /&gt;
=== Add traces in your code ===&lt;br /&gt;
&lt;br /&gt;
You can use the following:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;console.log( variable_to_inspect )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
It will give you the object structure of the variable in the Javascript console, without blocking the execution.&lt;br /&gt;
&lt;br /&gt;
It&#039;s often a good idea to precede this call with a console.log( &#039;### HERE ###&#039; ); to find more easily the appropriate line in the console log.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;alert( variable_to_inspect )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
It will popup what you wish and pause the execution until you click ok.&lt;br /&gt;
&lt;br /&gt;
This won&#039;t be useful for complex structures, only native types will get plainly displayed. But this is sometimes useful just with messages to make sure which way the execution goes.&lt;br /&gt;
&lt;br /&gt;
Modern browsers also allo to put the instruction in your js code&lt;br /&gt;
&lt;br /&gt;
debugger; &lt;br /&gt;
&lt;br /&gt;
That will stop code execution on that line and will launch the JavaScript debugger&lt;br /&gt;
&lt;br /&gt;
== Some frequent errors ==&lt;br /&gt;
&lt;br /&gt;
See [[Troubleshooting]].&lt;/div&gt;</summary>
		<author><name>Morgalad</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=BGA_Code_Sharing&amp;diff=2248</id>
		<title>BGA Code Sharing</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=BGA_Code_Sharing&amp;diff=2248"/>
		<updated>2017-02-19T00:54:52Z</updated>

		<summary type="html">&lt;p&gt;Morgalad: /* Projects on github */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is for listing of externally hosted bga projects, tools and resources, as well as internal project&lt;br /&gt;
intended for sharing&lt;br /&gt;
&lt;br /&gt;
== Projects on github ==&lt;br /&gt;
&lt;br /&gt;
See the table a link and nickname of the developer on bga (same as used for dev forum), and short description&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! GAME&lt;br /&gt;
! SOURCE&lt;br /&gt;
! DEVELOPER&lt;br /&gt;
|-&lt;br /&gt;
| Eruption&lt;br /&gt;
| https://github.com/AndyKerrison/bga-eruption&lt;br /&gt;
| Andy_K&lt;br /&gt;
|-&lt;br /&gt;
| Nile&lt;br /&gt;
| https://github.com/AndyKerrison/bga-nile&lt;br /&gt;
| Andy_K&lt;br /&gt;
|-&lt;br /&gt;
| Assyria &lt;br /&gt;
| https://github.com/sebastien-prudhomme/bga-assyria&lt;br /&gt;
| daikinee &lt;br /&gt;
|-&lt;br /&gt;
| Florenza: The Card Game&lt;br /&gt;
| https://github.com/alberto-bottarini/bga-florenza&lt;br /&gt;
| tarini &lt;br /&gt;
|-&lt;br /&gt;
| Incan Gold&lt;br /&gt;
| https://github.com/AntonioSoler/bga-incangold&lt;br /&gt;
| Morgalad &lt;br /&gt;
|-&lt;br /&gt;
| Marco Polo&lt;br /&gt;
| https://github.com/rcitaliano/MarcoPolo&lt;br /&gt;
| rcitaliano&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Projects on studio ==&lt;br /&gt;
&lt;br /&gt;
Links to studio project which owner will share as read only if you request.&lt;br /&gt;
Project owner please add you project here, dev nickname and short description if you would like to share it.&lt;br /&gt;
&lt;br /&gt;
== Other useful resources ==&lt;/div&gt;</summary>
		<author><name>Morgalad</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=BGA_Code_Sharing&amp;diff=2238</id>
		<title>BGA Code Sharing</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=BGA_Code_Sharing&amp;diff=2238"/>
		<updated>2017-02-14T13:45:26Z</updated>

		<summary type="html">&lt;p&gt;Morgalad: /* Projects on github */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is for listing of externally hosted bga projects, tools and resources, as well as internal project&lt;br /&gt;
intended for sharing&lt;br /&gt;
&lt;br /&gt;
== Projects on github ==&lt;br /&gt;
&lt;br /&gt;
See the table a link and nickname of the developer on bga (same as used for dev forum), and short description&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! GAME&lt;br /&gt;
! SOURCE&lt;br /&gt;
! DEVELOPER&lt;br /&gt;
|-&lt;br /&gt;
| Eruption&lt;br /&gt;
| https://github.com/AndyKerrison/bga-eruption&lt;br /&gt;
| Andy_K&lt;br /&gt;
|-&lt;br /&gt;
| Nile&lt;br /&gt;
| https://github.com/AndyKerrison/bga-nile&lt;br /&gt;
| Andy_K&lt;br /&gt;
|-&lt;br /&gt;
| Assyria &lt;br /&gt;
| https://github.com/sebastien-prudhomme/bga-assyria&lt;br /&gt;
| daikinee &lt;br /&gt;
|-&lt;br /&gt;
| Florenza: The Card Game&lt;br /&gt;
| https://github.com/alberto-bottarini/bga-florenza&lt;br /&gt;
| tarini &lt;br /&gt;
|-&lt;br /&gt;
| Incan Gold&lt;br /&gt;
| https://github.com/AntonioSoler/bga-incangold&lt;br /&gt;
| Morgalad &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Projects on studio ==&lt;br /&gt;
&lt;br /&gt;
Links to studio project which owner will share as read only if you request.&lt;br /&gt;
Project owner please add you project here, dev nickname and short description if you would like to share it.&lt;br /&gt;
&lt;br /&gt;
== Other useful resources ==&lt;/div&gt;</summary>
		<author><name>Morgalad</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Counter&amp;diff=2236</id>
		<title>Counter</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Counter&amp;diff=2236"/>
		<updated>2017-02-11T12:31:36Z</updated>

		<summary type="html">&lt;p&gt;Morgalad: /* Dependency */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
== Dependency ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
At first, don&#039;t forget to add &amp;quot;ebg/counter&amp;quot; as a dependency:&lt;br /&gt;
&lt;br /&gt;
    // in you game js&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;    /// &amp;lt;==== HERE],&lt;br /&gt;
&lt;br /&gt;
== updateCounters(counters) ==&lt;br /&gt;
&lt;br /&gt;
: Useful for updating game counters in the player panel (such as resources). &lt;br /&gt;
: &#039;counters&#039; arg is 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;
== 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;/div&gt;</summary>
		<author><name>Morgalad</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Counter&amp;diff=2235</id>
		<title>Counter</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Counter&amp;diff=2235"/>
		<updated>2017-02-11T12:31:09Z</updated>

		<summary type="html">&lt;p&gt;Morgalad: /* ; updateCounters(counters) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
== Dependency ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
At first, don&#039;t forget to add &amp;quot;ebg/counter&amp;quot; as a dependency:&lt;br /&gt;
&lt;br /&gt;
    // in you game js&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;    /// &amp;lt;==== HERE&lt;br /&gt;
],&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== updateCounters(counters) ==&lt;br /&gt;
&lt;br /&gt;
: Useful for updating game counters in the player panel (such as resources). &lt;br /&gt;
: &#039;counters&#039; arg is 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;
== 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;/div&gt;</summary>
		<author><name>Morgalad</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Counter&amp;diff=2234</id>
		<title>Counter</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Counter&amp;diff=2234"/>
		<updated>2017-02-11T12:30:41Z</updated>

		<summary type="html">&lt;p&gt;Morgalad: /* updateCounters(counters) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
== Dependency ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
At first, don&#039;t forget to add &amp;quot;ebg/counter&amp;quot; as a dependency:&lt;br /&gt;
&lt;br /&gt;
    // in you game js&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;    /// &amp;lt;==== HERE&lt;br /&gt;
],&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== ; updateCounters(counters) ==&lt;br /&gt;
&lt;br /&gt;
: Useful for updating game counters in the player panel (such as resources). &lt;br /&gt;
: &#039;counters&#039; arg is 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;
== 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;/div&gt;</summary>
		<author><name>Morgalad</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Counter&amp;diff=2233</id>
		<title>Counter</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Counter&amp;diff=2233"/>
		<updated>2017-02-11T12:29:05Z</updated>

		<summary type="html">&lt;p&gt;Morgalad: Created page with &amp;quot;  == Dependency ==   At first, don&amp;#039;t forget to add &amp;quot;ebg/counter&amp;quot; as a dependency:      // in you game js     define([     &amp;quot;dojo&amp;quot;,&amp;quot;dojo/_base/declare&amp;quot;,     &amp;quot;ebg/core/gamegui&amp;quot;, ...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
== Dependency ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
At first, don&#039;t forget to add &amp;quot;ebg/counter&amp;quot; as a dependency:&lt;br /&gt;
&lt;br /&gt;
    // in you game js&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;    /// &amp;lt;==== HERE&lt;br /&gt;
],&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== updateCounters(counters) ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Useful for updating game counters in the player panel (such as resources).&lt;br /&gt;
&#039;counters&#039; arg is 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;
== 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;/div&gt;</summary>
		<author><name>Morgalad</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Gamehelpincangold&amp;diff=2226</id>
		<title>Gamehelpincangold</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Gamehelpincangold&amp;diff=2226"/>
		<updated>2017-02-10T19:57:36Z</updated>

		<summary type="html">&lt;p&gt;Morgalad: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Brief explanation of the game:&lt;br /&gt;
&lt;br /&gt;
Players run 5 times a expedition into a temple (you reshuffle and draw a row of cards)&lt;br /&gt;
&lt;br /&gt;
A card is drawn, could be gems or a hazard:&lt;br /&gt;
&lt;br /&gt;
-gems are picked from the box, then split among the live players and the rest are left on the card (floor of the tunnel)&lt;br /&gt;
&lt;br /&gt;
-then players vote secretly with a faced down card to explore or to return to the camp.&lt;br /&gt;
&lt;br /&gt;
-the leavers may pick and split the gems left on the floor while returning to the camp, then their gems are safely stored in their tent (these gems cannot be lost now).&lt;br /&gt;
&lt;br /&gt;
-There are 5 types of hazard cards and 3 copies of each: mummy, snakes, spiders... when the 2nd of a kind is drawn the remaining players on the temple drop the pouches with the gems they have collected in this run &lt;br /&gt;
and flee to the camp.&lt;br /&gt;
&lt;br /&gt;
-The remaining players repeat this process until they decide to retreat or they are kicked off the temple by a hazard&lt;/div&gt;</summary>
		<author><name>Morgalad</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Gamehelpincangold&amp;diff=2225</id>
		<title>Gamehelpincangold</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Gamehelpincangold&amp;diff=2225"/>
		<updated>2017-02-10T19:56:54Z</updated>

		<summary type="html">&lt;p&gt;Morgalad: Created page with &amp;quot;Brief explanation of the game:  Players run 5 times a expedition into a temple (you reshuffle and draw a row of cards)  A card is drawn, could be gems or a hazard: -gems are p...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Brief explanation of the game:&lt;br /&gt;
&lt;br /&gt;
Players run 5 times a expedition into a temple (you reshuffle and draw a row of cards)&lt;br /&gt;
&lt;br /&gt;
A card is drawn, could be gems or a hazard:&lt;br /&gt;
-gems are picked from the box, then split among the live players and the rest are left on the card (floor of the tunnel)&lt;br /&gt;
-then players vote secretly with a faced down card to explore or to return to the camp.&lt;br /&gt;
-the leavers may pick and split the gems left on the floor while returning to the camp, then their gems are safely stored in their tent (these gems cannot be lost now).&lt;br /&gt;
-There are 5 types of hazard cards and 3 copies of each: mummy, snakes, spiders... when the 2nd of a kind is drawn the remaining players on the temple drop the pouches with the gems they have collected in this run and flee to the camp.&lt;br /&gt;
-The remaining players repeat this process until they decide to retreat or they are kicked off the temple by a hazard&lt;/div&gt;</summary>
		<author><name>Morgalad</name></author>
	</entry>
</feed>