- Basic server config
- Linode, Ubuntu
- Paul Armstrong’s node.js boilerplate
- express.js HTTP
- strictly to serve up JS game engine and dependent files
- game then played via socket.io, no more HTTP calls
- socket.io.js
- setup super simple and very loosely coupled
- you just pass it your HTTP server in node.js
- talk to it independently from your HTTP server
- underscore.js
- mostly for object helper functions like extend(), each() on node.js side
- Client config
- socket.io.js
- socket.io magically makes client JS files available in your node.js HTTP server
- WebSockets vs COMET/long-polling etc totally transparent
- underscore.js
- mostly because it is used in JS code shared between client and server
- jquery.js
- with jquery CSS transform patch
- custom game engine, DOM not Canvas
- Basics
- need to model the game on both the client and the server
- having both the client and the server written in JS is super nice
- didn’t have to create Bananas entities in both JS and also Python, Ruby, or PHP
- literally, server needs to calculate orbital mechanics of flight of all bananas, etc
- it must be an authoritative source of info
- tell a new joining player where all the entities are currently
- keep clients in sync
- let players know if they were actually hit or scored
- prevent cheating
- in client-server code, never ever ever trust the client
- server always refers to its own model
- clients don’t even send position info
- client just sends inputs
- I am moving
- I stopped moving
- I threw a banana this direction with this force
- server sanity checks
- our 48 hour server game loop
- all incoming info from client asynchronous via sockets.io
- although, practically speaking, these updates will be made between ticks of the loop
- server has synchronous simulation loop @ 30 FPS
- no need to draw… just updating data
- “ticks” or steps all the entities
- check if player should be moved, move them
- orbit/collide bananas
- etc
- server sends clients (players) updated data/events from synchronous loop
- data sent asynchronously, but in-order
- our 48 hour client game loop
- all incoming info from server asynchronous via sockets.io
- although, practically speaking, these updates will be made between ticks of the loop
- client has synchronous simulation loop @ 30 FPS
- “ticks” or steps all the entities
- update entity positions/state
- “draw” entities - offloaded to DOM, no erase cycle
- client sends player generated events to server asynchronously via sockets.io
- if player starts moving by pressing keyboard key, event sent to server
- if player fires banana, event sent to server
- truth about the game loops… trade offs… optimizations
- bananas
- server must simulate them to verify who hits who
- server could MAYBE stream positions of all bananas to clients at 30FPS … but that’s CRAAAAAZY
- in reality: clients model bananas themselves
- skip all that network traffic
- but collision events comes from server model over sockets
- gorillas
- server must simulate their movement to verify throwing positions
- same issues as bananas…. but gorillas << bananas
- in reality: clients model the gorillas themselves, but get server corrections
- server sends corrections from its model to all players @ 2fps
- consequences
- yay: very light network traffic
- player joins/leaves
- player input state change
- player hit
- banana created/destroyed
- player movement corrections
- boo: sometimes collisions (explosions) and bananas are a little out of sync
- boo: sometimes player movement is jittery
- sharing client and server code with node.js
- in reality, for our KO build, we had only one direction code share… the server Entity code for the bananas/gorillas/explosions/etc extends the client version of this code.
- in practice, we could have shared more code both ways, in particular the main Game object
- inheritance pattern
- inheritance-example.js
- using translation, preferrably 3d
thanks