2

I am developing a Turn Based Strategy Game where I output a series of arrays from PHP to be animated in canvas using javascript.

Given that I am aiming at 20 fps (frames per second) in the javascript/canvas the php is producing a lot of information for the browser to receive and then handle.

How can I pass these php arrays to javascript?

EDIT The volume of data I'm specifically refering to is about 5 megabytes per turn.

EnglishAdam
  • 1,380
  • 1
  • 19
  • 42
  • Why not generate these data in JavaScript? – Skydiver Mar 09 '13 at 13:38
  • You could look into using a socket http://stackoverflow.com/questions/1736382/how-to-use-sockets-in-javascript-html – CrayonViolent Mar 09 '13 at 13:38
  • @skydiver - I'd prefer if the game engine wasn't public... – EnglishAdam Mar 09 '13 at 13:39
  • @crayon violent, cheers I'm having a look right now, thanks – EnglishAdam Mar 09 '13 at 13:40
  • 1
    @Gamemorize Omm.. Are these data all necessary to be computed in server? Maybe you can transfer some basic data from server to client, and generate other data (such as animations data) from these basic data. – Skydiver Mar 09 '13 at 13:44
  • @skydiver, you're right to make sure and i'm looking to pass off as much work as possible to the client and save on bandwidth and my servers but I'll still be passing lots of data and so the problem will still be there! – EnglishAdam Mar 09 '13 at 13:48
  • Have you tried JSON? Not sure if that's what you're looking for, but you can definitely pass PHP arrays to Javascript. – bmorenate Mar 09 '13 at 13:48
  • @bmorenate, does data sent to a json file differ in process than data sent to a js file? – EnglishAdam Mar 09 '13 at 13:53
  • json_encode everything? – Mikael Dúi Bolinder Mar 09 '13 at 14:02
  • In php, you would `json_encode` your data, output that data with `header()` and `header('Content-type: application/json')`. In JS, you would call your PHP file with AJAX, get the returned json string, and then use `JSON.parse()` to parse the JSON string into a javascript array/object. At least that's how I would do it. Not sure if would work for your application. – bmorenate Mar 09 '13 at 14:05
  • @bmonerate - and mikael, - Thanks - and you guys would recommend json for passing MB's of info over other possibilities? anyways...SE isn't interested in opinions so if it's a valid possibility put it up as an answer and possibly mention any pros and cons. – EnglishAdam Mar 09 '13 at 14:09
  • @Gamemorize you should do some basic math around the "MBs" and your expected network bandwidth. – Pointy Mar 09 '13 at 14:28
  • @pointy, ok I'll add an estimate of how many "MBs" i'm talking about - fair point, thanks – EnglishAdam Mar 09 '13 at 14:30
  • @Gamemorize OK - so 5 megabytes per ... what? per frame? – Pointy Mar 09 '13 at 14:32
  • @pointy, it'd be about 5MB per 'turn', cheers re-edited, sorry. – EnglishAdam Mar 09 '13 at 14:35
  • 5MB per turn is an awful lot of data. What kind of things are you sending to the client? – Bojangles Mar 09 '13 at 14:50
  • @Bojangles, yep it is an awful lot of data. I'm sending very interesting things, ha ha. My reasons are outside of the scope of this problem in hand. I'm looking into solutions for the data transfer and then if things are problematic I'll review the 'what' issue. Thanks though for the 'challenge'. – EnglishAdam Mar 09 '13 at 15:24

2 Answers2

1

I think there are two questions that you are trying to answer.

  1. How to pass data from php to javascript?
  2. What format should the data be passed between php and javascript in?

In terms of Q1: There are several techniques to choose from, none of which offers a clear advantage without knowing a little bit more about your project. You could use:

  • WebSockets: if you need low latency, bidirectional communicaiton between server and client, or if you need to stream data
  • AJAX: if you need to request data at known intervals or in response to an event (user click)
  • Comet/long polling: if the data is "pushed" to you from the server at unknown times

In terms of Q2:

  • JSON: easy to work with, lots of support
  • MsgPack - smaller data structures, faster parser

It's hard to pick one best solution without knowing more about your project but I hope this list can get you started.

