package field

import "github.com/Diarkis/diarkis/field"

Package field ▷

Creates virtual space where all connected users share the same space and time.

Field allows automated synchronization based on user coordinates in the field space.

[IMPORTANT] Field module can be used along side with Room, Group, and MatchMaker.

Configurations

Field configurations are explained below.

The configuration file must be provided for both the front server (UDP or TCP) and the target node server (Default is HTTP).

{
  "fieldSize": 377970000,
  "fieldOfVisionSize": 1800,
  "syncInterval": 50,
}

▶︎ Configuration Values

fieldSize - Default is 377970000

The surface area size of the entire world to be auto-divided across the server nodes.

fieldOfVisionSize - Default is 1800

It controls the field of vision that the each user can see. This value will NOT be greater than the grid size. When the grid size decreases as the number of grids increase, fieldOfVisionSize may decrease along with it if configured value is greater than the grid size. fieldOfVisionSize is calculated as radius.

syncInterval - Default is 50 ms

It controls the interval of sync or disappear propagation in milliseconds. The minimum value of it is 17 milliseconds. The lower the value is more frequent the propagation is, but with increased server load.

Controls the interval in milliseconds of propagation of sync data to the users that "see" each other. If Sync is called multiple times within the interval, only the last Sync will be propagated to the remote users.

How Field Works

Field divides the whole field defined by "fieldSize" into "grids". Each server in the Diarkis cluster is responsible for one or more "grids". "grids" represent field map based on X and Y coordinates.

▶︎ When the number of servers in the Diarkis cluster changes, the number of "grids"
  and their size change.

▶︎ Users in different "field of view" do not see each other.

▶︎ Moving to a different "grid" that is on another server will cause the user to re-connect.

Users "see" each other if they are in the same "grid".

○ = User with no other users in view
● = User with other users in view

┏━━━━┓
┃    ┃ = Grid
┗━━━━┛

┌────┐
│    │ = Field of Vision
└────┘

╋━━━━━━━━━━━━━╋━━━━━━━━━━━━━╋━━━━━━━━━━━━━╋━━━━━━━━━━━━━━╋
┃  ┌───────┐  ┃             ┃  ○          ┃              ┃
┃  │●      │  ┃      ○      ┃             ┃       ○      ┃
┃  │ ●     │  ┃             ┃         ┌───╂───┐          ┃
┃  └───────┘  ┃             ┃ ○       │●  ┃ ● │        ○ ┃
╋━━━━━━━━━━━━━╋━━━━━━━━━━━━━╋━━━━━━━━━┿━━━╋━━━┿━━━━━━━━━━╋
┃             ┃┌───────┐    ┃       ○ └───╂───┘          ┃
┃      ○      ┃│   ●   │    ┃             ┃              ┃
┃             ┃│  ●  ● │    ┃             ┃          ○   ┃
┃             ┃└───────┘  ○ ┃     ○       ┃              ┃
╋━━━━━━━━━━━━━╋━━━━━━━━━━━━━╋━━━━━━━━━━━━━╋━━━━━━━━━━━━━━╋
┃             ┃             ┃┌───────┐  ○ ┃     ○        ┃
┃       ○     ┃             ┃│●      │    ┃              ┃
┃             ┃             ┃│● ● ●  │    ┃              ┃
┃             ┃      ○      ┃└───────┘    ┃              ┃
╋━━━━━━━━━━━━━╋━━━━━━━━━━━━━╋━━━━━━━━━━━━━╋━━━━━━━━━━━━━━╋
┃             ┃ ┌───────┐   ┃     ○       ┃       ○      ┃
┃             ┃ │  ●●● ●│  ○┃             ┃              ┃
┃   ○         ┃ │  ●● ● │   ┃         ┌───╂───┐          ┃
┃             ┃ └───────┘   ┃    ○    │  ●┃●  │   ○      ┃
╋━━━━━━━━━━━━━╋━━━━━━━━━━━━━╋━━━━━━━━━┷━━━╋━━━┷━━━━━━━━━━╋

▶︎ Users that are close, but in different "grids"

