Generic Collectible Card Game

© 2001,2002,2003 Tommi Ronkainen

Contents

1. Introduction
1.1. What is it?
1.2. Architecture
2. Client
2.1. Keyboard and mouse
2.2. Extensions for Mtg
2.3. Extensions for Pokemon
2.4. Extensions for Metw
2.5. Client command reference
3. Server
3.1. Rules definition file
3.2. Setting up a game server(s)
3.2.1. Setting up an additional table(s)
3.2.2. Creating a table with own rules
3.3. Setting up the whole system manually
3.3.1. Fine tuning
3.4. Tools for server adminstration
3.5. Adminstrator’s tasks
3.5.1. Roles
4. Internals
4.1. Dependent and independent parts
4.2. Boot sequence
4.2.1. Client boot sequence
4.2.2. Server boot sequence
4.3. Text formatting
4.3.1. General tags
4.3.2. Mtg specific tags
4.3.3. Metw specific tags
4.3.4. Pokemon specific tags
5. Scripting language
5.1. Syntax
5.1.1. Atomic data types
5.1.2. Expressions
5.1.3. Control flow
5.1.4. Defining own functions
5.1.5. Local variables
5.2. Function reference
5.2.1. Common client and server functions
5.2.2. Core functions (C++)
5.2.3. GUI library (C++)
5.2.4. Game data library (C++)
5.2.5. General client functions
5.2.6. General factory server functions
5.2.7. General game server functions
5.2.8. General meta server functions
5.2.9. General server functions (C++)
5.2.10. Lotr specific client functions
5.2.11. Lotr specific factory server functions
5.2.12. Lotr specific game server functions
5.2.13. Metw specific client functions
5.2.14. Metw specific common client and server functions
5.2.15. Metw specific factory server functions
5.2.16. Metw specific game server functions
5.2.17. Metw specific meta server functions
5.2.18. Mtg specific client functions
5.2.19. Mtg specific common client and server functions
5.2.20. Mtg specific factory server functions
5.2.21. Mtg specific game server functions
5.2.22. Mtg specific meta server functions
5.2.23. Net library (C++)
5.2.24. Pokemon specific client functions
5.2.25. Pokemon specific factory server functions
5.2.26. Pokemon specific game server functions
6. Implementing games using Gccg
6.1. Planning and preparations
6.2. Beginning of the hard work is easy
6.3. Basics of XML files
6.4. First Gccg-script
6.5. Creating set definition files
6.6. Setting up factory server
6.7. Setting up meta server
6.8. Details of game defining XML
6.9. Card placement algorithm

1. Introduction

1.1. What is it?

Generic Collectible Card Game is a multi-player multi-platform implementation of a card game engine. The card game engine is designed to be of general purpose core for several modules each defining the game specific behavior. Players download a client for their platform and all modules of interest. After launching the client for one of the games, it connects to the central server of the game chosen. When connected, all aspects of the collecting, trading and playing are available to the player.

1.2. Architecture

Fig.1: Architecure of the server system
Picture of architecture

The server system is a cluster of servers possibly distributed to several hosts. The center of the gaming system is the meta server, which is the place where clients connect to in first place. The meta server acts as a chat room and is also responsible for keeping track of players’ collections as well as all card and money transactions. The meta server is supported by one or more other servers.

Only obligatory additional server is the factory server, which serves as booster generator for meta server. The reasoning behind this server split is that the meta server does not have any knowledge of cards. It just uses simple integers to denote cards and product codes to denote different boosters and starters available. When the meta server sends amount of product and it’s product code, the factory server then generates list of (not necessarily) random integers presenting the product matching the product code. The generation process simulates actual rarity distribution of the product ordered.

When a single game server is launched, it connects to the meta server specified by it’s configuration. When a connection is established, the new server process appears as a table in the chat room. Players can see the operating parameters (such as bet and number of players required) of the game server on their screens. After initialization, the game server sleeps until the meta server awakes it by sending a message to initiate a game. After specified number of players are connected, the game begins and the game server process the whole game until the result of the game is declared. The declared game result is then sent to the meta server and the game server quits. Usually game servers are configured to start over again.

2. Client

2.1. Keyboard and mouse

Tbl.1: Keyboard shortcuts
Key comboActionMode
Alt+EnterToggle between fullscreen and windowed mode-
Ctrl+EnterEvaluate Gccg-script expression-
ShiftZoom card image-
[Collect stuff from menus and add here]
Tbl.2: Mouse gestures
Mouse actionTargetEventMode
Alt + Left clickAnySame as middle click-
Ctrl + Alt + Left clickAnySame as ctrl + middle click-
Ctrl + Left clickCard in playDetach a card if attachedPlay
Ctrl + Left dragCard in playAttach a card to anotherPlay
Ctrl + Middle clickAnyAdd name of the target to chat line-
Mouse wheelCurrent deck listingScroll up/down-
Mouse wheelMy collectionNext/previous page-
Mouse wheelNone aboveScroll messages up/down-
[Collect stuff from menus and add here]

2.2. Extensions for Mtg

Tbl.3: Keyboard shortcuts for Mtg
Key comboActionMode
Shift + Control + BProduce black mana symbol-
Shift + Control + CProduce colorless mana symbol (1)-
Shift + Control + GProduce green mana symbol-
Shift + Control + RProduce red mana symbol-
Shift + Control + UProduce blue mana symbol-
Shift + Control + WProduce white mana symbol-
(1) Repeat to produce symbols for 2 colorless mana, etc...

2.3. Extensions for Pokemon

Tbl.4: Keyboard shortcuts for Pokemon
Key comboActionMode
Control + 0Use pokemon powerplay
Control + 1Use first attackplay
Control + 2Use second attackplay
Control + 3Use third attackplay
Control + 4Use fourth attackplay
Control + 5Use fifth attackplay
Shift + Control + CProduce colorless energy symbol-
Shift + Control + FProduce fighting energy symbol-
Shift + Control + GProduce grass energy symbol-
Shift + Control + LProduce lightning energy symbol-
Shift + Control + PProduce psychic energy symbol-
Shift + Control + RProduce fire energy symbol-
Shift + Control + WProduce water energy symbol-

2.4. Extensions for Metw

Tbl.5: Keyboard shortcuts for Metw
Key comboActionMode
Ctrl + 1Announce Organization phase (1)-
Ctrl + 2Announce Long-event phase (1)-
Ctrl + 3Announce Movement phase (1)-
Ctrl + 4Announce Site phase (1)-
Ctrl + MToggle map on/off-
Ctrl + +Increment score of a card by oneplay
Ctrl + -Decrement score of a card by oneplay
EnterEnter to siteplay
Shift + Control + BProduce Border-land symbol-
Shift + Control + CProduce Coastal Seas symbol-
Shift + Control + DProduce Dark-domain symbol-
Shift + Control + FProduce Free-domain symbol-
Shift + Control + SProduce Shadow-land symbol-
Shift + Control + WProduce Wilderness symbol-
Shift + Alt + BProduce Border-hold symbol-
Shift + Alt + DProduce Dark-hold symbol-
Shift + Alt + FProduce Free-hold symbol-
Shift + Alt + HProduce Haven symbol-
Shift + Alt + RProduce Ruins & Lairs symbol-
Shift + Alt + SProduce Shadow-hold symbol-
(1) Key binding instead of function.

Tbl.6: Mouse gestures for Metw
Mouse actionTargetEvent
Middle clickA card in handPlay the card face down

2.5. Client command reference

/addproduct n id t prc
Mode: Chat mode
Restrictions: God and Salesman only
This command adds one product for sale. The ordering code of the product is 'id t', where id is the abbreviation of the card set and t is the type of the product ('booster', 'starter', etc.). The ordering code is a string which describes the product for the factory server. Number of the sale items available is n and the price of them is prc apiece.

/away text
Mode: Chat mode
Marks you as away from the keyboard with the given text as an explantion. Without any arguments, removes away status.

/ban player
Mode: Chat mode
Restrictions: God and Guard only
Without any arguments, this command lists all banned users. Adding one or more player nicks as arguments, this commands adds them to the ban list. When a player is banned, he cannot login in to the game anymore. Additionally, if the banned player is online when this command is issued, he is kicked automatically from the server. See also /help restrict and /help unban.

/bans
Mode: Chat mode
This command lists all banned users and restricted domains.

/bid bid
Mode: Play mode
Simple auction system works as follows: each player places their bids using this command. The bid can be any text. When each player has placed their bids, the auction results are displayed and book-keeping for bidding is reseted to be ready for next bidding.

/bind text
Mode: Any mode
Without any arguments, show a listing of all bindings. Otherwise, wait for a key press. After that, bind the given text to the key pressed. When the key with a binding is pressed, current input line is stored temporarily, the bound text is then put to the input line and return-key is pressed automatically. After that the content of the old input line is restored. See also /help bindk and /help unbind.

/bindk text
Mode: Any mode
Without any arguments, show a listing of all key stroke bindings. Otherwise, wait for a key press. After that, bind the given text to the key pressed. When the key with a binding is pressed, the bound text is appended to the input line as single key press. See also /help bind and /help unbind.

/buy n product
Mode: Chat mode
This command buys one or more products, which can be listed using /products command. An optional argument n determines the number of products to buy. Default is one. A product can be given as an abbreviation instead of the full set name. The set name may be followed by an optional product type specifier, which defaults to 'booster' if not given. The product names are also case insensitive.

/copydeck name
Mode: Chat mode
Make an exact copy of the current deck if selected and name it to name. Selects the copy as the current deck. If there are no deck selected, this command does nothing.

