Hi there,
I'm seeing a lot of topics like mine, sorry for creating another one. but I could not find anything about one specific technology. gRPC.
So, I want to create 2-12 person multiplayer game. It's turn-based but will have real time communication (some kind of chat, yes, and voice communication).
I've decided to create separate server instead of having it hosted by client - I could go this way, but I want to train on my first this approach, cause I have in mind much bigger game that will need cloud server.
So server → mutliple clients. All group of 2-12 players will gonna have to land on one server - obviously. But there might be more, I mean, why not, optimize costs. And as - it's gonna be more microservices - cause one main server for users/ global events, global lobbies. But then small servers that will contain from one to more groups (depends on load).
So question about communication.
I had one attempt with Web Sockets - Java Spring Boot server and Unity 3d client. It wasn't great but it was working.
The great thing I could minimize the info that was sent between players - so for example sending only information that is visible to specific player but game state and validation is done on server. The purpose is to minimize chance of cheating.
REST api as well could go, but I'm kind of not sure if it's good solution. I'd have to create something on side anyway for text and voice chat in game.
I wonder about gRPC, have any one of you tried it for game? I mean, there are tutorials, so ppl use it. But I'm not sure if any actual game went with it as product, not as a prototype only.
Thanks in advance for your time!
Turn based game - with a server
My experience: gRPC lives on top of HTTP2 which lives on top of TCP, much like websockets. gRPC gives you the ability to stream a number of different packets in either direction without necessarily having a formal request/response cadence, much like websockets. In general, gRPC has a slight advantage when it comes to tooling for “server” and “desktop” languages (C++, Java, Python,) and websockets have an advantage when it comes to web browsers (JavaScript.) gRPC marshaling/demarshaling is slightly faster than websockets marshaling/demarshaling (because JSON is slightly more expensive than protobuf) but the difference isn't as big as you'd perhaps assume.
If you can live with TCP (in-order, later packets are delayed while earlier packets are re-delivered in case of packet drops) then gRPC is a fine protocol, and has some good tools for defining the different kinds of packets (PDUs) you can send and receive. If you don't need to connect from a web browser, then gRPC is a very good choice. If you need to connect from a web browser, websockets may have a slight advantage.
It's also possible to write tools/gateways that translate between the two, so if you don't need browsers now, you can use gRPC, and then, if you need browsers later, you can introduce a gateway.
Another bit of advice:
And as - it's gonna be more microservices
“Microservices” are not the same thing as “services.” “Microservices” are a management solution to a people problem. If you have a large engineering team, with a thousand engineers, you can't have all of them coordinate all the time, because no progress would be made, so you say that “each little team is responsible for its own little interface to the world, and if this means duplication, then so be it.”
When you have a reasonable decomposition between “account registration and authentication," “game matchmaking/setup,” and “actual gameplay,” that's not a “microservices” setup, that's just “services.” And I would highly recommend thinking in fewer, bigger, services, rather than trying to decompose every single aspect into some separately deployed and managed service. The more things that need to coordinate with each other, the more bugs you will have, and the harder they will be to diagnose and solve.
If it were me, I'd have a REST (or perhaps GraphQL) based front-end for account creation, sign-in, payments, and such. This account would also mint verified authorization tokens that other parts of your system can verify. There would also be a back-end-only accessible service endpoint where this service can answer requests about customers. (There may also be some push updates if you want customer bans to take immediate effect, rather than wait for issued authorization tokens to expire.) This service would have a persistent relational database, like Postgres, MySQL, or SQL Server.
I'd then have a gRPC service for game matchmaking, where clients connect to find games they want to play, and get told where to connect to when selecting a game. There would also be a back-end only accessible service endpoint where game servers will register themselves and update the matchmaker/roster. This service would have an in-memory database, either just in the process (if it's small enough) or using something like Redis (without persistence) or Memcache.
Each game instance would then be an endpoint for a process, where users connect when match-made. If you want to avoid people trying to port-scan and connect directly to a game without going through matchmaker, then you'd need some kind of token from the matchmaker that grants admittance to the server, too. The game would connect to the other back-end services, but probably wouldn't itself have a back-end service. The game is a “database” of game state, inside the game process itself, but it wouldn't use another persistent database, but rather, talk to the other services for those needs.
There would be some kind of service to deal with leaderboards, scoring, MMR, player rankings, or whatever else you want to store related to player/game combinations. This service COULD be co-located with the authorization, or it COULD be co-located with the matchmaker, or it COULD be its own thing. I'd probably co-locate it with authorization, turning “authorization” more into a “persistent, request/response-oriented, data service.” If you build it as a separate thing, you'd want a persistent database here, too, and I'd prefer a relational database just like the authorization service (hence, why I would probably co-locate them.)
Finally, you'll need some web server that serves the web pages for the game. Whether this is a static site served out of an S3 or Cloudflare bucket, just talking straight to the services, or if it's something running its own node.js-with-react on a public web port, or a PHP or Ruby-on-rails depends on what web technology you want to use. In general, this will not have its own database, but instead use the back-end services provided by the others.
That's more than I'd ever think about as for answer! Thank you very much!
So gRPC is I think good choice then. It's not browser game.
Yeah, no microservices, for sure. I've missused that word.
Thanks for all those tips, I'd havent even though about anything like preventing port scans, or matchmakers based on ranks etc ? First game is simple training for simple multiplayer cooperation game for 1-6 ppl. The bigger number I've gave is competitive group game for 2-10 ppl, then I'll need all of that you've mentioned.
As for web page I'm gonna go with cloudflare cause I've already used that and vue.js cause it's a framework I've used at work and in my free time making some webapplication. But that's still, not for the first one.
The most needed right now is this gRPC technology knoledge thing and one matchmaking server, game servers (both .net core) and actual game on client side (unity). That's the MVP I'm going from start.
I need to save your answer somewhere locally in case something happens here. Great source of tips that I'm gonna need now and later ;)