Francisco Sant'Anna

On rewriting Pingus from C++ to Ceu

@_fsantanna

A few years ago, I wrote a blog post (and a simplified paper) on rewriting Pingus from C++ to Ceu. Pingus is an open-source clone of Lemmings, a puzzle-platformer video game. We rewrote 50% of the codebase, or 20k lines of code, which constitutes the entire game logic. The study advocates “Structured Synchronous Reactive Programming (SSRP)” as a more productive alternative for game logic development:

Ceu supports reactive control-flow primitives that eliminate callbacks and let programmers write code in direct and sequential style. Structured reactivity helps describing complex control-flow relationships in the game logic more concisely.

SSRP can be considered a flavor of “Structured Concurrency” (discussed in a previous blog post) with a focus on real-time interactive applications, such as video games.

The bulk of the study is a qualitative analysis of the programming techniques we applied during the rewriting process. For typical game behaviors, we could reduce up to 20% of the source code (e.g., event detection, interactive animations, menu transitions, etc). During the process, we also identified 5 control-flow patterns that likely apply to other games. In this context, a control-flow pattern is a recurring technique to describe execution dependency and/or explicit ordering between statements. They are:

  1. Finite State Machines: State machines describe the behavior of entities by mapping event occurrences to transitions between states that trigger appropriate actions.
    • Examples: double-click detection, character animations.
  2. Continuation Passing: The completion of a long-lasting activity may carry a continuation, i.e., some action to execute next.
    • Examples: interactive dialogs, menu transitions.
  3. Dispatching Hierarchies: Entities typically form a dispatching hierarchy in which a container that receives a stimulus automatically forwards it to its managed children.
    • Examples: redraw & update callbacks.
  4. Lifespan Hierarchies: Entities typically form a lifespan hierarchy in which a terminating container entity automatically destroys its managed children.
    • Examples: UI containers, particle systems.
  5. Signaling Mechanisms: Entities often need to communicate explicitly through signaling mechanisms, especially if there is no hierarchy relationship between them.
    • Examples: key shortcuts, screen pausing.

The reason I’m revisiting this study is because I’m currently rewriting Pingus to the upcoming version of Ceu. The goal is twofold:


Comment on @_fsantanna.