/default r p
Mode: Chat mode
When selling a card first time without any competing offer, the price of the card is set to the default value. Each rarity has it's own default price, which is set when you sell the first card having the rarity in question. At that time you set the initial default value using number pad and enter. After that you can set the price p as default for rarity r using this command. Without arguments, this command lists current default prices by rarity.

/delgame
Mode: Play mode
Remove a saved game for the current group of players. This command should be applied to save disk space on a server, when the saved game is not needed anymore.

/delproduct id t
Mode: Chat mode
Restrictions: God and Salesman only
This command removes one product. The ordering code id t is the same as in /addproduct.

/display name
Mode: Any mode
When you have filtered and sorted your own custom display, you can save it for later use with this command. The name of the custom display appears at the end of the display selection list. If you want to destroy this display later, you can choose \"Destroy this display\" from the collection menu while the display is selected. See also /help select and /help sort.

/draw options
Mode: Play mode
Declare the result of the game to be a draw. If someone has already declared the result, new declaration overrides it. Optional arguments options are game specific.

/eval exp
Mode: Any mode
This command takes an expression exp and evaluates it using gccg-script engine. The resulting value of the expression is stored to the variable E. Expression can contain more than one statements separated by semicolon. The last semicolon should be omitted.

/faq entry
Mode: Chat mode
This command displays an entry using {cyan}cyan text and adds a line to the FAQ proposals. All proposals are examined manually and added to the FAQ if they are useful. Please add questions starting with Q: and answers starting with A:. Without arguments, show current proposals for the FAQ.

/find card_name
Mode: Any mode
Find a card having a name card_name. If exact name was not found, then search for cards with the name containing a text card_name. If found either way, show the collection if not already visible. Then turn to page containing the card found. If already in such page, search for the next page containing the card qualifying the search criteria.

/give player amount
Mode: Chat mode
Give an amount of money to the other player. The other player must be online and the amount must be greater than zero.

/giveticket u n s p
Mode: Chat mode
Restrictions: God, Salesman and Judge only
Give n free product tickects, each allowing to buy one product p of the set s without charge, to the player u.

/go table
Mode: Chat mode
This command allows you to sit down to the table given as a table number. You can check available tables using /tables command.

/grant player1 player2
Mode: Chat mode
If the player2 is online, copy the password of player1 to the player2. Every player can grant his or her password to anybody, but only God can grant others' passwords. After the password is copied, the player2 who received the password, can log in as player1.

/have player
Mode: Chat mode
Asks the meta server for the have list of the given player. The have list contains all cards which you have marked as wanted and which are put for sale by the player.

/help topic
Mode: Any mode
Show information about the given topic. If there are no such topic, then all card names are checked against and if a match is found, then the card data of the mathed card is shown. Without arguments, show the list of available topics.

/inplay
Mode: Play mode
List all cards on table sorted by the owner of the card.

/join
Mode: Chat mode
Toggle your play/watch status. If you are sitting on table without the ongoing game, you will join to the game. If the number of players is sufficient, the game begins. If you join to the game that has already started, you will watch the game. This command also cancels 'ready to play' status, if already joined, but the game has not yet started.

/kick player
Mode: Chat mode
Restrictions: God and Guard only
This command forces disconnection for player.

/kicktable tblnum
Mode: Chat mode
Restrictions: God and Guard only
This command forces disconnection for table tblnum.

/legal
Mode: Play mode
This command asks the game server to report more detailed information on the legality of the current play deck. The deck is checked against all game formats defined and the report of violations against each format is generated.

/loadgame
Mode: Play mode
Searches if there is a saved game for current player(s) and restores it, if found. Note that you must be playing at the same server, where you saved your game - not necessarily at the same table. The game server announces at the beginning of the game, if there is a saved game available for your play group. Restoring the saved game does not remove it from the server; see also /help delgame.

/loadimages
Mode: Any mode
Normally all card images are loaded or generated on demand. This may cause unwanted delays when turning pages of the collection. This command loads all images at once.

/me text
Mode: Any mode
Send an emote string to the server, which replies it as an action made by you.

/newdeck deckname
Mode: Chat mode
Create an empty deck with the given deckname and select it as the current deck. Opens up the deck editing list automatically. The deck is saved automatically after the editing list is closed

/ok
Mode: Play mode
Give your acceptance to the declared result. After all players have accepted the declared result, the game ends and meta server will update all game depended statistics accordingly.

/payall amount
Mode: Chat mode
Restrictions: God only
Add the given amount of money to every player.

/products
Mode: Chat mode
List the quantity and the price of each product for sale.

/quit
Mode: Any mode
If you are watching or playing, leave the game and return to the chat mode. Otherwise, save decks and other client-side data and close the server connection. After that, quit.

/rd
Mode: Chat mode
Send the content of the current deck to the meta server for registration. The meta server stores a copy of the deck. After you have registered your deck, game servers check your game decks against the registered deck. Then reports are generated wether the game deck is identical to the registered deck and/or wether the combined parts of the game deck contains the same cards as the registered one. NOTE: The game servers do not report anything if the deck is not registered. So, it is up to the player to observe that an opponent haven't change his deck during tournament event. See also /help ro.

/reboot
Mode: Chat mode
Restrictions: God only
Send Quit-message to all players and game servers. After that, reboot the meta server.

/refresh
Mode: Any mode
Ask full refresh of the collection status from server. Normally the collection state is stored on disk cache and may be not accurate if you have been offline.

/register set
Mode: Chat mode
If the player has collected all cards of the set, he or she is awarded by a bonus. The bonus is $0.1 per individual card in the set. If the player has not yet collected all cards, the number of missing cards is announced. The set must be given as an abbreviation of the card set (case insensitive). If the abbreviation is not valid, the list of valid abbreviations are shown.

/removeuser player
Mode: Chat mode
Restrictions: God only
This command deletes all data of player.

/renamedeck name
Mode: Chat mode
Give new name to the current deck if selected. If there are no deck selected, this command does nothing.

/reproduce
Mode: Chat mode
Restrictions: God and Salesman only
Check all products. If there is a sold out product, then add a shipment of product with halved availability (compared to the previous shipment) and price increased by 10%.

/restrict domain
Mode: Chat mode
Restrictions: God and Guard only
Without any arguments, this command lists all restrictions currently in effect. Domain name can be exact or it can contain * as a joker character, for example *.cheaters.com. When the restriction is added to the domain, all existing players can connect but new players are not accepted any more. They get a message explaining the situation and how to get an account by email from the server administrator. See also /help ban and /help unrestrict.

/ro
Mode: Chat mode
You can retrieve the original composiotion of the registered deck with this command. Be careful when using this command, since it overwrites your current deck with the content of the registered deck. See also /help rd.

/rtfm
Mode: Any mode
Show a link http://gccg.sf.net/faq.php for newbies. Optional arguments are added after the link in parenthesis, e.g. section number to check out.

/save
Mode: Chat mode
This command saves all client-side data to the directory ~/.gccg/Game/. It also sends an advise to the server to save all important data.

/savegame
Mode: Play mode
Saves your current game status to the disk in the game server. Each player, player pair, player triple, etc. have one personal save file, which is overwritten each time using this command. Saving the game does not end it, but you can declare undecided result and continue later using /loadgame. This command is automatically applied when one of the players' network connection dies. See also /help delgame.

/sealed args
Mode: Chat mode
The sealed deck game is based on alter egos of players. To initiate an sealed deck event, you must first transfer an amount of money to the sealed deck alter ego of your player character. This is accomplished by the command /sealed <n>, where <n> is the amount of money to start with. Tha cards and money already owned by the sealed deck alter ego, is not lost. The money is added to instead. The command also switches to the sealed deck character immediately. If you want to switch between your normal character and the sealed deck character, you can say /sealed without any arguments. To transfer all cards and money back to your main character, say /sealed end.

/select exp
Mode: Any mode
You can refine your collection view by applying subsequent selects. Each select expression checks every card from the current display and drops those cards not matching the filter expression exp. The filter expression is one of the following:
   <e1> rel <e2> - comparison where rel is =, >, <, !=, <= or >=
   <e1> op <e2> - mathematical expression where op is +, -, *, or /
   (e) - parenthesis alters precedence
   <e1> has <e2> - true if e2 is a substring of e1 (comparison case independent)
   not <e> - negate expression e
   <e1> and <e2> - true if both expressions are true
   <e1> or <e2> - true if either expressions is true
   <attr> - "

/set var value
Mode: Chat mode
Without arguments, this command lists all options currenlty set. Otherwise it can be used to fine tune operating parameters of the client or the server. All settings are offered to the server. If the server accepts the setting, i.e. the given variable var is meaningful to the server, then the server side option is set to value. In any case, client-side option is set to the value. The list of client-side options follows:
   nosound <s> - if set to 'yes', play no sound when game begins
   log <s> - if set to 'yes', print messages to stdout.
   trade_limit <n> - if you own more than n copies of the given card, consider these extra cards as tradeable (default 4)
   price 'higher'/'lower'/'same'/'default' - when selling first card or pressing enter, choose price according to this setting (default 'higher')
  The list of server-side options:
   avatar <image> - choose an image presenting you (see graphics/avatar)
   email <s> - set your email address shown by /whois command to s
   plan <s> - set additional information shown by /whois command to s
   realname <s> - set your real name shown by /whois command to s
  

/sort [n] k1 k2 ...
Mode: Any mode
Sort the current collection view according to one or more sort keys k1, k2, etc. Each key is one of the following: name of the card attribute, age as age of the set, name as name of the card, or set as name of the set card belongs. The valid card attributes are "+

/su user
Mode: Chat mode
This command closes current session and begins new one with a player account user. You must have already registered the account.

/tables
Mode: Chat mode
Show a list of game servers available. The list contains IP-addresses, ports and game parameters (number of players, bet) of each game server.

