PDA

View Full Version : Attributes, Stats, & Modifiers, oh my!



Gleeok
12-12-2012, 07:06 AM
Yep. What the title says.

Here is my crappy editor work-up from a little while ago: (It won't look this crappy later though)
http://i235.photobucket.com/albums/ee138/Tiamat_AD/me1.jpg
http://i235.photobucket.com/albums/ee138/Tiamat_AD/me2.jpg

Here's how I had/have it:
-The editor will allow you to rename any or all names of attributes/status_conditions, etc. to anything you want.
-There is support for 32 integers (stats), 64 16-bit integers (status/elements) and a shit ton of true false values.
-Attributes are basically stored as arrays with no knowledge of what it stores, just that it can represent a percentage or be added or multiplied together with other attributes. In this way it has no concept of things like "HP" or "Agility" at all. Consider this:

We have equipped 2 swords, 3 armors, and 12 accessories (hey, why not right?).
Suppose armor A increases all elements by 20 percent and lowers speed, B increases only HP and defense, and C increases all sorts of weird things but adds the status flag assigned to "Poison". (Forgetting about accessories for now.)
We'd like to just say that the players stats are [ base + a + b + c ] (armor only here)
There are a few quirks:
-Suppose that multiple items that modify by percentage are equipped. What is the order of operations? Do they stack like in Valkyrie Profile 2? ie; multiply, then multiply again. ..or are they non cumulative?
This also applies to buffs too I guess.

Back to more on what does the engine "needs to know": What is HP anyway? Is it edible? Can I @#$% it? :P
Suppose the battle engine sees that enemy 4 has -12 HP and decides to remove it. Suppose you gave it "Zombie" status, or cast Life 3 on it or something and now it's gone so you have to write a script to workaround the fact that it was removed in the first place. Why not just have the Battle Engine controlling script say "engine.remove_enemy(e)". This also allows scripts to customize death animation/effects, bring it back to like, or whatever. So we could say knowing about stats and effects are a bad idea to things that have no business knowing about them. If we just follow good c++ object oriented paradigms it will allow the most flexibility.


So... Attributes and modifiers are pretty important to get right at the get go since they cannot be changed easily. (This means you have to demand stuff be put before it gets to the shipping station) :P


[edit] Just to be clear; is this a reasonable way to do this, enough room for custom use? Should item and spell data use a different structure than characters and monsters?
Thoughts?

ctrl-alt-delete
12-12-2012, 11:33 AM
Just one.

Oh my sweet Jesus Christ this looks awesome, why have you been keeping it from us??

CJC
12-12-2012, 10:36 PM
Percentage boost items should add their percentages together and then apply it to the current total. In that way, they don't balloon with exploitation stacking and they also are less detrimental when positive and negative percentages are equipped simultaneously.

IE: If item A and item B give a Defense boost of 2 and 5 respectively, and item C and D give a Defense boost of 12% and 7% respectively, then the attribute would become "(Defense + 2 + 5)*(1+[12+7]/100)"



So enemies and 'actors' (the characters the player controls) will be tracked in the same manner? Does that mean they share the same limit (So say, 512 slots would make room for 12 actors and 500 enemies)? I was going to use 'backup' character slots to handle a few complicated status ailments I have in mind (like Toad), and one of my biggest concerns was wasting all the player character slots with that sort of thing. But if I can just prune some enemies to make room, then it's not a problem.



Also, I agree with Kolt. This is made of awesome.

Gleeok
12-12-2012, 11:57 PM
Yeah that makes sense. So order would not matter in that case...but they'd need to be calculated separately.

Should items only increase a percentage of the base stats, or should we add the bonuses first, add the percentage modifiers second, and then calculate?
..and I guess "buffs" should treat the "base" value as all equipped values + base value.

OR, I can add overloaded methods to the script "actors", use the above calculations by default, and you can change the default behavior by editing the base character script.

..complications make it fun. :tan:

CJC
12-13-2012, 12:35 AM
Should items only increase a percentage of the base stats, or should we add the bonuses first, add the percentage modifiers second, and then calculate?
..and I guess "buffs" should treat the "base" value as all equipped values + base value.

Yeah, I figured equipment with flat bonuses would be added to the base, and then multipliers would be applied.


OR, I can add overloaded methods to the script "actors", use the above calculations by default, and you can change the default behavior by editing the base character script.

..complications make it fun. :tan:

I think this would be the safest way to code it with the highest degree of customization. Questmakers (Or whatever we're going to call them for FFC) can stick with the default for an FF style game, or experiment with the core 'actor' script to make a more complicated bonus system.

Gleeok
12-15-2012, 11:06 AM
OK, check it.

So far items, characters, and monsters are stored kinda like this:



<Monster name="Goblin" description="" script="Goblin">
<Attributes>8,6,6,1,1,80,0,0,4,4,2,6,4,16,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0</Attributes>
<Elements>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0</Elements>
<Status>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0</Status>
<Flags attrib="0" elements="0" status="0" family="0" class="0" misc="0"/>
<ItemDropSet count="0" multiple="false"/>
</Monster>


Obviously items and players don't have a drop set, and will need some spell/skill data also (not started on that yet). Other than those, am I missing anything? ...requests?

Flash Man
12-15-2012, 05:02 PM
It might make more sense to store the information using more XML elements, instead of implying a particular order with a comma delimited list. It will increase the size of the document, however it will make the format extensible by allowing more complex storage as necessary for future development.



<Monster name="Goblin" description="" script="Goblin">
<Attributes>
<Attribute type="hp">8</Attribute>
<Attribute type="mp">6</Attribute>
<Attribute type="attack">1</Attribute>
<!-- More attributes. -->
</Attributes>
<Elements>
<Element type="fire">0</Element>
<!-- More elements. -->
</Elements>

<!-- ... -->
</Monster>

Gleeok
12-16-2012, 09:13 AM
What I don't like about that is that it makes each element over 100 lines long. Multiply that by 128 and we've already got about 13,000 lines instead of a few hundred... This way should allow 3rd party interaction with the files much easier, plus it's a breeze to parse right now now.

There should be a key available which would give the string at any id though for sure, you are right about that. Something like:



<AttribStr>
<Index id = "0" name = "HP"/>
<Index id = "1" name = "EXP"/>
</AttribStr>



Also, last question (I think)

Spells/ Skills / Monster Skills :
-Should these use the same stats/atrributes as items, and should these be condensed into one list?

..If you make a blue mage class I guess it would be dumb to have 2 "white wind" spells. :\ Does anyone know how, say, FFIV or VI do these internally?

Glenn the Great
12-16-2012, 09:52 AM
Spells/ Skills / Monster Skills :
-Should these use the same stats/atrributes as items, and should these be condensed into one list?

..If you make a blue mage class I guess it would be dumb to have 2 "white wind" spells. :\ Does anyone know how, say, FFIV or VI do these internally?

I think what the classic Final Fantasy games have is one big list of "battle effects".
This list comprises every possible action that can happen in battle, regardless of whether it is a magic spell from any school, a monster ability that players may or may not have access to, a skill, or an item.
In this manner, the code that executes these effects can be generalized.

The different schools of magic/skills/etc. are just another system that you navigate through for a battle effect to be chosen and handed off to the system that applies them.
If an effect should behave differently when used by mobs vs. by players, you define the effect twice with the same spell name but different ID numbers.

Flash Man
12-16-2012, 03:05 PM
What I don't like about that is that it makes each element over 100 lines long. Multiply that by 128 and we've already got about 13,000 lines instead of a few hundred... This way should allow 3rd party interaction with the files much easier, plus it's a breeze to parse right now now.
I think that we would want to direct people to using the editor provided with the package. In addition providing a richer schema would enable those who wish to tinker with the content to better understand the format; XML is verbose. If size is the concern, then the content can always be reduced using a form of compression.


I think what the classic Final Fantasy games have is one big list of "battle effects".
That is exactly how I envisioned it; they are just repetitive effects that have slightly different calculations, visual displays and sound effects.

Glenn the Great
12-16-2012, 06:26 PM
... XML is verbose. If size is the concern, then the content can always be reduced using a form of compression.

A lot of people are dumping XML in favor of JSON. If you guys do decide to use XML, you might want to stop and consider it.
It might be a little less human readable (especially if you're not used to seeing it), but it's just as flexible if not more so than XML, while using less characters to express the same data. Supposedly there is no conceivable data structure that can't be expressed in JSON.

Flash Man
12-16-2012, 09:04 PM
I use and favor JSON in while working with Web technologies. Steam uses a very similar format called VDF. It can definitely represent all the data structures I think we will need.

For space saving we could even research the use of BSON.

Imzogelmo
12-19-2012, 11:32 PM
..If you make a blue mage class I guess it would be dumb to have 2 "white wind" spells. :\ Does anyone know how, say, FFIV or VI do these internally?

Yes, I have complete and exacting info for how FFVI's data is arranged. What do you need to know exactly?
All spells in the game are one table (including sub-ranges for regular magic spells, esper summons, blue magic, and enemy-only spells).

This is distinct from the list of items (a couple of items are implemented with spells, i.e. they have a unique spell that is fired off when the item is used, but that is really an exception and not the rule).

Gleeok
12-20-2012, 09:28 PM
Yes, I have complete and exacting info for how FFVI's data is arranged. What do you need to know exactly?
All spells in the game are one table (including sub-ranges for regular magic spells, esper summons, blue magic, and enemy-only spells).

This is distinct from the list of items (a couple of items are implemented with spells, i.e. they have a unique spell that is fired off when the item is used, but that is really an exception and not the rule).

Great! Thanks!

Do you know if items contain the same number of bytes regardless of type? (like potion : armor)

Glenn the Great
12-20-2012, 09:36 PM
Do you know if items contain the same number of bytes regardless of type?

Let me direct your attention to this fine page: http://www.tales-cless.org/docs/ff6hack.htm#part4

According to this, every item is stored with 30 bytes, though not every item uses all 30 of them.

Imzogelmo
12-21-2012, 01:33 AM
Great! Thanks!

Do you know if items contain the same number of bytes regardless of type? (like potion : armor)


Yes, in Final Fantasy 6, all items take up 30 bytes although I preface that by saying that many do no actually use the whole 30 depending on the type, and what the different fields within that 30 can mean different things based on the type (e.g. the same byte may be battle power on a weapon and defense power on an armor). Personally, I find 30 bytes too restrictive but of course if you're familiar with the game, they did a lot with those 30 bytes.

EDIT: rather than speak in hypotheticals, let me just post the data format:


Item: Tools Weapon Armor/Shield/Hat Relic Item
--------------------------------------------------------------------------------------------------------------------
$0000 Type (0) Type (1) Type (2, 3, 4) Type (5) Type (6)
$0001-$0002 -- Equippable Chars. Equippable Chars. Equippable Chars. --
$0003 -- -- Spell Learn Rate Spell Learn Rate --
$0004 -- -- Spell Learned Spell Learned --
$0005 -- Field Effects Field Effects Field Effects --
$0006 -- Cond. 1 Protection Cond. 1 Protection Cond. 1 Protection --
$0007 -- Cond. 2 Protection Cond. 2 Protection Cond. 2 Protection --
$0008 -- Cond. 3 when Equip Cond. 3 when Equip Cond. 3 when Equip --
$0009 -- Status Effects 1 Status Effects 1 Status Effects 1 --
$000A -- Battle Effects 1 Battle Effects 1 Battle Effects 1 --
$000B -- Status Effects 2 Status Effects 2 Status Effects 2 --
$000C -- Battle Effects 2 Battle Effects 2 Battle Effects 2 --
$000D -- Battle Effects 3 Battle Effects 3 Battle Effects 3 --
$000E Targetting Targetting Targetting Targetting Targetting
$000F -- Elem. Properties Elem. 50% Dmg. Elem. 50% Dmg. --
$0010 -- Vigor+/Speed+ Vigor+/Speed+ Vigor+/Speed+ --
$0011 -- Stamina+/Mag.Pwr.+ Stamina+/Mag.Pwr.+ Stamina+/Mag.Pwr.+ --
$0012 Attack When Used Attack when Used Attack when Used Attack when Used --
$0013 Weapon Properties Item Properties
$0014 Attack Strength Battle Power Defense Power Defense Power HP/MP Affected
$0015 Hit Rate Hit Rate Magic Defense Magic Defense Cond. 1 when Used
$0016 -- -- Elem. Absorb HP Elem. Absorb HP Cond. 2 when Used
$0017 -- -- Elem. No Effect Elem. No Effect Cond. 3 when Used
$0018 -- -- Elem. Weak Point Elem. Weak Point Cond. 4 when Used
$0019 -- -- Cond. 2 when Equip Cond. 2 when Equip --
$001A -- Evade%/MBlock% Evade%/MBlock% Evade%/MBlock% --
$001B -- ???/Spec.Atk. Special Action
$001C-$001D Price Price Price Price Price


EDIT: Sorry, didn't notice that Glenn already said pretty much the same thing. I can only redeem myself by saying that I can get you info on what all these things mean, as well as any other data format, if it helps to illustrate how the game operates.

Gleeok
01-06-2013, 06:55 AM
Thanks guys; I'm still going through those. I can't believe they were able to fit so much data onto one SNES cart. Pretty amazing when you think about it...

Anyway, I've got the complete monster sprite atlas done. Loading and saving xml and resources finally works now (including sprites and animations). So I can finally load these in, expose them to the scripting engine, and draw them. Not quite at the point where we can get down to it with enemy stats vs. player stats in combat, but I think getting something like a in-game bestiary done would be a good morale victory for now. :)

bobby_light
01-15-2013, 03:01 PM
A lot of people are dumping XML in favor of JSON. If you guys do decide to use XML, you might want to stop and consider it.
It might be a little less human readable (especially if you're not used to seeing it), but it's just as flexible if not more so than XML, while using less characters to express the same data. Supposedly there is no conceivable data structure that can't be expressed in JSON.

JSON (or possibly even YAML) is definitely a better way to go than XML. XML is ridiculously verbose; JSON is actually easier to read thanks to the removal of all the clutter the opening/closing tags bring with XML. You should go with what's most human-readable. Sure, XML would get you standardized validation, but if you're going to do things like smash tons of int values into a single text node like your example, you're losing a fair amount of that.

File size is pretty irrelevant; JSON/YAML has the benefit of being smaller, but no matter what the format it's going to be ultimately compressed anyway, and any text format is going to compress more than well enough.

Gleeok
01-25-2013, 12:36 AM
Alright. I think I've the gist of everything properly sorted out. There's a lot of strange special cases, many of which can just be put into misc values though, like an item that can cast a spell or cast another spell when attacking and adds a status (debuff) effect that casts a random spell every turn (all of which should be possible with the engine - with a script)... weird.

..Anyway. Two design dilemmas:

1) equippable-by and jobs flags. If 32 character classes/etc is not enough these need to be changed to a dynamic bitset. (FFV I think only had like 22 jobs so 32 seems like it should be fine.)
1B) status effect flags. Same as above. (also same as below)

2) Elemental attributes: Similar issue,; have a fixed amount (32 total - though 20 is probably more reasonable) or a pay for what you use policy by making them dynamically sized. (see below)
2B) Elemental attribute logic: FF just uses bits for weak--strong--absorb. If we use this structure then elements only need to be three bitflags which represent elemental attribute data, and actual values need to be removed. Similarly, if actual values are kept for these then the aforementioned structure should not be used in favor of values over flags.

