Home » Is it unethical to make a game AI that is secretly non-competitive?

Is it unethical to make a game AI that is secretly non-competitive?


What do you want to accomplish with your AI?

If your game is trying to tell a story, then it is reasonable to have the AI adjust so that you get the story you want to tell.

If you want the player to have a sense of accomplishment from overcoming an obstacle or beating an opponent, making the controlling AI throw the game takes away from that — you need the AI to actually be the threat it’s presented as.

Game AIs are almost always non-competitive, because if the AI would really try its hardest to win, it would often be unbeatable. An AI is not bound to human limitations like reflexes, accuracy, perception, fatigue or computational ability. So when it is seriously playing to win, no human would ever stand a chance.

Let’s take the first person shooter genre as an example. Most of this answer should be applicable to most other genres. There are exceptions. AIs have difficulties beating humans at very complex strategy games, for example. Many real time and turn-based 4X strategy games cheat a lot in order to make the AI players challenging. But covering every single game genre would make the scope of this answer too large. So let’s focus on the FPS genre.

A perfect playing AI would shoot you with perfect accuracy in the first frame where a single pixel of your character is visible to them. You sometimes encounter this in multiplayer when you play against cheaters. They are called aimbots, and nobody likes playing against them, because it’s extremely frustrating.

But such a perfect aiming AI is in fact the easiest one to program:

