cardinal

package module
v1.6.1 Latest Latest
Warning

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

Go to latest
Published: Jul 26, 2024 License: LGPL-3.0 Imports: 61 Imported by: 4

Documentation

Index

Examples

Constants

View Source
const (
	DefaultCardinalNamespace         = "world-1"
	DefaultCardinalLogLevel          = "info"
	DefaultRedisAddress              = "localhost:6379"
	DefaultBaseShardSequencerAddress = "localhost:9601"
)
View Source
const (
	PersonaStatusUnknown   = "unknown"
	PersonaStatusAvailable = "available"
	PersonaStatusAssigned  = "assigned"
)
View Source
const (
	DefaultHistoricalTicksToStore = 10
	RedisDialTimeOut              = 150
)

Variables

View Source
var (
	ErrEntityMutationOnReadOnly          = errors.New("cannot modify state with read only context")
	ErrEntitiesCreatedBeforeReady        = errors.New("entities should not be created before world is ready")
	ErrEntityDoesNotExist                = gamestate.ErrEntityDoesNotExist
	ErrEntityMustHaveAtLeastOneComponent = gamestate.ErrEntityMustHaveAtLeastOneComponent
	ErrComponentNotOnEntity              = gamestate.ErrComponentNotOnEntity
	ErrComponentAlreadyOnEntity          = gamestate.ErrComponentAlreadyOnEntity
)
View Source
var DefaultQueryGroup = "game"
View Source
var (
	ErrEVMTypeNotSet = errors.New("EVM type is not set")
)

Functions

func AddComponentTo

func AddComponentTo[T types.Component](wCtx WorldContext, id types.EntityID) (err error)

func Create

func Create(wCtx WorldContext, components ...types.Component) (_ types.EntityID, err error)

Create creates a single entity in the world, and returns the id of the newly created entity. At least 1 component must be provided.

func CreateMany

func CreateMany(wCtx WorldContext, num int, components ...types.Component) (entityIDs []types.EntityID, err error)

CreateMany creates multiple entities in the world, and returns the slice of ids for the newly created entities. At least 1 component must be provided.

func EachMessage

func EachMessage[In any, Out any](wCtx WorldContext, fn func(TxData[In]) (Out, error)) error

func FilterFunction added in v1.3.0

func FilterFunction[T types.Component](f func(comp T) bool) func(ctx WorldContext, id types.EntityID) (bool, error)

func GetComponent

func GetComponent[T types.Component](wCtx WorldContext, id types.EntityID) (comp *T, err error)

GetComponent returns component data from the entity.

func MustRegisterComponent

func MustRegisterComponent[T types.Component](w *World)

func NewSearch

func NewSearch() searchBuilder

NewSearch is used to create a search object.

Usage:

cardinal.NewSearch().Entity(filter.Contains(filter.Component[EnergyComponent]()))

func RegisterComponent

func RegisterComponent[T types.Component](w *World) error

func RegisterInitSystems

func RegisterInitSystems(w *World, sys ...System) error

func RegisterMessage

func RegisterMessage[In any, Out any](world *World, name string, opts ...MessageOption[In, Out]) error

RegisterMessage registers a message to the world. Cardinal will automatically set up HTTP routes that map to each registered message. Message URLs are take the form of "group.name". A default group, "game", is used unless the WithCustomMessageGroup option is used. Example: game.throw-rock

func RegisterQuery

func RegisterQuery[Request any, Reply any](
	w *World,
	name string,
	handler func(wCtx WorldContext, req *Request) (*Reply, error),
	opts ...QueryOption[Request, Reply],
) (err error)

func RegisterSystems

func RegisterSystems(w *World, sys ...System) error

func Remove

func Remove(wCtx WorldContext, id types.EntityID) (err error)

Remove removes the given Entity from the world.

func RemoveComponentFrom

func RemoveComponentFrom[T types.Component](wCtx WorldContext, id types.EntityID) (err error)