/time time message
Mode: Chat mode
Restrictions: Judge only
Adds a timer for calling time limits in a tournament. When this command is issued, the Judge yells 'time minutes until message'. Then it announces half time (if the limit is more than 19 minutes) and 5 minutes before the limit (if the limit is more than 5 minutes). Finally the end of the time limit is called.

/unban player
Mode: Chat mode
Restrictions: God and Guard only
Remove a player from the ban list. See also /help ban.

/unbind
Mode: Any mode
Waits for a key press. If the key pressed has a binding (see. /bind), remove the binding.

/undecided
Mode: Play mode
Declare that the game is not played to the final result. If someone has already declared the result, new declaration overrides it.

/unrestrict domain
Mode: Chat mode
Restrictions: God and Guard only
Remove a domain from the restriction list. See also /help restrict.

/unset var
Mode: Chat mode
This command removes the current setting of var.

/users pattern
Mode: Chat mode
Show list of all users matching wildcard pattern or all users if not given. The total number of users matching is shown instead if the list is too long.

/want player
Mode: Chat mode
Asks the meta server for the want list of the given player. The have list contains all cards which he or she have marked as wanted. The cards you have for sale or you have more than trade_limit, are shown in green.

/who
Mode: Chat mode
Show a list of all players and their ip-addresses, who are currently connected to the meta server.

/whois player
Mode: Chat mode
Ask the meta server to describe a player. The personal data (realname, email, plan) set by the player is shown as well as his/her wealth and game play history.

/win options
Mode: Play mode
Declare yourself as a winner of the game. If someone has already declared the result, new declaration overrides it. Optional arguments options are game specific.

/yell message
Mode: Chat mode
This command echoes a message to all players, even those who are currently playing.

3. Server

3.1. Rules definition file

Different game rules are specified by the rules definition file. It is a plain ASCII-file describing the rules for one or more game formats supported by the game servers. The syntax of the file is following:
Game name of the game
Info short description
Format name of the format
Rules for deck component
rules...
	
The name of the game is the abbreviation of the game, info gives a short description to display at tables, the name of the format is any text describing the game format and the deck component is the name of the part of the deck where rules applies to. The deck part ’all parts’ denotes all cards of the different deck parts joined together. After these definitions, there are one or more rules applying to the specified deck part in the given game format. Any of these two latter declarations (name of the format and deck component) can be repeated as many times as needed, i.e. it is possible to define several formats in the same file.

The deck checking works as follows. A set of rules is applied to each deck part (or to the combined set of all cards). Each limiting rule removes matching cards from the part under the examination. If there are any cards left after applying every limiting rule, the deck part is not legal. There are also check-rules that do not alter the deck part in any way, but checks some general principle. In short, the order of the rules is important.

The following rules are recognized:

Size min-max
	
Set the minimum and maximum number of cards the deck part can contain. The maximum number is optional and defaults to unlimited. This command should be the first one unless it is appropriate that certain type of cards are removed before the check.
Size n1,...,nk
	
Set the list of allowed sizes for the deck part.
Limit n
card name 1
card name 2 ...
	
The maximum number of each cards explicitly listed is set to n.
Limit any
card name 1
card name 2 ...
	
There is no limit to the number of listed cards.
General limit n
	
This is the default maximum number of each individual card.
Otherwise ok
	
This is a catch-all rule which denotes that the deck qualifies to the game format if any earlier rule was not broken. Each rule removes all cards passing the check. If there are any cards left after all rules are applied, an error occurs. It depends on the earlier rules if this catch-all rule is appropriate or not.
Set s limit n
	
Allow at most n cards from the card set s, where s is the abbreviation of the card set. Do not use rule Otherwise ok with this rule, since it won’t work.
Limit n for each card having e
	
Searches cards fulfilling the condition e given as a scripting language expression. Limit each of the cards to n. The expression may contain # to denote card number of the card.
Limit n cards having e
	
Searches cards fulfilling the condition e given as a scripting language expression. Limit the total number of the cards to n. The expression may contain # to denote card number of the card.
Check ’text’ using e
	
Evaluate an expression e and report failure for text, if the expression evaluates to false. The expression may contain # to denote a list of card numbers to check.
Ex.1: Rules defintion file for Pokemon
In this example we define Tournament rules for Pokemon. First we set the deck size to precisely 60. Then we remove all basic energy cards and all cards having at most 4 copies. If there aren’t any cards left after these removals, the deck is legal.
Game Pokemon
Format Tournament
Rules for deck

Size 60-60

Limit any

Fighting Energy
Grass Energy
Fire Energy
Lightning Energy
Water Energy
Psychic Energy

General limit 4

Otherwise ok

3.2. Setting up a game server(s)

You can launch your own game servers and add them as tables to the meta server. Usually this is needed if someone wishes to play with different set up than provided by the server owner or when there are more players than tables. For example, you can alter the number of players and amount of money to bet. You can even write your own rules definition file, then compile it to Gccg-script and play your own game format.

3.2.1. Setting up an additional table(s)

  1. Install binary package (or source and compile it) for your platform to have program called ccg_server.
  2. Then install the game module, the server module and the game specific server module
    ./gccg_package i game server game-server
  3. Launch your server for p players and connect it to the meta server meta
    ./Server --server meta --bet bet --players p game
    Without --server argument, the game server registers itself to the default meta server. Default bet is $1 and default number of players is one.
  4. Don’t forget to open appropriate incoming TCP/IP ports at your firewall if blocked by default.
If you wish set up more than one table, you need to give different port numbers for each server using argument --port num. See following table for port numbers.

Tbl.7: Port numbers
PortService
29100Meta server for Mtg
29101Factory server for Mtg
29102Meta server for Poker demo
29103Factory server for Poker demo
29104Meta server for Wind and Water
29105Factory server for Wind and Water
29110Meta server for Pokemon
29111Factory server for Pokemon
29120Meta server for Lotr
29121Factory server for Lotr
29130Meta server for Metw
29131Factory server for Metw
29200-29299Game servers for Mtg
29300-29399Game servers for Pokemon
29400-29499Game servers for Lotr
29500-29599Game servers for Metw
29600-29699Game servers for Wind and Water

3.2.2. Creating a table with own rules

Default rules for game servers includes only the most important game formats. There might be already additional rule sets depending on game, but it is also possible to define own game formats (see Section 3.1.). If you wish to create own rulesets, then you need to install a package dev-tools first.

The package contains subdirectory data/, where you can find examples of format definitions, each having .rules extension. Pick one of the examples which resembles your upcoming game format mostly and copy it to new name. Then edit it to implement your game format and convert it to Gccg-script by issuing command
make rules
The command reads all rules defintions having extension .rules found at data/ directory and converts them putting results to the directory script/.

Now rules are ready for testing (assume that our rule set is called Mtg-block.rules which comes with the dev-tools). Try one player table issuing
./Server --rules Mtg-block.rules mtg
Don’t forget to add --server argument if using other meta server than default one.

3.3. Setting up the whole system manually

First you need to install game, game-server and server packages as described in previous subsection. The following order is recommended altough the system should raise up eventually even if servers are not launched in the correct order:
  1. Lauch the factory server for your game
    ./Server factory-game
  2. Lauch the meta server for your game
    ./Server meta-game
  3. You should be now able to log in to your own meta server. Try your client
    ./Game --server your.server
  4. Launch game servers you need as described in earlier subsection. Remember to add --server argument or otherwise the game server(s) connects to the default meta server.
Servers load/save data automatically on startup/exit to the save/Game directory. You can stop servers simply pressing ctrl+c on each server process in reverse order as they are launched.

3.3.1. Fine tuning

Before you put your server system into production, you should check out the beginning of the scripts scripts/meta-server.functions and scripts/Game-meta-server.functions. Immediately after commented lines there are some variable definitions you may wish to change. Default values are defined in scripts/meta-server.functions, but if other definition is given in scripts/Game-meta-server.functions, the latter definition overrides the default. Here are some of the most important variables:
TIME_ZONE
This variable is announced to clients in certain situations where the local server-side time zone is needed.
INITIAL_MONEY
This is the minimum of the starting money given to the each new player.
AMOUNT_TO_PAY_WEEKLY
This is weekly payment. Together with the previous variable this defines the total number of money to be given to the new player. The exact formula is

INITIAL_MONEY + AMOUNT_TO_PAY_WEEKLY x p,

where p is the number of products available at the time of registration.
PRIZE_PER_PLAYER
This defines additional bonus to be given to the player winning a match. The formula for earnigs for the winning player is

(p - 1) x (b + PRIZE_PER_PLAYER) + (p x b),

where p is the number of players, b is the bet at the table used. In short, PRIZE_PER_PLAYER tells how much one player receives when playing against one opponent with $0 bet.

3.4. Tools for server adminstration

We are already familiar with one script called Server. It is a front end to the actual binary server. It chooses correct parameters to the binary in order to launch the server selected. It also passes through all extra parameters given. After launching the server, it waits until it terminates. If the server process returns error, then the script sleeps for 30 seconds and relaunches the server with the same parameters. If the server process exited without error, then relauch is made immediately.

[Descripe other scripts.]

3.5. Adminstrator’s tasks

3.5.1. Roles

When your server system is up and running, your first task is to reserve certain user accounts having special access to maintenance commands. This is accomplished by simply launching the client once for each account to reserve, i.e. ./Game --user God --server your.server. Roles to reserve are following:
God
This account have full access to everything. With this account you can give any amount of money (even negative) to anybody and the amount is not subtracted from this account. You can give cards without owning them. Any password can be granted to anybody, whereas usually players can grant only their own passwords.
Guard
This account can kick people out of the chat room.
Judge
Reserved for future.
Salesman
This account is now obsolete, but it still can do product management with /addproduct and /reproduce.
root
This has no special meaning in Gccg, but reserving the root account prevents stupid people to log in directly from root account.

