client (serverside)

Updated for v1.0.0

The serverside `client` object is accessible onConnect and while reading commands. Feel free to attach your own game data to the client object (or create an object that can be looked up by the client.id). Clients are created onConnect, and destroyed onDisconnect. You may also manually invoke instance.disconnect(client).

client.latency

Returns the average round trip latency time in milliseconds.

client.view

The client.view is an axis-aligned bounding box associated with any client connected to an instance.

This view is used by a nengi.Instance to determine which entities and localMessages are visible to a client. Any localMessage or entity outside of a client's view is culled (meaning that it is not sent over the network to that client).

A future version of nengi will allow for 3D view culling. If you are making a 3D game currently just set the 2D view to something huge.

// example
client.view = { 
    x: 0, 
    y: 0, 
    halfWidth: 400, 
    halfHeight: 300 
}

views and entities

When an entity first enters a client's view, the nengi.Instance will send the client a 'create' message for the entity.

If an entity remains within a client's view, the nengi.Instance will analyze the entity for changes each frame. If the entity experiences any changes the client will be sent an 'update' message for the entity.

If an entity leaves a client's view, the nengi.Instance will send a 'delete' message containing the entity id.

Disable culling: make the view big

instance.onConnect(client => {
    // can be anything so long as it includes the entire game world
    client.view = {
        x: 0,
        y: 0,       
        halfWidth: 99999, // number bigger than your game world
        halfHeight: 99999
    }
})

Any object appearing between -99999, -99999, and 99999, 99999 will then be sent to this client. It is up to the game logic to make entities appear in the relevant area, so clamp their x,y if they stand a chance of getting out.

As the number of entities and/or clients increase, the game will eventually hit a performance limit (which still might be overkill for your game, test and see!). This limit will likely be sooner than a game with culling.

Creating a game with a moving camera and culling

Simply move the view to the desired position. In this example we create an entity for the player, and then create an update function which will keep client.view centered on that entity.

instance.onConnect(client => {
    const entity = new Hero() // presuming Hero is an entity
    // center this client's view on their character
    client.view = {
        x: entity.x,
        y: entity.y,
        halfWidth: 1000,
        halfHeight: 600
    }
    client.entity = entity // give our client a reference to the character
    entity.client = client // also helpful!
    instance.addEntity(entity)
})


function update() {
    // every update, center each client's view on their entity
    const clients = instance.clients.toArray()
    clients.forEach(client => {
        client.view.x = client.entity.x
        client.view.y = client.entity.y
    })    
}

This will result in an 2000x1200 view attached to the player.

Tip: views should be larger than the actual rendered area on the game client.