# Add Your First Object
After the previous section, you have a somewhat empty checkers module integrated in a minimal app. It is now time to:
- Add a game storage type.
- Compile Protobuf.
- Add the necessary keeper functions.
# The game rules
A good start to developing a checkers blockchain is to define the rule set of the game. There are many versions of the rules. Choose a very simple set of basic rules (opens new window) to avoid getting lost in the rules of checkers or the proper implementation of the board state.
Use a ready-made implementation (opens new window) with the additional rule that the board is 8x8, is played on black cells, and black plays first. This code will not need adjustments. Copy this rules file into a new
rules folder inside the root folder of your
checkers-minimal module. Change its package from
rules. You can do this by command-line:
# A stored game object
With the rules in place, begin with the minimum game information needed to be stored.
# The game object type
- Index: A string, so it can be identified and retrieved from storage.
- Black player: A string, the serialized address.
- Red player: A string, the serialized address.
- Board proper: A string, the board as it is serialized by the rules file.
- Player to play next: A string, specifying whose turn it is.
When you save strings, it makes it easier to understand what comes straight out of storage but at the expense of storage space. As an advanced consideration, you could store the same information in binary.
As ever, taking inspiration from
minimal-module-example, this can be described in
Since Index is used to store and retrieve the stored game, it does not need to be saved to storage. This saves precious storage space.
Now that you have the individual stored game structure, you can define how it is kept in storage.
# The storage structure
The way that makes sense is to keep a map of games in storage (and controled by the keeper), and rely on the SDK's basic structures to optimize saving and retrieving.
However, the genesis takes a list, and in this list, the games need to be identified by their index.
To achieve that, you create a composed type that is used in the genesis state.
# Add validation
You can consider adding functions on the
StoredGame, for instance a
Additionally, you need to:
- Make sure that the
Indexbyte count remains within reasonable bounds, for instance less than 256 bytes.
- Make sure that the genesis does not pass games with conflicting indices.
Start with a new
errors.go file in the root folder of your
checkers-minimal module and a new
stored-game.go to contain relevant functions:
With these additions, you can validate the games in
With the basics of genesis and validation handled, shift focus to the keeper to have it handle this storage too.
# Adjust the keeper files
In order to declare the stored games as a map, you first need to define a map key in
Then declare its type in the keeper struct in
And then initialize the storage access, taking inspiration from
Do not forget the genesis manipulation to and from storage in
keeper/genesis.go, again taking inspiration from
# Test again
Just like you did in the previous section, compile the minimal chain, re-initialize, and start it. You need to re-initialize because your genesis has changed once again:
Now your minimal chain not only has a checkers module, but also a games storage area. After stopping it with CTRL-C, confirm this by calling up:
In there, you can find:
# Up next
You have an on-chain game storage area, but it is empty. In the next section, you will start populating it with the use of a transaction message.