# GarageServer.IO
A simple, lightweight, HTML multiplayer game server (and client) for Node.js
## Features
- Authoritative Game Server
- Client Side / Input Prediciton
- Client Side Smooting
- Entity Interpolation
- Server State History
- Server and Client Messaging
## Quick Start
### Server
```js
var garageServer = require('garageserver.io'),
// Create instance of GarageServer.IO - pass in a Socket.IO instance and GarageServer.IO options
var server = garageServer.createGarageServer(sockets,
{
interpolation: true,
clientSidePrediction: true,
worldState: { width: '400px', height: '400px'; }
});
// Start GarageServer.IO instance prior to starting physics loop
server.start();
// Inside physics loop, process inputs for players, process entites and update states
var players = server.getPlayers(),
entities = server.getEntities();
players.forEach(function (player) {
// Calculate new state from player.state, player.inputs and send GarageServer.IO new state
server.updatePlayerState(player.id, newState);
});
entities.forEach(function (entity) {
// Calculate new state from entity.state and send GarageServer.IO new state
server.updateEntityState(entity.id, newState);
});
```
### Client
```js
// Initialize GarageServer.IO
GarageServerIO.initializeGarageServer('http://insertmygameurlhere.com', {
onReady: function () {
// Call your game loop
},
onUpdatePlayerPrediction: function (state, inputs, deltaTime) {
// If using client prediction, process over inputs using current state and deltaTime and return new state
},
onInterpolation: function (previousState, targetState, amount) {
// If interpolating, return new state using the previous state, target state, and the amount of progress towards the latter
},
onWorldState: function (state) {
// Extract world state sent from server
}
};
// Inside render loop, extract player and entity states
GarageServerIO.getStates(function (playerStates, entityStates) {
playerStates.forEach(function (player) {
ctxCanvas.fillRect(player.state.x, player.state.y, 5, 5);
});
entityStates.forEach(function (entity) {
ctxCanvas.fillRect(entity.state.x, entity.state.y, 5, 5);
});
});
// Inside physics loop, capture and send input
GarageServerIO.addInput(myInput);
```
## API
### Client
#### initializeGarageServer
---
```js
GarageServerIO.initializeGarageServer(path, options)
/*
options = {
onPlayerConnect(callback),
onPlayerDisconnect(callback),
onPlayerReconnect(callback),
onPlayerUpdate(callback(state)),
onEntityUpdate(callback(state)),
onPlayerRemove(callback(id)),
onEntityRemove(callback(id)),
onEvent(callback(data)),
onWorldState(callback(state)),
onPing(callback(pingDelay)),
onUpdatePlayerPrediction(callback(state, inputs, deltaTime) : newState),
onInterpolation(callback(previousState, targetState, amount) : newState),
onReady(callback),
logging: true
}
*/
```
**path**
Type: string
**options**
Type: object literal
#### addInput
---
```js
GarageServerIO.addInput(input)
```
**input**
Type: object literal
#### getStates
---
```js
GarageServerIO.getStates(callback([, playerState], [, entityState]))
```
**callback**
Type: function(playerStates, entityStates)
**playerStates**
Type: array of object literals
**entityStates**
Type: array of object literals
#### getId
---
```js
GarageServerIO.getId() : playerid
```
**playerid**
Type: number
#### sendServerEvent
---
```js
GarageServerIO.sendServerEvent(data)
```
**data**
Type: object literal
### Server
#### createGarageServer
---
```js
require('garageserver.io').createGarageServer(io, options) : GarageServerIO
/*
options = {
stateInterval: 45,
logging: true,
clientSidePrediction: true,
interpolation: true,
interpolationDelay: 100,
smoothingFactor: 0.3,
pingInterval: 2000,
maxUpdateBuffer: 120,
maxHistorySecondBuffer: 1000,
worldState: {},
onPlayerConnect(callback(socket)),
onPlayerInput(callback(socket, input)),
onPlayerDisconnect(callback(socket)),
onPing(callback(socket, data)),
onEvent(callback(data))
}
*/
```
**io**
Type: Socket.IO instance
**options**
Type: object literal
#### start
---
```js
GarageServerIO.start()
```
#### stop
---
```js
GarageServerIO.stop()
```
#### getPlayers
---
```js
GarageServerIO.getPlayers() : [,{ id, state, [,inputs], [,{ states, executionTimes }] }]
```
**id**
Type: string
**state**
Type: object literal
**inputs**
Type: array of object literals
**stateHistory**
Type: array of object literals
#### getEntities
---
```js
GarageServerIO.getEntities() : [,{ id, state, [,{ state, executionTime }] }]
```
**id**
Type: string
**state**
Type: object literal
**stateHistory**
Type: array of object literals
#### updatePlayerState
---
```js
GarageServerIO.updatePlayerState(id, state)
```
**id**
Type: string
**state**
Type: object literal
#### updateEntityState
---
```js
GarageServerIO.updateEntityState(id, state)
```
**id**
Type: string
**state**
Type: object literal
#### addEntity
---
```js
GarageServerIO.addEntity(id)
```
**id**
Type: string
#### removeEntity
---
```js
GarageServerIO.removeEntity(id)
```
**id**
Type: string
#### sendPlayerEvent
---
```js
GarageServerIO.sendPlayerEvent(id, data)
```
**id**
Type: string
**data**
Type: object literal
#### sendPlayersEvent
---
```js
GarageServerIO.sendPlayersEvent(data)
```
**data**
Type: object literal
## Resources
## License
[MIT License](https://github.com/jbillmann/GarageServer.IO/blob/master/LICENSE.md)