Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Converts Rocket League rattletrap replay JSON data into only rigid body updates in an easier-to-use format
# Filters rattletrap replay JSON data into only rigid body updates in an easier-to-use format
def parseRBupdates(data):
playerNameMap = dict() # real_actor_id -> player_name
ballId = 0 # actor_id int - set later in the code (hopefully)
actorIdMap = dict() # temp_actor_id -> real_actor_id
rigidBodyUpdates = []
for frame_number, frame in enumerate(data['content']['frames']):
for i, replication in enumerate(frame['replications']):
actorId = replication['actor_id']['value']
if 'spawned_replication_value' in replication['value']: # Spawned something
spawn = replication['value']['spawned_replication_value']
if spawn['class_name'] == 'TAGame.Ball_TA': # Spawned a ball
ballId = actorId
for update in replication['value'].get('updated_replication_value', []):
if update['name'] == 'Engine.PlayerReplicationInfo:PlayerName': # Player name set
playerName = update['value']['string_attribute_value']
playerNameMap[actorId] = playerName
elif update['name'] == 'Engine.Pawn:PlayerReplicationInfo': # Player id set
# Unsure what to do if the value's 'flag' attribute is false
actorIdMap[actorId] = update['value']['flagged_int_attribute_value']['int']
elif update['name'] == 'TAGame.RBActor_TA:ReplicatedRBState': # Rigid Body Update
RBUpdate = {'frame': frame_number, 'time': frame['time'], 'rigid_body_update': update['value']['rigid_body_state_attribute_value']}
RBUpdate['is_ball'] = actorId == ballId
if not RBUpdate['is_ball']:
RBUpdate['id'] = actorIdMap[actorId]
rigidBodyUpdates.append(RBUpdate)
return {'player_name_map': playerNameMap, 'rigid_body_updates': rigidBodyUpdates}
# Example of how to use this
def test():
import json
data = json.load(open('replay.json'))
RBupdates = parseRBupdates(data)
json.dump(RBupdates, open('replay_rbupdates.json', 'w'))
@danielmoniz

This comment has been minimized.

Copy link

danielmoniz commented Sep 5, 2019

First of all, thank you! I've been confused about actor_id and some of the other keys, but getting basic position/orientation information was most of what I needed.

The keys in the data object have been modified in more recent versions. They are mostly simplified/shortened. Additionally, there is now a body key in between content and frames.

Here is an update to work as of Rattletrap v9.0.1:

# Filters rattletrap replay JSON data into only rigid body updates in an easier-to-use format
def parseRBupdates(data):
    playerNameMap = dict()  # real_actor_id -> player_name
    ballId = 0  # actor_id int - set later in the code (hopefully)
    actorIdMap = dict()  # temp_actor_id -> real_actor_id
    rigidBodyUpdates = []
    for frame_number, frame in enumerate(data['content']['body']['frames']):
        for i, replication in enumerate(frame['replications']):
            actorId = replication['actor_id']['value']
            if 'spawned' in replication['value']:  # Spawned something
                spawn = replication['value']['spawned']
                if spawn['class_name'] == 'TAGame.Ball_TA':  # Spawned a ball
                    ballId = actorId
            for update in replication['value'].get('updated', []):
                if update['name'] == 'Engine.PlayerReplicationInfo:PlayerName':  # Player name set
                    playerName = update['value']['string']
                    playerNameMap[actorId] = playerName
                elif update['name'] == 'Engine.Pawn:PlayerReplicationInfo':  # Player id set
                    # Unsure what to do if the value's 'flag' attribute is false
                    actorIdMap[actorId] = update['value']['flagged_int']['int']
                elif update['name'] == 'TAGame.RBActor_TA:ReplicatedRBState':  # Rigid Body Update
                    RBUpdate = {
                        'frame': frame_number, 'time': frame['time'], 'rigid_body_update': update['value']['rigid_body_state']}
                    RBUpdate['is_ball'] = actorId == ballId
                    if not RBUpdate['is_ball']:
                        RBUpdate['id'] = actorIdMap[actorId]
                    rigidBodyUpdates.append(RBUpdate)
    return {'player_name_map': playerNameMap, 'rigid_body_updates': rigidBodyUpdates}

# Example of how to use this
def test():
	import json
	data = json.load(open('replay.json'))
	RBupdates = parseRBupdates(data)
	json.dump(RBupdates, open('replay_rbupdates.json', 'w'))

Cheers!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.