<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="be">
	<id>https://be.doc.boardgamearena.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Justinfernal</id>
	<title>Board Game Arena - Уклад удзельніка [be]</title>
	<link rel="self" type="application/atom+xml" href="https://be.doc.boardgamearena.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Justinfernal"/>
	<link rel="alternate" type="text/html" href="https://be.doc.boardgamearena.com/%D0%90%D0%B4%D0%BC%D1%8B%D1%81%D0%BB%D0%BE%D0%B2%D0%B0%D0%B5:Contributions/Justinfernal"/>
	<updated>2026-09-30T13:14:01Z</updated>
	<subtitle>Уклад удзельніка</subtitle>
	<generator>MediaWiki 1.39.0</generator>
	<entry>
		<id>https://be.doc.boardgamearena.com/index.php?title=Deck&amp;diff=3951</id>
		<title>Deck</title>
		<link rel="alternate" type="text/html" href="https://be.doc.boardgamearena.com/index.php?title=Deck&amp;diff=3951"/>
		<updated>2020-04-03T22:37:32Z</updated>

		<summary type="html">&lt;p&gt;Justinfernal: For coherence with the command lines below.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;quot;Deck&amp;quot; is one of the most useful component on the PHP side. With &amp;quot;Deck&amp;quot;, you can manage the cards in your game on the server side.&lt;br /&gt;
