API Reference

This page documents the two static code surfaces a developer touches when reskinning Traffic Overtaker into their own game: TO_API (all persistence, currency, vehicle ownership, high scores, audio/quality settings, and scene navigation) and TO_Events (the static event bus). Both live under Assets/TO/Scripts/ and are written to be called directly from your own UI scripts, gameplay code, or custom managers without needing a reference to a manager instance. Every member listed here was read verbatim from the source (Assets/TO/Scripts/TO_API.cs and Assets/TO/Scripts/Misc/TO_Events.cs) — signatures match the shipping code exactly.

Both classes follow the project convention: the TO_ prefix, the BoneCrackerGames namespace, and all members are static, so you call them by type name (TO_API.GetCurrency(), TO_Events.OnRaceStarted += ...). Other TO scripts (also in BoneCrackerGames) see them with no using directive; from a script of your own outside that namespace, add using BoneCrackerGames; (or fully-qualify the type). There are no assembly definitions, so everything shares the default Assembly-CSharp. For the bigger picture of how these classes fit into the manager/singleton layer, see 04_SystemArchitecture.md.

TO_API — persistence and navigation

TO_API is the single entry point for everything that survives between play sessions. It is a thin, static wrapper over Unity's PlayerPrefs (plus the TO_PlayerPrefsX helper for booleans), so there is no instance to find and no component to add — you call the static methods from anywhere. Several setters fire TO_Events.Event_OnOptionsChanged() after writing, so UI that listens to that event refreshes automatically. The currency setters fire TO_API.OnPlayerMoneyChanged for the same reason.

A note on persistence boundaries: most getters/setters read and write a PlayerPrefs key, but GetControllerType() reads the live RCCP_Settings.Instance.mobileController value (not a PlayerPrefs key). Quality is the reverse — SetQuality() / GetQuality() both persist to the QualityLevel PlayerPrefs key and mirror it to Unity's QualitySettings (so GetQuality() returns the saved level, falling back to QualitySettings.GetQualityLevel() only on first launch). Keep this in mind when you reset or migrate save data.

Events on TO_API

Member Signature Fires when
OnPlayerMoneyChanged static event onPlayerMoneyChanged (delegate void onPlayerMoneyChanged()) AddCurrency or ConsumeCurrency runs
OnPlayerNameChanged static event onPlayerNameChanged (delegate void onPlayerNameChanged()) SetPlayerName runs

Currency and player identity

Method Returns Purpose
GetCurrency() int Reads the Currency key (default 0).
AddCurrency(int add) void Adds add to currency, then fires OnPlayerMoneyChanged.
ConsumeCurrency(int consume) void Subtracts consume from currency, then fires OnPlayerMoneyChanged.
GetPlayerName() string Reads the PlayerName key (default "New Player").
SetPlayerName(string newPlayerName) void Saves the name, calls SetTotalPlayedTime(), fires OnPlayerNameChanged.
IsFirstGameplay() bool true when total played time is <= 1 second.
GetTotalPlayedTime() float Reads TotalPlayedTime (default 0), in seconds.
SetTotalPlayedTime() void Adds Time.timeSinceLevelLoad to the stored total.

Vehicle ownership

Ownership is stored per vehicle as a {VehicleName}Owned key, where VehicleName is the prefab name of the entry in TO_PlayerCars. The index passed to these methods is the index into that roster. See 06_PlayerVehicles.md for the roster itself.

Method Returns Purpose
UnlockedVehicles() int[] Indexes of every vehicle whose Owned key exists.
OwnedVehicle(int index) bool true if that vehicle's Owned key exists.
UnlockVehicle(int index) void Sets the Owned key for that vehicle.
LockVehicle(int index) void Deletes the Owned key for that vehicle.
UnlockAllVehicles() void Sets the Owned key for every roster entry.

High scores

Method Returns Purpose
GetHighScores() int[] A one-element array holding the bestScoreOvertake value (single-mode game).

Audio, graphics, and controller settings

Method Returns Notes
GetAudioVolume() float Reads AudioVolume; default TO_Settings.Instance.defaultAudioVolume.
SetAudioVolume(float volume) void Sets AudioListener.volume, writes the key, fires OnOptionsChanged.
GetMusicVolume() float Reads MusicVolume; default TO_Settings.Instance.defaultMusicVolume.
SetMusicVolume(float volume) void Writes the key, fires OnOptionsChanged.
GetDrawDistance() float Reads DrawDistance; default TO_Settings.Instance.defaultDrawDistance.
SetDrawDistance(float distance) void Writes the key, fires OnOptionsChanged.
GetShadows() bool Reads Shadows via TO_PlayerPrefsX; default TO_Settings.Instance.defaultShadows.
SetShadows() void Toggles Shadows, fires OnOptionsChanged.
GetPP() bool Reads PP via TO_PlayerPrefsX; default TO_Settings.Instance.defaultPP.
SetPP() void Toggles PP (post-processing), fires OnOptionsChanged.
GetQuality() int Returns PlayerPrefs.GetInt("QualityLevel", QualitySettings.GetQualityLevel()) — the saved level, or the live level on first launch.
SetQuality(int qualityIndex) void Writes the QualityLevel key, calls QualitySettings.SetQualityLevel, fires OnOptionsChanged.
GetControllerType() int Derives from RCCP_Settings.Instance.mobileController (0=Touch, 1=Gyro, 2=SteeringWheel, 3=Joystick).
SetControllerType(int controllerIndex) void Writes ControllerType, calls RCCP.SetMobileController(...), fires OnOptionsChanged.

SetShadows() and SetPP() take no argument — each call flips the stored boolean. Controller types are covered in detail in 11_ControllerTypes.md.

