Slide 1

Slide 1 text

Christian Kvalheim - [email protected] twitter: @christkv Mongoman A Node.Js Powered Pacman Clone Friday, July 6, 12

Slide 2

Slide 2 text

WHO AM I •Wrote node.js driver for mongodb •Working for 10gen (you know the MongoDB company) •Based in Barcelona •I run •http://www.meetup.com/ mongodb-spain/ Friday, July 6, 12

Slide 3

Slide 3 text

WHY PACMAN NOSTALGIA Friday, July 6, 12

Slide 4

Slide 4 text

History of Pacman Friday, July 6, 12

Slide 5

Slide 5 text

The original pacman Friday, July 6, 12

Slide 6

Slide 6 text

32 years later Friday, July 6, 12

Slide 7

Slide 7 text

A RANT Friday, July 6, 12

Slide 8

Slide 8 text

The evolution of Game 1980S Friday, July 6, 12

Slide 9

Slide 9 text

The evolution of Game 1990S Friday, July 6, 12

Slide 10

Slide 10 text

The evolution of Game 2000S Friday, July 6, 12

Slide 11

Slide 11 text

The evolution of Game 2010S Friday, July 6, 12

Slide 12

Slide 12 text

The HTML5 state 2012 1980ish Friday, July 6, 12

Slide 13

Slide 13 text

Really this is Gaming ? •1980’s technology = Canvas •WEBGL IS NOT A STANDARD •NaCl IS NOT A STANDARD •Flash will have to stay for awhile YES REALLY Friday, July 6, 12

Slide 14

Slide 14 text

Building Pacman MongoMan Friday, July 6, 12

Slide 15

Slide 15 text

Challenges •Latency, Latency, Latency •Spend minimal time in the Eventloop •Process locality on server •Checking settings •Idle garbage collection •Socket noDelay •Minimize GC work Friday, July 6, 12

Slide 16

Slide 16 text

MongoMAN Friday, July 6, 12

Slide 17

Slide 17 text

Game Architecture Express.JS WEBSOCKET AKIHABARA SOUNDJS CLIENT SERVER Friday, July 6, 12

Slide 18

Slide 18 text

Technology •Node.JS •Akihabara for game engine •SoundJS for the audio •websocket npm package •Socket.IO was a lot slower •Mongo capped collections •findAndModify for board allocation Friday, July 6, 12

Slide 19

Slide 19 text

Akihabara •Retro 2D game engine •“Simple” to adapt example game to Mongoman •Uses canvas only so not the fastest game engine out there but plenty good enough :) Friday, July 6, 12

Slide 20

Slide 20 text

Websocket npm package •Pure websocket implementation •No fallback compatibility •Supports binary frame protocol for Websockets •Fast Friday, July 6, 12

Slide 21

Slide 21 text

SoundJS •Manages all the complexity of audio in the browser •Mixes audio •Simple to use API Friday, July 6, 12

Slide 22

Slide 22 text

Mongo Capped collections •Positives •Fifo based limiting memory exposure •Documents don’t move in memory •Predictable time to write/ read from collection •Supports Indexes •Tailable (like tail -f) Friday, July 6, 12

Slide 23

Slide 23 text

Mongo Capped collections •Negatives •Documents cannot grow so we need to prime each document Friday, July 6, 12

Slide 24

Slide 24 text

Node.JS Cluster •Express serves up the basic html pages and handles the hiscore list. •Organized using the cluster api in Node.js 0.6.X •1 parent process and X child processes handling game •If a child dies a new one is born Friday, July 6, 12

Slide 25

Slide 25 text

Cluster code // Fork workers (one pr. cpu), the web workers handle the websockets for (var i = 0; i < numCPUs; i++) { var worker = cluster.fork(); worker.on('message', function(msg) { if(msg != null && msg['cmd'] == 'online') { console.log("================================ worker online"); console.dir(msg); } }); } // If the worker thread dies just print it to the console and for a new one cluster.on('death', function(worker) { console.log('worker ' + worker.pid + ' died'); cluster.fork(); }); Friday, July 6, 12

Slide 26

Slide 26 text

Session workaround •Could not use express sessions as they don’t work with the websocket module •Wrote own session handling using capped collection •A bit HACKY but works •Using named cookie to tie sessions together •I should probably fix it Friday, July 6, 12

Slide 27

Slide 27 text

