This is a documentation for Board Game Arena: play board games online !

Game database model: dbmodel.sql

From Board Game Arena
Revision as of 14:10, 17 November 2021 by Bouletta (talk | contribs)
Jump to navigation Jump to search


Game File Reference



Useful Components

Official

  • Deck: a PHP component to manage cards (deck, hands, picking cards, moving cards, shuffle deck, ...).
  • Draggable: a JS component to manage drag'n'drop actions.
  • Counter: a JS component to manage a counter that can increase/decrease (ex: player's score).
  • ExpandableSection: a JS component to manage a rectangular block of HTML than can be displayed/hidden.
  • Scrollmap: a JS component to manage a scrollable game area (useful when the game area can be infinite. Examples: Saboteur or Takenoko games).
  • Stock: a JS component to manage and display a set of game elements displayed at a position.
  • Zone: a JS component to manage a zone of the board where several game elements can come and leave, but should be well displayed together (See for example: token's places at Can't Stop).

Undocumented component (if somebody knows please help with docs)

  • Wrapper: a JS component to wrap a <div> element around its child, even if these elements are absolute positioned.

Unofficial



Game Development Process



Guides for Common Topics



Miscellaneous Resources

In this file you specify the database schema of your game.

This file contains SQL queries that will be executed during the creation of your game table.

Note: you can't change the database schema during the game.

Create your schema

To build this file, we recommend you to build the tables you need with the PhpMyAdmin tool (see BGA user guide), and then to export them and to copy/paste the content inside this file.

Note: you must not use for a column the same name as for the table, as the framework replay function relies on regexp substitution to save/restore a previous state in a clone table with another name.

Example: Deck component, see Deck

CREATE TABLE IF NOT EXISTS `card` (
  `card_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `card_type` varchar(16) NOT NULL,
  `card_type_arg` int(11) NOT NULL,
  `card_location` varchar(16) NOT NULL,
  `card_location_arg` int(11) NOT NULL,
  PRIMARY KEY (`card_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

Example: Euro Game. See details on database design for euro game at BGA_Studio_Cookbook#Database_for_The_euro_game

CREATE TABLE IF NOT EXISTS `token` (
  `token_key` varchar(32) NOT NULL,
  `token_location` varchar(32) NOT NULL,
  `token_state` int(10),
  PRIMARY KEY (`token_key`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Rules you should follow:

  • Do not overcomplicate, you are dealing with games with 50-500 pieces!
    • If you have 5 tables for a card game with 30 cards - it is overkill
  • Database should only be storing dynamic data, all static data should be stored in material.php.inc
    • Example: you have cards that have power, color, special abilities. In database you only need to store card type, all the other properties should not be there. Only exception - if it changes during the game.
  • Columns should be permanent, independent of game data, i.e. location, type, position, row, etc
    • Example: do not create columns like Counry1, Country2, Country3, ...
  • Do not store translatable string in database, use integer number of "ident" to access properties
    • I.e. card type should be "22" or "bob_cat", instead of "Bob's cat"
  • Create separate module in php to handle all database queries, do a lot of type checking to prevent SQL injections

Example of method handling database query:

    // Set token state
    function setTokenState($token_key, $state) {
        self::checkState($state); // ensure state is number
        self::checkKey($token_key); // ensure key is alphanum
        $sql = "UPDATE " . $this->table;
        $sql .= " SET token_state='$state'";
        $sql .= " WHERE token_key='$token_key'"; // don't need to escape anymore since we checked key before
        self::DbQuery($sql);
        return $state;
    }

Default tables

Important: by default, BGA creates 4 tables for your game: global, stats, gamelog, and player.

You 'must not modify' the schemas of the global, stats or gamelog tables (and you must not access them directly with SQL queries in your PHP code).

The player table

You may add columns to the player table. This is very practical to add simple values associated with players.

Example:

ALTER TABLE `player` ADD `player_reserve_size` SMALLINT UNSIGNED NOT NULL DEFAULT '7';

The commonly used columns of default "player" table are:

  • player_no: the index of player in natural playing order (starting with 1)
  • player_id (int)
  • player_name: (note: it is better to access this date with getActivePlayerName() or loadPlayersBasicInfos() methods)
  • player_score: the current score of the player (displayed in the player panel). You must update this field to update player's scores.
  • player_score_aux: the secondary score, used as a tie breaker. You must update this field according to tie breaking rules of the game (see also: Manage_player_scores_and_Tie_breaker)
  • player_table_order: gives an indication of the rank of the player by order of arrival in the lobby (starting with 1). It is not the same as player_no (which is the player order within the game). player_table_order is useful for setting custom teams if desired in a game option (for instance, 1st-2nd vs 3rd-4th).
    Note: player_table_order only exists during game initialization (in the setupNewGame function). It is not added as a column in the players Db table.

CAUTION: player_table_order is not guaranteed to be equal to the rank of the player in the table. For example, in a 4-player game, if the table was full but the 3rd player leaves before the game starts, the 4th player becomes 3rd on this table but their player_table_no is still equal to 4! If another player then joins, their player_table_no will then be 5...
Thus, it is essential to normalize these values first in the game setup if you wish to use them to prevent bugs at game launch. For example, if the set of player_table_order are <player A>: 3, <player B>: 2, <player C>: 5, <player D>: 7, you see that you can't read that values as ranks directly, but you can still deduce that <player B> was 1st on the table, then <player A> then <player C> then <player D> 😉

See Assigning Player Order in the BGA Studio Cookbook for an example.

CREATE TABLES

you can create tables, using engine InnoDB

CREATE TABLE IF NOT EXISTS `hands` 
(
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, 
`player_id` TINYINT(1) NOT NULL,
`1` BOOL NOT NULL DEFAULT 1,	
`2` BOOL NOT NULL DEFAULT 1,	
`3` BOOL NOT NULL DEFAULT 1,	
`4` BOOL NOT NULL DEFAULT 1,	
`5` BOOL NOT NULL DEFAULT 1,		
`6` BOOL NOT NULL DEFAULT 1,	
`7` BOOL NOT NULL DEFAULT 1,	
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

Note: if you put comments, you cannot do it in the same line as code.

Example:

`3` BOOL NOT NULL DEFAULT 1, --  activated or not

will also comment out `3` BOOL, and that code will not be executed.

PHP

Database initialization should be in function setupNewGame() in 'gamename.game.php'.

Database schema migration should be in function upgradeTableDb(), see below.

Warning: all CREATE/ALTER tables and view should be in dbmodel.sql. Do not call this queries from php to avoid implicit commits https://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html which will cause issues. Only time you can do such queries from php is in upgradeTableDb method


Errors Log

To trace Database creation check the logs that you can access in /admin/studio.

Post-release database modification

If you want to modify your database schema after the first release of your game in production, you should implement upgradeTableDb method, see Updating the database schema after release