Skip to content

Sample Data Manifest

Andy Herbert edited this page Dec 1, 2025 · 4 revisions

Laser Games 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.

ROOT STRUCTURE

"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

MatchData

{
  "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

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
}

Events

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)
}

Event Types

  • "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]

Target Types

Targets can be identified via a Hit's FriendlyName and Abbreviation.

Determining a Player's Score, team, etc.

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 data field to get stuff like HitID, player ID, team ID.

Game States

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.

Notes

Unreal object references in data

  • All Unreal Engine paths follow the format: /Script/Package.Class'Path'
  • Player characters are referenced by their persistent level paths

Unreal HitInfo in data

  • Hit detection uses ray tracing from traceStart to traceEnd

Laser Games specifics

  • Physical materials affect hit behavior (reflective vs non-reflective)

Clone this wiki locally