GDLasso is a Swift package that provides a discrete, composable architecture pattern for the Godot game engine.
GDLasso is essentially Lasso, an open-source iOS architecture project, repurposed for Godot.
GDLasso is written in Swift and thus cannot be used directly in Godot (yet...). However, leveraging SwiftGodot you can write GDExtensions in Swift with GDLasso as an SwiftPM dependency.
Similar to other unidirectional, reactive frameworks, the View
sends actions to the Store
which updates the State
which the View
is observing. In the context of Godot, the View
is a Node
.
The real power comes from composition. Flows
are the "glue code" that manage multiple Stores
and facilitate communication between them. Stores
can communicate Output
to Flows
for this purpose.
As an example:
- The
EnvironmentNode
notices a Node3D has walked into a patch of lava. - It communicates this to its store,
EnvironmentStore
. EnvironmentStore
then it dispatchesOutput
to theFlow
, notifying it that something has stepped into lava.- The
Flow
checks if it was the player, and if so it informs thePlayerStore
that the player has taken damage from lava. - The
PlayerStore
applies damage to the player by reducing theHealth
value in itsState
.
See the Example project for more details.
It can seem complicated at first, especially when compared to Godot's Signals. However, Signals are (subjectively) an anti-pattern. In small projects Signals are great, and can help things move quickly, but when projects grow in size Signals cannot be managed sanely.
Think about it this way: A conversation with one other person in an empty room is straightforward, but once the room is full of people and those people are all having conversations with several other people simultaneously, conversation is impossible/infuriating.
By creating discrete, single-responsibility entities we can:
- Keep control of our lines of communication.
- Test each entity in a vacuum.
- Reuse entities in different contexts.
- Create a Swift GDExtension using SwiftGodot
- Add GDLasso as a dependency of your Swift GDExtension
- Build your extension using the GDLasso pattern.
I am currently using GDLasso to build Riposte. As I make progress there I will make improvements to GDLasso. The core concepts won't change, but APIs might be unstable for a while.
Things I'd like to see improved:
- Flows, currently they're nothing more than an empty protocol. All "glue" functionality is totally custom.
- More opinionated usage instructions.