Users that are in different grids may be able to "see" each other as long as they fit within the field of vision (Configured by fieldOfVisionSize).

[IMPORTANT] Synchronizing with users across multiple grids will add extra server load.

  The field of vision spans across two grids.
        ╋━━━━━━━━━━━━━╋━━━━━━━━━━━━━╋
        ┃         ┌───╂───┐   ○     ┃
        ┃         │  ●┃ ● │         ┃
        ┃         │ ● ┃●  │         ┃
        ┃ ○       └───╂───┘   ○     ┃
        ╋━━━━━━━━━━━━━╋━━━━━━━━━━━━━╋

How Grids and Front Servers (UDP/TCP) Interact With Storage Servers (By default HTTP) For Sync and Disappear

Field servers are structured with two separate server components:

1. Front Servers - The front servers communicate the clients directly.

2. Storage Servers - The storage servers manage grids and calculate each users vision. By Default HTTP is used as storage servers.

 The field of vision that fits in a single grid.

 ╋━━━━━━━━━━━━━━╋
 ┃   ┌───────┐○ ┃
 ┃   │ ●     │  ┃
 ┃   │  ●    │  ┃
 ┃○  └───────┘  ┃
 ╋━━━━━━━━━━━━━━╋

  Storage server (By default HTTP) manages grids and user visions.
  Every Sync will be propagated from the front servers to the storage servers (storage server address is resolved from the grid identifier key).
  The storage servers then retrieves the list of users and propagate Sync or Disappear data to appropriate front servers.

  [ NOTE ] Each storage and front server has their own sync loop.
  [ NOTE ] Key (Grid identifier) is created from the user coordinate.

      ┌─────────┐
      │ Storage ├─────────┬────────────┐
      └─────────┘         │            │
          ▲      [ Propagation of Sync or Disappear ]
          │               │            │
[ Sync or Disappear ]     │            │
          │               ▼            ▼
     ┌────┴────┐     ┌─────────┐  ┌─────────┐
     │  Front  │     │  Front  │  │  Front  │
     └─────────┘     └─────────┘  └─────────┘

How Users Across Multiple Grids Are Synchronized

 The field of vision spans across two grids.

       ╋━━━━━━━━━━━━━╋━━━━━━━━━━━━━╋
       ┃         ┌───╂───┐   ○     ┃
       ┃         │  ●┃ ● │         ┃
       ┃         │ ● ┃●  │         ┃
       ┃ ○       └───╂───┘   ○     ┃
       ╋━━━━━━━━━━━━━╋━━━━━━━━━━━━━╋

 If the field of vision spans across multiple grids,
 We synchronize multiple storage servers and propagate Sync data accordingly.
 More field of vision overlaps with different grids, the more storage servers need to be involved for Sync.

[NOTE] A single storage server may contain multiple grids.

       ┌────────────────────────────────────────────────────┬────────────┐
       │                                                    │            │
       │                                                    │            │
       │                                                    │            │
       │             ┌────────────┬────────────┐            │            │
       │             │            │            │            │            │
  ┌────┴────┐   ┌────┴────┐       │            │            │            │
  │ Storage │   │ Storage │       │            │            │            │
  └─────────┘   └─────────┘       │            │            │            │
      ▲              ▲            │            │            │            │
      └──────┬───────┘         [ ---- Propagation of Sync or Disappear ---- ]
             │                    │            │            │            │
   [ Sync or Disappear ]          │            │            │            │
             │                    ▼            ▼            ▼            ▼
        ┌────┴────┐          ┌─────────┐  ┌─────────┐  ┌─────────┐  ┌─────────┐
        │  Front  │          │  Front  │  │  Front  │  │  Front  │  │  Front  │
        └─────────┘          └─────────┘  └─────────┘  └─────────┘  └─────────┘

Setting up Field Module

In order to use Field, you must invoke field.Setup() before calling diarkis.Start().

You must call field.Setup() in front servers (By default UDP and/or TCP) and storage servers (By default HTTP).

Optional Configurations for Field internal storage

Field module has internal storage to store user locations (who is on which server). The storage has multiple optional configurations.

storageTargetNodeType     - Target node type determines the storage to use which servers as storage: Default is HTTP