4. Internals

4.1. Dependent and independent parts

[Table: script files]

4.2. Boot sequence

4.2.1. Client boot sequence

4.2.2. Server boot sequence

4.3. Text formatting

4.3.1. General tags

The text renderer of the Gccg client interpretes tags, which can be used to change font properties and add game specific symbols to the text. Each tag begins with { and ends with }. Here is a summary of general formatting tags:

Tbl.8: General formatting tags
TagInterpretation
{lb}Draw {.
{rb}Draw }.
{hr}Draw thin horizontal line.
{left}Align text left.
{center}Align text centered.
{right}Align text right.
{shadow}Turn on shadow for text.
{noshadow}Turn off shadow for text.
{szn}Set font size to n points.
{fontn}Select font number n as current font.
{reset}Reset all formatting properties to the default except shadow.
{red}Change text color to red.
{green}Change text color to green.
{black}Change text color to black.
{blue}Change text color to blue.
{yellow}Change text color to yellow.
{white}Change text color to white.
{brown}Change text color to brown.
{gold}Change text color to gold.
{gray}Change text color to gray.
{magenta}Change text color to magenta.
{orange}Change text color to orange.
{cyan}Change text color to cyan.

4.3.2. Mtg specific tags

Tbl.9: Mtg tags
TagInterpretation
{B}Black mana symbol.
{G}Green mana symbol.
{R}Red mana symbol.
{U}Blue mana symbol.
{W}White mana symbol.
{0}Zero mana symbol.
{1}One colorless mana symbol.
{2}Two colorless mana symbol.
{3}Three colorless mana symbol.
{4}Four colorless mana symbol.
{5}Five colorless mana symbol.
{6}Six colorless mana symbol.
{7}Seven colorless mana symbol.
{8}Eight colorless mana symbol.
{9}Nine colorless mana symbol.
{X}X mana symbol.
{Y}Y mana symbol.
{T}Tap symbol.

4.3.3. Metw specific tags

Tbl.10: Metw tags
{b}Border-land symbol.
{c}Coastal sea symbol.
{d}Dark-domain symbol.
{f}Free-domain symbol.
{s}Shadow-land symbol.
{w}Wilderness symbol.
{B}Border-hold symbol.
{D}Dark-hold symbol.
{F}Free-hold symbol.
{H}Haven symbol.
{R}Ruins & Lairs symbol.
{S}Shadow-hold symbol.

4.3.4. Pokemon specific tags

Tbl.11: Pokemon tags
{c}Colorless energy symbol.
{f}Fighting energy symbol.
{g}Grass energy symbol.
{l}Lightning energy symbol.
{p}Psychic energy symbol.
{r}Fire energy symbol.
{w}Water energy symbol.

5. Scripting language

5.1. Syntax

5.1.1. Atomic data types

null
Empty value which can be expressed explicitly using NULL or ().
integer
Any integer value supported by C++ compiler.
real
Any real value supported by C++ compiler.
string
A sequence of characters beginning and ending with " or . If the sequence is enclosed in ", the special sequence \n is converted to the new line and the sequence \c to the character c.
list
An ordered sequence of any other objects. The sequence begins with ( and ends with ) and elements are separated by commas. An empty list is denoted by (,) and a list with one member is denoted by (e,), where e is the member of the list.

5.1.2. Expressions

atomic
Any atomic value evaluates to itself.
variable
A legal variable name can have one or more following characters: a...z, A...Z, 0...9, _ and .. A digit cannot be the first character of the variable name and NULL is forbidden as a variable name. Variable evaluates to it’s current value if set. If not set, then it evaluates to NULL.
array
The language does not have separate array type. However, list variables can be used as arrays. If a=(a0,a1,...,an-1) is a list, we can use notation a[i] as a reference to ai. This notation can be nested like a[i][j], i.e lists of lists represents 2–dimensional array. Access time is constant. List indexing can be also used after any expression in parenthesis, e.g. (seq(1,5))[i].
dictionary
Dictionary type is also a special kind of list, which contains key–value pairs. Each member of the dictionary is a list with two members: (key,value). Dictionary must be initialized as an empty list, i.e. d=(,). After that each reference of form var{key} creates new pair (key,NULL) if necessary. If there is already correct key, then value corresponding to the key is returned. Dictionary indexing can also be used after expression in parenthesis like array indexing.
negation
Value of an expression -e is a negation of e if e is a number. Otherwise Parser::LangErr is thrown.
addition
Value of an expression e1+e2 is a concatenation of lists if both e1 and e2 are lists. If both are numbers, then value is the sum of those numbers. If one is an integer and other is a real, then answer is given as a real number. If one of the arguments is a string, then result is concatenation of the string and the other expression converted to string.
subtraction
An expression e1-e2 is a short hand notation for e1+(-e2) except for lists. If both arguments are list, the result is a list containing all members of e1 which do not belong to e2.
multiplication
An expression e1*e2 evaluates to e1 x e2 if both are numbers. If one is a number n and other is a string or a list, then the string or list is catenated with itself n times. If both operands are lists with the same size, then return value is a list containing pairwise multiplied elements of e1 and e2. Otherwise Parser::LangErr is thrown.
division
An expression e1 / e2 evaluates to the integer part of e1/e2 if both are integers. If either or both are real, the result of operation is e1/e2. Otherwise Parser::LangErr is thrown.
modulo
An expression e1 % e2 evaluates to remainder of division e1/e2 if both are integers. If either one is NULL, return NULL. Otherwise Parser::LangErr is thrown.
function call
Function call f(e) calls an user defined function if available. Otherwise an internal function is called. Function call evaluates to the value returned by the function.
substitution
Values can be assigned to variables with expression v=e, where v is a valid variable name. The substitution evaluates to e.
relation
Two expression can be compared with traditional operators ==, !=, <, >, <= and >=. Each of these operators returns 1, if relation is true and 0 otherwise. Relation is valid ordering and can be used with any type. When both operands are NULL, equality operator returns 1. If one of the operands is NULL and the other is not, equality operator returns 0. List operands are considered equal if they have same length and they have same members in same order. Operator != is a short hand notation for not e1 == e2.
logical
Operators &&, ! and || can be used. The !–operator returns 1 except when argument is non–zero integer or non–zero real. Other operators returns NULL if any argument is NULL. If both arguments are integers, then logical value 1 or 0 is returned. In any other case Parser::LangErr is thrown.

5.1.3. Control flow

Each code line is ended by ; and lines of the script beginning with # are comments. The scripting language supports standard if- and while-statements. Additionally, a for loop is supported as for (v) (L) {loop body}, where v is a loop variable which gets assigned all values of the list L. All loop variables are local to the loop body and stored to the stack. If the loop body alters stack content incorrectly (i.e. pushed values are not popped), then loop variables probably gets different values after the loop. As a special form of the for loop is for (v) (n) {loop body}, where n is an integer expression. In this case, the loop variable v runs through values 0,1,...,n-1.
Ex.2: Control flow
Following code
for(i)(10)
{
  if(i % 2==0)
  {
    j=i;
    while(j)
      print(j=j-1);
    println("");
  }
}
	  
produces
10
3210
543210
76543210
	  

5.1.4. Defining own functions

You can define own function as follows:

Ex.3: Defining functions
Let us define
def increment
{
  return(ARG+1);
}
	  
The statement return(ARG+1) sets the return value of the function which defaults to NULL. Pseudo variable ARG contains arguments of the function call. The function above increments given argument by one if possible. Otherwise it produces exception, if argument is incompatible with addition operation. For example, the expression increment(1.2) gives a result 2.2.

NOTE 1: The return-statement do not terminate the execution of the function. You can set the return value more than once and the last call to return takes precedence.

NOTE 2: The function can be defined more than once. New definition overwrites older definition.

NOTE 3: Function definitions can be introduced anywhere in the code, even inside loops or if-else constructions.

5.1.5. Local variables

There are no local variables. However, it is possible to simulate local variables using stack:
Ex.4: Local variables
Let us define
#
# foo(n,e) - evaluates n times expression e
#
def foo
{
  push(a);
  a=seq(1,ARG[0]);
  forall(ARG[1],a);
  a=pop();
}
	  
This function evaluates the argument ten times. (Actually it is unnecessary to store sequence 1,...,10 temporarily, but this is just an example.)

5.2. Function reference

All functions are documented here.

5.2.1. Common client and server functions

abs
MyPath
RulePass
age
round
RuleViolation
book_set_slot
RuleCanonicalCardLimitSingle
SavePath
CountCards
RuleCardLimitAny
sort_fn
DataPath
RuleCardLimitGeneral
strreplace
del
RuleCardLimitSingle
sum
dist
RuleCardSet
tofilename
GeneratePassword
RuleCardSetReprint
tofnc
isreal
RuleCheckExpression
tr
LegalityCheckDeck
RuleDeckMaximum
ValidCardNumber
LegalityCheckRule
RuleDeckMinimum
ValidMode
LegalityCheckRules
RuleDeckSizes
ValidUsername
LegalityCheckRuleset
RuleLimitByExpression
VersionCompare
listjoin
RuleLimitEachByExpression
wr

5.2.2. Core functions (C++)

apply
joker_match
set_lang
array
keys
shuffle
attach
L
sleep
cache_parameters
languages
sort
call
last
sort_fn
copy
lc
split
count
left
stacktrace
current_time
length
strreplace
date
load
substr
delsaved
max
tail
del_entry
min
time
diff_time
pop
toint
execute
print
toreal
find
println
tostr
first
push
toval
flatten
quit
tr
forall
random
trim
format
randomize
typeof
fuzzy
read_file
uc
get_lang
repeat
ucfirst
has_entry
replace
unique
head
return
valueof
index
reverse
values
isdict
right
vardump
isfunction
save
write_file
isvar
select
 