3) Status attributes: (Same as Elemental)

Side note: Yay encapsulation for being able to easily change stuff.

Imzogelmo
01-25-2013, 03:07 AM
(all 3) - I like the dynamic sizes, for reasons I think I've explained already. But basically, I can imagine wanting to exceed some of those limits. Perhaps force bitwise flags if using more than 32 in a given chunk? I could live with that tradeoff. Or perhaps a mix of some bytes and some bits, up to a maximum size (which can be done via script anyway, not a problem). See my reasons below...

regarding elementals specifically: I used to always wonder why FF6 had separate bytes for each of the 4 elemental persuasions that it supports (in order of evaluation, they go absorb, nullify, 1/2 damage, weak, normal). I thought to myself, why not just have it store a multiplier per elemental (-2, 0, 1, 4, 2 in terms of halves)? But then I finally realized the answer: FF6 has the Debilitator, which has the effect of setting a random weakness to its target. If the target is already weak to everything, it misses. Otherwise, it will always pick an element at random, make the target weak to it, and clear any absorb, resist, or nullify that it may have. So, there is some monster which has all weaknesses already--but it also has all absorbs. Since the "weak to everything" check occurs first, this makes the monster invulnerable to Debilitator's effect.

Am I saying it can't be done with byte-per-element multipliers? Absolutely not. It would take more logic, but it certainly can be done. I'm just saying that sometimes there is a reason to do a bitwise elemental scheme. Also, if each element gets a multiplier, the multiiplier either needs to be a float, or expressed in some integral number of a fraction (like eighths). And it would also have to be signed (to account for absorb; i.e. negative damage).

