Jump to content


Photo

Designing RPG formulas (stat growth, damage, etc)


  • This topic is locked This topic is locked
25 replies to this topic

#1 Yal

Yal

    Gun Princess

  • Global Moderators
  • 8548 posts
  • Version:GM:Studio

Posted 10 October 2011 - 02:17 PM

I'm currently in the making of an RPG, being fuelled by a recent addiction to Disgaea DS and having a puppy-eyed apprentice that wants a general-purpose RPG engine to work with. Now, I suddenly faced an unforseen obstacle: how to design formulas so that they stay balanced.


The general RPG formula take into account multiple things; the most simple form is basically output = constant_factor*(my_stat - your_stat), but it is exactly that: simple. Simple of course doesn't have to be bad, but it has flaws. For instance, say that this RPG uses that as the damage formula (with some fixes to not let the damage go negative). Then the damage will grow linearly with the player-character's (or enemy-character's) level. This is not necessarily a bad thing, but it doesn't make up for interesting gameplay where levelling really matters; when you were at Lv 2 and went to Lv 3, your attacks would get say 50% stronger and do a lot to make battles shorter - when you are at Lv 50 and get to Lv 51, the attack only does 0.5% more damage to the enemy. Which is quite measly and doesn't affect anything, so grinding won't let you get past that one boss easier.


This could obviously get bypassed by, say, making the player's ATK increase with an exponential part, so that levelling from Lv 2 to Lv 3 could give you say 2 more ATK points, but levelling from Lv 50 to Lv 51 maybe gives you 32 more ATK. The bad thing with this approach is that unless careful balancing is taken into consideration, one level more or less of grinding could make a difference in game difficulty that is far too high, turning an unsurmountable challenge into a pushover. This could be resolved by factoring more things into the formula, such as elemental resistance and special weaknesses, a character's skill with certain items, and so on, making strategy deal extra damage comparable with the raw power granted from grinding; however it just seems to make the formula more complex and thus easier to accidentally break.


How should one thing to design formulas like this to make them fair? Is it better to keep them simple and linear or should one try to design intricate structures from the start? When designing what factors should be more important (and never get tweaks), which ones should one give more priority? What formulas should use linear relations and what ones are better with polynomial or exponential relations? Is there other models that are more suitable in general?
  • 0

#2 xshortguy

xshortguy

    GMC Member

  • Global Moderators
  • 4345 posts
  • Version:GM:Studio

Posted 10 October 2011 - 02:48 PM

My advice: stick to predictable functions. For example, one can easily pick a function that goes from 0 to 1 to be a shape function. Here's an example:

f(x) = x^2

This function lies inside of the box [0,1]x[0,1], with a particular shape.

For the domain, we want numbers to be from Level_Min to Level_Max (say 1 to 99), so we can force this to conform to [0, 1] by using:

x = (Level - Level_Min) / Level_Max

Then we can plug this into our shape function to get [(Level - Level_Min) / Level_Max]^2.

We can then have Stat_Min and Stat_Max:

Stat = Stat_Min + (Stat_Max - Stat_Min) * [(Level - Level_Min) / Level_Max]^2.

Also, see this post here:

http://gmc.yoyogames...dpost&p=3713975
  • 1

#3 Yal

Yal

    Gun Princess

  • Global Moderators
  • 8548 posts
  • Version:GM:Studio

Posted 11 October 2011 - 10:56 AM

Those were quite helpful! I felt a bit like treated as I'd asked a simple question (and perhaps I did :P), but that doesn't make the advice less useful.

Assume that I want to make a game with an absurdly high level cap (like Disgaea's infamous 9 999), then. Or to be more precise, a pretty complex RPG where you really can't max out a stat (as opposed to the likes of Paper Mario).

Generally, the two important things about my special problem are:

- There is no real set max value for any given stat, and reaching the practical max value should not be done just by reaching the maximal level. That is, players can influence the growth of characters by tweaking certain stats, meaning that the same character can either get, say, a strong swordsman or a strong mage, and depending on how (s)he gets raised during the game, might end up with different maximal stats.
- Character growth is influenced by a set of secondary stats, each one affecting one of the primary stats. For instance the stat Vigor increases Atk, Acuity increases Hit, and Dexterity increases Agility. And so on. Raising these secondary stats will lead to extra points in affected primary stats upon leveling.

To implement these two things (stat growth is based on secondary stats; players shouldn't reach maximal values automatically just by levelling mindlessly), should a lot of reconsideration be done?

In general, I don't want to just have some sample functions thrown at me, I'd like to hear how to think when designing the formulas. I'll take the advice of using a pattern function, scale down its arguments to go into the range [0 1], and then scale up the output again... but is it the only way these things can be tackled? In particular, when the max level is so high that you aren't expected to reach it just by clearing the entire story, setting a maximal cap on stats seems a bit limiting.
  • 0

#4 xshortguy

xshortguy

    GMC Member

  • Global Moderators
  • 4345 posts
  • Version:GM:Studio

Posted 11 October 2011 - 02:13 PM

The general idea is the same: design functions that you can keep under your control. The ideal way is to chop your final function into smaller, manageable pieces and then design both of those separately. Set goals for various points, such as how strong you want your characters to be in chapter 5, or how strong do you want them to be when fighting the first post-game optional boss, etc. and try to get your component functions to agree with these goals. When you allow stats to be unbounded, then it can be very difficult to maintain a sense of balance. (Games like Disgaea are devoid of this balance; how often did you almost beat Baal? In my experience either you clobber him or he clobbers you.)

Don't be afraid to "glue" functions together either. Typically such functions are called piecewise functions, and they can be useful as well. This can be very useful when trying to reach discrete goals. Although some people don't like this approach since the end result doesn't always feel natural.

The bulk of the statistics in the Disgaea series, for example, are dependent only on a few factors. The stats that a character will end up having is largely determined by only two factors: their base stats and their aptitudes.

You can have different schemes as well for statistic development. For example:

Level 1: Character has X stats.
Level 100: Character has X * Aptitude Stats
Level 200: Character has X * Aptitude^2 Stats
...
Level 9900: Character has X * Aptitude^99 Stats.

The premise is that for every 100 levels, the stats of a character multiplies by the aptitude factor. For example, if the player has a base attack of 14, and an attack aptitude factor of 1.10, then at level 100, the attack will only be 15.4, and so on:

1: 14
100: 15.4
1000: 36.3
5000: 1,643.5
9800: 159,445.1
9900: 175,389.6 [notice the difference in just one-hundred levels is astronomical compared to the first 100 levels].

Typically multiplicative stats can 'go out of control' because the amount of a statistic gains towards the highest level is very large compared to smaller levels, and this is further amplified if you add flat bonuses on each level as well. (See annuity mathematics that finance people deal with; those are the same types of formulas used for such models.) In particular, with the large bonuses towards the end, it may prove difficult for a player whose only a few levels under a given enemy to defeat them, since the disparity in attack values is so large. Be aware of how your stats behave in every section that your parameters are allowed to go.

Also, note that even if I provide an example, its intent is not to provide you with formulas, but rather to illustrate how to construct various formulas. (The techniques of the construction are meant to be emphasized.)
  • 1

#5 Yal

Yal

    Gun Princess

  • Global Moderators
  • 8548 posts
  • Version:GM:Studio

Posted 12 October 2011 - 08:20 AM

In particular, with the large bonuses towards the end, it may prove difficult for a player whose only a few levels under a given enemy to defeat them, since the disparity in attack values is so large.

That.
Never thought about it that way.

From a game design standpoint, there's a delicate balance here. Using exponential stat growth makes every single level matter maybe a little bit too much, while still one want the player to feel rewarded for spending all that time growing a character one more level. Maybe I should focus on some way to balance those two aspects.

The first thing I come up with is "Why do levels have to need an exponentially growing XP requirement?". "Every game" does that, and the games that feel rewarding also make your stats grow according to the time getting a new level takes so that the levels matter, but that doesn't mean that it's a natural law.
If, say, you would level up every 100 XP, and each level-up would give basically the same stat increase,

stat = base_value + growth*level

and we say that the player starts with 10 stat and a growth of 1.1, it would net a scheme like

Lv1: 10
Lv30: 43
Lv100: 110
Lv200: 230
Lv1000: 1 110
Lv9800: 10 780
Lv9900: 10 890

The figures are more balanced here, and they might give off the impression that a level isn't worth that much time, but assuming that (roughly) the same amount of experience is needed for every new level and that XP awarded increases with enemy strength, it would mean that eventually you could gain multiple levels from slaying a single enemy. In practice, at higher levels you would gain a fraction of a "normal level", but add that to your stats instantly.

From a design standpoint, getting rewards more and more often make the player find them less rewarding, so it's not an ideal solution without some more elbow grease (such as obscuring the "flat levels" as a fraction of a "normal level", and require certain methods to add them to your current level, that are feasible to do e.g. when you have trouble defeating that one boss, but still so tedious that the player will not do it constantly all the time.)
  • 0

#6 xshortguy

xshortguy

    GMC Member

  • Global Moderators
  • 4345 posts
  • Version:GM:Studio

Posted 12 October 2011 - 09:23 AM

The first thing I come up with is "Why do levels have to need an exponentially growing XP requirement?". "Every game" does that, and the games that feel rewarding also make your stats grow according to the time getting a new level takes so that the levels matter, but that doesn't mean that it's a natural law.


Typically this is done to help stop or limit the ability to grind; I personally hate games where I unintentionally over-grind my characters because I'm just trying to get enough gold for the next item, resulting in the next portion of the game being too easy. Having an such a system won't blatantly stop grinding, however, so those who still want to do it can. Contrast this to a system where players gain less experience per monster if their levels are higher. This has the same effect as an exponential system (up to certain parameters), but eventually it becomes literally impossible to grind at all, since the enemies end up giving zero experience.

Many games don't result in exponential curves though, they will most likely use a parabolic growth. [Disgaea uses a parabolic growth system for their experience.] Parabolic growths are much more stable than exponential growth, since there is an easy 'proportion': every time you double your level, the experience required for the next level is multiplied by four. To see this, simply realize that (2 L)^2 = 4 L^2.

You're best off picking some fixed power for your various growth curves, whether it be linear, etc.
  • 0

#7 Yal

Yal

    Gun Princess

  • Global Moderators
  • 8548 posts
  • Version:GM:Studio

Posted 12 October 2011 - 11:25 AM

[Disgaea uses a parabolic growth system for their experience.]

May I just ask you, where did you find that out? I've searched all in-depth FAQs for all four games at gamefaqs for formulas without finding any for the base stats.

Typically this is done to help stop or limit the ability to grind; I personally hate games where I unintentionally over-grind my characters because I'm just trying to get enough gold for the next item, resulting in the next portion of the game being too easy.

That's mainly a case of bad game design... and in an area where it's hard to do the right thing. If it's too easy to get money in a game, it's possible to buy all the stuff you need and then go through the next portion of the game with extra stat bonuses and make the area easy because of that. The developers then tries to solve that by making money harder to come by, or by making the items more expensive... which only means that players that want them have to waste more time to get them. (I personally find Disgaea's method where items start out pretty awful and has to be improved by the player's actions to have potential here; even though in these games the only way to improve your items is... to grind inside them). It would be a better game design to lock the player out of overbuying in some other way than to hope that they will buy things to suit their wallet and then go on without the things they couldn't afford... but there's no The Only Answers here.

Having an such a system won't blatantly stop grinding, however, so those who still want to do it can. Contrast this to a system where players gain less experience per monster if their levels are higher. This has the same effect as an exponential system (up to certain parameters), but eventually it becomes literally impossible to grind at all, since the enemies end up giving zero experience.

I personally find such systems to be more annoying, since in most games I've played (especially in Castlevania: Harmony Of Dissonance), enemies do stay quite challenging a pretty long time after they've dropped down to single digits of XP worth. Beating something that takes nearly a minute to kill and poses a threat to you meanwhile and finally find out that it gives you as much XP as a bat from the first dungeon would; it makes you hold personal grudges against the developers after a while. Again, it's an example of bad game design that does not prove the technique bad in general... but I'm yet to see it executed seamlessly.

Many games don't result in exponential curves though, they will most likely use a parabolic growth. [Disgaea uses a parabolic growth system for their experience.] Parabolic growths are much more stable than exponential growth, since there is an easy 'proportion': every time you double your level, the experience required for the next level is multiplied by four. To see this, simply realize that (2 L)^2 = 4 L^2.

You're best off picking some fixed power for your various growth curves, whether it be linear, etc.

Understood. Always aim for predictable functions (polynomials) on predictable intervals, then scale them up to suit the desired interval.



If I've read you correctly, the advice you've given me can be condensed into this algorithm:

1: Decide how you want the output to behave (I realize that I've not cared about this step before!)
2: Make a simple [0 1]-interval function with desired shape (or multiple ones when the stat should behave differently on different intervals)
3: Add factors so that the input argument will be transformed to a value in the range(s) of the function(s)
4: Test-run the formula by feeding it some default values and some extremes and see if you accept the produced output

Thank you, sir! I will remember it.
  • 0

#8 xshortguy

xshortguy

    GMC Member

  • Global Moderators
  • 4345 posts
  • Version:GM:Studio

Posted 12 October 2011 - 12:12 PM

May I just ask you, where did you find that out? I've searched all in-depth FAQs for all four games at gamefaqs for formulas without finding any for the base stats.


Look in one of the FAQs by JungleJim [I believe its the Item World FAQ.]

EDIT: There's one more thing worth mentioning, and that's to "throw out" the beginnings of some functions. For example, one may find that the small values of the parabola grow "too slowly", so instead one might do this:

(30 + Level - Level_Min) / (30 + Level_Max); doing this will help move some of the early slowness out of the equation. (Instead of starting at say 1/99 = 0.01, you'll start at 31/129 = 0.24.)
  • 0

#9 Sinaz

Sinaz

    MCP Killer

  • GMC Elder
  • 2751 posts
  • Version:GM8

Posted 17 October 2011 - 05:53 PM

I'd like to flip this conversation a little.

I'm working on a game right now in which stats determine the functionality of starships. Primarily, they are crew stats, and they effect how much potential you can get from your current ship.

Effects that might be commonly dictated by stats might be something like, how accurately the ship turns toward a desired heading, or how much of the maximum turn rate the pilot can muster from the controls, or how quickly weapons will lock onto a target.

I experimented with a few formulas concerning the "turn the ship" problem.

At the moment, I settled on something where a skill formula like xshortguy suggests. When the ship is turning, it applies an angular impulse value of

( 0.5 + skill ) * impulse

So that a good pilot can turn a ship up to 50% harder than intended.

When it comes to steering to a heading, I took the target heading and gave it a margin of error of:

maximumerror * random( 1 - skill ) * choose( 1, -1 )

So that as the skill increases, the possible error decreases towards zero.

Often, I will be dealing with the accuracy with which the player's avatar can accomplish things, or the swiftness.

Can you think of any existing systems that I could research to help me formulate better strategies, or am I kinda on the right track?

Edited by Sinaz, 17 October 2011 - 11:04 PM.
realized a typo in one of my formulae

  • 0

#10 mechlore

mechlore

    GMC Member

  • New Member
  • 52 posts

Posted 17 October 2011 - 10:36 PM

I think, unless you're making 1: A huge game, or 2: A multiplayer game - there is really no reason to use formulas that are too complicated.

I would go so far as to say you would be remiss in trying to design your damage formula to be too complicated too early. I think you'll find that as your game progresses and certain features "compress" a lot of the things you were accounting for in your original damage formula arnt really necessary anymore. If its super complex - it will be that much more painful to alter later on.


Mine basically goes like this

if crit=0{
physicaldamage=flatweapondamage*modifiersfromstatsanditems*weapon_coeffients* -- then a bit at the end that I cant think of off the top of my head that reduces damage based on resistance.
^ ^ with each type of damage ^ ^


finaldamage=all_damages_added
}

if crit=1{
finaldamage+=finaldamage // this is if you want any type of damage to crit, which it does in my game.
}

VARIABLE.life-=finaldamage



Generally speaking, its incredibly simple.


This is sudo code obviously, its altered quite a bit to take into account min_damage and max_damage respectively.
  • 0

#11 Yal

Yal

    Gun Princess

  • Global Moderators
  • 8548 posts
  • Version:GM:Studio

Posted 18 October 2011 - 10:53 AM

Mech, my current formula is damage = pow*((attack + boosts)/(100 + defence + boosts)) (and a similar one for elemental damage, pow is attack power in percents). The main difference from your formula is that I name my variables meaningful things and actually take into account defensive values. I take you don't do that in the right way with a line of multiplications, since for instance it would be possible to get all damage to heal if you equip enough items to get any of those values negative. That's a bit bad.

As well, rather than to have one formula for each attack type, you could use one formula and pass attack_stat, defense_stat, attribute and pow/guts/critical values to that. And then check if the target has resistance to the attribute(s) and then decrease the value with that (e.g. use damage = damage/(max(1,100 + resistance)), where a negative resistance means you're suspectible to damage, e.g. -50% resistance to fire gives you double damage. This formula was used in Disgaea.).


EDIT: There's one more thing worth mentioning, and that's to "throw out" the beginnings of some functions. For example, one may find that the small values of the parabola grow "too slowly", so instead one might do this:

Noted. I happen to like the system of stats being a function of base stats and level more and more the more I think about it now. It would suit one of my projects perfectly, since it's about converting fallen enemies. I should rip off all formulas straight from Disgaea 1 and call it a day. ;)


I experimented with a few formulas concerning the "turn the ship" problem.

Hmm... as a player, I would find a skill in the range of 0 to 0.5 to sound pretty un-delicious to look at. You should consider displaying all bounded skills as a mastery percentage (0 - 100%) and all unbounded skills as big numbers, no matter what actual values are used for calculations. (You could even have all skills unbounded on the Stats screen but have a cap for values used for computations, so even if you have a driving skill of 653% you can't get more driving bonuses than a 100% keep course, 200% turning speed ability).


By the way, have you taken into consideration how status problems will affect the stats? Such that damaged or poisoned crew members would steer worse, or if your ship rudder is hurt you get a negative turning bonus.


Oh, finally: you might have noticed that all your example functions are linear. Do you want the skill to increase linearly, or faster when you get near perfection (like a x² curve), or faster in the beginning (a sqrt(x) curve)? You could even let the type of curve depend on the type of character you use; so that a pilot character has an y = sqrt(x) parabolic curve for steering mastery, a y = x curve for controlling a turret, and a y = x² curve for repairing machinery. A mechanic would have those values reversed, and a gunner yet another configuration. This could give you another dimension of tactics: to pick the right crew for the right positions on your ship. Should everyone be able to do everything in an OK way, or do you dare to have a crew of irreplaceable masters only?

Edited by Yal, 18 October 2011 - 11:03 AM.

  • 0

#12 Sinaz

Sinaz

    MCP Killer

  • GMC Elder
  • 2751 posts
  • Version:GM8

Posted 18 October 2011 - 05:28 PM

I experimented with a few formulas concerning the "turn the ship" problem.

Hmm... as a player, I would find a skill in the range of 0 to 0.5 to sound pretty un-delicious to look at. You should consider displaying all bounded skills as a mastery percentage (0 - 100%) and all unbounded skills as big numbers, no matter what actual values are used for calculations. (You could even have all skills unbounded on the Stats screen but have a cap for values used for computations, so even if you have a driving skill of 653% you can't get more driving bonuses than a 100% keep course, 200% turning speed ability).


Ah, no- the stats, under the hood, are mostly just 0-1 modifiers of total potential (though total potential exceeds the mechanical limits of the ship stats, which are just straight unit measurements.) There is no exposed numeric skill for the player... your crew members becomes seasoned and things just get better for you.

By the way, have you taken into consideration how status problems will affect the stats? Such that damaged or poisoned crew members would steer worse, or if your ship rudder is hurt you get a negative turning bonus.


Oh yeah... all of that is accounted for. This is a pretty deep project-- I have a growing design doc in the form of a private wiki. The depth of the game is pretty cool, as designed. There's even a caveat in which calling for a ship-wide "brace for impact" will save lives. The ships are a whole nother conversation in themselves. I didn't want to get to much into these details, as I'm mostly concerned with the statistical influence of the skills and mechanics in this conversation.

Oh, finally: you might have noticed that all your example functions are linear. Do you want the skill to increase linearly, or faster when you get near perfection (like a x curve), or faster in the beginning (a sqrt(x) curve)? You could even let the type of curve depend on the type of character you use; so that a pilot character has an y = sqrt(x) parabolic curve for steering mastery, a y = x curve for controlling a turret, and a y = x curve for repairing machinery. A mechanic would have those values reversed, and a gunner yet another configuration. This could give you another dimension of tactics: to pick the right crew for the right positions on your ship. Should everyone be able to do everything in an OK way, or do you dare to have a crew of irreplaceable masters only?


The effects functions are linear, but the skill level functions are curved-- in fact, right now, I'm just using xshortguy's suggested functions for skill levels.

The idea is that your crew members are specialized, each 'Station' has permanent crew member who levels up based on experience-- eventually it will be purely granular, no level steps-- just a constantly growing proficiency score. Crew members can be injured or killed at which point they get replaced by another crew member (anonymously promoted from the crew pool.) The new crew member manning the station starts at the global crew experience, which progresses slower than any individual specialized Station.

At the moment, using the functions I mentioned previously, the difference between minimum skill and maximum skill is pretty significant. It's interesting to see the error when setting a heading. In my sandbox level, the background is a gamey grid so I can better detect motion. But with an irregular stellar landscape in the background, it's difficult to notice the error-- it feels very organic, and I like that-- organic is good.

The grid also allows me to measure the turning radius visually.

Playing with it, it feels good, I just wish there were some element of predictable randomness in the straightforward application of skill-- like in the acceleration impulse... I'm thinking that combining some random functions so that the distribution is in a bell curve will give me that fluctuation of expected skill level in the middle of the graph, but occasionally get really good or really bad results. Criticals, as it were.

Would simply combining three or four random() calls suffice, or is there a better way to do this in code (since I'm not actually physically rolling dice?)
  • 0

#13 xshortguy

xshortguy

    GMC Member

  • Global Moderators
  • 4345 posts
  • Version:GM:Studio

Posted 20 October 2011 - 09:48 PM

Would simply combining three or four random() calls suffice, or is there a better way to do this in code (since I'm not actually physically rolling dice?)


Three or four random numbers added up is not sufficient to create a bell curve; most statisticians would recommend that you use at least a minimum of 30.

However, you're better off using the gauss script at gmlscripts.com to use the gaussian distribution itself.
  • 0

#14 Melle1

Melle1

    GMC Member

  • GMC Member
  • 224 posts
  • Version:GM8

Posted 25 October 2011 - 06:02 PM

Hi Yal,

Um I have OPen Source Code on a small rpg Unfinished piece of Dukey... well its not that bad, its only a battle room, i stopped this project because I did not know how to level up my character. or award gold at the end of a battle.
  • 0

#15 Sinaz

Sinaz

    MCP Killer

  • GMC Elder
  • 2751 posts
  • Version:GM8

Posted 25 October 2011 - 06:09 PM

Would simply combining three or four random() calls suffice, or is there a better way to do this in code (since I'm not actually physically rolling dice?)


Three or four random numbers added up is not sufficient to create a bell curve; most statisticians would recommend that you use at least a minimum of 30.

However, you're better off using the gauss script at gmlscripts.com to use the gaussian distribution itself.

I had a conversation with our lead core engineer at work-- and he had a decent insight-- he said, "why bother computing it at runtime-- just make a look up table with whatever values you want. If you want to pre-compute them with a curve, that's cool-- then you can go in and manually tweak."

A couple other bits of advice he had was to build your own look up tables that have built in bias and curve for randomizers, as well.

Had a good suggestion about having different "aptitude" curves so that some characters would be able to level up differently and better than others at specific skills and such.

Now, granted-- he was giving this advice in the context of the project I'm working on... and you may not want such delicately customized curves for characters in a straight RPG where you expect PCs and NPCs to be on some sort of equal ground.

But, yeah-- look up tables. I'm all about look up tables.
  • 0

#16 xshortguy

xshortguy

    GMC Member

  • Global Moderators
  • 4345 posts
  • Version:GM:Studio

Posted 25 October 2011 - 06:23 PM

Most uses of the normal (gauss) distribution are typically done with tables, since the probabilities don't have an explicit formula [and have to be computed iteratively]. This is typically how introductory statistics students are introduced to the normal distribution. From these table values, one then uses a linear interpolation between the points when necessary. This is slightly more involved than reading numbers off of tables, but is still quicker than computing the exact numbers, and often doesn't suffer a huge accuracy loss if done right.

The question then becomes: how should we design the table [for this or for any complicated formula] to provide good enough values. Depending on how "nice" the function is, this isn't easily answered.
  • 0

#17 Sinaz

Sinaz

    MCP Killer

  • GMC Elder
  • 2751 posts
  • Version:GM8

Posted 25 October 2011 - 06:31 PM

Most uses of the normal (gauss) distribution are typically done with tables, since the probabilities don't have an explicit formula [and have to be computed iteratively]. This is typically how introductory statistics students are introduced to the normal distribution. From these table values, one then uses a linear interpolation between the points when necessary. This is slightly more involved than reading numbers off of tables, but is still quicker than computing the exact numbers, and often doesn't suffer a huge accuracy loss if done right.

The question then becomes: how should we design the table [for this or for any complicated formula] to provide good enough values. Depending on how "nice" the function is, this isn't easily answered.

Well, I've never studied statistics-- so I'm at a loss. Though, I don't see why you'd need to interpolate-- I mean... if the player can't detect the loss of accuracy-- if he can't see the numbers being generated and it doesn't feel broken-- then, why bother-- go simple. Just read from the tables.
  • 0

#18 xshortguy

xshortguy

    GMC Member

  • Global Moderators
  • 4345 posts
  • Version:GM:Studio

Posted 25 October 2011 - 06:32 PM

Well, I've never studied statistics-- so I'm at a loss. Though, I don't see why you'd need to interpolate-- I mean... if the player can't detect the loss of accuracy-- if he can't see the numbers being generated and it doesn't feel broken-- then, why bother-- go simple. Just read from the tables.


Sometimes it can be noticeable if you don't interpolate the values, or if you don't have enough table values to have a meaningful representation of the intermediate values.
  • 0

#19 Sinaz

Sinaz

    MCP Killer

  • GMC Elder
  • 2751 posts
  • Version:GM8

Posted 25 October 2011 - 06:36 PM

Sometimes it can be noticeable if you don't interpolate the values, or if you don't have enough table values to have a meaningful representation of the intermediate values.

How much performance will you lose by simply having a table with more entries-- that'd be a finer sample rate, right? I mean-- generate a random look up on a table of 100 entries versus a table of 1000 entries... that's just memory right-- it's still just a simple random look with a bigger range.

I was implying that you would have to have a table of enough values so as to not appear broken to the player.
  • 0

#20 xshortguy

xshortguy

    GMC Member

  • Global Moderators
  • 4345 posts
  • Version:GM:Studio

Posted 25 October 2011 - 06:40 PM

How much performance will you lose by simply having a table with more entries-- that'd be a finer sample rate, right? I mean-- generate a random look up on a table of 100 entries versus a table of 1000 entries... that's just memory right-- it's still just a simple random look with a bigger range.

I was implying that you would have to have a table of enough values so as to not appear broken to the player.


You would gain more performance from having more performance by using larger tables at the cost of using more memory. However memory is easier to come by, so having large tables is ideal. [In fact, you really can't get much faster than reading a number off of a table.]

For a function like the gaussian, however, it might not be obvious to non-mathematicians on how to compute more table values, or if you have some sort of mystery function and only have certain table values, then you're next best choice is interpolation. You certainly don't have to interpolate.
  • 0

#21 Sinaz

Sinaz

    MCP Killer

  • GMC Elder
  • 2751 posts
  • Version:GM8

Posted 25 October 2011 - 06:53 PM

So can you describe an algorithm to populate a look up table with a Gaussian distribution-- in a hypothetical designed however best would illustrate the process? I thirst for knowledge!
  • 0

#22 xshortguy

xshortguy

    GMC Member

  • Global Moderators
  • 4345 posts
  • Version:GM:Studio

Posted 26 October 2011 - 01:30 AM

You can simply use the function for the gauss script:



If you wanted to compute the cumulative Gaussian function, you can use the definition of the integral:
Spoiler

  • 0

#23 Yal

Yal

    Gun Princess

  • Global Moderators
  • 8548 posts
  • Version:GM:Studio

Posted 28 October 2011 - 02:40 PM

If you have access to something like MATLAB, you could also compute a bunch of (x,y) pairs for the function, then least-square-adapt some cheaper function (e.g. a Ax^2 + Bx + C polynomial or a half-period sine wave segment) that runs trough these pairs. That could be used for other functions that won't benefit that much from a look-up table (e.g. lots of interpolation between table values would happen since the input is full of "fractional-part bias") and that still has to be called a lot.

If you're interested, I could give you some MATLAB code we've used for school assignments for doing just that.
  • 0

#24 TheouAegis

TheouAegis

    GMC Member

  • GMC Member
  • 10102 posts
  • Version:GM8

Posted 11 November 2011 - 02:52 AM

If you ever decide all this is too much to work out, you can always try the Shining Force method. Shining Force went with what was asked about earlier, where every 100 XP levels you up. The system had its pros and cons, based on how it was designed (some of the flaws remained throughout the entire series). The experience you gained from killing enemies was based on the level difference. It was a pretty predictable pattern too. Missing gained you 1 XP. Hitting gained you some amount based on something like 25*(1-(enemy_level-my_level)/enemy_level). Killing an enemy doubled that. AOE spells could potentially level a mage up very quickly, since the exp was additive. You also gained experience somewhat randomly (but with specific seeds) for casting spells and the effectiveness of the spell. For example, healing an ally for 8 HP granted you 1 to 5 XP, let's say, but healing an ally for 15 HP (the cap for Heal 1) granted you 10 XP, and fully healing an ally for 14 or 15 HP granted you 15 XP. This had a serious flaw that could easily be exploited in Shining Force II whereby a healer with the Boost spell could cast Boost on the party for up to 50 XP per cast since it's an AOE at level 2 or 3 (I forgot). One of the heroes in SF2 had the spell Aura, which was horribly bugged, since casting it at level 3 could grant 50 XP easily. Spamming these two skills resulted in an instant level up. Then you recall out of the battle and then go back and do it over again. With patience, you could easily get your monk up to level 99 and solo the final boss.

Anyway, the game mechanics were balanced out in some way by assigning each hero (there were many) set stats for level 99 (kinda like Pokemon) and then various stats would be raised as the hero gained levels. There could be 15 or 16 heroes in a battle all vying for XP from a limited number of enemies. This in turn helped keep levels low (the final boss fight would probably be at level 36 or so on average, I think). Considering only healers could easily reach level 99, it wasn't worthwhile to have one hero try to kill off all the enemies, since that would make each hero weaker. For a real challenge, you can try beating the game without recalling from any battles.

I personally like those mechanics better than what most RPGs do these days.
  • 0

#25 Melle1

Melle1

    GMC Member

  • GMC Member
  • 224 posts
  • Version:GM8

Posted 12 November 2011 - 04:38 AM

Sorry, I neglected to post the actual open source file, here is the link.

Download Here

The file has a working battle room, a Base HP for ally and enemy. An increase from spamming a move. But I do not know how to KO myself or OPPONENT, for gold or dropped items. Feel free to rip the formulas from the code. To actually fight, there will be a one digit number above Your HP, 0 is Neutral Attack, and 1 is Fire Buster.

I'm sure there might be a glitch or two, but here's something you can use.

HERE's my input for the topic related issues. I assume you are looking for an example curve to distribute exp and level caps. But if I were you i'd just use a MAX EXP amount, based on the Max level.
  • 0

#26 Yal

Yal

    Gun Princess

  • Global Moderators
  • 8548 posts
  • Version:GM:Studio

Posted 15 November 2011 - 11:01 AM

...But I do not know how to KO myself or OPPONENT, for gold or dropped items. Feel free to rip the formulas from the code...

...I assume you are looking for an example curve to distribute exp and level caps...

I assume you made that assumption without reading my post, or at least without understanding it.


You also gained experience somewhat randomly (but with specific seeds) for casting spells and the effectiveness of the spell. For example, healing an ally for 8 HP granted you 1 to 5 XP, let's say, but healing an ally for 15 HP (the cap for Heal 1) granted you 10 XP, and fully healing an ally for 14 or 15 HP granted you 15 XP.

That's an interesting game design issue: you get XP for killing enemies, but there's a limited supply of enemies that will eventually run out. You also get XP for healing your allies, and they will never run out, so the only character that can get an infinite amount of XP is the healer.

The obvious way to limit that, of course, would be to limit the MP the healer has; for instance, making MP impossible to recover - the starting MP the healer gets is all MP he'll get for the duration of the entire game. But I guess most player wouldn't like that approach...
  • 0




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users