Advertisement

Trying to figure out WebSockets

Started by February 12, 2015 12:21 AM
7 comments, last by jeffjenx 9 years, 9 months ago

I've been working on pong clone using HTML5, my first attempt at creating a complete game using web technologies. I'm trying to implement online multiplayer using web sockets (socket.io, node.js), but am having difficult time wrapping my head around how these it all fit together.

Is this the appropriate place to have such a conversation and is there anyone willing to assist?

I'm not looking for anyone to straight up do the code for me since I want to learn, but it would be nice to be able to discuss how to integrate web sockets into my specific project.

•?¿•??

Jeff


Quantastical.com

Yes, this is a fine place to have that discussion.

In general, a game has a very simple loop:

- read input
- update simulation
- render world state

For networking, you typically add "receive from server" to the "read input" part, and "send to server" either directly after reading (for input replication) or after updating simulation (for state replication -- more sensitive to hacking if your game is popular.)

The server generally has a similar loop, but instead of "render world state," does "distribute world state updates to all clients."

There are many devils in the details, of course, and the details vary very wildly based on the specifics of your gameplay and genre.
enum Bool { True, False, FileNotFound };
Advertisement

Thank you for the quick run-down. I have been reading a lot about multiplayer game logic, as well as experimenting with socket.io to create a rudimentary version of the loop that you describe.

I am aiming to "do it right" by replicating the physics updates on the server and pushing the results to the clients, which are also updating physics but are overridden by the server's commands. I believe this is what is referred to as an authoritative state, preventing clients from modifying values since the server is the one handling the true simulation. From what I understand, the client performs it's update just to mask any hiccups in network traffic that cause latency between server updates.

The particular aspect I'm having trouble with is getting two clients to connect and speak to one another without broadcasting their messages to other users. A lot of the socket.io articles explain how to set up an environment where everyone is messaging everyone, i.e. a chat room.

I've been diving through the socket.io documentation and there is a feature called "rooms" that seem to be what I need to use. But, I feel like the process of creating a room name, then having to require the next user log in and enter the same room name to connect to each other seems excessive. And, when they finally do "talk" to each other, what is being said? For example, "Player A to Server: Player A is pressing the Down button."?

•?¿•??

Jeff


Quantastical.com

Also, just to get things into perspective, I'd like to point out that this is a very simple PONG clone that I'm making, well re-making. It's a rebirth of a game called Pong Kombat created by Stefan Gagne in 1994, so my first multiplayer goal is to create something where players can play anonymous matches against others. I think the process would be as follows:

1. Establish connection with available player, or wait.

2. Each player selects their character, then waits for the other to do the same

3. Game is played the same as in single player, but each sends their input commands to the server

4. The server computes the positions of everything then sends the updated positions of the ball, paddles, and projectiles to each player

•?¿•??

Jeff


Quantastical.com

getting two clients to connect and speak to one another without broadcasting their messages to other users


If you use a single server instance for many game instances, the server needs to know which clients are in which games, and enqueue the appropriate messages to the appropriate clients.
socket.io lets you send a message to a single client, so you can keep a list of which clients are connected on a per-game-instance basis, and send messages only to people on that list.

Separately, game networking will typically not run at the same frame/tick rate as rendering or simulation. A typical number may be 120 Hz for physics, 60 Hz for rendering, and 20 Hz for networking. This means that you likely will have the ability to interpolate rendering between simulation steps, and you will have queues of messages wanting to be sent on the next network tick. Depending on how you do simulation, those messages will in turn also have tick-number-stamps on them.
enum Bool { True, False, FileNotFound };

Cool. I was able to get two browser instances to connect to each other and go through the character selection process while waiting for the peer to do the same.

Now, I'm trying to figure out the best way to replicate the game logic on the server. In my case, I wrote my game in plain-ol' JavaScript...no libraries, no node, no nothin' except a bunch of custom objects using prototypal inheritance.

That code all lives on an Apache server, what I'll call "Server A". The node server, a.k.a. "Server B", is what I'm using solely for handling the peer-to-peer communication, but this, too, needs to run the game logic, in addition to interacting with the clients (gathering input and pushing updates).

Is there a best practice for including all of my game code on the node server?

