Skip to main content

News

Topic: Gamasutra: Fixing Pokemon (Read 9231 times) previous topic - next topic

0 Members and 2 Guests are viewing this topic.
  • N E O
  • [*][*][*][*][*]
  • Administrator
  • Senior Administrator
Gamasutra: Fixing Pokemon
http://gamasutra.com/blogs/HardyLeBel/20141222/233000/Fixing_Pokemon.php

At the end, when he presents the table, I immediately thought of Radnen's Link.js and Lord English's Scenario for the powerful array function chaining to achieve such results easily.

So! Who else here thinks Pokemon needs to be fixed and how? I know Sphere has seen its share of Pokemon projects and I for one would love to see a TBS RPG on Sphere implement these "Master Mode" mechanics.

  • Radnen
  • [*][*][*][*][*]
  • Senior Staff
  • Wise Warrior
Re: Gamasutra: Fixing Pokemon
Reply #1
Heh, in my Blockman game I've been toying around with opponent AI using my link.js. I liked the AI systems in Bioware games and thought I could do something like that in my games (you have these configurable 'slots' that do actions in a very human readable way).

Code: (javascript) [Select]

// If the distance between me and the player is between 0 and 16 pixels, use the attack skill.
AI("enemy1").ifDistance("player", 0, 16).useSkill("attack", "player");

// If between 16 and 120, attempt to seek.
AI("enemy1").ifDistance("player", 16, 120).seek();

// I'm not sure about this, but I fear I need a stopping condition for the AI since it could change depending on enemy type.
AI("enemy1").ifDistance("player", 120).stop();

// If my hp is between 0 and 33%, use the skill 'heal'.
AI("enemy1").ifHP(0, 33).useSkill("heal");

// We can also do this to another target for a medic-like AI type.
AI("enemy1").ifOtherHP("enemy2", 0, 33).useSkill("heal", "enemy2");

// Status checking is in the mix too, as well as a smattering of other things.
AI("enemy1").ifOtherStatus("enemy2", "frozen").useSkill("defreeze", "enemy2");


Each row above creates an AI 'slot'. A typical enemy will use 4-5 slots, stronger AI's have more slots. They are created on the constructor of an enemy, so don't worry about the explicit naming. I've been looking into doing things like 'nearest enemy' or 'furthest ally'. In that regard some complex actions can be described relatively easily with this chaining method.

This applies to Pokémon because it too can be used for the AI (like with that table as NEO pointed out). My AI system also uses a light-weight threading system inspired by Lord English's scenario.js (I didn't want to use all of scenario on the battle engine, though I could I felt I just needed a lean-mean threading system.

