Sponsored By

Intelligence in turn based RPG combat

Cross-posted YIIK dev blog about the complexities about designing the game's artificial intelligence.

Cassandra Khaw, Blogger

June 26, 2015

9 Min Read

Y2k is an upcoming third-person JRPG inspired by Final Fantasy, Earthbound, and Haruki Murakami. It follows the misadventures of bearded college graduate named Alex Eggleston as he hunts through a '90s message board for information on the mysterious "Death Cab." Y2K also contains weaponized panda plushies and killer alpacas. This is the dev blog you are looking for. 

Crossposted from Ackkstudios' devlog. 

Intelligence in turn based RPG combat:

DoHeal DoHeal DoHeal, and other nicely named objects!

Hello, Brian here. I’m not even going to pretend I know what the week number is anymore!

Last week I turned my attention to enemy AI.

Previously, I simply had the enemy select from a list of possible skills at random. I never intended t›o keep this behavior, but I needed a placeholder AI for our previous demos, and this worked good enough at the time.

My goal for the new behavior was to have enemies that appeared to think, and that could be seen to behave differently from one another. I wanted something that could be modified in Unity’s editor without having to write different scripts for different behaviors.

The Gambit system from Final Fantasy XII came to my mind immediately. In Final Fantasy XI, you could equip your characters with “Gambits” that would change their behavior in battle if certain conditions were met.

(Image source: http://finalfantasy.wikia.com/wiki/Gambits)


Final Fantasy XII is a realtime game, but this system gave me an idea.

The idea has probably been tackled like this by thousands of other people before me, but since I couldn’t find anything as flexible as what I wanted, I set off to re-invent the wheel.

The Idea: Have a list of objects that contain fields that can be modified to execute an action if certain conditions have been met.

For lack of a better term, I called the objects in my script “Gambits” as well.

I realized would need a very generic way of accessing a wide variety of stats in order to make an informed decision.

The basic setup is like this:

AI Component

  • Has an Array of Gambits.

Gambits:

  • Has an array of conditions

  • Has an array of skill(s) to execute (one skill is often put here, but for more variety a second skill with a similar effect may be added to enhance the randomness of the fight, although it is not necessary)

Conditions:

I have a class with:

  • An enum for Actors to check. (This can include: Self, Anyone in the Hero Party, anyone in the Enemy Party, Enemy Leader, Hero Leader,pick strongest,pick weakest, most hp,least hp, Specific hero characters. etc…)

  • An enum for conditions to check.(Hp [Greater than, less than or equal to],Mp [Greater than, less than or equal to],

     *  And an int whose value is used differently depending on the context of the previous 2 enum values.


Analyze, Decide, Execute: At first I tried to execute the commands in the way I think FFXII did; initialize the current “Gambit” value (it’s place in the list/array) increment until a condition returns true, or keep searching until you come back to the value you began with. If nothing was found, I would default to an action marked as default.

This worked, but sometimes an enemy would wait a turn before healing themselves if an attack condition also returned true, and was closer to the first value. Not a good turn based solution.

What I did next is super obvious, and likely what most games do: I assigned a weighted “priority” value to a Gambit. I then scan the entire list and collect all of the gambits whose conditions are met. With this new list of gambits I randomly select one based on weight.

ObjeGambitcts with a higher value are more likely to be performed then  Gambit with a lower value.

To put it simply:

At the beginning of an (AI driven) Actors turn, Each Gambit is scanned.

All Gambit’s whose conditions are all met get added to a list of potential actions.

An action is selected based on the weighted value of the Gambit (favoring higher values).

What does it look like?

It looks like it’s thinking!

An enemy can be setup to heal itself if it is dieing, but it can also be set to sometimes take a risk and attempt to kill the player before healing.

It can be made so that it will only attempt to attack the player, if the player’s hp is below 10%, so that it has a decent chance of not dying in vein.

It can also be set to only check the player, if the player last attacked it.

A number of combinations can be put together to create complex strategies with simple building blocks.

(The script automatically names the array description field in the editor to show the logic+ result of a given Gambit, so you can see what it does without diving in to each element)

The Next Step:

The next thing I will do is write a nice editor script for setting up AI strategies. I don’t need exactly need an editor as everything can be modified in the inspector, but it looks a little cluttered and hard to read, so I think will write an editor to encourage myself to spend time creating interesting strategies.

Thanks for reading.

Read more about:

Blogs
Daily news, dev blogs, and stories from Game Developer straight to your inbox

You May Also Like