Scopes

Every game is defined by building what we call the Scope tree when the game’s modelservice starts up.

The Scope tree starts at Game, and is defined as follows:

The arity of each relationship is read by following the direction of the relationship line. For example, the arity of the Game-Run relationsip is 1:n – one game may be related to zero or more runs, but every run is related to exactly one game.

Because the Scope relationships are one-to-many, they can be viewed as forming a parent-to-children tree. Although an instance of the Scenario model could in theory be related to both a RunUser and a World, this does not occur in practice. Each Scenario Scope object has a single parent – either a RunUser or a World.

The modelservice.games module provides all the base classes to build this tree. Each of these classes is considered a Scope. The logic of your game will be implemented by subclassing the necessary scope and adding your own custom logic.

Your game is defined by registering your top-level Scope with the modelservices.games.game decorator.

Inside any Scope, you can make any method that returns a value callable from javascript by decorating it with the modelservice.games.register decorator. Similarly, you can use the modelservice.games.subscribe decorator to subscribe any method to a topic:

from modelservice.games import Scenario, Game
from modelservice.games import register, subscribe


class ZeroSumScenario(Scenario):
    players = {}

    @register
    def add(self, term1, term2, details):
        return term1 + term2

    @subscribe
    def player_quit(self, player, reason, details):
        self.players.pop(player['id'])

Game.register('zero-sum', [ZeroSumScenario])

In this example, ZeroSumScenario.add will be registered at the uri {settings.ROOT_TOPIC}.models.{resource_name}.{scope_pk}.add and ZeroSumScenario.player_quit will subscribe to {settings.ROOT_TOPIC}.models.resource_name}.{scope_pk}.player_quit.

Alternatively, the name that will be used for the topic can be passed to the decorator:

class ZeroSumScenario(Scenario):

    @subscribe('player.quit')
    def player_quit(self, player, reason):
        self.players.pop(player['id'])

Game.register('zero-sum', [ZeroSumScenario])

ZeroSumScenario.player_quit will now be subscribed to {settings.ROOT_TOPIC}.models.{resource_name}.{scope_pk}.player.quit.

Further customization can be achieved by overriding the Scope.get_routing(name) method.

Scope methods

All Scopes inherit from a common Scope subclass and share these common methods among many others:

Scope properties

All Scopes inherits from a common Scope subclass and share these common properties among many others:

Logging

To log from a Scope, you can use the .log attribute.

The best practice is to use a string with the r formatting operator for your variables. For example, if you’d want to log the somevar variable to the INFO level, you’d use:

myscope.log.info("Something happened: {myvar!r}", myvar=somevar)

Concrete Classes

For convenience, the following scopes are defined in modelservices.games:

modelservices.games.Game

In addition to the methods inherited from Scope, Game has the following methods:

In addition to the properties inherited from Scope, Game has the following properties:

modelservices.games.Run

In addition to the methods inherited from Scope, Run has the following methods:

In addition to the properties inherited from Scope, Run has the following properties:

modelservices.games.World

In addition to the properties inherited from Scope, World has the following properties:

modelservices.games.RunUser

In addition to the methods inherited from Scope, RunUser has the following methods:

In addition to the properties inherited from Scope, Run has the following properties:

modelservices.games.Scenario

In addition to the properties inherited from Scope, Scenario has the following properties:

modelservices.games.Period

In addition to the properties inherited from Scope, Period has the following properties:

modelservices.games.Decision

In addition to the properties inherited from Scope, Decision has the following properties:

modelservices.games.Result

In addition to the properties inherited from Scope, Result has the following properties: