Darkwood engineering

Strata Relay

Procedural terrain, deterministic mutations and interoperable messages with Symfony 8.2

Strata Relay isometric terrain and crystal anchors
01 | 12 @matyo91

The game concept

The player moves the terrain

  • Tap one column to pulse a local cross
  • Read the new contour before spending the next move
  • Connect both crystals through middle-height terrain
Initial Strata Relay board
02 | 12 @matyo91

A compact isometric world

25 columns inside a 5 × 5 × 5 bound

5 × 5
interactive heightfield
125
logical voxel positions
1 camera
fixed portrait view
03 | 12 @matyo91

Terrain mutations

One pulse changes at most five columns

+1
+1
tap
+1
+1

Only mutable cells inside the board advance.

1low
›
3resonant
›
5high

The wrap from high to low makes each pulse reversible.

04 | 12 @matyo91

Procedural generation

Solvability comes from construction

Seed + stageOne deterministic input recreates the same puzzle.
›
Valid routeA middle-height path links source and target.
›
Local scrambleKnown pulses add decoys and disruption.
›
Witness replayThe same public rule verifies a route to victory.

The witness proves solvability. It does not claim the shortest or only solution.

05 | 12 @matyo91

Small rules, many situations

Source compactness and delivery size differ

22,202 bytesruntime GDScript
0 importedgameplay art or audio assets
39.5 MBraw WebAssembly runtime
Unmeasuredisolated game-only runtime memory

Procedural generation reduces authored level data. It does not automatically reduce every other metric.

06 | 12 @matyo91

Godot implementation

State first, animation second

for changed in affected:
    var before := int(next["levels"][index_of(changed)])
    var after := (before + 1) % 3
    next["levels"][index_of(changed)] = after
    events.append({"cell": changed, "before": before, "after": after})
Rules

Generate, mutate and evaluate the authoritative board.

Events

Describe the local columns that changed during one turn.

View

Interpolate heights and redraw the derived signal path.

07 | 12 @matyo91

Performance and validation

Measured results from the completed game

557rule assertions
zero failures
5,000generated puzzles
witness replay passed
80.564 µsaverage generation
measured host
12.346 µsaverage local update
including state copy
686runtime GDScript lines
25cells examined at most
during connectivity
08 | 12 @matyo91

A visible consequence

Connectivity turns terrain into the objective

Middle-height columns carry the cyan signal. Victory arrives when one connected component reaches both crystal anchors.

The board evolves locally. The signal is derived from the resulting state.

Completed Strata Relay board with a connected cyan path
09 | 12 @matyo91

Symfony 8.2 cross-application messaging

A contract can cross the boundary

Application A

Owns its local simulation and publishes one accepted fact.

game.session
completed.v1
Application B

Maps the stable type to its own schema and behavior.

Hypothetical example. Strata Relay remains offline and does not emit this event.

10 | 12 @matyo91

Message identity

Three identifiers answer three questions

message_id

Which logical event is this, across delivery attempts?

correlation_id

Which wider workflow groups this event with related messages?

causation_id

Which earlier command or event produced this one?

#[AsMessage(serializedTypeName: 'game.session.completed.v1')]
final readonly class GameSessionCompleted { /* explicit versioned fields */ }
11 | 12 @matyo91

Conclusion

Small rules, explicit boundaries

Deterministic worlds

A seed reconstructs the same playable state.

Local consequences

One action changes a bounded, visible neighborhood.

Derived signals

Connectivity follows the terrain that actually exists.

Versioned contracts

Applications exchange facts without sharing internals.

darkwaar.com/games/strata-relay
12 | 12 @matyo91