storageMigration          - Enables or Disables key migration when scaling: Default is true

storageMigrationBatchSize - Number of keys to be batched and migrated at a time.
                            Setting is value large will make the migration time shorter,
                            but setting the value too large may cause each migration packet to split and slow down the migration instead:
                            Default is 10.

storageMigrationInterval  - Interval in milliseconds for each migration batch (server-to-server key transfer) to be sent: Default is 1ms
                            Longer this value is the longer it takes to complete migration, but less server stress.

SyncLimit

Sync function has a parameter called syncLimit. This parameter controls how many Sync/Disappear packets you want to receive at once.

If you set syncLimit to 10, then you will not receive more than 10 Sync/Disappear packets at once. This allows you to control up to how many remote users you want to "see". With the example of syncLimit=10, this will makes sure that you will not "see" more than 10 remote users at a time.

Maximum Data Size For Sync

Each Sync call allows byte array to be synchronized with the users in sight. There is a size limit to the byte array per Sync call.

[IMPORTANT] Larger the data size is the higher the server stress.

Maximum allowed size - 3000 bytes

Index

Functions

func AddUserPositionValidation

func AddUserPositionValidation(validator func(*user.User, int64, int64, int64) bool)

AddUserPositionValidation registers a validation function to be called on Sync

[IMPORTANT] This function can be used ONLY on the front servers (UDP or TCP).

validator - Custom function to be invoked for position validation.

func AfterDisappearCmd

func AfterDisappearCmd(callback func(ver uint8, cmd uint16, payload []byte, userData *user.User, next func(error)))

AfterDisappearCmd registers a command to be executed after field disappear: Must be called before ExposeCommands()

Parameters

ver      - Command ver sent from the client.
cmd      - Command ID sent from the client.
payload  - Command payload sent from the client.
userData - User data representing the client that sent the command.
next     - The function to signal the command to move on to the next operation of the same ver and command ID.
           This function must be called at the end of all operations in the callback.
           If you pass an error, it will not proceed to the next operations of the same command ver and ID.

func AfterLeaveCmd

func AfterLeaveCmd(callback func(ver uint8, cmd uint16, payload []byte, userData *user.User, next func(error)))

AfterLeaveCmd registers a command to be executed after field leave: Must be called before ExposeCommands()

Parameters

ver      - Command ver sent from the client.
cmd      - Command ID sent from the client.
payload  - Command payload sent from the client.
userData - User data representing the client that sent the command.
next     - The function to signal the command to move on to the next operation of the same ver and command ID.
           This function must be called at the end of all operations in the callback.
           If you pass an error, it will not proceed to the next operations of the same command ver and ID.

func AfterSyncCmd

func AfterSyncCmd(callback func(ver uint8, cmd uint16, payload []byte, userData *user.User, next func(error)))

AfterSyncCmd registers a command to be executed after field sync: Must be called before ExposeCommands()

Parameters

ver      - Command ver sent from the client.
cmd      - Command ID sent from the client.
payload  - Command payload sent from the client.
userData - User data representing the client that sent the command.
next     - The function to signal the command to move on to the next operation of the same ver and command ID.
           This function must be called at the end of all operations in the callback.
           If you pass an error, it will not proceed to the next operations of the same command ver and ID.

func BeforeDisappearCmd

func BeforeDisappearCmd(callback func(ver uint8, cmd uint16, payload []byte, userData *user.User, next func(error)))

BeforeDisappearCmd registers a command to be executed before field disappear: Must be called before ExposeCommands()

Parameters

ver      - Command ver sent from the client.
cmd      - Command ID sent from the client.
payload  - Command payload sent from the client.
userData - User data representing the client that sent the command.
next     - The function to signal the command to move on to the next operation of the same ver and command ID.
           This function must be called at the end of all operations in the callback.
           If you pass an error, it will not proceed to the next operations of the same command ver and ID.

func BeforeLeaveCmd

func BeforeLeaveCmd(callback func(ver uint8, cmd uint16, payload []byte, userData *user.User, next func(error)))

