{ "title": "AI vs Anti-cheat", "description": "Neural networks are a double-edged sword for anticheat.", "tags": ["Anti-cheat", "AI", "C++"], "author": "Noah", "date": "7/22/2023", "showTitle": true, "indexed": true, "pinned": true } ### Introduction > The source code for this project can be found at [Strayfade/FNN](https://github.com/Strayfade/FNN) Are "neural anti-cheats" like Valve's "VACnet" the solution to cheating in video games? Possibly. However, just as neural networks can be used by anti-cheat to detect cheaters, cheaters can use neural networks to avoid anti-cheat. This article will be discussing how certain input methods, such as mouse movement, can be easily detected by anti-cheat software, and how this problem can be solved through the use of input "humanization" through neural networks.
Presumed VACnet Patent
By looking at [Valve's publicly available patent](https://patentimages.storage.googleapis.com/e5/80/ee/aadc4e252c6791/WO2019182868A1.pdf) for VACnet, lots of information can be revealed about the upcoming anti-cheat's inner workings. On [page 44](https://patentimages.storage.googleapis.com/e5/80/ee/aadc4e252c6791/WO2019182868A1.pdf#page=44), Valve displays some of the values forwarded through the network: - Pitch - Yaw - Object Type - Action Result - Affected Object - Distance to AOExample input array given to the VACnet neural network.
While it's hard to guess at what some of these values represent, two are immediately recognizable: **pitch** and **yaw**. This likely confirms that VACnet closely monitors how the player's mouse movement affects the in-game camera's pitch and yaw over time. ### 1. Simple Detection Let's focus on the simplest form of aimbot detection: the distance of the crosshair from the target location. If this distance shows little to no movement over a long period of time, then it is safe to assume that the player is cheating. This is the easiest way to hypothetically detect a player using aimbot, but it is also the easiest to circumvent using our first "humanization" method: Input Smoothing. ### 2. Smoothing Detection The goal of "smoothing" is to move the mouse gradually to the target location, as a human would, instead of instantly moving the mouse where it needs to be. Smoothing is almost **always** accomplished using the following function, where _x_ is a screen coordinate and _t_ is that coordinate's target position: > f(x) = (t - x) / c + x Note that in this equation, _c_ is the **smoothing constant**, a value greater than _1_ which can be used to control the speed at which the coordinate changes. The higher the value, the slower the coordinate changes. The speed at which the crosshair moves to the enemy can be graphed using the equation **y = 1 - x**, and the approximate distance from the enemy can be graphed using the following: > y = 1 - (|(x - 1)|^(s + 1) \* -1 + 1) An anticheat could detect a user that is using smoothing simply because of the fact that the crosshair's distance from the target will always decrease at an exponential rate. This can, of course, happen natrually with human players at times, but it will **always** happen with players who are cheating and using smoothing. One way to avoid this detection is by using a linear smoothing function, or one that adds a constant value to the coordinate over time until it is within a certain distance from the target coordinate. Many cheats, however, don't take advantage of this, as an exponential smoothing algorithm is usually easier to code. Additionally, a linear smoothing algorithm could (_in theory_) be just as straightforward for an anticheat to detect as its exponential variant. ### The Solution It almost feels that we would need a smoothing algorithm with added randomness to make the inputs look "human". What is the best way to produce controlled randomness that can change depending on the circumstances? **Neural networks.** ### Writing Our Own Neural Network The key in creating a neural network is the layout of **weights** and **biases**. - **Weights** define how much the input should be changed by - **Biases** define the probability that the input will be changed at all Lastly, we have our input and output layers, or **neurons**. Here is example code that shows what we are working with. In this example, the `V(T)` is a macro for the `std::vector<>` object. `V2(T)` is the definition for a **Vector2** (`std::vector