The concept behind CoD's KillCam

Hello everyone,

I was wondering how to make CoD’s KillCam in a game. It’s pretty hard concept I think, but it surely will help catch thousands of hackers for a game. But how to really make it?

Me and a friend of mine, were wondering how to make it and thought that the game is recording keyboard inputs and then replays them. But another interesting topic is how does the game changes the camera without reloading the map or something.

Do you guys have any idea on how to make it maybe?

This also interests me. I assume it’s using a client-side recording to avoid bandwidth issues, but then the client-side recording needs to have all the relevant information to show the scene from the killer’s point of view. If it would be trivial we’d probably see it in more games already, so this is a pretty interesting challenge. If somebody would come up with a reusable way to do this with UE4, that would be pretty huge IMO.

We actually have something fairly similar as experimental. It’s basically just a plain recording but accessible via console right now. It allows you to record everything currently happening in the map (basically just saving everything you get from the server on your harddrive) and allows you to instantly play it back if you want.

Right now it’s not possible to work with timestamps here and as I said it’s kinda experimental but you can expect this to be worked on by epic.

Hmm… While it could use a temp buffer of constant recording, just limiting how many seconds it records then throwing away the rest. But that recording would be from the view of the clients player in that case. I thought the killcam showed from the point of view of the killer. It would be too much for the client to record all players into a short temp buffer constantly.

I’d like to hear how to accomplish something like that, as now it has tweaked my interest as to how they do it.

This sort of thing would also be great to have for our game, where we can show replays of goals that have been made!

A server recording should allow viewing from any player’s perspective (no idea if the experimental demo recording supports this right now though). So perhaps the best way to do it is to stream the last few seconds of the server recording to the client while it shows the killcam. Doing this nicely still sounds extremely complicated to me though.

I recall watching one of the twitch feeds where they showed recording a game, and it appeared that what it did was record everything that went on, and when you played back you could sort of free spectate the playback. If that is where their experiment ends up, then hopefully they will have a way to have a limited buffer of recording, and when a player is killed it simply plays it back with the ability to automate a camera to follow the view of the player that made the kill. Dunno, just thinking out loud.

To make a KillCam is simply record everything what is happening on the server. Save it for 10-15 seconds. If the player dies play it back to the client.
Also the recording should be server side, to avoid unnecessary network packets.

Since the 4.6 version you have:

But i have no idea if they can be used for this purpose.

If not, then the code should look something like this:


TArray<FFrame> Frames;
void Tick()
{
    FFRame Frame;   //Frame is a snapshot of player positions / movements
    // Fill Frame with player position
    Frame.Time = CurrentTime+15; // Set the expiration for 15 seconds.
    Frames.Add(Frame); 
    if(Frames[0].Time < CurrentTime) // Check if our first frame is old enough
    {
       Frames.RemoveAt(0); // delete the old frame
    }
}

It will eat out some memory but you can skip some frames if you need. But this is how it should be recorded. Then to play it back just send the frames to the client one by one.

I could be wrong, but personally I think it’s unlikely that a replay comes from the server, as that’s not a very elegant way to implement it.
I think it’s more likely that they store a history of the game for a set length of time, as your client saw it, and then play it back client-side.

If I had to guess, they probably serialize the game state periodically, and then store network messages that change the state of the game for actors that they care about, until the next serializable frame.
Messages like “this guy threw a grenade”, “the grenade exploded”, “this guy took damage”, etc.

So when a request to playback the replay comes in, they restore the game state to the closest fully serialized frame, and then play back all the state change messages at the appropriate time.
Alternatively, I guess you could just store all the network messages over a set period of time and reverse their effect, then play them back again.

Some games store the player’s previous positions and rotations for a set period of time, so that they can rewind time a few seconds for latency compensation purposes. I think Source engine works that way… possibly Unreal too, it’s been a while since I’ve looked at the player replication code.

Probably worth checking out Halo’s theatre mode too, as I think they might use a model like the one I described.
Notice that you can’t rewind the game as you would a videotape, you can only skip backwards in increments.
You also can’t skip forward until you’ve played up to that point (if I remember correctly), and even then you can only skip up to certain points in the game (you can’t just arbitrarily skip forward 10 seconds).

That would be consistent with saving the game state periodically, and just accumulating differences in between.

It’s client side. All they do is record the positions, rotation and basic actions of players in something like a 10 second buffer. They then play back those actions on the client before respawning back into the game. It’s 100% client side.