BeforeLeaveCmd registers a command to be executed before field leave: Must be called before ExposeCommands()

Parameters

ver      - Command ver sent from the client.
cmd      - Command ID sent from the client.
payload  - Command payload sent from the client.
userData - User data representing the client that sent the command.
next     - The function to signal the command to move on to the next operation of the same ver and command ID.
           This function must be called at the end of all operations in the callback.
           If you pass an error, it will not proceed to the next operations of the same command ver and ID.

func BeforeSyncCmd

func BeforeSyncCmd(callback func(ver uint8, cmd uint16, payload []byte, userData *user.User, next func(error)))

BeforeSyncCmd registers a command to be executed before field sync: Must be called before ExposeCommands()

Parameters

ver      - Command ver sent from the client.
cmd      - Command ID sent from the client.
payload  - Command payload sent from the client.
userData - User data representing the client that sent the command.
next     - The function to signal the command to move on to the next operation of the same ver and command ID.
           This function must be called at the end of all operations in the callback.
           If you pass an error, it will not proceed to the next operations of the same command ver and ID.

func CalcDistance

func CalcDistance(myX, myY, yourX, yourY int64) int64

CalcDistance calculates distance using triangle

     ┌───────────────▶︎ (Me)
     │                ╱│
     │               ╱ │
     │              ╱  │
Distance           ╱   │ Y
     │            ╱    │
     │           ╱     │
     │          ╱    ┏━┥
     └──▶︎ (You) ─────┸─┘
                  X

Parameters

myX   - X coordinate to calculate the distance against yourX.
myY   - Y coordinate to calculate the distance against yourY.
yourX - X coordinate to calculate the distance against myX.
yourY - Y coordinate to calculate the distance against myY.

func DestroyNPC

func DestroyNPC(uid string) error

DestroyNPC removes the locally stored NPC by its UID.

[IMPORTANT] You cannot destroy NPCs that are stored on different servers.
[IMPORTANT] This function will call Leave internally to remove the NPC from Field.
[IMPORTANT] This function removes the NPC from the storage, but if you keep the reference,
            it will not be deleted from your memory.

func Disappear

func Disappear(userData *user.User)

Disappear removes the user from the user entity list to stop from synchronization.

[IMPORTANT] This function is the alias for Leave
[IMPORTANT] This function can be used ONLY on the front servers (UDP or TCP).

Parameters

userData  - User that will propagate the synchronization the data to the users in view.

func ExposeCommands

func ExposeCommands()

ExposeCommands exposes commands to the client to work with Field package

func ExposePufferCommands

func ExposePufferCommands()

ExposePufferCommands exposes commands to the client to work with Field package

func GetFieldOfVisionSize

func GetFieldOfVisionSize() int64

GetFieldOfVisionSize returns the current field of view size.

func GetFieldSize

func GetFieldSize() int64

GetFieldSize returns the current field size.

func GetGridKeyByNodeType

func GetGridKeyByNodeType(x, y int64, nodeType string) string

GetGridKeyByNodeType returns the calculated grid key based on X and Y coordinate given.

Deprecated

This function has been deprecated and should not be used.

[IMPORTANT] Use GetGridKeyByPosition instead.

func GetGridKeyByPosition

func GetGridKeyByPosition(x, y, z int64) string

GetGridKeyByPosition returns the grid key based on X, Y, and Z coordinate.

func GetGridSize

func GetGridSize() int64

GetGridSize returns the size of a grid.

func GetNodeNum

func GetNodeNum() int

GetNodeNum returns the number of grid storage servers

func GetNumberOfGrids

func GetNumberOfGrids() int

GetNumberOfGrids returns the current number of grids.

func GetUserPosition

func GetUserPosition(userData *user.User) (int64, int64, int64)

GetUserPosition returns the given user's current coordinate: X, Y, and Z.

[IMPORTANT] This function can be used ONLY on the front servers (UDP or TCP).
[IMPORTANT] This function uses mutex lock on userData internally.

func Join

func Join(userData *user.User, x, y, z int64, data []byte, syncLimit int, filterID uint8, reliable bool) error

Join initializes the user. The user must "Join" the Field in order to use Sync, Disappear, and Leave.