&lt;br /&gt;
Using &amp;quot;deck&amp;quot;, you will be able to use the following features without writing a single SQL database request:&lt;br /&gt;
* Place cards in a pile, shuffle cards, draw cards one by one or many at a time.&lt;br /&gt;
* &amp;quot;Auto-reshuffle&amp;quot; the discard pile into the deck when the deck is empty.&lt;br /&gt;
* Move cards between different locations: hands of players, the table, etc.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Using Deck: Hearts example ==&lt;br /&gt;
&lt;br /&gt;
The Deck component is extensively used in the sample &#039;&#039;Hearts&#039;&#039; card game. You will find in &amp;quot;hearts.game.php&amp;quot; that the object &amp;quot;$this-&amp;gt;cards&amp;quot; is used many times.&lt;br /&gt;
&lt;br /&gt;
== Deck overview ==&lt;br /&gt;
&lt;br /&gt;
With Deck component, you manage all cards of your game.&lt;br /&gt;
&lt;br /&gt;
=== The 5 properties of each card ===&lt;br /&gt;
&lt;br /&gt;
Using the Deck component, each card will have 5 properties:&lt;br /&gt;
* &#039;&#039;&#039;id&#039;&#039;&#039;: This is the unique ID of each card.&lt;br /&gt;
* &#039;&#039;&#039;type&#039;&#039;&#039; and &#039;&#039;&#039;type_arg&#039;&#039;&#039;: These two values define the type of your card (i.e., what sort of card is this?).&lt;br /&gt;
* &#039;&#039;&#039;location&#039;&#039;&#039; and &#039;&#039;&#039;location_arg&#039;&#039;&#039;: These two values define where the card is at now.&lt;br /&gt;
&lt;br /&gt;
The id, type, and type_arg properties are constants throughout the game. location and location_arg change when your cards move from one place to another in the game area.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;id&#039;&#039;&#039; is the unique ID of each card. Two cards cannot have the same ID. IDs are generated automatically by the Deck component when you create cards during the Setup phase of your game.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;type&#039;&#039;&#039; and &#039;&#039;&#039;type_arg&#039;&#039;&#039; defines the type of your card.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;type&#039;&#039;&#039; is a short string, and &#039;&#039;&#039;type_arg&#039;&#039;&#039; is an integer.&lt;br /&gt;
&lt;br /&gt;
You can use these two values as you like to make sure you will be able to identify the different cards in the game. See usage of &amp;quot;type&amp;quot; and &amp;quot;type_arg&amp;quot; below.&lt;br /&gt;
&lt;br /&gt;
Examples of usage of &amp;quot;type&amp;quot; and &amp;quot;type_arg&amp;quot;:&lt;br /&gt;
* In &#039;&#039;Hearts&#039;&#039;, &amp;quot;type&amp;quot; represents the color (suite) of the card (1 to 4) and &amp;quot;type_arg&amp;quot; is the value of the card (1, 2, ... 10, J, Q, K).&lt;br /&gt;
* In &#039;&#039;Seasons&#039;&#039;, &amp;quot;type&amp;quot; represents the type of the card (e.g., 1 is Amulet of Air, 2 is Amulet of Fire, etc...). type_arg is not used.&lt;br /&gt;
* In &#039;&#039;Takenoko&#039;&#039;, a Deck component is used for objective cards. &amp;quot;type&amp;quot; is the kind of objective (irrigation/panda/plot) and &amp;quot;type_arg&amp;quot; is the ID of the specific objective to realize (e.g., &amp;quot;green bamboo x4&amp;quot;). Note that a second Deck component is used in &#039;&#039;Takenoko&#039;&#039; to manage the &amp;quot;garden plot&amp;quot; pile.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;location&#039;&#039;&#039; and &#039;&#039;&#039;location_arg&#039;&#039;&#039; define where a card is at now. &#039;&#039;&#039;location&#039;&#039;&#039; is a short string, and &#039;&#039;&#039;location_arg&#039;&#039;&#039; is an integer.&lt;br /&gt;
&lt;br /&gt;
You can use &#039;location&#039; and &#039;location_arg&#039; as you like, to move your card within the game area.&lt;br /&gt;
&lt;br /&gt;
There are 3 special &#039;location&#039; values that Deck manages automatically. You can choose to use these locations or not, depending on your needs:&lt;br /&gt;
* &#039;deck&#039;: the &#039;deck&#039; location is a standard draw deck. Cards are placed face down in a stack and are drawn in sequential order during the game. &#039;location_arg&#039; is used to specify where the card is located within the stack (the card with the highest location_arg value is the next to be drawn).&lt;br /&gt;
* &#039;hand&#039;: the &#039;hand&#039; location represents cards in a player&#039;s hand. &#039;location_arg&#039; is set to the ID of each player.&lt;br /&gt;
* &#039;discard&#039;: the &#039;discard&#039; location is used for discard piles. Card in &#039;discard&#039; may be reshuffled into the deck if needed (see &amp;quot;autoreshuffle&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Tips: using the Deck component, you will use generic properties (&amp;quot;location&amp;quot;, &amp;quot;type_arg&amp;quot;,...) for specific purposes in your game. Thus, during the design step before realizing your game, take a few minutes to write down the exact meaning of each of these generic properties in the context of your game.&lt;br /&gt;
&lt;br /&gt;
=== Create a new Deck component ===&lt;br /&gt;
&lt;br /&gt;
For each Deck component in your game, you need to create a dedicated table in the SQL database. This table has a standard format. In practice, if you just want to have a Deck component named &amp;quot;card&amp;quot;, you can copy/paste the following into your &amp;quot;dbmodel.sql&amp;quot; file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE TABLE IF NOT EXISTS `card` (&lt;br /&gt;
  `card_id` int(10) unsigned NOT NULL AUTO_INCREMENT,&lt;br /&gt;
  `card_type` varchar(16) NOT NULL,&lt;br /&gt;
  `card_type_arg` int(11) NOT NULL,&lt;br /&gt;
  `card_location` varchar(16) NOT NULL,&lt;br /&gt;
  `card_location_arg` int(11) NOT NULL,&lt;br /&gt;
  PRIMARY KEY (`card_id`)&lt;br /&gt;
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: the database schema of this table does not have to be exactly what is listed above. You can increase the size of the fields or add more fields. For additional fields&lt;br /&gt;
you just have to do manual queries.&lt;br /&gt;
&lt;br /&gt;
Once you have done this (and restarted your game), you can declare the Deck component in your PHP code in your class constructor. For &#039;&#039;Hearts&#039;&#039; for example, I added to the &amp;quot;Hearts()&amp;quot; method:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        $this-&amp;gt;cards = self::getNew( &amp;quot;module.common.deck&amp;quot; );&lt;br /&gt;
        $this-&amp;gt;cards-&amp;gt;init( &amp;quot;card&amp;quot; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that we specify &amp;quot;card&amp;quot; here: the name of our previously created table. This means you can create several &amp;quot;Deck&amp;quot; components with multiple tables:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        $this-&amp;gt;firstKindCards = self::getNew( &amp;quot;module.common.deck&amp;quot; );&lt;br /&gt;
        $this-&amp;gt;firstKindCards -&amp;gt;init( &amp;quot;first_kind_card&amp;quot; );&lt;br /&gt;
        $this-&amp;gt;secondKindCards = self::getNew( &amp;quot;module.common.deck&amp;quot; );&lt;br /&gt;
        $this-&amp;gt;secondKindCards -&amp;gt;init( &amp;quot;second_kind_card&amp;quot; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Most of the time this is not useful; a Deck component should manage all objects of the same kind (i.e., all cards in the game).&lt;br /&gt;
&lt;br /&gt;
Afterwards, we can initialize your &amp;quot;Deck&amp;quot; by creating all the cards of the game. Generally, this is done only once during the game, in the &amp;quot;setupNewGame&amp;quot; method.&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;Deck&amp;quot; component provides a fast way to initialize all your cards at once: createCards. Here is how it is used for &amp;quot;Hearts&amp;quot;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        // Create cards&lt;br /&gt;
        $cards = array();&lt;br /&gt;
        foreach( $this-&amp;gt;colors as  $color_id =&amp;gt; $color ) // spade, heart, diamond, club&lt;br /&gt;
        {&lt;br /&gt;
            for( $value=2; $value&amp;lt;=14; $value++ )   //  2, 3, 4, ... K, A&lt;br /&gt;
            {&lt;br /&gt;
                $cards[] = array( &#039;type&#039; =&amp;gt; $color_id, &#039;type_arg&#039; =&amp;gt; $value, &#039;nbr&#039; =&amp;gt; 1);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $this-&amp;gt;cards-&amp;gt;createCards( $cards, &#039;deck&#039; );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As you can see, &amp;quot;createCards&amp;quot; takes a description of all cards of the game. For each type of card, you have to specify its &amp;quot;type&amp;quot;, &amp;quot;type_arg&amp;quot; and the number of card to create. &amp;quot;createCards&amp;quot; create all cards and place them into the &amp;quot;deck&amp;quot; location (as specified in the second argument).&lt;br /&gt;
&lt;br /&gt;
Now, you are ready to use &amp;quot;Deck&amp;quot;!&lt;br /&gt;
&lt;br /&gt;
=== Simple examples using Deck ===&lt;br /&gt;
&lt;br /&gt;
(Most examples are from &amp;quot;Hearts&amp;quot; game)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     // In &amp;quot;getAllDatas&#039;, we need to send to the current player all the cards he has in hand:&lt;br /&gt;
     $result[&#039;hand&#039;] = $this-&amp;gt;cards-&amp;gt;getCardsInLocation( &#039;hand&#039;, $player_id );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     // At some time we want to check if all the cards (52) are in player&#039;s hands:&lt;br /&gt;
     if( $this-&amp;gt;cards-&amp;gt;countCardInLocation( &#039;hand&#039; ) == 52 )&lt;br /&gt;
           // do something&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     // When a player plays a card in front of him on the table:&lt;br /&gt;
     $this-&amp;gt;cards-&amp;gt;moveCard( $card_id, &#039;cardsontable&#039;, $player_id );&lt;br /&gt;
&lt;br /&gt;
     // Note the use of the custom location &#039;cardsontable&#039; here to keep track of cards on the table.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
     // This is a new hand: let&#039;s gather all cards from everywhere in the deck:&lt;br /&gt;
     $this-&amp;gt;cards-&amp;gt;moveAllCardsInLocation( null, &amp;quot;deck&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
     // And then shuffle the deck&lt;br /&gt;
     $this-&amp;gt;cards-&amp;gt;shuffle( &#039;deck&#039; );&lt;br /&gt;
&lt;br /&gt;
     // And then deal 13 cards to each player&lt;br /&gt;
     // Deal 13 cards to each players&lt;br /&gt;
     // Create deck, shuffle it and give 13 initial cards&lt;br /&gt;
     $players = self::loadPlayersBasicInfos();&lt;br /&gt;
     foreach( $players as $player_id =&amp;gt; $player )&lt;br /&gt;
     {&lt;br /&gt;
        $cards = $this-&amp;gt;cards-&amp;gt;pickCards( 13, &#039;deck&#039;, $player_id );&lt;br /&gt;
           &lt;br /&gt;
        // Notify player about his cards&lt;br /&gt;
        self::notifyPlayer( $player_id, &#039;newHand&#039;, &#039;&#039;, array( &lt;br /&gt;
            &#039;cards&#039; =&amp;gt; $cards&lt;br /&gt;
         ) );&lt;br /&gt;
     }  &lt;br /&gt;
&lt;br /&gt;
     // Note the use of &amp;quot;notifyPlayer&amp;quot; instead of &amp;quot;notifyAllPlayers&amp;quot;: new cards is a private information ;)  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Deck component reference ==&lt;br /&gt;
&lt;br /&gt;
=== Initializing Deck component ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;init( $table_name )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Initialize the Deck component.&lt;br /&gt;
&lt;br /&gt;
Argument:&lt;br /&gt;
* table_name: name of the DB table used by this Deck component.&lt;br /&gt;
&lt;br /&gt;
Must be called before any other Deck method.&lt;br /&gt;
&lt;br /&gt;
Usually, init is called in your game constructor.&lt;br /&gt;
&lt;br /&gt;
Example with Hearts:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	function Hearts( )&lt;br /&gt;
	{&lt;br /&gt;
        (...)&lt;br /&gt;
        &lt;br /&gt;
        $this-&amp;gt;cards = self::getNew( &amp;quot;module.common.deck&amp;quot; );&lt;br /&gt;
        $this-&amp;gt;cards-&amp;gt;init( &amp;quot;card&amp;quot; );&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;createCards( $cards, $location=&#039;deck&#039;, $location_arg=null )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Create card items in your deck component. Usually, all card items are created once, during the setup phase of the game.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;cards&amp;quot; describe all cards that need to be created. &amp;quot;cards&amp;quot; is an array with the following format:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   // Create 1 card of type &amp;quot;1&amp;quot; with type_arg=99,&lt;br /&gt;
   //  and 4 cards of type &amp;quot;2&amp;quot; with type_arg=12,&lt;br /&gt;
   //  and 2 cards of type &amp;quot;3&amp;quot; with type_arg=33&lt;br /&gt;
&lt;br /&gt;
   $cards = array(&lt;br /&gt;
        array( &#039;type&#039; =&amp;gt; 1, &#039;type_arg&#039; =&amp;gt; 99, &#039;nbr&#039; =&amp;gt; 1 ),&lt;br /&gt;
        array( &#039;type&#039; =&amp;gt; 2, &#039;type_arg&#039; =&amp;gt; 12, &#039;nbr&#039; =&amp;gt; 4 ),&lt;br /&gt;
        array( &#039;type&#039; =&amp;gt; 3, &#039;type_arg&#039; =&amp;gt; 33, &#039;nbr&#039; =&amp;gt; 2 )&lt;br /&gt;
        ...&lt;br /&gt;
   );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: During the &amp;quot;createCards&amp;quot; process, Deck generates unique IDs for all card items.&lt;br /&gt;
&lt;br /&gt;
Note: createCards is optimized to create a lot of cards at once. Do not use it to create cards one by one.&lt;br /&gt;
&lt;br /&gt;
If &amp;quot;location&amp;quot; and &amp;quot;location_arg&amp;quot; arguments are not set, newly created cards are placed in the &amp;quot;deck&amp;quot; location. If &amp;quot;location&amp;quot; (and optionally location_arg) is specified, cards are created for this specific location.&lt;br /&gt;
&lt;br /&gt;
=== Card standard format ===&lt;br /&gt;
&lt;br /&gt;
When Deck component methods are returning one or several cards, the following format is used:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
array(&lt;br /&gt;
   &#039;id&#039; =&amp;gt; ..,          // the card ID&lt;br /&gt;
   &#039;type&#039; =&amp;gt; ..,        // the card type&lt;br /&gt;
   &#039;type_arg&#039; =&amp;gt; ..,    // the card type argument&lt;br /&gt;
   &#039;location&#039; =&amp;gt; ..,    // the card location&lt;br /&gt;
   &#039;location_arg&#039; =&amp;gt; .. // the card location argument&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Picking cards ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;pickCard( $location, $player_id )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Pick a card from a &amp;quot;pile&amp;quot; location (ex: &amp;quot;deck&amp;quot;) and place it in the &amp;quot;hand&amp;quot; of specified player.&lt;br /&gt;
&lt;br /&gt;
Return the card picked or &amp;quot;null&amp;quot; if there are no more card in given location.&lt;br /&gt;
&lt;br /&gt;
This method supports auto-reshuffle (see &amp;quot;auto-reshuffle&amp;quot; below).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;pickCards( $nbr, $location, $player_id )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Pick &amp;quot;$nbr&amp;quot; cards from a &amp;quot;pile&amp;quot; location (ex: &amp;quot;deck&amp;quot;) and place them in the &amp;quot;hand&amp;quot; of specified player.&lt;br /&gt;
&lt;br /&gt;
Return an array with the cards picked, or &amp;quot;null&amp;quot; if there are no more card in given location.&lt;br /&gt;
&lt;br /&gt;
Note that the number of cards picked can be less than &amp;quot;$nbr&amp;quot; in case there are not enough cards in the pile location.&lt;br /&gt;
&lt;br /&gt;
This method supports auto-reshuffle (see &amp;quot;auto-reshuffle&amp;quot; below). In case there are not enough cards in the pile, all remaining cards are picked first, then the auto-reshuffle is triggered, then the other cards are picked.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;pickCardForLocation( $from_location, $to_location, $location_arg=0 )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This method is similar to &#039;pickCard&#039;, except that you can pick a card for any sort of location and not only the &amp;quot;hand&amp;quot; location.&lt;br /&gt;
&lt;br /&gt;
* from_location is the &amp;quot;pile&amp;quot; style location from where you are picking a card.&lt;br /&gt;
* to_location is the location where you will place the card picked.&lt;br /&gt;
* if &amp;quot;location_arg&amp;quot; is specified, the card picked will be set with this &amp;quot;location_arg&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
This method supports auto-reshuffle (see &amp;quot;auto-reshuffle&amp;quot; below).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;pickCardsForLocation( $nbr, $from_location, $to_location, $location_arg=0, $no_deck_reform=false )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This method is similar to &#039;pickCards&#039;, except that you can pick cards for any sort of location and not only the &amp;quot;hand&amp;quot; location.&lt;br /&gt;
&lt;br /&gt;
* from_location is the &amp;quot;pile&amp;quot; style location from where you are picking some cards.&lt;br /&gt;
* to_location is the location where you will place the cards picked.&lt;br /&gt;
* if &amp;quot;location_arg&amp;quot; is specified, the cards picked will be set with this &amp;quot;location_arg&amp;quot;.&lt;br /&gt;
* if &amp;quot;no_deck_reform&amp;quot; is set to &amp;quot;true&amp;quot;, the auto-reshuffle feature is disabled during this method call.&lt;br /&gt;
&lt;br /&gt;
This method supports auto-reshuffle (see &amp;quot;auto-reshuffle&amp;quot; below).&lt;br /&gt;
&lt;br /&gt;
=== Moving cards ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;moveCard( $card_id, $location, $location_arg=0 )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Move the specific card to given location.&lt;br /&gt;
&lt;br /&gt;
* card_id: ID of the card to move.&lt;br /&gt;
* location: location where to move the card.&lt;br /&gt;
* location_arg: if specified, location_arg where to move the card. If not specified &amp;quot;location_arg&amp;quot; will be set to 0.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;moveCards( $cards, $location, $location_arg )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Move the specific cards to given location.&lt;br /&gt;
&lt;br /&gt;
* cards: an array of IDs of cards to move.&lt;br /&gt;
* location: location where to move the cards.&lt;br /&gt;
* location_arg: if specified, location_arg where to move the cards. If not specified &amp;quot;location_arg&amp;quot; will be set to 0.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;insertCard( $card_id, $location, $location_arg )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Move a card to a specific &amp;quot;pile&amp;quot; location where card are ordered.&lt;br /&gt;
&lt;br /&gt;
If location_arg place is already taken, increment all cards after location_arg in order to insert new card at this precise location.&lt;br /&gt;
&lt;br /&gt;
(note: insertCardOnExtremePosition method below is more useful in most of the case)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;insertCardOnExtremePosition( $card_id, $location, $bOnTop )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Move a card on top or at bottom of given &amp;quot;pile&amp;quot; type location.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;moveAllCardsInLocation(  $from_location, $to_location, $from_location_arg=null, $to_location_arg=0 )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Move all cards in specified &amp;quot;from&amp;quot; location to given location.&lt;br /&gt;
&lt;br /&gt;
* from_location: where to take the cards&lt;br /&gt;
* to_location: where to put the cards&lt;br /&gt;
* from_location (optional): if specified, only cards with given &amp;quot;location_arg&amp;quot; are moved.&lt;br /&gt;
* to_location (optional): if specified, cards moved &amp;quot;location_arg&amp;quot; is set to given value. Otherwise location_arg is set to zero.&lt;br /&gt;
&lt;br /&gt;
Note: if you want to keep &amp;quot;location_arg&amp;quot; untouched, you should use &amp;quot;moveAllCardsInLocationKeepOrder&amp;quot; below.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;moveAllCardsInLocationKeepOrder( $from_location, $to_location )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Move all cards in specified &amp;quot;from&amp;quot; location to given &amp;quot;to&amp;quot; location. This method does not modify the &amp;quot;location_arg&amp;quot; of cards.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;playCard( $card_id )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Move specified card at the top of the &amp;quot;discard&amp;quot; location.&lt;br /&gt;
&lt;br /&gt;
Note: this is an alias for: insertCardOnExtremePosition( $card_id, &amp;quot;discard&amp;quot;, true )&lt;br /&gt;
&lt;br /&gt;
=== Get cards informations ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;getCard( $card_id )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Get specific card information.&lt;br /&gt;
&lt;br /&gt;
Return null if this card is not found.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;getCards( $cards_array )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Get specific cards information.&lt;br /&gt;
&lt;br /&gt;
cards_array is an array of cards ID.&lt;br /&gt;
&lt;br /&gt;
If some cards are not found or if some cards IDs are specified multiple times, the method throws an (unexpected) Exception.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;getCardsInLocation( $location, $location_arg = null, $order_by = null )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Get all cards in specific location, as an array. Return an empty array if the location is empty.&lt;br /&gt;
&lt;br /&gt;
* location (string): the location where to get the cards.&lt;br /&gt;
* location_arg (optional): if specified, return only cards with the specified &amp;quot;location_arg&amp;quot;.&lt;br /&gt;
* order_by (optional): if specified, returned cards are ordered by the given database field. Example: &amp;quot;card_id&amp;quot; or &amp;quot;card_type&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;countCardInLocation( $location, $location_arg=null )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Return the number of cards in specified location.&lt;br /&gt;
&lt;br /&gt;
* location (string): the location where to count the cards.&lt;br /&gt;
* location_arg (optional): if specified, count only cards with the specified &amp;quot;location_arg&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;countCardsInLocations()&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Return the number of cards in each location of the game.&lt;br /&gt;
&lt;br /&gt;
The method returns an associative array with the format &amp;quot;location&amp;quot; =&amp;gt; &amp;quot;number of cards&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  array(&lt;br /&gt;
    &#039;deck&#039; =&amp;gt; 12,&lt;br /&gt;
    &#039;hand&#039; =&amp;gt; 21,&lt;br /&gt;
    &#039;discard&#039; =&amp;gt; 54,&lt;br /&gt;
    &#039;ontable&#039; =&amp;gt; 3&lt;br /&gt;
  );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;countCardsByLocationArgs( $location )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Return the number of cards in each &amp;quot;location_arg&amp;quot; for the given location.&lt;br /&gt;
&lt;br /&gt;
The method returns an associative array with the format &amp;quot;location_arg&amp;quot; =&amp;gt; &amp;quot;number of cards&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Example: count the number of cards in each player&#039;s hand:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    countCardsByLocationArgs( &#039;hand&#039; );&lt;br /&gt;
    &lt;br /&gt;
    // Result:&lt;br /&gt;
    array(&lt;br /&gt;
        122345 =&amp;gt; 5,    // player 122345 has 5 cards in hand&lt;br /&gt;
        123456 =&amp;gt; 4     // and player 123456 has 4 cards in hand&lt;br /&gt;
    );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;getPlayerHand( $player_id )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Get all cards in given player hand.&lt;br /&gt;
&lt;br /&gt;
Note: This is an alias for:&lt;br /&gt;
getCardsInLocation( &amp;quot;hand&amp;quot;, $player_id )&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;getCardOnTop( $location )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Get the card on top of the given (&amp;quot;pile&amp;quot; style) location, or null if the location is empty.&lt;br /&gt;
&lt;br /&gt;
Note that the card pile won&#039;t be &amp;quot;auto-reshuffled&amp;quot; if there is no more card available.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;getCardsOnTop( $nbr, $location )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Get the &amp;quot;$nbr&amp;quot; cards on top of the given (&amp;quot;pile&amp;quot; style) location.&lt;br /&gt;
&lt;br /&gt;
The method return an array with at most &amp;quot;$nbr&amp;quot; elements (or a void array if there is no card in this location).&lt;br /&gt;
&lt;br /&gt;
Note that the card pile won&#039;t be &amp;quot;auto-reshuffled&amp;quot; if there is not enough cards available.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;getExtremePosition( $bGetMax ,$location )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
(rarely used)&lt;br /&gt;
&lt;br /&gt;
Get the position of cards at the top of the given location / at the bottom of the given location.&lt;br /&gt;
&lt;br /&gt;
Of course this method works only on location in &amp;quot;pile&amp;quot; where you are using &amp;quot;location_arg&amp;quot; to specify the position of each card (example: &amp;quot;deck&amp;quot; location).&lt;br /&gt;
&lt;br /&gt;
If bGetMax=true, return the location of the top card of the pile.&lt;br /&gt;
&lt;br /&gt;
If bGetMax=false, return the location of the bottom card of the pile.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;getCardsOfType( $type, $type_arg=null )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Get all cards of a specific type (rarely used).&lt;br /&gt;
&lt;br /&gt;
Return an array of cards, or an empty array if there is no cards of the specified type.&lt;br /&gt;
&lt;br /&gt;
* type: the type of cards&lt;br /&gt;
* type_arg: if specified, return only cards with the specified &amp;quot;type_arg&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;getCardsOfTypeInLocation( $type, $type_arg=null, $location, $location_arg = null )&lt;br /&gt;
&lt;br /&gt;
Get all cards of a specific type in a specific location (rarely used).&lt;br /&gt;
&lt;br /&gt;
Return an array of cards, or an empty array if there is no cards of the specified type.&lt;br /&gt;
&lt;br /&gt;
* type: the type of cards&lt;br /&gt;
* type_arg: if specified, return only cards with the specified &amp;quot;type_arg&amp;quot;.&lt;br /&gt;
* location (string): the location where to get the cards.&lt;br /&gt;
* location_arg (optional): if specified, return only cards with the specified &amp;quot;location_arg&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Shuffling ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;shuffle( $location )&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Shuffle all cards in specific location.&lt;br /&gt;
&lt;br /&gt;
Shuffle only works on locations where cards are on a &amp;quot;pile&amp;quot; (ex: &amp;quot;deck&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Please note that all &amp;quot;location_arg&amp;quot; will be reset to reflect the new order of the cards in the pile.&lt;br /&gt;
&lt;br /&gt;
=== auto-reshuffle ===&lt;br /&gt;
&lt;br /&gt;
To enable auto-reshuffle you must do &amp;quot;$this-&amp;gt;cards-&amp;gt;autoreshuffle = true&amp;quot; during the setup of the component.&lt;br /&gt;
&lt;br /&gt;
Every time a card must be retrieved from the &amp;quot;deck&amp;quot; location, if it is empty the &amp;quot;discard&amp;quot; location will be automatically reshuffled into the &amp;quot;deck&amp;quot; location.&lt;br /&gt;
&lt;br /&gt;
If you need to notify players when the deck is shuffled, you can setup a callback method using this feature: $this-&amp;gt;cards-&amp;gt;autoreshuffle_trigger = array(&#039;obj&#039; =&amp;gt; $this, &#039;method&#039; =&amp;gt; &#039;deckAutoReshuffle&#039;);&lt;br /&gt;
&lt;br /&gt;
If you need to use other locations than &amp;quot;deck&amp;quot; and &amp;quot;discard&amp;quot; for auto-reshuffle feature, you can configure it this way: $this-&amp;gt;cards-&amp;gt;autoreshuffle_custom = array(&#039;deck&#039; =&amp;gt; &#039;discard&#039;); (replace &#039;deck&#039; and &#039;discard&#039; with your custom locations).&lt;/div&gt;</summary>
		<author><name>Justinfernal</name></author>
	</entry>
	<entry>
		<id>https://be.doc.boardgamearena.com/index.php?title=Tools_and_tips_of_BGA_Studio&amp;diff=3912</id>
		<title>Tools and tips of BGA Studio</title>
		<link rel="alternate" type="text/html" href="https://be.doc.boardgamearena.com/index.php?title=Tools_and_tips_of_BGA_Studio&amp;diff=3912"/>
		<updated>2020-03-29T00:01:50Z</updated>

		<summary type="html">&lt;p&gt;Justinfernal: Adding File Sync description for VSCode&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Server Tools and Tips ==&lt;br /&gt;
=== Starting a game in one click ===&lt;br /&gt;
&lt;br /&gt;
To start a game:&lt;br /&gt;
* Create a new table with your game.&lt;br /&gt;
* If you want to play a game with 3 players, specify that you want a maximum of 3 players at this table.&lt;br /&gt;
* Click on &amp;quot;Express Start&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Stopping a game in one click ===&lt;br /&gt;
&lt;br /&gt;
* Click on the &amp;quot;quit&amp;quot; icon on the top right of the screen.&lt;br /&gt;
* Click on &amp;quot;Express Stop&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Switching between users ===&lt;br /&gt;
&lt;br /&gt;
When running a game on Studio, you can use the little red arrow near each player&#039;s name to open a new tab with this player&#039;s perspective.&lt;br /&gt;
&lt;br /&gt;
=== Access to game database and Logs ===&lt;br /&gt;
&lt;br /&gt;
At the bottom of the game area, there is section without a title containing 3 useful links:&lt;br /&gt;
&lt;br /&gt;
  Go to game database • BGA request&amp;amp;SQL logs • BGA unexpected exceptions logs&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;Go to game database&amp;quot; link is an immediate access to the PhpMyAdmin tool to view/edit the tables of the current game&lt;br /&gt;
* BGA request&amp;amp;SQL logs - link to your studio PHP log - all tables, all severities. Anything you print using debugging and tracing functions from PHP and some framework logs&lt;br /&gt;
* BGA unexpected exceptions logs - same log as above but only severity warning and higher&lt;br /&gt;
&lt;br /&gt;
See [[Practical debugging]] for more info about it.&lt;br /&gt;
&lt;br /&gt;
=== Save &amp;amp; restore state ===&lt;br /&gt;
&lt;br /&gt;
Using links of this section, you can save the complete current (database) state of your game, then restore it later.&lt;br /&gt;
&lt;br /&gt;
This is particularly useful when you want to develop a part of the game that is difficult to reproduce: you just have to save the situation just before, and then restore it until this part works fine.&lt;br /&gt;
&lt;br /&gt;
We provide you 3 &amp;quot;slots&amp;quot;: 1, 2 and 3. This way, you can save 3 different game situations.&lt;br /&gt;
&lt;br /&gt;
Limits:&lt;br /&gt;
* the &amp;quot;restore&amp;quot; function does not work anymore when the game is over.&lt;br /&gt;
* a saved situation from a given table cannot be restored in another table.&lt;br /&gt;
* when you &amp;quot;restore&amp;quot; a situation, the current browser page is refreshed to reflect the updated game situation, but you have to refresh you other tabs/pages manually.&lt;br /&gt;
&lt;br /&gt;
=== Input/Output debugging section ===&lt;br /&gt;
&lt;br /&gt;
This section shows you:&lt;br /&gt;
* The AJAX calls made by your game interface to the game server. AJAX calls (outputs) begins with &amp;quot;&amp;gt;&amp;quot;&lt;br /&gt;
* The notifications received by your game interface. Notifications (inputs) begins with &amp;quot;&amp;lt;&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Note: if you click on some notification title, you can resend it immediately to the user interface.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Run PHP functions from the chat ===&lt;br /&gt;
&lt;br /&gt;
On BGA Studio, you can directly run a PHP method from the table chat.&lt;br /&gt;
&lt;br /&gt;
For example, if on your PHP you have this method:&lt;br /&gt;
   &lt;br /&gt;
   function giveMoneyToPlayer($player_id, $amount) { ... }&lt;br /&gt;
&lt;br /&gt;
You can call this method directly from the chat like this: &lt;br /&gt;
&lt;br /&gt;
  giveMoneyToPlayer(2564,2)&lt;br /&gt;
&lt;br /&gt;
Note: this is not a real php statement, you cannot use self::, you cannot use &amp;quot;;&amp;quot; at the end and you cannot use quotes,&lt;br /&gt;
if you need to pass a string skip the quotes, like this&lt;br /&gt;
  &lt;br /&gt;
  giveToActivePlayer(money,2)&lt;br /&gt;
&lt;br /&gt;
=== Stopping Hanging Game ===&lt;br /&gt;
&lt;br /&gt;
If game is hanging and you cannot enter it to stop you can type this URL (replace 12345 with your table number),&lt;br /&gt;
which should bring you to a place where you can stop it without entering:&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;http://en.studio.boardgamearena.com/#!table?table=12345&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Desktop and Web Tools ==&lt;br /&gt;
=== Code Editors and IDEs ===&lt;br /&gt;
==== Eclipse For PHP Developers ====&lt;br /&gt;
&lt;br /&gt;
Eclipse PHP package can be starting point for development you need. You may also want to &lt;br /&gt;
install Tern JS plugins to understand dojo style JS. All desktops.&lt;br /&gt;
https://projects.eclipse.org/projects/tools.pdt&lt;br /&gt;
&lt;br /&gt;
==== Visual Studio Code ====&lt;br /&gt;
&lt;br /&gt;
Microsoft Visual Studio Code is light weight IDE/Editor. All desktops.&lt;br /&gt;
https://code.visualstudio.com&lt;br /&gt;
&lt;br /&gt;
==== Gedit (Ubuntu) ====&lt;br /&gt;
&#039;&#039;&#039;Edit TPL&#039;&#039;&#039;&lt;br /&gt;
To edit TPL with HTML code highlightings in Gedit under Ubuntu:&lt;br /&gt;
&lt;br /&gt;
find gtksourceview directory in /usr/share, depending on your version (2.0, 3.0,...).&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Here it&#039;s 3.0, then type in a terminal window:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    sudo gedit /usr/share/gtksourceview-3.0/language-specs/html.lang&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
then find &#039;globs&#039; section, and change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    &amp;lt;property name=&amp;quot;globs&amp;quot;&amp;gt;*.html;*.htm;*.tpl&amp;lt;/property&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== File Sync ===&lt;br /&gt;
&lt;br /&gt;
==== File Sync on Windows ====&lt;br /&gt;
&lt;br /&gt;
Install [http://winscp.net/ WinSCP]. Map a remote directory to a local one and enable continuous sync (one way). You need SFTP password you get when you registered dev account.&lt;br /&gt;
&lt;br /&gt;
==== File Sync on Linux ====&lt;br /&gt;
&lt;br /&gt;
* Option 1 - Nautilus (file manager)&lt;br /&gt;
You can just use Nautilus &amp;quot;connect to a server&amp;quot; function with URL sftp://1.studio.boardgamearena.com&lt;br /&gt;
Then you&#039;ll get a mounted local folder mapping your studio folder and you can use any editor you like without further need for sync. Downside - if connection goes down you cannot work on source code, no local copy.&lt;br /&gt;
&lt;br /&gt;
* Option 2 - sftp and rsync&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
BASEDIR=`dirname $0`&lt;br /&gt;
REMOTE=$BASEDIR/remote&lt;br /&gt;
LOCAL=$BASEDIR/workspace&lt;br /&gt;
GAME=mygamenamehere&lt;br /&gt;
&lt;br /&gt;
#mount remote&lt;br /&gt;
fusermount -u $REMOTE #this unmounts dir&lt;br /&gt;
echo LongDevPassword | sshfs -o password_stdin myusernamehere@1.studio.boardgamearena.com: $REMOTE&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#this starts auto-sync from local to remote mount&lt;br /&gt;
killall lsyncd&lt;br /&gt;
lsyncd -delay 1 -rsync $LOCAL/$GAME/ $REMOTE/$GAME&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This can be able run on startup, so you don&#039;t have to do anything manually. However sshfs is not very stable you&lt;br /&gt;
have to kill and restart it sometimes. And remote goes away sometimes due to connection issues with studio. &lt;br /&gt;
In this case its handy to have a local copy, which is what lsyncd for.&lt;br /&gt;
&lt;br /&gt;
You can also sync on demand (from a build script or editor command) using&lt;br /&gt;
 rsync -vlrt $LOCAL/$GAME/ $REMOTE/$GAME&lt;br /&gt;
&lt;br /&gt;
==== File Sync using VSCode ====&lt;br /&gt;
You might rely on your IDE to sync the files with the SFTP server. Each time you &amp;quot;save&amp;quot; a file with your modifications, the IDE will also submit it to the sFTP server.&lt;br /&gt;
&lt;br /&gt;
If you&#039;re using VSCode as an IDE, you might &#039;&#039;&#039;install this extension&#039;&#039;&#039; : &lt;br /&gt;
https://marketplace.visualstudio.com/items?itemName=liximomo.sftp&lt;br /&gt;
&lt;br /&gt;
- &#039;&#039;&#039;Open VSCode on an empty folder&#039;&#039;&#039; that will be the local root of your project.&lt;br /&gt;
&lt;br /&gt;
- Execute Ctrl+Shift+P on Windows/Linux or Cmd+Shift+P on Mac to open the command palette, and the type/run : &#039;&#039;&#039;&amp;quot;SFTP: config&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
- &#039;&#039;&#039;Update the json&#039;&#039;&#039; as below : &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;name&amp;quot;: &amp;quot;BGA&amp;quot;,&lt;br /&gt;
    &amp;quot;host&amp;quot;: &amp;quot;1.studio.boardgamearena.com&amp;quot;,&lt;br /&gt;
    &amp;quot;protocol&amp;quot;: &amp;quot;sftp&amp;quot;,&lt;br /&gt;
    &amp;quot;port&amp;quot;: 22,&lt;br /&gt;
    &amp;quot;username&amp;quot;: &amp;quot;replace with your SFTP username&amp;quot;,&lt;br /&gt;
    &amp;quot;password&amp;quot;: &amp;quot;replace with your SFTP password&amp;quot;,&lt;br /&gt;
    &amp;quot;remotePath&amp;quot;: &amp;quot;/replace with the name of your project/&amp;quot;,&lt;br /&gt;
    &amp;quot;uploadOnSave&amp;quot;: true,&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;
    ]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
- Execute Ctrl+Shift+P on Windows/Linux or Cmd+Shift+P on Mac to open the command palette, and the type/run : &#039;&#039;&#039;&amp;quot;SFTP: Download Project&amp;quot;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
This will download all the files locally, and each time you modify/save a file in VSCode, it will upload it to the SFTP Server.&lt;br /&gt;
&lt;br /&gt;
=== Debuggers ===&lt;br /&gt;
&lt;br /&gt;
Browser is the best tool for JS/HTML5 debugging, see [[Practical debugging]] for details.&lt;br /&gt;
&lt;br /&gt;
=== Version Control ===&lt;br /&gt;
Studio providers svn for you code on server, there are some limited abilities there to see history and restore. I recommend to keep your code in another repository. I suggest to use git with local repo, which you can sync to cloud or backup.&lt;br /&gt;
Other option is to host source code on github, if you do use this convention github.com/&amp;lt;yourname&amp;gt;/bga-&amp;lt;yourgame&amp;gt;. In such case make sure you don&#039;t post high-res publisher graphics only web resources, and post a separate license for graphics files.&lt;br /&gt;
&lt;br /&gt;
=== PHP CLI ===&lt;br /&gt;
Its handy to have php cli (command line) tools install to run php locally, so you can test some stuff without deployment cycle, or create some scripts that generate code or markup.&lt;br /&gt;
&lt;br /&gt;
=== Image Manipulation ===&lt;br /&gt;
==== ImageMagick ====&lt;br /&gt;
Handy set of image manipulation &#039;&#039;&#039;command line&#039;&#039;&#039; tools, useful to for example to stitch together bunch of images and re-size, to use as sprite (in Stock component for example). I.e. you got a graphics file from publisher where every tile is 600x600 PNG file in separate file. You want .jpg instead of .png to make it not like 20Mb, and combine all images in one column and re-size to 128x128:&lt;br /&gt;
&lt;br /&gt;
(Linux example)&lt;br /&gt;
 /usr/bin/montage  `ls Tiles*.png` -tile 1 -geometry 128x128+0+0 out/tiles128.jpg&lt;br /&gt;
&lt;br /&gt;
https://www.imagemagick.org/script/download.php&lt;br /&gt;
&lt;br /&gt;
==== Gimp ====&lt;br /&gt;
&lt;br /&gt;
GUI tool, very complex but will do ALL what you possibly need to do with game graphics&lt;br /&gt;
&lt;br /&gt;
https://www.gimp.org/&lt;br /&gt;
&lt;br /&gt;
==== Shrinking ====&lt;br /&gt;
&lt;br /&gt;
Shrink images without loss of quality https://tinypng.com/ or http://www.iloveimg.com/ &lt;br /&gt;
&lt;br /&gt;
==== PDF Scrabber ====&lt;br /&gt;
&lt;br /&gt;
PDF Scraper - extract images from PDF file (i.e. game rulebook) - http://www.extractpdf.com/&lt;br /&gt;
&lt;br /&gt;
==== Rename/Copy project ====&lt;br /&gt;
&lt;br /&gt;
There is a script available in sharedcode project to do the renaming which can be called in command line if you have php command line installed.&lt;br /&gt;
You need to have php clt (command line interface) installed, then you can download script and run it.&lt;br /&gt;
&lt;br /&gt;
https://github.com/elaskavaia/bga-sharedcode/blob/master/tools/bgaprojectrename.php&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
 php bgaprojectrename.php &amp;lt;originalProjectPath&amp;gt; &amp;lt;copyOfProjectRenamedPath&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example on how to call it in command line  if you project name is &amp;quot;heartsmyproject&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 php7.0 git/bga-sharedcode/tools/bgaprojectrename.php remote/hearts/ remote/heartsmyproject/&lt;br /&gt;
&lt;br /&gt;
==== BGA Workbench ====&lt;br /&gt;
&lt;br /&gt;
PHP library providing tools to help manage BGA Studio projects including deployment and test utilities. https://github.com/danielholmes/bga-workbench&lt;br /&gt;
&lt;br /&gt;
== Client Tips ==&lt;br /&gt;
&lt;br /&gt;
=== Speed up game re-loading by disabling Input/Output debug section ===&lt;br /&gt;
&lt;br /&gt;
Development UI have few sections for debugging only, such as &#039;Input/Output debugging section&#039;. Loading this data will significantly slow down&lt;br /&gt;
your reload. I did some profiling and my reloading (i.e. F5) took 14 seconds, 12 of which it was dealing with loading this section. &lt;br /&gt;
If you not using it you can disable it. In your JavaScript code, in the begging of &#039;setup&#039; method add this code&lt;br /&gt;
&lt;br /&gt;
         dojo.destroy(&#039;debug_output&#039;);&lt;br /&gt;
&lt;br /&gt;
That should get rid of this section and overhead associated with loading it (it may have some other side-effects, I have not explored all of them)&lt;br /&gt;
&lt;br /&gt;
=== Speed up CSS development and layout ===&lt;br /&gt;
&lt;br /&gt;
Syncing files to server and refreshing is relative fast but still can take up to 20 seconds which is annoying.&lt;br /&gt;
If you working&lt;br /&gt;
a lot on css/images/layout you can speed it up by coping html in some state of the game to your local folder.&lt;br /&gt;
I.e. in your  project folder create directory misc/ and save your html as misc/test.html and changing path to css to load from local disk (and it will load your images to from local disk as well). &lt;br /&gt;
I.e. find something like&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;http://1.studio.boardgamearena.com:8081/data/themereleases/151226-1240/games/mygame/999999-9999/mygame.css&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and replace with&lt;br /&gt;
   &amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;../mygame.css&amp;quot;/&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
You project structure will look like this&lt;br /&gt;
&lt;br /&gt;
 mygame&lt;br /&gt;
   img/ &amp;lt;-- your images&lt;br /&gt;
   mygame.css  &amp;lt;-- your original css&lt;br /&gt;
   ...&lt;br /&gt;
   misc/&lt;br /&gt;
     test.html &amp;lt;-- your test html&lt;br /&gt;
&lt;br /&gt;
It is a bit tricky to save html exact state, if you do save as it also pulls all resources sometimes.&lt;/div&gt;</summary>
		<author><name>Justinfernal</name></author>
	</entry>
</feed>