join
seq
 

5.2.3. GUI library (C++)

add_marker
del_marker
put_deck_top
add_text
del_object
put_hand
attach
del_text
put_inplay
beep
detach
raise
book_cards
dump
redraw
book_entry
get_attr
refresh
book_last_page
get_texts
replace_cardbox_recenter
book_page
h
rot
book_pageof
hand
scale_image
book_set_deck
has_text
screen2table
book_set_entry
image_height
set_attr
book_set_index
image_pixel
set_bgcolor
book_set_page
image_width
set_cardsize
book_set_slot
inplay
set_fgcolor
book_titles
InputSplit
set_name
card
intersect
set_textalign
cardbox
invert
set_textcolor
card_data
listbox_clear
set_textfont
center_of
listbox_entry
set_textmargin
change_card
listbox_scroll
set_textsize
create_book
listbox_set_deck
set_textvalign
create_cardbox
listbox_set_entry
set_title
create_deck
listbox_sort_rows
table2screen
create_hand
load_image
tap
create_image
lower
tapped
create_listbox
message
tapped_left
create_menu
mouse
tap_left
create_msgbox
move_object
text_height
deck
msgbox_scroll
text_width
del_all_texts
objects
title
del_cardbox
object_data
trigger
del_cardbox_all_recenter
object_name
untap
del_cardbox_recenter
object_type
untapped
del_deck
put_cardbox
w
del_deck_top
put_cardbox_recenter
 
del_hand
put_deck_bottom
 

5.2.4. Game data library (C++)

age
fuzzy_images
rules
Attr
game_data
scripts
attributes
game_option
sets
attrs
having_rarity
set_data
canonical_name
images
set_of
cards
inline_images
sort_by
card_attr
load_deck
text
card_back
name
 
decks
rarities
 

5.2.5. General client functions

ActiveSetMenu
ImportAdd
PlayCommandOk
AddCard
ImportASCIIDeck
PlayCommandUndecided
AddCards
ImportDeck
PlayCommandWin
AddHistory
ImportDeckFormat
PlayerName
AddMarker
ImportDeckMenu
PlayKeyControlKeyA
AddMinuteTimer
ImportDeckMenuEntry
PlayKeyControlKeyD
AddRoomPlayer
ImportErrorAdd
PlayKeyControlKeyDelete
AddRoomTable
ImportGccgDeck
PlayKeyControlKeyE
AddTimer
ImportReaderLineByLine
PlayKeyControlKeyF
AddToDeck
Initialize
PlayKeyControlKeyHome
Alert
InitializeConnection
PlayKeyControlKeyL
AlertOff
InitializeInputSystem
PlayKeyControlKeyP
ApplyImportDeck
InitializePanelSystem
PlayKeyControlKeyS
ApplyImportDeckBack
InitializeScoreSystem
PlayKeyControlKeyT
ASCIIFormatParser
Input
PlayKeyControlKeyU
ASCIIFormatSuffix
InputKeyBackspace
PlayKeyDelete
Attach
InputKeyDelete
PlayKeyEnd
Attachments
InputKeyEnd
PlayKeyHome
AvatarFloorPos
InputKeyHome
PlayKeyInsert
AvatarRecalcTable
InputKeyLeft
Positions
Bid
InputKeyRight
PressKey
BookChangeForsale
InputNewline
PriceDelta
BookFullRefresh
InputSplit
ProductLookup
BookGoBack
InverseSelectByAttr
PutActive
BookSetPrice
IsAway
PutCardInGroup
Buy
IsStayTapped
PutDeck
CardMenu
IsUserDisplay
PutDeckBottom
CardSelectBoxMenu
IsVeryNear
PutHand
Category
IsVolatile
PutTable
CategoryMatch
is_object
Quit
ChatCommandAway
JoinTable
Raise
ChatCommandBuy
JudgeChatCommandTime
RandomNearPoint
ChatCommandCopydeck
KeyAltKey1
Receive
ChatCommandDefault
KeyAltKey2
RecognizeCard
ChatCommandGive
KeyAltKey3
RecognizeDeckFormat
ChatCommandGo
KeyAltKey4
RefineFilter
ChatCommandJoin
KeyAltKey5
RefreshBook
ChatCommandNewdeck
KeyAltKey6
RefreshBookForDeck
ChatCommandRd
KeyBackspace
RefreshCurrentDeck
ChatCommandRenamedeck
KeyControlKeyB
RegisterSubmenu
ChatCommandSave
KeyControlKeyC
RemoveAvatar
ChatCommandSealed
KeyControlKeyH
ReplaceTable
ChatCommandSu
KeyControlKeyP
RestoreDeck
ChatKeyControlKeyD
KeyControlKeyPageDown
RestoreMenuContext
ChatKeyControlKeyE
KeyControlKeyPageUp
root_object
ChatKeyControlKeyI
KeyControlKeyR
Rotate
ChatKeyControlKeyS
KeyControlKeyReturn
RuleOptions
ChatKeyControlKeyW
KeyDelete
SaveAll
ChatKeyControlKeyX
KeyDown
SaveBookState
CheckFilterVersion
KeyEnd
SaveMenuContext
CheckForCard
KeyEnter
Say
CheckFunctionsOrQuit
KeyEscape
Score
CheckInitialVariables
KeyF10
ScoreToText
CheckInitialVariablesOrQuit
KeyF11
ScrollHistory
CheckLegalitySubmenu
KeyF12
SearchDeck
ChooseDeckMenu
KeyF1
SectionSubmenu
ClearCardBook
KeyHome
SelectByAttr
ClearEmptyGroups
KeyLeft
SelectCard
ClearGame
KeyModifierDown
SelectDeck
ClearScores
KeyModifierUp
SelectDeckPart
ClearSearchbox
KeyPageDown
SelectMenuChooseADeck
CommandBind
KeyPageUp
Send
CommandBindk
KeyReturn
SendMeta
CommandDisplay
KeyRight
SetActive
CommandEval
KeyTab
SetAvatar
CommandFind
KeyUp
SetAwayOff
CommandHelp
LeaveChatMode
SetAwayOn
CommandLoadimages
LeavePlayMode
SetBookIndex
CommandLog
LeaveTable
SetBookPage
CommandMe
LeaveWatchMode
SetCardbook
CommandNewuser
LineSplitFirstSpace
SetDeck
CommandQuit
LoadAllRules
SetHand
CommandRefresh
LoadAllScripts
SetHandSize
CommandSelect
LoadAvatar
SetJoinGame
CommandSet
LoadBookState
SetMe
CommandSort
LoadMenu
SetMode
CommandTables
LocationList
SetMoney
CommandUnbind
Lower
SetMyName
CommandUnset
LowerAttachments
SetOption
CommandWho
MainLoop
SetPassword
ConnectServer
MakeLegalityCheck
SetPrice
ConstructMenu
ManualTarget
SetProducts
CoordinateMapping
Menu
SetScore
CountCanonicalNamePairs
MenuByContext
SetStayTapped
CounterSubmenu
MenuClick
ShowHelp
CountNamePairs
MergeDeck
ShowPanel
CreateActive
MergeDeckSubmenu
ShowPlaymat
CreateAvatar
Message
ShowScreen
CreateDeck
Mode
SingleCardMenu
CreateFilter
MouseControlLeftClick
SlashCommand
CreateHand
MouseControlLeftDragBegin
SlashComments
CreateIndex
MouseControlLeftDragEnd
Special
CreatePanel
MouseControlMiddleClick
SplitToWords
CreatePlayerIcon
MouseLeftClick
StacksByGroup
CreateScreen
MouseLeftClickActiveSet
StartChatMode
CurrentDeckMenu
MouseLeftClickCard
StartPlayMode
CurrentFilter
MouseLeftClickCardSelectBox
StartWatchMode
CurrentSorting
MouseLeftClickCurrentDeck
str2filter_atom
DeckMenu
MouseLeftClickDeck
str2filter_exp
DeckName
MouseLeftClickDeckSearchBox
str2filter_join
DeckSearchBoxMenu
MouseLeftClickHand
str2filter_rel
Default
MouseLeftClickMyCollection
str2filter_split
DefaultInitialPrice
MouseLeftClickOpenBooster
str2filter_sum
DelActive
MouseLeftClickOpponentHand
str2filter_term
DelCardInGroup
MouseLeftClickTable
str2filter_typeconvert
DelCursor
MouseLeftDragBegin
str2filter_typetoint
DelDeck
MouseLeftDragEnd
str2filter_typetostring
DelDeckTop
MouseMiddleClick
str2sorting
DeleteDeck
MouseMiddleClickCard
String2Filter
DelHand
MouseMiddleClickCurrentDeck
String2Sorting
DelMarker
MouseMiddleClickDeckSearchBox
Submenu
DelMenu
MouseMiddleClickMyCollection
subobjects
DelRoomPlayer
MouseMiddleClickOpenBooster
Table
DelRoomTable
MouseMiddleClickTable
TableCoord
DelTable
MouseMiddleDragBegin
TableMenu
DestroyUserDisplay
MouseMiddleDragEnd
TableNumber
Detach
MouseMoveObject
TableObject
DiscardPileMenu
MouseWheel
TargetCard
DisplaySubmenu
MouseWheelChatMsg
TargetingOptions
EditAdd
MouseWheelCurrentDeck
Timer15Seconds
EditCardname
MouseWheelMenu
Timer5Seconds
EditCardNumber
MouseWheelMyCollection
Timer
EditCountCards
MoveAvatar
TimerMinute
EditCreateDeck
MoveObject
TogglePanel
EditDel
MovePanel
TrimSpaces
EditNearestPartname
Msg
TryTransferTo
EditPartname
MsgChat
UnsetStayTapped
ExportASCIIDeck
MyCollectionMenu
UpdatePanel
ExportCards
MyDeck
UpdateProductsPanel
ExportDeckMenu
NextFreeAttachPos
WantList
ExportGccgDeck
NextTarget
WatchActiveSetMenu
ExportToFile
None
WatchCardMenu
FindCardGroupIndices
Null
WatchCommandInplay
FindCards
ObjectAt
WatchCommandNewdeck
FindOtherCard
ObjH
WatchCommandRd
FindSpace
ObjW
WatchDeckMenu
Flash
OpenBoosterMenu
WatchDeckSearchBoxMenu
FreeTablePos
OpponentActiveSetMenu
WatchDiscardPileMenu
GameSetup
OpponentDeckMenu
WatchHandMenu
GccgFormatParser
OpponentDiscardPileMenu
WatchKeyControlKeyD
GccgFormatSuffix
OpponentHandMenu
WatchKeyControlKeyE
GetByPrimaryCategory
OtherDeckFormats
WatchKeyControlKeyI
GetGroups
Owner
WatchKeyControlKeyS
GiveCardSubmenu
PanelVisible
WatchKeyControlKeyW
GroupNumbers
ParentObject
WatchKeyControlKeyX
HandlePriceInput
Play
WatchOpponentDeckMenu
HandMenu
PlayCard
WatchOpponentDiscardPileMenu
HashComments
PlayCommandDraw
WatchOpponentHandMenu
HaveList
PlayCommandInplay
_EndGame
HidePanel
PlayCommandLegal
_InitializeGame
HidePlaymat
PlayCommandLose
_StartGame

