gorl

package module
v0.0.0-...-6cd614a Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 25, 2016 License: BSD-3-Clause Imports: 9 Imported by: 0

README

GoRL

GoRL is a (somewhat) generic roguelike toolkit for Go. It is intended mostly for development of Sticks and Stones, but should be generally useful for various roguelikes. It is written entirely in Go and utilizes termbox-go for display so it should be usable on all major platforms.

Features

  • Game Model
    • Simple but powerful Entity-Component system
    • Graph based maps
    • Delta clock for Entity scheduling
  • Procedural Generation
    • World generation
    • Maze generation
    • Dungeon generation
    • Data-driven name generator
  • AI
    • Graph-based pathfinding
    • Dijkstra fields
    • Behavior trees (forthcoming)
  • Dice
    • Fast and high quality xorshift1024 random source
    • Roguelike-specific RNG functions
  • UI
    • Terminal abstraction based on termbox-go
    • Composable terminal-based UI elements
  • FoV
    • Extremely fast field of view computation
    • Fast line of sight checks which match field of view

Documentation

Overview

Package gorl is a (somewhat) generic roguelike toolkit for Go.

Index

Constants

View Source
const (
	ColorRed          = Color(termbox.ColorRed)
	ColorBlue         = Color(termbox.ColorBlue)
	ColorCyan         = Color(termbox.ColorCyan)
	ColorBlack        = Color(termbox.ColorBlack)
	ColorGreen        = Color(termbox.ColorGreen)
	ColorWhite        = Color(termbox.ColorWhite)
	ColorYellow       = Color(termbox.ColorYellow)
	ColorMagenta      = Color(termbox.ColorMagenta)
	ColorLightRed     = Color(termbox.ColorRed | termbox.AttrBold)
	ColorLightBlue    = Color(termbox.ColorBlue | termbox.AttrBold)
	ColorLightCyan    = Color(termbox.ColorCyan | termbox.AttrBold)
	ColorLightBlack   = Color(termbox.ColorBlack | termbox.AttrBold)
	ColorLightGreen   = Color(termbox.ColorGreen | termbox.AttrBold)
	ColorLightWhite   = Color(termbox.ColorWhite | termbox.AttrBold)
	ColorLightYellow  = Color(termbox.ColorYellow | termbox.AttrBold)
	ColorLightMagenta = Color(termbox.ColorMagenta | termbox.AttrBold)
)

Color constants for use with ColorChar.

Variables

View Source
var KeyMap = map[Key]Offset{
	'h': {-1, 0}, '4': {-1, 0},
	'l': {1, 0}, '6': {1, 0},
	'k': {0, -1}, '8': {0, -1},
	'j': {0, 1}, '2': {0, 1},
	'u': {1, -1}, '9': {1, -1},
	'y': {-1, -1}, '7': {-1, -1},
	'n': {1, 1}, '3': {1, 1},
	'b': {-1, 1}, '1': {-1, 1},
	'.': {0, 0}, '5': {0, 0},
}

KeyMap stores default directional Key values. This dictionary can be edited to affect any core functions which require knowledge of directional keys.

Functions

func Abs

func Abs(x int) int

Abs returns the absolute value of x.

func Clamp

func Clamp(min, val, max int) int

Clamp limits a value to a specific range.

func FoV

func FoV(origin *Tile, radius int) map[Offset]*Tile

FoV uses a simple heuristic to approximate shadowcasting field of view calculation. The Offsets in the resulting field are relative to the given origin. The Tile objects provide the absolute Offsets if needed. The origin is included in the field of view.

func GenFence

func GenFence(tiles []*Tile, f GenTileMutate)

GenFence mutates any Tile which is not 8-connected.

func GenTransform

func GenTransform(tiles []*Tile, f GenTileMutate)

GenTransform applies a transformation to an entire map.

func Max

func Max(x, y int) int

Max returns the maximum of x and y.

func Min

func Min(x, y int) int

Min returns the minimum of x and y.

func Mod

func Mod(x, y int) int

Mod returns x modulo y (not the same as x % y, which is remainder).

func RandBetaBin

func RandBetaBin(n int, alpha, beta float64) int

