The RaceRoom Racing Experience Broadcast Web Overlay allows you to create a web page that is superimposed on the in-game spectator gameplay.
- Create a basic .html file
- Include r3e.js in your page and you should be good to get started
- Put it on a publicly hosted server
- If you are looking for a basic example take a look at example-overlay.html or the API reference below.
- Download RaceRoom Racing Experience from Steam
- Go into the game's Properties in the Steam client and change "SET LAUNCH OPTIONS..." to:
- -broadcastUrl=http://your-website.com/page/
- Start RaceRoom Racing Experience
- Enter the Multiplayer server list though the game menus
- Join the server you want to spectate
- There are no requirements to own the content used on the server
Get vehicle related data based on the slotId passed.
r3e.getVehicleInfo({
'slotId': 0
}, function(vehicleInfo) {
/*
// vehicleInfo
{
"slotId": "int",
"rpm": "int",
"gear": "int",
"speed": "int", //km per h
"drsLeft": "int",
"drsTotal": "int",
"drsEnabled": "bool"
}
*/
});
Get "pit" related data based on the slotId passed.
r3e.getPitInfo({
'slotId': 0
}, function(pitInfo) {
/*
// pitInfo
{
"slotId": "int",
"inPitlane": "bool",
"isPitting": "bool",
"numPitstops": "int",
"servedMandatoryPitstop": "bool",
"tyreType": "string",
"damage": {
"engine": "int", // 0 - 100
"transmission": "int", // 0 - 100
"frontAero": "int", // 0 - 100
"rearAero": "int" // 0 - 100
}
}
*/
});
Get push to pass related data based on the slotId passed.
r3e.getPushToPassInfo({
'slotId': 0
}, function(pushToPassInfo) {
/*
// pushToPassInfo
{
"active": "bool",
"allowed": "bool",
"amountLeft": "int",
"durationTimer": "int",
"slotId": "int",
"waitTimer": "int"
}
*/
});
Get extended driver related data based on the slotId passed.
r3e.getExtendedInfo({
'slotId': 0
}, function(extendedInfo) {
/*
// extendedInfo
{
"slotId": "int",
"currentSector": "int",
"currentLapInfo": {
"valid": "bool",
"sector1": "int", // milliseconds, -1 if not set
"sector2": "int", // milliseconds, -1 if not set
"sector3": "int" // milliseconds, -1 if not set
},
"lastTenLapsInfo": [
{
"valid": "bool",
"sector1": "int", // milliseconds, -1 if not set
"sector2": "int", // milliseconds, -1 if not set
"sector3": "int" // milliseconds, -1 if not set
}
]
}
*/
});
Get driver related data based on the slotId passed.
r3e.getDriverInfo({
'slotId': 0
}, function(driverInfo) {
/*
// driverInfo
{
"name": "string",
"slotId": "int",
"portalId": "int",
"teamId": "int",
"classId": "int",
"manufacturerId": "int",
"liveryId": "int",
"performanceIndex": "int",
"mandatoryPitstopPerformed": "int",
"scoreInfo": {
"positionOverall": "int",
"positionRaceGridClass": "int",
"positionClass": "int",
"laps": "int",
"distanceTravelled": "int", //meters
"currentLapTime": "int", //milliseconds
"bestLapInfo": {
"valid": "bool",
"sector1": "int", //milliseconds, -1 if not set
"sector2": "int", //milliseconds, -1 if not set
"sector3": "int" //milliseconds, -1 if not set
},
"distanceDiff": "int", //meters
"timeDiff": "int", //milliseconds
"lapDiff": "int",
"flagInfo": {
"black": "int",
"blue": "int",
"yellow": "int",
"causedYellow": "bool"
}
}
}
*/
});
Get driver related data for all drivers on the server.
r3e.getDriversInfo(function(driversInfo) {
/*
// driversInfo
[
{
"name": "string",
"slotId": "int",
"portalId": "int",
"teamId": "int",
"classId": "int",
"manufacturerId": "int",
"liveryId": "int",
"performanceIndex": "int",
"mandatoryPitstopPerformed": "int",
"scoreInfo": {
"positionOverall": "int",
"positionRaceGridClass": "int",
"positionClass": "int",
"laps": "int",
"distanceTravelled": "int", //meters
"currentLapTime": "int", //milliseconds
"bestLapInfo": {
"valid": "bool",
"sector1": "int", //milliseconds, -1 if not set
"sector2": "int", //milliseconds, -1 if not set
"sector3": "int" //milliseconds, -1 if not set
},
"distanceDiff": "int", //meters
"timeDiff": "int", //milliseconds
"lapDiff": "int",
"flagInfo": {
"black": "int",
"blue": "int",
"yellow": "int",
"causedYellow": "bool"
}
}
},
...
]
*/
});
Get the current session data.
r3e.getSessionInfo(function(sessionInfo) {
/*
// type can be:
'Unknown',
'Practice',
'Qualify',
'Warmup',
'Race 1',
'Race 2',
'Race 3',
'Event Results'
// phase can be:
'START',
'WALKTHROUGH',
'GARAGE',
'FORMATION',
'COUNTDOWN',
'GREEN',
'CHECKERED',
'END'
// sessionInfo
{
"type": "string",
"phase": "string",
"timeTotal": "int", //seconds
"timeLeft": "int" //seconds
}
*/
});
Get the current event data.
r3e.getEventInfo(function(eventInfo) {
/*
// eventInfo
{
"serverName": "string",
"metric": "bool",
"trackId": "int",
"trackName": "string",
"layoutId": "int",
"layoutName": "string",
"length": "int",
"weatherInfo": {
"ambientTemp": "int",
"trackTemp": "int",
"windSpeed": "int",
"conditions": "string",
"forecast": "string"
}
}
*/
});
Enables or disables the in game cursor.
r3e.showCursor({
"show": "bool"
});
Set the focused driver and which camera should be used.
r3e.setCamera.nosecam({'slotId': 0})
r3e.setCamera.cockpit({'slotId': 0})
r3e.setCamera.swingman({'slotId': 0})
r3e.setCamera.onboard({'slotId': 0})
r3e.setCamera.trackside({'slotId': 0})
r3e.setCamera.onboard1({'slotId': 0})
r3e.setCamera.onboard2({'slotId': 0})
r3e.setCamera.frontCam({'slotId': 0})
r3e.setCamera.rearCam({'slotId': 0})
r3e.setCamera.flFront({'slotId': 0})
r3e.setCamera.frFront({'slotId': 0})
r3e.setCamera.rlRear({'slotId': 0})
r3e.setCamera.rrRear({'slotId': 0})
r3e.setCamera.rlFront({'slotId': 0})
r3e.setCamera.rrFront({'slotId': 0})
r3e.setCamera.exhaust({'slotId': 0})
r3e.setCamera.wing({'slotId': 0})
If you want to handle showing results running this will put you in charge of triggering the "proceed" trigger.
r3e.waitOnResults({'wait': true})
If you ran r3e.waitOnResults
you should trigger r3e.goToNextEvent
when you are done showing the results. Otherwise the game will just stay idle and not connect to the next event on the mp server.
Make sure you don't run this too soon after r3e.on.resultsUpdate
. Then you might experience connection issues as the server needs time to start a new event.
Default values when not using r3e.waitOnResults
is 30 seceonds. 20+ should be fine.
r3e.goToNextEvent()
Takes you back to multiplayer menus.
r3e.exit()
Pass r3e.on.resultsUpdate a callback which will get executed when the game client has results to show.
This only gets called at the end of a race session.
r3e.on.resultsUpdate(function(results) {
/*
// results
{
"Results": [
{
"name": "string",
"portalId": "int",
"teamId": "int",
"classId": "int",
"manufacturerId": "int",
"liveryId": "int",
"positionOverall": "int",
"positionClass": "int",
"finishStatus": "string",
"totalTime": "int", // milliseconds
"lapsBehind": "int",
"penaltyTime": "int",
"penaltyWeight": "int",
"bestLapInfo": {
"valid": "bool",
"sector1": "int", // milliseconds, -1 if not set
"sector2": "int", // milliseconds, -1 if not set
"sector3": "int" // milliseconds, -1 if not set
}
},
...
]
}
*/
});
Pass r3e.on.eventOccurred a callback which will get executed when the game client has an event to show.
r3e.on.eventOccurred(function(event) {
/*
// event
{
"slotId": "int",
// DriveThrough = 0,
// StopAndGo = 1,
// Pitstop = 2,
// Time = 3,
// Slowdown = 4,
// Disqualify = 5,
// Misc = 6,
"type": "int",
// Based on the type you can assume the reason is:
// DriveThroughPenaltyInvalid = 0,
// DriveThroughPenaltyCutTrack = 1,
// DriveThroughPenaltyPitSpeeding = 2,
// DriveThroughPenaltyFalseStart = 3,
// DriveThroughPenaltyIgnoredBlue = 4,
// DriveThroughPenaltyDrivingTooSlow = 5,
// DriveThroughPenaltyIllegallyPassedBeforeGreen = 6,
// DriveThroughPenaltyIllegallyPassedBeforeFinish = 7,
// DriveThroughPenaltyIllegallyPassedBeforePitEntrance = 8,
// DriveThroughPenaltyIgnoredSlowDown = 9,
// DriveThroughPenaltyMax = 10
// StopAndGoPenaltyInvalid = 0,
// StopAndGoPenaltyCutTrack1st = 1,
// StopAndGoPenaltyCutTrackMult = 2,
// StopAndGoPenaltyYellowFlagOvertake = 3,
// StopAndGoPenaltyMax = 4
// PitstopPenaltyInvalid = 0,
// PitstopPenaltyIgnoredPitstopWindow = 1,
// PitstopPenaltyMax = 2
// ServableTimePenaltyInvalid = 0,
// ServableTimePenaltyServedMandatoryPitstopLate = 1,
// ServableTimePenaltyIgnoredMinimumPitstopDuration = 2,
// ServableTimePenaltyMax = 3
// SlowDownPenaltyInvalid = 0,
// SlowDownPenaltyCutTrack1st = 1,
// SlowDownPenaltyCutTrackMult = 2,
// SlowDownPenaltyMax = 3
// DisqualifyPenaltyInvalid = -1,
// DisqualifyPenaltyFalseStart = 0,
// DisqualifyPenaltyPitlaneSpeeding = 1,
// DisqualifyPenaltyWrongWay = 2,
// DisqualifyPenaltyEnteringPitsUnderRed = 3,
// DisqualifyPenaltyExitingPitsUnderRed = 4,
// DisqualifyPenaltyFailedDriverChange = 5,
// DisqualifyPenaltyThreeDriveThroughsInLap = 6,
// DisqualifyPenaltyLappedFieldMultipleTimes = 7,
// DisqualifyPenaltyIgnoredDriveThroughPenalty = 8,
// DisqualifyPenaltyIgnoredStopAndGoPenalty = 9,
// DisqualifyPenaltyIgnoredPitStopPenalty = 10,
// DisqualifyPenaltyIgnoredTimePenalty = 11,
// DisqualifyPenaltyExcessiveCutting = 12,
// DisqualifyPenaltyIgnoredBlueFlag = 13,
// DisqualifyPenaltyMax = 14
// MiscClassLeaderPitting = 0
// MiscClassNewLeader = 1
// MiscClassNewFastestLap = 2
// MiscClassNewFastestSector = 3
// MiscCollision = 4
// MiscOffTrack = 5
// MiscStationary = 6
// MiscLostControl = 7
// MiscCriticalDamage = 8
// MiscPuncture = 9
"reason": "int"
}
*/
});
-
To use Chromium debugger
- Put devtools_resources.pak in Game folder
- Start with -webdev -broadcastUrl=<url>
- Go to http://localhost:8080 using Chrome
-
The overlay page will be reloaded between each session.
-
How do I fetch the livery renders based on liveryId?
- Use: http://game.raceroom.com/store/image_redirect?id=[liveryId]&size=big You can select between thumb, small, big, full sizes.
-
How can I get user information from portalId?
- Using: http://game.raceroom.com/users/[portal-id]/?json will return JSON that can be useful.
-
How can I get relevant information based on teamId, manufacturerId, liveryId, classId?
- For that you will have to include r3e-data.js which is a part of this repo. It contains data for the corresponding ids.
- When joining in race session timeleft will be incorrect.
- The CEF message loop updates at 60Hz so callbacks for retrieving data might take a while to trigger.
- Triggering too many API calls will affect game performance.
- Using Chromium 33.0.1750.58
Please visit our support forum thread.
See LICENSE.