---
A similar argument could be made for statuses, but I can see the flexibility that would be brought by having bytes to express a continuum rather than on/off. You could have Haste and Really Really Hasted with bytes. :) But I can't imagine Toad and Kinda Sort Toad. Some things lend themselves to binary quite well.
------------
EDIT: Another pair of design dilemmas:
1. The order of priority for elemental 'persuasions' (to use my word) is not always the same across games. If a game has a bitwise elemental scheme as above, then there is a priority (I mentioned FF6's system whereby Absorb is first and Weakness is last as an example). If there's a byte-scale to it, then it's conceivable to just add up the multipliers and get an aggregate (if that is desired), but typically the first 'match' wins in FF games so that would be a major change from norm.
2. Multi-elemental attacks: Again, noting the 'first match wins' standard, if a theoretical attack were to be flagged with fire and ice, and it hits a target with fire absorb and ice weakness, what should happen? In FF6, the full spell power would be absorbed by the target, as absorb has priority. It's conceivable to have it grant (2+(-4))/2 = 1/2 spell damage to the target by using multiples of 0.5 for each element involved. How do we handle multi-elementals, that is the question.

Gleeok
01-25-2013, 05:34 AM
Alright then. Gonna just go with how FF would of done them if the old SNES carts had more room : http://www.gamefaqs.com/ps/197343-final-fantasy-viii/faqs/58936
Weakness: < 0%
Resist: > 0%
Absorb: > 100%
Status Imunity: 0 - 100%
That should be able to reproduce any other system without much trouble. It's also conceivable to rewrite the damage formulas and use something other than percentages too I guess...



2. Multi-elemental attacks: Again, noting the 'first match wins' standard, if a theoretical attack were to be flagged with fire and ice, and it hits a target with fire absorb and ice weakness, what should happen? In FF6, the full spell power would be absorbed by the target, as absorb has priority. It's conceivable to have it grant (2+(-4))/2 = 1/2 spell damage to the target by using multiples of 0.5 for each element involved. How do we handle multi-elementals, that is the question.

Yeah that's a good one. .. I don't know. I guess everyone would do it differently, but I might do something like this
-Calculate damage
-for each % of element split the damage into that many parts and modify them based on target defense for that type.
-add them back together again.
.. :shrug:


Also what do you mean all three? ..All of them? :read:

Imzogelmo
01-25-2013, 06:45 AM
Also what do you mean all three? ..All of them? :read:

I mean that the statement in that paragraph applies to all 3 of your bullet points:


(all 3) - I like the dynamic sizes, for reasons I think I've explained already. But basically, I can imagine wanting to exceed some of those limits. Perhaps force bitwise flags if using more than 32 in a given chunk? I could live with that tradeoff. Or perhaps a mix of some bytes and some bits, up to a maximum size (which can be done via script anyway, not a problem). See my reasons below...

(apply this to all 3: equippable-by and jobs flags, Elemental attributes, Status attributes)

The rest up to the ---- before the Edit was exposition.

The Edit is a separate pair of issues I was raising.

Gleeok
04-22-2013, 09:02 PM
Hehe...it's amazing how crazy these things get when you start picking apart every little thing. :googly:

Anyway, at the root of these I've come up with three things that can represent both simple or complex ideas, and would (should) be enough so simulate any jrpg ever made. These are:
*Buffs (essentially all equipment is like a buff. Easy for things like "all element resist +1" or "any/all stats +- some amounts")
*Modifiers (Limited to a single stat, eg; hp + 10%)
*Factors (not limited to anything, really, but require to be defined by scripts. Things like "enemy_atk_x5, exp x2" or "adds random status effect to attacks".)

At any rate we'll have to finish the battle algorithms and logic before adding anything else.

Gleeok
05-22-2013, 09:26 PM
One last thing regarding this:

Currently there are bits for elemental absorb, resist, null, weak. Elements seem to get most of the single bits as FF games handle it this way. When calculating combined flags all equipment etc.. is basically OR'd together - as far as I can figure this is the only way it can be done where you don't lose data.
Also there are values for element def [-128...128), but only flags for elem_atk. This seems like the best to me also.
Status atk, def get similar values since atk with status is not 0 or 1 (only inflict calculation results are), but either need probability or chance.

So, any comments?

[edit] ...I hate the small stuff sometimes... :\