RemoveComponentFrom removes a component from an entity.

func SetComponent

func SetComponent[T types.Component](wCtx WorldContext, id types.EntityID, component *T) (err error)

SetComponent sets component data to the entity.

func UpdateComponent

func UpdateComponent[T types.Component](wCtx WorldContext, id types.EntityID, fn func(*T) *T) (err error)

Types

type AndSearch added in v1.3.3

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

func (*AndSearch) Collect added in v1.3.3

func (andSearch *AndSearch) Collect(wCtx WorldContext) ([]types.EntityID, error)

func (*AndSearch) Count added in v1.3.3

func (andSearch *AndSearch) Count(wCtx WorldContext) (int, error)

func (*AndSearch) Each added in v1.3.3

func (andSearch *AndSearch) Each(wCtx WorldContext, callback CallbackFn) error

func (*AndSearch) First added in v1.3.3

func (andSearch *AndSearch) First(wCtx WorldContext) (types.EntityID, error)

func (*AndSearch) MustFirst added in v1.3.3

func (andSearch *AndSearch) MustFirst(wCtx WorldContext) types.EntityID

type CallbackFn added in v1.3.3

type CallbackFn func(types.EntityID) bool

type EVMTxReceipt

type EVMTxReceipt struct {
	ABIResult []byte
	Errs      []error
	EVMTxHash string
}

type EntitySearch added in v1.3.3

type EntitySearch interface {
	Searchable
	Where(componentFilter FilterFn) EntitySearch
}

func NewLegacySearch added in v1.3.0

func NewLegacySearch(componentFilter filter.ComponentFilter) EntitySearch

TODO: should deprecate this in the future. NewLegacySearch allows users to create a Search object with a filter already provided as a property.

Example Usage:

cardinal.NewLegacySearch().Entity(filter.Exact(Alpha{}, Beta{})).Count()

type FilterFn added in v1.3.3

type FilterFn func(wCtx WorldContext, id types.EntityID) (bool, error)

func AndFilter added in v1.3.3

func AndFilter(fns ...FilterFn) FilterFn

func ComponentFilter added in v1.3.3

func ComponentFilter[T types.Component](f func(comp T) bool) FilterFn

func OrFilter added in v1.3.3

func OrFilter(fns ...FilterFn) FilterFn

type MessageManager added in v1.3.3

type MessageManager interface {
	RegisterMessage(msgType types.Message, msgReflectType reflect.Type) error
	GetRegisteredMessages() []types.Message
	GetMessageByID(id types.MessageID) types.Message
	GetMessageByFullName(fullName string) (types.Message, bool)
	GetMessageByType(mType reflect.Type) (types.Message, bool)
}

type MessageOption added in v1.3.3

type MessageOption[In, Out any] func(mt *MessageType[In, Out])

func WithCustomMessageGroup added in v1.3.3

func WithCustomMessageGroup[In, Out any](group string) MessageOption[In, Out]

WithCustomMessageGroup sets a custom group for the message. By default, messages are registered under the "game" group which maps it to the /tx/game/:txType route. This option allows you to set a custom group, which allow you to register the message under /tx/<custom_group>/:txType.

func WithMsgEVMSupport added in v1.3.3

func WithMsgEVMSupport[In, Out any]() MessageOption[In, Out]

type MessageType added in v1.3.3

type MessageType[In, Out any] struct {
	// contains filtered or unexported fields
}

MessageType manages a user defined state transition message struct.

Example
//nolint:testableexamples // can figure this out later.
package main

import (
	"errors"
	"fmt"

	"pkg.world.dev/world-engine/cardinal"
)

type MovePlayerMsg struct {
	DeltaX int
	DeltaY int
}

type MovePlayerResult struct {
	FinalX int
	FinalY int
}

