Wednesday, July 15, 2015

More Battle Details (Transitions/Enemy Leveling)

Decided to take a break from fixing up animator controllers and focus on some of the code and thinking behind battle transitions and combat in general. As it stands now, battles are currently initiated by coming into contact with an enemy character. Within actual areas (not the world map), enemies roam around freely, doing whatever it is the hell they do. This principally consists of waiting forever on the player to deliver unto them an ass-kicking.

Any character can have a series of waypoints set up (talked about in a previous post) and enemies additionally contain battle scene transitions, which are just special scene transitions that load the specified battle scene. We had toyed around with the idea of having battles take place in the exact area in which the enemies are encountered, ie, it would not load a specific battle scene.

There were drawbacks with this, mainly in that we would need to tailor our maps very carefully to ensure that areas in which enemies could be encountered were conducive to actual battles. This also posed questions with enemy/ally placement, would you have to physically collide with the enemy or just be within a certain radius for the battle to commence?

Having the battle take place in the same area would simplify a few things, too, however: we wouldn't need to load separate scenes at all. Obviously, a major drawback is that we will need to create battle scenes specifically for each area. This can be simplified, though, by loading a single scene and by creatively altering ally/enemy positioning.

As it stands now, the battle scene contains several entry transitions. We plan on having these chosen randomly--currently, this is a property of the actual battle scene transitions, which again, are contained within each enemy. Additionally, battle scene transitions contain their own screen transitions, which can be customized depending on the encounter (swirl, fadein, blur, et cetera).

Finally, each battle scene transition contains a list of the actual enemies that will actually be fought when the battle scene is loaded. These are literally the prefab names, representing the prefabs that will be loaded when positioning combatants.

When in areas, enemies can be tagged as docile or hostile, which indicates whether a particular enemy will chase the player when the player steps into a given detection radius. Other behaviors are planned as well (for instance, having a tree-like enemy that blends in with a patch of trees and jumps out when within a certain proximity. Or other ambushes (no pun intended)) When the player leaves the enemy's detection radius, the enemy will go back to whatever it was they were doing.

For simplicity, it would be nice to keep the transition loading framework the same, even when we are on the world map. Since enemies will not actually appear on the world map, we have elected to use random encounters when the player is moving around, which is pretty standard, as is our method of initiating these encounters.

We essentially use a threshold distance (say 500 units) and allow the player to move that many units on the world map before a battle can be initiated. After the character has moved this many units, for every additional 10 units, the probability of a battle occurring will increase by a certain percentage (0.25% or so). Pretty straightforward.

I guess this is a good point to stop and talk about a particularly controversial aspect of the game. Full-frontal male nudity. OK, just kidding, that isn't controversial, really.

From a philosophical standpoint, I've always felt that RPGs are a tad on the easy side (for the most part, although there are outliers). Granted, I've been out of the RPG game (redundant acronym) for quite some time, so I cannot attest to the difficulty of contemporary RPGs. Do they even still make them anymore?

There are a shit ton of options for handling difficulty in an RPG, but most challenges can almost always be overcome by grinding. For those unfamiliar, grinding is the act of repeatedly fighting enemies and increasing your level and combat stats until the enemies are vastly underpowered compared to you and your party. Grinding sucks, let's face it. At best, it can be somewhat sugar-coated and daresay I, fun--at worst, it can be the sole reason why a person decides to quit playing a particular game. (Looking at you, FF13. JK, I never even got to the grindy part.)

I was always a fan of Final Fantasy 8 (get dem pitchforks out) and particularly, the fact that enemies leveled with the character. Granted, FF8 is hardly the first or only game to have a system like this, but it stands out in my mind the most. If not for the rest of FF8's broken-ass combat systems, this might have actually helped keep the difficulty consistent.

However, even if enemies do level with the character, the character can almost always outpace them anyhow by accessing new abilities, increasing attributes, et cetera. Enemies do not typically have this level of customization, thus, the player still ends up kicking their asses usually--but they have to grind in order to do so.

For Bevontule, I would like to minimize the amount of grinding a character will have to do. Granted, every single person that makes an RPG says this but I mean it! -spit-

There are two ways in which I am wanting to minimize this: the first is to have enemy levels scale with the character, to a certain extent. For instance, the world map area between Cephaline and Auvane (the first 'playable' area) will have a specific enemy level range of something like 1 - 3. Basically, you cannot encounter any enemies outside this level within this region. (May be caveats to this...)

Additionally, the enemy levels will be determined based on the average level of the party. So you won't randomly encounter a group of Level 3 DeathShitters (this is a real enemy. You should see his concept art.) as your first combat experience. Instead, you'll most likely encounter a group of level 1 infant unicorns beanie babies. Or something.

So, if you're above level 3, what happens? The game crashes. OK, not really. Not in that case. Nothing really changes, except that you will encounter the maximum level enemies there consistently, which in this case, is 3.

Which brings me to the next thing: experience caps. I know, I don't really like this that much either, but I think it will work. Essentially, if you are fighting an enemy that is lower-level than you are, you will receive significantly reduced EXP. I'm thinking 1% or so. This means that if you are a sadist, you can still grind. But the diminishing returns make this pretty unattractive. However, this also means that you can grind to the highest possible (feasible) level in each area without a significant amount of hassle.

I'm not entirely sure how in love I am with this system, but I think we're going to go with it for now. Keeping the difficulty high is one of the foremost goals of this game--I feel like allowing for a small amount of grinding helps the player gain an advantage--but not too large of one.

Anyhow, got a little side-tracked there... back to battle transitions. Our current thinking is to essentially divide the world map into areas using various colliders. Each area will contain either a list of all enemies that can be encountered in that area with a mapping between that enemy and its encounter rate or alternately, it might make more sense to have each area store a list of lists that directly represent the enemies that you can encounter in a battle. This is basically a question of having precomputed permutations versus the game figuring out what enemies to fight dynamically. Probably makes more sense to do it the latter way (saints).

Determining the enemy levels should be straightforward... we would essentially take the average level of the party and try to set the enemy levels to something similar, while respecting the minimum/maximum level of potential enemies in that area. Honestly, this would probably just use the experience of the character directly to allow for fractional levels (not in practice; just in the computation of enemy levels). We could also use a ceil function on this to (perhaps randomly) spike an enemy level. This means that you could encounter enemies that are actually a higher-level than you. It might also make sense to set the minimum level of an enemy encounter in a particular area to the same level as your party.

For instance, let's say you got to level 4 in an area where the enemies are in the range (1-3). Good job. You are now being sued for having unlawfully gained access to our source code, and having implemented features that we ourselves do not yet have. (After you make bail, which we will pay, we're gonna have to get them changes, yaknowaddimean?)

The next area contains enemies that are in the range (3-6). Of course, it doesn't really make much sense to encounter any enemies that are level 3 because, per our shitty rules above, they will give you practically no experience. Maybe we can add something that sets the minimum level in a particular area to the level of your lowest-level party member/average. I don't really know. For that matter, the 'range' could actually just be a single number which indicates the 'spread' of the enemy levels, rather than a min/max. I'm actually not sure... hadn't really thought much about this particular case.


OK, that's enough for now. Maybe next time we'll talk about the skill system....

No comments: