Cells and values - makingthematrix/gailibrary GitHub Wiki
A Cell
is a basic component of GAI. It may model an agent in the game or it may be a more abstract entity, helping GAI in the decision-making process.
struct Cell {
id: CellId
type: CellTypeId
values: Map<ValueId, Value>
refs: Vector<Cell>
lazyVals: Map<ValueId, Value>
variables: Map<ValueId, Value>
rnd: Rnd // random numbers generator
results: Map<ValueId, Value>
}
Cellular automata emphasize immutable states. The results of computations are stored in a cache (the results
map) and the values
are replaced only at the end of the iteration. In theory it means that each function working on the cell can be run in parallel, since they don't interfere with each other's data. In practice sometimes this approach turns out to be too restrictive to be practical: sometimes it’s better to have a few small functions called in sequence than one big with all the functionality in it. Especially if it turns out that some of these small functions do not have to be called at all, but we will learn about that only after calling the ones before them. Please refer to paragraphs about lazy vals and variables to read what the hell am I talking about.
A Value
is usually a number or a simple data structure. All the value types I'm currently thinking about are listed below:
enum Value {
intValue: Int
floatValue: Double
state: State // actually an Int, but mathematical operations are not allowed
position: Position
rotation: Rotation
percent: Percent // an Int in the range <0-100>
date: Date
}
Position
is an alias for a 3D point. Whatever the implementation, I'm mainly interested in having two methods:
fn equals(other: Point): Boolean
fn distance(other: Point): Float
And that’s it. Generally the only purpose of a point is to distinguish one location from another, and to let us compute the distance between them. How they differ exactly is an implementation detail.
A Rotation
is a mathematical vector of length 1.0, but „vectors” have a different meaning in programming languages, so I decided to use another name. A Rotation(dx, dy, dz)
is a triple of floats in the range <-1.0, 1.0> and they have to be normalized: (dx)^2 + (dy)^2 + (dz)^2 = 1
. Just as Position
, the exact implementation is not important right now.
In the future I might expand the list of types available as Value
s, but I’m pretty sure I want it to be a sealed list of primitives and very simple data structures (points, math vectors). If you need to use more complex data types in your cells, especially collections, consider instead creating additional cells of a special type and referencing them in the main cell. This approach is more idiomatic. A cell does not necessarily have to be a 1-to-1 representation of an object in the game. It might as well as an abstract entity connected to another cell and providing it with additional functionality.
There’s one special cell, World
, of a special type, also World
. (Actually, I could think later about some special API for singleton cells). This cell is processed as the first cell in the iteration, and all other cells have references to it by default. It contains all values considered global. For example, it may contain the lazy val for the player being in the room.