func main() {
	world, err := cardinal.NewWorld(cardinal.WithMockRedis())
	if err != nil {
		panic(err)
	}

	err = cardinal.RegisterMessage[MovePlayerMsg, MovePlayerResult](world, "move-player")
	if err != nil {
		panic(err)
	}

	err = cardinal.RegisterSystems(world, func(wCtx cardinal.WorldContext) error {
		return cardinal.EachMessage[MovePlayerMsg, MovePlayerResult](wCtx,
			func(txData cardinal.TxData[MovePlayerMsg]) (MovePlayerResult, error) {
				// handle the transaction
				// ...

				if err := errors.New("some error from a function"); err != nil {
					// A returned non-nil error will be appended to this transaction's list of errors. Any existing
					// transaction result will not be modified.
					return MovePlayerResult{}, fmt.Errorf("problem processing transaction: %w", err)
				}

				// Returning a nil error implies this transaction handling was successful, so this transaction result
				// will be saved to the transaction receipt.
				return MovePlayerResult{
					FinalX: txData.Msg.DeltaX,
					FinalY: txData.Msg.DeltaY,
				}, nil
			})
	})
	if err != nil {
		panic(err)
	}
	// The above system will be called during each game tick.

	err = world.StartGame()
	if err != nil {
		panic(err)
	}
}
Output:

func NewMessageType added in v1.3.3

func NewMessageType[In, Out any](
	name string,
	opts ...MessageOption[In, Out],
) *MessageType[In, Out]

NewMessageType creates a new message type. It accepts two generic type parameters: the first for the message input, which defines the data needed to make a state transition, and the second for the message output, commonly used for the results of a state transition. By default, messages will be grouped under the "game" group, however an option may be passed in to change this.

func (*MessageType[In, Out]) ABIEncode added in v1.3.3

func (t *MessageType[In, Out]) ABIEncode(v any) ([]byte, error)

ABIEncode encodes the input to the message's matching evm type. If the input is not either of the message's evm types, an error is returned.

func (*MessageType[In, Out]) AddError added in v1.3.3

func (t *MessageType[In, Out]) AddError(wCtx WorldContext, hash types.TxHash, err error)

func (*MessageType[In, Out]) Decode added in v1.3.3

func (t *MessageType[In, Out]) Decode(bytes []byte) (any, error)

func (*MessageType[In, Out]) DecodeEVMBytes added in v1.3.3

func (t *MessageType[In, Out]) DecodeEVMBytes(bz []byte) (any, error)

DecodeEVMBytes decodes abi encoded solidity structs into the message's "In" type.

func (*MessageType[In, Out]) Each added in v1.3.3

func (t *MessageType[In, Out]) Each(wCtx WorldContext, fn func(TxData[In]) (Out, error))

func (*MessageType[In, Out]) Encode added in v1.3.3

func (t *MessageType[In, Out]) Encode(a any) ([]byte, error)

func (*MessageType[In, Out]) FullName added in v1.3.3

func (t *MessageType[In, Out]) FullName() string

func (*MessageType[In, Out]) GetInFieldInformation added in v1.3.3

func (t *MessageType[In, Out]) GetInFieldInformation() map[string]any

GetInFieldInformation returns a map of the fields of the message's "In" type and it's field types.

func (*MessageType[In, Out]) GetReceipt added in v1.3.3

func (t *MessageType[In, Out]) GetReceipt(wCtx WorldContext, hash types.TxHash) (
	v Out, errs []error, ok bool,
)

func (*MessageType[In, Out]) Group added in v1.3.3

func (t *MessageType[In, Out]) Group() string

func (*MessageType[In, Out]) ID added in v1.3.3

func (t *MessageType[In, Out]) ID() types.MessageID

func (*MessageType[In, Out]) In added in v1.3.3

func (t *MessageType[In, Out]) In(wCtx WorldContext) []TxData[In]

In extracts all the TxData in the tx pool that match this MessageType's ID.

func (*MessageType[In, Out]) IsEVMCompatible added in v1.3.3

func (t *MessageType[In, Out]) IsEVMCompatible() bool

