Documentation ¶
Overview ¶
Package game - in concert with packages events and ai - implements the game simulation.
Index ¶
- Constants
- Variables
- func CloseSave()
- func LoadSave(id string) error
- func LoadSaveInfo() error
- func LoadTileRefs()
- func LoadValue(key string) io.Reader
- func NewPath(p1, p2 util.Point, m *CityMap, ret *Path)
- func NewSave(name string, mods []string) error
- func SaveTileRefs()
- func SaveValue(key string, value []byte)
- type AIModel
- type Actor
- func (a *Actor) ActSpeed() float64
- func (a *Actor) AddItemToInventory(i *Item) bool
- func (a *Actor) Damage(min, max float64, t time.Time, from *Actor) float64
- func (a *Actor) DropCorpse(m *CityMap)
- func (a *Actor) RemoveItemFromInventory(item *Item) bool
- func (a *Actor) TargetedDamage(which BodyPartCode, min, max float64, t time.Time, from *Actor) float64
- func (a *Actor) UnWearItem(i *Item) bool
- func (a *Actor) UnWieldItem(i *Item) bool
- func (a *Actor) WalkSpeed() float64
- func (a *Actor) WearItem(i *Item) string
- func (a *Actor) WieldItem(i *Item) string
- func (a *Actor) Write(w io.Writer)
- type ActorGen
- type BodyPart
- type BodyPartCode
- type Chunk
- func (c *Chunk) CanStep(a *Actor, p util.Point) (bool, bool)
- func (c *Chunk) PlaceActor(a *Actor, climbing bool) (bool, bool)
- func (c *Chunk) PlaceActorRelative(a *Actor)
- func (c *Chunk) PlaceItem(i *Item, force bool) bool
- func (c *Chunk) PlaceItemRelative(i *Item)
- func (c *Chunk) Read(r io.Reader)
- func (c *Chunk) RebuildBitmaps()
- func (c *Chunk) RemoveActor(a *Actor)
- func (c *Chunk) RemoveItem(i *Item)
- func (c *Chunk) Unload()
- func (c *Chunk) Write(w io.Writer)
- type ChunkFlags
- type ChunkGen
- type CityMap
- func (m *CityMap) ActorAt(p util.Point) *Actor
- func (m *CityMap) ActorsWithin(b util.Rect) []*Actor
- func (m *CityMap) CanSeePlayerFrom(p util.Point) bool
- func (m *CityMap) EnsureLoaded(r util.Rect)
- func (m *CityMap) FullSave()
- func (m *CityMap) GetActors(b util.Rect) []*Actor
- func (m *CityMap) GetChunk(p util.Point) *Chunk
- func (m *CityMap) GetChunkFromMapPoint(p util.Point) *Chunk
- func (m *CityMap) GetTile(p util.Point) *TileDef
- func (m *CityMap) ItemsAt(p util.Point) []*Item
- func (m *CityMap) ItemsWithin(b util.Rect) []*Item
- func (m *CityMap) LoadBitmaps()
- func (m *CityMap) LoadChunk(c *Chunk, now time.Time)
- func (m *CityMap) LoadCityPlan()
- func (m *CityMap) LoadDynamicData()
- func (m *CityMap) MakeVisibilitySets(b util.Rect)
- func (m *CityMap) PlaceActor(a *Actor, climbing bool)
- func (m *CityMap) PlaceItem(i *Item, force bool) bool
- func (m *CityMap) PlayerCanClimb(d util.Direction) bool
- func (m *CityMap) PlayerTookTurn(d time.Duration)
- func (m *CityMap) Read(r io.Reader)
- func (m *CityMap) RemoveActor(a *Actor)
- func (m *CityMap) RemoveItem(i *Item)
- func (m *CityMap) SaveBitmaps()
- func (m *CityMap) SaveCityPlan()
- func (m *CityMap) SaveDynamicData()
- func (m *CityMap) StepActor(a *Actor, climbing bool, d util.Direction) (bool, bool)
- func (m *CityMap) StepPlayer(climbing bool, d util.Direction) bool
- func (m *CityMap) Update(p util.Point, d time.Duration)
- func (m *CityMap) Write(w io.Writer)
- type DMap
- type DMapRank
- type Evaluator
- type GenStatement
- type Item
- type ItemCreator
- type ItemGen
- type ItemStatement
- type Logger
- type Path
- type Player
- type SaveInfo
- type TileCrossRef
- type TileDef
- type TileGen
- type TileRef
Constants ¶
const ( BodyPartHead BodyPartCode = 0 BodyPartBody BodyPartCode = 1 BodyPartArms BodyPartCode = 2 BodyPartLegs BodyPartCode = 3 BodyPartHand BodyPartCode = 4 BodyPartFeet BodyPartCode = 5 BodyPartCount int = int(BodyPartFeet) + 1 BodyPartEars BodyPartCode = 6 BodyPartEyes BodyPartCode = 7 BodyPartNeck BodyPartCode = 8 BodyPartElbow BodyPartCode = 9 BodyPartWrist BodyPartCode = 10 BodyPartFinger BodyPartCode = 11 BodyPartWaist BodyPartCode = 12 BodyPartKnees BodyPartCode = 13 BodyPartAnkle BodyPartCode = 14 BodyPartSoles BodyPartCode = 15 BodyPartBack BodyPartCode = 16 BodyPartEquipmentSlotCount int = int(BodyPartBack) + 1 )
const ( ChunkWidth int = 16 // Width of a chunk in tiles ChunkHeight int = 16 // Height of a chunk in tiles )
const ( CityMapWidth int = 660 // Width of a city map in chunks CityMapHeight int = 660 // Height of a city map in chunks )
const ( MaxPath int = 64 // Maximum number of steps along a path, we keep this short to short-circuit broad explorations MaxPathNodes int = (MaxPath*2 + 1) * (MaxPath*2 + 1) // Maximum number of path nodes that could possibly be in memory at one time )
Variables ¶
var ActorDefs = map[string]*Actor{}
Map of all actor definitions from all mods.
var ActorGens = map[string]ActorGen{}
ActorGens is the mapping of generator names to objects.
var BodyPartInfo = []struct { Name string DamageMod float64 }{ {"Head", 2.5}, {"Body", 0.5}, {"Arms", 1.0}, {"Legs", 1.0}, {"Hand", 1.5}, {"Feet", 1.5}, }
BodyPartInfo is a mapping of BodyPartCode to static information about a body part.
ExecuteItemUpdateEvent is the Item update event executer.
var GetChunkGen func(string) ChunkGen
GetChunkGen is the ChunkGen getter.
var ItemDefs = map[string]*Item{}
Item definitions
var ItemGens = map[string]ItemGen{}
ItemGens is the mapping of generator names to objects.
var NewAIModel func(string) AIModel
NewAIModel should return a new AI model by template name.
var NewAIModelFromReader func(io.Reader) AIModel
NewAIModelFromReader reads AI model state information from r and constructs a new AIModel ready for use.
var Saves = map[string]*SaveInfo{}
Saves is the map of all save information.
var TileCrossRefForRef = map[TileRef]TileCrossRef{}
tileCrossRefForRefs is a map of tileCrossRef associated TileRefs.
var TileCrossRefs []*TileDef
TileCrossRefs indexes all valid tileCrossRef values in the save database to the tile defs.
var TileDefs []*TileDef
TileDefs is the global TileRef-to-*TileDef reference.
var TileGens = map[string]TileGen{}
TileGens is the mapping of generator names to objects.
var TileRefMap = map[TileCrossRef]string{}
TileRefMap is a map of tileCrossRef values to tile IDs.
var TileRefs = map[string]TileRef{}
TileRefs is the global string-to-TileRef reference.
Functions ¶
func NewPath ¶
NewPath calculates a shortest path from p1 to p2 considering the current walk-ability of each location with regard to m. The path is appended to ret. The A/A* path-finding algorithm used here is presented in the following article: https://theory.stanford.edu/~amitp/GameProgramming/AStarComparison.html
Types ¶
type AIModel ¶
type AIModel interface { // Act is responsible for taking the next action for the actor and returning // the duration until the next call to Act(). Act(*Actor, *CityMap) time.Duration // PeriodicUpdate is responsible for handling periodic updates. The passed // duration may be very long in the case of reloading a chunk from disk. // Periodic update functions are expected to execute in linear time no // matter how long the duration. PeriodicUpdate(*Actor, *CityMap, time.Duration) // Write writes the internal state of the model to the writer. Write(io.Writer) }
AIModel is the interface the actor AI models must implement.
type Actor ¶
type Actor struct { // Persistent values TemplateID string // Template ID Position util.Point // Current position on the map AIModel AIModel // AIModel for the actor NextThink time.Time // Time of the next think BodyParts [BodyPartCount]BodyPart // Status of all body parts Equipment [BodyPartEquipmentSlotCount]*Item // All items equipped to the body, if any Inventory []*Item // All items held in inventory, if any Weapon *Item // The item wielded as a weapon, if any // Reconstructed values AITemplate string // AI template name Name string // Descriptive name Rune string // Display rune Fg termui.Color // Display foreground color Bg termui.Color // Display background color Speed float64 // Number of seconds between steps at walking pace SightRange int // Distance this actor can see MinDamage float64 // Minimum damage done by normal attacks MaxDamage float64 // Maximum damage done by normal attacks IsPlayer bool // Only true for the player's actor // Transient values Dead bool // If true something has happened to this actor to cause death // contains filtered or unexported fields }
Actor represents a moving, thinking actor on the map.
func NewActorFromReader ¶
NewActorFromReader reads the actor information from r and returns a new Actor with this information.
func (*Actor) AddItemToInventory ¶
AddItemToInventory adds the item to the actor's inventory.
func (*Actor) Damage ¶
Damage calls TargetedDamage with a random body part weighted to hit probabilities. Returns the amount of damage done.
func (*Actor) DropCorpse ¶
DropCorpse drops a corpse item for this actor.
func (*Actor) RemoveItemFromInventory ¶
RemoveItemFromInventory removes the item from inventory, returning true on success.
func (*Actor) TargetedDamage ¶
func (a *Actor) TargetedDamage(which BodyPartCode, min, max float64, t time.Time, from *Actor) float64
TargetedDamage applies a random amount of damage in the range [min-max) to the indicated body part scaled as needed and makes updates as necessary. Returns the amount of damage done.
func (*Actor) UnWearItem ¶
UnWearItem takes off the item, returning true on success.
func (*Actor) UnWieldItem ¶
UnWieldItem drops the weapon, returning true on success.
func (*Actor) WearItem ¶
WearItem attempts to wear the item as clothing. On failure a string is returned describing why the action failed as a complete, punctuated sentence. On success an empty string is returned.
type ActorGen ¶
type ActorGen []string
ActorGen generates a single actor from a set of possibilities.
func (ActorGen) Generate ¶
Generate returns a pointer to the selected tile def after procedural generation.
func (*ActorGen) UnmarshalJSON ¶
type BodyPart ¶
type BodyPart struct { // Persistent Health float64 // Health between [0.0-1.0] BrokenUntil time.Time // When this body part will heal // Reconstituted values Which BodyPartCode // Indicates which body part we describe Broken bool // If true the body part is currently broken }
BodyPart encapsulates information about an actor's body part.
type BodyPartCode ¶
type BodyPartCode uint8
BodyPartCode is a code that indicates a player's body part.
func (*BodyPartCode) UnmarshalJSON ¶
func (c *BodyPartCode) UnmarshalJSON(in []byte) error
type Chunk ¶
type Chunk struct { Position util.Point // Position of the chunk on the city map in chunks Ref uint32 // Reference index for the chunk Bounds util.Rect // Bounds of the chunk Generator ChunkGen // The chunk generator responsible for procedural generation ChunkGenOffset util.Point // Offset from the top-left corner of the chunk generator Facing util.Facing // Facing of the chunk during generation Name string // Descriptive name of the chunk MinimapRune string // Rune to display on the minimap MinimapForeground termui.Color // Foreground color of the rune on the minimap MinimapBackground termui.Color // Background color of the rune on the minimap Flags ChunkFlags // Flags Loaded time.Time // Time this chunk was loaded, the zero value means it is not in memory Tiles []*TileDef // Tile matrix Items []*Item // All items within the chunk Actors []*Actor // All actors within the chunk HasSeen bitmap.Bitmap // Bitmap of all spaces that have been previously viewed by the player BlocksWalk bitmap.Bitmap // Bitmap of all spaces that are blocked for walking BlocksVis bitmap.Bitmap // Bitmap of all spaces that are blocked for visibility BlocksClimb bitmap.Bitmap // Bitmap of all spaces that can be climbed // contains filtered or unexported fields }
Chunk represents the smallest unit of city planning and contains the tiles, items and actors within its bounds.
func NewChunk ¶
NewChunk allocates and returns a new Chunk struct. Note that this struct does *not* have the Generator field set yet and all of the tile pointers are nil. See Load().
func (*Chunk) CanStep ¶
CanStep returns true if the location is valid for an actor to step. The second return value is true only if the first return value is false and the location allows climbing.
func (*Chunk) PlaceActor ¶
PlaceActor places the actor within the chunk. This is a no-op if the current position lies outside the chunk. If the climbing parameter is true the locations that allow climbing are also considered. The first return value is true if the actor can step on the location. The second return value is true only if the first return value is false and the location allowed climbing.
func (*Chunk) PlaceActorRelative ¶
PlaceActorRelative adds the actor to the chunk and adjusts the position from chunk-relative to absolute. This function always allows standing on climbable locations.
func (*Chunk) PlaceItem ¶
PlaceItem places the item within the chunk. This is a no-op if the item's current position lies outside the chunk.
func (*Chunk) PlaceItemRelative ¶
PlaceItemRelative adds the item to the chunk and adjusts the position from chunk-relative to absolute.
func (*Chunk) RebuildBitmaps ¶
func (c *Chunk) RebuildBitmaps()
RebuildBitmaps must be called after chunk load or generation in order to rebuild the walk and vis bitmap caches. The HasSeen bitmap is persistent.
func (*Chunk) RemoveActor ¶
RemoveActor removes the Actor from the chunk. This is a no-op if the current position lies outside the chunk.
func (*Chunk) RemoveItem ¶
RemoveItem removes the item from the chunk. This is a no-op if the item's current position lies outside the chunk.
type ChunkFlags ¶
type ChunkFlags uint8
ChunkFlag encodes various bit flags of a chunk.
const ( ChunkFlagsNone ChunkFlags = 0b00000000 // No flags enabled ChunkFlagsOccupied ChunkFlags = 0b00000001 // Chunk was explicitly placed during the city gen process )
type ChunkGen ¶
type ChunkGen interface { // Generate handles all initial procedural generation for the chunk Generate(*Chunk, *CityMap) // AssignStaticInfo inserts all of the non-procedurally generated bits into // the chunk, such as name and map rune. AssignStaticInfo(*Chunk) // GetID returns the unique ID of the generator. GetID() string }
ChunkGen is the interface all chunk generators must implement for the game library to interact with them.
type CityMap ¶
type CityMap struct { // Dynamic persistent data Player *Player // Player actor Now time.Time // Current in-game time // Static persistent data Chunks []*Chunk // The chunks of the map // Reconstructed values Bounds util.Rect // Bounds of the city map in chunks TileBounds util.Rect // Bounds of the city map in tiles // Working variables Visibility bitmap.Bitmap // Last visibility set calcualted for the player Remembered bitmap.Bitmap // Last remembered set calculated for the player BitmapBounds util.Rect // Bounds of the Visibility and Remembered bitmaps // contains filtered or unexported fields }
CityMap represents the entire world of the game in terms of which chunks go where.
func NewCityMap ¶
func NewCityMap() *CityMap
NewCityMap allocates and returns a new CityMap structure.
func (*CityMap) ActorsWithin ¶
ActorsWithin returns the items within the given bounds.
func (*CityMap) CanSeePlayerFrom ¶
CanSeePlayerFrom returns true if there is line of sight between the given point and the player.
func (*CityMap) EnsureLoaded ¶
EnsureLoaded ensures that all chunks in the area given in chunk coordinates have been generated and are loaded into memory.
func (*CityMap) FullSave ¶
func (m *CityMap) FullSave()
FullSave commits the entire working set to the current save database without freeing memory.
func (*CityMap) GetActors ¶
GetActors returns a slice of all of the actors within the given bounds. The returned slice is reused by subsequent calls to GetActors().
func (*CityMap) GetChunk ¶
GetChunk returns the correct chunk for the given absolute tile point or nil if the point is out of bounds.
func (*CityMap) GetChunkFromMapPoint ¶
GetChunkFromMapPoint returns the chunk definition at the given map location or nil if out of bounds. Note the point is in chunks not tiles.
func (*CityMap) GetTile ¶
GetTile returns the tile at the given absolute tile point or nil if the point is out of bounds.
func (*CityMap) ItemsWithin ¶
ItemsWithin returns the items within the given bounds. Subsequent calls to ItemsWithin will re-use the same slice.
func (*CityMap) LoadBitmaps ¶
func (m *CityMap) LoadBitmaps()
LoadBitmaps loads all persistent bitmaps.
func (*CityMap) LoadChunk ¶
LoadChunk loads the passed-in chunk or generates it if needed. This function is cheap if the chunk is already in memory.
func (*CityMap) LoadCityPlan ¶
func (m *CityMap) LoadCityPlan()
LoadCityPlan loads the city plan from the current save database.
func (*CityMap) LoadDynamicData ¶
func (m *CityMap) LoadDynamicData()
LoadDynamicData loads top-level dynamic map data.
func (*CityMap) MakeVisibilitySets ¶
MakeVisibilitySets constructs bitmaps representing the current and remembered visibility of each position within the bounds relative to the player. This is a no-op if the bounds do not contain the player. Visibility sets are stored in Visibility and Remembered members.
func (*CityMap) PlaceActor ¶
PlaceActor adds the actor to the city at it's current location.
func (*CityMap) PlayerCanClimb ¶
PlayerCanClimb returns true if the player can climb in the given direction.
func (*CityMap) PlayerTookTurn ¶
PlayerTookTurn is responsible for updating the city map model for the given duration as well as anything else that should happen after the player's turn.
func (*CityMap) RemoveActor ¶
RemoveActor removes the actor from the city at it's current location.
func (*CityMap) RemoveItem ¶
RemoveItem removes the item from the city map.
func (*CityMap) SaveBitmaps ¶
func (m *CityMap) SaveBitmaps()
SaveBitmaps saves all persistent bitmaps.
func (*CityMap) SaveCityPlan ¶
func (m *CityMap) SaveCityPlan()
SaveCityPlan saves the city plan in the current save database.
func (*CityMap) SaveDynamicData ¶
func (m *CityMap) SaveDynamicData()
SaveDynamicData writes top-level dynamic map data.
func (*CityMap) StepActor ¶
StepActor attempts to move the actor in the given direction. The first return value is true if the actor was able to step on the location. The second return value is true only if the first return value is false and the actor successfully climbed to the location.
func (*CityMap) StepPlayer ¶
StepPlayer attempts to move the player's actor in the given direction returning true on success.
type DMap ¶
type DMap struct { Bounds util.Rect // Bounds of the map relative to the city map Map []DMapRank // Value map }
DMap implements a "Dijkstra Map" as described by Brian Walker - the developer of Brouge - in this article: https://www.roguebasin.com/index.php/The_Incredible_Power_of_Dijkstra_Maps
func (*DMap) Calculate ¶
Calculate calculates the Dijkstra map based on the current set of goals. In order for Calculate to have meaningful output, call Clear() first and SetGoal() one or more times beforehand.
func (*DMap) Clear ¶
func (m *DMap) Clear()
Clear sets the rank of all points on the map to DMapRankMax.
func (*DMap) Relocate ¶
Relocate changes the position of the top-left corner of the bounds without changing the area of the bounds.
func (*DMap) RollDown ¶
RollDown returns a randomly selected rank from the set of lowest neighbor ranks. If p is out of bounds p is returned and the direction returned will be util.DirectionInvalid.
type DMapRank ¶
type DMapRank uint16
DMapRank represents the rank of a position in the Dijkstra map.
type Evaluator ¶
type Evaluator interface { // Evaluate evaluates a single expression executing its function. Evaluate(*Chunk, util.Point, time.Time) }
Evaluator evaluates a single expression executing its generation function.
type GenStatement ¶
type GenStatement []Evaluator
GenStatement is a list of expressions to run on a single position in the chunk at generation time. The text format of an expression is as follows: exp[;exp]... Where: exp = (tile_exp|item_exp)|(item_exp@XinY) Where: tile_name is the name of a tile or tile generator item_name is the name of an item or item generator Y is the bounded maximum of the half-open range [0-Y) X is the value of the random roll [0-Y) below which the item will appear
func (*GenStatement) UnmarshalJSON ¶
func (s *GenStatement) UnmarshalJSON(in []byte) error
func (*GenStatement) Validate ¶
func (s *GenStatement) Validate() error
Validate validates the generator statement.
type Item ¶
type Item struct { // Persistent values TemplateID string // Template ID Position util.Point // Current position on the map LastUpdate time.Time // Time of the last call to event update SArg string // Generic string argument TArg time.Time // Generic time argument Inventory []*Item // Container contents if any // Reconstructed values Events map[string]string // Map of event names to event handler names Name string // Descriptive name Rune string // Display rune Fg termui.Color // Display foreground color Bg termui.Color // Display background color BlocksVis bool // If true this item blocks visibility BlocksWalk bool // If true this item blocks walking Climbable bool // If true this item may be climbed over Destroyed bool // If true something has happened to this item to cause it to be destroyed, it will be removed from the world at the end of the next update cycle Fixed bool // If true the item cannot be moved at all Wearable bool // If true this item can be worn as a piece of clothing WornBodyPart BodyPartCode // Code of the body part this item is worn on Weapon bool // If true this item can be wielded as a weapon WeaponMinDamage float64 // Minimum damage bonus when using this item as a weapon WeaponMaxDamage float64 // Maximum damage bonus when using this item as a weapon Container bool // If true this item contains other items Contents []string // Container content item statements if any // contains filtered or unexported fields }
Item is any dynamic item within the world, anything that can be used, taken, destroyed or built.
func NewItemFromReader ¶
NewItemFromReader reads the item information from r and returns a new Item with this information.
func (*Item) AddItem ¶
AddItem adds the item to this container's content if it is a container, returning true on success.
func (*Item) CacheContentStatements ¶
CacheContentStatements generates the cache of content statements. This must be called on all item prototypes after item and item gen loading is complete.
func (*Item) RemoveItem ¶
RemoveItem removes the item from the container's content, returning true on success.
type ItemCreator ¶
type ItemCreator interface { // CreateItem generates the new item and returns it if any. CreateItem(time.Time) *Item }
ItemCreator generates new items based on the expression.
type ItemGen ¶
type ItemGen []string
ItemGen generates a single item from a set of possibilities.
func (*ItemGen) UnmarshalJSON ¶
type ItemStatement ¶
type ItemStatement []ItemCreator
ItemStatement is a generation statement that is only allowed to produce items.
func (ItemStatement) Evaluate ¶
func (s ItemStatement) Evaluate(t time.Time) *Item
Evaluate evaluates each expression in the statement in order and returns the first item created.
func (*ItemStatement) UnmarshalJSON ¶
func (s *ItemStatement) UnmarshalJSON(in []byte) error
type Logger ¶
Logger implementers can consume colored log messages.
var Log Logger
Log is the global log consumer.
type Player ¶
type Player struct {
Actor
}
Player implements the player's special actor.
func NewPlayerFromReader ¶
NewPlayerFromReader reads the player information from r and returns a new player with this information.
type SaveInfo ¶
type SaveInfo struct { ID string // Save ID, save path is saves/[ID]/ Name string // Human-readable Mods []string // List of mods used when creating the save }
SaveInfo holds metadata about a save.
type TileCrossRef ¶
type TileCrossRef uint16
TileCrossRef is the value we write to the save database for persisting tile selections. See tileCrossRefs.
type TileDef ¶
type TileDef struct { BackRef TileRef // The TileRef that indexes this TileDef within TileDefs, used to accelerate saving ID string // The unique ID of the tile Name string // Descriptive name of the tile Rune string // Map display rune Fg termui.Color // Foreground display color Bg termui.Color // Background display color BlocksVis bool // If true this tile blocks visibility BlocksWalk bool // If true this tile blocks walking Climbable bool // If true this tile may be (c)limbed over even if it blocks walk }
TileDef represents all of the data associated with a single tile.