5.2.6. General factory server functions

CardsOfSetWithRarity
InitTables
RandomCardSet
FixedSet
Log
 
Initialize
Produce
 

5.2.7. General game server functions

AcceptableResult
IsObject
RegisterPlayer
AcceptResult
LegalityCheck
Reply
Action
Log
ResultAccepted
AddMarker
Lower
Reveal
AllDecksLoaded
MakeLegalityCheck
Roll
AssignPlayer
MapCon2Plr
RootObject
Attach
MoveObject
Rotate
AvatarPos
MsgCards
SaveFilename
Command
MsgOrdinal
Say
CommandBid
MsgTransfer
Score
CommandDelgame
MsgVerbObject
SearchDeck
CommandLoadgame
MsgVerbObjectObject
Send
CommandReload
Null
SendAll
CommandRtfm
Number
SendFullGameStatus
CommandSavegame
ObjectName
SendOther
Con2Plr
OriToPlr
ShuffleDeck
CoordToPlr
OriToSvr
Special
CoordToSvr
Owner
StartGame
CreateDeck
Play.Card.Stage1
SubjectName
CreatePlayerObjects
Play.Card.Stage2
Take.Active
DeckName
PlayerNumber
Take.Deck
DeclareResult
PlayerOrder
Take.DeckTop
DelMarker
Plr2Con
Take.Hand
Detach
Put.Active
Take.OutOfPlay
EndGame
Put.DeckBottom
Take.SearchDeck
Flip
Put.DeckTop
Take.Table
Group
Put.Hand
TargetName
HandleMetaServer
Put.OutOfPlay
Touch
HandPos
Put.Table
Transfer
Image
Raise
UploadDeck
InitializeWatcher
ReceiveClose
Verb
InitServer
ReceiveData
WaitMetaEvents
IsLoop
ReceiveOpen
WatcherSay

5.2.8. General meta server functions

Action
CommandSave
RegisterGameResult
AddCard
CommandUnban
RegisterPlayer
AddCards
CommandUnrestrict
RegisterServer
AddGameResult
CommandUsers
RemoveObsoletePrices
AddTickets
CommandWant
Reply
AvailableForSale
CommandWhois
ReRegisterPlayer
AvailableForTrade
CommandYell
Roll
Buy
Con
SaveAll
BuyCard
DeckCheck
Say
CheckPrice
DelCard
Sealed
CheckSealedCharacter
DelCards
SealedEnd
Command
DisconnectPlayer
SealedOff
CommandAddproduct
DisconnectServer
SealedOn
CommandBan
EndGame
SealedStart
CommandBans
EnsurePriceUpdate
Send
CommandDebug
Give
SendAll
CommandDelproduct
GiveCard
SendAllNP
CommandFaq
GiveMoney
SendOther
CommandFaqclear
IsRestricted
Set
CommandGiveticket
IsServer
SetForsale
CommandGrant
IsTableBanned
SetOfCard
CommandHave
JoinTable
SetPrice
CommandKick
LeaveTable
StartGame
CommandKicktable
Log
Tickets
CommandPayall
Mode
TicketsList
CommandProducts
NewUser
TicketsOf
CommandReboot
Null
ToggleJoinGame
CommandRegister
PrizeForDraw
TransferMoney
CommandReload
PrizeForLoss
UpdateCard
CommandRemoveuser
PrizeForWin
User
CommandReproduce
ReceiveData
UserWithoutMode
CommandRestrict
Refresh
WeStartedGame
CommandRo
RefreshChatRoom
 
CommandRtfm
RegisterDeck
 

5.2.9. General server functions (C++)

add_to_collection
have_list
set_error_trigger
check_card
is_user
set_forsale
count_cards
min_price
set_price
del_prices
price_list
user_has_cards
get_card_data
remove_obsolete_prices
want_list

5.2.10. Lotr specific client functions

BidHook
MouseLeftClickTwilightPool
PlaySite
CompanySize
MouseMiddleClickTwilightPool
PlaySitesMenu
EndOfTurnHook
MyFrodo
PlayTwilightPoolMenu
InitializeGame
NewDeck
PutTableHook
InitializeLocationTables
NextSiteNumber
SearchStartingCards
InputHook
PlayEvent
StartGame
MouseLeftClickActiveSet
PlayKeyControlKeyA
TryTransferHook
MouseLeftClickSiteCard
PlayKeyControlKeyD
TwilightPool
MouseLeftClickSites
PlayKeyControlKeyDelete
TwilightTokens
MouseLeftClickSitesSearchBoxHook
PlayKeyControlKeyU
 

5.2.11. Lotr specific factory server functions

InitDistributions
   

5.2.12. Lotr specific game server functions

InitialScore
InitServerHook
SetUpPlayer

5.2.13. Metw specific client functions

AddSideboardFwCards
KeyShiftControlKeyC
PlayKeyControlKeyPlus
AdjustScore
KeyShiftControlKeyD
PlayKeyEnter
ChatMapMenu
KeyShiftControlKeyF
PlayMapMenu
CreateDeckHook
KeyShiftControlKeyS
PlayPoolMenu
CurrentDeckAddHavens
KeyShiftControlKeyW
PlaySideboardMenu
CurrentDeckAddSites
MouseControlMiddleClickMap
PlaySiteFromSelection
CurrentDeckRemoveSites
MouseLeftClickActiveSet
PlaySitesMenu
CurrentDeckRemoveUnownedSites
MouseLeftClickDiscardPile
PoolSearchBoxMenuHook
DelDeckHook
MouseLeftClickDiscardPileSearchBoxHook
PutDeckHook
DelTableHook
MouseLeftClickMap
PutTableHook
EditAddSideboard
MouseLeftClickPool
RecalculateScores
EditRemoveSideboard
MouseLeftClickPoolSearchBoxHook
ReplaceTableHook
InitializeGame
MouseLeftClickSideboard
ScoreAdjustment
InitializeLocationTables
MouseLeftClickSideboardSearchBoxHook
ScoreToText
KeyControlKeyM
MouseLeftClickSites
SideboardSearchBoxMenuHook
KeyEscapeHook
MouseLeftClickSitesSearchBoxHook
SingleCardMenuHook
KeyShiftAltKeyB
MouseMiddleClickHand
SitesOfRegion
KeyShiftAltKeyD
MouseMiddleClickMap
SortSites
KeyShiftAltKeyF
MouseMiddleClickPoolSearchBoxHook
SpecialEventAdjustScore
KeyShiftAltKeyH
MouseMiddleClickSites
StartGame
KeyShiftAltKeyR
NewDeck
TryTransferHook
KeyShiftAltKeyS
PlayFromSelectionHook
UntapHook
KeyShiftControlKeyB
PlayKeyControlKeyMinus
 

5.2.14. Metw specific common client and server functions

RuleAgentMindTotal
RuleCountCreatures
RuleSpecific
RuleBothHeroAndMinionUnique
RuleHazardResourceBalance
RuleStagepoints
RuleCheckWizards
RuleNonUniqueStageCards
 

5.2.15. Metw specific factory server functions

InitDistributions
ProduceLE_Starter
ProduceTW_Starter

5.2.16. Metw specific game server functions

InitialScore
SavegameHook
SpecialHook
InitServerHook
SendFullGameStatusHook
 
LoadgameHook
SetUpPlayer
 

5.2.17. Metw specific meta server functions

EndGameHook
SealedEndHook
SealedStartHook

5.2.18. Mtg specific client functions