RandBetaBin generates a random Beta-Binomial distributed int. It panics if n < 0, alpha <= 0 or beta <= 0. Sampling is done using the Pólya Urn Scheme to conduct n Bernoulli trials. The number of successful trials is returned.

func RandBool

func RandBool() bool

RandBool returns true with probability .5 and false otherwise.

func RandChance

func RandChance(p float64) bool

RandChance returns true with the given probability. The probability p should be in [0, 1], but Chance will simple return false if p < 0 or true if p > 1.

func RandFloat

func RandFloat() float64

RandFloat returns, as a float64, a pseudo-random number in [0.0,1.0).

func RandGauss

func RandGauss(mu, sigma float64) float64

RandGauss generates a random Gaussian distributed float64 with a mean of mu and a standard deviation of sigma.

func RandInt

func RandInt() int

RandInt returns a non-negative pseudo-random int.

func RandIntn

func RandIntn(n int) int

RandIntn returns, as an int, a non-negative pseudo-random number in [0,n). It panics if n <= 0.

func RandPerm

func RandPerm(n int) []int

RandPerm returns, as a slice of n ints, a pseudo-random permutation of the integers [0,n).

func RandPoisson

func RandPoisson(lambda float64) int

RandPoisson generates a random Poisson distributed int. It panics if lambda <= 0. For values of lambda <= 500, we use the inverse transform sampling algorithm given by Luc Devroye in "Non-Uniform Random Variate Generation". This algorithm becomes unstable for values of lambda > 500, so for these values we approximate the Poisson with a truncated sample from a Guassian distribution.

func RandRange

func RandRange(min, max int) int

RandRange returns, as an int, a pseudo-random number in [min, max].

func RandRoll

func RandRoll(y int) int

RandRoll returns the result of rolling a y-sided die.

func RandSeed

func RandSeed(seed int64)

RandSeed uses the provided seed value to initialize the Source to a deterministic state. If Seed is not called, the generator behaves as if seeded by Seed(time.Now().UnixNano()).

func RandSymBetaBin

func RandSymBetaBin(n int, concentration float64) int

RandSymBetaBin generates a random Beta-Binomial distributed int using a symetric Beta distribution. It panics if n < 0 or concentration <= 0. Sampling is done using the Pólya Urn Scheme to conduct n Bernoulli trials. The number of successful trials is returned.

func RandTriangular

func RandTriangular(a, c, b float64) float64

RandTriangular generates a random triangular distributed float64. It panics if the left bound a is greater than the mode c or the right bound b is less than the mode c. The sample is generated using the inversion method using the fact that if u is uniform [0, 1] variate then F^-1(u) will be triangular on [0, 1]. The triangular distribution is typically used when there is only limited sample data, but the bounds are known.

func RandXdY

func RandXdY(x, y int) int

RandXdY returns the result of rolling x y-sided dice.

func TermClear

func TermClear()

TermClear erases everything in the internal termbox buffer. No changes are made on screen until TermRefresh is called.

func TermDone

func TermDone()

TermDone deinitializes the termbox library. Typically a call to TermDone is deferred immediately after a successful call to TermInit.

func TermDraw

func TermDraw(x, y int, g Glyph)

TermDraw places a Glyph into the internal termbox buffer at the given location. No changes are made on screen until TermRefresh is called.

func TermInit

func TermInit() error

TermInit initializes the termbox library. TermInit should be called before any other Term functions are used. After a successful call to TermInit, a call to TermDone should be deferred.

func TermMustInit

func TermMustInit()

TermMustInit is like TermInit, except that any errors result in a panic.

func TermRefresh

func TermRefresh()

TermRefresh ensures that the screen reflects the internal buffer state.

Types

type ActBehavior

type ActBehavior func() BehaviorState

ActBehavior is a leaf Behavior which should perform an action on the target Entity. The return value of the underlying function is used as the state of the Behavior. While any BehaviorState may be returned by the Action, typically the underlying function should only return SuccessState, FailureState, RunningState, or DoneState.

func (ActBehavior) Reset

func (b ActBehavior) Reset()

Reset is a noop for the ActBehavior.

func (ActBehavior) Run

func (b ActBehavior) Run() BehaviorState

Run performs the ActBehavior.

