Documentation ¶
Index ¶
- Constants
- Variables
- func AddSystemTransaction(w *state.GameWorld, tickNumber int, transactionType string, data string, ...) int
- func BroadcastMessage(ctx *EngineCtx, clientEvents []ClientEvent)
- func CORSMiddleware() gin.HandlerFunc
- func CalcFutureTickFromMs(ctx *EngineCtx, timeInMs int) int
- func CalcFutureTickFromS(ctx *EngineCtx, timeInSeconds int) int
- func CreateBasicResponseObject(requestUuid string) interface{}
- func CreateBasicResponseObjectWithData(requestUuid string, data any) interface{}
- func CreateRequestForTick[T any](ctx *EngineCtx) gin.HandlerFunc
- func CreateResponseWithError(requestUuid string, errorMessage string) interface{}
- func DecodeRequestBody[T any](c *gin.Context) (T, error)
- func DeleteAllTicksAtTickNumber(w *state.GameWorld, tickNumber int)
- func GetSystemTransactionsOfType[T any](ctx *EngineCtx) []int
- func GetTickTransactionsOfType(w *state.GameWorld, transactionType string, tickNumber int) []int
- func GetTransactionUuid(w state.IWorld, transactionId int) int
- func GetTransactionsAtTickNumber(w *state.GameWorld, tickNumber int) []int
- func HandleRewindState(ctx *EngineCtx) gin.HandlerFunc
- func PrintErrorLog(ctx *EngineCtx)
- func QueueTxAtTime[T any](w state.IWorld, tickNumber int, data KeystoneTx[T], uuid string, ...) error
- func QueueTxFromExternal[T any](ctx *EngineCtx, data KeystoneTx[T], tickId string) error
- func QueueTxFromInternal[T any](w state.IWorld, tickNumber int, data KeystoneTx[T], tickId string) error
- func RegisterDefaultTables(w *state.GameWorld)
- func SerializeRequestToString[T any](req T) (string, error)
- func SetupSaveStateLoop(ctx *EngineCtx, saveInterval time.Duration)
- func SetupSaveTxLoop(ctx *EngineCtx, saveInterval time.Duration)
- func ShouldTriggerTick(tickNumber int, tickRate int, frequencyInMs int) bool
- func TickGameSystems(ctx *EngineCtx)
- func TickWorldForward(ctx *EngineCtx, ticks int) int
- type CMD
- type ClientEvent
- type ConnectionType
- type EngineCtx
- func (ctx *EngineCtx) AddStateUpdatesToSave()
- func (ctx *EngineCtx) AddSystem(IntervalMs int, tickFunction TickSystemFunction)
- func (ctx *EngineCtx) AddTables(tables map[interface{}]*state.TableBaseAccessor[any])
- func (ctx *EngineCtx) AddTransactionToSave(transaction TransactionSchema, tick int) error
- func (ctx *EngineCtx) AddTransactionsToSave()
- func (ctx *EngineCtx) ClearStateUpdatesToSave()
- func (ctx *EngineCtx) ClearTransactionsToSave()
- func (ctx *EngineCtx) SetEmitErrorHandler(errorHandler ISystemErrorHandler)
- func (ctx *EngineCtx) SetEmitEventHandler(broadcastHandler ISystemBroadcastHandler)
- func (ctx *EngineCtx) SetGameId(id string)
- func (ctx *EngineCtx) SetGameLiveliness(isLive bool)
- func (ctx *EngineCtx) SetPort(port int)
- func (ctx *EngineCtx) SetSaveState(saveState bool)
- func (ctx *EngineCtx) SetSaveStateHandler(saveStateHandler ISaveState, saveInterval time.Duration)
- func (ctx *EngineCtx) SetSaveTx(saveTx bool)
- func (ctx *EngineCtx) SetSaveTxHandler(saveTxHandler ISaveTransactions, saveInterval time.Duration)
- func (ctx *EngineCtx) SetSocketRequestRouter(router ISocketRequestRouter)
- func (ctx *EngineCtx) SetStreamRate(rate int)
- func (ctx *EngineCtx) SetTickRate(tickRateMs int)
- func (ctx *EngineCtx) SetWebsocketPort(port int)
- func (ctx *EngineCtx) Start()
- type ErrorLog
- type EthereumWalletAuth
- type EventCtx
- type GameMode
- type GameTick
- type HeaderField
- type IMiddleware
- type ISaveState
- type ISaveTransactions
- type ISocketRequestRouter
- type ISystemBroadcastHandler
- type ISystemErrorHandler
- type ISystemHandler
- type KeystoneTx
- type NetworkMessage
- func (msg *NetworkMessage) GetCommand() uint32
- func (msg *NetworkMessage) GetData() []byte
- func (msg NetworkMessage) GetProtoMessage(structData proto.Message) (proto.Message, error)
- func (msg *NetworkMessage) Param() uint32
- func (msg *NetworkMessage) ParseFromBuffer(buffer []byte)
- func (msg *NetworkMessage) ParseToBuffer() []byte
- type NetworkMessageHead
- type NetworkMessages
- type ProtoBasedBroadcastHandler
- type ProtoBasedErrorHandler
- type RewindStateRequest
- type StreamServer
- func (ws *StreamServer) AddConnection(conn *websocket.Conn, subscribeToStateUpdates bool)
- func (ws *StreamServer) ClearClientMessageQueue()
- func (ws *StreamServer) ClearTableUpdatesQueue()
- func (ws *StreamServer) FetchEventsFromQueue() []ClientEvent
- func (ws *StreamServer) FetchTableUpdatesFromQueue() []state.TableUpdate
- func (ws *StreamServer) PublishStateChanges(tableUpdates state.TableUpdateArray, clientEvents []ClientEvent)
- func (ws *StreamServer) RemoveConnection(conn *websocket.Conn)
- func (ws *StreamServer) SetPlayerIdToConnection(playerId int, conn *websocket.Conn)
- func (s *StreamServer) SetSocketRequestRouter(router ISocketRequestRouter)
- func (s *StreamServer) Start(ctx *EngineCtx)
- func (ws *StreamServer) StartMessageBroadcastLoop()
- type TickSchedule
- type TickSystem
- type TickSystemFunction
- type TransactionCtx
- type TransactionSchema
- type UpdatePacket
- type WSMessage
Constants ¶
const ( Dev GameMode = "dev" DevMySQL GameMode = "devMySQL" DevSQLite GameMode = "devSQLite" Prod GameMode = "prod" SaveStateInterval = time.Second * 10 DevSaveStateInterval = time.Millisecond * 100 DefaultServerPort = 9000 DefaultWebsocketPort = 9001 DefaultTickRate = 100 // ms TickRate = 100 )
const (
MessageHeadLength = 13 // Fixed length of Message Head
)
Variables ¶
var BaseTableSchemasToAccessors = map[interface{}]*state.TableBaseAccessor[any]{ &TransactionSchema{}: (*state.TableBaseAccessor[any])(TransactionTable), }
var (
TransactionTable = state.NewTableAccessor[TransactionSchema]()
)
Functions ¶
func AddSystemTransaction ¶
func BroadcastMessage ¶
func BroadcastMessage(ctx *EngineCtx, clientEvents []ClientEvent)
func CORSMiddleware ¶
func CORSMiddleware() gin.HandlerFunc
func CalcFutureTickFromMs ¶ added in v0.1.0
time in milliseconds
func CalcFutureTickFromS ¶ added in v0.1.0
func CreateBasicResponseObject ¶
func CreateBasicResponseObject(requestUuid string) interface{}
func CreateRequestForTick ¶
func CreateRequestForTick[T any](ctx *EngineCtx) gin.HandlerFunc
creates a corresponding request from a Gin request to user
func CreateResponseWithError ¶
func GetSystemTransactionsOfType ¶
get tick transactions of type at a current tick number
func GetTickTransactionsOfType ¶
get tick transactions
func HandleRewindState ¶ added in v0.1.0
func HandleRewindState(ctx *EngineCtx) gin.HandlerFunc
TODO will only one person have the power to restore the state initialize the world before calling it
func PrintErrorLog ¶
func PrintErrorLog(ctx *EngineCtx)
used in debug mode, print all the errors the game has collected should be the same set of errors that are broadcasted to clients
func QueueTxAtTime ¶
func QueueTxAtTime[T any](w state.IWorld, tickNumber int, data KeystoneTx[T], uuid string, isExternal bool) error
queues tick transactions to be executed in the future
func QueueTxFromExternal ¶
func QueueTxFromExternal[T any](ctx *EngineCtx, data KeystoneTx[T], tickId string) error
queue transactions that are user-initiated aka external
func QueueTxFromInternal ¶
func QueueTxFromInternal[T any](w state.IWorld, tickNumber int, data KeystoneTx[T], tickId string) error
queue transactions that are internal (ex: move planning)
func RegisterDefaultTables ¶
registers default tables keystone must operates on such as tick related
func SetupSaveStateLoop ¶
game loop that triggers the save world state
func SetupSaveTxLoop ¶ added in v0.1.0
Set up save transaction loop
func ShouldTriggerTick ¶
if the tick happened between the previous and the current tick, we can still trigger it
func TickWorldForward ¶ added in v0.1.0
ticks the world forward for testing. time machine go brr
Types ¶
type ClientEvent ¶
type ClientEvent struct { NetworkMessage *NetworkMessage PlayerIds []int }
type ConnectionType ¶ added in v0.1.0
type ConnectionType struct {
SubscribeAllStateUpdates bool
}
type EngineCtx ¶
type EngineCtx struct { // Unique game ID GameId string // Is the game live IsLive bool // Is the game state is being restored from db IsRestoringState bool // Game world containing table game state World *state.GameWorld // Game tick. The heartbeat of your game GameTick *GameTick // Stream server for broadcasting data such as table changes and errors to clients Stream *StreamServer // Gin HTTP server GinHttpEngine *gin.Engine // HTTP port HttpPort int // Transaction queue TransactionsToSaveLock sync.Mutex // Transactions to be stored in the data availability layer (aka a write ahead log basically) TransactionsToSave []TransactionSchema // Handles interactions for saving stae ShouldSaveState bool SaveStateHandler ISaveState ShouldSaveTransactions bool SaveTransactionsHandler ISaveTransactions // Implementations on how to broadcast events and errors SystemErrorHandler ISystemErrorHandler SystemBroadcastHandler ISystemBroadcastHandler // "dev", "prod" Mode GameMode // Whether game should record error in error log ShouldRecordError bool // Error log for printing when testing ErrorLog []ErrorLog StateUpdatesMutex sync.Mutex // State updates PendingStateUpdatesToSave []state.TableUpdate }
Context containing everything for the game server
func (*EngineCtx) AddStateUpdatesToSave ¶
func (ctx *EngineCtx) AddStateUpdatesToSave()
add to the list of state updates to save to database
func (*EngineCtx) AddSystem ¶ added in v0.1.12
func (ctx *EngineCtx) AddSystem(IntervalMs int, tickFunction TickSystemFunction)
Interval: how frequently a system ticks (in milliseconds)
func (*EngineCtx) AddTables ¶ added in v0.1.12
func (ctx *EngineCtx) AddTables(tables map[interface{}]*state.TableBaseAccessor[any])
Add tables to world
func (*EngineCtx) AddTransactionToSave ¶
func (ctx *EngineCtx) AddTransactionToSave(transaction TransactionSchema, tick int) error
add a transactions that needs to be saved
func (*EngineCtx) AddTransactionsToSave ¶
func (ctx *EngineCtx) AddTransactionsToSave()
func (*EngineCtx) ClearStateUpdatesToSave ¶
func (ctx *EngineCtx) ClearStateUpdatesToSave()
func (*EngineCtx) ClearTransactionsToSave ¶
func (ctx *EngineCtx) ClearTransactionsToSave()
clear transactions to save
func (*EngineCtx) SetEmitErrorHandler ¶ added in v0.1.12
func (ctx *EngineCtx) SetEmitErrorHandler(errorHandler ISystemErrorHandler)
Set broadcast error handler
func (*EngineCtx) SetEmitEventHandler ¶ added in v0.1.12
func (ctx *EngineCtx) SetEmitEventHandler(broadcastHandler ISystemBroadcastHandler)
Set broadcast event handler
func (*EngineCtx) SetGameLiveliness ¶
set whether game is live or not
func (*EngineCtx) SetSaveState ¶ added in v0.1.13
Whether engine runs the state backup service. By default disabled for local development
func (*EngineCtx) SetSaveStateHandler ¶ added in v0.1.12
func (ctx *EngineCtx) SetSaveStateHandler(saveStateHandler ISaveState, saveInterval time.Duration)
Set save state handler
func (*EngineCtx) SetSaveTx ¶ added in v0.1.13
Whether engine runs the transaction backup service By default disabled for local development
func (*EngineCtx) SetSaveTxHandler ¶ added in v0.1.12
func (ctx *EngineCtx) SetSaveTxHandler(saveTxHandler ISaveTransactions, saveInterval time.Duration)
Set save transaction handler
func (*EngineCtx) SetSocketRequestRouter ¶ added in v0.1.12
func (ctx *EngineCtx) SetSocketRequestRouter(router ISocketRequestRouter)
Set websocket request router
func (*EngineCtx) SetStreamRate ¶ added in v0.1.14
Set rate of streaming packets to clients (milliseconds)
func (*EngineCtx) SetTickRate ¶ added in v0.1.12
Set tick rate (milliseconds)
func (*EngineCtx) SetWebsocketPort ¶ added in v0.1.12
Set websocket port
type EthereumWalletAuth ¶ added in v0.1.14
func NewEthereumWalletAuth ¶ added in v0.1.14
func NewEthereumWalletAuth[T any](privateKey *ecdsa.PrivateKey, req T) (*EthereumWalletAuth, error)
func (*EthereumWalletAuth) Verify ¶ added in v0.1.14
func (p *EthereumWalletAuth) Verify() bool
type EventCtx ¶
type EventCtx struct {
ClientEvents []ClientEvent
}
used once per-request
func (*EventCtx) AddEvent ¶
func (e *EventCtx) AddEvent(msg *NetworkMessage, playerIds []int)
adds a client event to the event context
type GameTick ¶
type GameTick struct { // the current game tick number TickNumber int // per how many milliseconds the game ticks TickRateMs int // schedule of ticks and corresponding functions Schedule *TickSchedule }
func NewGameTick ¶
type HeaderField ¶ added in v0.1.13
type HeaderField string
const (
EthereumWalletAuthHeader HeaderField = "ethereumWalletAuth"
)
type IMiddleware ¶
type IMiddleware[T any] func(ctx *TransactionCtx[T]) bool // manually emit errors to the transaction context as needed using ctx.EmitError
func VerifyEthereumWalletAuth ¶ added in v0.1.14
func VerifyEthereumWalletAuth[T any]() IMiddleware[T]
type ISaveState ¶
type ISaveState interface { SaveState(tableUpdates []state.TableUpdate) error RestoreState(ctx *EngineCtx, gameId string) error }
general interface to implement
type ISaveTransactions ¶
type ISocketRequestRouter ¶
type ISocketRequestRouter func(ctx *EngineCtx, requestMsg *NetworkMessage, socketConnection *websocket.Conn)
type ISystemBroadcastHandler ¶
type ISystemBroadcastHandler interface {
BroadcastMessage(ctx *EngineCtx, clientEvents []ClientEvent)
}
error broadcasting interface
type ISystemErrorHandler ¶
type ISystemErrorHandler interface {
FormatMessage(transactionUuidIdentifier int, errorMessage string) *NetworkMessage
}
error handling interface
type ISystemHandler ¶
type ISystemHandler[T any] func(ctx *TransactionCtx[T])
type KeystoneTx ¶ added in v0.1.13
type KeystoneTx[T any] struct { Headers map[HeaderField]json.RawMessage Data T }
wraps the headers
func DecodeTxData ¶
func DecodeTxData[T any](ctx *EngineCtx, transactionId int) KeystoneTx[T]
decode a string
func NewKeystoneTx ¶ added in v0.1.13
func NewKeystoneTx[T any](req T, headers map[HeaderField]json.RawMessage) KeystoneTx[T]
type NetworkMessage ¶
type NetworkMessage struct {
// contains filtered or unexported fields
}
func NewMessage ¶
func NewMessageFromBuffer ¶
func NewMessageFromBuffer(buffer []byte) *NetworkMessage
decode message from client to server
func NewRequestMessage ¶ added in v0.1.13
func NewRequestMessage[T proto.Message](flag uint8, command uint32, param uint32, data KeystoneTx[T]) (*NetworkMessage, error)
func (*NetworkMessage) GetCommand ¶
func (msg *NetworkMessage) GetCommand() uint32
func (*NetworkMessage) GetData ¶ added in v0.1.13
func (msg *NetworkMessage) GetData() []byte
func (NetworkMessage) GetProtoMessage ¶
Get Proto Message from Network Message
func (*NetworkMessage) Param ¶
func (msg *NetworkMessage) Param() uint32
func (*NetworkMessage) ParseFromBuffer ¶
func (msg *NetworkMessage) ParseFromBuffer(buffer []byte)
Parse NetworkMessage from network buffer
func (*NetworkMessage) ParseToBuffer ¶
func (msg *NetworkMessage) ParseToBuffer() []byte
Parse NetworkMessage to network buffer
type NetworkMessageHead ¶
type NetworkMessageHead struct {
// contains filtered or unexported fields
}
func (*NetworkMessageHead) Decode ¶
func (head *NetworkMessageHead) Decode(buffer []byte)
func (*NetworkMessageHead) Encode ¶
func (head *NetworkMessageHead) Encode(buffer []byte)
func (*NetworkMessageHead) ParseHeadFromBuffer ¶
func (head *NetworkMessageHead) ParseHeadFromBuffer(buffer []byte)
type NetworkMessages ¶
type NetworkMessages []*NetworkMessage
type ProtoBasedBroadcastHandler ¶ added in v0.1.13
type ProtoBasedBroadcastHandler struct { }
func (*ProtoBasedBroadcastHandler) BroadcastMessage ¶ added in v0.1.13
func (h *ProtoBasedBroadcastHandler) BroadcastMessage(ctx *EngineCtx, clientEvents []ClientEvent)
type ProtoBasedErrorHandler ¶ added in v0.1.13
type ProtoBasedErrorHandler struct { }
func (*ProtoBasedErrorHandler) FormatMessage ¶ added in v0.1.13
func (h *ProtoBasedErrorHandler) FormatMessage(transactionUuidIdentifier int, errorMessage string) *NetworkMessage
format message into protobuf
type RewindStateRequest ¶ added in v0.1.0
type StreamServer ¶
type StreamServer struct { // Websocket port Port int // Stream interval (milliseconds) StreamInterval int // Lock for protobuf packets ProtoBufPacketsMutex sync.Mutex // Socket request router SocketRequestRouter ISocketRequestRouter // Client message data packets to be broadcasted ClientEventsQueue []ClientEvent // Table updates to be broadcasted TableUpdatesQueue []state.TableUpdate // A pool of connections Conns map[*websocket.Conn]ConnectionType ConnsMutex sync.Mutex // PlayerID to websocket connection PlayerIdToConnection map[int]*websocket.Conn PlayerIdToConnectionMutex sync.Mutex }
func (*StreamServer) AddConnection ¶ added in v0.1.0
func (ws *StreamServer) AddConnection(conn *websocket.Conn, subscribeToStateUpdates bool)
func (*StreamServer) ClearClientMessageQueue ¶
func (ws *StreamServer) ClearClientMessageQueue()
clear all messages in the client message queue
func (*StreamServer) ClearTableUpdatesQueue ¶
func (ws *StreamServer) ClearTableUpdatesQueue()
clear all table updates from queue
func (*StreamServer) FetchEventsFromQueue ¶
func (ws *StreamServer) FetchEventsFromQueue() []ClientEvent
func (*StreamServer) FetchTableUpdatesFromQueue ¶
func (ws *StreamServer) FetchTableUpdatesFromQueue() []state.TableUpdate
fetch all table updates from queue
func (*StreamServer) PublishStateChanges ¶
func (ws *StreamServer) PublishStateChanges(tableUpdates state.TableUpdateArray, clientEvents []ClientEvent)
this is similar to broadcasting events in Solidity. we broadcast state changes to client along with additional useful metadata, for clients, data pipelines down the line, etc TODO: NOTE: currently we do not broadcast table updates
func (*StreamServer) RemoveConnection ¶ added in v0.1.0
func (ws *StreamServer) RemoveConnection(conn *websocket.Conn)
func (*StreamServer) SetPlayerIdToConnection ¶
func (ws *StreamServer) SetPlayerIdToConnection(playerId int, conn *websocket.Conn)
func (*StreamServer) SetSocketRequestRouter ¶ added in v0.1.12
func (s *StreamServer) SetSocketRequestRouter(router ISocketRequestRouter)
Set socket request router
func (*StreamServer) Start ¶ added in v0.1.12
func (s *StreamServer) Start(ctx *EngineCtx)
Start websocket server TODO: have this return an error?
func (*StreamServer) StartMessageBroadcastLoop ¶ added in v0.1.14
func (ws *StreamServer) StartMessageBroadcastLoop()
Start message broadcast loop
type TickSchedule ¶
type TickSchedule struct { // list of systems that need to be triggered ScheduledTickSystems []TickSystem }
func NewTickSchedule ¶
func NewTickSchedule() *TickSchedule
Initialize an empty tick schedule. Systems are added to the tick schedule
func (*TickSchedule) AddSystem ¶ added in v0.1.12
func (s *TickSchedule) AddSystem(tickInterval int, tickFunction TickSystemFunction)
tick interval in milliseconds
type TickSystem ¶
type TickSystem struct { // how fast the game ticks TickInterval int // tick system function TickFunction TickSystemFunction }
type TickSystemFunction ¶
func CreateGeneralSystem ¶
func CreateGeneralSystem(handler ISystemHandler[any]) TickSystemFunction
general are not triggered by user inputs
func CreateSystemFromRequestHandler ¶
func CreateSystemFromRequestHandler[T any](handler ISystemHandler[T], middlewareFunctions ...IMiddleware[T]) TickSystemFunction
type TransactionCtx ¶
type TransactionCtx[T any] struct { GameCtx *EngineCtx // the transaction entity ID TxId int // access world variables through this W state.IWorld // transaction request parameters Req KeystoneTx[T] EventCtx *EventCtx ErrorReturned bool Meta map[string]any }
transaction ctx
func (*TransactionCtx[T]) EmitError ¶
func (ctx *TransactionCtx[T]) EmitError(errorMessage string, playerIds []int)
emit error
type TransactionSchema ¶
type TransactionSchema struct { // Entity ID Id int `gorm:"primaryKey;autoIncrement:false"` // Transaction type Type string // A uuid that's sent from the client, which is usd to identify which quest has been satisfied Uuid string // Data payload serialized to string format Data string // Tick number when the transaction was to be processed TickNumber int // Timestamp of when the transaction was received by server UnixTimestamp int // whether transaction was submitted by player or other systems IsExternal bool }
func CopyTransactions ¶
func CopyTransactions(transactions []TransactionSchema) []TransactionSchema
type UpdatePacket ¶
type UpdatePacket struct { // array of table update packets that need to be broadcasted to clients TableUpdates []state.TableUpdate `json:"tableUpdates"` // id of package that corresponds with the HTTP requests's returned UUID (similar to a transaction hash) Uuid string `json:"uuid"` // timestamp Time int64 `json:"time"` // error message string returned from a request Message string `json:"message"` }
TODO: unused. remove in future