11 ms·
Building multiplayer games with Socket.io and HTML5 Canvas
- majc2 9y agoGreat fun - one suggestion would be if it could tell you who you are when you start.
- synthmeat 9y agoI'm doing similar, it's so much fun, and here are my takeaways: - Ignore socket.io, do pure binary websocket - Do not serialize JSON, or use msgpack or protobuf - write your own protocol. - Write tests for protocol, you need fast iteration. It's super easy to write tests for codec. - Quadtrees are kinda lousy compared to r-trees. - Measure everything with realistic load - i.e. I've found out that it's more costly to calculate world entity deltas to send to client, than to send everything in his view. - Keep client updates under MTU payload. This is basically impossible with JSON. - Mutability is the way to go for performance. - Share code with backend and frontend, you'll need it for client prediction. - Prefer fixed entity speeds. - Don't log per-frame in production, journalctl will eat up your memory. - Write game bots to test your load non-synthetically. - Test on your VPS, you'll be surprised how underperforming CPUs are in most providers. Neighbours are probably serving some CRUD and are very likely not to be as noisy as you are. Now, all this might not apply depending on exact gameplay mechanics you have, but it works for me. I have Node.js serving 200 clients and 10k entities with vision (can run at or from you) at 20 frames per second that keeps under 100MB RAM with no hiccups. I think I could use something like Golang for some more advanced physics though. A question to all reading - I'm considering adding an option to mine Monero in my next game. It'd probably be a flip-switch between ads and mining right there on the home screen, with some intelligent throttle/thread decisions depending on the kind of device game is running on. I'd appreciate any feedback regarding the sentiment on that.
- gfysfm 9y ago>Write game bots to test your load non-synthetically. Can you expand a bit more on that? Cool tips, for sure. Personally I'd appreciate a flip-switch between ads and mining, as long as it defaulted to ads.
- synthmeat 9y agoIn my particular game, for core gameplay, I'm just sending the angle and whether the action button is down or up. So I just slapped together a Node.js script to spawn N clients that, according to some simple logic send that input to server. They don't even interpret what server sends back to them, because I'm testing the server-side with them. Bonus is that you can test your algos in extreme circumstances, like send all clients to particular spot on the map, so you can see how it performs with different distributions of locations. This was invaluable to almost all multiplayer games I did. Wrt mining/ads, I'm considering to default to mining if I detect ad-blocker, or you're on Chrome + Desktop PC (not laptops).
- gfysfm 9y ago> Wrt mining/ads, I'm considering to default to mining if I detect ad-blocker, or you're on Chrome + Desktop PC (not laptops). Do what you've gotta do to get paid for your work, but if I found out this was happening it would strongly discourage me from remaining on the website.
- bsaul 9y agoIn case you haven't reached that point yet : also evaluate how much network badnwidth is going to cost you if you ever host your servers on aws or gcloud and encounter average success. You may be in for a (bad) surprise. Now compare that to how much you'll gain from ads. And soon you'll realize one huge issue you're going to have is to maintain your own servers a little bit everywhere in the world.
- synthmeat 9y agoI've carefully measured and worked toward 1TB/month/VPS at full load. Didn't get there, but now I'm at 2TB (still estimates). With socket.io and JSON, that'd easily blow up to few hundreds TB/month. DigitalOcean for now (but that might change in the future) still doesn't charge on overages, but you do get a slap on the wrist of some kind if you go way overboard, so it's preferable solution to other VPS providers. It's good that you mention this, since I've heard "horror" stories of people working in this space earning about $10k/mo but spending as much and more on AWS.
- nickrio 9y agoWow, I'm not a game dev pro. But 200 clients + 10K entities could cause that amount of traffic?
- synthmeat 9y agoYeah, I've choked one office network on a client project (they went through VPN though) with bot tests. :D But single-digit TB monthly outbound per VPS was not that surprising to me. Almost triple-digit one in naive implementation, scared the hell out of me first time around. Spent hours double and triple-checking and measuring. :D
- zubspace 9y agoIf you are writing a game server with web, mobile and desktop clients, is socket.io the way to go? AFAIK, socket.io is a wrapper around websockets. This makes it unsuitable for some fast paced games with alot of players. Is there a library which abstracts away tcp and udp connections? And what can you do about tcp attack vectors? Are lamers trying to take down servers a real threat? How do you prepare for this? I therefore advise against writing your own network stack if you intend to make the service available to the public. Or am I too cautious?
- synthmeat 9y ago> If you are writing a game server with web, mobile and desktop clients, is socket.io the way to go? Socket.io's most discerning feature was fallback to polling. There's also some useful abstractions there, like reconnecting, rooms, as well as some useful ecosystem around it, like socket.io-redis adapter which enables you transparently scale horizontally. If your time is at premium, you might find socket.io work for you, but it's not really hard to write everything better yourself, and better tuned to your use-case. > AFAIK, socket.io is a wrapper around websockets. This makes it unsuitable for some fast paced games with alot of players. For fast-action multiplayer, there's currently no sensible offering besides WebRTC's DataChannel, with all it brings on board (I've yet to study it in-depth). I'm having high hopes for QUIC to gain more ground. > And what can you do about tcp attack vectors? Are lamers trying to take down servers a real threat? From what I've experienced first hand, bots/scripts are most frequent enjoyment-spoiler for other players. I've never ran at scale where I'd be interesting target for actual attacks.
- gfysfm 9y agoAs for udp connections, WebRTC looks like the only mature solution (but it's not designed for games and is way more complicated than game devs want it to be). Alternatively, I know about https://github.com/networkprotocol/netcode.io https://github.com/networkprotocol/netcode.io but it's very much in the early stages - afaik you even need a Chrome extension to use it on the client. It's not easy to do udp on the web.
- lxtx 9y ago
- Entangled 9y agoAny not so expensive hosting options for sockets-based apps? Heroku? Digital ocean? AWS? Also, what are the limitations by the hosting provider regarding concurrent connections, data transfer, etc. I am currently working on a poker app using free Heroku dynos but would like to have a budget in mind for when going live.
- synthmeat 9y agoOn DigitalOcean, I'm planning a following setup to launch: 1. $20 staging at all times, already live [1] 2. $20 static nginx 3. 3x$5 for socket servers on North America / Europe / Asia 4. $5 master server with WS connections to full mesh of socket servers / orchestration / future. All Debian. Have no clue what's Heroku like for that, but last time I've checked, it wasn't as good choice as DO was and is for me. [1] WARNING: might break at any time, by choice or not http://staging.munchies.io http://staging.munchies.io
- Entangled 9y agoThanks for the info. Good thing about turn-based games is that you send small packets to few players every few seconds, so they're not that intensive in memory/transfer. I hope having a thousand players in a room won't break my piggy bank. Later on I'll venture with chess, checkers and backgammon, all turn-based games.
- synthmeat 9y agoIn this oldie of mine [1][2][3], I used protobuf (with no dictionary), and basically only used real-time information to show other player make moves, in otherwise turn-based/async profile game. It's currently solely on single $20 DO droplet, so I hope no HN effect kicks-in. :) [1] https://bit.ly/ShowdownFacebook https://bit.ly/ShowdownFacebook (FB+Flash) [2] https://bit.ly/ShowdownApple https://bit.ly/ShowdownApple (iOS) [3] https://bit.ly/ShowdownGoogle https://bit.ly/ShowdownGoogle (Android)
- explodingcamera 9y agoFor that money you might as well get a beefy dedicated server that's multiple times as powerful and not have to worry about all these small servers.
- unoti 9y agoThe author mentioned that using a control scheme with small acceleration leads to better synchronizing with the server. Another approach to this is control schemes where the client indicates to the server "I'm planning on being at this location at this future time."
- synthmeat 9y agoThat's then, logically, open to exploitation from user and client-side. Unless deeper logic layers are made to prevent that. Rabbit-hole, I tell ya. They're fun, though. :)
- coldcode 9y agoHaving worked on a commercial networked first person shooter, I can verify that making it smooth and coordinated is a massive pain in the ass. Having a game like World Of Tanks where the server makes all the decisions only works if the game entities are big and don't change much (i.e. tanks). There is a reason why none of the World games have people. Nothing is harder than trying to make a knife fight work over the internet without it looking spastic.
- synthmeat 9y agoDon't not share - which FPS? :) Yeah, game design and tech to support it are tightly linked, and there's approaches to it from either side.
- btown 9y agoIt's also why many MMORPGs rarely try to do collision testing, and have gameplay mechanics where you queue up abilities in advance of expecting to see their effects.
- bmsleight_ 9y ago"spastic" Are there not better words ? Uncoordinated ? Glitchy ? clumsy ? awkward? blundering?
- arca_vorago 9y agoI'm working on a project I hope to make multiplayer eventually, but the issues surrounding it scares me a bit. I wish more companies doing the hard multiplayer work (fps's mostly) would reveal more of their back end and how they do things. I don't think anyone has really done it well yet but everyone is hiding what they have figured out so far. I have noticed that certain engines tend to have better success at this, for example source engine seems to have drastically improved, allowing games working on this issue like Insurgency to make some noticeable strides towards being better. This has me remembering UT over dialup lag...
- deleted 9y ago[deleted]
- oboopfmlrmnmn 9y agoJust wondering, why are people still using socket.io and not standard websockets, as available in every browser since several years now?
- 11235813213455 9y agosockJS is a good solution, websocket are reliable, but it's annoying to make sure they reconnect when they close, sockJS does it in a sane way People are using socket.io because of the hype/sheep behavior and misinformation
- XCSme 9y agoIf you don't mind performance, using socket.io gives you stay-alive on the ws connection. If you don't mind writing the 5 lines of code it takes to implement stay-alive for normal websockets then socket.io makes no sense anymore.
- gbuk2013 9y agoIt provides fallback connection methods if WS connection fails, as it can do if you have, for example, a HTTP/1.0 only proxy between you and the client. For example it was not that long ago that nginx did not support proxying HTTP/1.1. It is getting less and less relevant but at least for me the socket.io code has worked for a long time and there hasn't been a need to rewrite it.
- emilsedgh 9y agoI'm personally using it because it gives me: 1. Rooms 2. Disconnects and reconnects, 3. Fallack solutions for free. Although not for a game. I trust that its just not made for that kind of performance. But for a messaging app its actually quite decent.
- neillyons 9y agoThis is a great write up. I've had similar experiences, and agree, have the server-side game state be the single source of truth. I basically stuck some visuals on top of the example "counting" snippet on the Elm site (http://elm-lang.org/examples/buttons http://elm-lang.org/examples/buttons) and made it multiplayer. First player to count to 50 wins. I didn't use a tick approach, instead the state of the game was only updated on an event sent from one of the clients. I then broadcast the new state of the game to the other clients. This is what I made http://retrorace.neillyons.io/ http://retrorace.neillyons.io/ https://github.com/nwjlyons/retrorace https://github.com/nwjlyons/retrorace. Something is not quite right in the backend code. I think there are problems with waiting for the mutex to unlock. The game feels like it freezes sometimes, but it could also just be a latency issue. The server is in London and I've only tested it with people who are several hundred miles away. I also had plans to build multiplayer snake but felt like latency would make the game too slow.
- synthmeat 9y agoI try to squeeze a little Go side-wise, so I'll be sure to check this out in the future. Thanks.
- pdfernhout 9y agoI wrote something similar as a very simple demo multi-player tank game/simulator with socket.io and canvas: https://github.com/pdfernhout/TanksInYourBrowser https://github.com/pdfernhout/TanksInYourBrowser
- errozero 9y agoDo you have a live demo somewhere?
- pdfernhout 9y agoNo, sorry -- but it is easy to run it locally if you already have nodejs installed. It's not very fancy -- just shows the basics.
- joe_carrot 9y ago"io.call('up')" broke your server. Sorry :(
- gfysfm 9y agoJust woke up and it seems to be working now. No harm done, I guess?
- joe_carrot 9y agoWell not really, anyone could type in 'io.call()' and it would add a new player to your server with no controller. 'while(true) { io.call() }' would kill your server in about a minute
- pg_is_a_butt 9y ago"Application Error" let me know when your next article "Building multiplayer games that actually work" comes out.
- baffo 9y agoIf you have problems with lag and conflicts resolution of state, take a look at this article, it may be useful. https://0fps.net/2014/02/17/replication-in-networked-games-latency-part-2/ https://0fps.net/2014/02/17/replication-in-networked-games-l...
- arkmanxbet3 9y agoParker vs Fury Live Stream Free https://www.reddit.com/r/ParkervsFurytv/ https://www.reddit.com/r/ParkervsFurytv/
- bullen 9y agohttps://github.com/tinspin/fuse https://github.com/tinspin/fuse TLDR: Websockets are overengineered and waste CPU cycles doing nothing but marshalling. HTML is better than canvas because it can be GPU accelerated and you get components and z-order for free.
- dkersten 9y agoOn the topic of multiplayer HTML5 games, I've recently started playing with Lance[1] and its pretty good. Its main draw is that it largely does the networking and latency compensation (it has options for interpolation and extrapolation) for you. The only requirement is that you write your game (client and server) in javascript and run the server on node, so that the gameplay logic can be run both in server and client (game is simulated both on client and server, but the clients are periodically synced with the server, using interpolation to make it look smooth). [1] http://lance.gg http://lance.gg