type ActEvent

type ActEvent struct{}

ActEvent is an Event triggering an Entity action.

type Behavior

type Behavior interface {
	Reset()
	Run() BehaviorState
}

Behavior is a node in a behavior tree. It could be a composite Behavior, a Behavior decorator, or a leaf node in the tree.

func ConcurrentBehavior

func ConcurrentBehavior(children ...Behavior) Behavior

ConcurrentBehavior is a composite Behavior which runs each child in order but concurrently (not in parallel though). In other words, each call to Run will result in each child being run. ConcurrentBehavior immediately fails if any of its children fail, but succeeds if all of its children succeed. If any of the child Behavior are still running, then concurrent will continue to rerun all child Behaviors, which often does nothing for children in the done state.

func InverterBehavior

func InverterBehavior(child Behavior) Behavior

InverterBehavior is a Behavior decorator that inverts the success and fail states. Any other state, including running and done are simply returned.

func RandomBehavior

func RandomBehavior(children ...Behavior) Behavior

RandomBehavior is a composite Behavior which runs each child in random order. It succeeds if any of its children succeed, and fails if all of its children fail. It is akin to the 'or' operator for Behavior, but with randomized order.

func RepeatingBehavior

func RepeatingBehavior(child Behavior) Behavior

RepeatingBehavior is a Behavior decorator that repeatedly runs the child Behavior until it fails. Upon completion (i.e. the failure of the child), the RepeatingBehavior succeeds.

func SelecteBehavioror

func SelecteBehavioror(children ...Behavior) Behavior

SelecteBehavioror is a composite Behavior which runs the children in order. SelecteBehaviorors immediately succeed if any of of its children run successfully, and fails if all of its children fail. It is akin to the 'or' operator for Behavior.

func SequenceBehavior

func SequenceBehavior(children ...Behavior) Behavior

SequenceBehavior is a composite Behavior which runs the children in order. SequenceBehaviors succeeds if all the children run successfully, but immediately fails if any of its children fail. It is akin to the 'and' operator for Behavior.

type BehaviorCondition

type BehaviorCondition func() bool

BehaviorCondition is a leaf Behavior which can only succeed or fail. It succeeds if the underlying condition is true, and fails otherwise.

func (BehaviorCondition) Reset

func (b BehaviorCondition) Reset()

Reset is a noop for the BehaviorCondition.

func (BehaviorCondition) Run

Run performs the BehaviorCondition.

type BehaviorState

type BehaviorState uint8

BehaviorState indicates the result of running a Behavior.

const (
	SuccessState BehaviorState = iota
	FailureState
	RunningState
	DoneState
)

BehaviorState constants used to indicate the result of running a Behavior.

type BumpEvent

type BumpEvent struct {
	Bumped Entity
}

BumpEvent is an Event in which one Entity bumps another.

type Camera

type Camera struct {
	Radius int
	// contains filtered or unexported fields
}

Camera is a Component which enables an Entity to respond to FoVEvent and LoSEvent.

func (*Camera) Process

func (c *Camera) Process(v Event)

Process implements Component for Camera.

type CameraWidget

type CameraWidget struct {
	Window
	Camera Entity
}

CameraWidget is a Widget which displays an Entity field of view on screen.

func NewCameraWidget

func NewCameraWidget(x, y, w, h int, camera Entity) *CameraWidget

NewCameraWidget creates a new CameraWidget with the given camera Entity.

func (*CameraWidget) Update

func (w *CameraWidget) Update()

Update draws the camera field of view on screen.

type CollideEvent

type CollideEvent struct {
	Obstacle *Tile
}

CollideEvent is an Event in which an Event collides with a Tile obstacle.

type Color

type Color uint16

Color represents the color of a Glyph

type Component

type Component interface {
	Process(Event)
}

Component processes Events for an Entity.

func BehaviorTree

func BehaviorTree(b Behavior) Component

BehaviorTree is a Component which runs a Behavior on an Act Event.

type ComponentFunc

type ComponentFunc func(Event)

ComponentFunc is function which implements Component.

func (ComponentFunc) Process

func (c ComponentFunc) Process(v Event)

Process implements Component for ComponentFunc

type ComponentSlice

