Skip to content

Instantly share code, notes, and snippets.

@argusdusty
Created October 8, 2017 20:16
Show Gist options
  • Save argusdusty/3f6717676f99fb9824007b34c0515a6f to your computer and use it in GitHub Desktop.
Save argusdusty/3f6717676f99fb9824007b34c0515a6f to your computer and use it in GitHub Desktop.
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
Copy link

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