-
Notifications
You must be signed in to change notification settings - Fork 4
Challenging Game Designs
This page collects examples of interesting challenges in various real-world game designs. The idea is that when considering a change to the design of the system, we verify that these interesting use cases are all satisfied.
Ticket to ride has a number of cases where you need to do really expensive calculations, like longest train, or very complex decisions of if a move is legal or not. These are good stress tests for any ideas about representing IsLegal as a declarative tree of statements, for example.
Problem: Fascists know the other fascists, including Hitler. But Hitler doesn't know who the fascists are. This requires a very weird visibility state that knows quite a bit about the game to know who to reveal it to.
A VisibilityState of VisibleToUsers that is a list of user IDs might be the only way to do it?
Dark Moon has the notion of various dice (which are components), which can be either in the general pool, or hidden behind the player screen. This is an example of a component that has dynamic state (which side is showing) that needs to be hidden to other players.
This is not particular to Ticket to Ride, but the use case demonstrates it. Much of Ticket To Ride proceeds in orderly turns, where only one user may make a move at a time. However, at the very beginning of the game, users are given three contract cards, and they may reject up to two of them. The order in which they do this is not set; they may do it in any order, before signaling they are OK to proceed.
This example illustrates the need for more than just a "single player is current player" mode.
In most cases, the list of components is fixed across all games of that type. However, in some examples, like Cards Against Humanity, the players can customize a card for that game. A similar thing applies to Pandemic Legacy, but in those cases the possible modifications are easy to model in advance.
This use case gets at that components are not always fully fixed in their "Static" state.
In Mysterium, one (or possibly two) players are the ghost, and all others are the guessers. Their rules and types of state are fundamentally different across those two roles.
This gets at the fact that different users may have different structs representing their game states. The roles are very different, but are fixed for the life of the game.
In mysterium, after all of the clues are given by the ghost in a round, a timer is started. When that timer is up (or all non-ghost players assert that they are done), we advance to the next round.
This is challenging because it's a move that should be auto-applied at some point in the future.
Related: in that case does the countdown timer get included in state? Or does every client count, too? And if the number of seconds remaining is part of the state, how do we ensure that we only tick it once a second?
In House on Haunted Hill, all players start off with the same basic rules. However, at some point in the middle of the game, one of the characters will turn into a demon, at which point their rules will drastically change compared to other users. (That game also has ~30 different demon rulesets that could be triggered, but that's not challenging to handle.)
The challenge is that at a key point in the game, a given "normal" user switches roles in a fundamental way that is likely hard to model with only one UserState object schema used by all users