Posts: 2,087
Threads: 125
Joined: May 2010
So I've been thinking about a little something I want to program into the World of Chaos games, and that's randomized equipment drops. Like for example, when a monster is about to drop a Knife, instead of just getting a Knife, you have a chance to get a Polished Knife (which would be better than the regular Knife), or a Damaged Knife (worse than the regular Knife), and other tiers of such. I was mostly thinking about how the heck I should approach this efficiently.
My primary thought is to have an array that represents an inventory (naturally) of 32 or however many slots for each class of item I want: Consumables, Weapons, Armor and Key Items. Inside this array is stored an ID number to represent an item. My main focus is the Weapons (since the same could be done for the armor) array. The values stored here would be ID numbers that represent an item...for example, 0 could be a Knife, 1 could be a Machete, 2 could be a Bronze Sword, etc. However, I'd need another array that's adjusted alongside this that stores the adjusted "class" of the item. 0 would mean it's a plain old Knife, for example, 1 would mean it's a Polished Knife, 2 would mean it's a Damaged Knife, etc. And finally, I'd need to create two lookup arrays; quite possibly 2D-arrays. One with all of the weapons having their base values for each stat stored. For example, 0, 0 would represent Knife's base Power stat, 0, 1 would be the Knife's base Fort stat, and etc. The second 2D-array would be for the special classes, and how much they modify the other values by percentage. So 0, 0 would represent how much Polished affects the Base Power, 0, 1 would represent how much Polished affects the Base Fort stat, and etc. The only problem I'm seeing with this method (besides being a bit weird to keep track of once the tables get pretty big) is...what if I want weapons to get random bonus stat increasers as well. For example, you may pick up a plain old knife again, but this one has a +2 Power bonus. Do I need to make the array that stores the special classes of each specific weapon in the weapons array a 2D array to store bonus changes too, also creating a bonus lookup table as well? And is this the most efficient route, or way more work than necessary?
I hope I'm being clear enough...this is boggling my mind.
This really depends on the language you're using, or more specifically, whether you're using an OOP language. I program in AS3, which is heavily object-oriented, and the method you're using looks horrible and messy to me. But it's quite possible that in Java or something this would be a perfectly acceptable way to do it.
Personally, I would make a base "Weapon" class, which has properties and methods that each weapon should have. In your case this would be things like "base damage", "base fort", "power bonus" (which would be 0 if there is none), etc. Then you could have "PolishedWeapon" and "DamagedWeapon" which each inherent "Weapon", and have all the little additions which Polished and Damaged weapons need. In the end you'd then make a bunch of weapons (either as subclasses or just instances, depending on your needs), with their stats safely tucked away in objects, rather than long messy arrays. This is not only more manageable to code, but makes it easier for your mind to handle as well.
That's just to give you an idea of what I'd do, depending on the game you could make it make it more complex, with more subclasses. Of course, as I said, the general way to approach this really depends on your language, the above is just what I would suggest for an greatly OOP language like AS3.
You may have a fresh start any moment you choose, for this thing that we call "failure" is not the falling down, but the staying down. -Mary Pickford
Posts: 2,087
Threads: 125
Joined: May 2010
08-08-2013, 09:29 PM
(This post was last modified: 08-08-2013, 09:30 PM by Koh.)
Well I'm actually developing in Game Maker, and while it is object oriented in the sense that there's inheritance and all of that, it doesn't necessarily have the same type of pointer setup C++ and Java have. Like I COULD have the game create objects floating in space that does almost exactly what you're stating up there, just accessed by their ID number (which would be about the same as using a memory location in C++/Java, AKA Pointer), but I feel like having that many objects floating around (which wouldn't be saved into the save file btw) would be unnecessary, since in Game Maker, objects have a lot of default variables from just being objects (imagine, all objects inheriting from an Object superclass, with tons of predefined variables).
They wouldn't have to inherent from Object, would they? In AS3 you can just make a class from nothing, not extending anything. All these classes would do are hold weapon stats, and maybe one or two methods for some special calculations.
Plus, you don't even need to instantiate them all at once. You could make subclasses for every separate weapon, and just instantiate them (with their unique traits, like bonus damage) when you pick it up. Then you don't have them all floating around with nothing to do. I do admit that a separate class for every weapon is a bit of a hassle, but it isn't much worse than huge arrays.
You may have a fresh start any moment you choose, for this thing that we call "failure" is not the falling down, but the staying down. -Mary Pickford
Posts: 2,087
Threads: 125
Joined: May 2010
08-08-2013, 10:55 PM
(This post was last modified: 08-08-2013, 10:56 PM by Koh.)
Unfortunately with Game Maker they do. You don't actually SEE the Object superclass, but it might as well be there, since all objects get the same predefined variables. I'm familiar with just building classes from nothing (as well as Structs/Structures) from using C++. I'll have to experiment with 2d arrays much more now in Game Maker. But they aren't necessarily THAT memory intensive. I've actually ran into lag from having way too many active objects, rather than having large arrays. You have given me something to think about in regards to trying out building a game within C++ though, thanks .
I do admit that memory-wise, arrays will probably be lighter, especially if objects must extend Object. The cost is organisation of course, but if the weapons are fairly simple I guess it's a reasonable choice.
In any case good luck! I feel like making something like this myself now...
You may have a fresh start any moment you choose, for this thing that we call "failure" is not the falling down, but the staying down. -Mary Pickford
Your method in the OP is probably the best you can get in standard Game Maker.
You could perhaps try some clever usage of the Object superclass variables to represent other things. This would come at a cost to the organization benefits of even using Objects in the first place though, as then you'd have weird variable names like x and y instead of durability or power or what-have-you.
Posts: 524
Threads: 9
Joined: Jul 2012
08-09-2013, 02:27 AM
(This post was last modified: 08-09-2013, 02:39 AM by TheShyGuy.)
*Ehh sorry for repeating what you want. I was a bit confused about what you were describing...
*I wrote this in notepad. I wrote it as I was thinking about the solution....you'll see if you open the spoiler.
*there are probably quite a bit of grammar and spelling mistakes....Im sorry lol.
wall O text
Ok... From what I've read, Koh, you're looking for a way to define a variety of an item (eg.polished or damaged knife) that is randomly chosen when its base type is dropped (a knife).
problem: easily and efficiently defining and maybe storing a variety of an item
-Weapons are defined by stats, modifiers and random bonuses.
-no need to derive anything, no extra functionality or data is added.
-the only difference between a weapon variety (or weapon for that matter) are stats, modifers, and bonuses
-random bonuses can be generated by GameMaker. No need to store random values.
-so a weapon variety is now defined by altered stats and modfiers
-So how do you define and store a different type of weapon (polished knife)?
-It's all data
-why not store them in a file?
*The functionality and implementation for a knife or weapon is defined in GameMaker by code.
*The stats and modifiers which define a sub type of a weapon are stored in files.
Example:
Code: *FileName: Knife Types.txt
Number Of Types = 3
//defines base stats
Base Weapon Name = Knife
//Stats
Power = 5
Fort:=3
....
...
Defense = 0
//loop for the total number of weapon types to read in all types
Name = Plain
//modifiers : don't really have to define this i guess, but i threw it in just in case
Power Modifier :1
Fort Modifier : 1
...
...
Defense Modifier : 1
//-----------------end of one loop iteration
Name = Polished
//modifiers : Unless the base stats can change overtime, you could just redefine the stat value.
//Since theyre both constant.
Power Modifier : 2 (5 * 2 = 10)
Fort Modifer : 1.5
...
...
Defense Modifier : 0
//-----------------end of loop 2
Name = Damaged
Power Modifier : 0.7
Fort Modifer : 0.3
...
...
Defense Modifier : 0
//--------------------end of loop------All types shouldve been read in
That takes care of storing different (weapon) types. No more arrays an whatever.
This also means that you don't waste in-game memory.
....
If you're unsure about how to choose a random item:
-store the number of types of an item (3 for the knife).
-when randomly choosing for a type, have 3 be the maximum index possible.
-How you actually access the data in the file is up to you. You can read it in
at the moment of drop if you can.... Or you could go down the
array implementation again. Except everything will be better organized.
Simply define a class that defines all possible modifiers (power, fort,defense).
Code: class WeaponModifers
{
//damaged , polished
string Name;
int PowerModifier;
int FortModifier:
....
int Defense Modifier;
}
Then create an array of these for each type of weapon at level load time or whenever.
Code: WeaponModifiers[] knifeTypes = ReadAllTypesFromFile("Knife Types.txt");
WeaponModifiers[] ScimitarTypes = ReadAllTypesFromFile("Scimitar Types.txt");
....
...
This is similar to the 2D array way you posted about, but it's pretty clear what type of weapons you're using.
hmmmmm....You can probably take this a step further.....But I already wrote a wall of text - and I have zero knowledge of Gamemaker and its limits. If anything is confusing, just ask.
Something To Think About:
-Binary Data instead of pure text:
--> PRO: Data becomes more compact and should be faster to read in. This means, reading in stats can be done right before drop and avoid arrays altogether.
--> CON If you don't have experience looking at raw binary data or hex values, creating files would be confusing. -If you do it by hand. (Make a small program to read/write files)
Edit:
-If you're wondering how to save a "special" weapon that the player has, you can always just store the special weapon's index and random bonuses. Then when you load the player's inventory of weapons, just re-read in the data file containing the weapon's types and load the corresponding sub type. Then read in the stored bonus.
Posts: 2,087
Threads: 125
Joined: May 2010
I actually hadn't thought of that...I could have all the base stats of weapons stored in a text file, and just load them in when the weapon is created. It's something I'll experiment with today; thanks for all the help =).
(08-09-2013, 02:27 AM)TheShyGuy Wrote: -Binary Data instead of pure text:
-->PRO: Data becomes more compact and should be faster to read in. This means, reading in stats can be done right before drop and avoid arrays altogether.
-->CON If you don't have experience looking at raw binary data or hex values, creating files would be confusing. -If you do it by hand. (Make a small program to read/write files)
Just wanna say I agree with this. Obviously, if you're not experienced with binary data and/or Game Maker isn't fit for handling it, text may be easier. It's probably easier to write too (unless you make a custom tool to create these files).
However personally, once I understood how to work with it, I highly prefer binary files over text or XML files. It's smaller, easier to parse (from my point of view anyway), and probably quicker too.
You may have a fresh start any moment you choose, for this thing that we call "failure" is not the falling down, but the staying down. -Mary Pickford
Posts: 2,087
Threads: 125
Joined: May 2010
I'm thinking of separate text files for each item class. For example, Knives.txt would contain all the information about each and every knife, categorized by id. Like this:
Code: [0]
name=Knife
lvreq=1
power=3
[1]
name=Machete
lvreq=3
power=11
As for the method of storing, I think a single 2D array would work when set up like this:
Code: /*
2D array for storing items. First value represents the inventory slot
number of an item, the second represents specifics:
Second Value Meanings
00 = Is there an item here or not (boolean).
01 = Item class (0 = knives, 1 = swords).
02 = Item ID of the item class.
03 = Special Quality ID (used for equipment).
04 = Name of Item
05 = Level Requirement
06 = Power Modifier
07 = Fort Modifier
08 = Mystic Modifier
09 = Stamina Modifier
10 = Energy Modifier
11 = Sprite for the item in the HUD.
*/
global.inventory[25,10]=0;
Posts: 524
Threads: 9
Joined: Jul 2012
08-09-2013, 02:52 PM
(This post was last modified: 08-09-2013, 02:56 PM by TheShyGuy.)
(08-09-2013, 09:17 AM)Koh Wrote: the second represents specifics:
Second Value Meanings
00 = Is there an item here or not (boolean).
01 = Item class (0 = knives, 1 = swords).
02 = Item ID of the item class.
03 = Special Quality ID (used for equipment).
04 = Name of Item
05 = Level Requirement
06 = Power Modifier
07 = Fort Modifier
08 = Mystic Modifier
09 = Stamina Modifier
10 = Energy Modifier
11 = Sprite for the item in the HUD.
Code: global.inventory[25,10]=0;
Hmmm, you can approach it from another and clearer way. Going this route of "an index represents a property value" is very complicated and not very intuitive.
Since It seems you can't create classes without inheriting all the GM Object garage, I'd go with the approach of just creating multiple arrays that define a single property foreach inventory slot item.
Example:
Code: int maxInventory = 32;
boolean[] slotOccupied = new boolean[maxInventory];
int[] Class = new int[maxInventory];
int[] ID = new int[maxInventory];
int[] SpecialQualityID = new int[maxInventory];
string[] Name = new string[maxInventory];
...
...
int[] EnergyModifier = new int[maxInventory];
Image[] SpriteIcon= new Image[maxInventory];
How you would access a property:
Code: global.EnergyModifier[25] = 0;
It's obvious which inventory slot you're talking about and what property you're changing.
Posts: 2,087
Threads: 125
Joined: May 2010
That way does seem the most approachable, since even if I were to add more things a piece of equipment could increase, I wouldn't have to backtrack and update the size of the array to accommodate that. I'll have to try it this way now too XD.
|