Websocket session grab code // Parse the cookie var cookie = connectUtils.parseCookie(request.httpRequest.headers['cookie']); // Grab the session id var sessionId = cookie['connect.sid']; // Grab the username based on the session id and initialize the board state.sessionsCollection.findOne({id:sessionId}, function(err, session) { if(err) throw err; session = typeof session == 'undefined' || session == null ? {} : session; initializeBoard(state, session, self); }) •Uses connect npm package for nice to have cookie parser functions •Using capped collection as well Friday, July 6, 12

Slide 28

Slide 28 text

.findAndModify( {number_of_players: {$lt:5}, pid: process.pid}, [], {$inc: {number_of_players: 1}, $push:{players:connection.connectionId}}, {new:true, upsert:false}, function(err, board) { // Code to deal with the board or the non existance of the board } Initializing a board •Using findAndModify to pick a board •Atomic operation to add player to existing board •Process bound Friday, July 6, 12

Slide 29

Slide 29 text

Sample ghost state machine FIGURE 1. State diagram for Pac-Man ghost AI A state machine can also be represented by a table, but in general, the state diagram is more intuitive, making it easier to consider how the system works as a whole. A table can be useful in Friday, July 6, 12

Slide 30

Slide 30 text

Our simplified one FIGURE 1. State diagram for Pac-Man ghost AI A state machine can also be represented by a table, but in general, the state diagram is more intuitive, making it easier to consider how the system works as a whole. A table can be useful in YOU Friday, July 6, 12

Slide 31

Slide 31 text

Simple example of state mongoman ghost ghost ghost ghost server movement collision +ghost +powerpill ghostdead Friday, July 6, 12

Slide 32

Slide 32 text

All messages are belong to •Messages from server •initialize •dead •mongowin •ghostdead •powerpill •movement Friday, July 6, 12

Slide 33

Slide 33 text

Current state of affairs •Collision detection managed on server •Pills are not managed on server •Might need to move the entire board to server Friday, July 6, 12

Slide 34

Slide 34 text

Friday, July 6, 12

Slide 35

Slide 35 text

One for all, all for one •Websocket connections are bound to a specific process •Avoids overhead •Would need separate IO queues, would cause latency Friday, July 6, 12

Slide 36

Slide 36 text

Garbage collection •Keeping a lot in memory •disable v8’s idle garbage collection •“–nouse-idle-notification” •avoid v8 needing to iterate over a massive list of objects that are not collectable •lowers latency and pauses Friday, July 6, 12

Slide 37

Slide 37 text

Connections •Ensure you use noDelay(true) •Sends packets as fast as they arrive not doing any buffering •Set to true by default Friday, July 6, 12

Slide 38

Slide 38 text

Native BSON parser in Node •Using bson native parser •avoid intermediate memory allocation •uses less memory •slightly faster •Waiting for a patch to take the performance up massively Friday, July 6, 12

Slide 39

Slide 39 text

Light speed that #@!@#$ •Your max resolution is 2X times the ping time to the server •20ms = 40 ms delivery = 25 fps •135 = 270 ms delivery = 4 fps •Now you know why it’s a WOW EU server or US server Friday, July 6, 12

Slide 40

Slide 40 text

Friday, July 6, 12

Slide 41

Slide 41 text

•Websockets still fresh •Few browsers support binary •Understand memory/cpu at high connection count •Avoid process switching is possible •Latency is the mind killer •If you users are in Germany have a local server for Germany Keep in mind Friday, July 6, 12

Slide 42

Slide 42 text

•How much data are you pushing across the wire •What’s the ping time to the client •Profile both the browser and the server using available tools •Chrome development tools •Collect stats wire usage etc. Profile the game Friday, July 6, 12

Slide 43

Slide 43 text

Whats on the horizon Friday, July 6, 12

Slide 44

Slide 44 text

•WebGL Coming in iOS at some point soon as well as Android •In the near future we can use for real 2+ years I recon •Supported by Firefox, Chrome and Safari and even Opera but not IE (probably NEVER) WebGL and mobile Friday, July 6, 12

Slide 45

Slide 45 text

•Initial support in Chrome •Pros •No waiting for ack •Lower latency •Cons •Lost messages •No resend UDP might be coming Friday, July 6, 12

Slide 46

Slide 46 text

Next project in the works •Write a tank AI to do battle •DCPU-16 support •Want to help ? •I need graphics and coding help :) •Launching as soon as it’s ready Friday, July 6, 12

Slide 47

Slide 47 text

Game TIME Friday, July 6, 12

Slide 48

Slide 48 text

Demo game •Join in the game, DDOS My Mac Mini. •SSD: mongoman •Password: mongoman •IP: http://192.168.1.100 Friday, July 6, 12

Slide 49

Slide 49 text

Where to get the code •https://github.com/christkv/ mongoman Friday, July 6, 12