The game logic isn't written to be modularized, so it doesn't play well with node's require function, since it doesn't have any "exports" exposing the global objects. I'm not sure what I should be doing here. Besides that, since they are two separate environments (Server A and Server B), I can't just require them.

I feel like I'm a bit mixed up here, I hope I'm explaining my situation well enough to make sense.

Maybe I shouldn't be worrying about executing the game code on the server, even though it's the "correct" way, since it prevents clients from manipulating the information sent to the server that is to be broadcast to the other peer. (Sorry for the babbling, sometimes it's nice to just explain things so I understand them better myself).

•?¿•??

Jeff


Quantastical.com

Advertisement

I am designing a game too. I am using NodeJS and Apache. Because of Node query processing speed, I am using it only for real-time things, while the Apache server is for login, register and things which not need fast processing.

But that's for now. I am considiring to migrate to Node only and use the power of JavaScript only. There are enough libraries for Node which can replace PHP at all.

But you always can open several node servers with different ports which to reflects different aspects of the game.

For example: if the battle system is such like a WoW or any other desktop games, that means a lot queries to the server, especially if you have a battle with more than 1 enemy player. This includes positioning queries(when you move, you always need to show to your enemy player where is your actual position), spell queries(when send spells each-other), calculations and etc.

So this would be better to be processed by another server. Should increase the performance for the rest of the site.

One advice when you use Node. Always use "Promises". They are very powerful and useful for code structuring and for promise that you'll get a result.


function someFunc(args, args, ..., cb) {
         //... code code...
         cb(result); // some result or data
}


// some other file

someFunc(data, data, ..., function ( result ) {
     // using the result from someFunc as Promise
});

Is there a best practice for including all of my game code on the node server?

This, for me, is worst thing ever. I am also trying to structure my code, but for now when I'm using PHP with Apache all my stuffs are structured with MVC pattern. But when I need to use NodeJS all files there, are spread away.

So now, I am trying to create some MVC pattern. But if I migrate to Node at all I'll maybe use MEAN stack(Mongodb(for Models), Express(for Controller), AngularJS(for View) and NodeJS(for server)), which provides this.

Of course there are many other libs for that as ReactJS for View in M-V-C.

Sorry about my english. I hope that I've been understanable.

Is there a best practice for including all of my game code on the node server?

The game logic isn't written to be modularized, so it doesn't play well with node's require function,


The best practice is to re-factor your code so it plays nice with modules! You can write code that runs in both a browser and in Node, if you assume that the browser first includes a simple helper script that provides scaffolding as appropriate. For example: you might define a require() function that returns a pre-constructed object with the precise methods that you actually use, hooked up to the browser DOM.

Also, if you have a different server for actually serving the JS files, compared to actually doing the websockets, then the browser security model may get in your way. If you end up getting surprising access denied errors, or empty payloads, this is likely the reason. It may be possible to easily fix by making sure that the Node responses include the "Access-Control-Allow-Origin: *" header, but then of course you have to make sure that doesn't compromise whatever security you want for this system.

Finally, for a game that won't be big and popular, it's probably OK to run the logic only on the client; the incentive to cheating starts when there are people who really care deeply about a game for a long time. Either because real dollars are involved, or because the game has a significant community.
enum Bool { True, False, FileNotFound };

Thank you for the thoughtful responses. I agree, hplus0603, that refactoring my code is probably the ideal solution.

I think for now, as you said, it might be easiest to do it the non-ideal way, since I don't have to break everything down and build it back up, and because it's a simple hobbyist project.

This will give me the opportunity to learn everything in a more simplified manner, then I can revisit it down the road to refactor and improve everything.

To relaxo4o, I actually started with a MEAN stack but was overwhelmed a bit because I have such a solid understanding of PHP MV* pattern. In an effort to GSD (Get Shit Done) I abandoned that process to do it on Apache, but now I am starting to better understand how those things all work together and why they are beneficial.

Ultimately, I think I am going to continue following the "GSD" method and then possibly convert everything down the road (a version 2, so to speak) to a MEAN stack, modularize my game code, and update the multiplayer strategy, and improve my game code to improve memory management and reduce garbage collection impact.

Thank you both for your assistance and knowledge.

•?¿•??

Jeff


Quantastical.com

This topic is closed to new replies.

Advertisement