AddInputHook
KeyShiftControlKeyG
PlayInterrupt
CreateDeckHook
KeyShiftControlKeyR
PlayKeyControlKeyI
EditAddSideboard
KeyShiftControlKeyT
PlaySideboardMenu
EditRemoveSideboard
KeyShiftControlKeyU
PlaySorcery
EndGame
KeyShiftControlKeyW
PutTableHook
filter_mana
KeyShiftControlKeyX
ShowGameSpecificHelp
InitializeGame
KeyShiftControlKeyY
SingleCardMenuHook
InitializeLocationTables
mana
StartGame
InputHook
MessageHook
TokenSubmenu
KeyShiftControlKey0
MouseLeftClickSideboard
UntapHook
KeyShiftControlKeyB
NewDeck
 
KeyShiftControlKeyC
PlayInstant
 

5.2.19. Mtg specific common client and server functions

CreateTypeLegalTable
RuleCountColors
TypeLegal
RuleCountBiggestPopulation
TribalLegal
TypeRestricted

5.2.20. Mtg specific factory server functions

InitDistributions
ProduceBE_Booster
ProduceBE_Starter

5.2.21. Mtg specific game server functions

InitialScore
SetUpPlayer
 

5.2.22. Mtg specific meta server functions

EndGameHook
SealedEndHook
SealedStartHook

5.2.23. Net library (C++)

net_client_ip
net_get
net_server_isopen
net_client_name
net_isopen
net_server_send
net_close
net_send
net_server_send_all
net_connect
net_server_close
 
net_create_server
net_server_get
 

5.2.24. Pokemon specific client functions

InitializeGame
KeyShiftControlKeyC
MouseMiddleClickCard
InitializeLocationTables
KeyShiftControlKeyF
NewDeck
KeyControlKey0
KeyShiftControlKeyG
OpponentPrizesMenu
KeyControlKey1
KeyShiftControlKeyL
PlayTrainer
KeyControlKey2
KeyShiftControlKeyP
PrizesMenu
KeyControlKey3
KeyShiftControlKeyR
ScoreToText
KeyControlKey4
KeyShiftControlKeyW
ShowGameSpecificHelp
KeyControlKey5
MouseLeftClickPrizes
StartGame

5.2.25. Pokemon specific factory server functions

InitDistributions
ProduceBooster
 

5.2.26. Pokemon specific game server functions

InitialScore
InitServerHook
SetUpPlayer

6. Implementing games using Gccg

6.1. Planning and preparations

Before starting a concrete work on a game project, you must collect some knowledge and material. You should be very familiar with the traditional conventions and rules of the game under implementation. Also, it would be very fruitful for the speed of the development, if you have at least basic knowledge for several other games already implemented under Gccg. When accomplishing each task a developer with large knowledge base can select the existing game with the most resemblance with respect to the task under work. If lucky, you can use lot of existing material as source.

Following information must be collected as a preparation for the project:

Ex.5: Collectible Poker - Step 1
As an example, we build our own collectible card game. It is a collectible Poker game with jokers. We choose Poker as a short name for the game. List of cards is traditional 2,3,4,5,6,7,8,9,10,J,Q,K,A of spades, hearts, clubs and diamonds plus two jokers, red and black. Since there is no rarity distribution, we made one by ourselves. Let us call rarities as common, uncommon, rare and very rare and denote them C, U, R and V. We choose that 2,3,4,5,6,7 and 8 are commons; 9,10,J and Q are uncommons; kings and aces of each suit are rares; and jokers are very rare. Suppose that these are sold as boosters containing 1 rare, 2 uncommon and 4 commons. We set that instead of a rare card, there can be a very rare card with probability of 20%.

This documentation is written to Unix-environment. Fortunately there is an excellent collection of Unix tools for Windows called Cygwin. You should install Cygwin if using Windows. [What packages are needed for Cygwin?] Then the most of this document applies also to the Cygwin environment. In addition to the decent working environment, you need to install at least binary packages (or compile from source) for your platform and the following packages: client, fonts, server and dev-tools. It is also highly recommended that you install all games you know including server packages. These can help you a lot, when you can peek how things are done in the game you are familiar with.

6.2. Beginning of the hard work is easy

Let us start from the easiest task. We need to establish similar directory structure as other games by creating subdirectories with the same name as the short name of the game. Then we need the image (or images if the game have several card backs) presenting the back of the cards in our game and store it under graphics/Game/ directory. The card back image can be in any format supported by SDL_image and it must have the size of a zoomed card image on the client. The zoom size can be decided by the designer of the game.

Ex.6: Collectible Poker - Step
At first, we create directories
mkdir data/Poker
mkdir lib/Poker
mkdir decks/Poker
mkdir graphics/Poker
mkdir xml/Poker
mkdir scripts/Poker
and then we store our card background image to
graphics/Poker/back.jpg

6.3. Basics of XML files

The game and cards are defined in XML-files. The game definition file is stored in xml/game.xml and it defines general properties of the game and client behavior. Each published card set is described in set definition file and are stored under xml/Game/ directory.

Ex.7: Collectible Poker - Step 1
Let us write a minimal game definition file xml/poker.xml for Poker and extend it later as needed:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE ccg SYSTEM "gccg-game.dtd">

<ccg name="Collectible Poker" dir="Poker">
  <option name="hand card size" value="50"/>
  <option name="table card size" value="50"/>
  <option name="deck card size" value="50"/>
  <option name="book card size" value="50"/>
  <cardset source="poker_basecards.xml"/>
</ccg>
Now we can validate XML code, for example, using command line tool xmllint
xmllint --noout --valid xml/poker.xml

The structure of the game definition file is simple. Everything is stored inside tag ccg, which have two attributes, the full name of the game and the short name of the game. Everything else is given in any order using couple of predefined tags. In above example, we introduced option tag which have two attributes: name of the option and it’s value. The options above determines the size of cards used in several places in the client. The values are percentage of the size with respect to our card background image. So, in the example, we decided that cards in the hand, in the deck, in the collection or on the table have their sizes halved. After the options, there is a tag pointing to a set definition file. The cardset tag determines which set definition files to load on startup.

The set definition file specifies a list of cards in some order. The order determines one-to-one mapping between card numbers and card names. The first card of the first set definition file given in the game definition file is a card number zero. After that, each card gets next integer in sequence and this numbering continues through every set definition file specified in the game definition file. The card number zero has a special meaning. It represents the back side image of cards. Additionally, the first set definition file does not specify any real cards. It is reserved for card backs and other special objects needed.

Ex.8: Collectible Poker - Step 2
Let’s create a set definition file xml/Poker/poker_basecards.xml for reserved cards:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE ccg-setinfo SYSTEM "../gccg-set.dtd">
<ccg-setinfo name="" game="Collectible Poker">

  <cards>
    <card name="A Card" text="" graphics="back.jpg">
    </card>
    <card name="_unknown_" text="" graphics="">
    </card>
    <card name="_unknown_" text="" graphics="">
    </card>
  </cards>

</ccg-setinfo>
And, of course, we validate our XML
xmllint --noout --valid xml/Poker/poker_basecards.xml

In the example above, we didn’t gave a name to our set (name attribute of ccg-setinfo tag). In that case, all cards from the nameless set definition file is considered special and they do not appear in players’ collection. Cards are listed in order inside cards tag. Each individual card is defined by card tag, which have attributes name, text and graphics. In the example, name attributes have a special value A Card denoting that the card does not have any meaningful name and _unknown for unused card slots. Attribute text contains the text of the card if any. The last attribute graphics points to the image representing the card. The images are searched from graphics/Game/ directory, unless the set definition file specifies different directory (see Section 6.5.). The example above sets image for the card number zero, i.e. the backside of cards. After the zero-card, there are cards 1 and 2 reserved for future. The number of reserved cards should be decided now to be big enough, since it ruins everything if card numbers changes later. If adding one card here, it shifts all the rest card numbers by one and every old server and client are incompatible thereafter.

6.4. First Gccg-script

The game specific functionality is programmed using platform independent Gccg-script. When the client starts, it checks that the most important definitions are give and if not, client displays an error message and quits. We are not yet going to the details of scripting, but we set up minimal script scripts/Game.include to boot our game instead and fill details later.
Ex.9: Collectible Poker - Step 3
We write following scripts/Poker.include:
# VARIABLES
# =========

HANDSIZE=5;
DECKBOX_SIZE=(20,220,110);
if(!port)
  port=29102;
product.image=(,);

# FUNCTIONS
# =========

def NewDeck
{
  return((("deck",(,)),));
}

def InitializeLocationTables
{
  rules.category=(,);
  rules.coordinate=(,);
}

def StartGame 
{
}

In the example above, we defined couple of variables and functions. Here is a description of variables:

HANDSIZE
This is the natural hand size for the game if any. Usually there are menu entries that allow directly transfer HANDSIZE number of cards from one target to another where appropriate.
DECKBOX_SIZE
This variable contains a triplet (w1, w2, w3), where each number is a width of the deck edit field in pixels. The first component w1 sets the width of the number of the cards field, w2 sets width for card names and w3 sets width of the card type field.
port
This is the default port number where to connect. We should check first that we don’t override port number given as an argument to the client.
product.image
This is a dictionary mapping product names to the corresponding product images under graphics/Game/. In the example we just defined an empty dictionary (which is the same as an empty list). If the image of a product is not found from this dictionary, the client uses graphics/unknown_booster.jpg instead.
And here are short descriptions of obligatory function definitions:
NewDeck()
This functions takes no arguments and returns an empty deck structure. The decks are described as dictionary which maps deck name strings to the lists of integers representing card numbers in the deck part. In this case, we are satisfied with one part called deck and it’s content defaults to the empty list.
InitializeLocationTables()
The card placement algorithm is described in section 6.9. This is an initialization function, which fills rules for the location algorithm. We leave tables rules.category and rules.coordinate empty for now and discuss them later.
StartGame()
This function is called at the beginning of the each game and can contain initialization tasks and automated start up procedures at the beginning of the match.

