Multiplayer JS game platform
JavaScript HTML CSS
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.


Nintendo is great because everyone sits in a room and plays games together, but why buy a console? Why limit to 4 players? Everyone has a phone that can turn into a controller, and at least a laptop for the main screen. Let's bring in-person multiplayer to the web! And because the framework is as vanilla as possible, it should be easy to port existing games.

Heroku demo (iOS browser is broken since it doesn't support browser WebRTC, native app on iTunes(src))


npm install
npm start

Visit http://localhost:8080 in two tabs. Click host in one and player in the other. For the player, the controller only responds to touch events, so open devtools (⌘-alt-j) and switch to device mode (⌘-⬆-m).

If you're making changes to hosts/clients, use

npm run webpack

If you're making changes to server.js consider

devtool server.js -w

Add a new game

  • First fork the repo
  • Copy an existing game
cp -r public/spacewar public/mynewgame
  • You'll need a host and a client. Pay particular attention to the transport hooks. See public/scripts/webtendo.js for documentation.
import * as webtendo from '../scripts/webtendo';
webtendo.callbacks.onMessageReceived = x => { ... };
webtendo.callbacks.onConnected = id => { ... };
webtendo.sendToClient(recipientId, obj);

// Client library
import * as client from '../scripts/client';
client.callbacks.onTouch = function(e, touch, region) { ... };
  • Add an entry for your host and client to webpack.config.js
  • Restart the webpack watcher if it's already running, or start it with npm run webpack
  • Add your new host and client entries to public/index.html
  • Send a pull request! Once it's in I'll deploy for you.


  • Signaling server + WebRTC transport
  • Send data directly between local network devices
  • Performance analysis
  • Master/slave mode
  • Multiple clients
  • Automatic connection integrity (refresh robust)
  • Standard "controller" w/ forwarded touch events
  • Example game
  • Heroku deployment
  • Game selection
  • Automatic/manual room determination based on external IP
  • Native client (at 8enmann/WebtendoClient)
  • Analytics
  • Game rating

Comms flow

In public/scripts/webtendo.js

  1. Socket connection to server
  2. Host asks server to join a room (emit 'create or join')
  3. Get back 'created'
  4. Client asks to join
  5. Host & client get 'joined' event
  6. Everyone creates a peer connection and sends ICE candidates to other listeners through server.
  7. Host creates a data channel.
  8. Host creates an offer and sends it through the server to clients.
  9. Clients receive offer and send an answer through the server.
  10. Host receives answer and data channel opens.