adityaravishankar / command-and-conquer

Command & Conquer in HTML5/Javascript
772 stars 168 forks source link

Client code needs to be updated for multiplayer support #31

Open adityaravishankar opened 12 years ago

jovoud commented 12 years ago

How are you going to setup multiplayer games? through a dedicated server or like age of empires, every client simulating the game and sending commands?

//edit http://www.gamasutra.com/view/feature/3094/1500__archers_on_a_288_network_.php

adityaravishankar commented 12 years ago

Still exploring options... But this demo looks promising.... http://nowjs.com/examples/map

And I've already done some work on nowjs+node.js before. http://www.adityaravishankar.com/2011/10/nowjs-node-js-tutorial-creating-multi-room-chat-server/

jakemac53 commented 12 years ago

I was thinking node.js as well ;). nowjs seems like an awesome framework for it pretty cool idea, im going to have to check it out on some of my own projects!

jovoud commented 12 years ago

As it seems there is still no way to do p2p in webbrowsers and only the option of a push server, it looks like you're gonna have to work through a proxy server anyway. The question is if you are simulating the game on that server, or let the server proxy push the game state of the different players to each other.

player1(browser 1) <---------A-------->server<----------B-------->player2(browser2)

so you have 2 well known methods of multiplayer here: 1) each players simulates his own gamelogic, commands are being send over A and B en pushed through the server. Here we have to make sure the gamestates of player1 and player2 are synchronised. 2) each player receivers the changes made from the gamelogic that is been simulated on the server, over A and B go gamelogic changes and commands.

So it's about the logic and not the technology. This difference has a big impact on the game code. In option A it's fairly easy to implement single player without using the server (once the files are cached anyways) and in B this is not possible unless you run the multiplayer gamelogic on the server but for single player run the gamelogic on the client. This way you need the gamelogic on both server and client.

adityaravishankar commented 12 years ago

Using the server to just broadcast commands collected from clients and letting the clients do the hard work seems simpler based on the work already done on the client..

jovoud commented 12 years ago

