highscore Submodule

Overview

The highscore module provides a set of classes to make gathering and displaying high score information relatively simple. Classic Grand Champion, High Score #1-#4 style high score tables can be created with just a few lines. With a few more lines you can gather more sophisticated high scores, such as loop champion or similar.

While InitialEntryMode prompts the player for their initials, most developers will want to use EntrySequenceManager, which coordinates the display of a series of InitialEntryMode s. EntrySequenceManager is designed to be used with a subclass of HighScoreLogic, which enables the developer to take advantage of these classes while using completely custom logic to determine what initials need to be prompted for. CategoryLogic, is a powerful HighScoreLogic subclass that most developers will find suitable for implementing modern high score functionality.

Finally, generate_highscore_frames() can help to quickly create a traditional high score display.

Using EntrySequenceManager

In your GameController subclass’s setup method, configure the categories you wish to track scores for. The categories are used each time the game ends, as we’ll see in the next step. In this case we’ll setup two categories: a ‘classic’ category for the traditional Grand Champion and high scores 1-4, and a more modern ‘loop champ’ category. We set score_for_player to tell the category how to obtain that particular score value. Note that because the loop champ only has one title, only the highest loop score will be saved. The number of titles is used to determine how many scores are saved.

def setup(self):
    self.highscore_categories = []

    cat = highscore.HighScoreCategory()
    cat.game_data_key = 'ClassicHighScoreData'
    cat.titles = ['Grand Champion', 'High Score 1', ... , `High Score 4`]
    self.highscore_categories.append(cat)

    cat = highscore.HighScoreCategory()
    cat.game_data_key = 'LoopsHighScoreData'
    cat.titles = ['Loop Champ']
    cat.score_for_player = lambda category, player: player.loops
    cat.score_suffix_singular = ' loop'
    cat.score_suffix_plural = ' loops'
    self.highscore_categories.append(cat)

    for category in self.highscore_categories:
        category.load_from_game(self)

We use EntrySequenceManager to manage the high score prompting process once the game has finished. We instantiate it like a normal mode, set the finished handler and logic, and then add it to the mode queue:

def game_ended(self):
    seq_manager = highscore.EntrySequenceManager(game=self, priority=2)
    seq_manager.finished_handler = self.highscore_entry_finished
    seq_manager.logic = highscore.CategoryLogic(game=self, categories=self.highscore_categories)
    self.modes.add(seq_manager)

Finally, we write the finished handler to remove the sequence manager and add the attract mode to prepare for starting a new game:

def highscore_entry_finished(self, mode):
    self.modes.remove(mode)
    self.start_attract_mode()

An attract mode that displays the high scores might look like this:

class Attract(game.Mode):
    def mode_started(self):
        script = [{'seconds':2.0, 'layer':None}]
        for frame in highscore.generate_highscore_frames(self.game.highscore_categories):
            layer = dmd.FrameLayer(frame=frame)
            script.append({'seconds':2.0, 'layer':layer})
        self.layer = dmd.ScriptedLayer(width=128, height=32, script=script)

That the None layer allows the score display to be seen (as it is beneath the attract mode) for one period of the script.

Default Scores

Default scores and initials should be set using the game data template (the template_filename argument to procgame.game.GameController.load_game_data()). The key must match the HighScoreCategory.game_data_key value. Example:

ClassicHighScores:
  - {inits: GSS, score: 5000000}
  - {inits: ASP, score: 4000000}
  - {inits: JRP, score: 3000000}
  - {inits: JAG, score: 2000000}
  - {inits: JTW, score: 1000000}
LoopsHighScoreData:
  - {inits: GSS, score: 5}

Classes

CategoryLogic

class procgame.highscore.CategoryLogic(game, categories)

Subclass of HighScoreLogic. Implements a variable number of scoreboards using categories.

categories is a list of HighScoreCategory instances which will be checked for qualifying high scores.