func (*MessageType[In, Out]) Name added in v1.3.3

func (t *MessageType[In, Out]) Name() string

func (*MessageType[In, Out]) SetID added in v1.3.3

func (t *MessageType[In, Out]) SetID(id types.MessageID) error

func (*MessageType[In, Out]) SetResult added in v1.3.3

func (t *MessageType[In, Out]) SetResult(wCtx WorldContext, hash types.TxHash, result Out)

type Namespace

type Namespace string

Namespace is a unique identifier for a world used for posting to the data availability layer and to prevent signature replay attacks across multiple worlds.

func (Namespace) String

func (n Namespace) String() string

func (Namespace) Validate

func (n Namespace) Validate() error

Validate validates that the namespace is alphanumeric or - (hyphen).

type NotSearch added in v1.3.3

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

func (*NotSearch) Collect added in v1.3.3

func (notSearch *NotSearch) Collect(wCtx WorldContext) ([]types.EntityID, error)

func (*NotSearch) Count added in v1.3.3

func (notSearch *NotSearch) Count(wCtx WorldContext) (int, error)

func (*NotSearch) Each added in v1.3.3

func (notSearch *NotSearch) Each(wCtx WorldContext, callback CallbackFn) error

func (*NotSearch) First added in v1.3.3

func (notSearch *NotSearch) First(wCtx WorldContext) (types.EntityID, error)

func (*NotSearch) MustFirst added in v1.3.3

func (notSearch *NotSearch) MustFirst(wCtx WorldContext) types.EntityID

type Option

type Option func(*World)

type OrSearch added in v1.3.3

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

func (*OrSearch) Collect added in v1.3.3

func (orSearch *OrSearch) Collect(wCtx WorldContext) ([]types.EntityID, error)

func (*OrSearch) Count added in v1.3.3

func (orSearch *OrSearch) Count(wCtx WorldContext) (int, error)

func (*OrSearch) Each added in v1.3.3

func (orSearch *OrSearch) Each(wCtx WorldContext, callback CallbackFn) error

func (*OrSearch) First added in v1.3.3

func (orSearch *OrSearch) First(wCtx WorldContext) (types.EntityID, error)

func (*OrSearch) MustFirst added in v1.3.3

func (orSearch *OrSearch) MustFirst(wCtx WorldContext) types.EntityID

type PersonaSignerQueryRequest added in v1.3.3

type PersonaSignerQueryRequest struct {
	PersonaTag string `json:"personaTag"`
	Tick       uint64 `json:"tick"`
}

PersonaSignerQueryRequest is the desired request body for the query-persona-signer endpoint.

type PersonaSignerQueryResponse added in v1.3.3

type PersonaSignerQueryResponse struct {
	Status        string `json:"status"`
	SignerAddress string `json:"signerAddress"`
}

PersonaSignerQueryResponse is used as the response body for the query-persona-signer endpoint. Status can be: "assigned": The requested persona tag has been assigned the returned SignerAddress "unknown": The game tick has not advanced far enough to know what the signer address. SignerAddress will be empty. "available": The game tick has advanced, and no signer address has been assigned. SignerAddress will be empty.

func PersonaSignerQuery added in v1.3.3

type Plugin

type Plugin interface {
	Register(world *World) error
}

type QueryManager added in v1.3.3

type QueryManager interface {
	RegisterQuery(queryInput query) error
	GetRegisteredQueries() []query
	HandleQuery(group string, name string, bz []byte) ([]byte, error)
	HandleQueryEVM(group string, name string, abiRequest []byte) ([]byte, error)

	BuildQueryFields() []types.FieldDetail
	// contains filtered or unexported methods
}

type QueryOption added in v1.3.3

type QueryOption[Request, Reply any] func(qt *queryType[Request, Reply])

func WithCustomQueryGroup added in v1.3.3

func WithCustomQueryGroup[Request, Reply any](group string) QueryOption[Request, Reply]

