Skip to main content
GameDev.net gamedev.net
🔒 Locked

MMO Attack types

Started by EmpireProductions Nov 14, 2009 at 8:20 PM 9 replies 2.2k views
Original Post
EmpireProductions
EmpireProductions
I am working on my Battle system. I have it so that battle messages are being sent back and forth between client and server and its all working as expected but now I am trying to set up the different types of attacks. I want the attacks to be scripted using Lua but I have no idea how to set it up. So far they are all hard coded into my battle manager using C++. Here is what I have so far. I have created a Attack type template: AttacksTypesTemplate.h

#include <string>
#include "NetCommon.h"

using namespace std;

struct Attack_Type;

class AttackTypesTemplate
{
public:
	Attack_Type attack;

	AttackTypesTemplate();
	~AttackTypesTemplate();

	//Create Attack
	void createAttack(string Name);          // Creates an Attack with the name giving

	//Sets
	void setAttackStrength(int strength);    // Sets the attack strength for the attack
	void setUIImage(string ImageLocation);   // Sets the location of the image to use to represent the attack
	void setNeededLevel(int Level);          // Sets the level at which the Attack becomes available
	void setDamageType(int DamageType);
	void setDescription(std::string Description);


	//Gets
	struct Attack_Type GetAttack();          // Gets the attack so it can be used
	std::string getDescription();


private:
protected:
};
AttacksTypesTemplate.cpp

#include "AttackTypesTemplate.h"

AttackTypesTemplate::AttackTypesTemplate()
{
}

AttackTypesTemplate::~AttackTypesTemplate()
{
}

void AttackTypesTemplate::createAttack(std::string Name)
{
	attack.AttackName = Name;
}

void AttackTypesTemplate::setAttackStrength(int strength)
{
	attack.AttackStrength = strength;
}

void AttackTypesTemplate::setNeededLevel(int Level)
{
	attack.neededLevel = Level;
}

void AttackTypesTemplate::setUIImage(std::string ImageLocation)
{
	attack.imageLocation = ImageLocation;
}

struct Attack_Type AttackTypesTemplate::GetAttack()
{
	return attack;
}

void AttackTypesTemplate::setDamageType(int DamageType)
{
	attack.damageType = DamageType;
}

void AttackTypesTemplate::setDescription(std::string Description)
{
	attack.Description = Description;
}

std::string AttackTypesTemplate::getDescription()
{
	return attack.Description;
}
Then the attack is created using:

AttackTypesTemplate* Fireball = new AttackTypesTemplate();
	Fireball->createAttack("Fireball");
	Fireball->setAttackStrength(10);
	Fireball->setDamageType(MAGIC_FIRE);
	Fireball->setNeededLevel(1);
	Fireball->setDescription("You cast a Magic Fireball \n");
	Fireball->setUIImage("../media/UI/Spells/Fireball.jpg");
How can I convert that to use Lua instead of using C++ to hard code each attack and then how would I have it load all the lua scripts from a folder. Also is this an effective way of doing it or should I rethink how I create attacks? Also I am guessing that I would have the server load all the attack types and then send the clients the needed information to display the attack? Should I have a server side script for each attack that has the needed math information about the attack and then have a client script that has the visual information for each attack? Thanks for your suggestions and tips!
In Development:Rise of Heros: MORPG - http:www.riseofheroesmmo.com
Windryder
Windryder
Your question about converting your hard-coded C++ templates into Lua would probably get better response in the Scripting Languages and Game Mods section, but it probably comes down to binding your C++ functions to Lua so that they can be invoked from script.

I like data-driven systems because they are flexible and well suited to MMOs . With that said, if you only need to store information (attack strength, level required, etc) but no code, there might be better options than Lua. XML might be a good choice for describing attack types, for example. I feel that I should mention that I've heard of many cases where MMO servers load things like item information, spells, attack types, etc from an SQL database instead because this allows the information to be stored in a central place. If your server architecture is distributed you may want to look into that.
hplus0603
hplus0603
There are two ways to use LUA. One is to use it as a data binder. Define the table properties that can configure an attack (stat used, name of attack, damage caused, armor type shielding, etc). In C++ you simply have a single "attack" class, and you configure it by handing it a LUA table that contains all the parameters. The visuals for the attack (animation, particles, text) come from the C++ class, but may be configured by the LUA table (such as name of particle system effect, name of animation, name of attack and type of damage).

The second is to put the attack logic into LUA. Pass in the attacker as a table (or a bound object), and the target as a table (or a bound object), and just run the function for the particular attack. It can then figure out whether to use stats, skills, armor, etc, based on the properties available on attacker and target. At this point, the visuals should generally be available as functions for the LUA script. You might have functions like "PlayParticleSystem," "PlaySound," "SendBattleText" etc. It's then up to the LUA attack function to do the right thing. That, in turn, can be implemented using LUA classes/inheritance if you want, but architectually, that's at a different layer.