[IMPORTANT] This function can be used ONLY on the front servers (UDP or TCP).

[NOTE] Z space is not a coordinate, but it describes dimension or space.
       For example, users with the same x and y with different z will not "see" each other.

Parameters

userData  - User that will propagate the synchronization the data to the users in view.
x         - X position of the user to synchronize.
y         - Y position of the user to synchronize.
z         - Z space of the user to synchronize.
data      - Synchronize byte array data. Maximum allowed length is 3000 bytes.
            The data byte array must NOT be empty.
syncLimit - Maximum number of the sync and disappear packets the user allows to receive.
            This limit applies to the packets the user receives NOT the packets the user sends.
filterID  - Unique ID of the custom filter to be applied for this user's synchronization process.
reliable  - whether or not to use reliable UDP on UDP connection

func Leave

func Leave(userData *user.User) error

Leave allows the user to cleanly leave from the Field and resets all Field data of the user.

[IMPORTANT] This function can be used ONLY on the front servers (UDP or TCP).

Parameters

userData  - User that will propagate the synchronization the data to the users in view.

func SetCustomFilter

func SetCustomFilter(customFilterID uint8, filter FilterCallback)

SetCustomFilter defines a custom filter that will be invoked when user client indicates while synchronizing. The purpose of the filter is to manipulate the users in sight for synchronizing.

[IMPORTANT] Custom callbacks are executed on the front node servers (UDP or TCP).
[IMPORTANT] The callback will have both sender and receiver UID, however, the sender user data is not be accessible from the callback.

Parameters

customFilterID - Unique ID to identify the custom filter.
filter         - Custom operation function to perform filtering.

func SetOnDisappear

func SetOnDisappear(cb func(userData *user.User, senderUID string, payload []byte))

SetOnDisappear assigns a callback to be invoked when a user receives a Disappear command from another user.

[IMPORTANT] This callback is called in the front server.

func SetOnSync

func SetOnSync(cb func(userData *user.User, senderUID string, payload []byte))

SetOnSync assigns a callback to be invoked when a user receives a Sync command from another user.

[IMPORTANT] This callback is called in the front server.

func Setup

func Setup(confpath string)

Setup setup Field module.

Parameters

confpath - Absolute path of the configuration file to be loaded.

func Sync

func Sync(userData *user.User, x, y, z int64, data []byte, syncLimit int, filterID uint8, reliable bool) error

Sync updates synchronization data.

[IMPORTANT] This function can be used ONLY on the front servers (UDP or TCP).

[NOTE]      Z space is not a coordinate, but it describes dimension or space.
            For example, users with the same x and y with different z will not "see" each other.

Parameters

userData  - User that will propagate the synchronization the data to the users in view.
x         - X position of the user to synchronize.
y         - Y position of the user to synchronize.
z         - Z space of the user to synchronize.
data      - Synchronize byte array data. Maximum allowed length is 3000 bytes.
            The data byte array must NOT be empty.
syncLimit - Maximum number of the sync and disappear packets the user allows to receive.
            This limit applies to the packets the user receives NOT the packets the user sends.
filterID  - Unique ID of the custom filter to be applied for this user's synchronization process.
reliable  - whether or not to use reliable UDP on UDP connection

Types

type FilterCallback

type FilterCallback func(receiverUser *user.User, senderUID string, distance int64, cmd uint16, payload []byte) bool

FilterCallback is a callback to decide if you want to send a sync message to the receiver user or not.

type MeshData

type MeshData struct {
	Packed []byte `json:"p"`
	sync.RWMutex
}

MeshData represents internally used data transport

type NPC

type NPC struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

NPC represents a non-playable character or an object in the Field.

func GetNPCByUID

func GetNPCByUID(uid string) *NPC

GetNPCByUID returns the NPC by its UID. The function returns nil if matching NPC is not found.

func NewNPC

func NewNPC() (*NPC, error)

NewNPC creates a new NPC and stores it locally.

[IMPORTANT] All NPCs are stored and controlled in the front server.
[IMPORTANT] If the front server that stores NPCs goes away, the NPCs stored there will be lost.