WithCustomQueryGroup sets a custom group for the query. By default, queries are registered under the "game" group which maps it to the /query/game/:queryType route. This option allows you to set a custom group, which allow you to register the query under /query/<custom_group>/:queryType.

func WithQueryEVMSupport added in v1.3.3

func WithQueryEVMSupport[Request, Reply any]() QueryOption[Request, Reply]
type Search struct {
	// contains filtered or unexported fields
}

Search represents a search for entities. It is used to filter entities based on their components. It receives arbitrary filters that are used to filter entities. It contains a cache that is used to avoid re-evaluating the search. So it is not recommended to create a new search every time you want to filter entities with the same search.

func (*Search) Collect added in v1.3.3

func (s *Search) Collect(wCtx WorldContext) ([]types.EntityID, error)

func (*Search) Count added in v1.3.3

func (s *Search) Count(wCtx WorldContext) (ret int, err error)

Count returns the number of entities that match the search.

func (*Search) Each added in v1.3.3

func (s *Search) Each(wCtx WorldContext, callback CallbackFn) (err error)

Each iterates over all entities that match the search. If you would like to stop the iteration, return false to the callback. To continue iterating, return true.

func (*Search) Entity added in v1.3.3

func (s *Search) Entity(componentFilter filter.ComponentFilter) EntitySearch

func (*Search) First added in v1.3.3

func (s *Search) First(wCtx WorldContext) (id types.EntityID, err error)

First returns the first entity that matches the search.

func (*Search) MustFirst added in v1.3.3

func (s *Search) MustFirst(wCtx WorldContext) types.EntityID

func (*Search) Where added in v1.3.3

func (s *Search) Where(componentFilter FilterFn) EntitySearch

Once the where clause method is activated the search will ONLY return results if a where clause returns true and no error.

type Searchable added in v1.3.3

type Searchable interface {
	Each(wCtx WorldContext, callback CallbackFn) error
	First(wCtx WorldContext) (types.EntityID, error)
	MustFirst(wCtx WorldContext) types.EntityID
	Count(wCtx WorldContext) (int, error)
	Collect(wCtx WorldContext) ([]types.EntityID, error)
	// contains filtered or unexported methods
}

func And added in v1.3.3

func And(searches ...Searchable) Searchable

func Not added in v1.3.3

func Not(search Searchable) Searchable

func Or added in v1.3.3

func Or(searches ...Searchable) Searchable

type System

type System func(ctx WorldContext) error

System is a user-defined function that is executed at every tick.

type SystemManager added in v1.3.3

type SystemManager interface {
	// GetRegisteredSystems returns a slice of all registered systems' name.
	GetRegisteredSystems() []string

	// GetCurrentSystem returns the name of the currently running system.
	// If no system is currently running, it returns an empty string.
	GetCurrentSystem() string
	// contains filtered or unexported methods
}

type TestFixture added in v1.4.0

type TestFixture struct {
	testing.TB

	// Base url is something like "localhost:5050". You must attach http:// or ws:// as well as a resource path
	BaseURL string
	World   *World
	Redis   *miniredis.Miniredis

	StartTickCh chan time.Time
	DoneTickCh  chan uint64
	// contains filtered or unexported fields
}

TestFixture is a helper struct that manages a cardinal.World instance. It will automatically clean up its resources at the end of the test.

func NewTestFixture added in v1.4.0

func NewTestFixture(t testing.TB, redis *miniredis.Miniredis, opts ...WorldOption) *TestFixture

NewTestFixture creates a test fixture with user defined port for Cardinal integration tests.

func (*TestFixture) AddTransaction added in v1.4.0

func (t *TestFixture) AddTransaction(txID types.MessageID, tx any, sigs ...*sign.Transaction) types.TxHash

func (*TestFixture) CreatePersona added in v1.4.0

func (t *TestFixture) CreatePersona(personaTag, signerAddr string)

func (*TestFixture) DoTick added in v1.4.0