EntryPrompt

class procgame.highscore.EntryPrompt(key=None, left=None, right=None)

Used by HighScoreLogic subclasses’ HighScoreLogic.prompts() methods to communicate which scores need to be prompted for.

key

Object that will be used to identify this prompt when HighScoreLogic.store_initials() is called.

left

String or array of strings to be displayed on the left side of InitialEntryMode.

right

String or array of strings to be displayed on the right side of InitialEntryMode.

HighScore

class procgame.highscore.HighScore(score=None, inits=None, name=None, key=None)

Model class.

score, inits and date are persisted via the dictionary with from_dict() and to_dict(). The remaining attributes are used to maintain state.

date

String date representation of this score, using time.asctime().

from_dict(src)

Populate the high score value from a dictionary. Requires score and inits keys, may include date.

inits

Player’s initials.

key

Object value used to uniquely identify this score.

name

Player’s name, such as Player 1.

score

Numeric high score value.

title

Title for this score, such as Grand Champion.

to_dict()

Returns a dictionary representation of this high score, including score, inits, and date.

HighScoreCategory

class procgame.highscore.HighScoreCategory
game_data_key

Key to this high score category’s data within game.GameController.game_data.

load_from_game(game)

Loads scores from game using game_data_key.

save_to_game(game)

Saves scores to game using game_data_key.

score_for_player

Method used to fetch the high score score value for a given Player. The default value is:

lambda player: player.score
score_suffix_plural

Plural suffix to append to string representations of high scores in this category, such as points. Used by generate_highscore_frames().

score_suffix_singular

Singular suffix to append to string representations of high scores in this category, such as point. Used by generate_highscore_frames().

scores

List of HighScore objects for this category. Populated by load_from_game().

titles

There must be a title for each high score slot desired for this category.

HighScoreLogic

class procgame.highscore.HighScoreLogic

Interface used by EntrySequenceManager to abstract away the details of high score entry and storage.

prompts()

Return a list of EntryPrompt objects to be presented to the player, in order.

store_initials(key, inits)

Called by EntrySequenceManager to store the entered initials.

InitialEntryMode

class procgame.highscore.InitialEntryMode(game, priority, left_text, right_text, entered_handler)

Mode that prompts the player for their initials.

left_text and right_text are strings or arrays to be displayed at the left and right corners of the display. If they are arrays they will be rotated.

entered_handler is called once the initials have been confirmed.

This mode does not remove itself; this should be done in entered_handler.

entered_handler

Method taking two parameters: mode and inits.

EntrySequenceManager

class procgame.highscore.EntrySequenceManager(game, priority)

A Mode subclass that manages the presentation of InitialEntryMode in order to prompt the player(s) for new high scores.

The logic attribute should be set to an instance of HighScoreLogic, which is used to customize the behavior of the sequence manager. The behavior of this class can be modified by supplying different subclasses of HighScoreLogic.

This mode does not remove itself from the mode queue. Set finished_handler to a method to call once the sequence is completed. The handler will be called immediately (once this mode is added to the mode queue) if there are no high scores to be entered.

create_highscore_entry_mode(left_text, right_text, entered_handler)

Subclasses can override this to supply their own entry handler.

finished_handler

Method taking one parameter, the mode (this object instance).

logic

Set this attribute to an instance of HighScoreLogic.

prompt()

To be called externally if using the ready_handler, once that handler has been called. Presents the initials entry mode.

ready_handler

Method taking two objects: this class instance and the EntryPrompt to be shown next. The implementor must call prompt() in order to present the initials entry mode, otherwise the sequence will not proceed. If this attribute is not set then initials entry mode will be shown immediately. This allows for special displays or interaction before each initials prompt.

Helper Methods

procgame.highscore.generate_highscore_frames(categories)

Utility function that returns a sequence of Frame objects describing the current high scores in each of the categories supplied. categories should be a list of HighScoreCategory objects.