<?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=Leocaseiro</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=Leocaseiro"/>
	<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/Special:Contributions/Leocaseiro"/>
	<updated>2026-11-11T20:39:24Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.11</generator>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=BGA_Code_Sharing&amp;diff=14283</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=14283"/>
		<updated>2022-08-08T11:42:48Z</updated>

		<summary type="html">&lt;p&gt;Leocaseiro: add Tic Tac Match game&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Studio_Framework_Navigation}}&lt;br /&gt;
&lt;br /&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;
== Community shared components, pens, etc ==&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;
! DESCRIPTION&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; | Dice models and animation&lt;br /&gt;
|-&lt;br /&gt;
| Die: 4 sided &lt;br /&gt;
| https://codepen.io/mrkiffie/pen/doVZgW&lt;br /&gt;
| code pen&lt;br /&gt;
|-&lt;br /&gt;
| Die: 6 sided &lt;br /&gt;
| https://github.com/elaskavaia/bga-sharedcode&lt;br /&gt;
| Code can be found in project&lt;br /&gt;
|-&lt;br /&gt;
| Die: 12 sided (dodecahedron) &lt;br /&gt;
| https://codepen.io/VictoriaLa/pen/xxLLxOP&lt;br /&gt;
| Code pen&lt;br /&gt;
|- &lt;br /&gt;
| Die: 20 sided &lt;br /&gt;
| https://codepen.io/vicentemundim/details/cenIh&lt;br /&gt;
| Code pen&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; | Moving object using CSS animation (mostly)&lt;br /&gt;
|-&lt;br /&gt;
| Phantom object move on oversurface &lt;br /&gt;
| https://codepen.io/VictoriaLa/pen/gORvdJo&lt;br /&gt;
| This technique creates clone of the object it moves it on another surface. It works well when parents that css transform applies such as scale and rotate&lt;br /&gt;
|-&lt;br /&gt;
| Move object directly using positioning &lt;br /&gt;
| https://codepen.io/VictoriaLa/pen/dyzgKVX&lt;br /&gt;
| This technique is modification of BGA framework method to allow mobile object not to have absolute position before or after the move (and uses css animation not dojo). Methods slideToObjectRelative, attachToNewObjectNoDestroy&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; | Responsive layout for game boards&lt;br /&gt;
|-&lt;br /&gt;
|Flex Layout&lt;br /&gt;
|https://codepen.io/VictoriaLa/pen/XWjJJgG&lt;br /&gt;
|Example on how to create flexible layout just by using css&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; | Algorithms&lt;br /&gt;
|-&lt;br /&gt;
|Hex grid&lt;br /&gt;
|tapestry,Tumbleweed,gaia project,Gold West&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|Shortest path on hex grid&lt;br /&gt;
|memoir 44&lt;br /&gt;
| Disjktra&lt;br /&gt;
|-&lt;br /&gt;
|Largest area on hex grid&lt;br /&gt;
|tapestry, ...&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|Largest area on square grid&lt;br /&gt;
|king domino, ...&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|Tetris pieces&lt;br /&gt;
|patchwork, ...&lt;br /&gt;
|Matrix manupations to rotate, flip and fit tetris pieces&lt;br /&gt;
|-&lt;br /&gt;
|Line of sights on hex grid&lt;br /&gt;
|memoir 44&lt;br /&gt;
|Find intersecting hexes on a line between two cells&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Projects hosted not in studio ==&lt;br /&gt;
&lt;br /&gt;
See the table a link and nickname of the developer on bga (same as used for dev forum), and short description. See [[Tools_and_tips_of_BGA_Studio#Version_Control]] for some suggestions on how and where to publish your code externally. Also see the [https://github.com/topics/boardgamearena boardgamearena] tag on github.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important notice about artwork on BGA Open Source projects: original hi-resolution images from publishers must not be published on the repositories. In addition, it is better to specify that the images derivated from publishers artwork are copyrighted and cannot be licensed under a free license like Creative Commons.&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! NON-GAME PROJECTS&lt;br /&gt;
! CODE LINK&lt;br /&gt;
! DEVELOPER&lt;br /&gt;
! COMMENT&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;
| Examples of various game components and PHP stubs of framework code to make IDE happy&lt;br /&gt;
|-&lt;br /&gt;
| BoardGameArena Workbench (not a game)&lt;br /&gt;
| https://github.com/danielholmes/bga-workbench&lt;br /&gt;
| Daniel Holmes (dhau)&lt;br /&gt;
|-&lt;br /&gt;
! GAME&lt;br /&gt;
! CODE LINK&lt;br /&gt;
! DEVELOPER&lt;br /&gt;
! COMMENT&lt;br /&gt;
|-&lt;br /&gt;
| 99 (Trick-taking Card Game)&lt;br /&gt;
| https://github.com/ekelly/bga-ninetynine&lt;br /&gt;
| QuasarDukeDev&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;
| Aura&lt;br /&gt;
| https://github.com/micahstairs/bga-aura&lt;br /&gt;
| Micah Stairs (micahstairs)&lt;br /&gt;
|-&lt;br /&gt;
| Bandido &lt;br /&gt;
| https://github.com/opheliehb/BandidoBGA&lt;br /&gt;
| ophelopede &amp;amp; Harkle &lt;br /&gt;
|-&lt;br /&gt;
| The Battle for Hill 218&lt;br /&gt;
| https://github.com/danielholmes/battle-for-hill-218&lt;br /&gt;
| Daniel Holmes (dhau)&lt;br /&gt;
|-&lt;br /&gt;
| Bonbons&lt;br /&gt;
| https://github.com/AntonioSoler/bga-bonbons&lt;br /&gt;
| Morgalad &lt;br /&gt;
|-&lt;br /&gt;
| Coinche&lt;br /&gt;
| https://github.com/drasill/bga-coinche&lt;br /&gt;
| Draasill&lt;br /&gt;
|-&lt;br /&gt;
| Coup: City State&lt;br /&gt;
| https://github.com/quietmint/bga-coupcitystate&lt;br /&gt;
| quietmint&lt;br /&gt;
|-&lt;br /&gt;
| Dungeon Roll&lt;br /&gt;
| https://github.com/MartinGoulet/bga-dungeonroll&lt;br /&gt;
| MGoulet&lt;br /&gt;
|-&lt;br /&gt;
| Egyptian Ratscrew&lt;br /&gt;
| https://github.com/0BuRner/bga-egyptianratscrew&lt;br /&gt;
| 0BuRner&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;
| A Fistful Of Gold&lt;br /&gt;
| https://bitbucket.org/Joel_L/fistfulofgold&lt;br /&gt;
| Brainchild&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;
| Hearts &#039;&#039;&#039;(Tutorial)&#039;&#039;&#039;&lt;br /&gt;
| https://github.com/elaskavaia/bga-heartsla&lt;br /&gt;
| Victoria_La&lt;br /&gt;
|-&lt;br /&gt;
| Homesteaders&lt;br /&gt;
| https://github.com/npatron/bga-homesteaders&lt;br /&gt;
| TheBoot&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;
| Innovation&lt;br /&gt;
| https://github.com/micahstairs/bga-innovation&lt;br /&gt;
| Micah Stairs (micahstairs)&lt;br /&gt;
|-&lt;br /&gt;
| Mapmaker: The Gerrymandering Game&lt;br /&gt;
| https://github.com/gzhang01/bga-mapmaker&lt;br /&gt;
| gkz&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;
| Nile&lt;br /&gt;
| https://github.com/AndyKerrison/bga-nile&lt;br /&gt;
| Andy_K&lt;br /&gt;
|-&lt;br /&gt;
| Noir: Killer vs Inspector&lt;br /&gt;
| https://bitbucket.org/chhuang76/bga_noirkvi&lt;br /&gt;
| ch huang&lt;br /&gt;
|-&lt;br /&gt;
| Penny Press&lt;br /&gt;
| https://github.com/AdamNovotny/bga-blooms&lt;br /&gt;
| A-dam&lt;br /&gt;
|-&lt;br /&gt;
| P.I.&lt;br /&gt;
| https://gitlab.com/fa81/bga-pi, https://github.com/hellp/bga-pi (mirror)&lt;br /&gt;
| Fabian Neumann (fa81)&lt;br /&gt;
|-&lt;br /&gt;
| Santorini&lt;br /&gt;
| https://github.com/AntonioSoler/bga-santorini&lt;br /&gt;
| Morgalad, quietmint, Tisaac&lt;br /&gt;
|-&lt;br /&gt;
| Tablut&lt;br /&gt;
| https://github.com/Lucas-C/tablut&lt;br /&gt;
| Lucas-C &amp;amp; ntaffore&lt;br /&gt;
|-&lt;br /&gt;
| Takara Island&lt;br /&gt;
| https://github.com/AntonioSoler/bga-takaraisland&lt;br /&gt;
| Morgalad&lt;br /&gt;
|-&lt;br /&gt;
| Taluva&lt;br /&gt;
| https://github.com/quietmint/bga-taluva&lt;br /&gt;
| Morgalad &amp;amp; quietmint&lt;br /&gt;
|-&lt;br /&gt;
| Teotihuacan: City of Gods&lt;br /&gt;
| https://github.com/Trompetenhut/bga-teotihuacan&lt;br /&gt;
| Trompetenhut&lt;br /&gt;
|-&lt;br /&gt;
| Texas 42 (domino game, still under development)&lt;br /&gt;
| https://github.com/ishermandom/bga-42&lt;br /&gt;
| Stardust Spikes, Jason Turner-Maier, Ilya Sherman&lt;br /&gt;
|-&lt;br /&gt;
| Tic Tac Match&lt;br /&gt;
| https://github.com/leocaseiro/bga-tictacmatch&lt;br /&gt;
| Leo Caseiro&lt;br /&gt;
|-&lt;br /&gt;
| Uptown&lt;br /&gt;
| https://github.com/elliotkendall/bga-uptown&lt;br /&gt;
| SpottedShroom&lt;br /&gt;
|-&lt;br /&gt;
| Via Magica&lt;br /&gt;
| https://github.com/christopherburke/bga_viamagica&lt;br /&gt;
| CuriousTerran&lt;br /&gt;
|-&lt;br /&gt;
| Just Desserts&lt;br /&gt;
| https://github.com/mizutismask/bga-just-desserts&lt;br /&gt;
| mizutismask&lt;br /&gt;
|-&lt;br /&gt;
| The King&#039;s Guild&lt;br /&gt;
| https://github.com/AdamNovotny/BGG-KingsGuild&lt;br /&gt;
| A-dam&lt;br /&gt;
|-&lt;br /&gt;
| Get the MacGuffin&lt;br /&gt;
| https://github.com/mizutismask/bga-get-the-MacGuffin&lt;br /&gt;
| mizutismask&lt;br /&gt;
|-&lt;br /&gt;
| President&lt;br /&gt;
| https://github.com/quaresma95/president&lt;br /&gt;
| quaresma95&lt;br /&gt;
|-&lt;br /&gt;
| Hardback&lt;br /&gt;
| https://github.com/quietmint/bga-hardback&lt;br /&gt;
| quietmint&lt;br /&gt;
|-&lt;br /&gt;
| Dice Summoners&lt;br /&gt;
| https://github.com/eoincos/bga-dicesummoners&lt;br /&gt;
| eoincos&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Projects on studio ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Any developer can add themselves to a project as read-only from https://studio.boardgamearena.com/#!projects page (almost any project).&lt;br /&gt;
The list below are no-games which do not have bgg id and not showing up there.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! NAME&lt;br /&gt;
! CODE LINK&lt;br /&gt;
! DEVELOPER&lt;br /&gt;
|-&lt;br /&gt;
| Shared Code&lt;br /&gt;
| https://studio.boardgamearena.com/gamepanel?game=sharedcode&lt;br /&gt;
| Victoria_La&lt;br /&gt;
|-&lt;br /&gt;
| Original BGA template&lt;br /&gt;
| https://studio.boardgamearena.com/gamepanel?game=template&lt;br /&gt;
| Victoria_La&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Other useful resources ==&lt;br /&gt;
&lt;br /&gt;
Moved to [[Tools_and_tips_of_BGA_Studio]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Studio]]&lt;/div&gt;</summary>
		<author><name>Leocaseiro</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Category:Studio&amp;diff=13954</id>
		<title>Category:Studio</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Category:Studio&amp;diff=13954"/>
		<updated>2022-07-11T12:05:01Z</updated>

		<summary type="html">&lt;p&gt;Leocaseiro: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;To search only pages from Studio category, use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;keyword &amp;quot;[[Category:Studio]]&amp;quot;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or go to: [https://en.doc.boardgamearena.com/index.php?search=+%22%5B%5BCategory%3AStudio%5D%5D%22&amp;amp;title=Special%3ASearch&amp;amp;profile=default&amp;amp;fulltext=1]&lt;/div&gt;</summary>
		<author><name>Leocaseiro</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Category:Studio&amp;diff=13953</id>
		<title>Category:Studio</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Category:Studio&amp;diff=13953"/>
		<updated>2022-07-11T12:00:58Z</updated>

		<summary type="html">&lt;p&gt;Leocaseiro: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;To search in Studio category, use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;nowiki&amp;gt; keyword &amp;quot;[[Category:Studio]]&amp;quot;&amp;lt;/nowiki&amp;gt;&lt;/div&gt;</summary>
		<author><name>Leocaseiro</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Category:Studio&amp;diff=13952</id>
		<title>Category:Studio</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Category:Studio&amp;diff=13952"/>
		<updated>2022-07-11T11:57:19Z</updated>

		<summary type="html">&lt;p&gt;Leocaseiro: Created page with &amp;quot;To search in Studio category, use: `keyword &amp;quot;Category:Studio&amp;quot;`&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;To search in Studio category, use:&lt;br /&gt;
`keyword &amp;quot;[[Category:Studio]]&amp;quot;`&lt;/div&gt;</summary>
		<author><name>Leocaseiro</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Gamehelptictacmatch&amp;diff=13941</id>
		<title>Gamehelptictacmatch</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Gamehelptictacmatch&amp;diff=13941"/>
		<updated>2022-07-09T15:31:41Z</updated>

		<summary type="html">&lt;p&gt;Leocaseiro: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Overview===&lt;br /&gt;
&lt;br /&gt;
Create a line of three of your symbol AND the same colour (you are not assigned a colour)&lt;br /&gt;
&lt;br /&gt;
===Turn===&lt;br /&gt;
&lt;br /&gt;
Play a card either on to an empty space or a previously used space (same symbol or same colour)&lt;br /&gt;
&lt;br /&gt;
===Specials===&lt;br /&gt;
&lt;br /&gt;
The main makeup of the cards are different coloured X&#039;s &amp;amp; 0&#039;s, however, there are a few unique cards too:&lt;br /&gt;
&lt;br /&gt;
Flip - This changes your side, so if you were X&#039;s you are now 0&#039;s. Your teammate stays the same as they also flip, along with the opponents&lt;br /&gt;
&lt;br /&gt;
Wipe Out - Pick a player, NOT yourself, to discard all cards and draw new ones (This can be an opponent or a teammate)&lt;br /&gt;
&lt;br /&gt;
Double Play - Allows you to play 2 extra cards in addition to itself. The 2 other cards CANNOT be Double Play OR Wipe Out&lt;/div&gt;</summary>
		<author><name>Leocaseiro</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Gamehelptictacmatch&amp;diff=13924</id>
		<title>Gamehelptictacmatch</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Gamehelptictacmatch&amp;diff=13924"/>
		<updated>2022-07-09T02:19:52Z</updated>

		<summary type="html">&lt;p&gt;Leocaseiro: from O to 0&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Overview===&lt;br /&gt;
&lt;br /&gt;
Create a line of three of your symbol AND the same colour (you are not assigned a colour)&lt;br /&gt;
&lt;br /&gt;
===Turn===&lt;br /&gt;
&lt;br /&gt;
Play a card either on to an empty space or a previously used space&lt;br /&gt;
&lt;br /&gt;
===Specials===&lt;br /&gt;
&lt;br /&gt;
The main makeup of the cards are different coloured X&#039;s &amp;amp; 0&#039;s, however, there are a few unique cards too:&lt;br /&gt;
&lt;br /&gt;
Flip - This changes your side, so if you were X&#039;s you are now 0&#039;s. Your teammate stays the same as they also flip, along with the opponents&lt;br /&gt;
&lt;br /&gt;
Wipe Out - Pick a player, NOT yourself, to discard all cards and draw new ones (This can be an opponent or a teammate)&lt;br /&gt;
&lt;br /&gt;
Double Play - Allows you to play 2 extra cards in addition to itself. The 2 other cards CANNOT be Double Play OR Wipe Out&lt;/div&gt;</summary>
		<author><name>Leocaseiro</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Using_Vue&amp;diff=13281</id>
		<title>Using Vue</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Using_Vue&amp;diff=13281"/>
		<updated>2022-05-17T01:19:54Z</updated>

		<summary type="html">&lt;p&gt;Leocaseiro: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This guide will discuss how to incorporate the progressive JavaScript framework [https://v3.vuejs.org/ Vue.js 3] to make a game on BGA.&lt;br /&gt;
&lt;br /&gt;
 [[Category:Studio]]&lt;/div&gt;</summary>
		<author><name>Leocaseiro</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=I_wish_I_knew_this_when_I_started&amp;diff=13280</id>
		<title>I wish I knew this when I started</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=I_wish_I_knew_this_when_I_started&amp;diff=13280"/>
		<updated>2022-05-17T01:18:56Z</updated>

		<summary type="html">&lt;p&gt;Leocaseiro: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page contains most &amp;quot;I wish I knew this before...&amp;quot; momentics (in regards to BGA studio game development). One line per statement please with doc references. Docs link can be outside of BGA wiki.&lt;br /&gt;
Most of this is already documented on BGA wiki in details, search wiki or google for generic subject to find more info.&lt;br /&gt;
&lt;br /&gt;
* Browser caches images and css, to force re-cache use Ctrl+F5 or Ctrl+Shift+R, and sometimes it&#039;s not enough so go to the web console &amp;gt; Network &amp;gt; check &amp;quot;disable cache&amp;quot;&lt;br /&gt;
* Browser has powerful embeded dev tools for inspection of dom, css and js, you can debug js right in browser (F12)&lt;br /&gt;
* You don&#039;t have to login with another dev account to play test the game under development, little colored arrows on studio player panel switch between test accounts&lt;br /&gt;
* You can run PHP functions from chat&lt;br /&gt;
* You can change style of elements (css) depending on their parent, sibling or other properties of the element&lt;br /&gt;
* You cannot save php state in global variables between actions, all data has to be stored in db&lt;br /&gt;
* Ajax actions in BGA do not use the traditional request-response model of a normal application. The ajax response does not contain any payload and instead you must send a notification (self::notifyAllPlayers) to communicate the response to appropriate players.&lt;br /&gt;
* Almost every change you make to the game via sending notifications must also be included in getAllDatas (e.g., in case a player loads/refreshes the game during the middle of play).&lt;br /&gt;
* You can easily scale elements by using &amp;quot;em&amp;quot; as unit for width/height and varying font-size, i.e. .meeple {width: 2em;height: 2.5em;font-size: 20px;}&lt;br /&gt;
* You can access your javascript methods / properties in the browser console using &#039;&#039;&#039;&#039;&#039;gameui.&amp;lt;yourMethod&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
* To interactively debug JS issues you can put &#039;&#039;&#039;&#039;&#039;debugger;&#039;&#039;&#039;&#039;&#039; statement in your code, enable dev tools (F12) and reload. It will hit breakpoint.&lt;br /&gt;
* To quickly try a fix you can edit css, js and html directly in browser dev tool window, no reload required (just don&#039;t forget to copy it back to your code after)&lt;br /&gt;
* To spell check all your translatable strings use Project Check from control panel - it will generate all strings, you can cut &amp;amp; paste this in online spell checker (or just use Firefox - it has embedded spell checker).&lt;br /&gt;
* To remove inline style property from dom node $(token).style.removeProperty(&amp;quot;position&amp;quot;); or dojo.style(&#039;token&#039;, &#039;position&#039;, null);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 [[Category:Studio]]&lt;/div&gt;</summary>
		<author><name>Leocaseiro</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=13279</id>
		<title>SandboxScripts</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=SandboxScripts&amp;diff=13279"/>
		<updated>2022-05-17T01:18:35Z</updated>

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

		<summary type="html">&lt;p&gt;Leocaseiro: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;UNDER CONSTRUCTION&lt;br /&gt;
&lt;br /&gt;
Trying to add info on how to add bots and AI in bga games. There is no framework support (now), so it is all custom stuff.&lt;br /&gt;
&lt;br /&gt;
What about &amp;quot;Can&#039;t Stop&amp;quot; Bot? Well it is the only game that has AI (without I) that is treated as separate player, admins won&#039;t &lt;br /&gt;
reveal how it is done nor that is feasible to implement in other games.&lt;br /&gt;
&lt;br /&gt;
== Games ==&lt;br /&gt;
The following game have modes that support bots Conspiracy, Glow, Crew, Crew Deepsea&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Techniques ==&lt;br /&gt;
=== Testing bot ===&lt;br /&gt;
Testing bot is actually JavaScript bot that presses on buttons on behalf of player. Its handy for testing on Studio.&lt;br /&gt;
Recommended way of doing it is add Studio only button (together with debug bar) &amp;quot;Run bot/Stop bot&amp;quot;, when running it can react to state changes and press stuff.&lt;br /&gt;
Example &amp;quot;Battleship&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== JavaScript AI ===&lt;br /&gt;
Currently I don&#039;t see how it is feasible, JS code requires real player connected to game and browser, so it cannot be run as AI engine&lt;br /&gt;
&lt;br /&gt;
=== Server Bot as registered game Player ===&lt;br /&gt;
This would be ideal, but currently on Can&#039;t Stop does it and no other game can use this technique&lt;br /&gt;
&lt;br /&gt;
=== Server Bot as game state action ===&lt;br /&gt;
This is the only feasible way in production. In addition to whatever game states are doing, it can handle fake players and simulate their moves&lt;br /&gt;
&lt;br /&gt;
In some games Bot will take player color and whole board similar to what player, and can even have resources.&lt;br /&gt;
So it natural that Bot behaive like a player in a game.&lt;br /&gt;
However you cannot add fake player into player table, so you cannot add any field in that table to track resources for examples.&lt;br /&gt;
You cannot make fake player active or multiactive.&lt;br /&gt;
&lt;br /&gt;
==== Bot Player ID ====&lt;br /&gt;
Reserve non-exising player id for bots (i.e. 1-6)&lt;br /&gt;
If bot needs color and order see below&lt;br /&gt;
&lt;br /&gt;
==== Bot Color, Order and Resources ====&lt;br /&gt;
Create table similar player to track bots color, name, score, score_aux and possibly other stuff&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE TABLE IF NOT EXISTS `playerextra` (&lt;br /&gt;
 `player_id` int(10) unsigned NOT NULL,&lt;br /&gt;
 `player_name` varchar(32) NOT NULL,&lt;br /&gt;
 `player_avatar` varchar(10) NOT NULL,&lt;br /&gt;
 `player_color` varchar(6) NOT NULL,&lt;br /&gt;
 `player_no` int(10) NOT NULL,&lt;br /&gt;
 `player_score` int(10) NOT NULL DEFAULT &#039;0&#039;,&lt;br /&gt;
 `player_score_aux` int(10) NOT NULL DEFAULT &#039;0&#039;,&lt;br /&gt;
 `player_ai` tinyint(1) NOT NULL DEFAULT &#039;0&#039; COMMENT &#039;1 = player is an AI&#039;,&lt;br /&gt;
  PRIMARY KEY (`player_id`)&lt;br /&gt;
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Bot Actions ====&lt;br /&gt;
* All actions that can be done by Bot have to have $player_id as argument and not use active player&lt;br /&gt;
* Separate code of ajax actions themselves and functional code, so function can be run from ajax action or from game state action&lt;br /&gt;
* If you using getPlayerNameById to sen player_name in notification, you may have to override id (same for player color)&lt;br /&gt;
    public function getPlayerNameById($player_id) {&lt;br /&gt;
        if ($player_id == PLAYER_AUTOMA)&lt;br /&gt;
            return (&#039;Automa&#039;);&lt;br /&gt;
        return parent::getPlayerNameById($player_id);&lt;br /&gt;
    } &lt;br /&gt;
* You may also create a function like loadPlayersBasicInfosWithBots which will return similar data as loadPlayersBasicInfos but with bots ids. Cache the result if using a lot&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    function loadPlayersBasicInfosWithBots() {&lt;br /&gt;
        $player_basic = $this-&amp;gt;loadPlayersBasicInfos();&lt;br /&gt;
        if ( !$this-&amp;gt;isAutoma())&lt;br /&gt;
            return $player_basic;           &lt;br /&gt;
        if ( !isset($this-&amp;gt;player_bots)) {&lt;br /&gt;
            $this-&amp;gt;player_bots = $this-&amp;gt;getCollectionFromDb(&amp;quot;SELECT * FROM playerextra&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        return $this-&amp;gt;player_bots + $player_basic;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Bot Player Panel ====&lt;br /&gt;
If you want bot on player panel you have to add it manually.&lt;br /&gt;
You can either create template similar to real one or use this hack.&lt;br /&gt;
Below we get player_id and player from playerextra&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
var over = $(&#039;overall_player_board_&#039; + player_id);&lt;br /&gt;
if (!over) {&lt;br /&gt;
	let active_id = this.getActivePlayers()[0];&lt;br /&gt;
	let active_name = gamedatas.players[active_id].name;&lt;br /&gt;
	var xclone = $(&#039;overall_player_board_&#039; + active_id).outerHTML;&lt;br /&gt;
	xclone = xclone.replaceAll(String(active_id), player_id);&lt;br /&gt;
	xclone = xclone.replaceAll(active_name, player.name);&lt;br /&gt;
	xclone = xclone.replaceAll(gamedatas.players[active_id].color, player.color);&lt;br /&gt;
        var node = dojo.place(xclone, &#039;player_boards&#039;);&lt;br /&gt;
// tweak to change avatar status and such&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Bot Player Notifications ====&lt;br /&gt;
When you send notification with ${player_name} you also should send &#039;player_id&#039; with you fake id.&lt;br /&gt;
In additio getAllDatas() should contain record matching fake player id in players field, i.e if $player has data for fake player:&lt;br /&gt;
    protected function getAllDatas() {&lt;br /&gt;
        $result = [];&lt;br /&gt;
    ...&lt;br /&gt;
            $result [&#039;players&#039;] [$player_id] [&#039;id&#039;] = $player[&#039;id&#039;];&lt;br /&gt;
            $result [&#039;players&#039;] [$player_id] [&#039;score&#039;] = $player[&#039;score&#039;];&lt;br /&gt;
            $result [&#039;players&#039;] [$player_id] [&#039;color&#039;] = $player[&#039;color&#039;];&lt;br /&gt;
            $result [&#039;players&#039;] [$player_id] [&#039;name&#039;] = $player[&#039;name&#039;];&lt;br /&gt;
   ...&lt;br /&gt;
        return $result;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 [[Category:Studio]]&lt;/div&gt;</summary>
		<author><name>Leocaseiro</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Using_Typescript_and_Scss&amp;diff=13277</id>
		<title>Using Typescript and Scss</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Using_Typescript_and_Scss&amp;diff=13277"/>
		<updated>2022-05-17T01:14:58Z</updated>

		<summary type="html">&lt;p&gt;Leocaseiro: add Studio category&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page will help you set up your project to use Typescript client file and Scss style files, and automatically build Javascript (in ES5) files and CSS files so your project stay compatible to BGA framework requirements.&lt;br /&gt;
You can use only TS or only SCSS part if you want, they are not linked.&lt;br /&gt;
&lt;br /&gt;
== How to install the auto-build stack ==&lt;br /&gt;
&lt;br /&gt;
=== Install dev stack  ===&lt;br /&gt;
Install node/npm.  Here is an example to activate auto-build in Visual Studio Code, if you use another tool I strongly recommend to find an equivalent so you don&#039;t have to launch build manually after each modification.&lt;br /&gt;
&lt;br /&gt;
=== Auto build JS and CSS files ===&lt;br /&gt;
In VS Code, add extension https://marketplace.visualstudio.com/items?itemName=emeraldwalk.RunOnSave and then add to VSCode &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt; extension part :&lt;br /&gt;
        &amp;quot;commands&amp;quot;: [&lt;br /&gt;
            {&lt;br /&gt;
                &amp;quot;match&amp;quot;: &amp;quot;.*\\.ts$&amp;quot;,&lt;br /&gt;
                &amp;quot;isAsync&amp;quot;: true,&lt;br /&gt;
                &amp;quot;cmd&amp;quot;: &amp;quot;npm run build:ts&amp;quot;&lt;br /&gt;
            },&lt;br /&gt;
            {&lt;br /&gt;
                &amp;quot;match&amp;quot;: &amp;quot;.*\\.scss$&amp;quot;,&lt;br /&gt;
                &amp;quot;isAsync&amp;quot;: true,&lt;br /&gt;
                &amp;quot;cmd&amp;quot;: &amp;quot;npm run build:scss&amp;quot;&lt;br /&gt;
            }&lt;br /&gt;
        ]&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;build:ts&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;build:scss&amp;lt;/code&amp;gt; are script tasks we&#039;ll configure later.&lt;br /&gt;
&lt;br /&gt;
&amp;gt; Alternatively you can run on terminal: `npm run watch`&lt;br /&gt;
&lt;br /&gt;
=== Auto-upload built files ===&lt;br /&gt;
Also add one auto-FTP upload extension (for example https://marketplace.visualstudio.com/items?itemName=lukasz-wronski.ftp-sync) and configure it. The extension will detected modified files in the workspace, including built ones, and upload them to remote server.&lt;br /&gt;
In ignored files section, you can put :&lt;br /&gt;
    &amp;quot;ignore&amp;quot;: [&lt;br /&gt;
        &amp;quot;\\.vscode&amp;quot;,&lt;br /&gt;
        &amp;quot;\\.git&amp;quot;,&lt;br /&gt;
        &amp;quot;\\.DS_Store&amp;quot;,&lt;br /&gt;
        &amp;quot;package.json&amp;quot;,&lt;br /&gt;
        &amp;quot;package-lock.json&amp;quot;,&lt;br /&gt;
        &amp;quot;yarn.lock&amp;quot;,&lt;br /&gt;
        &amp;quot;tsconfig.json&amp;quot;,&lt;br /&gt;
        &amp;quot;src&amp;quot;,&lt;br /&gt;
        &amp;quot;node_modules&amp;quot;,&lt;br /&gt;
        &amp;quot;README.md&amp;quot;&lt;br /&gt;
    ],&lt;br /&gt;
&lt;br /&gt;
=== Hint ===&lt;br /&gt;
Make sure &amp;lt;code&amp;gt;.vscode&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;node_modules&amp;lt;/code&amp;gt; are in &amp;lt;code&amp;gt;.gitignore&amp;lt;/code&amp;gt; if you commit your project somewhere.&lt;br /&gt;
&lt;br /&gt;
== Create skeleton ==&lt;br /&gt;
When you create your game in BGA Studio, a JS and CSS file are generated. As we will overwrite them with autobuild. You can put the TS/SCSS files on a &amp;lt;code&amp;gt;src&amp;lt;/code&amp;gt; folder to separate them from built files, but that&#039;s not mandatory.&lt;br /&gt;
&lt;br /&gt;
=== Typescript file skeleton ===&lt;br /&gt;
Typescript example here have been stripped down of all comments for clarity. You can view full file with generated comments [https://github.com/thoun/bga-ts-example/blob/main/src/yourgamename.ts here].&lt;br /&gt;
Your TS code can be splitted in multiple files, you can have a look [https://github.com/thoun/bga-ts-example here] for inspiration.&lt;br /&gt;
To make this page concise, I removed comments and code samples. If it&#039;s your first game, I strongly recommend you to report them on the TS file before activating auto-build !&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;your game name&amp;gt;.ts&#039;&#039;&#039;&lt;br /&gt;
 declare const define;&lt;br /&gt;
 declare const ebg;&lt;br /&gt;
 declare const $;&lt;br /&gt;
 //declare const dojo/*: Dojo*/;&lt;br /&gt;
 declare const _;&lt;br /&gt;
 declare const g_gamethemeurl;&lt;br /&gt;
 &lt;br /&gt;
 class &amp;lt;Your game name&amp;gt; /*implements Game*/ {&lt;br /&gt;
 &lt;br /&gt;
     private gamedatas: any;&lt;br /&gt;
     private player_id: string;&lt;br /&gt;
     private players: { [playerId: number]: any /*Player*/ };&lt;br /&gt;
     private playerNumber: number;&lt;br /&gt;
 &lt;br /&gt;
     constructor() {}&lt;br /&gt;
     &lt;br /&gt;
     public setup(gamedatas: any) {&lt;br /&gt;
         this.setupNotifications();&lt;br /&gt;
     } &lt;br /&gt;
     public onEnteringState(stateName: string, args: any) {}&lt;br /&gt;
     public onLeavingState(stateName: string) {}&lt;br /&gt;
     public onUpdateActionButtons(stateName: string, args: any) {} &lt;br /&gt;
     public setupNotifications() {}&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
To plug the class with BGA framework, we&#039;ll also create another file :&lt;br /&gt;
&#039;&#039;&#039;define.ts&#039;&#039;&#039;&lt;br /&gt;
 define([&lt;br /&gt;
     &amp;quot;dojo&amp;quot;,&amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/stock&amp;quot;&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.&amp;lt;your game name&amp;gt;&amp;quot;, ebg.core.gamegui, new &amp;lt;Your game name&amp;gt;());             &lt;br /&gt;
 });&lt;br /&gt;
Copy &amp;lt;code&amp;gt;bgagame.&amp;lt;your game name&amp;gt;&amp;lt;/code&amp;gt; from original JS to avoid name mistakes. &amp;lt;code&amp;gt;new &amp;lt;Your game name&amp;gt;()&amp;lt;/code&amp;gt; must match your class name defined on previous file.&lt;br /&gt;
&lt;br /&gt;
=== SCSS file ===&lt;br /&gt;
Nothing special here, just write classic SCSS (will be compiled by Dart scss) and name it &#039;&#039;&#039;&amp;lt;your game name&amp;gt;.scss&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Your SCSS code can be splitted in multiple files, for example :&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;your game name&amp;gt;.scss&#039;&#039;&#039;&lt;br /&gt;
  @import &#039;gametable&#039;;&lt;br /&gt;
 &lt;br /&gt;
  /* some classes */&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;_gametable.scss&#039;&#039;&#039;&lt;br /&gt;
  /* _gametable related classes */&lt;br /&gt;
&lt;br /&gt;
=== Configure package.json and tsconfig.json ===&lt;br /&gt;
&lt;br /&gt;
Create a file named &amp;lt;code&amp;gt;package.json&amp;lt;/code&amp;gt; on the root folder, not on the src folder.&lt;br /&gt;
&#039;&#039;&#039;package.json&#039;&#039;&#039;&lt;br /&gt;
 {&lt;br /&gt;
   &amp;quot;name&amp;quot;: &amp;quot;&amp;lt;your game name&amp;gt;&amp;quot;,&lt;br /&gt;
   &amp;quot;version&amp;quot;: &amp;quot;1.0.0&amp;quot;,&lt;br /&gt;
   &amp;quot;description&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
   &amp;quot;main&amp;quot;: &amp;quot;&amp;lt;your game name&amp;gt;.js&amp;quot;,&lt;br /&gt;
   &amp;quot;scripts&amp;quot;: {&lt;br /&gt;
     &amp;quot;build:ts&amp;quot;: &amp;quot;tsc&amp;quot;,&lt;br /&gt;
     &amp;quot;build:scss&amp;quot;: &amp;quot;sass --no-source-map src/&amp;lt;your game name&amp;gt;.scss &amp;lt;your game name&amp;gt;.css&amp;quot;,&lt;br /&gt;
     &amp;quot;watch:ts&amp;quot;: &amp;quot;tsc --watch&amp;quot;,&lt;br /&gt;
     &amp;quot;watch:scss&amp;quot;: &amp;quot;sass --watch src/&amp;lt;your game name&amp;gt;.scss &amp;lt;your game name&amp;gt;.css&amp;quot;,&lt;br /&gt;
     &amp;quot;watch&amp;quot;: &amp;quot;npm run watch:ts &amp;amp;&amp;amp; npm run watch:sass&amp;quot;&lt;br /&gt;
   },&lt;br /&gt;
   &amp;quot;author&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
   &amp;quot;license&amp;quot;: &amp;quot;ISC&amp;quot;,&lt;br /&gt;
   &amp;quot;devDependencies&amp;quot;: {&lt;br /&gt;
     &amp;quot;sass&amp;quot;: &amp;quot;^1.32.6&amp;quot;,&lt;br /&gt;
     &amp;quot;typescript&amp;quot;: &amp;quot;^4.1.3&amp;quot;&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
When package.json is created, run &amp;lt;code&amp;gt;npm i&amp;lt;/code&amp;gt; on the root folder to install builders (will generate a node_modules folder).&lt;br /&gt;
&lt;br /&gt;
For Typescript compilation we also need to set up a &amp;lt;code&amp;gt;tsconfig.json&amp;lt;/code&amp;gt; on the root folder.&lt;br /&gt;
&#039;&#039;&#039;tsconfig.json&#039;&#039;&#039;&lt;br /&gt;
 {&lt;br /&gt;
     &amp;quot;rootDir&amp;quot;: &amp;quot;.&amp;quot;, &lt;br /&gt;
     &amp;quot;compilerOptions&amp;quot;: {&lt;br /&gt;
       &amp;quot;target&amp;quot;: &amp;quot;es5&amp;quot;,&lt;br /&gt;
       &amp;quot;module&amp;quot;: &amp;quot;none&amp;quot;,&lt;br /&gt;
       &amp;quot;lib&amp;quot;: [&amp;quot;dom&amp;quot;, &amp;quot;esnext&amp;quot;],  &lt;br /&gt;
       &amp;quot;sourceMap&amp;quot;: false,&lt;br /&gt;
       &amp;quot;outFile&amp;quot;: &amp;quot;&amp;lt;your game name&amp;gt;.js&amp;quot;,&lt;br /&gt;
     },&lt;br /&gt;
     &amp;quot;files&amp;quot;: [&lt;br /&gt;
         &amp;quot;src/&amp;lt;your game name&amp;gt;.ts&amp;quot;,&lt;br /&gt;
         &amp;quot;src/define.ts&amp;quot;&lt;br /&gt;
     ]&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
If you want to split your code onto multiple files, just add them in the file list (order is important for dependencies, new subpart should go on top of the list). No need to import classes or types from one file to another. In fact, you can&#039;t with this configuration. If you manage to make them work, please contact me and we&#039;ll update this documentation.&lt;br /&gt;
&lt;br /&gt;
=== Code completion ===&lt;br /&gt;
To add code completion on framework, doko, stock, ... you&#039;ll need definition files. Feel free to copy them from [https://github.com/thoun/bga-ts-example this repo] and reference them at the top of files array, even before your subpart files.&lt;br /&gt;
&lt;br /&gt;
 [[Category:Studio]]&lt;/div&gt;</summary>
		<author><name>Leocaseiro</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=I_wish_I_knew_this_when_I_started&amp;diff=12857</id>
		<title>I wish I knew this when I started</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=I_wish_I_knew_this_when_I_started&amp;diff=12857"/>
		<updated>2022-04-25T08:41:18Z</updated>

		<summary type="html">&lt;p&gt;Leocaseiro: fix typo for width&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page contains most &amp;quot;I wish I knew this before...&amp;quot; momentics (in regards to BGA studio game development). One line per statement please with doc references. Docs link can be outside of BGA wiki.&lt;br /&gt;
Most of this is already documented on BGA wiki in details, search wiki or google for generic subject to find more info.&lt;br /&gt;
&lt;br /&gt;
* Browser caches images and css, to force re-cache use Ctrl+F5 or Ctrl+Shift+R, and sometimes it&#039;s not enough so go to the web console &amp;gt; Network &amp;gt; check &amp;quot;disable cache&amp;quot;&lt;br /&gt;
* Browser has powerful embeded dev tools for inspection of dom, css and js, you can debug js right in browser (F12)&lt;br /&gt;
* You don&#039;t have to login with another dev account to play test the game under development, little colored arrows on studio player panel switch between test accounts&lt;br /&gt;
* You can run PHP functions from chat&lt;br /&gt;
* You can change style of elements (css) depending on their parent, sibling or other properties of the element&lt;br /&gt;
* You cannot save php state in global variables between actions, all data has to be stored in db&lt;br /&gt;
* Ajax actions in BGA do not use the traditional request-response model of a normal application. The ajax response does not contain any payload and instead you must send a notification (self::notifyAllPlayers) to communicate the response to appropriate players.&lt;br /&gt;
* Almost every change you make to the game via sending notifications must also be included in getAllDatas (e.g., in case a player loads/refreshes the game during the middle of play).&lt;br /&gt;
* You can easily scale elements by using &amp;quot;em&amp;quot; as unit for width/height and varying font-size, i.e. .meeple {width: 2em;height: 2.5em;font-size: 20px;}&lt;br /&gt;
* You can access your javascript methods / properties in the browser console using &#039;&#039;&#039;&#039;&#039;gameui.&amp;lt;yourMethod&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
* To interactively debug JS issues you can put &#039;&#039;&#039;&#039;&#039;debugger;&#039;&#039;&#039;&#039;&#039; statement in your code, enable dev tools (F12) and reload. It will hit breakpoint.&lt;br /&gt;
* To quickly try a fix you can edit css, js and html directly in browser dev tool window, no reload required (just don&#039;t forget to copy it back to your code after)&lt;br /&gt;
* To spell check all your translatable strings use Project Check from control panel - it will generate all strings, you can cut &amp;amp; paste this in online spell checker (or just use Firefox - it has embedded spell checker).&lt;br /&gt;
* To remove inline style property from dom node $(token).style.removeProperty(&amp;quot;position&amp;quot;); or dojo.style(&#039;token&#039;, &#039;position&#039;, null);&lt;/div&gt;</summary>
		<author><name>Leocaseiro</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Using_Typescript_and_Scss&amp;diff=12558</id>
		<title>Using Typescript and Scss</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Using_Typescript_and_Scss&amp;diff=12558"/>
		<updated>2022-04-08T14:42:43Z</updated>

		<summary type="html">&lt;p&gt;Leocaseiro: /* Configure package.json and tsconfig.json */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page will help you set up your project to use Typescript client file and Scss style files, and automatically build Javascript (in ES5) files and CSS files so your project stay compatible to BGA framework requirements.&lt;br /&gt;
You can use only TS or only SCSS part if you want, they are not linked.&lt;br /&gt;
&lt;br /&gt;
== How to install the auto-build stack ==&lt;br /&gt;
&lt;br /&gt;
=== Install dev stack  ===&lt;br /&gt;
Install node/npm.  Here is an example to activate auto-build in Visual Studio Code, if you use another tool I strongly recommend to find an equivalent so you don&#039;t have to launch build manually after each modification.&lt;br /&gt;
&lt;br /&gt;
=== Auto build JS and CSS files ===&lt;br /&gt;
In VS Code, add extension https://marketplace.visualstudio.com/items?itemName=emeraldwalk.RunOnSave and then add to VSCode &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt; extension part :&lt;br /&gt;
        &amp;quot;commands&amp;quot;: [&lt;br /&gt;
            {&lt;br /&gt;
                &amp;quot;match&amp;quot;: &amp;quot;.*\\.ts$&amp;quot;,&lt;br /&gt;
                &amp;quot;isAsync&amp;quot;: true,&lt;br /&gt;
                &amp;quot;cmd&amp;quot;: &amp;quot;npm run build:ts&amp;quot;&lt;br /&gt;
            },&lt;br /&gt;
            {&lt;br /&gt;
                &amp;quot;match&amp;quot;: &amp;quot;.*\\.scss$&amp;quot;,&lt;br /&gt;
                &amp;quot;isAsync&amp;quot;: true,&lt;br /&gt;
                &amp;quot;cmd&amp;quot;: &amp;quot;npm run build:scss&amp;quot;&lt;br /&gt;
            }&lt;br /&gt;
        ]&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;build:ts&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;build:scss&amp;lt;/code&amp;gt; are script tasks we&#039;ll configure later.&lt;br /&gt;
&lt;br /&gt;
&amp;gt; Alternatively you can run on terminal: `npm run watch`&lt;br /&gt;
&lt;br /&gt;
=== Auto-upload built files ===&lt;br /&gt;
Also add one auto-FTP upload extension (for example https://marketplace.visualstudio.com/items?itemName=lukasz-wronski.ftp-sync) and configure it. The extension will detected modified files in the workspace, including built ones, and upload them to remote server.&lt;br /&gt;
In ignored files section, you can put :&lt;br /&gt;
    &amp;quot;ignore&amp;quot;: [&lt;br /&gt;
        &amp;quot;\\.vscode&amp;quot;,&lt;br /&gt;
        &amp;quot;\\.git&amp;quot;,&lt;br /&gt;
        &amp;quot;\\.DS_Store&amp;quot;,&lt;br /&gt;
        &amp;quot;package.json&amp;quot;,&lt;br /&gt;
        &amp;quot;package-lock.json&amp;quot;,&lt;br /&gt;
        &amp;quot;yarn.lock&amp;quot;,&lt;br /&gt;
        &amp;quot;tsconfig.json&amp;quot;,&lt;br /&gt;
        &amp;quot;src&amp;quot;,&lt;br /&gt;
        &amp;quot;node_modules&amp;quot;,&lt;br /&gt;
        &amp;quot;README.md&amp;quot;&lt;br /&gt;
    ],&lt;br /&gt;
&lt;br /&gt;
=== Hint ===&lt;br /&gt;
Make sure &amp;lt;code&amp;gt;.vscode&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;node_modules&amp;lt;/code&amp;gt; are in &amp;lt;code&amp;gt;.gitignore&amp;lt;/code&amp;gt; if you commit your project somewhere.&lt;br /&gt;
&lt;br /&gt;
== Create skeleton ==&lt;br /&gt;
When you create your game in BGA Studio, a JS and CSS file are generated. As we will overwrite them with autobuild. You can put the TS/SCSS files on a &amp;lt;code&amp;gt;src&amp;lt;/code&amp;gt; folder to separate them from built files, but that&#039;s not mandatory.&lt;br /&gt;
&lt;br /&gt;
=== Typescript file skeleton ===&lt;br /&gt;
Typescript example here have been stripped down of all comments for clarity. You can view full file with generated comments [https://github.com/thoun/bga-ts-example/blob/main/src/yourgamename.ts here].&lt;br /&gt;
Your TS code can be splitted in multiple files, you can have a look [https://github.com/thoun/bga-ts-example here] for inspiration.&lt;br /&gt;
To make this page concise, I removed comments and code samples. If it&#039;s your first game, I strongly recommend you to report them on the TS file before activating auto-build !&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;your game name&amp;gt;.ts&#039;&#039;&#039;&lt;br /&gt;
 declare const define;&lt;br /&gt;
 declare const ebg;&lt;br /&gt;
 declare const $;&lt;br /&gt;
 //declare const dojo/*: Dojo*/;&lt;br /&gt;
 declare const _;&lt;br /&gt;
 declare const g_gamethemeurl;&lt;br /&gt;
 &lt;br /&gt;
 class &amp;lt;Your game name&amp;gt; /*implements Game*/ {&lt;br /&gt;
 &lt;br /&gt;
     private gamedatas: any;&lt;br /&gt;
     private player_id: string;&lt;br /&gt;
     private players: { [playerId: number]: any /*Player*/ };&lt;br /&gt;
     private playerNumber: number;&lt;br /&gt;
 &lt;br /&gt;
     constructor() {}&lt;br /&gt;
     &lt;br /&gt;
     public setup(gamedatas: any) {&lt;br /&gt;
         this.setupNotifications();&lt;br /&gt;
     } &lt;br /&gt;
     public onEnteringState(stateName: string, args: any) {}&lt;br /&gt;
     public onLeavingState(stateName: string) {}&lt;br /&gt;
     public onUpdateActionButtons(stateName: string, args: any) {} &lt;br /&gt;
     public setupNotifications() {}&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
To plug the class with BGA framework, we&#039;ll also create another file :&lt;br /&gt;
&#039;&#039;&#039;define.ts&#039;&#039;&#039;&lt;br /&gt;
 define([&lt;br /&gt;
     &amp;quot;dojo&amp;quot;,&amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/stock&amp;quot;&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.&amp;lt;your game name&amp;gt;&amp;quot;, ebg.core.gamegui, new &amp;lt;Your game name&amp;gt;());             &lt;br /&gt;
 });&lt;br /&gt;
Copy &amp;lt;code&amp;gt;bgagame.&amp;lt;your game name&amp;gt;&amp;lt;/code&amp;gt; from original JS to avoid name mistakes. &amp;lt;code&amp;gt;new &amp;lt;Your game name&amp;gt;()&amp;lt;/code&amp;gt; must match your class name defined on previous file.&lt;br /&gt;
&lt;br /&gt;
=== SCSS file ===&lt;br /&gt;
Nothing special here, just write classic SCSS (will be compiled by Dart scss) and name it &#039;&#039;&#039;&amp;lt;your game name&amp;gt;.scss&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Your SCSS code can be splitted in multiple files, for example :&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;your game name&amp;gt;.scss&#039;&#039;&#039;&lt;br /&gt;
  @import &#039;gametable&#039;;&lt;br /&gt;
 &lt;br /&gt;
  /* some classes */&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;_gametable.scss&#039;&#039;&#039;&lt;br /&gt;
  /* _gametable related classes */&lt;br /&gt;
&lt;br /&gt;
=== Configure package.json and tsconfig.json ===&lt;br /&gt;
&lt;br /&gt;
Create a file named &amp;lt;code&amp;gt;package.json&amp;lt;/code&amp;gt; on the root folder, not on the src folder.&lt;br /&gt;
&#039;&#039;&#039;package.json&#039;&#039;&#039;&lt;br /&gt;
 {&lt;br /&gt;
   &amp;quot;name&amp;quot;: &amp;quot;&amp;lt;your game name&amp;gt;&amp;quot;,&lt;br /&gt;
   &amp;quot;version&amp;quot;: &amp;quot;1.0.0&amp;quot;,&lt;br /&gt;
   &amp;quot;description&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
   &amp;quot;main&amp;quot;: &amp;quot;&amp;lt;your game name&amp;gt;.js&amp;quot;,&lt;br /&gt;
   &amp;quot;scripts&amp;quot;: {&lt;br /&gt;
     &amp;quot;build:ts&amp;quot;: &amp;quot;tsc&amp;quot;,&lt;br /&gt;
     &amp;quot;build:scss&amp;quot;: &amp;quot;sass --no-source-map src/&amp;lt;your game name&amp;gt;.scss &amp;lt;your game name&amp;gt;.css&amp;quot;,&lt;br /&gt;
     &amp;quot;watch:ts&amp;quot;: &amp;quot;tsc --watch&amp;quot;,&lt;br /&gt;
     &amp;quot;watch:scss&amp;quot;: &amp;quot;sass --watch src/&amp;lt;your game name&amp;gt;.scss &amp;lt;your game name&amp;gt;.css&amp;quot;,&lt;br /&gt;
     &amp;quot;watch&amp;quot;: &amp;quot;npm run watch:ts &amp;amp;&amp;amp; npm run watch:sass&amp;quot;&lt;br /&gt;
   },&lt;br /&gt;
   &amp;quot;author&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
   &amp;quot;license&amp;quot;: &amp;quot;ISC&amp;quot;,&lt;br /&gt;
   &amp;quot;devDependencies&amp;quot;: {&lt;br /&gt;
     &amp;quot;sass&amp;quot;: &amp;quot;^1.32.6&amp;quot;,&lt;br /&gt;
     &amp;quot;typescript&amp;quot;: &amp;quot;^4.1.3&amp;quot;&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
When package.json is created, run &amp;lt;code&amp;gt;npm i&amp;lt;/code&amp;gt; on the root folder to install builders (will generate a node_modules folder).&lt;br /&gt;
&lt;br /&gt;
For Typescript compilation we also need to set up a &amp;lt;code&amp;gt;tsconfig.json&amp;lt;/code&amp;gt; on the root folder.&lt;br /&gt;
&#039;&#039;&#039;tsconfig.json&#039;&#039;&#039;&lt;br /&gt;
 {&lt;br /&gt;
     &amp;quot;rootDir&amp;quot;: &amp;quot;.&amp;quot;, &lt;br /&gt;
     &amp;quot;compilerOptions&amp;quot;: {&lt;br /&gt;
       &amp;quot;target&amp;quot;: &amp;quot;es5&amp;quot;,&lt;br /&gt;
       &amp;quot;module&amp;quot;: &amp;quot;none&amp;quot;,&lt;br /&gt;
       &amp;quot;lib&amp;quot;: [&amp;quot;dom&amp;quot;, &amp;quot;esnext&amp;quot;],  &lt;br /&gt;
       &amp;quot;sourceMap&amp;quot;: false,&lt;br /&gt;
       &amp;quot;outFile&amp;quot;: &amp;quot;&amp;lt;your game name&amp;gt;.js&amp;quot;,&lt;br /&gt;
     },&lt;br /&gt;
     &amp;quot;files&amp;quot;: [&lt;br /&gt;
         &amp;quot;src/&amp;lt;your game name&amp;gt;.ts&amp;quot;,&lt;br /&gt;
         &amp;quot;src/define.ts&amp;quot;&lt;br /&gt;
     ]&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
If you want to split your code onto multiple files, just add them in the file list (order is important for dependencies, new subpart should go on top of the list). No need to import classes or types from one file to another. In fact, you can&#039;t with this configuration. If you manage to make them work, please contact me and we&#039;ll update this documentation.&lt;br /&gt;
&lt;br /&gt;
=== Code completion ===&lt;br /&gt;
To add code completion on framework, doko, stock, ... you&#039;ll need definition files. Feel free to copy them from [https://github.com/thoun/bga-ts-example this repo] and reference them at the top of files array, even before your subpart files.&lt;/div&gt;</summary>
		<author><name>Leocaseiro</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Using_Typescript_and_Scss&amp;diff=12557</id>
		<title>Using Typescript and Scss</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Using_Typescript_and_Scss&amp;diff=12557"/>
		<updated>2022-04-08T14:40:45Z</updated>

		<summary type="html">&lt;p&gt;Leocaseiro: /* Auto build JS and CSS files */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page will help you set up your project to use Typescript client file and Scss style files, and automatically build Javascript (in ES5) files and CSS files so your project stay compatible to BGA framework requirements.&lt;br /&gt;
You can use only TS or only SCSS part if you want, they are not linked.&lt;br /&gt;
&lt;br /&gt;
== How to install the auto-build stack ==&lt;br /&gt;
&lt;br /&gt;
=== Install dev stack  ===&lt;br /&gt;
Install node/npm.  Here is an example to activate auto-build in Visual Studio Code, if you use another tool I strongly recommend to find an equivalent so you don&#039;t have to launch build manually after each modification.&lt;br /&gt;
&lt;br /&gt;
=== Auto build JS and CSS files ===&lt;br /&gt;
In VS Code, add extension https://marketplace.visualstudio.com/items?itemName=emeraldwalk.RunOnSave and then add to VSCode &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt; extension part :&lt;br /&gt;
        &amp;quot;commands&amp;quot;: [&lt;br /&gt;
            {&lt;br /&gt;
                &amp;quot;match&amp;quot;: &amp;quot;.*\\.ts$&amp;quot;,&lt;br /&gt;
                &amp;quot;isAsync&amp;quot;: true,&lt;br /&gt;
                &amp;quot;cmd&amp;quot;: &amp;quot;npm run build:ts&amp;quot;&lt;br /&gt;
            },&lt;br /&gt;
            {&lt;br /&gt;
                &amp;quot;match&amp;quot;: &amp;quot;.*\\.scss$&amp;quot;,&lt;br /&gt;
                &amp;quot;isAsync&amp;quot;: true,&lt;br /&gt;
                &amp;quot;cmd&amp;quot;: &amp;quot;npm run build:scss&amp;quot;&lt;br /&gt;
            }&lt;br /&gt;
        ]&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;build:ts&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;build:scss&amp;lt;/code&amp;gt; are script tasks we&#039;ll configure later.&lt;br /&gt;
&lt;br /&gt;
&amp;gt; Alternatively you can run on terminal: `npm run watch`&lt;br /&gt;
&lt;br /&gt;
=== Auto-upload built files ===&lt;br /&gt;
Also add one auto-FTP upload extension (for example https://marketplace.visualstudio.com/items?itemName=lukasz-wronski.ftp-sync) and configure it. The extension will detected modified files in the workspace, including built ones, and upload them to remote server.&lt;br /&gt;
In ignored files section, you can put :&lt;br /&gt;
    &amp;quot;ignore&amp;quot;: [&lt;br /&gt;
        &amp;quot;\\.vscode&amp;quot;,&lt;br /&gt;
        &amp;quot;\\.git&amp;quot;,&lt;br /&gt;
        &amp;quot;\\.DS_Store&amp;quot;,&lt;br /&gt;
        &amp;quot;package.json&amp;quot;,&lt;br /&gt;
        &amp;quot;package-lock.json&amp;quot;,&lt;br /&gt;
        &amp;quot;yarn.lock&amp;quot;,&lt;br /&gt;
        &amp;quot;tsconfig.json&amp;quot;,&lt;br /&gt;
        &amp;quot;src&amp;quot;,&lt;br /&gt;
        &amp;quot;node_modules&amp;quot;,&lt;br /&gt;
        &amp;quot;README.md&amp;quot;&lt;br /&gt;
    ],&lt;br /&gt;
&lt;br /&gt;
=== Hint ===&lt;br /&gt;
Make sure &amp;lt;code&amp;gt;.vscode&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;node_modules&amp;lt;/code&amp;gt; are in &amp;lt;code&amp;gt;.gitignore&amp;lt;/code&amp;gt; if you commit your project somewhere.&lt;br /&gt;
&lt;br /&gt;
== Create skeleton ==&lt;br /&gt;
When you create your game in BGA Studio, a JS and CSS file are generated. As we will overwrite them with autobuild. You can put the TS/SCSS files on a &amp;lt;code&amp;gt;src&amp;lt;/code&amp;gt; folder to separate them from built files, but that&#039;s not mandatory.&lt;br /&gt;
&lt;br /&gt;
=== Typescript file skeleton ===&lt;br /&gt;
Typescript example here have been stripped down of all comments for clarity. You can view full file with generated comments [https://github.com/thoun/bga-ts-example/blob/main/src/yourgamename.ts here].&lt;br /&gt;
Your TS code can be splitted in multiple files, you can have a look [https://github.com/thoun/bga-ts-example here] for inspiration.&lt;br /&gt;
To make this page concise, I removed comments and code samples. If it&#039;s your first game, I strongly recommend you to report them on the TS file before activating auto-build !&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;your game name&amp;gt;.ts&#039;&#039;&#039;&lt;br /&gt;
 declare const define;&lt;br /&gt;
 declare const ebg;&lt;br /&gt;
 declare const $;&lt;br /&gt;
 //declare const dojo/*: Dojo*/;&lt;br /&gt;
 declare const _;&lt;br /&gt;
 declare const g_gamethemeurl;&lt;br /&gt;
 &lt;br /&gt;
 class &amp;lt;Your game name&amp;gt; /*implements Game*/ {&lt;br /&gt;
 &lt;br /&gt;
     private gamedatas: any;&lt;br /&gt;
     private player_id: string;&lt;br /&gt;
     private players: { [playerId: number]: any /*Player*/ };&lt;br /&gt;
     private playerNumber: number;&lt;br /&gt;
 &lt;br /&gt;
     constructor() {}&lt;br /&gt;
     &lt;br /&gt;
     public setup(gamedatas: any) {&lt;br /&gt;
         this.setupNotifications();&lt;br /&gt;
     } &lt;br /&gt;
     public onEnteringState(stateName: string, args: any) {}&lt;br /&gt;
     public onLeavingState(stateName: string) {}&lt;br /&gt;
     public onUpdateActionButtons(stateName: string, args: any) {} &lt;br /&gt;
     public setupNotifications() {}&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
To plug the class with BGA framework, we&#039;ll also create another file :&lt;br /&gt;
&#039;&#039;&#039;define.ts&#039;&#039;&#039;&lt;br /&gt;
 define([&lt;br /&gt;
     &amp;quot;dojo&amp;quot;,&amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/stock&amp;quot;&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.&amp;lt;your game name&amp;gt;&amp;quot;, ebg.core.gamegui, new &amp;lt;Your game name&amp;gt;());             &lt;br /&gt;
 });&lt;br /&gt;
Copy &amp;lt;code&amp;gt;bgagame.&amp;lt;your game name&amp;gt;&amp;lt;/code&amp;gt; from original JS to avoid name mistakes. &amp;lt;code&amp;gt;new &amp;lt;Your game name&amp;gt;()&amp;lt;/code&amp;gt; must match your class name defined on previous file.&lt;br /&gt;
&lt;br /&gt;
=== SCSS file ===&lt;br /&gt;
Nothing special here, just write classic SCSS (will be compiled by Dart scss) and name it &#039;&#039;&#039;&amp;lt;your game name&amp;gt;.scss&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Your SCSS code can be splitted in multiple files, for example :&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;your game name&amp;gt;.scss&#039;&#039;&#039;&lt;br /&gt;
  @import &#039;gametable&#039;;&lt;br /&gt;
 &lt;br /&gt;
  /* some classes */&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;_gametable.scss&#039;&#039;&#039;&lt;br /&gt;
  /* _gametable related classes */&lt;br /&gt;
&lt;br /&gt;
=== Configure package.json and tsconfig.json ===&lt;br /&gt;
&lt;br /&gt;
Create a file named &amp;lt;code&amp;gt;package.json&amp;lt;/code&amp;gt; on the root folder, not on the src folder.&lt;br /&gt;
&#039;&#039;&#039;package.json&#039;&#039;&#039;&lt;br /&gt;
 {&lt;br /&gt;
   &amp;quot;name&amp;quot;: &amp;quot;&amp;lt;your game name&amp;gt;&amp;quot;,&lt;br /&gt;
   &amp;quot;version&amp;quot;: &amp;quot;1.0.0&amp;quot;,&lt;br /&gt;
   &amp;quot;description&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
   &amp;quot;main&amp;quot;: &amp;quot;&amp;lt;your game name&amp;gt;.js&amp;quot;,&lt;br /&gt;
   &amp;quot;scripts&amp;quot;: {&lt;br /&gt;
     &amp;quot;build:ts&amp;quot;: &amp;quot;tsc&amp;quot;,&lt;br /&gt;
     &amp;quot;build:scss&amp;quot;: &amp;quot;sass --no-source-map src/&amp;lt;your game name&amp;gt;.scss &amp;lt;your game name&amp;gt;.css&amp;quot;,&lt;br /&gt;
     &amp;quot;watch:scss&amp;quot;: &amp;quot;sass --watch src/&amp;lt;your game name&amp;gt;.scss &amp;lt;your game name&amp;gt;.css&amp;quot;&lt;br /&gt;
   },&lt;br /&gt;
   &amp;quot;author&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
   &amp;quot;license&amp;quot;: &amp;quot;ISC&amp;quot;,&lt;br /&gt;
   &amp;quot;devDependencies&amp;quot;: {&lt;br /&gt;
     &amp;quot;sass&amp;quot;: &amp;quot;^1.32.6&amp;quot;,&lt;br /&gt;
     &amp;quot;typescript&amp;quot;: &amp;quot;^4.1.3&amp;quot;&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
When package.json is created, run &amp;lt;code&amp;gt;npm i&amp;lt;/code&amp;gt; on the root folder to install builders (will generate a node_modules folder).&lt;br /&gt;
&lt;br /&gt;
For Typescript compilation we also need to set up a &amp;lt;code&amp;gt;tsconfig.json&amp;lt;/code&amp;gt; on the root folder.&lt;br /&gt;
&#039;&#039;&#039;tsconfig.json&#039;&#039;&#039;&lt;br /&gt;
 {&lt;br /&gt;
     &amp;quot;rootDir&amp;quot;: &amp;quot;.&amp;quot;, &lt;br /&gt;
     &amp;quot;compilerOptions&amp;quot;: {&lt;br /&gt;
       &amp;quot;target&amp;quot;: &amp;quot;es5&amp;quot;,&lt;br /&gt;
       &amp;quot;module&amp;quot;: &amp;quot;none&amp;quot;,&lt;br /&gt;
       &amp;quot;lib&amp;quot;: [&amp;quot;dom&amp;quot;, &amp;quot;esnext&amp;quot;],  &lt;br /&gt;
       &amp;quot;sourceMap&amp;quot;: false,&lt;br /&gt;
       &amp;quot;outFile&amp;quot;: &amp;quot;&amp;lt;your game name&amp;gt;.js&amp;quot;,&lt;br /&gt;
     },&lt;br /&gt;
     &amp;quot;files&amp;quot;: [&lt;br /&gt;
         &amp;quot;src/&amp;lt;your game name&amp;gt;.ts&amp;quot;,&lt;br /&gt;
         &amp;quot;src/define.ts&amp;quot;&lt;br /&gt;
     ]&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
If you want to split your code onto multiple files, just add them in the file list (order is important for dependencies, new subpart should go on top of the list). No need to import classes or types from one file to another. In fact, you can&#039;t with this configuration. If you manage to make them work, please contact me and we&#039;ll update this documentation.&lt;br /&gt;
&lt;br /&gt;
=== Code completion ===&lt;br /&gt;
To add code completion on framework, doko, stock, ... you&#039;ll need definition files. Feel free to copy them from [https://github.com/thoun/bga-ts-example this repo] and reference them at the top of files array, even before your subpart files.&lt;/div&gt;</summary>
		<author><name>Leocaseiro</name></author>
	</entry>
	<entry>
		<id>https://en.doc.boardgamearena.com/index.php?title=Using_Typescript_and_Scss&amp;diff=12556</id>
		<title>Using Typescript and Scss</title>
		<link rel="alternate" type="text/html" href="https://en.doc.boardgamearena.com/index.php?title=Using_Typescript_and_Scss&amp;diff=12556"/>
		<updated>2022-04-08T14:39:45Z</updated>

		<summary type="html">&lt;p&gt;Leocaseiro: /* Configure package.json and tsconfig.json */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page will help you set up your project to use Typescript client file and Scss style files, and automatically build Javascript (in ES5) files and CSS files so your project stay compatible to BGA framework requirements.&lt;br /&gt;
You can use only TS or only SCSS part if you want, they are not linked.&lt;br /&gt;
&lt;br /&gt;
== How to install the auto-build stack ==&lt;br /&gt;
&lt;br /&gt;
=== Install dev stack  ===&lt;br /&gt;
Install node/npm.  Here is an example to activate auto-build in Visual Studio Code, if you use another tool I strongly recommend to find an equivalent so you don&#039;t have to launch build manually after each modification.&lt;br /&gt;
&lt;br /&gt;
=== Auto build JS and CSS files ===&lt;br /&gt;
In VS Code, add extension https://marketplace.visualstudio.com/items?itemName=emeraldwalk.RunOnSave and then add to VSCode &amp;lt;code&amp;gt;config.json&amp;lt;/code&amp;gt; extension part :&lt;br /&gt;
        &amp;quot;commands&amp;quot;: [&lt;br /&gt;
            {&lt;br /&gt;
                &amp;quot;match&amp;quot;: &amp;quot;.*\\.ts$&amp;quot;,&lt;br /&gt;
                &amp;quot;isAsync&amp;quot;: true,&lt;br /&gt;
                &amp;quot;cmd&amp;quot;: &amp;quot;npm run build:ts&amp;quot;&lt;br /&gt;
            },&lt;br /&gt;
            {&lt;br /&gt;
                &amp;quot;match&amp;quot;: &amp;quot;.*\\.scss$&amp;quot;,&lt;br /&gt;
                &amp;quot;isAsync&amp;quot;: true,&lt;br /&gt;
                &amp;quot;cmd&amp;quot;: &amp;quot;npm run build:scss&amp;quot;&lt;br /&gt;
            }&lt;br /&gt;
        ]&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;build:ts&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;build:scss&amp;lt;/code&amp;gt; are script tasks we&#039;ll configure later.&lt;br /&gt;
&lt;br /&gt;
=== Auto-upload built files ===&lt;br /&gt;
Also add one auto-FTP upload extension (for example https://marketplace.visualstudio.com/items?itemName=lukasz-wronski.ftp-sync) and configure it. The extension will detected modified files in the workspace, including built ones, and upload them to remote server.&lt;br /&gt;
In ignored files section, you can put :&lt;br /&gt;
    &amp;quot;ignore&amp;quot;: [&lt;br /&gt;
        &amp;quot;\\.vscode&amp;quot;,&lt;br /&gt;
        &amp;quot;\\.git&amp;quot;,&lt;br /&gt;
        &amp;quot;\\.DS_Store&amp;quot;,&lt;br /&gt;
        &amp;quot;package.json&amp;quot;,&lt;br /&gt;
        &amp;quot;package-lock.json&amp;quot;,&lt;br /&gt;
        &amp;quot;yarn.lock&amp;quot;,&lt;br /&gt;
        &amp;quot;tsconfig.json&amp;quot;,&lt;br /&gt;
        &amp;quot;src&amp;quot;,&lt;br /&gt;
        &amp;quot;node_modules&amp;quot;,&lt;br /&gt;
        &amp;quot;README.md&amp;quot;&lt;br /&gt;
    ],&lt;br /&gt;
&lt;br /&gt;
=== Hint ===&lt;br /&gt;
Make sure &amp;lt;code&amp;gt;.vscode&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;node_modules&amp;lt;/code&amp;gt; are in &amp;lt;code&amp;gt;.gitignore&amp;lt;/code&amp;gt; if you commit your project somewhere.&lt;br /&gt;
&lt;br /&gt;
== Create skeleton ==&lt;br /&gt;
When you create your game in BGA Studio, a JS and CSS file are generated. As we will overwrite them with autobuild. You can put the TS/SCSS files on a &amp;lt;code&amp;gt;src&amp;lt;/code&amp;gt; folder to separate them from built files, but that&#039;s not mandatory.&lt;br /&gt;
&lt;br /&gt;
=== Typescript file skeleton ===&lt;br /&gt;
Typescript example here have been stripped down of all comments for clarity. You can view full file with generated comments [https://github.com/thoun/bga-ts-example/blob/main/src/yourgamename.ts here].&lt;br /&gt;
Your TS code can be splitted in multiple files, you can have a look [https://github.com/thoun/bga-ts-example here] for inspiration.&lt;br /&gt;
To make this page concise, I removed comments and code samples. If it&#039;s your first game, I strongly recommend you to report them on the TS file before activating auto-build !&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;your game name&amp;gt;.ts&#039;&#039;&#039;&lt;br /&gt;
 declare const define;&lt;br /&gt;
 declare const ebg;&lt;br /&gt;
 declare const $;&lt;br /&gt;
 //declare const dojo/*: Dojo*/;&lt;br /&gt;
 declare const _;&lt;br /&gt;
 declare const g_gamethemeurl;&lt;br /&gt;
 &lt;br /&gt;
 class &amp;lt;Your game name&amp;gt; /*implements Game*/ {&lt;br /&gt;
 &lt;br /&gt;
     private gamedatas: any;&lt;br /&gt;
     private player_id: string;&lt;br /&gt;
     private players: { [playerId: number]: any /*Player*/ };&lt;br /&gt;
     private playerNumber: number;&lt;br /&gt;
 &lt;br /&gt;
     constructor() {}&lt;br /&gt;
     &lt;br /&gt;
     public setup(gamedatas: any) {&lt;br /&gt;
         this.setupNotifications();&lt;br /&gt;
     } &lt;br /&gt;
     public onEnteringState(stateName: string, args: any) {}&lt;br /&gt;
     public onLeavingState(stateName: string) {}&lt;br /&gt;
     public onUpdateActionButtons(stateName: string, args: any) {} &lt;br /&gt;
     public setupNotifications() {}&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
To plug the class with BGA framework, we&#039;ll also create another file :&lt;br /&gt;
&#039;&#039;&#039;define.ts&#039;&#039;&#039;&lt;br /&gt;
 define([&lt;br /&gt;
     &amp;quot;dojo&amp;quot;,&amp;quot;dojo/_base/declare&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/core/gamegui&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/counter&amp;quot;,&lt;br /&gt;
     &amp;quot;ebg/stock&amp;quot;&lt;br /&gt;
 ],&lt;br /&gt;
 function (dojo, declare) {&lt;br /&gt;
     return declare(&amp;quot;bgagame.&amp;lt;your game name&amp;gt;&amp;quot;, ebg.core.gamegui, new &amp;lt;Your game name&amp;gt;());             &lt;br /&gt;
 });&lt;br /&gt;
Copy &amp;lt;code&amp;gt;bgagame.&amp;lt;your game name&amp;gt;&amp;lt;/code&amp;gt; from original JS to avoid name mistakes. &amp;lt;code&amp;gt;new &amp;lt;Your game name&amp;gt;()&amp;lt;/code&amp;gt; must match your class name defined on previous file.&lt;br /&gt;
&lt;br /&gt;
=== SCSS file ===&lt;br /&gt;
Nothing special here, just write classic SCSS (will be compiled by Dart scss) and name it &#039;&#039;&#039;&amp;lt;your game name&amp;gt;.scss&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Your SCSS code can be splitted in multiple files, for example :&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;your game name&amp;gt;.scss&#039;&#039;&#039;&lt;br /&gt;
  @import &#039;gametable&#039;;&lt;br /&gt;
 &lt;br /&gt;
  /* some classes */&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;_gametable.scss&#039;&#039;&#039;&lt;br /&gt;
  /* _gametable related classes */&lt;br /&gt;
&lt;br /&gt;
=== Configure package.json and tsconfig.json ===&lt;br /&gt;
&lt;br /&gt;
Create a file named &amp;lt;code&amp;gt;package.json&amp;lt;/code&amp;gt; on the root folder, not on the src folder.&lt;br /&gt;
&#039;&#039;&#039;package.json&#039;&#039;&#039;&lt;br /&gt;
 {&lt;br /&gt;
   &amp;quot;name&amp;quot;: &amp;quot;&amp;lt;your game name&amp;gt;&amp;quot;,&lt;br /&gt;
   &amp;quot;version&amp;quot;: &amp;quot;1.0.0&amp;quot;,&lt;br /&gt;
   &amp;quot;description&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
   &amp;quot;main&amp;quot;: &amp;quot;&amp;lt;your game name&amp;gt;.js&amp;quot;,&lt;br /&gt;
   &amp;quot;scripts&amp;quot;: {&lt;br /&gt;
     &amp;quot;build:ts&amp;quot;: &amp;quot;tsc&amp;quot;,&lt;br /&gt;
     &amp;quot;build:scss&amp;quot;: &amp;quot;sass --no-source-map src/&amp;lt;your game name&amp;gt;.scss &amp;lt;your game name&amp;gt;.css&amp;quot;,&lt;br /&gt;
     &amp;quot;watch:scss&amp;quot;: &amp;quot;sass --watch src/&amp;lt;your game name&amp;gt;.scss &amp;lt;your game name&amp;gt;.css&amp;quot;&lt;br /&gt;
   },&lt;br /&gt;
   &amp;quot;author&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
   &amp;quot;license&amp;quot;: &amp;quot;ISC&amp;quot;,&lt;br /&gt;
   &amp;quot;devDependencies&amp;quot;: {&lt;br /&gt;
     &amp;quot;sass&amp;quot;: &amp;quot;^1.32.6&amp;quot;,&lt;br /&gt;
     &amp;quot;typescript&amp;quot;: &amp;quot;^4.1.3&amp;quot;&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
When package.json is created, run &amp;lt;code&amp;gt;npm i&amp;lt;/code&amp;gt; on the root folder to install builders (will generate a node_modules folder).&lt;br /&gt;
&lt;br /&gt;
For Typescript compilation we also need to set up a &amp;lt;code&amp;gt;tsconfig.json&amp;lt;/code&amp;gt; on the root folder.&lt;br /&gt;
&#039;&#039;&#039;tsconfig.json&#039;&#039;&#039;&lt;br /&gt;
 {&lt;br /&gt;
     &amp;quot;rootDir&amp;quot;: &amp;quot;.&amp;quot;, &lt;br /&gt;
     &amp;quot;compilerOptions&amp;quot;: {&lt;br /&gt;
       &amp;quot;target&amp;quot;: &amp;quot;es5&amp;quot;,&lt;br /&gt;
       &amp;quot;module&amp;quot;: &amp;quot;none&amp;quot;,&lt;br /&gt;
       &amp;quot;lib&amp;quot;: [&amp;quot;dom&amp;quot;, &amp;quot;esnext&amp;quot;],  &lt;br /&gt;
       &amp;quot;sourceMap&amp;quot;: false,&lt;br /&gt;
       &amp;quot;outFile&amp;quot;: &amp;quot;&amp;lt;your game name&amp;gt;.js&amp;quot;,&lt;br /&gt;
     },&lt;br /&gt;
     &amp;quot;files&amp;quot;: [&lt;br /&gt;
         &amp;quot;src/&amp;lt;your game name&amp;gt;.ts&amp;quot;,&lt;br /&gt;
         &amp;quot;src/define.ts&amp;quot;&lt;br /&gt;
     ]&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
If you want to split your code onto multiple files, just add them in the file list (order is important for dependencies, new subpart should go on top of the list). No need to import classes or types from one file to another. In fact, you can&#039;t with this configuration. If you manage to make them work, please contact me and we&#039;ll update this documentation.&lt;br /&gt;
&lt;br /&gt;
=== Code completion ===&lt;br /&gt;
To add code completion on framework, doko, stock, ... you&#039;ll need definition files. Feel free to copy them from [https://github.com/thoun/bga-ts-example this repo] and reference them at the top of files array, even before your subpart files.&lt;/div&gt;</summary>
		<author><name>Leocaseiro</name></author>
	</entry>
</feed>