func (t *TestFixture) DoTick()

DoTick executes one game tick and blocks until the tick is complete. StartWorld is automatically called if it was not called before the first tick.

func (*TestFixture) Get added in v1.4.0

func (t *TestFixture) Get(path string) *http.Response

Get executes a http GET request to this TestFixture's cardinal server.

func (*TestFixture) Post added in v1.4.0

func (t *TestFixture) Post(path string, payload any) *http.Response

Post executes a http POST request to this TextFixture's cardinal server.

func (*TestFixture) StartWorld added in v1.4.0

func (t *TestFixture) StartWorld()

StartWorld starts the game world and registers a cleanup function that will shut down the cardinal World at the end of the test. Components/Systems/Queries, etc should be registered before calling this function.

type TickResults

type TickResults struct {
	Tick     uint64
	Receipts []receipt.Receipt
	Events   [][]byte
}

func NewTickResults

func NewTickResults(initialTick uint64) *TickResults

func (*TickResults) AddEvent

func (tr *TickResults) AddEvent(event any) error

func (*TickResults) AddStringEvent

func (tr *TickResults) AddStringEvent(e string) error

func (*TickResults) Clear

func (tr *TickResults) Clear()

func (*TickResults) SetReceipts

func (tr *TickResults) SetReceipts(newReceipts []receipt.Receipt)

func (*TickResults) SetTick

func (tr *TickResults) SetTick(tick uint64)

type TxData added in v1.3.3

type TxData[In any] struct {
	Hash types.TxHash
	Msg  In
	Tx   *sign.Transaction
}

type World

type World struct {
	SystemManager
	MessageManager
	QueryManager
	component.ComponentManager
	// contains filtered or unexported fields
}

func NewWorld

func NewWorld(opts ...WorldOption) (*World, error)

NewWorld creates a new World object using Redis as the storage layer

func (*World) AddEVMTransaction

func (w *World) AddEVMTransaction(
	id types.MessageID,
	v any,
	sig *sign.Transaction,
	evmTxHash string,
) (
	tick uint64, txHash types.TxHash,
)

func (*World) AddTransaction

func (w *World) AddTransaction(id types.MessageID, v any, sig *sign.Transaction) (
	tick uint64, txHash types.TxHash,
)

AddTransaction adds a transaction to the transaction pool. This should not be used directly. Instead, use a MessageType.addTransaction to ensure type consistency. Returns the tick this transaction will be executed in.

func (*World) ConsumeEVMMsgResult

func (w *World) ConsumeEVMMsgResult(evmTxHash string) ([]byte, []error, string, bool)

ConsumeEVMMsgResult consumes a tx result from an EVM originated Cardinal message. It will fetch the receipt from the map, and then delete ('consume') it from the map.

func (*World) CurrentTick

func (w *World) CurrentTick() uint64

func (*World) EvaluateCQL added in v1.3.3

func (w *World) EvaluateCQL(cqlString string) ([]types.EntityStateElement, error)

func (*World) GameStateManager

func (w *World) GameStateManager() gamestate.Manager

func (*World) GetDebugState added in v1.3.3

func (w *World) GetDebugState() ([]types.DebugStateElement, error)

func (*World) GetEVMMsgReceipt

func (w *World) GetEVMMsgReceipt(evmTxHash string) (EVMTxReceipt, bool)

func (*World) GetMessageByID

func (w *World) GetMessageByID(id types.MessageID) (types.Message, bool)

func (*World) GetReadOnlyCtx added in v1.3.0

func (w *World) GetReadOnlyCtx() WorldContext

func (*World) GetRegisteredComponents

func (w *World) GetRegisteredComponents() []types.ComponentMetadata

func (*World) GetSignerComponentForPersona

func (w *World) GetSignerComponentForPersona(personaTag string) (*component.SignerComponent, error)

func (*World) GetSignerForPersonaTag

func (w *World) GetSignerForPersonaTag(personaTag string, tick uint64) (addr string, err error)

