Skip to content
On this page

3. New model โ€‹


This step is optional. It is only needed if you want to define a new game with new rules. To get started, it may be easier to use one of the pre-defined example models.

A model is a piece of code that determine the rules of a game. They consist of two lambdas: init and apply_.

init takes a set of parameters and returns the initial state of the game. apply_ takes a current state, a move, and a current state metadata. It returns a new state and, if the game is finished, an outcome. The outcome can be mapped to a settlement, using a list defined at game creation.

Push a new model on the platform โ€‹


The model_wrap function of returns the structure expected by the new_model entrypoint.

Click me to view the code
import smartpy as sp
gp         ="state_channel_games/")
Tictactoe  ="state_channel_games/models/").Tictactoe
model_wrap ="state_channel_games/").model_wrap

@sp.add_test(name="New Model")
def test():
    sc = sp.test_scenario()
    player1 = sp.test_account("player1")
    platform_address = sp.address('KT1_ADDRESS_OF_THE_PLATFORM'),
    platform = gp.GamePlatform(admins = sp.set([player1.address]), self_addr = platform_address)
    sc += platform

    # New Model
    tictactoe = Tictactoe()
    model = sc.compute(model_wrap.model_wrap(tictactoe))
    model_id = sc.compute(model_wrap.model_id(model))
    platform.new_model(model).run(sender = player1.address)

Compute the model_id โ€‹

The model_id is a BLAKE2B hash of the parameters model given to new_model.

import smartpy as sp
model_wrap   ="state_channel_games/").model_wrap
Tictactoe    ="state_channel_games/models/").Tictactoe

tictactoe = Tictactoe()
model     = sc.compute(model_wrap.model_wrap(tictactoe))
model_id  = sc.compute(model_wrap.model_id(model))

How to code the model? โ€‹


You should never use blockchain operations instructions inside your lambda.

The complete list of instructions is available in the Michelson Reference. It includes:

You should never accept a game with a model that contains one of these instructions. More explanations here

Model class โ€‹

A model is a python class that defines the following attributes:

  • name: A string with the name of the model
  • t_init_input: SmartPy type of the parameter of init
  • t_game_state: SmartPy type of the game state
  • t_move_data: SmartPy type of the parameter of a play move
  • t_outcome: list of the model outcomes

And two methods:

  • apply_: How the game acts after a play move`
  • init: How the game is initialized
def admin_new_model(self, metadata, model, permissions, rewards):
    # The metadata of the model.
    sp.set_type(metadata, sp.TMap(sp.TString, sp.TBytes))
    # The model
    sp.set_type(model, sp.TBytes)
    # Model's permissions
    sp.set_type(permissions, sp.TMap(sp.TString, sp.TBytes))
    # A list of transfers from the platform to reward the creators of the model.
            token_id=sp.TNat).layout(('to_', ('token_id', 'amount'))))
class MyModel:
    def __init__(self):
        # Name of the model
        # Example: "Tictactoe" = ...
        # Type of the unpacked `model_init` params
        # Example: sp.TUnit
        self.t_initial_config = ...
        # Type of the unpacked game state
        # Example: sp.TMap(sp.TInt, sp.TMap(sp.TInt, sp.TInt))
        self.t_game_state = ...
        # Type of the unpacked `mode_data`
        # Example: sp.TRecord(i=sp.TInt, j=sp.TInt)
        self.t_move_data =
        # List of possible outcomes
        # Example: ["draw", "player_1_won", "player_2_won"]
        self.t_outcome = ...

    def model_init(self, params):
        """The lambda that will be called when instantiating a new game."""
        sp.set_type(params, sp.TBytes)  # The game params
        # The initial state computation and checks
        sp.result(sp.pack(...))  # The game's initial state

    def model_apply(self, apply_input):
        """The lambda that will be called every time someone is playing."""
        sp.set_type(apply_input, sp.TRecord(
            move_data=sp.TBytes,  # Move data given to the model
            move_nb=sp.TNat,  # Incremental id of the move. (Managed by the platform.)
            player=sp.TNat,  # Id of the current player. (Managed by the platform)
            state=sp.TBytes,  # Current state of the game. (Last state returned by the model)
        # A new state computed from inputs.
        result = ...
                sp.TBytes,  # New state of the game
                # Outcome: If `None`, the game continues.
                #          Otherwise the game ends with the given outcome.

Model wrap โ€‹

model_wrap from is a helper that takes an instance of your class and returns a record that you can give to the new_model entrypoint.

model_wrap automatically

packs and unpacks your inputs and outputs. So the game platform only stores bytes.

The gameTester let you test your model without the wrapping process and channels complexity. :::

init lambda โ€‹

The init lambda takes one parameter of the type defined in t_init_input.

It returns (by calling sp.result) a game state of the type defined in t_game_state.

apply_ lambda โ€‹

The apply_ lambda takes 4 parameters:

  • move_data of type t_move defined in t_move_data
  • move_nb of type nat: the id of the current move
  • player of type int: the id of the current player
  • state of type defined in t_game_state

It returns (by calling sp.result) a pair of

  • new_state of type defined in t_game_state
  • outcome (see outcomes)


The outcome returned by apply_ is surrounded by sp.bounded because verifies that it is listed in self.t_outcome.

Example โ€‹

Example with the simplest model:

import smartpy as sp

class Transfer:
    def __init__(self): = "Transfer"
        self.t_init_input = sp.TUnit
        self.t_game_state = sp.TUnit
        self.t_move_data  = sp.TUnit
        self.t_outcome    = ["transferred"]

    def apply_(self, move_data, move_nb, player, state):

    def init(self, params):

The rest is SmartPy code that you can learn and try on

We've build a lot of models that can be used as examples. Also, you can always contact us on Telegram

Game tester โ€‹

Game tester is a little platform that let you test your models in a simple environment. Examples of its usage can be found in the tictactoe template

Models permissions โ€‹

Models can have permissions to mint platform tokens. see tokens