Skip to content

Example Host

In this example a host node is used to handle game logic, physics, and network updates. It is the authority for the game state, and is responsible for broadcasting updates to the clients.

host.js
import EchoD from 'echo-d';

Prepare an events object to handle events such as actorInput.

host.js
import { events } from './events.js';

Include the listenToClients and broadcastClients methods from the transport layer.

host.js
import { listenToClients, broadcastClients } from './transport.js';

Echo-D Host Instance

Create a new Echo-D instance, and pass in the events along with options. The events will be used to handle events such as actorInput.

In this example we are using f32 for position components, and compressing strings as integers. We are also setting isAuthority to true, and isSymbolLeader to true. compressStringsAsInts is enabled to reduce the size of messages.

The updateOptions are used to specify which updates to send to the clients. In this example we are only sending position updates and inputs are masked from the host becayse they are only allowed from clients.

host.js
const echoOptions = {
compressStringsAsInts: true,
isAuthority: true,
isSymbolLeader: true,
types: { position: [ 'f32', 3 ] },
responder: broadcastClients,
updateOptions: {
mask: { inputs: true },
validkeys: { position: true }
}
};
const echoD = new EchoD( { events }, echoOptions );

Listen to Clients

Import the listenToClients and broadcastClients methods from the transport layer. Listen to clients and handle incoming messages with Echo-D.

host.js
listenToClients( echoD );

Game Loop

Use Echo-D to perform a game network update by broadcasting updates to the clients.

host.js
function gameNetworkUpdate ( ) {
echoD.updater( );
}

Create a game loop function to handle game logic, physics, and network updates.

host.js
function gameLoop ( ) {
// gamePhysicsOrOther();
gameNetworkUpdate( );
}

Setup the game loop using setInterval, or use a different game loop method.

host.js
let gameInterval = null;
export function gameStart ( ) {
gameInterval = setInterval( gameLoop, 1000 / 30 );
}
export function gameStop ( ) { clearInterval( gameInterval ); }
gameStart( );

Actor Input Handler

Add an event listener for actorInput events. This will be used to handle actor inputs. In this example inputs are used to move the position of actors.

host.js
events.on('actorInput', ( id, input, index, tick ) => {
const position = echoD.store.findComponent( id, 'position' ) || [ 0, 0, 0 ];
echoD.upsertComponent( id, 'position', new Float32Array( [
position[ 0 ] + ( input.x || 0 ),
position[ 1 ] + ( input.y || 0 ),
position[ 2 ] + ( input.z || 0 ),
] ) );
} );

Host Transport Layer

Choose a network transport layer such as BroadcastChannel, WebSocket, or WebRTC.

Create a BroadcastChannel instance for broadcasting to game clients.

host/transport/bc.js
const bcGameClients = new BroadcastChannel( 'game-clients' );
const bcGameHost = new BroadcastChannel( 'game-host' );

Now setup a message handler for the bcGameHost. This example only supports one host and multiple clients. Handle messages by passing them to the Echo-D instance.

host/transport/bc.js
export function listenToClients ( echoD ) {
bcGameHost.onmessage = ( { data } ) => echoD.many( data );
}

Implement a broadcastClients method to broadcast a message to the clients.

host/transport/bc.js
export function broadcastClients ( message ) {
bcGameClients.postMessage( message );
}

Default Client Transport

Provide a way to import the broadcastClients method from ./host/transport.js.

Set the default transport to BroadcastChannel.

host/transport.js
export * from './transport/bc.js';