igoratron
  • 134
  • 3
  • Thanks +1, nicely explained options as the answer. Not sure if these are ALL the options. Is FTP an option for example? PERSONALLY I'll know when the next turn needs to be called so it'll be AJAX and using JSON has been my default thinking, my wonder -personal- is also if that's also the 'best' format. – EnglishAdam Mar 09 '13 at 17:02
  • I agree, this is definitely not an exhaustive list of options but rather some of the more obvious choices. However, I don't think this is really a "which technology" question. I would argue this is an architectural question to which markE's answer is more appropriate. Specific technology can give you can give you an improvement of, probably, a couple percent but an architectural choice can have an impact of an order of magnitude. As to your last question, FTP isn't really an option unless you are willing to go down the plugin road with java or flash; Javascript can't connect to an FTP server. – igoratron Mar 09 '13 at 21:48
1

Ok, if you MUST send 5mb, the very, very best thing you can do is:

Use data compression like gzip or gzcompress to reduce the 5mg payload. Typically a file can be reduced to about 20-25% of original size (down to 1-1.25mb in your case).

That said, you really should look at restructuring what data you require to power your game, because 5mb is way more than typical!

You’re not giving us any specifics to work with, so here’s a “straw dog” for us to play with: Assume your game is chess. (I know it’s not, but we need something to center our focus on)

Move all rendering to the client. The data you send should only send the move (“Rook-A6”). The client takes that data and renders the Rook graphically moving from its current position to the new position on A6.

Move game logic to the client. The client should be able to independently react to game conditions. For example, the client should “undo” a move which the player tries to put his king in jeopardy. Similarly, if you send data for a complicated move like (“castle king-side”), the client should know how to move the king+rook appropriately without requiring explanation from your data.

Do some pattern recognition to simplify/reduce data being sent. So to set the initial position of all 32 pieces on the chess board, you send (“Reset”) instead of (“move white Rook-A1, move white Knight-B1…and so on”).

Use semaphores to control the availability of game resources. If part of your game is requiring users to acquire/use a common group of scarce resources, use semaphores to let the users “check-out”/”check-in” resources instead of actually tracking the individual resources.

markE
  • 102,905
  • 11
  • 164
  • 176
  • Thanks +1 for more options. The data is a lot but being a TBG (so no interactivity is needed) it outputs a mini-film, valid for about 3-5 minutes of viewing (imagine a football match or a battle played out). The client is going to do a lot of work and your considerations are all correct (and done). – EnglishAdam Mar 09 '13 at 17:07
  • Ahhh...video. You might consider setting up a video stream--either off your own server or off a host server like vimeo. With vimeo you can allow/disallow access per person to your stream. Alternately, a very efficient way of showing video is Progressive Downloading where you break the video down into parts and the user can start viewing part#1 while parts#2-x download asynchronously in the background. – markE Mar 09 '13 at 17:54
  • Cheers but it's not a video but an animation generated by the php arrays via sprite sheets / js & canvas and can last 3-5 minutes - a turn based game that outputs a video though is a cool idea! – EnglishAdam Mar 09 '13 at 17:57
  • Still...Progressive Downloading still applies. Get the user viewing the first 1mb while you're asynchronously downloading the remaining 4mb in the background. I know, you'll probably have to rework some or all of your sprites/js, but isn't **fast/seamless** viewing of 5mb of data what you want! *Important addition*: spritesheets are ideal candidates for **preloading & caching** on the client side. – markE Mar 09 '13 at 18:06
  • It's an idea that we'll have a look at, I really didn't expect so many *gasp*s of 'RE-THINK' for 5MB of data. But as you can tell I've never sent so heavy packets before. In reality I'm looking at ways of not even needing such large data packets but the SO Q still stands. – EnglishAdam Mar 09 '13 at 18:35
  • One final thought, then I'm done. If you break up your spritesheets into packages of 6 and disburse them across multiple domains, you can maximize the concurrent downloading of that part of your payload. (browsers concurrently load up to 6 resources from a domain at the same time) – markE Mar 09 '13 at 18:42
  • Thanks again Mark, while your ideas are off topic for the question are on topic for my project! And this last one is completely new to me! – EnglishAdam Mar 09 '13 at 19:06