Documentation ¶
Index ¶
- Constants
- Variables
- func AddComponentTo[T types.Component](wCtx WorldContext, id types.EntityID) (err error)
- func Create(wCtx WorldContext, components ...types.Component) (_ types.EntityID, err error)
- func CreateMany(wCtx WorldContext, num int, components ...types.Component) (entityIDs []types.EntityID, err error)
- func EachMessage[In any, Out any](wCtx WorldContext, fn func(TxData[In]) (Out, error)) error
- func FilterFunction[T types.Component](f func(comp T) bool) func(ctx WorldContext, id types.EntityID) (bool, error)
- func GetComponent[T types.Component](wCtx WorldContext, id types.EntityID) (comp *T, err error)
- func MustRegisterComponent[T types.Component](w *World)
- func NewSearch() searchBuilder
- func RegisterComponent[T types.Component](w *World) error
- func RegisterInitSystems(w *World, sys ...System) error
- func RegisterMessage[In any, Out any](world *World, name string, opts ...MessageOption[In, Out]) error
- func RegisterQuery[Request any, Reply any](w *World, name string, ...) (err error)
- func RegisterSystems(w *World, sys ...System) error
- func Remove(wCtx WorldContext, id types.EntityID) (err error)
- func RemoveComponentFrom[T types.Component](wCtx WorldContext, id types.EntityID) (err error)
- func SetComponent[T types.Component](wCtx WorldContext, id types.EntityID, component *T) (err error)
- func UpdateComponent[T types.Component](wCtx WorldContext, id types.EntityID, fn func(*T) *T) (err error)
- type AndSearch
- func (andSearch *AndSearch) Collect(wCtx WorldContext) ([]types.EntityID, error)
- func (andSearch *AndSearch) Count(wCtx WorldContext) (int, error)
- func (andSearch *AndSearch) Each(wCtx WorldContext, callback CallbackFn) error
- func (andSearch *AndSearch) First(wCtx WorldContext) (types.EntityID, error)
- func (andSearch *AndSearch) MustFirst(wCtx WorldContext) types.EntityID
- type CallbackFn
- type EVMTxReceipt
- type EntitySearch
- type FilterFn
- type MessageManager
- type MessageOption
- type MessageType
- func (t *MessageType[In, Out]) ABIEncode(v any) ([]byte, error)
- func (t *MessageType[In, Out]) AddError(wCtx WorldContext, hash types.TxHash, err error)
- func (t *MessageType[In, Out]) Decode(bytes []byte) (any, error)
- func (t *MessageType[In, Out]) DecodeEVMBytes(bz []byte) (any, error)
- func (t *MessageType[In, Out]) Each(wCtx WorldContext, fn func(TxData[In]) (Out, error))
- func (t *MessageType[In, Out]) Encode(a any) ([]byte, error)
- func (t *MessageType[In, Out]) FullName() string
- func (t *MessageType[In, Out]) GetInFieldInformation() map[string]any
- func (t *MessageType[In, Out]) GetReceipt(wCtx WorldContext, hash types.TxHash) (v Out, errs []error, ok bool)
- func (t *MessageType[In, Out]) Group() string
- func (t *MessageType[In, Out]) ID() types.MessageID
- func (t *MessageType[In, Out]) In(wCtx WorldContext) []TxData[In]
- func (t *MessageType[In, Out]) IsEVMCompatible() bool
- func (t *MessageType[In, Out]) Name() string
- func (t *MessageType[In, Out]) SetID(id types.MessageID) error
- func (t *MessageType[In, Out]) SetResult(wCtx WorldContext, hash types.TxHash, result Out)
- type Namespace
- type NotSearch
- func (notSearch *NotSearch) Collect(wCtx WorldContext) ([]types.EntityID, error)
- func (notSearch *NotSearch) Count(wCtx WorldContext) (int, error)
- func (notSearch *NotSearch) Each(wCtx WorldContext, callback CallbackFn) error
- func (notSearch *NotSearch) First(wCtx WorldContext) (types.EntityID, error)
- func (notSearch *NotSearch) MustFirst(wCtx WorldContext) types.EntityID
- type Option
- type OrSearch
- func (orSearch *OrSearch) Collect(wCtx WorldContext) ([]types.EntityID, error)
- func (orSearch *OrSearch) Count(wCtx WorldContext) (int, error)
- func (orSearch *OrSearch) Each(wCtx WorldContext, callback CallbackFn) error
- func (orSearch *OrSearch) First(wCtx WorldContext) (types.EntityID, error)
- func (orSearch *OrSearch) MustFirst(wCtx WorldContext) types.EntityID
- type PersonaSignerQueryRequest
- type PersonaSignerQueryResponse
- type Plugin
- type QueryManager
- type QueryOption
- type Search
- func (s *Search) Collect(wCtx WorldContext) ([]types.EntityID, error)
- func (s *Search) Count(wCtx WorldContext) (ret int, err error)
- func (s *Search) Each(wCtx WorldContext, callback CallbackFn) (err error)
- func (s *Search) Entity(componentFilter filter.ComponentFilter) EntitySearch
- func (s *Search) First(wCtx WorldContext) (id types.EntityID, err error)
- func (s *Search) MustFirst(wCtx WorldContext) types.EntityID
- func (s *Search) Where(componentFilter FilterFn) EntitySearch
- type Searchable
- type System
- type SystemManager
- type TestFixture
- func (t *TestFixture) AddTransaction(txID types.MessageID, tx any, sigs ...*sign.Transaction) types.TxHash
- func (t *TestFixture) CreatePersona(personaTag, signerAddr string)
- func (t *TestFixture) DoTick()
- func (t *TestFixture) Get(path string) *http.Response
- func (t *TestFixture) Post(path string, payload any) *http.Response
- func (t *TestFixture) StartWorld()
- type TickResults
- type TxData
- type World
- func (w *World) AddEVMTransaction(id types.MessageID, v any, sig *sign.Transaction, evmTxHash string) (tick uint64, txHash types.TxHash)
- func (w *World) AddTransaction(id types.MessageID, v any, sig *sign.Transaction) (tick uint64, txHash types.TxHash)
- func (w *World) ConsumeEVMMsgResult(evmTxHash string) ([]byte, []error, string, bool)
- func (w *World) CurrentTick() uint64
- func (w *World) EvaluateCQL(cqlString string) ([]types.EntityStateElement, error)
- func (w *World) GameStateManager() gamestate.Manager
- func (w *World) GetDebugState() ([]types.DebugStateElement, error)
- func (w *World) GetEVMMsgReceipt(evmTxHash string) (EVMTxReceipt, bool)
- func (w *World) GetMessageByID(id types.MessageID) (types.Message, bool)
- func (w *World) GetReadOnlyCtx() WorldContext
- func (w *World) GetRegisteredComponents() []types.ComponentMetadata
- func (w *World) GetSignerComponentForPersona(personaTag string) (*component.SignerComponent, error)
- func (w *World) GetSignerForPersonaTag(personaTag string, tick uint64) (addr string, err error)
- func (w *World) GetTransactionReceiptsForTick(tick uint64) ([]receipt.Receipt, error)
- func (w *World) IsGameRunning() bool
- func (w *World) Namespace() string
- func (w *World) ReceiptHistorySize() uint64
- func (w *World) RegisterPlugin(plugin Plugin)
- func (w *World) Search(filter filter.ComponentFilter) EntitySearch
- func (w *World) Shutdown()
- func (w *World) StartGame() error
- func (w *World) StoreReader() gamestate.Reader
- func (w *World) UseNonce(signerAddress string, nonce uint64) error
- func (w *World) WaitForNextTick() (success bool)
- type WorldConfig
- type WorldContext
- type WorldOption
- func WithCustomLogger(logger zerolog.Logger) WorldOption
- func WithCustomRouter(rtr router.Router) WorldOption
- func WithDisableSignatureVerification() WorldOption
- func WithMockJobQueue() WorldOption
- func WithMockRedis() WorldOption
- func WithPort(port string) WorldOption
- func WithPrettyLog() WorldOption
- func WithReceiptHistorySize(size int) WorldOption
- func WithStoreManager(s gamestate.Manager) WorldOption
- func WithTickChannel(ch <-chan time.Time) WorldOption
- func WithTickDoneChannel(ch chan<- uint64) WorldOption
Examples ¶
Constants ¶
const ( DefaultCardinalNamespace = "world-1" DefaultCardinalLogLevel = "info" DefaultRedisAddress = "localhost:6379" DefaultBaseShardSequencerAddress = "localhost:9601" )
const ( PersonaStatusUnknown = "unknown" PersonaStatusAvailable = "available" PersonaStatusAssigned = "assigned" )
const ( DefaultHistoricalTicksToStore = 10 RedisDialTimeOut = 150 )
Variables ¶
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 )
var DefaultQueryGroup = "game"
var (
ErrEVMTypeNotSet = errors.New("EVM type is not set")
)
var NonFatalError = []error{ ErrEntityDoesNotExist, ErrComponentNotOnEntity, ErrComponentAlreadyOnEntity, ErrEntityMustHaveAtLeastOneComponent, }
Functions ¶
func AddComponentTo ¶
func Create ¶
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 FilterFunction ¶ added in v1.3.0
func GetComponent ¶
GetComponent returns component data from the entity.
func MustRegisterComponent ¶
func NewSearch ¶
func NewSearch() searchBuilder
NewSearch is used to create a search object.
Usage:
cardinal.NewSearch().Entity(filter.Contains(filter.Component[EnergyComponent]()))
func RegisterInitSystems ¶
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 Remove ¶
func Remove(wCtx WorldContext, id types.EntityID) (err error)
Remove removes the given Entity from the world.
func RemoveComponentFrom ¶
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 ¶
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
type CallbackFn ¶ added in v1.3.3
type EVMTxReceipt ¶
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 ComponentFilter ¶ added in v1.3.3
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.
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
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
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
func PersonaSignerQuery(wCtx WorldContext, req *PersonaSignerQueryRequest) (*PersonaSignerQueryResponse, 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 ¶ added in v1.3.0
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 ¶
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 (*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 ¶
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 (*World) EvaluateCQL ¶ added in v1.3.3
func (w *World) EvaluateCQL(cqlString string) ([]types.EntityStateElement, error)
func (*World) GameStateManager ¶
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 (*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 ¶
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 (*World) IsGameRunning ¶
func (*World) ReceiptHistorySize ¶ added in v1.3.3
func (*World) RegisterPlugin ¶
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 ¶
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 (*World) WaitForNextTick ¶
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.
Source Files ¶
- cardinal.go
- composedsearch.go
- config.go
- filtercomponent.go
- message.go
- message_manager.go
- namespace.go
- option.go
- persona_signer.go
- plugin.go
- plugin_persona.go
- query.go
- query_manager.go
- search.go
- search_iterator.go
- system.go
- tick_results.go
- util.go
- world.go
- world_context.go
- world_fixture.go
- world_persona.go
- world_receipt.go
- world_recovery.go
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. |
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. |