Too bad you can't receive incomming connections in a browser. P2p support in browsers would be a nice addition. (http://www.webrtc.org/). It would reduce the load on your servers. But like you said the command broadcasting is the best solution here. But don't forget it's going to be a pain to synchronize the multiple gamestates. Also this is important for anti-cheating measures. What happens if the game goes out of sync? cause it's not that hard to give youself 1000$ resources in a javascript client game :). This will cause the other gamestates to be out sync and the simulation will run differently. (cause I can build a tank which the other gamestate can not due a lack of resources. So What about that tank shooting at an enemy in my cheated gamestate? How does that reflect on a command let's say mytank.shoot(enemy), if the mytank tank object does not exists in the other gamestate?) Btw nice efforts already on a js game :)!

adityaravishankar commented 12 years ago

Good points.

Personally, I'd like to just get the cheat-able version out and then eventually recode the new one...

Trying to get it perfect on the first try will delay getting any features out...

Once we have the basic infrastructure in place, and people are actually playing/enjoying multiplayer, we can think about more features.

jakemac53 commented 12 years ago

For me it seems like using NowJS and running ALL game logic on the server would be the simplest implementation from a programming standpoint. That way all the clients would be doing is calling functions defined on the server, and the server would be updating all the objects for each of the clients. Then the clients are reduced to simply a drawing loop and some input functions. There would be only 1 state of things.

The only thing you would have to do to prevent cheating is adding a way of detecting if a client changed their "now" object on their own. Since in this situation any change to that object would not be allowed on the client side (only server functions would be doing this) then you could just keep a copy of each clients now object or something and check it against their actual one maybe once a second? If they are not exactly equal then they have cheated.

Do you think this would be to much server load? It would not have to do any drawing so I think it should be able to run many games at the same time still....how many though is the question I guess. The main flaw I personally see in this is just that it requires a lot more work on the server side, but if anything thats good because it will allow the client side game to run smoother?

jovoud commented 12 years ago

If you are just building a front-end javascript render engine, why bother writing the server in javascript? why not use an other programming language which already got nice game-server-frameworks and reusable code? Secondly remember that your server is doing more than playing as proxy server and pushing commands to clients, it is simulating the gamelogic itself. Meaning that all A* pathfinding, collision detecting and other heavy cpu cycle en memory space things are happening on the server. So don't think you will run lots of game simultanious on that server :p As explained in the article about 'age of empires': 30% graphic rendering, 30% AI and Pathing, and 30% running the simulation & maintenance. So that means your clients are doing 30% rendering and the other 60% is being done on the server. It's almost the same as those new video game platforms which are streamed to your pc,tv,tablet or phone. They gather input send it to a server which runs the gamelogic and renders the screen and streams it as a video back to the input device.. But in this case you send the gamestate and render it with your javascript render engine... One pro is that, if you ever publish your game and want to exploid it commercially, they can't rip your gamelogic code. :p But you would need to invest in some serious computer server power to run all gamelogic. I think the best way to implement multiplayer (as in this case we already have a single player mode) is to run the gamelogic on every client,send messages and synchronize. This design implemented in age of empires was come to be because they wanted multiplayer in genie (the engine of age of empires) without heavely changing their code. You could also implement some feature that note all gamelogic is simulated on each client. So that not all pathfinding are done simultanious on each client, but on 1 client and pushed to the other clients. Which reduces the cpu load on the clients. But the downside is that there is more chance on people cheating.

//edit But I find it very important to 1) make all code more reusable and easy to look at by splitting it in multiple files and 2) abstract the logic from the rendering.

This also has the advantage for server simulating or even to build a dedicated server and if you later want to build an isometric game with the samen gamelogic it is possible with minor changes.

As I was thinking about the problem i figured out that you can also run the gamelogic entirely on 1 client (lets say benchmarked on the fastest computer) and let the other clients push the commands to the server-client's gamelogic. It does have some drawbacks: cheating is easier for the server-client + when the server-client quits the game, the game freezes over unless you quickly transfer the gamelogic state to an other client. not ideal, but stuff to think about :)

adityaravishankar commented 12 years ago

Thats a good point.... Moving pathfinding and AI to a node.js server means even old and crappy machines can run this game....

I'm still cleaning up the sprites and other code... Will take a look at all options before building this.... :)

jovoud commented 12 years ago

If you want to play this game with a couple of friends on crappy computers, it is a good solution.. However if you want to integrate this game into facebook and want to reach 10k users, you'll need to have 10k dollars too, to maintain your serverfarm :p I personaly think the synchronized gamestates is the way to go. But i have to read up on alternatives in modern games. Also we are confronted still in javascript, that we need to use a pushing proxy..

jakemac53 commented 12 years ago

@jovoud while this may be true I feel like everything is moving towards doing more computing on the cloud anyways. CPU power is cheap, and the better CLIENT experience you can produce the better. It is not as if all the sudden a million people will be playing this game, and even if that did happen then you should be able to generate more than enough revenue off of ads. Also the AI and Pathfinding in this particular game are very simple and not particularly cpu intensive. Also, keep in mind Age of Empires was built to run computers with very few resources (I am pretty sure I ran it with 256 ram and like a 333mgz cpu but I could be wrong). If anything this game is simpler in Pathfinding, AI, and Graphics, so server load should be minimal?

On another note, I may be wrong about this, but I am pretty sure that the goal here is not a money-making enterprise. Would that even be legal? Its not like we own the copyrights to any of these sprites so any money-making venture should probably be avoided. I don't really know anything about this specifically, maybe the copyrights are expired and its free game? If so then facebook integration could be really awesome lol and you could probably make a decent buck doing it.

jovoud commented 12 years ago

Very true but still, you need to provide the cpu cycles and memory space and nowadays every 'computer' (as in pc,tablet,smartphone,...) would be fast enough to simulate this itself. Then you don't need to rent cloud space... Also it's more (cheaper) scalable in the synchronized way (unless you change the nature of the game to an 100 players multiplayer game, yes then you need a fast server to do the gamelogic for you. This is not the case and normal pc today can handle upto 10 players with 200 units each easely). As for making it commercial, that's not realy the point.. In this case with these sprites I don't think you can as they are copyrighted. But if you do this project to learn and let other people build on top of this, it should be designed as a game engine first and the c&c game build on top of that engine. Let's say this game gets to a point it's playable in multiplayer with lots of features. It should be possible to use that codebase (game engine) to create a new rts with maybe a slightly other gameplay and with other sprites and artwork. It's like building a custom cms for each site you make...why do that? it's easier to use a stable codebase like say drupal and create a template and configure the cms.. just my 2cents, Jo

//edit True that aoe runs on low hardware if you compare them today computers but make no mistake they bitfucked all the way :) If you try to rebuild aoe with javascript you have a lot of overhead. I don't think a javascript version of aoe runs wel on a 1Ghz computer with 512MB ram ...

StephanMoeller commented 12 years ago

I must say I totally agree with jovoud that letting the clients synchronize the game model by sending actions only over network is the better choice. This solutions has a lot of advantages:

I agree to, that the separation of networking, gamelogic and rendering is important as the network part could be reused (as already mentioned).

As comes to cheating, I agree with Aditya that this should not be the main concern at this point.

And yes, if we could somehow make holepunching possible (being it udp or tcp) this would take scalability to a whole new level.

jovoud: "But don't forget it's going to be a pain to synchronize the multiple gamestates".

jovoud: You mention Age of empires. Do you know where to find the whitepaper they did on their networking part? I read it som e years ago, but I don't know where to find it :)

jakemac53 commented 12 years ago

I guess for me it comes down to whether this was ever intended to be released on any sort of large scale. I at least saw it as more of a hobby project to be played among friends but not necessarily advertised to the public. In this case what makes more sense to me is the option which is simplest to program. I am fairly certain my original idea of doing all logic on the server would be the quickest and easiest strategy from a programming standpoint since there is no synchronization to worry about. It would absolutely not be trivial to sync up 2 different clients running their own simulations perfectly. As described in the AOE article they had a ton of issues with this themselves where tiny differences would multiply into large errors over time.

I do agree however that from a scalability standpoint doing the logic on each client and only passing actions between them with the server as just a go-between would be the most scalable option. It would absolutely be the least server intensive.

I guess the real question here is what this will be used for. If it is ever to be released on a large scale then I would concede the more scalable option is the better one. However, if its more of just something for more tech savvy people to throw up on a personal server and host games with their friends then I would say scalability is essentially irrelevant, and keeping the client side light and programming to a minimum is the best option.

adityaravishankar commented 12 years ago

Most of the code is already in the client side... So making a server just communicates commands might be the simpler option... Will give it a shot and see what happens.... Since both sides are JS, we can always transfer from client to server pretty easily if the need arises...

jovoud commented 12 years ago

I believe the synchronized gamestates is the way to go! nice lets try that :) (can't wait to have some spare time to mess with this :D ) I do not have the whitepaper of aoc, but i have quoted the url about that multiplayer part here above.

jakemac53 commented 12 years ago

Yeah I have been convinced as well. Synchronizing everything should be really interesting but it will prevent a fun challenge. Keeping network usage to a minimum should be priority #1 since thats the slowest thing and doing it this way should minimize network usage as much as possible.

jovoud commented 12 years ago

http://stackoverflow.com/questions/1411745/multiplayer-game-synchronization

StephanMoeller commented 12 years ago

Could we create some sort of closed repository where we, as a closed circle, could share code? I have already made this synchronization model which shows how to run singleplayer, multiplayer and replayers with very little change.

adityaravishankar commented 12 years ago

Github does allow private repositories if you upgrade your account.....

StephanMoeller commented 12 years ago

Cool. I made a private repository and shared it with you 3 guys :)