But network code is highly optimised to only send what is relevant to the client. That’s why usually you cannot switch players while watching a client-side recording, and I assume that the demo recording implemented in Unreal works that way too?

So either it will not work client-side, or you will have to make the network code less efficient just for the sake of the killcam, which isn’t really an acceptable compromise. Remember that this is about showing the kill from the killer’s perspective, not about replaying the last few seconds of the player’s death.

A thought just occurred to me, isn’t CoD using peer to peer networking? That could make this a lot more straight-forward, e.g. you could directly send a compressed replay from the killer to the victim without affecting server performance.

Ah yes, there is some indication that this is indeed true:

Sounds like CoD was having trouble getting it to work with dedicated servers as well. And if that’s the case, you can take it for granted that this is anything but an easy problem to solve…

That would be very, very, very interesting. But it wouldn’t surprise me since COD has an endless list of in-game “bugs” ;D

Programmatically i don’t see any difference? Record -> Replay.

The server is aware of everything. What if you’re optimizing very hardly, and you simply don’t send info about the player movement if they can’t see each other? It can have many reasons why it should be on the server. (Save the killcams to file and watch them later? It is very good for server admins=])
If you’re developing an FPS game you may want your server to take snapshots of the world (For lag compensation purposes). I took it as a starting point so basically you already have the data to work with. You just have to optimize it out and send the important data to the clients.

(Look at lag compensation:
Source Multiplayer Networking - Valve Developer Community)

It’s my approach but i’d like to hear if you have a better idea :slight_smile:

Yeah I checked, it’s peer to peer. Apparently they also supported dedicated servers at least for some versions, but I don’t think the latest (Advanced Warfare) supports dedicated servers.

The difference is that the client only records what is relevant to it.

First of all this doesn’t work because you’d have to predict when the players might see (and kill) each other in the next few seconds, which could at best be roughly approximated (but most likely not even that). Second, even if you optimise it it would mean sending more data than otherwise necessary to the client. I doubt that anybody is willing to sacrifice even a bit of network performance for the sake of killcams alone. Unless you mean sending all of this data only AFTER the kill happens, in which case:

Yes recording a demo on the server is useful anyway (CS:GO does this for every competitive game), the challenge is in how to stream the last few seconds of the replay to the client efficiently, for the purpose of showing the killcam. It may sound easy in theory but I suspect that it requires some engine-level wizardry to implement properly. I would be happy to be wrong of course, but I won’t believe it until I see a working implementation. :slight_smile:

Yeah, I’ve actually been a heavy proponent of this concept and probably posted the first implementation of this for Unreal over ten years ago. :slight_smile:

Things to keep in mind though are:

  • Data is stored to efficiently roll back entity positions to a specific point in time, not to efficiently play back player movement. Network streams (i.e. proper demo recordings) are much better suited for this.

  • Lag compensation only stores a fraction of a second of history, storing several seconds for a killcam is a rather different story.

  • Even if you wanted to go down this path (which is feasible IMO, but probably won’t be super efficient and will likely result in somewhat choppy playback), this only answers how to store the information on the server. The more challenging part is how to get this information to the client efficiently and use it to show a proper replay.

Bear in mind I’ve not looked at Unreal’s replication code for a few years, so I’m not claiming to speak with full authority here, but I think you’ve overestimating the extent to which replication code is efficient with regard to what it sends to the client. (Especially for modern games in the era of broadband)

Generally yeah, if your opponent is miles away, they probably won’t get replicated. But if someone’s close enough to kill you, then most of the time they’re also going to be within network relevancy range, and there’ll be enough data replicated on your side to reconstruct what happened. Some games (like Halo) don’t seem to have a concept of network relevancy range, and just replicate all players.

Most games don’t replicate the player’s exact camera look location (which is probably why you can’t drop into first person for other player’s in Halo’s theatre mode), but you can probably approximate it based on various factors, and use interpolation methods to get something that looks decent.

Unless you’re an MMO, periodically replicating information like position/rotation, etc, for every player isn’t going to kill you network-wise.

Also look at Halo’s theatre mode. Everyone gets recorded regardless of whether or not you’re the host.
Granted they’re likely using a peer to peer/hybrid model too, since most console games do. But there’s no way they’re accurately replicating absolutely everything that happens in the game. The state of other players is an approximation, as it always is in network games.

Thanks for all the replies guys, I got a better understanding now :slight_smile: