Hello!
I’ve got a game design AI related issue I’m having trouble to solve and I’d love to have you guys input on this :)
A bit of background on my game:
I’m designing an idle/incremantal RPG with a turn based battle system similar to FF7. The player can setup pre-determined rules for his party that the game engine will then execute (very much like the FF12 gambit system: a bunch of if/then/else do that).
I am now working on the monster’s AI. I’ve settled for a chess-like approach to the problem: Create a tree of all possible game state by listing at each unit’s turn, each possible move/skill she can use. And then, parse that tree and find the best move for the AI. I used a custom evaluation function to assess leaf nodes and value how good/bad the situation is for the AI.
I’ve managed to build up my AI data tree quite nicely and it can also use a MiniMax algorithm to find a good move to play. I’ve got unrelated issues to this topic (mainly my AI is way too slow and can only expand fully like 100 nodes, but this shouldn’t really matter for what I am coming here).
The issue:
For now, my AI use fixed random seed to simulate a unit’s turn and then use the same seed for the real turn. It allows me to know exactly how the game will pan out during my simulation.
The main things affected are everything that is percentage based:
- Chance to hit mainly
- Skill with a proc chance (ex: 10% do to this, 90% to do nothing)
My AI knowing what this random numbers will be, know if his next move is going to fail for example. It then chose a move that will either not miss or is just buying her time until the RNG seed is more favorable to her. If all skill would fail this turn, she then simply chose the one that cost her the less resources so she can maintain her advantage. It is smart of her but it means that the AI will likely never “miss” an attack or only use proc based skill when they will actually proc.
For example, it kind of transform a spell that has “X% chance to do Y”, to a spell that has “100% to do Y but has a cooldown of 1/X% turns”. This is not what I want.
I want my AI to use actions and sometimes miss. I’ve tried to find a “clean” solution to this but every ones I think about still has big flaws.
As my AI is kind of slow, I’d like to avoid adding a layer of complexity to it. I can compute things a bit differently but I cannot compute much more scenarios that it is already handling. Example: I cannot split every percentage roll into 2 sub branch tree: passed / fail. It would solve most of my issues but will be too time consuming for me.
Some of my ideas:
1 - Leave it that way and make a design feature: fighting an AI that can “predict” the future can be a challenge in itself, maybe even an interesting one if balanced properly. For example The AI may never miss a skill but if the player uses skills that reduce the monster’s chance to hit it may lead the AI to be forced to make poor choice in the end if it really has no other options. Not my favorite option but still worth exploring.
2 - Changing our RNG seed dynamically so that any random generated during the simulation of a move/turn will not be the same when the turn is really played. Easy to do. The simulation will be “realistic” but In the end inaccurate. It reflects a possibility that could happen but not the real one. The more depth we explore, the farther we will deviate from the real output of the game since we will be re-rolling every random number. In these cases, if the AI selected a move because during simulation because it seemed good, it would still have a chance to fail when the move is really made (that is main advantage of this method). But it doesn’t solve the inverse case where if the AI think it will miss an attack, will still discard it for other safer moves, leading here to eventually make stupid moves : if the AI got only an attack and the possibility to skip turn, it will skip its turn which make no sense.
3 – Change my simulation function to try and average every proc based on percentage. For example: instead of hit/miss I could multiply the damage done by the hit% chance and make it always hit. In average it gives the same damage. It does solves the issue of a “miss” since the AI will chose the best choice regardless of that. The thing is, the more depth we analyze, the farther we will end up from reality (making our decision process more fragile) and some procs are really hard to average with accuracy (stupid example to illustrate: a skill that has 5% chance to kill a character). It is also something that would require extensive recoding and that I’d like to avoid if possible.
4 – Use the same RNG in simulation and the real turn but while deciding what moves to choose, dumb down my AI and add a X% of chance to choose a different move than the best one. It allows us to somehow force the AI to select a move that will miss its target for example. I don’t really like dumbing down my AI on purpose that way. It could make her chose very stupid moves while an optimal one was the obvious choice (ex: a target can be finished with a simple attack but since the AI knows it will fail, it will skip its turn -> it’s counter-intuitive to what a player would do, a player would try to finish off the target, not knowing if the hit will land or not, but he will try if he has a decent hit chance). It also poses the issue of how to chance that X% to select a different move…not a trivial task at all if we want to be as realist as possible.
5 – Some other ones I already forgot :/
In the end, my problem is heavily tied to risk assessment. Trying to find how human assess these risk/reward situation would definitely help me in making the AI do the “right thing”. I want it to appear “smart” and avoid her making choices that the player can label as poor easily. The optimal move are often debatable but the really bad ones tends to stand one and that’s what I want to stay away from.
If you got ideas on all this, or question, don’t be shy :)