GetSignerForPersonaTag returns the signer address that has been registered for the given persona tag after the given tick. If the engine's tick is less than or equal to the given tick, ErrorCreatePersonaTXsNotProcessed is returned. If the given personaTag has no signer address, ErrPersonaTagHasNoSigner is returned.

func (*World) GetTransactionReceiptsForTick

func (w *World) GetTransactionReceiptsForTick(tick uint64) ([]receipt.Receipt, error)

func (*World) IsGameRunning

func (w *World) IsGameRunning() bool

func (*World) Namespace

func (w *World) Namespace() string

func (*World) ReceiptHistorySize added in v1.3.3

func (w *World) ReceiptHistorySize() uint64

func (*World) RegisterPlugin

func (w *World) RegisterPlugin(plugin Plugin)

func (*World) Search

func (w *World) Search(filter filter.ComponentFilter) EntitySearch

func (*World) Shutdown

func (w *World) Shutdown()

Shutdown will trigger a graceful shutdown of the World.

func (*World) StartGame

func (w *World) StartGame() error

StartGame starts running the world game loop. Each time a message arrives on the tickChannel, a world tick is attempted. In addition, an HTTP server (listening on the given port) is created so that game messages can be sent to this world. After StartGame is called, RegisterComponent, registerMessagesByName, RegisterQueries, and RegisterSystems may not be called. If StartGame doesn't encounter any errors, it will block forever, running the server and ticking the game in the background.

func (*World) StoreReader

func (w *World) StoreReader() gamestate.Reader

func (*World) UseNonce

func (w *World) UseNonce(signerAddress string, nonce uint64) error

func (*World) WaitForNextTick

func (w *World) WaitForNextTick() (success bool)

WaitForNextTick blocks until at least one game tick has completed. It returns true if it successfully waited for a tick. False may be returned if the engine was shut down while waiting for the next tick to complete.

type WorldConfig

type WorldConfig struct {
	// CardinalNamespace The shard namespace for Cardinal. This needs to be unique to prevent signature replay attacks.
	CardinalNamespace string `mapstructure:"CARDINAL_NAMESPACE"`

	// CardinalRollupEnabled When true, Cardinal will sequence and recover to/from base shard.
	CardinalRollupEnabled bool `mapstructure:"CARDINAL_ROLLUP_ENABLED"`

	// CardinalLogLevel Determines the log level for Cardinal.
	CardinalLogLevel string `mapstructure:"CARDINAL_LOG_LEVEL"`

	// CardinalLogPretty Pretty logging, disable by default due to performance impact.
	CardinalLogPretty bool `mapstructure:"CARDINAL_LOG_PRETTY"`

	// RedisAddress The address of the redis server, supports unix sockets.
	RedisAddress string `mapstructure:"REDIS_ADDRESS"`

	// RedisPassword The password for the redis server. Make sure to use a password in production.
	RedisPassword string `mapstructure:"REDIS_PASSWORD"`

	// BaseShardSequencerAddress This is the address that Cardinal will use to sequence and recover to/from base shard.
	BaseShardSequencerAddress string `mapstructure:"BASE_SHARD_SEQUENCER_ADDRESS"`

	// BaseShardRouterKey is a token used to secure communications between the game shard and the base shard.
	BaseShardRouterKey string `mapstructure:"BASE_SHARD_ROUTER_KEY"`

	// TelemetryTraceEnabled When true, Cardinal will collect OpenTelemetry traces
	TelemetryTraceEnabled bool `mapstructure:"TELEMETRY_TRACE_ENABLED"`

	// TelemetryProfilerEnabled When true, Cardinal will run Datadog continuous profiling
	TelemetryProfilerEnabled bool `mapstructure:"TELEMETRY_PROFILER_ENABLED"`
}

func (*WorldConfig) Validate

func (w *WorldConfig) Validate() error

