Building AI That Fights Back Without Cheating
All News

Building AI That Fights Back Without Cheating

8 min read

The central design problem of our AI system is not making opponents hard. Making them hard is easy. You can push aggression parameters up, give the AI perfect aim, or let it read a player's hitbox before the frame has finished rendering. Hard is trivial.

The real problem is making them hard in a way that feels earned. Our adaptive opponents need to push back with genuine pressure without ever crossing the line into behavior that makes a player feel cheated rather than beaten. Those are different feelings, and the distance between them is everything. Getting that distinction right took us longer than anything else in the system.

What "Cheating" Actually Looks Like From the Player's Chair

Before we could build an AI that did not cheat, we had to work out what cheating actually is in a competitive game context. The obvious cases are not the interesting ones. Perfect aim is clearly cheating. Seeing through walls is clearly cheating. Players notice those immediately and stop trusting the system entirely.

The subtle cases are harder to name. We identified three categories that players consistently describe as "unfair" without being able to articulate why:

Response latency violations. If an AI reacts faster than a human can physically react, it does not matter that its other actions are legal. A skilled player holding a corner can process and respond in roughly 150 to 200 milliseconds at the fast end. An AI that processes and fires in 20 milliseconds has a mechanical advantage no amount of player skill can close. The player loses and has no framework for why. This is the most common way well-intentioned AI implementations tip into feeling broken.

Information asymmetry. If the AI uses information the player cannot access, the contest becomes unequal in a way that is invisible. We have seen AI implementations that track exact player health, precise position, and cooldown states at all times. Even if such an AI does not have aimbot accuracy, playing against a system with perfect state knowledge produces a similar effect. You feel hunted in a way that does not match what your opponent should be able to know.

Adaptation that outpaces visibility. An AI that counters your strategy before you have fully committed to it reads as prescient in the wrong way. The player has not done enough yet to signal intent. If the AI is pattern-matching on too short a behavioral window, it can feel like the system is simply denying everything rather than countering something specific you have decided to do.

How the Adaptation Loop Is Structured

Our AI builds a behavioral model of each player across the match. Not between matches, not across session history, but within the live game from the opening engagement forward. The model updates on meaningful events: sustained engagements, routing decisions, weapon selection under pressure, movement timing in transition phases.

The key word is "meaningful." Early in the match, the model has low confidence. The AI's counter-behavior is weighted accordingly. It uses what it has observed, but it does not overweight thin data. As the match progresses and confidence rises, the AI's counter-behavior becomes more specific and more assertive. By round five or six, if you have been running the same flanking angle on every approach, the AI will have that pattern locked and will pre-position for it. That is the design intent: you can see it coming, you chose to repeat the behavior, and now you have to change.

The response latency floor is hardcoded. The AI cannot initiate a direct reactive response to a player action in under 180 milliseconds. It can pre-position based on pattern inference, which is different because a skilled human opponent would do the same thing. But a pure reaction response has a floor below which we do not go.

The Information Budget

One of the more interesting design constraints we landed on is what we call the information budget. The AI opponent has access to less information than the game engine technically has available, and that restriction is enforced at an architectural level rather than a behavioral one.

The AI knows its own state perfectly. It has a witnessed zone that operates like a genuine line-of-sight model. Outside that zone, it works from decaying probability estimates, not position locks. If it last saw you move left and then lost sight for eight seconds, it knows you went left and it knows eight seconds have passed. It does not know where you are now.

This sounds like a simple implementation choice. It is actually an architectural one. Building a real fog-of-war layer for an AI agent that runs inside the same process as the game state requires deliberate work. The temptation is to let the AI access full engine state and just write rules against acting on it. We found that approach does not hold. The inference layer was silently using state it should not have had access to without us catching it. The isolation has to be structural, not behavioral.

Where We Got This Wrong the First Time

We should be honest about the earlier versions of this system, because they were bad in instructive ways.

The original adaptation system had no confidence weighting. It adapted fast, from the first engagement, and it adapted aggressively. Playtesters described it as oppressive rather than challenging. The feeling was not "this opponent has read my game." It was "I cannot do anything." That is not a good competitive experience. It removes the sense that you can outmaneuver a system that has learned you, which is the core pleasure we are trying to build.

We also lacked the information budget constraint in the first version. The AI was using full engine state. When we ran the first internal playtests with that build, players kept saying the AI felt like it had a different level of awareness than they did. The phrase "it always knows where I am" appeared in five separate feedback sessions across different player groups. That is the exact feeling we were designing against, and we had built it anyway.

The current version is roughly the fourth major iteration of the core design. The underlying approach did not change, but the calibration and the structural constraints took a long time to get right.

Drawing the Line in Practice

We want to be clear about what we are and are not claiming here. We are not saying that difficult AI is the problem. High difficulty is something competitive players actively seek. Some of our most positive playtest feedback came from sessions where players described the AI as relentless. That is the target.

The line we are drawing is between difficulty that comes from intelligent behavior and difficulty that comes from mechanical advantages the player cannot overcome or even identify. An AI that learns your preferred engagement range and forces you out of it is hard in the right way. You know what happened. An AI with sub-100ms reaction times that you cannot challenge regardless of positioning is hard in the wrong way. You cannot identify what happened, and no tactical adjustment changes the outcome.

The internal test we use is straightforward: can a skilled player identify what the AI did, understand why it worked, and design a counter? If yes, the difficulty is legitimate. If the answer is "the AI just responded faster than any human could," we have crossed the line we set out to stay behind.

That test does not produce exact parameter values. It gives you a lens for evaluating what you build. The parameter values require playtesting to calibrate, and we expect to keep tuning them as we move toward a wider audience. But the lens is right, and the architectural constraints that enforce it are what make the rest of the adaptive system worth building at all.