←back to thread

333 points freetonik | 1 comments | | HN request time: 0s | source
Show context
fleabitdev ◴[] No.42471288[source]
This engine uses a Redux-like architecture. You have a State type (containing data like "the position of the black kingside rook") and a stream of in-game actions (like "knight to F3"). Each action is handled by a pure function which converts the current State to a new State. You can either transmit State deltas from the server to the client, or just transmit the actions themselves (https://longwelwind.net/blog/networking-turn-based-game/).

This design makes it easy to implement optimistic updates, rollback, replays, automated testing, and recovery after a disconnection. It's a surprisingly good fit for UI, too; you can render simple games as a React component which takes the current State as one of its props.

However, a stream of context-free actions can be a really inconvenient representation for some games. The rules of a board game are often like the control flow of a computer program: you'll see branching, iteration, local variables, function calls, structured concurrency, and sometimes even race conditions and reentrancy. When you try to represent all of this logic as a State object, you're basically maintaining a snapshot of a "call stack" as plain data, and manually resuming that "program" whenever you handle an action. It doesn't seem ideal.

I've been sketching a board game engine which would represent the game logic as normal code instead. It seems promising, but it really needs a couple of language features which don't exist in the mainstream yet, like serialisation of suspended async functions.

replies(5): >>42471791 #>>42472084 #>>42472570 #>>42475998 #>>42477605 #
LudwigNagasena ◴[] No.42472084[source]
My main pain point with any sort of Flux-like state management is transitions [1]. The state of UI is not fully described by the state of the game [2]. If I play a card, the game state can be instantly updated to the next decison-making point, but in reality I want to show steps of the game through animations, some of which are concurrent and some of which are consecutive. That usually ends up in a mess; and I've never seen someone implement it nicely.

[1] And generally dynamic stuff like drag-n-drop, which is infinitely times simpler in any other architecture than in React.

[2] That is also true for business apps, but their animations are usually so simple you can simply use CSS.

replies(7): >>42472171 #>>42472685 #>>42475075 #>>42475378 #>>42476566 #>>42476646 #>>42480234 #
1. ginsider_oaks ◴[] No.42476566[source]
I remember someone making a card game GALGA [1] in Haskell and compiling a high-level "rules" DSL to a low-level "animation" DSL and "primitive" DSL for handling animations and state changes respectively.

[1] https://roganmurley.com/2021/12/11/free-monads.html