func (*NPC) ClearData

func (n *NPC) ClearData()

ClearData deletes all property data.

func (*NPC) GetDataAsBytes

func (n *NPC) GetDataAsBytes(key string) ([]byte, bool)

GetDataAsBytes returns NPC's property data by its key.

[IMPORTANT] If the value of the key is not the correct data type,
            the function's second return value will be false.

func (*NPC) GetDataAsInt16

func (n *NPC) GetDataAsInt16(key string) (int16, bool)

GetDataAsInt16 returns NPC's property data by its key.

[IMPORTANT] If the value of the key is not the correct data type,
            the function's second return value will be false.

func (*NPC) GetDataAsInt32

func (n *NPC) GetDataAsInt32(key string) (int32, bool)

GetDataAsInt32 returns NPC's property data by its key.

[IMPORTANT] If the value of the key is not the correct data type,
            the function's second return value will be false.

func (*NPC) GetDataAsInt64

func (n *NPC) GetDataAsInt64(key string) (int64, bool)

GetDataAsInt64 returns NPC's property data by its key.

[IMPORTANT] If the value of the key is not the correct data type,
            the function's second return value will be false.

func (*NPC) GetDataAsInt8

func (n *NPC) GetDataAsInt8(key string) (int8, bool)

GetDataAsInt8 returns NPC's property data by its key.

[IMPORTANT] If the value of the key is not the correct data type,
            the function's second return value will be false.

func (*NPC) GetDataAsString

func (n *NPC) GetDataAsString(key string) (string, bool)

GetDataAsString returns NPC's property data by its key.

[IMPORTANT] If the value of the key is not the correct data type,
            the function's second return value will be false.

func (*NPC) GetPayload

func (n *NPC) GetPayload() []byte

GetPayload returns a copy of the latest payload data that has been synchronized.

func (*NPC) GetPositions

func (n *NPC) GetPositions() (int64, int64, int64)

GetPositions returns NPC's current X, Y, Z, coordinates.

func (*NPC) GetUID

func (n *NPC) GetUID() string

GetUID returns the NPC UID as a string.

func (*NPC) GetUIDBytes

func (n *NPC) GetUIDBytes() []byte

GetUIDBytes returns the NPC UID as a byte array.

func (*NPC) IncrDataAsInt16

func (n *NPC) IncrDataAsInt16(key string, d int16) (int16, error)

IncrDataAsInt16 increments NPC's property data by its key. The function returns the result value.

[NOTE] If the key does not exist, it sets the given value as the initial value of the given key.

func (*NPC) IncrDataAsInt32

func (n *NPC) IncrDataAsInt32(key string, d int32) (int32, error)

IncrDataAsInt32 increments NPC's property data by its key. The function returns the result value.

[NOTE] If the key does not exist, it sets the given value as the initial value of the given key.

func (*NPC) IncrDataAsInt64

func (n *NPC) IncrDataAsInt64(key string, d int64) (int64, error)

IncrDataAsInt64 increments NPC's property data by its key. The function returns the result value.

[NOTE] If the key does not exist, it sets the given value as the initial value of the given key.

func (*NPC) IncrDataAsInt8

func (n *NPC) IncrDataAsInt8(key string, d int8) (int8, error)

IncrDataAsInt8 increments NPC's property data by its key. The function returns the result value.

[NOTE] If the key does not exist, it sets the given value as the initial value of the given key.

func (*NPC) Join

func (n *NPC) Join(x, y, z int64, data []byte, filterID uint8, reliable bool) error

Join allows the NPC to join the Field.

[IMPORTANT] It starts keep alive loop to synchronize every 5 seconds.
            Keep alive WILL stop when you call Leave or DestroyNPC.
[NOTE]      Z space is not a coordinate, but it describes dimension or space.
            For example, users with the same x and y with different z will not "see" each other.

Parameters

x         - X position of the user to synchronize.
y         - Y position of the user to synchronize.
z         - Z space of the user to synchronize.
data      - Synchronize byte array data.
            The data byte array must NOT be empty.

func (*NPC) Leave

func (n *NPC) Leave() error