type ComponentSlice []Component

ComponentSlice is an Entity which is a slice of Components.

func (*ComponentSlice) AddComponent

func (e *ComponentSlice) AddComponent(c Component)

AddComponent appends a Component to the ComponentSlice.

func (ComponentSlice) Handle

func (e ComponentSlice) Handle(v Event)

Handle implements Entity for ComponentSlice by sending an Event to each Component for processing in order.

type DeltaClock

type DeltaClock struct {
	// contains filtered or unexported fields
}

DeltaClock implements a data structure which allows for fast scheduling. The DeltaClock is essentially a linked list in which each node stores a collection of Entity events, and a delta (in time) until the next node. Since each node stores the time until the next node, the total time until any one node is the result of the sum of the deltas of all the previous nodes. Consequently, advancing the clock can be done in O(1) time. Adding new events can be done in O(n) time, where n is the number of nodes (not the number of events!).

func NewDeltaClock

func NewDeltaClock() *DeltaClock

NewDeltaClock creates an empty DeltaClock.

func (*DeltaClock) Advance

func (c *DeltaClock) Advance() map[Entity]struct{}

Advance returns the next set of Entity scheduled. If all Events have been removed from the next delta, then the set will be empty. If no deltas are remaining, then the result is nil. The Entity to delta mapping is left unchanged, so each Entity in the returned Entity set may still be unscheduled or rescheduled.

func (*DeltaClock) Delta

func (c *DeltaClock) Delta(e Entity) (delta float64, ok bool)

Delta returns the schedule delta for an Entity. The ok bool indicates whether the Entity was actually scheduled or not.

func (*DeltaClock) NewScheduler

func (c *DeltaClock) NewScheduler(e Entity, offset float64) Component

NewScheduler creates a Component which responds to TriggerSchedule and TriggerUnschedule Event for the given Entity.

func (*DeltaClock) Schedule

func (c *DeltaClock) Schedule(e Entity, delta float64)

Schedule adds an Entity to the queue at the given delta. Note that the delta is split into its integer and fractional part. The integer part is used to determine the amount of delay, while the fractional part is only used to ensure a unique scheduling delta. If the Entity was previous scheduled, it will be unscheduled from the previous delta.

As an example, suppose we repeatedly schedule event A with deltas of 1, event B with deltas of 1.5, and event C with deltas of 2. It is *not* the case that A will fire 3 times for every 2 times B fires. Instead, both A and B will fire at the same rate, but A will always go first as it has a lower fractional part in its delta. It *is* the case that A and B will fire twice as often as C.

func (*DeltaClock) Tick

func (c *DeltaClock) Tick()

Tick advances the clock, and sends an ActEvent to each of the Entity in the next delta. No reschedules are made, so the Entity actions should include a call to Schedule if needed.

func (*DeltaClock) Unschedule

func (c *DeltaClock) Unschedule(e Entity)

Unschedule removes an Entity from the queue. If an Entity is in a delta which has already been advanced, it will be removed from that delta. If the Entity is not in a delta, no action is taken.

type Entity

type Entity interface {
	Handle(Event)
}

Entity is a single game object represented as a collection of Component.

type Event

type Event interface{}

Event is a message sent to an Entity.

type FoVEvent

type FoVEvent struct {
	FoV map[Offset]*Tile
}

FoVEvent is an Event querying an Entity for a field of view.

type GenTile

type GenTile func(o Offset) *Tile

GenTile generates Tile for various map generators. The typical use case is to wrap other GenTile types for use with NewTileGrid.

type GenTileFloat

type GenTileFloat func(o Offset, h float64) *Tile

GenTileFloat generates Tiles from float64 values.

type GenTileMutate

type GenTileMutate func(*Tile)

GenTileMutate mutates extisting Tiles to modify existing maps.

type Glyph

type Glyph interface {
	Ch() rune
	Fg() Color
}

Glyph pairs a rune with a color.

func Char

func Char(ch rune) Glyph

Char creates a white Glyph with the given rune.

func ColoredChar

func ColoredChar(ch rune, fg Color) Glyph

ColoredChar creates a Glyph with the given rune and Color.

type Key

type Key rune

Key represents a single keypress.

