{ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://local.projectcars-data/schemas/udp-packets.schema.json", "title": "Project CARS UDP Parsed Packet State", "description": "Readable JSON Schema for the parsed JSON emitted by this app from Project CARS UDP packets. The game sends binary UDP packets; this schema describes the decoded JSON shape exposed by /api/state and SSE events.", "type": "object", "additionalProperties": false, "properties": { "latest": { "type": "object", "description": "Latest parsed packet by packet type number.", "additionalProperties": { "$ref": "#/$defs/parsedPacket" }, "properties": { "0": { "$ref": "#/$defs/carPhysicsPacket" }, "1": { "$ref": "#/$defs/raceDefinitionPacket" }, "2": { "$ref": "#/$defs/participantsPacket" }, "3": { "$ref": "#/$defs/timingsPacket" }, "4": { "$ref": "#/$defs/gameStatePacket" }, "5": { "$ref": "#/$defs/weatherStatePacket" }, "6": { "$ref": "#/$defs/vehicleNamesPacket" }, "7": { "$ref": "#/$defs/timeStatsPacket" }, "8": { "$ref": "#/$defs/participantVehicleNamesPacket" } } }, "recent": { "type": "array", "description": "Most recent raw parsed packets, newest first.", "items": { "$ref": "#/$defs/parsedPacket" } }, "leaderboard": { "$ref": "#/$defs/leaderboard" } }, "$defs": { "parsedPacket": { "type": "object", "additionalProperties": false, "required": ["receivedAt", "source", "base", "name", "size", "data"], "properties": { "receivedAt": { "type": "string", "format": "date-time" }, "source": { "type": "string", "examples": ["127.0.0.1:5606"] }, "base": { "$ref": "#/$defs/packetBase" }, "name": { "type": "string" }, "size": { "type": "integer", "minimum": 0 }, "data": { "type": "object" } } }, "packetBase": { "type": "object", "additionalProperties": false, "required": [ "packetNumber", "categoryPacketNumber", "partialPacketIndex", "partialPacketNumber", "packetType", "packetVersion" ], "properties": { "packetNumber": { "type": "integer", "minimum": 0 }, "categoryPacketNumber": { "type": "integer", "minimum": 0 }, "partialPacketIndex": { "type": "integer", "minimum": 0, "maximum": 255 }, "partialPacketNumber": { "type": "integer", "minimum": 0, "maximum": 255 }, "packetType": { "type": "integer", "enum": [0, 1, 2, 3, 4, 5, 6, 7, 8], "description": "0 CarPhysics, 1 RaceDefinition, 2 Participants, 3 Timings, 4 GameState, 5 WeatherState, 6 VehicleNames, 7 TimeStats, 8 ParticipantVehicleNames" }, "packetVersion": { "type": "integer", "minimum": 0, "maximum": 255 } } }, "number3": { "type": "array", "prefixItems": [{ "type": "number" }, { "type": "number" }, { "type": "number" }], "minItems": 3, "maxItems": 3 }, "number4": { "type": "array", "prefixItems": [{ "type": "number" }, { "type": "number" }, { "type": "number" }, { "type": "number" }], "minItems": 4, "maxItems": 4 }, "integer3": { "type": "array", "prefixItems": [{ "type": "integer" }, { "type": "integer" }, { "type": "integer" }], "minItems": 3, "maxItems": 3 }, "integer4": { "type": "array", "prefixItems": [{ "type": "integer" }, { "type": "integer" }, { "type": "integer" }, { "type": "integer" }], "minItems": 4, "maxItems": 4 }, "carPhysicsPacket": { "allOf": [ { "$ref": "#/$defs/parsedPacket" }, { "properties": { "base": { "allOf": [ { "$ref": "#/$defs/packetBase" }, { "properties": { "packetType": { "const": 0 } } } ] }, "data": { "$ref": "#/$defs/carPhysicsData" } } } ] }, "carPhysicsData": { "type": "object", "additionalProperties": false, "properties": { "viewedParticipantIndex": { "type": "integer" }, "input": { "type": "object", "additionalProperties": false, "properties": { "throttle": { "type": "integer" }, "brake": { "type": "integer" }, "steering": { "type": "integer" }, "clutch": { "type": "integer" } } }, "car": { "type": "object", "additionalProperties": false, "properties": { "flags": { "type": "integer" }, "oilTempCelsius": { "type": "integer" }, "oilPressureKPa": { "type": "integer" }, "waterTempCelsius": { "type": "integer" }, "waterPressureKpa": { "type": "integer" }, "fuelPressureKpa": { "type": "integer" }, "fuelCapacity": { "type": "integer" }, "brake": { "type": "integer" }, "throttle": { "type": "integer" }, "clutch": { "type": "integer" }, "fuelLevel": { "type": "number" }, "speedMps": { "type": "number" }, "speedKph": { "type": "number" }, "rpm": { "type": "integer" }, "maxRpm": { "type": "integer" }, "steering": { "type": "integer" }, "gear": { "type": "string" }, "numGears": { "type": "integer" }, "boostAmount": { "type": "integer" }, "crashState": { "type": "integer" }, "odometerKM": { "type": "number" }, "brakeBias": { "type": "integer" } } }, "vectors": { "type": "object", "additionalProperties": false, "properties": { "orientation": { "$ref": "#/$defs/number3" }, "localVelocity": { "$ref": "#/$defs/number3" }, "worldVelocity": { "$ref": "#/$defs/number3" }, "angularVelocity": { "$ref": "#/$defs/number3" }, "localAcceleration": { "$ref": "#/$defs/number3" }, "worldAcceleration": { "$ref": "#/$defs/number3" }, "extentsCentre": { "$ref": "#/$defs/number3" }, "fullPosition": { "$ref": "#/$defs/number3" } } }, "tyres": { "type": "object", "additionalProperties": false, "properties": { "flags": { "$ref": "#/$defs/integer4" }, "terrain": { "$ref": "#/$defs/integer4" }, "y": { "$ref": "#/$defs/number4" }, "rps": { "$ref": "#/$defs/number4" }, "temp": { "$ref": "#/$defs/integer4" }, "heightAboveGround": { "$ref": "#/$defs/number4" }, "wear": { "$ref": "#/$defs/integer4" }, "brakeTempCelsius": { "$ref": "#/$defs/integer4" }, "treadTemp": { "$ref": "#/$defs/integer4" }, "layerTemp": { "$ref": "#/$defs/integer4" }, "carcassTemp": { "$ref": "#/$defs/integer4" }, "rimTemp": { "$ref": "#/$defs/integer4" }, "internalAirTemp": { "$ref": "#/$defs/integer4" }, "tempLeft": { "$ref": "#/$defs/integer4" }, "tempCenter": { "$ref": "#/$defs/integer4" }, "tempRight": { "$ref": "#/$defs/integer4" }, "wheelLocalPositionY": { "$ref": "#/$defs/number4" }, "rideHeight": { "$ref": "#/$defs/number4" }, "suspensionTravel": { "$ref": "#/$defs/number4" }, "suspensionVelocity": { "$ref": "#/$defs/number4" }, "suspensionRideHeight": { "$ref": "#/$defs/integer4" }, "airPressure": { "$ref": "#/$defs/integer4" }, "compound": { "type": "array", "items": { "type": "string" }, "minItems": 4, "maxItems": 4 } } }, "engine": { "type": "object", "additionalProperties": false, "properties": { "speed": { "type": "number" }, "torque": { "type": "number" }, "turboBoostPressure": { "type": "number" }, "wings": { "type": "array", "items": { "type": "integer" }, "minItems": 2, "maxItems": 2 }, "handBrake": { "type": "integer" } } }, "damage": { "type": "object", "additionalProperties": false, "properties": { "aero": { "type": "integer" }, "engine": { "type": "integer" }, "brake": { "$ref": "#/$defs/integer4" }, "suspension": { "$ref": "#/$defs/integer4" } } }, "hardware": { "type": "object", "additionalProperties": false, "properties": { "joyPad0": { "type": "integer" }, "dPad": { "type": "integer" } } } } }, "raceDefinitionPacket": { "allOf": [ { "$ref": "#/$defs/parsedPacket" }, { "properties": { "base": { "allOf": [ { "$ref": "#/$defs/packetBase" }, { "properties": { "packetType": { "const": 1 } } } ] }, "data": { "$ref": "#/$defs/raceDefinitionData" } } } ] }, "raceDefinitionData": { "type": "object", "additionalProperties": false, "properties": { "worldFastestLapTime": { "type": "number" }, "personalFastestLapTime": { "type": "number" }, "personalFastestSectors": { "$ref": "#/$defs/number3" }, "worldFastestSectors": { "$ref": "#/$defs/number3" }, "trackLength": { "type": "number" }, "trackLocation": { "type": "string" }, "trackVariation": { "type": "string" }, "translatedTrackLocation": { "type": "string" }, "translatedTrackVariation": { "type": "string" }, "lapsTimeInEvent": { "type": "integer" }, "enforcedPitStopLap": { "type": "integer" } } }, "participantsPacket": { "allOf": [ { "$ref": "#/$defs/parsedPacket" }, { "properties": { "base": { "allOf": [ { "$ref": "#/$defs/packetBase" }, { "properties": { "packetType": { "const": 2 } } } ] }, "data": { "$ref": "#/$defs/participantsData" } } } ] }, "participantsData": { "type": "object", "additionalProperties": false, "properties": { "participantsChangedTimestamp": { "type": "integer" }, "participants": { "type": "array", "items": { "$ref": "#/$defs/participantName" } } } }, "participantName": { "type": "object", "additionalProperties": false, "properties": { "slot": { "type": "integer" }, "localSlot": { "type": "integer" }, "partialPacketIndex": { "type": "integer" }, "name": { "type": "string" }, "nationality": { "type": "integer" }, "index": { "type": "integer" } } }, "timingsPacket": { "allOf": [ { "$ref": "#/$defs/parsedPacket" }, { "properties": { "base": { "allOf": [ { "$ref": "#/$defs/packetBase" }, { "properties": { "packetType": { "const": 3 } } } ] }, "data": { "$ref": "#/$defs/timingsData" } } } ] }, "timingsData": { "type": "object", "additionalProperties": false, "properties": { "numParticipants": { "type": "integer" }, "participantsChangedTimestamp": { "type": "integer" }, "eventTimeRemaining": { "type": "number" }, "splitTimeAhead": { "type": "number" }, "splitTimeBehind": { "type": "number" }, "splitTime": { "type": "number" }, "localParticipantIndex": { "type": "integer" }, "participants": { "type": "array", "items": { "$ref": "#/$defs/timingParticipant" } } } }, "timingParticipant": { "type": "object", "additionalProperties": false, "properties": { "slot": { "type": "integer" }, "worldPosition": { "$ref": "#/$defs/integer3" }, "orientation": { "$ref": "#/$defs/integer3" }, "currentLapDistance": { "type": "integer" }, "racePosition": { "type": "integer" }, "active": { "type": "boolean" }, "sector": { "type": "integer" }, "sectorRaw": { "type": "integer" }, "sectorExtraPrecision": { "type": "integer" }, "highestFlag": { "type": "integer" }, "pitModeSchedule": { "type": "integer" }, "carIndex": { "type": "integer" }, "raceState": { "type": "integer" }, "currentLap": { "type": "integer" }, "currentTime": { "type": "number" }, "currentSectorTime": { "type": "number" }, "mpParticipantIndex": { "type": "integer" } } }, "gameStatePacket": { "allOf": [ { "$ref": "#/$defs/parsedPacket" }, { "properties": { "base": { "allOf": [ { "$ref": "#/$defs/packetBase" }, { "properties": { "packetType": { "const": 4 } } } ] }, "data": { "$ref": "#/$defs/gameStateData" } } } ] }, "gameStateData": { "type": "object", "additionalProperties": false, "properties": { "buildVersionNumber": { "type": "integer" }, "gameStateRaw": { "type": "integer" }, "gameState": { "type": "integer" }, "gameStateName": { "type": ["string", "null"] }, "sessionState": { "type": "integer" }, "sessionStateName": { "type": ["string", "null"] }, "ambientTemperature": { "type": "integer" }, "trackTemperature": { "type": "integer" }, "rainDensity": { "type": "integer" }, "snowDensity": { "type": "integer" }, "windSpeed": { "type": "integer" }, "windDirectionX": { "type": "integer" }, "windDirectionY": { "type": "integer" } } }, "weatherStatePacket": { "description": "Packet type 5 is recognized by the app but currently emitted with the generic unimplemented parser payload.", "allOf": [ { "$ref": "#/$defs/parsedPacket" }, { "properties": { "base": { "allOf": [ { "$ref": "#/$defs/packetBase" }, { "properties": { "packetType": { "const": 5 } } } ] }, "data": { "$ref": "#/$defs/unimplementedPacketData" } } } ] }, "vehicleNamesPacket": { "description": "Packet type 6 is recognized by the app but currently emitted with the generic unimplemented parser payload. Participant vehicle/class names are decoded from packet type 8.", "allOf": [ { "$ref": "#/$defs/parsedPacket" }, { "properties": { "base": { "allOf": [ { "$ref": "#/$defs/packetBase" }, { "properties": { "packetType": { "const": 6 } } } ] }, "data": { "$ref": "#/$defs/unimplementedPacketData" } } } ] }, "unimplementedPacketData": { "type": "object", "additionalProperties": false, "required": ["rawPacketType", "message"], "properties": { "rawPacketType": { "type": "integer", "enum": [5, 6] }, "message": { "type": "string" } } }, "timeStatsPacket": { "allOf": [ { "$ref": "#/$defs/parsedPacket" }, { "properties": { "base": { "allOf": [ { "$ref": "#/$defs/packetBase" }, { "properties": { "packetType": { "const": 7 } } } ] }, "data": { "$ref": "#/$defs/timeStatsData" } } } ] }, "timeStatsData": { "type": "object", "additionalProperties": false, "properties": { "participantsChangedTimestamp": { "type": "integer" }, "participants": { "type": "array", "items": { "$ref": "#/$defs/timeStatsParticipant" } } } }, "timeStatsParticipant": { "type": "object", "additionalProperties": false, "properties": { "slot": { "type": "integer" }, "fastestLapTime": { "type": "number" }, "lastLapTime": { "type": "number" }, "lastSectorTime": { "type": "number" }, "fastestSectors": { "$ref": "#/$defs/number3" }, "participantOnlineRep": { "type": "integer" }, "mpParticipantIndex": { "type": "integer" } } }, "participantVehicleNamesPacket": { "allOf": [ { "$ref": "#/$defs/parsedPacket" }, { "properties": { "base": { "allOf": [ { "$ref": "#/$defs/packetBase" }, { "properties": { "packetType": { "const": 8 } } } ] }, "data": { "$ref": "#/$defs/participantVehicleNamesData" } } } ] }, "participantVehicleNamesData": { "type": "object", "additionalProperties": false, "properties": { "vehicles": { "type": "array", "items": { "$ref": "#/$defs/vehicleInfo" } }, "classes": { "type": "array", "items": { "$ref": "#/$defs/classInfo" } } } }, "vehicleInfo": { "type": "object", "additionalProperties": false, "properties": { "index": { "type": "integer" }, "class": { "type": "integer" }, "name": { "type": "string" } } }, "classInfo": { "type": "object", "additionalProperties": false, "properties": { "classIndex": { "type": "integer" }, "name": { "type": "string" } } }, "leaderboard": { "type": "object", "additionalProperties": false, "properties": { "rows": { "type": "array", "items": { "$ref": "#/$defs/leaderboardRow" } }, "note": { "type": "string" }, "session": { "type": "object", "additionalProperties": false, "properties": { "trackName": { "type": "string" }, "sessionType": { "type": "string" }, "timeLeft": { "type": ["number", "null"] }, "weather": { "type": "string" }, "lastUpdate": { "type": ["string", "null"], "format": "date-time" } } } } }, "stateEvent": { "type": "object", "additionalProperties": false, "required": ["latest", "recent", "leaderboard"], "properties": { "latest": { "type": "object", "description": "Latest parsed packet by packet type number.", "additionalProperties": { "$ref": "#/$defs/parsedPacket" } }, "recent": { "type": "array", "items": { "$ref": "#/$defs/parsedPacket" } }, "leaderboard": { "$ref": "#/$defs/leaderboard" } } }, "packetEvent": { "type": "object", "additionalProperties": false, "required": ["packet", "state", "leaderboard"], "properties": { "packet": { "$ref": "#/$defs/parsedPacket" }, "state": { "type": "object", "additionalProperties": false, "required": ["latest", "recent"], "properties": { "latest": { "type": "object", "additionalProperties": { "$ref": "#/$defs/parsedPacket" } }, "recent": { "type": "array", "items": { "$ref": "#/$defs/parsedPacket" } } } }, "leaderboard": { "$ref": "#/$defs/leaderboard" } } }, "sharedMemoryIngestRequest": { "type": "object", "additionalProperties": true, "required": ["packets"], "properties": { "source": { "type": "string", "examples": ["shared-memory"] }, "sequence": { "type": "integer", "minimum": 0 }, "capturedAt": { "type": "string", "format": "date-time" }, "packets": { "type": "array", "items": { "$ref": "#/$defs/parsedPacket" } } } }, "ingestAccepted": { "type": "object", "additionalProperties": false, "required": ["ok", "packets"], "properties": { "ok": { "type": "boolean", "const": true }, "packets": { "type": "integer", "minimum": 0 } } }, "errorResponse": { "type": "object", "additionalProperties": false, "required": ["ok", "error"], "properties": { "ok": { "type": "boolean", "const": false }, "error": { "type": "string" } } }, "leaderboardRow": { "type": "object", "additionalProperties": true, "properties": { "id": { "type": ["integer", "string"] }, "slot": { "type": ["integer", "string"] }, "sortPosition": { "type": "number" }, "position": { "type": ["integer", "null"] }, "positionChange": { "type": ["object", "null"], "additionalProperties": false, "properties": { "direction": { "type": "string", "enum": ["up", "down"] }, "places": { "type": "integer", "minimum": 1 }, "previousPosition": { "type": "integer" }, "currentPosition": { "type": "integer" }, "changedAt": { "type": "string", "format": "date-time" } } }, "active": { "type": ["boolean", "null"] }, "status": { "type": ["object", "null"], "additionalProperties": false, "properties": { "code": { "type": "string", "enum": ["unknown", "dnf", "dsq", "finished", "waiting", "drive_through", "pit_entry", "pit_stop", "pit_exit", "garage", "garage_exit", "invalidated", "blue_flag", "inactive", "racing"] }, "label": { "type": "string" }, "tone": { "type": "string", "enum": ["good", "warn"] } } }, "driver": { "type": "string" }, "nationality": { "type": ["object", "null"], "additionalProperties": false, "properties": { "code": { "type": "string" }, "country": { "type": "string" }, "source": { "type": "string", "enum": ["udp", "override"] } } }, "vehicle": { "type": ["string", "null"] }, "vehicleShortName": { "type": ["string", "null"] }, "lap": { "type": ["integer", "null"] }, "sector": { "type": ["integer", "null"] }, "sectorRaw": { "type": ["integer", "null"] }, "sectorExtraPrecision": { "type": ["integer", "null"] }, "currentTime": { "type": ["number", "null"] }, "currentSectorTime": { "type": ["number", "null"] }, "checkpointSplit": { "$ref": "#/$defs/sectorSplit" }, "sectorTimeSplit": { "$ref": "#/$defs/sectorSplit" }, "lastLapTime": { "type": ["number", "null"] }, "latestLapSplit": { "$ref": "#/$defs/lapSplit" }, "fastestLapTime": { "type": ["number", "null"] }, "bestLapSplit": { "$ref": "#/$defs/lapSplit" }, "fastestSectors": { "$ref": "#/$defs/number3" }, "pitModeSchedule": { "type": ["integer", "null"] }, "pit": { "type": ["object", "null"], "additionalProperties": false, "properties": { "raw": { "type": "integer" }, "pitMode": { "type": "integer" }, "pitSchedule": { "type": "integer" }, "phase": { "type": ["string", "null"], "enum": ["Pit entry", "Pit stop", "Pit exit", "Serving drive-through", "Garage", "Garage exit", null] }, "penalty": { "type": ["string", "null"], "enum": ["drive-through", null] } } }, "highestFlag": { "type": ["integer", "null"] }, "flag": { "type": ["object", "null"], "additionalProperties": false, "properties": { "raw": { "type": "integer" }, "colour": { "type": "integer" }, "reason": { "type": "integer" }, "observed": { "type": ["string", "null"], "enum": ["blue", "black", "checkered", null] } } }, "raceState": { "type": ["integer", "null"] }, "raceStateCode": { "type": ["integer", "null"] }, "invalidatedLap": { "type": ["boolean", "null"] }, "carIndex": { "type": ["integer", "null"] }, "nationalityRaw": { "type": ["integer", "null"] } } }, "lapSplit": { "type": ["object", "null"], "additionalProperties": false, "properties": { "comparedTo": { "type": "string" }, "time": { "type": "number" }, "referenceTime": { "type": "number" }, "delta": { "type": "number" } } }, "sectorSplit": { "type": ["object", "null"], "additionalProperties": false, "properties": { "source": { "type": ["string", "null"], "enum": ["checkpoint", "timeStats", null] }, "basis": { "type": ["string", "null"], "enum": ["raceOrder", "personalBestSector", null] }, "checkpoint": { "type": "string" }, "comparedTo": { "type": ["string", "null"] }, "time": { "type": "number" }, "referenceTime": { "type": ["number", "null"] }, "delta": { "type": ["number", "null"] } } } } }