Leave allows the NPC to leave the Field. Users and NPC that were in sight will receive Disappear command.

[IMPORTANT] Leave stops the loop started by StartLoop.

func (*NPC) SetDataAsBool

func (n *NPC) SetDataAsBool(key string, v bool) error

SetDataAsBool sets NPC's property data by its key.

func (*NPC) SetDataAsBytes

func (n *NPC) SetDataAsBytes(key string, v bool) error

SetDataAsBytes sets NPC's property data by its key.

func (*NPC) SetDataAsString

func (n *NPC) SetDataAsString(key string, v string) error

SetDataAsString sets NPC's property data by its key.

func (*NPC) StartLoop

func (n *NPC) StartLoop(interval int64, cb func(uid string))

StartLoop starts a goroutine loop for the NPC to call the given callback at the given interval.

[IMPORTANT] StopLoop, Leave, and DestroyNPC will stop this loop.

Parameters

interval - Interval of the loop to invoke the callback in milliseconds.
cb       - Callback to be invoked at the given interval.

func (*NPC) StopLoop

func (n *NPC) StopLoop()

StopLoop stops the loop started by StartLoop.

func (*NPC) Sync

func (n *NPC) Sync(x, y, z int64, data []byte, filterID uint8, reliable bool) error

Sync allows the NPC to synchronize with other users and NPCs.

[NOTE] Z space is not a coordinate, but it describes dimension or space.
       For example, users with the same x and y with different z will not "see" each other.

Parameters

x         - X position of the user to synchronize.
y         - Y position of the user to synchronize.
z         - Z space of the user to synchronize.
data      - Synchronize byte array data.
            The data byte array must NOT be empty.

func (*NPC) UpdateDataAsBytes

func (n *NPC) UpdateDataAsBytes(k string, cb func(currentValue []byte) ([]byte, bool)) ([]byte, error)

UpdateDataAsBytes allows you to update the value of the key using a callback. The function returns the updated value and an error if there is an error.

[IMPORTANT] The callback is executed while a mutex lock is held.
[IMPORTANT] If the key does not exist, it will return an error.

func (*NPC) UpdateDataAsInt16

func (n *NPC) UpdateDataAsInt16(k string, cb func(currentValue int16) (int16, bool)) (int16, error)

UpdateDataAsInt16 allows you to update the value of the key using a callback. The function returns the updated value and an error if there is an error.

[IMPORTANT] The callback is executed while a mutex lock is held.
[IMPORTANT] If the key does not exist, it will return an error.

func (*NPC) UpdateDataAsInt32

func (n *NPC) UpdateDataAsInt32(k string, cb func(currentValue int32) (int32, bool)) (int32, error)

UpdateDataAsInt32 allows you to update the value of the key using a callback. The function returns the updated value and an error if there is an error.

[IMPORTANT] The callback is executed while a mutex lock is held.
[IMPORTANT] If the key does not exist, it will return an error.

func (*NPC) UpdateDataAsInt64

func (n *NPC) UpdateDataAsInt64(k string, cb func(currentValue int64) (int64, bool)) (int64, error)

UpdateDataAsInt64 allows you to update the value of the key using a callback. The function returns the updated value and an error if there is an error.

[IMPORTANT] The callback is executed while a mutex lock is held.
[IMPORTANT] If the key does not exist, it will return an error.

func (*NPC) UpdateDataAsInt8

func (n *NPC) UpdateDataAsInt8(k string, cb func(currentValue int8) (int8, bool)) (int8, error)

UpdateDataAsInt8 allows you to update the value of the key using a callback. The function returns the updated value and an error if there is an error.

[IMPORTANT] The callback is executed while a mutex lock is held.
[IMPORTANT] If the key does not exist, it will return an error.

func (*NPC) UpdateDataAsString

func (n *NPC) UpdateDataAsString(k string, cb func(currentValue string) (string, bool)) (string, error)

UpdateDataAsString allows you to update the value of the key using a callback. The function returns the updated value and an error if there is an error.

[IMPORTANT] The callback is executed while a mutex lock is held.
[IMPORTANT] If the key does not exist, it will return an error.