# Algorithm for game difficulty/pacing curve generation in single player RPG

I'm looking at this article about pacing in entertainment and games. It suggests that all good entertainment roughly follows a pacing/engagement curve like Star Wars(below).

I'm interested in how I can procedurally generate random-looking curve that would conform to the Star Wars engagement intensity pattern (linear increase and oscillating peaks-valleys). The simplest implementation I can think of is a rectified sine wave and a sloped line, but that would be very predictable. I have an algorithm for perlin noise already in the game and am interested if I can leverage perlin noise algorithm to procedurally generate a varying sequence of peaks and valleys on an increasing slope.

Here's my attempt so far:

Once I have an algorithm, I can reference it to get engagement difficulty in relation to game turn or progress through some level.

I will add my thoughts to this question in hopes that someone can correct or point out flaws in my approach below:

• I get the basic XP system in place (previous level *1000 to advance to next level)
• Decide on the level cap (lets say 20 levels)
• Plot available equipment tiers vs 20 levels (regular at lvl 1, magical at lvl 10, epic at lvl 20)
• Using the peak-valley graph decide how many fights are in each peak-valley cycle (5 to reach lvl 2, 12 to reach lvl 20).
• estimate number of turns per fight, let's say 5 turns per fight
• calculate xp needed and turns needed to reach to each new level
• Plot turn number and hypothetical xp the party has at each level.

Now for each peak I have a number of turns and the amount of XP that the curve should have between two valleys.

Using whatever formula the curve follows at that peak (let's assume a bell curve), I can get the xp value of monsters I have to spawn during that turn. These monsters have their equipment adjusted according to the equipment vs tier/turn number that was calculated above.

Now I need to adjust monster XP and test it at different levels. A simple sanity check: a party of 6 players must kill:

• 750 xp of monsters in first fight in 5 turns, that is 30 actions.
• 1500 in second fight
• 1800 in third fight
• 1350 in fourth
• 555 in fifth

• What have you tried already? It sounds like you have a plan, but you haven't explained why that plan won't work. You only have an implied question here (in bold) and the answer is, yes, you can do that. Dec 26, 2013 at 18:46
• I've updated the question. Pretty much I have an algorithm that generates terrain height. I'm interested if I can use it to generate difficulty curve too. Dec 26, 2013 at 19:13
• I haven't tried anything, but maybe integrating a perlin noise + a small constant could do. Dec 26, 2013 at 21:01
• Hey Alex, the answers area is for answers, please post updates to the question as edits to the question. Do feel free to post an answer if you've answered the question, but you should attempt to make it into an answer instead of "this is what I've tried an it's not working". Thanks. Dec 26, 2013 at 22:21
• Are you really sure that you want to leave your gameplay balance and feel up to some random numbers that you can't easily control? I think that since you know the system from the inside you're seriously over-estimating how "predictable" a player will find any hard wired variations versus one with this randomness thrown in. My instinct is that you're over-engineering this solution to try and solve a problem that doesn't exist. Dec 27, 2013 at 0:29

Yes, you can leverage the noise algorithm. Use your attempt so far as a baseline. Then, using a single dimension perlin noise function, use the x axis as an input to add noise to your baseline function. You can either do this at every point along the axis, or you can do it just for the peaks and valleys and interpolate the values between.

This will be pretty unrelated to your terrain height algorithm. The only similarities being that you're using perlin noise for both.

Another algorithm available to you is midpoint displacement:

You will have to modify the algorithm a bit, since it doesn't usually expect baseline values other than zeros. Once modified, use your sloped sine wave as an input.

This is sounding a bit like Valve's "Game Director" in the Left For Dead series.

The idea is that there's an AI "watching" the player to make sure they're having fun. When things are tough it generates fewer and weaker enemies. When you seem to be picking the zombies apart effortlessly, it creates more and harder zombies.

Not only that, it also tries to create suspense by leaving periods of dead time where there are no enemies, then unleashing zombie hell on the player.

Personally, I found it pretty effective. I liked the pacing in those games.

I'm wondering what sort of RPG you're coding. Is this the retro style RPG where monsters attack you randomly as you wander the map/ (like the old final fantasy games?) Or is it more action / adventure like Diablo?

I think either way, you could probably create the same effect. Instead of a continuous stream of enemies, which is psychologically taxing, create some dead time in between your battles so that the player has time to adjust inventory, heal, etc.

Rather than planning all this out in advance, why not just do it on the fly? come up with some algorithm that tells your "game director" how much trouble the player is having at any set time in the game, (You can look at things like player level, hitpoints, recent potions used, etc.) then use that information to adjust the difficulty of the enemies.

Leave some room in the director for a few pushover battles, and some fairly epic fights, regardless of how hard the player's doing, but set it up to where the player should have a reasonable expectation of winning, at least most of the time. (But not all the time... See Dwarf Fortress's motto: Losing is fun)

• Another thing occurs to me... I don't think it's an either / or proposition... You could easily have an algorithm that's a "base difficulty curve" and adjust it upwards or downwards, depending on how the player's doing. Also, don't forget that you have the Math.rand() function, which could add a certain amount of unpredictability to your difficulty function. Dec 27, 2013 at 19:24
• Thanks for mentioning game director, that's a good thing to look into. The game I'm building is similar to Heroes of Might and Magic, where 2 armies battle on a grid battlefied. Except in my case the opponent's army has reinforcements arriving from off map. Similar to your zombie example. Dec 27, 2013 at 20:13

Another possibility is that instead of adding Perlin noise to the y axis of your graph, you could use it to scale the x axis. This would mean that you have a fixed difficulty curve, but it takes a different amount of time to get through different bits of it. For example the Perlin noise could be in the range 0.5 to 2.0, and that could be how quickly time passes on that curve.