if (lineIsUnobstructed (this.position, player.position)) {
     rotateTowards (player.position);

So perfect play is the default behavior. Human weaknesses like inattentiveness, limited perception, delayed reaction and inaccurate aiming are things you as a game developer need to program intentionally. And you usually take a long time to tweak these aspects until the enemy behavior is both plausible and provides the right amount of challenge to the player. How much challenge is “the right amount of challenge”? Very interesting question, but not within the scope of this question.

Also keep in mind that most single-player games are inherently asymmetrical for narrative reasons. Player and AI opponents usually do not have the same goals, have different tools available and are often not even subject to the same game mechanics. It’s not uncommon for the sole player-character to face dozens or hundreds of opponents in a single level. When every opponent would be as good as the player, this would be impossible to do. But most games are selling power fantasies. The player is supposed to be a badass action hero who can single-handedly defeat a small army. That’s usually the experience the player expects when they buy a first person shooter. That means in order to give the player a “fair” challenge, you need to make the single enemy relatively weak and stupid.

Now regarding the question “Should I make the game easier when the player is losing?”. Maybe, maybe not. Lots of players do indeed feel condescended when they repeatedly fail at a challenge and then suddenly the challenge gets taken away by becoming a lot easier. So you might want to avoid that, at least without asking the player if they want help.

But what many games do very successfully is a technique called rubber banding. Adjust the difficulty of future encounters depending on the player’s success in past encounters. Sometimes you can even do that naturally within the fiction of the game.

A game’s AI is a part of a game’s overall design. At the end of the day, the AI you create needs to complement the game design.

If your game is designed around creating a challenging, competitive environment, then a “perfect” AI might be a good thing. At the same time, you have to consider something very important:

Humans aren’t computers.

Even without cheating, it’s not at all difficult in many competitive games to craft an AI that can beat any human without effort. AIs don’t have to read player inputs to have faster reaction times than any human. If the player takes an action that has any visual hint, the AI has the right under your “play as best as it can” rule to use even slight visual differences to perfectly react to what is happening.

To make this work, you have to change the nature of the game itself. For human-to-human play, you might have all of the wind-up animations for fast attacks look very different, since human reaction time is being taken into account. But for computers, such a game is trivially easy; they can react instantaneously and perfectly.

So in fighting games, if a perfect computer has a fast move, and you attack with anything that takes more frames than their move, the computer will hit you. What was an intricate guessing game where players have to predict each others’ movements turns into the human losing to the computer.

If you want to have a perfect AI, you need to build a game where the AI can play perfectly and still lose. That’s not an easy thing, and it wouldn’t work in a lot of genres. It could only happen if there are things that the AI has to react to but without enough time to do so. This would be like RTS games where there is hidden information. Truly perfect play would require perfect knowledge, but that is unattainable. Therefore, the computer will have to settle for “perfect, as far as I know, play”. And thus, it can be fooled.

But even in such games, the speed of computers gives them an advantage in any situation where there is well-understood information. They can micro perfectly, positioning each unit for maximum effect. And so forth.

Basically, most games made for humans are made for humans, not for computers.

This is not a question of “ethics”. It’s a question of who the game is made for and what the purpose of the AI opponent is.

Related Solutions

Calculate the sum with minimum usage of numbers

Here's a hint: 23 : 11 + 11+ 1 ( 3 magic numbers) 120: 110+ 10 (2 magic numbers) The highest digit in the target number is the answer, since you need exactly k magic numbers (all having 1 in the relevant position) in order for the sum to contain the digit k. So...

Why not drop the “auto” keyword? [duplicate]

Your proposal would be rejected on the basis of backward compatibility alone. But let's say for the sake of argument that the standards committee like your idea. You don't take into account the numerous ways you can initialize a variable widget w; // (a) widget...

Recursive to iterative using a systematic method [closed]

So, to restate the question. We have a function f, in our case fac. def fac(n): if n==0: return 1 else: return n*fac(n-1) It is implemented recursively. We want to implement a function facOpt that does the same thing but iteratively. fac is written almost in...

How can I match values in one file to ranges from another?

if the data file sizes are not huge, there is a simpler way $ join input1 input2 | awk '$5<$4 && $3<$5 {print $2, $5-$3+1}' B100002 32 B100043 15 B123465 3 This Perl code seems to solve your problem It is a common idiom: to load the entire...

Javascript difference between “=” and “===” [duplicate]

You need to use == or === for equality checking. = is the assignment operator. You can read about assignment operators here on MDN. As a quick reference as you are learning JS: = assignment operator == equal to === equal value and equal type != not equal !==...

Compiler complains about misplaced else [closed]

Your compiler complains about an misplaced else because, well, there is an else without a preceding if: // ... for (j=1; j<n-i; j++) { if(a[j]<=a[j+1]) { // ... } // END OF IF } // END OF FOR else { continue; } // ... The else in your code does not follow...

Bootstrap – custom alerts with progress bar

/* !important are just used to overide the bootstrap css in the snippet */ .alertContainer { border-radius: 0 !important; border-width: 0 !important; padding: 0 !important; height: auto !important; position: absolute !important; bottom: 15px !important; left:...

How to Garbage Collect an external Javascript load?

Yes, s.onload = null is useful and will garbage collect! As of 2019, it is not possible to explicitly or programmatically trigger garbage collection in JavaScript. That means it collects when it wants. Although there is cases where setting to null may do a GC...

Math programming with python

At first, what you are looking for is the modulo operator and the function math.floor() Modulo from wikipedia: In computing, the modulo operation finds the remainder after division of one number by another (sometimes called modulus). for example: 12%12=0...

Android slide over letters to create a word [closed]

Here some advice you can use: First for each cell you can create an object that represents the state of that cell: class Cell { char mChar; int row,column; boolean isSelected; } then you can create a 2D array of your cells Cell[][] mTable = ... For views you...

Sum two integers in Java

You reused the x and y variable names (hence the variable x is already defined in method main error), and forgot to assign the ints read from the Scanner to the x and y variables. Besides, there's no need to create two Scanner objects. public static void...

Extend three classes that implements an interface in Java

Using this simplified implementation of the library, using method() instead of M(): interface IFC { void method(); } class A implements IFC { public void method() { System.out.println("method in A"); }; } As akuzminykh mentions in their comment You'd write a...

How to set the stream content in PHPExcel? [closed]

Okey, First thing first PHPExcel_Worksheet_MemoryDrawing() can't solve your problem if you insist to use stream content and pass that to your worksheet your PDF will not render your image. But you can use `PHPExcel_Worksheet_Drawing()' if you want to render...

How to remove all files from a directory?

Linux does not use extensions. It is up to the creator of the file to decide whether the name should have an extension. Linux looks at the first few bytes to figure out what kind of file it is dealing with. To remove all non-hidden files* in a directory use: rm...

Hacker used picture upload to get PHP code into my site

Client side validation The validation code you have provided is in JavaScript. That suggests it is code that you use to do the validation on the client. Rule number one of securing webapps is to never trust the client. The client is under the full control of...