Database for a multi-user RPG - actionscript-3

I'm making a Flash turn-based RPG to practice OOP (who doesn't :P) I have a pretty good setup with the Weapons, Items, and all that Jazz. Though I'm currently considering how I will make my characters.
Currently I have an player and enemy class that extends the battler class.
Battler
/ \
/ \
Player Enemy
My player class has some functions that initialize the player itself, adding the graphics and all that. My party class calls on player, passing a paramater like so: player.setup(1) with 1 being the playerID.
To Clarify this is my player pseudocode:
{ setup(player_id)
player = **??????player_id??????????**
name = player.name
character_name = player.character_name
character_index = player.character_index
weapon_id = player.returnWeapon
/*---------
armor1_id = player.returnArmor //increase for other body parts
----------*/
level = player.level
}
My question, or more of a problem is how I will store the player data. I need to have many players as this is a game with many players in a party.
How will I actually use something like player.returnArmor ? Because when I do that it just calls a function, and it will not know who that player is (I guess I could use parameters, like player.returnArmor(player) but I think there is a better way to do this.
Any language is welcome, but just so you don't use assembly language as an example ;), C++, Actionscript 3, Ruby, and/or Java is fine. Please Help Me! Thank you in advance.

In AS3 you can have static and instance functions. If you call player.returnarmor(), you're calling a static function. You want to have an instance function, and call it for the instance of the player whose armor value you want.
If you have a few (<4) characters, you can just have named variables for each, but more than 3 or 4 and you should just have an array or other container for them.
var mainProtagonist:player;
var spunkySidekick:player;
var whiteMage:player;
var players:Array = new Array();
players.push(mainProtagonist);
players.push(spunkySidekick);
players.push(whiteMage);
Then to get a player's armor...we'll say you want the spunky sidekick's armor:
players[1].returnarmor();
// or
spunkySidekick.returnarmor();
You might have an array of all the players in existence, as well as another array, when used in battle, with just the players in the current party/battle. That way your enemies can target players at random, and only from those currently in the battle.

It might be worth considering using an entity system, where each item in the game is treated as a collection of unrelated properties (location, velocity, bitmap/mesh) which can be managed separately. This tends to make the hard problems easier (scalability, synchronisation, storage).
http://www.tomseysdavies.com/2011/01/23/entity-systems/
http://www.richardlord.net/blog/what-is-an-entity-framework
http://www.richardlord.net/blog/why-use-an-entity-framework

Related

Actionscript 3 - How to access integer variable in main timeline from inside MovieClip

First, sorry if my english is bad and I'm new to Actionscript 3.
I have a movieclip, I give it an instance name "symbol1" which include a code inside it, like this :
var a: int = 2;
var b: int = 3;
var total: int = a + b;
How can I access the "total" integer variable inside that movieclip in the main timeline? I try to trace it but the result is 0. In the main timeline I wrote this code :
trace(symbol1.total);
I appreciate the help, thanks
The "problem" is the order of execution of frames. The parent is executed first.
The value is 0 and not undefined because the property does indeed exist since the creation of the object which happens in a previous separate step.
You should be able to verify that by stepping through your code with the debugger.
I've made 6 games. each game is in the MovieClip including the game functions, times, scores, variables, etc. I want the total score of each game summed outside each MoviClips, which is in the main timeline. is there a solution to that problem?
This makes your timing problem even more apparent.
You arrive at a frame, which contains a game and you immediately want to access the total score of it. It should be obvious that the game first has to be played in order to obtain a score from it.
Asking a newborn baby what his favourite moment in the first 60 years of his live was doesn't make much sense.
You have to notify the main timeline that the game was finished. The best way to do this is to dispatch an Event from the game. Frames are totally unnecessary.
Your code could look something like this:
var game:Game = new Tetris();
addChild(game);
game.addEventListener(GameEvent.FINISH, onFinish);
function onFinish(e:GameEvent):void
{
trace("finished game with score " + game.score);
}
If you want to update the exterior score sum while the game is running (to immediately reflect any change in the score, not just when the game is finished), your best bet is to create a ScoreModel for the score which you pass to the game, the Game. The Game modifies the ScoreModel, which in turn causes it to dispatch Events:
var score:ScoreModel = new ScoreModel();
var game:Game = new Tetris(score);
addChild(game);
score.addEventListener(Event.CHANGE, onScoreChange);
function onScoreChange(e:Event):void
{
trace("score changed to " + score);
}
Both examples are "what your code could look like"-type of examples. There are many questions about how to dispatch events that explain how to do this in more detail.
Something that came up in the comments from #Jezzamon:
I'm pretty sure you're accessing the variable total correctly, otherwise I would expect it to cause an error (you can test this by trying to run trace(symbol1.variableNameThatDoesntExist)).
No, there cannot be an error for accessing a variable as seen in the question. The reason for that is that the property is accessed on a MovieClip object, which is a dynamic class. As such, the compiler doesn't know if accessing a particular property is valid, because that can change at runtime. And because nothing else relies on the value to be valid, there isn't a runtime error either.
Here's some example code to illustrate this:
trace("toString: " + {}.toString); //toString: function Function() {}
trace("bananas: " + {}.bananas); //bananas: undefined
This is one of the reasons why using MovieClip can be a bad idea. In addition to that, the Flash IDE modifies the code behind the scenes. That can lead to unexpected execution of code. A purely code based workflow sure is advantageous in this regard and recommended.

Vector holding (certain) (sub)classes (instead of instances of)

So I've only somewhat recently I've started ActionScript 3.
For practice purposes I'm trying to make a simple game that should have a small number of levels. All levels are a subclass of the super class World.
So, basically I would want to do something like:
private static var levels:Vector.<Class> = new <Class>[ Level1, Level2 ];
Except in this case I only know that the classes in my vector are a subclass of Class (right?), where as I would like to know they are sub classes of World.
I know I can grab the Class from the vector, then cast to World- but if at all possible I really would prefer to be able to do this without such casting.

Dll-Injection, call function in target process

I have some basic knowledge about how assembly works and I also know the basics about higher level programming. (I did a lot of ahk and lua.)
But I never really did object orientated programming.
I did the official Cheat Engine tutorial, so I know how to find static pointers to changeable values and I'm also able to make a program decrement a value instead of incrementing it. And I know that the properties of units in computergames or mostly stored in consecutive addresses...
Well, what I want is to find and call functions of some of my computergames.
Examples:
draw pictures and text (the same way the game does it, with the same font etc)
shoot my gun
cast my spell to position xy
buy a new weapon/spell or whatever
I don't want to hook directX or simulate keystrokes.
I want to do it in C++ via Dll-Injection.
I don't really know C++, but I could write a function, loop, if statement and declare variables etc (all that basic stuff).
It will probably a bit more complicated, but something like that would be great: a lib/class/function which I could use like this:
pointer = [[[[myprocess.exe]+C4]+0]+8]
address = PointerToAddress(pointer)
CallFunction(address) //or CallFunction(address, param1, param2, ...)

Is Robotlegs capable of doing this task?

I consulted with a coworker about something I want to implement in my project, and he told me about Robotlegs, it would be like this:
from a external data source (databse, xml, etc) I create objects that behave the way I need and more important, when I need, let me explain:
I got a unit, let say, a soldier, that listens to the event: "walk" and executes the method: "walkNormally". The database would have 2 records, one with the unit name: "Soldier" and other one with both fields, one the event, and the other one the method to execute when that event triggers.
Obviously, I got a lot more of pairs of events - methods that I need in order to get my soldier performing like a soldier, like shoot, run, die, etc.
Is Robotlegs capable of making this task?.
Thanks in advance.
I hope your co-worker isn't an AS3 developer, because Robotlegs has nothing to do with what you are asking
You can access a function by calling its name in string format. Just like the XML you are reading it from.
var mySoldier = new Soldier( )
mySoldier['WALK']( 10 )
package{
class Soldier{
public function walk( var howFar:int ):void{
// do walking stuff here
}
public function shoot( ):void{
// do shooting stuff here
}
}
}

How can I create Vectors dynamically in AS3?

I want to create a class that will mainly house a Vector. The class will have some methods that deal with items in the Vector.
The issue I am having at the moment is that I can't work out how to dynamically create an instance of Vector. So far I've tried this and similar with no luck:
public class List
{
private var _content:Vector;
public function List(type:Class)
{
_content = new Vector.<type>();
}
}
Here is how I dynamically construct a vector of BitmapData (which is required by the MouseCursorData class):
var vectorClassOfBitmapData:Class = Class(getDefinitionByName("__AS3__.vec::Vector.<flash.display::BitmapData>"));
var bitmapDataVector:* = new vectorClassOfBitmapData(1,true);
The above is the same as the compile-time:
var bitmapDataVector:* = new Vector.<BitmapData>(1, true);
In this way, you can compose the class definition string at runtime and use getDefinitionByName to dynamically construct vectors of different data types.
Not exactly what you were after, but it might help others.
This post by Paul Robertson (previously Senior ActionScript Developer/Writer at Adobe) provides a little more information on how Vectors are declared:
The Vector class allows (requires) you to specify the type it will
contain at compile time — both for variable declarations and when
creating instances.
Because the type parameter is a literal, it must be provided at compile time. In fact, every reference to a Vector is checked at compile time, with the exception of .shift() and .unshift, which are checked at run time.
Adobe's article on indexed arrays provides some more interesting information on that. In fact, it mentions that strict compile time type safety is one of the key features of Vectors.
In short: It is not possible to use a variable to set a Vector's type, because the type parameter is a literal and a compile time requirement.
Hope that helps!
Additional References:
http://www.adobe.com/devnet/flash/quickstart/programming_vectors_as3.html
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/Vector.html
http://www.mikechambers.com/blog/2008/08/19/using-vectors-in-actionscript-3-and-flash-player-10/
How do generics (Vector) work inside the AVM?
Another option that might work for you is to use an interface; Vectors do not have to be concrete types. So if you can abstract out some common contract that your objects can abide by, then use that instead. For example, say you wanted a list of renderable objects, you could say:
public interface IRenderable {
function renderTo(obj:DisplayObject):void;
}
var _content:Vector.<IRenderable> = new Vector.<IRenderable>();
Then you can shove as many different concrete types into the Vector, as long as they implement the IRenderable interface. So while generics in ActionScript 3 are really just syntactic compiler sugar, like Andrew Odri said, you might be able to get around that depending on what you are specifically trying to do.
Sounds like you just need an Array! The performance is only improved with a Vector<> because the type is sorted out at compile time. If you want a "dynamic" type, then you should use an Array.
The original question is a couple years old, but I felt like sharing this because it might help others.
It's inspired upon Matthew Peterson's answer but it assumes a little less about the internal class names (it only assumes the .<> syntax).
function CreateVectorOf(subtype:Class)
{
var vecname:String = getQualifiedClassName(Vector);
var subname:String = getQualifiedClassName(subtype);
var vecclass:Class = getDefinitionByName(vecname + ".<" + subname + ">") as Class;
return new vecclass();
}