The director module deals with state management.

Most games have at least two screens: a main menu that prompts you to play, and the actual game. The DirectorLoop class keeps track of the screen (scene) that the player is seeing and interacting with, and lets you switch to another one.

Scenes are stored in a stack. To go back to the previous scene, you pop off the top of the stack. If there are no more scenes, the loop exits.

Here’s a simple example:

from bearlibterminal import terminal
from clubsandwich.director import DirectorLoop, Scene

class BasicLoop2(DirectorLoop):
    def get_initial_scene(self):
        return MainMenuScene()

class MainMenuScene(Scene):
    def terminal_update(self):
        print(0, 0, "Press Enter to begin game, Esc to quit")

    def terminal_read(self, val):
        if val == terminal.TK_ENTER:
        elif val == terminal.TK_ESCAPE:

class GameScene(Scene):
    def terminal_update(self):
            0, 0,
            "You are playing the game, it is so fun!" +
            " Press Esc to stop.")

    def terminal_read(self, val):
        if val == terminal.TK_ESCAPE:

if __name__ == '__main__':
class clubsandwich.director.DirectorLoop

An event loop that manages a stack of scenes. Forwards all input events to the topmost scene. Draws all scenes each frame, starting with the topmost scene a True value for Scene.covers_screen.

You use this class by subclassing it. Override get_initial_scene() to return the initial scene. Override terminal_init() to do any initial setup.

This is a subclass of BearLibTerminalEventLoop, so after subclassing it, instantiate it and call .run() to run your game.


List of scenes. Topmost is active.


The scene on top of the stack which is receiving keyboard events.



You must override this in your subclass.

Parameters:may_exit (bool) – If False, the loop will not exit if there are no more scenes in the stack.

Pop a scene off the stack and make the next topmost one active.


Pop all scenes off the stack and exit the loop.

Parameters:new_value (Scene) –

Push a scene onto the stack and make it active.


Pop all scenes off the stack and exit the loop.

Parameters:new_value (Scene) –

Replace the topmost scene on the stack with a new value. If popping a scene results in an empty stack, the loop does not exit.


Called immedialy after the terminal has been opened, but before the first terminal.refresh() call.

If you subclass, you probably want to call super().terminal_init() after you do your setup, because this method implementation adds the first scene to the stack.


DirectorLoop’s implementation of BearLibTerminalEventLoop.terminal_read(). Forwards events to the active scene.

You don’t need to call or subclass this method.


DirectorLoop’s implementation of BearLibTerminalEventLoop.terminal_update(). Updates the active scene and any visible behind it.

You don’t need to call or subclass this method.

class clubsandwich.director.Scene

Handle logic for one screen.


If True, no scenes under this one in the stack will be drawn by DirectorLoop. You’ll probably want to set this to True in most cases, unless you really want the lower scenes to show through (e.g. popups).

Parameters:reader (Object) – An object that has a method terminal_read(val)

Add an object to be called when terminal input is sent to this scene. All input is sent to all readers.

You may never need to worry about this. UIScene takes care of the details for clubsandwich.ui.


Called by DirectorLoop when becoming the active scene. Always called after enter().


Weak reference to the director this scene is managed by. Becomes None if the director is garbage collected, or if this scene is removed from the director’s stack.


Called by DirectorLoop when added to the stack.


Called by DirectorLoop when removed from the stack.

Parameters:reader (Object) – An object in the list of terminal readers

Stop calling reader.terminal_read(val) when this scene receives events.


Called by DirectorLoop when this scene is about to stop being the active scene. Always called before exit().

Parameters:char (str) – Return value of

Called by DirectorLoop if there is input to be processed.

Parameters:is_active (bool) – DirectorLoop will pass True iff this scene is topmost in the stack.

Called by DirectorLoop each frame iff no scenes above it in the stack have set covers_screen == True.