Meteor or vanilla node.js with socket.io?


#1

Hi, I want to create a multiplayer game 2v2, with game rooms, room list etc.
Can i do it in meteor without drop in performance ?
If yes, maybe could i get some piece of code how it was done ?
How I can emit data to specific user ?


#2

“Performance last”.

With meteor you do it usually data-driven. So you have a representation of your rooms and games in collections.

So e.g. you have a Rooms collection where one document may look like this:

aRoom = {
  _id: "xxxx",
  teamsA: ["player1Id", "player2Id"],
  teamsB: ["player3Id", "player4Id"],
}

depending on your game, you’ll need to save the game-state somewhere. If you have a game where you walk around, you want to save the position of your players (x,y,z) and maybe more.

You can define a Player’s collection, where a player might look like this:

aPlayer = {
  _id: "player1Id",
  roomId: "xxx", // redundant, i know, but can make sense
  userId: "meteoruserid" // if the player is a logged-in user with an account, you can store a reference to it.
  x: 123.34
  y: 24, 
  z: 0
}

So every player belongs to a room. You can delete the player if the room does not exists anymore. Depending on your game, a player defines a name when he enters a room, or he has a userId assigned, when he or she is logged in.

The players interact with the game through Meteor.methods, e.g.

Meteor.methods({
  moveTo({playerId, x, y}) {
     Players.update(playerId, {$set: {x,y}});
  },
  // or
  walk({playerId}) {
   // calculate x and y based on the direction the player is facing or whatever...
   const x = ....
   const y = ....
   Players.update(playerId, {$set: {x,y}});
 }

On your client, you can now use default-meteor-stuff to show a representation of theses players.

On 2d, you can use html to show them with blaze or react, or use a canvas-library (pixi, konva, d3, …). For react there are
also some wrappers for some of these libraries, there is even a Three.js (3d) wrapper for react.

Cool thing with react is, that the code looks pretty similar, no matter if you render actual dom/html or a 2d or 3d-scene.

Without using react or if you want to use a library that has no react-binding, you can use cursor.observe or cursor.observeChanges (http://docs.meteor.com/api/collections.html#Mongo-Cursor-observeChanges) to update your game.

E.g. somewhere on your client, e.g. in Template.Room.onRendered-callback:

Players.find({roomId: this.roomId}).observe({
  added(player) {
     // place the player on your canvas/3d-szene/whatever
  },
  changed(player, oldPlayerState) {
     // find the player on your canvas/3d-szene/whatever and update its position, etc.
  },
  removed(player) {
     // the player has left the room or so, remove it also from the scene
  }
});

You can extend this also by using collections to represent obstacles, enemies, npcs, or other entities that might move around.

Cool thing about this approach is that you even have latency-compensation, at least for your own moves. So e.g. if you want to walk a step, you trigger the method above. if the method is shared on client and server, it will update your local collection without waiting for server-callback, will trigger the changed-callback and will imediatly update your position on screen.

You can even share more of your game-logic, so that the game is always run both locally on the clients and on the server. The server will win, if there is a difference.

It is surly not as good as latency-compensation in todays multiplayer games, where you predict more than just your positions, but it may be enough for your purposes (and its really meteor-basic)

Hope this gives you some ideas!

I have some samples I did during school where i tried this approaches, both with threejs. One is a connect-4

( i know representing a connect-4 in 3d is sort of strange :joy:)

and the other is a egoshooter:


#3

you can do it with meteor, but it’s probably more flexible with Node

Look I wrote an article