const (
	KeyEsc   Key = Key(termbox.KeyEsc)
	KeyEnter Key = Key(termbox.KeyEnter)
	KeyCtrlC Key = Key(termbox.KeyCtrlC)
	KeyPgup  Key = Key(termbox.KeyPgup)
	KeyPgdn  Key = Key(termbox.KeyPgdn)
)

Key constants which normally require escapes.

func TermGetKey

func TermGetKey() Key

TermGetKey returns the next keypress. It blocks until there is one.

type LoSEvent

type LoSEvent struct {
	Target  *Tile
	Visible bool
}

LoSEvent is an Event querying an Entity whether a Tile is in line of sight.

type LogEvent

type LogEvent struct {
	Msg string
}

LogEvent is an Event requesting that a message be logged.

func Log

func Log(s string, args ...interface{}) *LogEvent

Log applies the gorl log formating language to create a LogEvent.

The format specifiers include the following:

%s - subject
%o - object
%v - verb
%x - literal

Additionally, verb literals may be included using the form <verb>.

Each format specifier can be mapped to any arbitrary value, and is converted to a string by the fmt package. Consequently, format values should probably implement the fmt.Stringer interface to ensure that the values are correctly represented in the formatted string.

Example usage:

Fmt("%s <hit> %o", hero, bear) yields "You hit the bear."
Fmt("%s %v %o", tiger, verb, hero) yields "The saber-tooth slashes you."
Fmt("%s <hit> %o!", tiger, rabbit) yields "The saber-tooth hits the rabbit!"
Fmt("%s %v %o?", bear, verb, bear) yields "The bear hits itself?"
Fmt("%s <laugh>", unique) yields "Gorp laughs."

Note that if the String conversion for a value is "you" so that the formatter knows which grammatical-person to use. Named monsters should have string representations which are capitalized so the formatter knows not to add certain articles to the names.

Also note that if no ending punctuation is given, then a period is added automatically. The sentence is also capitalized if was not already.

type LogWidget

type LogWidget struct {
	Window
	// contains filtered or unexported fields
}

LogWidget is a Widget which stores and displays log messages. LogWidget is also a Component which accepts LogEvent.

func NewLogWidget

func NewLogWidget(x, y, w, h int) *LogWidget

NewLogWidget creates a new empty LogWidget.

func (*LogWidget) Log

func (w *LogWidget) Log(msg string)

Log places a message in the LogWidget cache.

func (*LogWidget) NewLogger

func (w *LogWidget) NewLogger(condition func() bool) Component

NewLogger creates a Component which responds to LogEvent whenever the condtion returns true.

func (*LogWidget) Process

func (w *LogWidget) Process(v Event)

Process implements Component for LogWidget.

func (*LogWidget) Update

func (w *LogWidget) Update()

Update draws the cached log messages on screen.

type MoveEvent

type MoveEvent struct {
	Dest *Tile
}

MoveEvent is an Event triggering an Entity move to a new Tile.

type NameEvent

type NameEvent struct {
	Name string
}

NameEvent is an Event querying an Entity for its name.

type OccupyEvent

type OccupyEvent struct {
	Occupant Entity
}

OccupyEvent is an Event informing about a new Entity occupant.

type Offset

type Offset struct {
	X, Y int
}

Offset stores a 2-dimensional int vector.

func RandDelta

func RandDelta() Offset

RandDelta returns an Offset with each value in [-1, 1].

func RandOffset

func RandOffset(cols, rows int) Offset

RandOffset returns an Offset within the given bounds.

func (Offset) Add

func (o Offset) Add(a Offset) Offset

Add returns the result of adding another Offset to this one.

func (Offset) Chebyshev

func (o Offset) Chebyshev() int

Chebyshev returns the L_inf distance off the Offset.

func (Offset) Euclidean

func (o Offset) Euclidean() float64

Euclidean returns the L_2 distance off the Offset.

func (Offset) Manhattan

func (o Offset) Manhattan() int

Manhattan returns the L_1 distance off the Offset.

func (Offset) Neg

func (o Offset) Neg() Offset

Neg returns the result of negating the Offset.

func (Offset) Scale

func (o Offset) Scale(s int) Offset

