Skip to content

GameOfLifeEffect

Source: GameOfLifeEffect.h

GameOfLifeEffect

class GameOfLifeEffect
src/light/effects/GameOfLifeEffect.h:27

Inherits: EffectBase

Conway's Game of Life cellular-automaton effect.

GameOfLifeEffect card GameOfLifeEffect controls Author: Ewoud Wijma (2022), modifications by Brandon Butler / @Brandon502 / wildcats08, https://natureofcode.com/book/chapter-7-cellular-automata/ , https://github.com/DougHaber/nlife-color , https://github.com/ewowi/MoonLight/blob/main/src/MoonLight/Nodes/Effects/E_MoonModules.h

A live cell survives when its live-neighbor count is in the ruleset's survive set. A dead cell is born when its count is in the birth set. Neighbors are the 8 around a cell in 2D and the 26 in 3D, optionally wrapping toroidally.

Prior art: MoonLight's GameOfLife, after natureofcode chapter 7 and DougHaber/nlife-color.

Public Attributes

uint8_t backgroundColorR = 0 : The background's red channel, which dead cells fade toward.

uint8_t backgroundColorG = 0 : The background's green channel.

uint8_t backgroundColorB = 0 : The background's blue channel.

uint8_t ruleset = 1 : The selected ruleset, 0 reading customRuleString.

char customRuleString = "B/S" : A user-typed rule, parsed as digits around a slash.

uint8_t speed = 20 : Generations a second, where 100 runs uncapped.

uint8_t lifeChance = 32 : What percentage of cells a new game starts alive.

uint8_t mutation = 2 : How often a birth takes a random color rather than inheriting one.

bool wrap = true : Wrap the board toroidally, so a glider leaving one edge returns at the other.

bool disablePause = false : Skip the settle pause a new game opens with.

bool colorByAge = false : Age a live cell from green toward red rather than painting its palette color.

bool infinite = true : Respawn a static board rather than letting it sit.

uint8_t blur = 128 : How far a dead cell blurs toward the background, leaving a trail.

Public Methods

virtual inline const char * tags() const override : Catalog tags: MoonLight origin, MoonModules.

virtual inline Dim dimensions() const override : Volumetric: a 3D board uses the 26-cell neighborhood.

virtual inline void defineControls() override : Publish the ruleset, the speed, the density and the coloring.

virtual inline void prepare() override : Size the planes on the heap: an inline array here bootlooped a P4 by overflowing its stack.

virtual inline void onControlChanged(const char * name) override : Reparse the rule whenever the ruleset or the custom string changes.

inline bool allocateForTest(lengthType w, lengthType h, lengthType d) : Test seam: size the grid without a Layer, so a test can drive the automaton deterministically.

inline void setCellForTest(lengthType x, lengthType y, lengthType z, bool on) : Test seam: seed one cell of the pattern.

inline bool isAliveForTest(lengthType x, lengthType y, lengthType z) const : Test seam: read one cell back.

inline void stepForTest() : Test seam: run exactly one generation, with no rendering or respawn.

inline void parseRulesetForTest() : Test seam: parse the selected rule into the birth and survive sets.

inline bool birthForTest(uint8_t n) const : Test seam: whether a dead cell with n live neighbors is born.

inline bool surviveForTest(uint8_t n) const : Test seam: whether a live cell with n live neighbors survives.

virtual inline void tick() override : Run a generation when the speed allows, painting births, deaths and the blur trail.

Public Static Attributes

constexpr const char * kRulesetOptions = { "Custom B/S", "Conway's Game of Life B3/S23", "HighLife B36/S23", "InverseLife B0123478/S34678", "Maze B3/S12345", "Mazecentric B3/S1234", "DrighLife B367/S23"}

constexpr uint8_t kRulesetCount = 7 : How many rulesets the select offers, including the custom entry at index 0.

constexpr const char * kRulesetStrings = { nullptr, "B3/S23", "B36/S23", "B0123478/S34678", "B3/S12345", "B3/S1234", "B367/S23"}

More info

How a game ends, and the next begins

The board fingerprints itself with crc16 at three periods. Every 16 generations catches oscillators, every lcm(h,w)*4 catches spaceships. Every sixth of those catches cube gliders in a volume. A recurring fingerprint, a die-out, a density floor or a random nudge respawns or resets it. A respawn injects an R-pentomino, or a glider one time in five. Each new game opens with a 1.5 second settle pause, unless disablePause is set.