7
\$\begingroup\$

I've been toying with an idea for a game prototype where the player must defend against waves of enemies, but between each wave the enemies "evolve" to better combat whatever tactics the player is using. Essentially each enemy type has some genetic information that can be used to generate their health, speed, attack type and so on; with the more "successful" enemy types being mutated into new sub-types, while ineffective enemy types are phased out.

What I'm trying to figure out, is what is a good way of measuring "success" against the player?

EDIT: Although I don't really want to get too specific about the game mechanics, let's assume that the game world is complex enough that you cannot figure out if an enemy type will be effective against the player without testing it.

So far I've thought of two basic solutions:

  • Use heuristics like whether a certain enemy deals damage to the player or survives a long time without being killed.

    The problem I have with this approach is that it can be exploited if (when) the player figures out how the algorithm works. For example you would be able to deliberately let the weakest enemies land a few free hits to trick the game into creating more of them. It may be possible to improve this with better heuristics however.

  • Only use about half the pool of enemy types at once and swap types in and out randomly between waves. Analysis could then be performed on the player's performance throughout the wave and each participating enemy type would be considered equally successful/unsuccessful. After a number of waves the success of enemy types would be varied enough to perform mutation/deletion.

    This solution seems intuitively harder to exploit and it would also pick up on successful combinations of enemy types that might not be possible to detect by looking at individuals, however it might also result in anomalies where useless enemy types are considered successful because they happened to get assigned to waves with stronger enemy types backing them up.

To clarify, I'm not asking about the actual process of evolving enemies, just about how to measure which enemies are successful against the player.

\$\endgroup\$
3
  • 1
    \$\begingroup\$ Here's a good article: ai-depot.com/GameAI/Learning.html \$\endgroup\$ May 30, 2013 at 4:26
  • \$\begingroup\$ When the player has problems beating a certain enemy, the game punish the player by making that one enemy more numerous. That idea is devious, cruel and frustrating... I like it! \$\endgroup\$
    – Philipp
    May 31, 2013 at 11:34
  • \$\begingroup\$ A few years ago I had a similar idea, but focused on enemies in a RPG game, and having each enemy type evolving independently. My bottom line is, don't worry about player 'cheating' the game by letting weaker monsters get better scores. If the genetic algorithm is properly implemented, these tactics will be usefull only for a short time. And if it stills worries you a lot, you can introduce a high mutation rate or reduce the evolution speed to alleviate the problem. \$\endgroup\$
    – angarg12
    Aug 16, 2014 at 12:16

4 Answers 4

1
\$\begingroup\$

I'm wondering whether you could simplify the matter by focusing on how the player fights:

If you have a range of weapons, that effectively provide different ways of fighting, then you can have set classification variables that iterate on use. Think of it as elements and then element resistances for the creatures.

As an example:

You have a range of weapons and whenever the player uses a weapon the variable for that weapon iterates up.

Whenever the game generates a new wave it looks for the top x variables and sends creatures with attributes that make them good against the player's favourite weapons.

-The player uses flame weapons a lot so when the game generates it's next wave it sends a swarm of creatures with flame proof skin.-

\$\endgroup\$
1
  • \$\begingroup\$ That would work in a more discrete game world where it's easy to establish that weapon X is good vs enemy Y without actually testing it in-game. I was hoping for something that would work in a more complex environment, without using things like resistances and elemental damage types. \$\endgroup\$ May 29, 2013 at 15:07
1
\$\begingroup\$

I would measuring the success of an enemy against the player by a costs vs. damage relation.

You have some costs for "producing" the enemy unit (e.g. money, time, other resources). Your unit causes damage to the player in form of resources (e.g. needs to use medikit for healing, kills some of his units [costs for replacing them], ..). The same calculation can be done for e.g. destroyed harvesters, as the player gains less resources of some type for a given period.

So, track what kind of costs you had to producing the unit and to finally cause the damage (=time) and track which kind of damage you did and what a 1:1 replacement costs. Then you can calculate the efficiency for each ressource:

efficiency(resource) = damage_costs(resource) / own_costs(resource) 

Replacement costs can vary with time, as your player maybe improves some building and is able to produce units faster for less money. So you should recalculate the efficiency during the game regularly based on current courses.

Defeating the player means driving some or all of the resources of the player down to zero. Which in the end means that he can not produce some or any new units.

So even a harvester working near to the player can cause damage to him, as it is harvesting his resources, which in the end isn't available to the player anymore. So the player must e.g. invest more time to gain such resources.

\$\endgroup\$
1
  • \$\begingroup\$ PS: This calculation can also be done for a bunch of different units attacking the player. It's possible that a combination of units together is more effective than multiple the best of the units for the same "price". \$\endgroup\$
    – SDwarfs
    Jun 4, 2013 at 13:11
0
\$\begingroup\$

This is a good concept that is not in enough games. The best way to implement this would be to use both of your strategies. Concerning your first strategy I wouldn't be too worried about a player exploiting it because if they let an enemy damage them then they still took damage so they can't do that exploit forever. I still think your second strategy concerning multiple enemies in conjunction is important I'll give the following example. If you have a large "tank" enemy with low DPS and a sniper enemy that hides behind with high DPS the two of them could be a big problem where separately they were weak.

Suggested Improvements for Strat 1 Ways to improve this could be to rank the various heuristics the damage an enemy does is ranked higher than enemy lifetime.

More heuristic ideas for you assuming some type of shooter 1st person, 3rd person or top down. Other heuristics could be ammo user fires at said enemy (hard to track). User movement while fighting an enemy (measure if they are working harder/dodging more against this enemy type).

Suggested Improvements for Strat 2 I would suggest something like swapping out one enemy per level (evolution cycle) and keeping them in reserve, measuring that wave and determining if it did better or worse without that enemy. Cycle out other enemy types next round and measure again.

\$\endgroup\$
1
  • \$\begingroup\$ Another heuristic to consider is how quickly the user puts out damage, what enemies/elements slow that down. \$\endgroup\$ May 30, 2013 at 19:47
0
\$\begingroup\$

Before I would try solving the problem, I would first create a mock setup (with random enemies) and log the data (enemy health over time, other stats, etc...) Then, I would see if there is a pattern that matches up with enemies the player perceived as "tough" and try to replicate that.

I'd imagine that a successful enemy would be one that the player would react to more. As in, one that the player tries to stay away from, rush to for a quick kill to get it out of the way, focuses fire on, one that elicits the most response from the player. Maybe that's too hard to implement, though.

I hope this helps somewhat!

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .