TODO: update
Board games are not just for fun: they seriously exercise our reasoning abilities and prepare players for “real-world” activities that require problem solving.
Turn-based board games, regarded as formal systems, form an interesting computation - ? avoid debate ^ - emphasize computational model/interaction between state and people
There is much recent interest in complex games that include large libraries of cards and scenarios in order to combinatorially increase gameplay variety. Regarded as formal systems, these games are a legitimate challenge to represent using software.
We introduce a language, Partake, which allows for compositional development of games using programs that match the conciseness of natural language. Going beyond traditional monist object-oriented systems, Partake recognizes a basic duality between situations and actors, which clarifies the role of each in specifying gameplay. Game rules typically specify complex situations in which players act, so we focus on the task of specifying situations. Situations unfold over time into choice-points to be decided by various actors, be they people, randomizers, rulings, or strategic heuristics. We present a temporal semantic model based on episode segments that naturally group together these choices. We introduce two intertwined new languages: a declarative relational language for defining concepts and a procedural one for episodes.
Finally, our approach allows us to decouple low-level input/output issues like event handling and rendering from the high-level input/output specified by game logic. We demonstrate this with a novel GUI generation algorithm, which provides a way of smoothly interpolating between a minimalist menu-based GUI all the way to fully custom GUIs, while significantly reducing the effort needed for practical board-game style GUIs.
We propose a relational object-oriented model for defining games and other interactive software.
summary of the aspects of board games as a model of computation that we must capture in the language:
(Comparison to traditional OO model)
The original Smalltalk system was designed to support the human creative spirit by attempting to reflect human communication patterns onto those of the computer. The central metaphor was that of the physical object, a restricted area of space with definite affordances. A central focus was on formally capturing affordances and needs; any object with affordances appropriate for a particular need could be used to satisfy that need. For instance, many file-system implementations might be hidden behind a particular interface that represents a need to list files within a directory and access particular files by name. Uniformity of representation was emphasized by ensuring that all programmer-facing value types were objects todo.
Game objects, however, do not have a function-oriented nature, instead being purely symbolic. The collection of game objects takes on meaning based on rules that impose particular relationships among them and between them and the players’ goal(s). A typical game token is an entity without internal structure: it is merely distinct from other tokens and occupies some physical space. However, it may take on an arbitrarily large salience due to attributes granted it by game rules.
In order to design a programming language that reflects the natural way that people combine and learn about game rules, we must begin by reflecting the basic values that rules refer to and manipulate.
In light of the reasons and examples just given, we propose that a relational model for game entities is necessary. Relations do not impose a fixed up-front structure on entities. For instance, the statement
token P
located P -> L
asserts merely that P
is a token
with a
location L
. Additional facts may or may not be asserted and
updated later:
health P -> 10
has-ability P 'attack-right
has-ability P 'flee
...
health P -> 8
Syntax note: We use the traditional
logic-programming style syntax for tuples and queries, with lower-case
predicates and upper-case variables
(e.g. predicate(X, A+B)
), except written in the style of ML
function application (e.g. predicate X (A+B)
).
A second core observation about the board game domain is that almost the entirety of the game state must live on the board. This is a simple reflection of human short-term memory limitations: a well-designed game and game board should impose minimal unnecessary cognitive burden on the players.
However, there are two issues that conflict with this:
However, a high-level view of gameplay suggests that typical games require players to make choices and then promptly unfold the consequences of those choices as determined by the relevant game rules. The process of unfolding the rules takes time, and we note that the intermediate points may not always have a literal board representation. For instance, when playing a card that says “draw a card, then discard a card from your hand”, it is clear that
The computational state needed to carry out this action is simple for a player to carry mentally, and we wish to reflect this in our mechanism for representing rules.
Procedural languages have a simple notion of time during execution: the program counter and call-stack. Reasoning about program behavior at this level is notoriously tedious, but programming an application such as a board game engine requires carefully mapping game time onto execution time in some way. The procedural model is poorly suited to the task of representing computations mainly consist of cycles of interaction between several actors.
Instead, we propose an objective representation of time that captures a basic way that people group situations into periods of time. We refer to a period of time formally as an episode. Episodes can contain other episodes (such as when a player’s turn consists of two phases) and may be ordered temporally (such as when a player’s turn must fully elapse before another player’s turn may begin). Episodes can also be concurrent (such as when two players in a cooperative game may take their turns in an arbitrarily interleaved fashion) (or in a simultaneous moves game, where players must make certain decisions and then reveal them simultaneously).
More formally, we assume an infinite set E of episodes, and equip them with the following structure:
(ignore)
Rules that match one attribute need not refer to others:
has-ability P 'attack-right, located P -> L,
adjacent-right L L', located P' L'
-----------------------------------------
may-attack P P'.
But may if they wish to:
has-ability P 'flee, health P -> HP, HP > 5
---------------------------------------
may-flee P.
The most important consequence of this choice is that rules combine commutatively.
Turn-based board games represent an interesting computational paradigm. We are interested in games with fully explicit rules, so that they can be formalized as transition systems.
The episode language unfolds into a tree of episodes.
type Pattern = (Name, List Term)
def Episode :=
| Node Name Episode
| Observe Query Episode
| Choose Actor Query Episode
| Branch Actor (List (Name, Episode))
| Assert Pattern
| Begin Name Episode
Name, Term = ...
Actor = ...
basic actors:
- all at once
- this before that
- player's choice
- up to N
forms of input: - label, C (choose which child to go down) and then C - map (label -> C) (do C_l for each label) - pragmatic thing (for incrementally resolving choice) -
challenges to demonstrate:
modifying local facts
adding new derivations for a relation
rebinding a relation
taking control from older rule
structural complexity (if example below)
interruptions to expected game flow (fizzle type rules (no move, do as much as possible))
What should happen if two rules attempt to simultaneously move a token from its current location to different target locations? For this simple reason, a language cannot universally provide both state manipulation and simultaneity. Simultaneity still provides a useful increase in expressivity: it allows for games such as rock-paper-scissors, and even in perfect-information games, it enables transitions which are distinct from doing either one of the two actions in series. It can be provided so long as the game rules only introduce simultaneous episodes that mutate independent aspects of the game board.
…In particular, an append-only language makes no gaurantees that reading earlier code will have any benefit for understanding current code, as it might have been wholesale replaced. …introduction of a new concept that refines or unifies prior concepts. …most important learning is what happens, not the syntax of how that is specified. refinements preserve a player’s understanding of what happens. there are always many ways to specify, and those ways can only be distinguished when new behavior is added.
This work is motivated by the desire to increase the of software, both for games as well as interactive software more generally. We note that software systems can be generally decomposed into three sorts of parts: \begin{itemize}Base components (graphics rendering, networking, hardware drivers) that are not application specific and usually irrelevant to the user’s understanding of a particular system. - Code defining the software is arranged in a manner that is most conducive to learning about the totality of its behavior - When new features are to be added, modifications to existing code must be limited to refinement or unification
Languages for software engineering often focus on modularity, which can be regarded as a variant of the two points. Modularity assists software understanding by forcing decoupling of implementation choices from clients [cite 70s module paper]. Ideally, a module is understood by understanding its code along with the interfaces of any modules its code refers to (but not their code). Modules assist development by guiding the modifier to relevant parts of the code Software development relies on the following key phenomenon: when code is split into modules “well”, it generalizes to new tasks (modifications to be made for a new feature are limited to a small set of modules).
Faced with the task of developing open games, our criteria are somewhat more stringent at the cost of being less feasible to uphold for software at large. In particular, the second bullet point is very stringent. An example of a hypothetical system that trivially satisfies only the second point would be any “append only” programming language, where a codebase can only be modified by appending new code. New code would contain directives over older code to ignore, satisfying the letter of the rule if not the spirit. Such a system would entirely violate the first point, however: an append-only language would make no gaurantees that reading earlier code would have any benefit for understanding current code, as it might have been wholesale replaced.
We emphasize totality of behavior in the first point because games must be fully understood to be played. This is in contrast to usual technology development, where it is often seen as a merit if a system has been decomposed so that only small parts need be understood to be operated or modified.
competitive (dominion, MtG) coop (SI, gloomhaven, D&D) story oriented
no more, (! no less !) no opaque encoding scheme need indexicals for this
"creature gains +1/+1 for each spell cast this turn"
1 2 3 3' 4 5 6 7 8 9
1 8 9 6 45
creature C, *~turn [ cast C ],
---------------------
2 3
boost-attack C -> 1,
2 3'
boost-toughness C -> 1,
.
creature C, type C 'slime,
~turn = T, T [ ~cast
story +foo atoms never go away dynamic ... --- foo
atoms
are maintained
Our goal is to provide a language that is appropriate for direct encoding of game rules, including the calculation of game-state dependent options, rules that automatically trigger upon occurrence of particular patterns in the game state, rules that refer to recent events that have transpired, rules that can be resolved concurrently by different players, and rules that rely on linguistic indexicality to refer to dynamically changing context (such as the current turn, a particular game object implicitly denoted by its relevancy, or terms that change depending on where the rule is printed). We find that these difficulties can be handled by a fairly small set of concepts, the most fundamental being expressions that branch based on the result of a logical query. Queries are used in Partake to represent choice sets, branches in the episode tree, and patterns that guard rule triggers.
Because we use incremental database evaluation and timestamp tuples, it is trivial to rewind the last several inputs, so we can use speculative execution when designing a GUI, provide universal undo by construction, and
If we want a binary relation that relates a card to
its cost, we might name it card/cost.
If the cost is a static property, then we’ll use a normal tuple
card/cost Card Cost
, but if it’s something that dynamically
changes according to some aggregate we’ll use
card/cost Card -> Cost
. Static information about a card
is typically best attached to a static name for that card. Say we want a
card named
make sure to mention that SAD is used in the implementation of Partake.
Games as computation:
main concepts:
games are microcosms: they are object oriented and situational
games are designed to be predictable and manipulable by human minds. they are a great object of study because we want software with these properties, and we have basically no idea how to deliver it.
we want open games: we never know the totality of effects that might influence a particular episode
rules are simpler and more composable if they focus on what can happen instead of trying to unambiguously carve out what must happen
whatever cognitive affordances are exploited by game design patterns should be reflected in corresponding formalization choices (especially: board state vs temporal state vs declarative inference rules)
calling by name is brittle, recognizing situations and relationships less so
a rule is best thought of as a short narrative: it describes a series of events and choices
rules tend to describe what usually happens as simply as possible, with clarifications of edge cases handled later
a particular predicate refers to a particular subset of the board state and recent events
gameplay as determination: go from fully nondeterministic game to a single narrative
players learn from each other. they construct meaningful/relevant hypotheticals and both allowed and forbidden actions
(GUI) actions are ultimately simple and should be simple to perform
single declarative language to compose concepts about the current moment
simple language for reactively instantiating stories
AutoGUI