
Where Lights Don’t Shine is a First-Person Shooter where you play as a SWAT officer responding to and neutralizing a terrorist attack. This project is in active development.
Technical Details

AI Attack and Flanking Coordination
In order to make enemy AI behave more like a trained, coordinated force, I implemented Combat Brain subsystem to orchestrate attacks and flanking at the squad level.
During combat, the system divides the battlefield into arbitrary number of angular slices, originated from the player. If an AI occupies a slice, cascading weights are applied to that slice and its neighbors to discourage clustering. When an AI needs to reposition, Combat Brain randomly selects from the lowest-weight slices. The AI will then find a new cover via EnvQuery, encircle the player and provide them a more challenging fight.
Additionally, Combat Brain maintains an Attack Token system that limits how many AI can fire at the player at once, improving pacing while still preserving that believable “coordinated unit” feel.
Contextual Leaning
Seen in both Black Ops 6 and Battlefield 6, Contextual Leaning might not be the most useful mechanic, but it is still something I was very interested in implementing.
To detect whether we can lean around any cover, the solution is simply some 3D math. First, we want to confirm the player is indeed within certain a distance of a solid object. Then, we shoot two rays to the front-left and front-right, which helps us to determine which side has a clearing that allows us to lean. Since we only want the player to lean when it results in a clear line of sight, we do one last line trace based on the predicted position after leaning.



Recoil Smoothing and Recenter
Recoil handling is a key aspect of achieving great gunplay in FPS games. In this project, it consists of three parts:
First, we add a random 2D recoil for each shot. If we want every shot to land directly on the player’s reticle, we have to apply the recoil directly to the player’s camera. Additionally, we smooth the recoil climb by moving the camera only a small amount each frame.
Second, we also track the total recoil climb. After firing and a small delay, we pull the player’s camera back by the total recoil climb amount to recenter their view. Again, this needs to be smoothed over frames.
Finally, depending on how much the player moved their view during or after the recoil climb, we reduce or even cancel the recentering altogether. This ensures if the player is compensating for recoil, recentering won’t pull their camera toward the ground.