Scene navigation and reset

Method Returns Purpose
MainMenu() void SceneManager.LoadSceneAsync(0), then SetTotalPlayedTime().
RestartGame() void Reloads the active scene by build index, then SetTotalPlayedTime().
ResetGame() void PlayerPrefs.DeleteAll(), then loads TO_Settings.Instance.mainMenuSceneIndex.

MainMenu() is hard-coded to build index 0, while ResetGame() loads the configurable mainMenuSceneIndex from TO_Settings. If you reorder your Build Settings so the main menu is not index 0, audit both paths.

PlayerPrefs keys used by TO_API

Every key below was confirmed against TO_API.cs. Defaults marked "TO_Settings" are pulled from the TO_Settings ScriptableObject at read time, so changing the asset changes the fallback for a fresh install.

Key Type Default Written / read by
Currency int 0 GetCurrency / AddCurrency / ConsumeCurrency
PlayerName string "New Player" GetPlayerName / SetPlayerName
TotalPlayedTime float 0 GetTotalPlayedTime / SetTotalPlayedTime
{VehicleName}Owned int (absent) vehicle lock/unlock methods
bestScoreOvertake int 0 GetHighScores
AudioVolume float defaultAudioVolume (TO_Settings) audio volume getter/setter
MusicVolume float defaultMusicVolume (TO_Settings) music volume getter/setter
DrawDistance float defaultDrawDistance (TO_Settings) draw distance getter/setter
Shadows bool (TO_PlayerPrefsX) defaultShadows (TO_Settings) GetShadows / SetShadows
PP bool (TO_PlayerPrefsX) defaultPP (TO_Settings) GetPP / SetPP
QualityLevel int QualitySettings.GetQualityLevel() GetQuality / SetQuality
ControllerType int (read from RCCP) written by SetControllerType

The keys SelectedPlayerCarIndex and SelectedModeIndex carry the cross-scene selection but are not read or written inside TO_API.cs — they are managed elsewhere (the main menu and gameplay managers), so they are intentionally omitted from the table above.

TO_API usage example

// Award currency at the end of a run and persist a new best score.
void OnRunFinished(int runScore) {

    TO_API.AddCurrency(runScore);           // fires OnPlayerMoneyChanged

    int best = TO_API.GetHighScores()[0];
    if (runScore > best)
        PlayerPrefs.SetInt("bestScoreOvertake", runScore);
}

// Unlock a car from a shop button, then refresh the wallet label.
void BuyCar(int rosterIndex, int price) {

    if (TO_API.GetCurrency() >= price && !TO_API.OwnedVehicle(rosterIndex)) {
        TO_API.ConsumeCurrency(price);
        TO_API.UnlockVehicle(rosterIndex);
    }
}

TO_Events — the static event bus

TO_Events decouples gameplay systems from UI. Producers (the gameplay manager, the player, the menu) call a Event_OnXxx() trigger method; consumers (HUD, sound, analytics) subscribe to the matching static event. Every trigger method null-checks its event before invoking, so it is always safe to fire even when nothing is listening. This is the standard pattern inherited from the project's HR2 lineage and is used throughout the UI scripts described in 04_SystemArchitecture.md.

Events and their delegates

Event Delegate signature Meaning
OnCountDownStarted void onCountDownStarted() The pre-run countdown began.
OnRaceStarted void onRaceStarted() Control handed to the player; the run is live.
OnPlayerSpawned void onPlayerSpawned(TO_Player player) The player vehicle was instantiated.
OnPlayerDied void onPlayerDied(TO_Player player, int[] scores) The run ended (crash); scores carries the final tally.
OnPaused void onPaused() The game was paused.
OnResumed void onResumed() The game resumed from pause.
OnVehicleChanged void onVehicleChanged(int carIndex) The selected car changed in the main menu.
OnOptionsChanged void OptionsChanged() Any audio/graphics/controller option changed (fired by most TO_API setters).

Trigger methods

Each event has a matching public trigger you call to raise it. These are what the managers invoke; you normally only call them if you are writing your own producer.

Method Raises
Event_OnCountDownStarted() OnCountDownStarted
Event_OnRaceStarted() OnRaceStarted
Event_OnPlayerSpawned(TO_Player player) OnPlayerSpawned
Event_OnPlayerDied(TO_Player player, int[] scores) OnPlayerDied
Event_OnPaused() OnPaused
Event_OnResumed() OnResumed
Event_OnVehicleChanged(int carIndex) OnVehicleChanged
Event_OnOptionsChanged() OnOptionsChanged

TO_Events usage example

// A HUD widget that reacts to run lifecycle and options.
void OnEnable() {
    TO_Events.OnRaceStarted   += HandleRaceStarted;
    TO_Events.OnPlayerDied    += HandlePlayerDied;
    TO_Events.OnOptionsChanged += RefreshFromSettings;
}

void OnDisable() {
    TO_Events.OnRaceStarted   -= HandleRaceStarted;
    TO_Events.OnPlayerDied    -= HandlePlayerDied;
    TO_Events.OnOptionsChanged -= RefreshFromSettings;
}

void HandleRaceStarted() { /* show the live HUD */ }

void HandlePlayerDied(TO_Player player, int[] scores) {
    int finalScore = scores.Length > 0 ? scores[0] : 0;
    // present the game-over panel with finalScore
}

Always subscribe in OnEnable and unsubscribe in OnDisable (or OnDestroy). Because every event is a static, a forgotten unsubscribe keeps your destroyed object's handler alive across scene loads, which leaks the object and can throw MissingReferenceException the next time the event fires. This is the single most common mistake when extending the event bus.

See Also