Road Rash: bails leave marks on the skater that build up

After 10 bails the leg of the side that took more of them shows road dust
and a graze, its arm one bail later; at 14 the marks are bigger and the
other side starts; at 20 they are raw wounds and the face is bruised. A
mark never gets smaller until the player heals. The worst wounds bleed,
or are dry and scabbed with the blood switch off.

The marks are cosmetic items of a content mod (tattoo items for the limbs,
moles items for the face, named RoadRash_<Set>_[<design>_]<level>). Road
Rash puts them into the local skater's recipe with the game's own recipe
copy, after the validation the multiplayer code runs on a peer's outfit.
Nothing is written to the outfit or the profile's skater, and without the
item pack nothing shows and nothing is changed.

A bail is the physics state selector choosing Wipeout (No Bail's watch).
Its side comes from the ragdoll's contacts through Hall of Meat's reader:
impact and slide of the arm and leg bodies that touch something other than
the skater's own board, summed per side while the body is a ragdoll.

Outfit menus. The game feeds a skater's items either from the player's
outfit or from a recipe of the skater's own: after the recipe copy the
skater in the world no longer gets what the player changes in the menus.
So the skater is given back to the game while a game menu is up, with
nothing to show, on healing, when a switch changes and when switched off:
the four words of the item component the copy had changed go back to what
they were and the component is told its feed changed, and the game puts
the outfit's own items back and feeds the skater again. The marks go back
on, over the outfit as it is by then, a second after the menu has gone.
Whose recipe a skater wears is read from the skater at every look: a
respawn hands over the same skater, items and all, as if it were new.
The player's own tattoos and moles stay unless roadrashtattoos is on, and
come back the same way.

The recipe handed to the copy names no item, only hashes, like the game's
own for the local skater: the game changes that skater's items where they
lie, and a name left beside one would stop every later read of the
recipe, the multiplayer code's too.

Console: roadrash, roadrashblood, roadrashtattoos, roadrash heal,
roadrash bails <count>. Menus: Road Rash, Road Rash blood and Heal Road
Rash beside Hall of Meat (Mod Options > Player, the overlay's skater page,
the native tools view). The three choices are saved with the profile.

No new hooks. The rules (side of a fall, levels per count, item names,
decal placement, comparing parameters the game has rounded) are in
road_rash_model.h with their own test target,
DINGOSDK_BUILD_ROAD_RASH_TESTS. Notes and what is not tried yet:
contrib/road-rash.md.
This commit is contained in:
Fourth Studio committed 2026-10-10 19:55:29 +02:00
1 parent b7936a36c6
commit 1b0bb2b12f
18 files changed
+1078

No files matched your search

+3
View File
@@ -11,6 +11,7 @@
#include "Engine/Vfs/mod_catalog.h"
#include "Extension/Boot/offline_boot.h"
#include "Extension/HallOfMeat/hall_of_meat.h"
#include "Extension/RoadRash/road_rash.h"
#include "Extension/Skater/camera_observer.h"
#include "Extension/Progression/entitlement_request_hook.h"
#include "Extension/Skater/skater_observer.h"
@@ -375,6 +376,8 @@ extern "C" __declspec(dllexport) BOOL WINAPI DingoSDKDebugInitialize() {
(void)dingosdk::start_no_bail(r.base);
const bool meat = dingosdk::hall_of_meat::start(r.base);
record("{\"event\":\"hall_of_meat_initialized\",\"active\":" + std::string(meat ? "true" : "false") + "}");
const bool rash = dingosdk::road_rash::start(r.base);
record("{\"event\":\"road_rash_initialized\",\"active\":" + std::string(rash ? "true" : "false") + "}");
const bool noclip_velocity = dingosdk::start_client_noclip_velocity(r.base);
record("{\"event\":\"noclip_velocity_initialized\",\"active\":" + std::string(noclip_velocity ? "true" : "false") + "}");
const bool loading_screens = dingosdk::loading_screen::start(r.base);