https://github.com/SRYER/RtsJs

adityaravishankar commented 12 years ago

Cool...

jovoud commented 12 years ago

yeah what he said! Ill take a look at it next week.

StephanMoeller commented 12 years ago

Some info about the "lock step" networking model, that my module uses: http://aff2aw.com/blog/starcaft-networking.html And some of the age of empire white paper I was refering to: http://www.gamasutra.com/view/feature/3094/1500_archers_on_a_288_network_.php

StephanMoeller commented 12 years ago

I have now rewritten the entrie code and along with that, made runtime latency adjustment possible (as in Starcraft 1) which means, you can adjust the latency of the game. This is typically used when lag (due to network overhead) is experienced.

Just following the instructions in the README file to get it running.

Aditya: What is the current status of the project? It's a little silent inhere :)

adityaravishankar commented 12 years ago

Sorry bout that....

I tried your last demo, and thought it was pretty cool.

Been swamped the last few days... I released patches with some essential bugfixes over the weekend, but thats about it..

Took some screenshots of the multiplayer screens (lobby) from the original game so I can start emulating it....

StephanMoeller commented 12 years ago

Okay sounds cool. Let me know any time if there is something that I can do.

Maybe we should just focus on getting the game up running in multiplayer first? Then some can do lobby, fb integration, game polishing, network tweeking etc. afterwards? :)

adityaravishankar commented 12 years ago

I find it easier to mock up a shell of everything and plugging the working bits later.... It makes it easier to plan all the requirements for the backend code...

So a lobby that looks like original and just shows hard coded player1, player2"... Will try to mock something up soon and share :)