I'm building a multiplayer game in PHP. Each game is split into stages that last a set amount of time - currently 2 minutes. In each stage, players work together for a set amount of time until the game either advances to the next stage, or the stage (and hence the game) is lost, and a new game starts again.
I have a vision of playing the game on an HTML page, where users can see how much time is left in the current stage through a constantly updating countdown clock. When the countdown clock reaches zero, the game either advances or ends, and the result is returned through Ajax. What I'm having problems with is the (theoretical) thought of 100 players playing the game simultaneously.
How do I call the update script? If I call it by running PHP, which player's browser calls it? If a player's browser refreshes the content one second before the stage actually finishes, what happens?
Is PHP the right language for a game like this?
"Is PHP the right language for a game like this?"
Yes, if you do it right. Here's how you do it...
Using a method called Comet, you can have multiple clients pulling data from the server, but only when that data is updated. It works something like this:
Client A makes pull request to server.
Server waits, keeping connection to Client A open.
Client B makes pull request to server.
Server waits, keeping connection to Client B open.
Client A pushes new data to server.
Server pushes new data to Client A and Client B through still open connections.
Client A makes pull request...
etc...
In other words, it means that all clients receive up-to-date information immediately it is pushed to the server by any client. This means you don't have to implement a "refresh every x seconds" system, which is good for 2 reasons:
1) You don;t waste time and bandwidth make requests to the server when nothing has happened;
2) All the clients get data pushed to them at the same time, that's absolutely up-to-date and not x seconds old.
In practice, Comet is implemented via AJAX. Google for some examples of Comet- it's pretty simple, and extremely useful.
In client-server games, your server should be running a simulation in parallel to the client's simulation (the game).
Usually the server simulation is authoritative, so that when, say, a match is over it will inform all clients in the match that the simulation state changed to "match over" or whatever. The client will then lock the UI or present a "Game Over" message or announce winners-- whatever you want.
So for you, your server should run the count down timer, while the clients keeping polling (via AJAX or WebSockets) the server for state changes. When the server's timer hits zero, the next time clients poll the server, the server will say, "Hey, yo-- the game's over!".
Edit
I'd also like to say that PHP will probably work, but you have to understand that PHP was built for web services, not games. Simple games like tic tac toe or checkers or chess can become quite complex when you toss in multiplayer functionality. Simulations often require threading. PHP can do threading but it can get very ugly if you don't know what you're doing.
Well, if you are using the PHP session system, the script will recognize the Ajax request as being from the same user who (for example) logged in into your game.
One second before the stage finishes, well you could return in PHP the time left to the stage so the javascript counter stay synchronized? Both the server and the clients must be aware of the status of the game, else expect hackers somewhen.
Related
I am trying to create a multi-player, PHP+JS-powered card game (2-6 players).
When a player chooses a card from his/her hand, I pass on that information to the other players by updating and then retrieving the details using a database/file (haven't decided which one, but that's not the issue here).
If it is a player's turn to choose a card and they don't, the system selects one of the cards and drops it for them. Whether it's a manual choice or a system choice, the same mechanism of using a central database/file to update the others' interfaces is used. As long as there is an AJAX call being made to update the database, it is all well and good.
But if any of the players lose connectivity or close the browser, there won't be a fresh AJAX call anymore from their turn. Even this can be managed with polling being done from other players' scripts (do let me know if there is a better, more efficient way of doing this - but again, not my MAIN question here).
If all players lose connectivity, there is no AJAX call from any of them, and the game "goes into a coma" there: there is no client calling the PHP script that manages the game, and that means nothing more happens in the game. No new rounds, no automatic card selection.
So is there a way to keep the PHP script alive (simulating player inputs till the logical end of the game) even after all the players have gone offline?
To answer a likely question: If there is no solution or workaround to this, I can accept that if ALL players have dropped off, I can leave that game in a state of suspended animation. I might still do this anyway, but I'd like to know anyway if there's a way to keep the game's script running until the game is over (all cards exhausted)?
So as you know in some browser-games such as Travian, Tribalwars and etcetera, you can build up a building, it takes X amount of time and it finishes.
So I'm curious how that is done?
Is it a cron-job running every second or what? How are they then doing with troops, they can't have a cron-job running ever millisecond, that wouldn't be resource usage friendly, right?
So I'm really curious about this and I have no idea so I can't really say I have tried. I have however searched around but never found anything helpful.
Thanks.
The easiest way to implement something like this is simple timestamps. The request on the front end generates a timestamp based on the constraints given by the details of the request (what type of building you are building, what level you are, if you have bought the upgrade). Then a timestamp is inserted into the database for when the completion occurs. Then, if you want the browser to refresh when the job is up, you make a script on the js that makes a request for all timestamps in queue and reloads when they come up.
One way: You let the client handle the timer. So the timer will sit on the browser side counting down using javascript. When the time is up it will contact server to see if it's valid (never trust client side code). Server looks up the building and see if it would have been finished by then. Server side doesn't need to keep any timers it just answers requests. Timers are UI side.
Well, PHP is one of the worst things you could use to build a game... In games, everything is controlled by the main loop that controls the game. So basically, in a game, everything is running inside an infinite loop, albeit one that allows for user input without freezeing the computer, obviously. So that loop takes care of the timing as well, and the way to compute timing will depends on the language on which the game is developed. For web-based games, Java, JavaScript and Flash are usual choices.
Here's the scenario:
I have a SmartFox server running on Amazon EC2 and using MySQL for the database. I'm using AS3 as the programming language.
I have a virtual world in which the user can click on some icon (like home design), and it shows the animation as the house is getting built. It takes eight hours to build it and it will show the percentage with a progress bar as it's getting build.
I could have used AS3 timers, but the problem is that the user might log out from the virtual world (or close the browser) and come back at a later (after maybe two to eight hours, for instance).
I haven't done anything like this before, so can anyone help me with the details, such as what general strategy needs to be used and how to implement, etc.
Please help.
You could do it like this - right after user clicks and starts the process notify the server about that and make server side script get current time and save it to the DB. If the user logs out right after that, just retrieve that saved timestamp each time your client app starts again and calculate how much time passed since the timestamp was taken (at server side), then pass calculated value to the client. This way you will always have the right time displayed and calculations will be client internal clock independent.
I'm building a prototype where on one page A I have a controller. Imagine a TV remote. On another page B, independent of form A -- it can be a different screen/computer -- with some elements X, Y, and Z that are going to be animated by the remote on page A.
My first idea would be:
Remote on page A saves an action wanted and sends JSON.
I create a listener on page B that reads the JSON to listen to what action to trigger.
I wonder if this the right direction.
It is just for a prototype so it doesn't have to be a production-perfect idea.
You can use web sockets for this.
Let's assume you're using 2 computers, both pointed at the website, as this technique could work in both scenarios.
If it's just a prototype, you could just simply have your page B poll the server every 5 seconds to look for updates that were submitted by page A.
However, in reality, for a production app with thousands of users, this could consume lots of bandwidth and put a heavy load on your server. To compensate for the load and bandwidth usage, you could increase the polling rate to 10 seconds, or 30 seconds, but in response to this change your users would experience delays while they wait for the browser to request an update from the server.
In a production app, many developers are turning to Comet as a solution. Comet is basically a term given by Alex Russell for a technique that involves using the request/response cycle to simulate server-push.
The general idea is that the browser makes a request to the server, and the server holds that connection open indefinitely. The connection remains open until another user posts an update to the server, in which case, the server then sends a response to the connected users.
The Dojo and Jetty team have demonstrations where they show that this technique can scale to 20,000 connections, when using continuations.
While I think you can carry out your experiment just fine with a database and/or some session variables, if your want to learn more about Comet on PHP, check out How to Implement Comet with PHP. Good luck!
UPDATE:
I also wanted to say that you definitely have the right idea for how to conceptually think about your message passing with JSON:
I create a listener on page B that reads the JSON to listen to what action to trigger.
I really like how you are thinking about passing a message that then tells the page what action to trigger. If you think about it, you could reuse your message passing concept to call other commands so that you avoid reinventing the wheel when a new command comes along that you need to call. Regardless of whether you poll, use Comet, or use WebSockets, it's a great idea to think about abstractions and generic, reusable data transports.
You could do this either with polling (having page B constantly poll for updates from the server) or use a server push technology like server sent events or websockets.
Yes, that would work. You could also just make it the same way you would make a vector line animation. Send the "commands" for movement to a server and record them (in a database, file, whatever) the client program can then request and redraw the movement smoothly any time and anywhere.
Using a cron job to execute Page B for every x unit time will make you check for any latest updated json (queried/returned output according your logic) from Page A. This way, you can use new updated json from page A and do your further task...
I am working on a turn based web game in PHP5.
This is pretty simple game, a kind of board game: two people join a "session" and they play until one of them wins.
My problem in nutshell:
User A and User B play a game.
User A finished his turn
Request will be sent to the server to perform necessary operations.
Now it is time for User B to move..
But how could I notify User B about this?
I mean, now the server has to communicate with the other user, the one that is inactive, not the one that initiated the request.
I know that this could be implemented using some kind of periodic AJAX call that checks whether the opponent finished his turn etc, but such a thing generates a huge number of requests.
Isn't there a better way to solve this?
I'm thinking of something like this:
User A's turn ends
Server saves his score
Server contacts User B
User B's turn gets started.
Is this possible using PHP and comet-style requests somehow? Or is there a better way to do this?
Any help would be appreciated!
Thanks in advance!
An in-memory database of currently running games/turns, and one check from user B every 1.5 secs or so, won't really generate a huge number of requests, or server load.
You can even have a polling scheme like 7s, 5s, 3s, 2s, 1s, 1s and so on, according to what fits your game.
You can even leave PHP out entirely, if you just touch a session file whenever a turn is done, and check the last-modified client side.
Php Sockets !
http://php.net/manual/en/book.sockets.php
server listen
client_a connect
client_b connect
client_a send start game to server
client_a send move to server
server send play client_b
[...]