enzanki-ars / rocket-league-replay-analysis

UNMAINTAINED - Creating videos for Analyzing Rocket League Replays (https://gitlab.com/enzanki_ars/rocket-league-replay-analysis)
https://gitlab.com/enzanki_ars/rocket-league-replay-analysis
GNU Affero General Public License v3.0
24 stars 2 forks source link

Add boost data. #15

Closed enzanki-ars closed 6 years ago

enzanki-ars commented 7 years ago

There is boost data in the replay file, but it seem hard to parse. Every so often the value is explicitly updated, but does not seem to be updated on use or pickup.

In terms of the bounty:

jjbott commented 6 years ago

I'm about 4% sure that:

Then you can calculate the boost at any point in time based on how when it is picked up and when it is used. You can use the values in the replay to double check your accuracy.

jeromepl commented 6 years ago

I have worked on something similar from Rattletrap replay files in the past and did indeed do exactly what @jjbott listed. I had found that the rate at which boost is consumed is almost exactly 33.33% per second (or 100 boost to 0 in 3 seconds, or 85/255 per second if stored in a byte).

enzanki-ars commented 6 years ago

Thank you for the tips @jjbott and @jeromepl. The only problem is that either I am missing something obvious, or I am missing the value of boost pickups, who picks it up, and when usage starts/stops. I see something referred to as "BoostPickup", but I don't see a way to tie it to a player...

There is something obvious I am missing, but I just can't figure it out.

jjbott commented 6 years ago

The value of the boost pickups isn't in the replays. Somehow we'd need to figure out that, for example, "UtopiaStadium_Snow_p.TheWorld:PersistentLevel.VehiclePickup_Boost_TA_21" is 100 boost (maybe, I made that value up).

Pretty sure "TAGame.VehiclePickup_TA:ReplicatedPickupData" shows when a boost was picked up, and by who. The number in the data is the id if the car that picked it up. I should make that more obvious in the json...

Boost on/off is "TAGame.CarComponent_TA:ReplicatedActive". If the value is odd, boost is on. I've got that logic here, although I suspect that's currently dead code for some reason: https://github.com/jjbott/RocketLeagueReplayParser/blob/9314b551550a3ed24cd3cd3835eb028a7534358a/RocketLeagueReplayParser/Serializers/ActorStateJsonConverter.cs#L72

jeromepl commented 6 years ago

I would need to do more research on how Rattletrap and RocketLeagueReplayParser compare, but when using Rattletrap, I was able to attach a Archetypes.CarComponents.CarComponent_Boost actor (along with its actor ID) to a Player. From there, when a replication matched the boost actor ID and that the value name was TAGame.CarComponent_Boost_TA:ReplicatedBoostAmount, the byte value can be used to update the boost amount. I had found that this happens on boost pickup. On top of that, boost needs to decrease based on the consumption rate, and for that you need to know if a player is currently boosting. As @jjbott said, this can easily be found by checking if TAGame.CarComponent_TA:ReplicatedActive is odd. Once you got that, you can decrease the boost amount by the consumption rate multiplied by the delta time.

The portion of code I had for this was the following (inside a loop going over the replications in each frame of the replay file):

if (player.boostActorID && player.boostActorID === replication.actor_id.value) {
    replicationValue.forEach((updatedReplicationValue) => {
        if (updatedReplicationValue.name === 'TAGame.CarComponent_Boost_TA:ReplicatedBoostAmount') {
            player.setBoostValue(updatedReplicationValue.value.byte_attribute_value);
        } else {
            // Since boost value is not updated in every frame while a player is boosting, manually update its value
            // based on whether or not the player is currently boosting.
            player.updateBoostValue(delta);
        }

        if (updatedReplicationValue.name === 'TAGame.CarComponent_TA:ReplicatedActive') {
            // Odd values means the player started boosting, even values means he/she stopped boosting or ran out of boost
            player.boosting = updatedReplicationValue.value.byte_attribute_value % 2 === 1;
        }
    });
}

Inside Player.updateBoostValue(deltaTime) I have the following (where BOOST_CONSUMPTION_RATE = 85):

updateBoostValue(delta) {
    if (this.boosting) {
        this.boostValue -= delta * BOOST_CONSUMPTION_RATE;
        this.boostValue = Math.max(0, this.boostValue);
    }
}
enzanki-ars commented 6 years ago

@jeromepl Thanks so much. That should help a bunch, and I should be able to translate that very easily as Rattletrap and RocketLeagueReplayParser are very similar.

I have some other things that I need to fix first, but boost data should be added in very shortly then. Thank you so much for your assistance.

enzanki-ars commented 6 years ago

Based on what I see here, I will remove the bounty tag.

@jeromepl feel free to PM on Reddit at /u/enzanki_ars or on twitter @enzanki_ars if you are interested in a couple of crates. I know that they are useless without keys, but I don't play much competitive/online to get drops, so I have absolutely nothing else.

jeromepl commented 6 years ago

Glad I could help! Don't worry about the crates, I don't care about them too much either ;) If I find the time later next week, I might take a deeper look at this project and try contributing! Keep up the good work!

enzanki-ars commented 6 years ago

Thanks again for the help @jjbott and @jeromepl! I was able to add in the boost data, and add a boost comparison render.