Game Development Community

Point me in the right direction? (MMO)

by Kyle Martin · in Torque 3D Professional · 09/22/2011 (4:44 am) · 8 replies

This is my first thread so bare with me. I have had a lot of experience coding so LUA files, C++ files, and MySQL databases. I am looking into starting to create a MMO, not exactly to release or anything. Just to refine my skills and learn. The thing is I dont exactly know where to start.

I have a general idea. I have to code the game to connect to a server. Like a master server. Or Authentication server. I know how to create a MySQL database and files. Im looking for my database to have a account table, character table, inventory table, spell table, npc table, item table, bank table, and a few others.

The thing is, I am a newbie when it comes to understanding servers. So would i need a master server and would it be able to read those databases, or would i need a python authentication server to read them?

If anyone points me in the right direction to creating a Server to where the client can contact that. The server loads the database files. The client feeds from the database files. Etc... I will post tutorials on creating a good MMORPG database and how to optimize it.

#1
09/22/2011 (6:01 am)
As far as i can reasonably tell, the only thing torque is missing is multi-server management and good real time databasing code.

If it were me, id probably take a look at one or two of the WoW emulated servers and see how they do things then work that system into torque
#2
09/22/2011 (7:05 am)
I have a thread with a huge amount of articles located here.

It's in horrible need of an update, but some things I can tell you in my own travels:

- Amazon AWS is a fantastic and relatively cheap tool with which to create a network. Zynga uses it to launch games (which they then reintegrate into their datacenter once the player population stabilizes).

- Refer to the links to the IBM server architecture for MMOs using Torque. It's dealing with an older version of the engine, but the networking has not seen much change over the years, so the white paper is very accurate.

- T3D is made for FPS servers in mind, and an MMO will transmit much more data. You're going to want to rip out any network data being sent that isn't being used, and probably lower the fidelity of the data as well, if you're not going to do much with accuracy (you'll notice this in other MMOs as well).

- Don't do anything that relies on the client for information. Never, ever, 3V3R!!!11!1!one

- Don't expose your database directly to any server which is directly touched by a client. That is bad networking practice, since if the client compromises that server, they have a direct bead on your database. If you use TCPObject or HTTPObject against a web server, which in turn queries the database, it's much more secure.

- As a corollary to the above, secure even your sever to server communications. The harder your network, the harder it is to defeat.

I can go on all day about this stuff :) Take a look at the link and there is a lot of info on making MMOs using Torque in there, both from a coding stand-point as well as blogs by those who have done it. Good luck!
#3
09/27/2011 (5:43 pm)
My question is. If I code 3 server cores. Logon Server, Gameserver, and World server. What files in Torque do i change, or create for the game to connect to the logon server to check accounts, load the game from the game server files, and have the npcs and stuff connect to the world server for their function?

And the server cores connect to MySQL
#4
09/28/2011 (7:48 am)
@Kyle: That question's answer is about 300 pages long- I'm not kidding.

Building an MMO is more than just building a "game", it's building a "service", and like any service, there's a million ways to do it, and none are easy. I would suggest starting by reading some of the books out there on MMO design and development. You might think that they're long-winded, but they will teach you a lot about not just what you want to do, but why you want to do it, and "the why" is a big deal. MMO gameplay is not the hard part of this project- it's content, the back-end, and making everything work together. And that's why there are books dedicated just to making MMOs.
#5
09/28/2011 (8:07 am)
Issues like this is why we are working on a new MMO solution of Torque and not just our own MMO. OMNI (what we are calling the MMO solution) will take care of alot of the repetitive coding that most MMOs contain (auto updater, chat programs, database access, etc).

IMO people should be able to worry more about game design and less about the "internals".
#6
10/03/2011 (8:20 pm)
Im with you there Winterleaf. I just need to know where to start. Like how do i go about coding a server that will talk to torque and MySQL.
#7
10/04/2011 (4:29 am)
Quote:how do i go about coding a server that will talk to torque and MySQL.

Set up a web server with PHP or ASP or something like that. T3D can connect to it using HTTPObject and parse the results, and any web tech out there can connect to a database back-end. As to which web server to use- that's up to your level of comfort, but the two big ones are IIS (Microsoft) and Apache (Linux). Linux obviously has less overhead, but IIS/Windows Server is a fine choice as well.
#8
10/05/2011 (7:07 am)
Quote:What files in Torque do i change, or create for the game to connect to the logon server to check accounts, load the game from the game server files, and have the npcs and stuff connect to the world server for their function?

You can use Torque's HTTPObject along with REST or SOAP, to send data to the server. You will probably want to implement openssl in torque to do this.

As a code example, here is how I did this with SOAP:
add this

and script like this
//-----------------------------------------------------------------------------
// Login
//-----------------------------------------------------------------------------

function checkPassword(%user, %passhash, %function)
{
   %client = new HTTPObject();
   %client.user = %user;
   %client.pass = %passhash;
   %client.func = %function;   
   
   %client.callService("AccountMgr", "getSalt", "<q0:username>" @ %user @ "</q0:username>");
   %client.waitForService("checkPassword1");
}

function checkPassword1(%client, %data)
{
   %resp = sha(%client.pass @ stripTagTo(%data, "getSaltReturn"));
   %client.callService("AccountMgr", "checkPassword",
   "<q0:username>" @ %client.user @ "</q0:username><q0:password>" @ %resp @ "</q0:password>");
   %client.waitForService("checkPassword2");
}

function checkPassword2(%client, %data)
{
   call(%client.func, stripTagTo(%data, "checkPasswordReturn") $= "true");
   %client.delete();
}

//-----------------------------------------------------------------------------
// Utility
//-----------------------------------------------------------------------------

$Web::Host = ""; //hostname
$Web::Port = "8080"; //usually
$Web::Uri = "/whatever/services_or_something/";

function HTTPObject::onConnectFailed(%this)
{
   echo("Connection failed");
   MessageBoxOK("Error", "Could not connect to server.");
   cancel(%this.sched); //avoid spurious errors
}

function HTTPObject::onLine(%this, %line)
{
   %this.buf = %this.buf NL %line;
}

function HTTPObject::callService(%this, %service, %function, %args)
{
   %this.buf = "";
   %query = "<soapenv:Envelope xmlns:q0=\"xml_namespace_here\" xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" "
            @ "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><soapenv:Body>"
            @ "<q0:" @ %function @ ">" @ %args @ "</q0:" @ %function @ ">"
            @ "</soapenv:Body></soapenv:Envelope>";
   %this.post($Web::Host @ ":" @ $Web::Port, $Web::Uri @ %service, "", %query);
}

function HTTPObject::waitForService(%this, %function, %count)
{
   if (%count > 1000) //timeout
   {
      error("Service timeout!");
      MessageBoxOK("Error", "Service timed out, please try again.");
      return;
   }
   
   if (hasError(%this.buf))
   {
      error("SOAP error: " @ stripTagTo(%this.buf, "soapenv:Fault"));
      MessageBoxOK("Error", "Server error. See log file for details.");
      return;
   }

   if (strstr(%this.buf, "</soapenv:Envelope>") != -1)
      call(%function, %this, stripTagTo(%this.buf, "soapenv:Body"));
   else
      %this.sched = %this.schedule(300, waitForService, %function, %count + 1);
}

function stripTagTo(%string, %tag)
{
   %begin = strstr(%string, "<" @ %tag @ ">") + strlen(%tag) + 2;
   return getSubStr(%string, %begin, strstr(%string, "</" @ %tag @ ">") - %begin);
}

function hasError(%xml)
{
   return strstr(%xml, "soapenv:Fault") != -1;
}