-
Notifications
You must be signed in to change notification settings - Fork 0
Sample Data Manifest
This document describes the structure of JSON data for a laser tag video game match. The data format appears to be from an Unreal Engine-based laser tag game system.
"SessionInfo": Unreal Engine session info, including the server and map name
"MatchData": Hits and events occurring in the match
"TeamData": Per-team data such as team name, color.
"PlayerData": Per-player data such as player name
{
"gameTypeName": string, // Name of the game mode (e.g., "The Challenge")
"bFreeForAll": boolean, // Whether the game is free-for-all or team-based
"teamData": object, // Team information (empty in this sample)
"hits": array, // Array of hit events during the match
"events": array // Array of game events (scores, team changes, etc.)
}
Hits track info regarding a hit between a player and a Taggable.
{
"hitComponent": string, // Unreal Engine component path of the hit target
"shotActor": string, // Actor that fired the shot ("None" if not applicable)
"instigator": string, // Player character who fired the shot (UE path)
"basePointValue": number, // Base score value for the hit (500 or 600)
"pointMultiplier": number, // Multiplier applied to base points (1 or 2)
"distance": number, // Distance to target in game units
"distanceMultiplier": number, // Distance-based scoring multiplier (~0.01)
"hitMatchState": {
"roundNum": number, // Current round number
"roundTime": number, // Time elapsed in current round (seconds)
"gameTime": number, // Total game time elapsed (seconds)
"state": string // Current game state (often empty)
},
"hitResult": {
"faceIndex": number, // Face index of hit geometry (-1 if not applicable)
"time": number, // Time of impact calculation
"distance": number, // Precise distance measurement
"location": {x, y, z}, // 3D world position where hit was detected
"impactPoint": {x, y, z}, // 3D world position of actual impact
"normal": {x, y, z}, // Surface normal vector at hit location
"impactNormal": {x, y, z}, // Surface normal vector at impact point
"traceStart": {x, y, z}, // 3D starting position of the laser trace
"traceEnd": {x, y, z}, // 3D ending position of the laser trace
"penetrationDepth": number, // How deep the hit penetrated (usually 0)
"myItem": number, // Item index for shooter (-1 if not applicable)
"item": number, // Item index for target (-1 if not applicable)
"elementIndex": number, // Element index in hit object
"bBlockingHit": boolean, // Whether this hit blocked further tracing
"bStartPenetrating": boolean, // Whether trace started inside the object
"physMaterial": string, // Physical material of hit surface (UE path)
"hitObjectHandle": {
"referenceObject": string // Reference to the hit object blueprint
},
"component": string, // Specific component that was hit (UE path)
"boneName": string, // Bone name if hit on skeletal mesh ("None")
"myBoneName": string // Shooter's bone name ("None")
},
"hitTags": array, // Additional tags for the hit (usually empty)
"instigatorStateId": {
"index": number // State index of the player who shot
},
"hitStateId": {
"index": number // State index of hit target (-1 for objects)
},
"hitIndex": number // Sequential index of this hit in the match
"hitFriendlyName": string // A user-viewable name for what was hit
"hitAbbreviation": string // An abbreviation of what was hit
}
Game events track various match activities.
{
"eventName": string, // Type of event (see Event Types below)
"matchState": {
"roundNum": number, // Round number when event occurred
"roundTime": number, // Round time when event occurred
"gameTime": number, // Game time when event occurred
"state": string // Game state ("PRE_MATCH", "", etc.)
},
"dataKeys": array, // Array of data field names
"dataValues": array, // Array of corresponding data values
"data": object // Additional event data (usually empty)
}
-
"TeamChange": Player switched teams
- dataKeys: ["PlayerID", "old", "new"]
- dataValues: [player ID, player's old team ID, player's new team ID]
-
"PlayerDataReset": Player statistics reset
- dataKeys: ["PlayerID", "StatName"]
- dataValues: [player ID, previous stat value]
-
"HitEvent": Hit was registered
- dataKeys: ["ID"]
- dataValues: [hit index]
-
"PlayerScore": Player's score changed
- dataKeys: ["PlayerID", "HitID", "oldScore", "newScore"]
- dataValues: [player ID, hit ID, previous score for player, new score for player]
-
"TeamPointsChange": Team score changed
- dataKeys: ["ID", "HitID", "old", "new"]
- dataValues: [team ID, hit ID, previous score for team, new score for team]
Targets can be identified via a Hit's FriendlyName and Abbreviation.
The player score and team, as well as other stats, must be dynamically determined from a given time in the match.
The LaserTagDataProcessor class (dataProcessor.js) has a function getPointInfoForHit(hitIndex), which given a hit index, searches for events with a matching HitID, and returns an object containing the updated scores and deltas for any team and any player (mapped ID to score value) with a change in score from the hit.
The LaserTagDataProcessor class similarly has a function getPlayerTeam(playerID, endTime) which given a playerID, will find the player's team ID up to endTime.
For other dynamic data throughout a match, the general process is:
- get a start and end time which you want to view the data in
- filter match events to include only events within the start and end time, and further depending on what data you're interested in
- read from the data's
datafield to get stuff like HitID, player ID, team ID.
Note: game states in current sample data are bugged.
- "PRE_MATCH": Before the match officially begins
- "COUNTDOWN": Time between PRE_MATCH and INGAME
- "INGAME": Normal gameplay
- "POST_MATCH": after INGAME
- Other states exist in the game. This documentation will be updated when states are properly recorded.
- All Unreal Engine paths follow the format: /Script/Package.Class'Path'
- Player characters are referenced by their persistent level paths
- Hit detection uses ray tracing from traceStart to traceEnd
- Physical materials affect hit behavior (reflective vs non-reflective)