The article is pretty interesting, I've always liked to read discussions on battle systems. The main thing I disliked about Pokemon was how you can do an attack-always approach and usually won if you could correctly match opposing types. I think two things that need to happen more often is skills that require more than 1 turn to use, not the charge-up skills, but basic skills like 'tackle' so they don't get abused, and the second thing is opponents that have unassuming normals, such as a Raticate that like knows thunder. Wouldn't that throw you for a loop? On top of that they should be randomized enough so you can't read a guide knowing you are going into a battle with a Raticate that happens to know thunder. In fact, more of that randomization needs to occur. (If it does in later games, then I'm wrong, my knowledge only goes up to Ruby/Sapphire).

If we are talking about mechanics then it'd be nice to see some type affinity happening. In dual-battles two types that compliment each other could add critical bonuses to skills. Think Chrono trigger and it's combo system, but applied to Pokémon. Would be neat to see.
If you use code to help you code you can use less code to code. Also, I have approximate knowledge of many things.

Sphere-sfml here
Sphere Studio editor here

Re: Gamasutra: Fixing Pokemon
Reply #2
Why not just create a variable for AI("enemy1") if you're going to be using it a lot, rather than repeatedly call AI("enemy1").method()?

  • Radnen
  • [*][*][*][*][*]
  • Senior Staff
  • Wise Warrior
Re: Gamasutra: Fixing Pokemon
Reply #3

Why not just create a variable for AI("enemy1") if you're going to be using it a lot, rather than repeatedly call AI("enemy1").method()?


I see what you mean, but it won't work like that. If I cached AI("enemy1") into a variable then I'm just appending forever onto the same context. Each Call of AI("enemy1") creates a new chain. I use my Link.js library to help with this.

Link returns a Lazily executable chain. So I'm actually not repeatedly calling AI().method(), the methods you see above are there to build a chain of events. I store that chain into a variable or array and then I can execute the AI chain whenever without having to rebuild it. The system is all about describing the AI's.

Code: (javascript) [Select]

// only make this once:
this.ai.push(AI("enemy1").ifDistance("player", 0, 20).useSkill('attack'));

// later in the entities AI loop:
Link(this.ai).invoke();


Ok, I'm also using link above, but basically I create the chains once and can continue to execute them as often as we need. Because Link is good at filtering, doing things like waiting for the player to be "in range" or for the health to be between certain values, it can execute these chains rather quickly.
  • Last Edit: December 28, 2014, 04:55:23 am by Radnen
If you use code to help you code you can use less code to code. Also, I have approximate knowledge of many things.

Sphere-sfml here
Sphere Studio editor here

Re: Gamasutra: Fixing Pokemon
Reply #4
Oh I see, that makes sense.

  • Fat Cerberus
  • [*][*][*][*][*]
  • Global Moderator
  • Sphere Developer
Re: Gamasutra: Fixing Pokemon
Reply #5
Getting the thread back on track, this "Master Mode" seems like an awesome idea and would be a much-welcomed addition to the Pokemon formula.  I still love me some Pokemon (X/Y were awesome) but the single-player campaign suffers in all cases because of the formulaic plot (stop the bad guys from harnessing the Legendary Pokemon to destroy the world, capture said Legendary Pokemon for yourself, then go steal the Champion's title) and boring (also: non-existent ;)) enemy AI.  I would be willing to let the cliched story slide if trainer battles were actually fun.  There are so many trainer battles in every game that there's really no excuse for the braindead random move selection at this stage.
neoSphere 5.9.2 - neoSphere engine - Cell compiler - SSj debugger
forum thread | on GitHub

  • Fat Cerberus
  • [*][*][*][*][*]
  • Global Moderator
  • Sphere Developer
Re: Gamasutra: Fixing Pokemon
Reply #6
Hm, I think I killed the thread in the process of un-derailing it...  Oops! :-X
neoSphere 5.9.2 - neoSphere engine - Cell compiler - SSj debugger
forum thread | on GitHub

  • Radnen
  • [*][*][*][*][*]
  • Senior Staff
  • Wise Warrior
Re: Gamasutra: Fixing Pokemon
Reply #7
Not sure, there's like only 4 or 5 guys here still active! (I might have gotten too technical with Link... :/)
If you use code to help you code you can use less code to code. Also, I have approximate knowledge of many things.

Sphere-sfml here
Sphere Studio editor here

Re: Gamasutra: Fixing Pokemon
Reply #8
How would the Link AI system pick randomly weighted strategy "paths"? The example Radnen gave at the top of the thread reminded me of the Final Fantasy 12 gambit system, and it made me wonder if something like that could be easily implemented with a Link backend.

  • Radnen
  • [*][*][*][*][*]
  • Senior Staff
  • Wise Warrior
Re: Gamasutra: Fixing Pokemon
Reply #9

How would the Link AI system pick randomly weighted strategy "paths"? The example Radnen gave at the top of the thread reminded me of the Final Fantasy 12 gambit system, and it made me wonder if something like that could be easily implemented with a Link backend.


Well it wouldn't be used for randomly selected weighted paths. I was thinking more along the lines of traditional turn based games and even games like Bioware's JadeEmpire or KOTOR (or heck, even their Dragon Age games) and how they all uses predefined "AI slots" to do actions and the more slots filled, presumably, the smarter the AI. It's basically a list of causes and effects. Pokémon could be made more interesting in this way.
If you use code to help you code you can use less code to code. Also, I have approximate knowledge of many things.

Sphere-sfml here
Sphere Studio editor here

  • Fat Cerberus
  • [*][*][*][*][*]
  • Global Moderator
  • Sphere Developer
Re: Gamasutra: Fixing Pokemon
Reply #10
How does this slot system handle the case where two (or more) conditions are met?  RPG Maker has a surprisingly elegant solution for this with priorities, but this Link method doesn't appear to have anything of the sort, it just naively picks the first action whose condition is met.
neoSphere 5.9.2 - neoSphere engine - Cell compiler - SSj debugger
forum thread | on GitHub

Re: Gamasutra: Fixing Pokemon
Reply #11
I can imagine that in the simplest case, you could just solve that with the ordering in the underlying list of possibilities.

In Link, I'd assume you could also just sort them based on some added priority field.

  • Fat Cerberus
  • [*][*][*][*][*]
  • Global Moderator
  • Sphere Developer
Re: Gamasutra: Fixing Pokemon
Reply #12
You're still just picking the first action in a list whose condition is met, there's no element of randomness.  In RPG Maker, if two or more AI actions are valid at the time, it randomly picks one, weighted by their priorities (higher priorities being picked more often than lower ones).  This way you can have a low-priority action to, say, heal when below 33% health without that completely overriding all the (higher-priority) normal actions the enemy takes.
neoSphere 5.9.2 - neoSphere engine - Cell compiler - SSj debugger
forum thread | on GitHub

Re: Gamasutra: Fixing Pokemon
Reply #13
I would hope Link would have a `select all that match' function. After that, it would be pretty simple to do a randomly weighted choice among those.

  • Radnen
  • [*][*][*][*][*]
  • Senior Staff
  • Wise Warrior
Re: Gamasutra: Fixing Pokemon
Reply #14

You're still just picking the first action in a list whose condition is met, there's no element of randomness.  In RPG Maker, if two or more AI actions are valid at the time, it randomly picks one, weighted by their priorities (higher priorities being picked more often than lower ones).


Well, these create the slots, there would presumably be another runner that runs the slots (you know, executes it). That runner can easily be set up with weights and what-not. I've only been mentioning slots, not exactly how they are ran. Sure they have conditions like "if in 30 pixels do this", but still there is something on top of all that checking for these conditions and running them.
If you use code to help you code you can use less code to code. Also, I have approximate knowledge of many things.

Sphere-sfml here
Sphere Studio editor here