It's easiest to run all this on the server, and simply forward the visible effects of the attack to the clients: The property "Orc32.Hitpoints" changed to 45, the battle text "Rogue backstabs Orc32 for 98 damage" appears, the particle system "SmallBlood" plays on bone "Spine02" on "Orc32," etc.
enum Bool { True, False, FileNotFound };
EmpireProductions
EmpireProductions
windryder had suggested storing all the attack information in a mySQL database. I am planning on storing user account information, character information, Items, Objects, and all that stuff in the database. Should I just go ahead and store the attack information in the database as well? What other types of things is a Scripting language used for if all that stuff is stored in a database?
In Development:Rise of Heros: MORPG - http:www.riseofheroesmmo.com
Windryder
Windryder
The advantage of storing it in the database is that it can be updated on the fly, and no updates need to be distributed to the servers. Of course, you could also use Lua or XML and then update all your servers' local files using a tool like rsync. I'd go with the database approach because that way you get the benefits of being able to have your changes immediately reflected throughout the entire system, and only having to make said changes once.

As for your question regarding what one could use a scripting language for if not to describe data, it really depends on how your game works. If you're not sure of what you could use a scripting language for if you store all your data in the database, don't implement one! Here are some random ideas though:

- Scripting AI, for NPCs and monsters
- Allowing world designers to extend the core engine by adding functionality like scripted trigger and event response
- Adding custom behavior to items and in-game objects

This list is by no means exhaustive, but it should give you a general idea of what you might be able to use scripting for.
EmpireProductions
EmpireProductions
You mentioning AI brings up another question. What is the best way to handle AI? Right now I have a non-graphical client that controls the 2 NPCs I currently have in world. They log into the server and are treated just like a normal player which for right now with just me logging on is fine but once I have hundreds of NPCs and hundreds of Players there is going to come a time that having the NPCs treated like a normal player is going to limit the number of real players that can connect. Also I have done nothing in the past with AI. So far the actions of the AI are completely hard coded and just do the things I have programmed them to do. What are some resources online for programming AI that will at the very least be able to surprise us some what?
In Development:Rise of Heros: MORPG - http:www.riseofheroesmmo.com
Windryder
Windryder
There is an entire section on this forum dedicated to AI. I'm sure the forum FAQ can help you with your general questions. Turns out that a FAQ hasn't been created for the AI section yet. I just assumed there was one because I could click the link. Sorry. However, I'm sure you can find plenty of resources on game AI using Google and asking some intelligent (no pun intended) questions in AI section.

How to implement a scalable AI system on the server side is a completely different thing. Your current method of making no distinction between players and NPC clients will most likely result in trouble when you want to treat players and NPCs differently, which you may very well need to. For example, each NPC will require a database row to be stored (as opposed to storing NPC templates and creating instances from said templates on startup), and there will be no way of telling whether the entry represents an NPC or a player (unless the client provides this information to the server, which may be dangerous).

There are many reasonable approaches to solving this problem. One thing to keep in mind is that AI will require a fair amount of processing, so if your game server isn't distributed you will have to accept a CPU load that increases proportionally (at best!) to the number of NPCs present in the game. The Planeshift project uses an NPC "superclient", which connects to the server using a slightly modified player protocol. The benefit of the superclient is that it can manage multiple NPCs at once, and it can be run from any machine which is able to connect to your game server. The Planeshift implementation is briefly explained in this
">Youtube video
. This concept could be expanded upon to allow multiple superclients to run simultaneously, each managing a subset of the NPCs currently in the game.
hplus0603
hplus0603
Quote:
Should I just go ahead and store the attack information in the database as well?


Databases are great at storing regular, tabular-style information. Generally, you don't want to run a query for each battle event (each attack, etc), but instead select all the data into a convenient in-memory data structure on start-up of the program. You may also want a function that re-builds these data structures from the database, and atomically updates the reference inside the server to the data structures, so that you can change game rules without restarting the server. Or just cycle the server; that's a lot easier, but would kick currently logged-on players...

If your attacks need a lot of special casing ("this attack is 3x more effective against any zombie, but only if it's a new moon, and when it is, it uses yellow instead of green gore effects") then a script is probably more natural than a database table/row/property set, though.
enum Bool { True, False, FileNotFound };
EmpireProductions
EmpireProductions
I have the online users stored in a std::map would that work for storing the attack types as well?

Have a method that loops through the attack types table and gathers the information needed then adds it to the map then repeats for the next attack type.

They can be stored in the map based on name so then in the battle manager it can just search the map for the attack name in order to get the information for the attack.

Would that work?

One reason I have been putting off adding a database is because I have forgotten the code needed to search the database and get the results. Back over the summer I knew what to use but have since forgotten. Any one know what to use for working with the database?
In Development:Rise of Heros: MORPG - http:www.riseofheroesmmo.com
Windryder
Windryder
Quote:
Original post by EmpireProductions
They can be stored in the map based on name so then in the battle manager it can just search the map for the attack name in order to get the information for the attack.


Of course you could store that in a regular map, but I'd be concerned about performance if such a lookup has to be performed every time an attack is used. I won't pretend that I know the details of the common std::map implementations, but I suspect it might not scale very well. Have you considered the hash_map class? Note that it's NOT a standard library class, but it is supported by both Visual C++ standard library (stdext::hash_map) and the GNU one (I don't remember the namespace it's in, though).
Quote:
Original post by EmpireProductions
Any one know what to use for working with the database?


You may just as well ask for anyone who knows how to "drive a vehicle". There are plenty of databases, and only some of them are based on familiar technology like SQL. You will need to be more specific.
hplus0603
hplus0603
Quote:
Would that work?


Probably, if you implemented it correctly.

enum Bool { True, False, FileNotFound };

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.