client.view

Updated for v0.3.3

Disambiguation: `client` is the object created on the server when a player connects. This is not to be confused with the nengi.Client, which is the browser-side of nengi's api.

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).

// from nengi/core/instance/Client.js
this.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 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.

A single screen game, or a game with no culling by the instance

instance.onConnect(client => {
    // can be anything so long as it includes the entire game world
    client.view = {
        x: 0,
        y: 0,       
        halfWidth: 99999, // really big number
        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

Within your game logic, 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 => {
    let entity = new Hero() // create a character for this client
    // center this client's view on their character
    client.view = {
        x: entity.x,
        y: entity.y,
        halfWidth: 400,
        halfHeight: 300
    }
    client.entity = entity // give our client a reference to the character
    instance.addEntity(entity)
})


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

This will result in an 800x600 view that is centered on the hero. Each time update is called the view will be recentered onto the hero.

Note: a view should be larger than the intended viewable are in the browser, so that small amounts of lag does not cause entitiest to suddenly teleport from the edge of the screen. In most games it will be fine to have the network view considerably larger than what can be seen.