Eagle
I gave a presentation at the Erlang/Elixir/Gleam-and-friends devroom at FOSDEM 2024 on EAGLE: Evolving your (web)App with GLeam and Erlang.I used gleam to define the rules of a game, and generate core erlang that ran instances of the game.
In this post, I look forward to the Future.
Feedback
The talk was well-received (and will hopefully get a sequel, elsewhere).One question was about the ability to replay a whole instance. I answered that that could be possible, although on second thought
- it will not be possible with the naive instance as I have it, as it only executes migrations, but is not aware of the delta underneath.
- but it would be cool to have it (where both model deltas and player actions can be replayed)
Event Sourcing
This paper, in turn, pointed to Event Sourcing by Martin Fowler. In the context of my game(s), both a rule change and a player action are Events in this sense, and thus the sense of the question above.
Instance in Gleam, after all?
If my instance/game were a little wiser, instead of receiving an upgrade message and calling a dynamically generated migrate function, it would receive a Semantic Delta, pattern match and migrate. Likely, the migration is the bulk of the work, so the additional pattern matching isn't a problem.It would obviate writing complex meta core-erlang code. It would also save time compiling that code, although that is a lesser concern ((a) compiling would be on another thread, and (b) rule changes for games in progress should not happen very often). By switching to gleam, writing code would become a lot simpler.
For a player action, there would be no practical difference! The naive code has to distinguish between various actions and execute them. A smarter version would still do the same. Again, smarter code in Gleam is likely easier to write than gleam code that generates core-erlang code.
Not the Whole State
The Instance Client currently receives the whole, updated state. The migrate function in the server-side instance merely modifies data, it does not carry the delta that describes the change. If the instance knows about delta on both sides, there would be no need to convert/transfer the whole state (the delta is likely to be smaller, that is an advantage).
To prevent the list of events from growing arbitrarily long, some form of snapshotting is needed: a new starting point to which the remaining events can be applied. For the kind of games I am working with, board games that end quickly, this is not necessary.
Good match for BEAM
A game, ah, an instance, oh! a process! that receives an event, processes it, and generates events for other processes, yes, its clients. As if the Event Sourcing architecture describes BEAM. Seems there is indeed a match between MDD and BEAM, and I will be exploring that further.