One simulation, sixty times a second
Input becomes a serialisable command object, the command feeds a fixed 60Hz step, and only then does anything get drawn. The simulation never imports the renderer, which is what keeps a hit registering identically no matter what your frame rate is doing.
Recoil you can learn
Recoil is an authored list of offsets in degrees, not a random kick. The rifle walks up, pulls left, then settles into a repeating figure. Hold it long enough and you will know where the thirtieth round goes.
You buy between deaths
Kills pay a bounty, the buy window opens near your own spawn, and ammunition is a purchase rather than a refill. Respawning does not top you up, which is what gives dying a price.
One simulation, two hosts
Bots feed the same command objects a human does, through the same tick function. That discipline has already paid out: the online server runs the shipped simulation package itself, at the same fixed rate, so the browser and the referee agree on every hit.