Validate validates the config values. If CARDINAL_ROLLUP=true, the BASE_SHARD_SEQUENCER_ADDRESS and BASE_SHARD_ROUTER_KEY are required.

type WorldContext

type WorldContext interface {
	// Timestamp returns the UNIX timestamp of the tick in milliseconds.
	// We are using millisecond because subsecond ticks are possible and we want to ensure we have that level
	// of precision.
	Timestamp() uint64
	// CurrentTick returns the current tick.
	CurrentTick() uint64
	// Logger returns the logger that can be used to log messages from within system or query.
	Logger() *zerolog.Logger
	// EmitEvent emits an event that will be broadcast to all websocket subscribers.
	EmitEvent(map[string]any) error
	// EmitStringEvent emits a string event that will be broadcast to all websocket subscribers.
	// This method is provided for backwards compatability. EmitEvent should be used for most cases.
	EmitStringEvent(string) error
	// Namespace returns the namespace of the world.
	Namespace() string
	// Rand returns a random number generator that is seeded specifically for a current tick.
	Rand() *rand.Rand
	// contains filtered or unexported methods
}

func NewReadOnlyWorldContext

func NewReadOnlyWorldContext(world *World) WorldContext

func NewWorldContext

func NewWorldContext(world *World) WorldContext

type WorldOption

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

WorldOption represents an option that can be used to augment how the cardinal.World will be run.

func WithCustomLogger

func WithCustomLogger(logger zerolog.Logger) WorldOption

func WithCustomRouter

func WithCustomRouter(rtr router.Router) WorldOption

func WithDisableSignatureVerification

func WithDisableSignatureVerification() WorldOption

WithDisableSignatureVerification disables signature verification for the HTTP server. This should only be used for local development.

func WithMockJobQueue added in v1.6.0

func WithMockJobQueue() WorldOption

WithMockJobQueue runs the router with an in-memory job queue instead of a persistent one that writes to disk.

func WithMockRedis

func WithMockRedis() WorldOption

WithMockRedis runs the World with an embedded miniredis instance on port 6379.

func WithPort

func WithPort(port string) WorldOption

WithPort sets the port that the HTTP server will run on.

func WithPrettyLog

func WithPrettyLog() WorldOption

func WithReceiptHistorySize

func WithReceiptHistorySize(size int) WorldOption

WithReceiptHistorySize specifies how many ticks worth of transaction receipts should be kept in memory. The default is 10. A smaller number uses less memory, but limits the amount of historical receipts available.

func WithStoreManager

func WithStoreManager(s gamestate.Manager) WorldOption

func WithTickChannel

func WithTickChannel(ch <-chan time.Time) WorldOption

WithTickChannel sets the channel that will be used to decide when world.doTick is executed. If unset, a loop interval of 1 second will be set. To set some other time, use: WithTickChannel(time.Tick(<some-duration>)). Tests can pass in a channel controlled by the test for fine-grained control over when ticks are executed.

func WithTickDoneChannel

func WithTickDoneChannel(ch chan<- uint64) WorldOption

WithTickDoneChannel sets a channel that will be notified each time a tick completes. The completed tick will be pushed to the channel. This option is useful in tests when assertions need to be performed at the end of a tick.

Directories

Path Synopsis
Package gamestate allows for buffering of state changes to the ECS dbStorage layer, and either committing those changes in an atomic Redis transaction, or discarding the changes.
Package gamestate allows for buffering of state changes to the ECS dbStorage layer, and either committing those changes in an atomic Redis transaction, or discarding the changes.
msg
Package receipt keeps track of transaction receipts for a number of ticks.
Package receipt keeps track of transaction receipts for a number of ticks.
iterator/mocks
Package mocks is a generated GoMock package.
Package mocks is a generated GoMock package.
mocks
Package mocks is a generated GoMock package.
Package mocks is a generated GoMock package.
docs
Package docs Code generated by swaggo/swag.
Package docs Code generated by swaggo/swag.

Jump to

Keyboard shortcuts

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