by flash_mmo » May 25th, 2010, 2:47 am
by fox1980 » May 25th, 2010, 3:01 am
by flash_mmo » May 25th, 2010, 12:34 pm
fox1980 wrote:There is no safe way to save data at the moment. There is data persistance being developed, but it's not here yet.
If you REALLY want to persist data and still want to use playerio you have to keep the data in an external web server (with MySQL or something).
by fox1980 » May 25th, 2010, 1:18 pm
by flash_mmo » May 25th, 2010, 1:44 pm
fox1980 wrote:That's what i'm doing at the moment. You can check my game here: http://apps.facebook.com/soltris
Altough it's just a Tetris clone i do persist data like high-scores, player rankings and a couple of other data.
I'm having my flash client communicate with my PHP server with amfphp. But bear in mind that this method is vunerable to hacking, there is a firefox plugin that can intercept data sent from flash and change it. That's why i said there is no "safe" way to persist data at the moment.
by fox1980 » May 25th, 2010, 2:49 pm
by flash_mmo » May 25th, 2010, 3:36 pm
fox1980 wrote:I would say any MySQL server on a shared host would handle 100 concurrent connections perfectly fine. Facebook farmville works with a Flash -> amfphp -> PHP approach, and has millions of concurrent users any time. But it's a webserver we're talking about, the response time is way slower than sockets connections. If you're gonna write an MMO that has turn based battles like Dofus online a web server would fit nicely, but if you need fast paced action like World of Warcraft then a sockets server like PlayerIO is totally required. Maybe you can do a combination of both, store the importante variables in the MySQL database, and use PlayerIO for player movement, and other stuff that requires fast response times.
My advice to you: try and focus on other parts of your game, and wait till PlayerIO integrates persistent data. Even if you can get by with a web server, you'll always have bigger latency, it will be easier to hack, and you'll have a harder time scaling it if it get's successfull. Remember PlayerIO takes care of all hardware issues for you.
by fox1980 » May 25th, 2010, 4:23 pm
by flash_mmo » May 25th, 2010, 4:40 pm
fox1980 wrote:Even a simple MMO is far more complex than that. Make a good design document on paper first, you'll avoid many roadblocks in the future. The solution you mentioned will make you duplicate a lot of work, you'll have to replicate some functions in both the C# Server and the PHP Server, and you'll have a nightmare of a job keeping them both synced.
I'm in the same situation as you are at the moment, and i also hope for some easy port between MySQL and PlayerIO persistance, i have 5 years experience in MySQL, i hope i don't have to throw all that knowledge away and learn something new.
What i'm doing on the MMO i'm developing is using only PlayerIO without persistance. I'm implementing moving, trading, chatting and i know i'll be busy with that for quite a while. When persistance is released, most of my work will still be usable, i just have to tell the server to keep the data.
by fox1980 » May 25th, 2010, 5:23 pm
by flash_mmo » May 25th, 2010, 6:15 pm
fox1980 wrote:What MMO's are you talking about ?
Most slow paced facebook games are using the Flash -> amfphp.
Dofus Online uses a custom socket server.
The rest is using either Electroserver or SmartFoxServer, both of wich are socket servers written in Java. They both have the ability to store data in a MySQL/MSSQL server, and they're both free until 20 concurrent users, up from there they get really expensive, but worst of all, they just provide the server software. You'll have to host the server yourself, and no way any shared hosting provider will let you run a socket server. You'll have to get a private virtual server, or a dedicated server plan in order to host it, and the monthly fees for those aren't cheap either.
by fox1980 » May 25th, 2010, 7:12 pm
by flash_mmo » May 25th, 2010, 7:16 pm
fox1980 wrote:Ok, i got the impression you were going to do something that would require "true" realtime communication. PlayerIO as it is would be perfect then to enhance the interaction, like implementing player movement, chatting, etc...
Look into amfphp: http://www.amfphp.org/ if you haven't already for Flash->PHP communication.
by fox1980 » May 25th, 2010, 7:37 pm
by flash_mmo » May 25th, 2010, 7:51 pm
fox1980 wrote:Amfphp is a remoting utility for Flash->PHP communication. You don't actually need to use it, you can talk to your webserver with urlrequests in flash. But what you get in return is an HTML page. You have to manually parse it to get back the info you need and then cast it into the object type you want.
Amfphp does all this for you, it's like calling a PHP function inside Flash. Amfphp respect data types, so if you return a PHP array, it will be treated as an AS array, you don't have to worry about parsing. So far it has supported all the formats i needed, strings, integers, arrays, arrays of arrays, xml, you name it. By using the AMF3 protocol it also means communication is sent in a compressed binary format, wich saves bandwith, communication delay, and helps keeping the script kiddies at bay.
by fox1980 » May 25th, 2010, 8:06 pm
by flash_mmo » May 25th, 2010, 9:05 pm
fox1980 wrote:Cheers mate. I don't know how to draw data directly from GET, all i got when i used an urlrequest was the source HTML. At the time i was searching the best way to do Flash->PHP communication and everyone i asked advised me to use amfphp, i tried it, tought it was fast and easy and was convinced quickly.
If you do want a better answer than the one i gave you, you can read a compreensive description about amfphp here:
http://www.amfphp.org/amfphprocks.html
I'll post and example in a while (not at home atm).
by fox1980 » May 25th, 2010, 9:34 pm
<?php
class HiWorld
{
public function test() {
$var[0]="Hello";
$var[1]=" World";
return $var;
}
}
?>
import mx.remoting.*;
import mx.rpc.*;
private function test():void {
var responder:Responder = new Responder(onresult);
var connection:NetConnection = new NetConnection;
connection.connect(http://www.yourserver.com/amfphp/gateway.php");
connection.call("HiWorld.test", responder);
}
private function onresult(result:Array):void
{
Alert.show(result[0] + result[1]);
}
by flash_mmo » May 25th, 2010, 10:29 pm
fox1980 wrote:Amfphp is just a set of php scripts that implement the amf3 protocol.
Flash already has builtin components to talk to amfphp. All you need to do is download amfphp and upload it to a folder on your webserver.
Create a file called HiWorld.php inside /amfphp/services. Put this inside:
- Code: Select all
<?php
class HiWorld
{
public function test() {
$var[0]="Hello";
$var[1]=" World";
return $var;
}
}
?>
Now in actionscript you can call the test function like this:
- Code: Select all
import mx.remoting.*;
import mx.rpc.*;
private function test():void {
var responder:Responder = new Responder(onresult);
var connection:NetConnection = new NetConnection;
connection.connect(http://www.yourserver.com/amfphp/gateway.php");
connection.call("HiWorld.test", responder);
}
private function onresult(result:Array):void
{
Alert.show(result[0] + result[1]);
}
Of course this is just a simple example, but you can already see the it's usefullness. Flash recognises the php array as such, try and pass an array or even more complex objects through GET
by flash_mmo » May 26th, 2010, 4:59 pm
by fox1980 » May 26th, 2010, 6:18 pm
by flash_mmo » May 26th, 2010, 6:32 pm
fox1980 wrote:Oh yes, i forgot to mention that. I'm an uncondicional fan of Flex/Flash Builder, so yes the imports are from the flex framework.
Here's a link to a very good and easy tutorial for Flash CS->amfphp:
http://www.gotoandlearn.com/play?id=79
by fox1980 » May 26th, 2010, 6:42 pm
by flash_mmo » May 26th, 2010, 6:51 pm
fox1980 wrote:When you get that error message, 99% of the time it's a bad formatted php file. Make sure all parenthesis are closed, and it's actually php code, i lost count of how many time i wrote AS3 syntax inside a php file. For easier debugging just access the php service file you created directly in the browser and it will tell you wich line is causing the problem.
by fox1980 » May 26th, 2010, 6:59 pm
Some typical situations which raise a Call.BadVersion while developing in AMF-PHP Remoting:
1.open with browser the gateway.php file. A download dialog should appear, this means it's all ok. if you don't see the download dialog or the page is not blank, you've errors in the gateway file
2.open with the browser the php class file you're using as service (for example localhost/flashservices/service/myclass.php). no character must appear in the page
3.build PHP test suites to thoroughly test your PHP classes. If your tests generate warnings or errors, you can either fix them or do error_reporting(0); at the top of your PHP code. It happened to me that opening a class in my browser didn't generate any output (which is the desired behavior) but when calling one buggy method from Flash it did generate warnings and returned a Call.BadVersion.
4.if you're under windows try to name the php class file and the class & constructor with lowercase characters
5.blank line or spaces at the beginning or end of your php files (gateway.php and class file)
6.be sure you're not adding any BOM header to the files if your editor save files with UTF encoding
7.If you're using firewall program such as ZoneAlarm try to disable them and try again
8.If in your flash you're trying to call 2 remoting methods in the same time try to comment out one. If next time it works then you need to download the last AMFPHP version
9.If you work under Windows or Mac OS X, your editor may be creating incompatible line breaks. Windows terminates every line with CRLF (\n\r); some applications in Mac OS X terminate lines with the standard Mac line ending (chr(13)) plus a CR (\n)
10.If your PHP service class uses include files do not forget to check the line breaks in those include files as well.
11.Check if in your functions, you haven't included "echo" for tests. Remove every echo-call.
12.For the installation on Mac OSX with apache
13.If you receive a message like:
Scene=Scene 1, Layer=Remoting, Line=1: Error 5: Error opening include file NetServices.as: File not found.
#include "NetServices.as"then you first need to download the Flash Remoting components from macromedia.com
1.Also take note that if your service class uses included classes, the calling function will need to have the class file included in the function itself
2.Don't forget to look at the errors PHP generates. On test systems you will usually see the PHP errors directly on the PHP page called; you can't use that info when working with remoting. What you need to do is change the php.ini log_errors value to On. When you do this you will be able to retrieve the errors PHP generates in Apache's error log (available under (server)/logs/error.log. Usually these errors are helpful enough that you will be able to pinpoint the source of the problem.
3.The path in gateway.php (in your project folder) must be ABSOLUTE:
e.g
include("d:\appserv\www\flashservices\app\Gateway.php"); (change to your absolute path!);
$gateway = new Gateway(); $gateway->setBaseClassPath("./services/"); $gateway->service();
by flash_mmo » May 26th, 2010, 7:07 pm
fox1980 wrote:So you get a normal result when you press 'call' from the services browser ?
The services browser is just a program so you can test your services, if you get the php return value back then the problem should lie in your AS3 code.
Anyway i found this info:
package
{
import flash.net.Responder;
public class RemotingTest
{
private var rs:RemotingService;
function RemotingTest()
{
init();
}
private function init()
{
rs = new RemotingService("http://localhost/amfphp/gateway.php");
var responder:Responder = new Responder(onResult,onFault);
var params:Object = new Object;
params.arg1 = "something";
params.arg2 = "2";
rs.call("Test.test",responder,params);
}
private function onResult(result:Object):void
{
trace(result);
}
private function onFault(fault:Object):void
{
trace(fault);
}
}
}
by fox1980 » May 26th, 2010, 7:41 pm
var params:Object = new Object;
var params:Object = new Object();
private function init()
{
rs = new RemotingService("http://localhost/amfphp/gateway.php");
var responder:Responder = new Responder(onResult,onFault);
var params:Array= new Array();
params.push("something");
params.push("2");
rs.call("Test.test",responder,params);
}
define("PRODUCTION_SERVER", false);
by flash_mmo » May 26th, 2010, 8:58 pm
fox1980 wrote:Not sure if this is the reason but :
- Code: Select all
var params:Object = new Object;
should be:
- Code: Select all
var params:Object = new Object();
Tough i would never tried passing an object type.
Can you try this ?
- Code: Select all
private function init()
{
rs = new RemotingService("http://localhost/amfphp/gateway.php");
var responder:Responder = new Responder(onResult,onFault);
var params:Array= new Array();
params.push("something");
params.push("2");
rs.call("Test.test",responder,params);
}
Also if you're working on localhost you should change production_server parameter to false in gateway.phpdefine("PRODUCTION_SERVER", false);
If none of these work can you show me your php file ?
function loadX($uid)
{
$result = mysql_query("SELECT x FROM players WHERE uid=$uid");
return mysql_result($result, 0);
}
var charX:Number = gw.call("loadPlayerService.loadX", res, 0);
by flash_mmo » May 26th, 2010, 9:42 pm
public function onResult(responds:Object):void{
if (getNetResponse.length > 0)
getNetResponse.pop();
else
getNetResponse[0] = responds;
trace("Server response: "+responds);
}
my_char.x = getNetResponse[0];
by fox1980 » May 27th, 2010, 12:13 am
function loadX($uid)
{
$result = mysql_query("SELECT x FROM players WHERE uid=$uid");
$row=mysql_fetch_array($result);
return $row["x"];
}
public function onResult(responds:int):void{
trace("Server response: "+responds);
my_char.x = responds;
}