Now we are ready for our first test launch. Just say
ccg_client game.xml
and client should start using our minimal set of definitions. Connection to the meta server will fail and there is not much to do. You can browse empty collection without any cards and quit.

Fig.2: First launch
First launch

6.5. Creating set definition files

The first larger programming task is the generation of set definition files. Usually this is accomplished by downloading appropriate spoilers preferably in ASCII text format and then converting them to XML using Perl. A directory data/Game is reserved for accumulating all external data needed for the game. You can write small sample XML file by hand if not yet familiar with this process and try it first. After that you can write Perl script game_spoil_to_xml.pl to convert full featured set description. You must also edit the game definition file to load all information of sets.

Ex.10: Collectible Poker - Step 4
We want to create one deck suitable for playing poker. Here is a snippet of xml/basic_deck.xml:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE ccg-setinfo SYSTEM "../gccg-set.dtd">
<ccg-setinfo name="Basic Deck" dir="BasicDeck"
  abbrev="BD" game="Collectible Poker">

  <cards>
    <card name="Red Joker" text="" graphics="rj.jpg">
       <attr key="rarity" value="V"/>
       <attr key="suit" value="any"/>
       <attr key="rank" value="any"/>
    </card>
    <card name="Black Joker" text="" graphics="bj.jpg">
       <attr key="rarity" value="V"/>
       <attr key="suit" value="any"/>
       <attr key="rank" value="any"/>
    </card>
    <card name="Ace of Spades" text="" graphics="as.jpg">
       <attr key="rarity" value="R"/>
       <attr key="suit" value="spades"/>
       <attr key="rank" value="ace"/>
    </card>
    <card name="King of Spades" text="" graphics="ks.jpg">
       <attr key="rarity" value="R"/>
       <attr key="suit" value="spades"/>
       <attr key="rank" value="king"/>
    </card>

    ...

    <card name="Three of Clubs" text="" graphics="3c.jpg">
       <attr key="rarity" value="C"/>
       <attr key="suit" value="clubs"/>
       <attr key="rank" value="3"/>
    </card>
    <card name="Two of Clubs" text="" graphics="2c.jpg">
       <attr key="rarity" value="C"/>
       <attr key="suit" value="clubs"/>
       <attr key="rank" value="2"/>
    </card>
  </cards>

</ccg-setinfo>
We also need to update the game definition file to read this file in after our previous set definition file, which defined the card back.
  ...
  <cardset source="poker_basecards.xml"/>
  <cardset source="basic_deck.xml"/>
  ...
The line in bold text represents our latest addition to the file. Now we have following: card number zero is the back of the card, card numbers 1 and 2 are reserved for future, card numbers 3 and 4 are jokers, card number 5 is ace of spades and so on.

If we wish, we can create several copies of this set definition file and create several different products each having different graphics. This can be done simply by changing subdirectory specification dir at the beginning of the set definition file. We can also change rarities of additional card sets, if we like.

The header tag ccg-setinfo introduced two new attributes. The attribute dir defines subdirectory for the set, which is used as source when looking for card images. In the example above, the full path of the image of King of Spades is thus graphics/Poker/BasicDeck/ks.jpg. The attribute abbrev is two letter abbreviation for the set, which is used in several places instead of the full set name. Each card now contains card property definitions. Each property is given by attr tag, which has two attributes: key and value. When a script needs to know an attribute of a card, it can call a function card_attr(a,n), where n is the number of the card and a is the attribute. If there is an attr mapping having key="a" defined in the set definition file, the value attribute is then returned; NULL otherwise. Only compulsory property for actual cards is rarity. It is one of the letters chosen to present rarities followed by optional probability weight, e.g. R2. For the sake of completeness, we mention that card tag can contain an attribute back, which defines the card number of the card. Default card back is zero card.

When your Perl converter works perfectly, you can update Makefile in data/ directory to help rebuilding of XML files. You should add your game to usage line and create an entry for your game, which builds all XML files needed. In principle, you need one line for each set
./game_spoil_to_xml.pl Game/set_spoiler.txt > ../xml/Game/set.xml
You can find examples from the existing data/Makefile.

Now it is time for second test launch. This time we can browse the collection having empty slots for cards. We can use Ctrl+H to view statistics of a card or zoom a computer generated default card image using Shift key. However, cards are in alphabetical order, which probably is not acceptable for the most of the games. See chapter 6.8. for more information.

Fig.3: Second launch
Second launch

6.6. Setting up factory server

We have working client now. Our next step is to build server environment for the game. The factory server loads XML description of the game and card sets and provides randomly generated products. The protocol is simple. The factory server return a list of card numbers when it receives a triplet (n,s,t), where n is the number of products, s is the card set and t is the product type requested from the card set.
Ex.11: Collectible Poker - Step 5
Write initial scripts/Poker-factory-server.include:
if(!port)
  port=29103;

def InitDistributions
{
  distribution=(,);
  distribution{"BD"}=(,);
  distribution{"BD"}{"booster"}=((4,"C"),(2,"U"),(1,"R"));
}
This version does not yet recognize our special rarity V, but we will add that soon after we have tested this version.

We need to define following variables:

port
Port number of the factory server.
distribution
This variable contains the rarity distribution of products and it is initialized at function InitDistributions. The distribution is a dictionary with two keys: a set abbreviation and product name. Value of the dictionary entry is a list containing pairs (n,r), where n is the number of cards having rarity r in the product.
and following function:
InitDistributions()
This function is responsible to initialize distribution variable. In the example above we define a booster containing BD cards (i.e. cards from the Basic Deck card set). The dictionary should contain list of pairs (n,d), where n is the number of cards to be taken from the distribution d.

Ex.12: Collectible Poker - Step 6
We are ready to launch our factory server:
./ccg_server --load factory-server.triggers poker.xml
Now we can test it using telnet:
[wigy] gandalf:~ >telnet localhost 29103
Trying 127.0.0.1...
Connected to localhost.
Escape character is ’^]’.
(("BD",("Basic Deck",3,56)),)
(2,"BD","booster")
((42,14,37,13,48,7,44),(12,42,53,30,21,8,31))
When connecting to the factory server, it sends some information usable to the meta server. We then ask two Basic Deck boosters and the server replies nicely returning a list of two boosters as card numbers.

Sometimes products cannot be constructed directly from the distribution information. When the product does not have clear "slots" for each rarity, we may need to code our own function. We can overwrite default behavior by defining function ProduceName, which is called when the server wants to construct any product called Name. We can refine even further, by defining function ProduceSet_Name, which is called when the server generates the specified product Name from the given Set.

Ex.13: Collectible Poker - Step 7
We look at Pokemon factory server how Holo-cards are implemented and we implement Very Rare cards in the same way. We add the following code (in bold) to the factory server code.
  ...
  distribution{"BD"}{"booster"}=((4,"C"),(2,"U"),(1,"R"));
  distribution{"BD-V"}=(,);
  distribution{"BD-V"}{"booster"}=((4,"C"),(2,"U"),(1,"V"));
}

def ProduceBD_Booster
{
  if(random(100) < 20)
    return(RandomCardSet("BD",distribution{"BD-V"}{"booster"}));
  else
    return(RandomCardSet("BD",distribution{"BD"}{"booster"}));
}
Now we have two alternative distributions. We have added special distribution where a rare card is replaced with a very rare card. When a booster is generated, we choose randomly which one of the distributions to use. Then we use factory server function RandomCardSet to generate cards from the chosen distribution.

6.7. Setting up meta server

One more server is needed to initiate basic functionality of collecting and trading. The meta server handles this task. Basicly we do not need much more than initialize some variables to bring the meta server alive.
AMOUNT_TO_PAY_WEEKLY
See 3.3.1.
INITIAL_MONEY
See 3.3.1.
PRIZE_PER_PLAYER
See 3.3.1.
factory.port
Port number of the factory server, where the meta server connects to.
port
Port number of the meta server.
products
This variable holds current storage of products. It is a dictionary having complete product names as a key. Each key corresponds to a value (n,p,(s,t),n0). The initial size of the current print run is n0 and the number of products available now is n (see command /reproduce). The product itself is described by the pair (s,t), where s is the card set and t is the product type (see 6.6.). The price of the product is p.

Ex.14: Collectible Poker - Step 8
Let us write following scripts/Poker-meta-server.include:
if(!port)
  port=29102;
factory.port=29103;

PRIZE_PER_PLAYER=1.0;
INITIAL_MONEY=50.0;
AMOUNT_TO_PAY_WEEKLY=10.0;

if(!load("products"))
{
  products=(,);
  products{"Basic deck booster"}=(65536,3.9,("BD","booster"),65536);
  save("products");
}
We do not want to lose the status of the variable products between reboots. So, we try to load it’s saved value first and if that fails, we initialize it to the initial value. We put 65536 boosters available for $3.90. Finally, we save the value of the products. This is also done automatically when server is shut down.

Now it is time to test, if our server system is ready to sell products and manage collections. First we need to launch the factory server as described in the previous section and then launch the metaserver
./ccg_server --load meta-server.triggers game.xml
Now we can try our client to connect the meta server (don’t forget to add --server argument if necessary) and if succeeded, we are able to buy boosters, buy and sell cards, create decks and manage our want-lists. However, there are no card graphics yet but just simple blank skeletons having the name of the card and nothing else.

Fig.4: Buying the first boosters
Second launch

After testing you can shut down servers by simply pressing Ctrl+C. When receiving Ctrl+c or some other signal suggesting the end of excecution, the server saves it’s data and quits. You can look to the directory save/Game and there are all the non-static data of both servers.

6.8. Details of game defining XML

6.9. Card placement algorithm


[Rest details to be given later. These are just copy paste from my personal notes and probably also outdated.]