Scale returns the result of multiplying the Offset by an integer scalar.

func (Offset) Sub

func (o Offset) Sub(a Offset) Offset

Sub returns the result of subtracting another Offset from this one.

type RenderEvent

type RenderEvent struct {
	Render Glyph
}

RenderEvent is an Event querying an Entity for a Glyph to render.

type ScheduleEvent

type ScheduleEvent struct {
	Delta float64
}

ScheduleEvent is an Event triggering an Entity scheduling.

type Screen

type Screen []Widget

Screen is a collection of Widget.

func (Screen) Update

func (s Screen) Update()

Update runs Update on each ScreenElement of the Screen.

type TermState

type TermState interface {
	Restore()
}

TermState captures the state of the internal termbox buffer so it can be restored later on.

func TermSave

func TermSave() TermState

TermSave captures the current state of the internal buffer so it can be restored later on.

type TextWidget

type TextWidget struct {
	Window
	Binding func() string
}

TextWidget is a Widget which displays dynamically bound text on screen.

func NewTextWidget

func NewTextWidget(x, y, w, h int, binding func() string) *TextWidget

NewTextWidget creates a new TextWidget with the given binding.

func (*TextWidget) Update

func (w *TextWidget) Update()

Update draws the bound text on screen.

type Tile

type Tile struct {
	Face     Glyph
	Pass     bool
	Lite     bool
	Offset   Offset
	Adjacent map[Offset]*Tile
	Occupant Entity

	ComponentSlice
}

Tile is an Entity representing a single square in a map.

func GenHeightmap

func GenHeightmap(cols, rows int, f GenTileFloat) []*Tile

GenHeightmap creates a 2D grid of Tile using the given GenTileFloat.

func GenTileGrid

func GenTileGrid(cols, rows int, f GenTile) []*Tile

GenTileGrid creates a 2D grid of Tile using the given GenTile.

func LoS

func LoS(origin, goal *Tile) ([]*Tile, bool)

LoS computes a line of Tile from the origin to the goal. The line is computed using the same heuristic as FoV, so if Trace finds a line, then the goal Tile would be included in the field of view computed from the origin (assuming large enough radius). The sentinel bool return value indicates whether the goal is in line of sight from the origin. If a line is found, the origin Tile is not included in the returned path.

func NewTile

func NewTile(o Offset) *Tile

NewTile creates a new Tile with no neighbors or occupant.

func RandOpenTile

func RandOpenTile(tiles []*Tile) *Tile

RandOpenTile selects a random open Tile from the slice. A Tile is considered open if it is both passable and unoccupied. The selection is done using rejection sampling - that is to say, a random Tile is chosen, and is returned if the Tile is passable, or the Tile will be rejected. If 100 Tile are rejected, then the Tile slice is instead filtered based on passability, and then a random Tile is chosen.

func RandPassTile

func RandPassTile(tiles []*Tile) *Tile

RandPassTile selects a random passable Tile from the slice. The selection is done using rejection sampling - that is to say, a random Tile is chosen, and is returned if the Tile is passable, or the Tile will be rejected. If 100 Tile are rejected, then the Tile slice is instead filtered based on passability, and then a random Tile is chosen.

func RandTile

func RandTile(tiles []*Tile, condition func(*Tile) bool) *Tile

RandTile selects a random Tile from the slice for which the condition is true. The selection is done using rejection sampling - that is to say, a random Tile is chosen, and will either be returned if the condition is true, or the Tile will be rejected. If 100 Tile are rejected, then the Tile slice is instead filtered based on the condition, and then a random Tile is chosen.

func (*Tile) Handle

func (e *Tile) Handle(v Event)

Handle implements Entity for Tile

type UnscheduleEvent

type UnscheduleEvent struct{}

UnscheduleEvent is an Event triggering an Entity unscheduling.

type Widget

type Widget interface {
	Update()
}

Widget represents something which can draw itself on the screen.

type Window

type Window struct {
	X, Y, W, H int
}

Window serves as a base for various Widget which need relateive drawing.

func (*Window) DrawRel

func (w *Window) DrawRel(x, y int, g Glyph)

DrawRel performs a TermDraw relative to the location of the Widget.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL