Make a livery
You'll build mod.rb-repaint, a Red Bull repaint, three ways: on the stock Red Bull in every year that inherits its livery, on Classic Seasons 2017's own Red Bull only, or as an extra choice in the livery picker. Pick the one you want; the player sees the repaint on track in Grand Prix and Time Trial.
The folder
mod.rb-repaint/
swofty.json
livery/
redbull_d.tif.mipmaps
redbull_m.tif.mipmaps
archives/
redbull_repaint.erp
native/
build.sh
livery.dll
src/
livery.cpp
registry/
livery.json
layers.jsonChoose C++ or Without code. The C++ version uses native/; the data version uses registry/ and leaves operations out of the manifest. The archive is for the special-livery version. Textures covers painting and exporting the texture files.
1. Repaint the stock Red Bull
Put your stock Red Bull textures in livery/, then create the files below. cars::Vehicle::model points at the car's model files and uses the donor's model when empty. The livery's vehicle declares which car it fits; the layer makes that car use it.
#include <swofty/registry.hpp>
#include <swofty/systems/cars.hpp>
#include <swofty/systems/liveries.hpp>
using namespace swofty;
SWOFTY_REGISTER
{
auto car = cars::vehicles["game/redbull_2025"];
auto repaint = liveries::liveries.add("repaint", {
.vehicle = car,
.textures = file("livery/"),
});
cars::vehicles.layer(car, [=](cars::Vehicle &v) {
v.livery = repaint;
});
}
SWOFTY_ADDON()Create swofty.json:
{
"schema_version": 1,
"id": "mod.rb-repaint",
"name": "Red Bull Repaint",
"version": "1.0.0",
"author": "you",
"category": "cars",
"compat": {
"game": "f1_25",
"launcher": ">=1.6.0"
},
"operations": {
"native": [
{ "dll": "native/livery.dll" }
]
}
}The repaint reaches every year that inherits the stock car's livery. Classic Seasons 2017 keeps the livery its own car sets. See How changes reach seasons and careers.
2. Put it on the 2017 car
For a repaint that targets only Classic Seasons 2017, replace the previous source or data files with these. Use textures that fit the 2017 car's model, and place this addon after Classic Seasons 2017 in load order.
#include <swofty/registry.hpp>
#include <swofty/systems/cars.hpp>
#include <swofty/systems/liveries.hpp>
using namespace swofty;
SWOFTY_REGISTER
{
// Required reference to the year's own car.
auto car = cars::vehicles["swofty.classic-seasons-2017/redbull"];
auto repaint = liveries::liveries.add("repaint", {
.vehicle = car,
.textures = file("livery/"),
});
// Change this car directly, including its own /livery value.
cars::vehicles.layer(car, [=](cars::Vehicle &v) {
v.livery = repaint;
});
}
SWOFTY_ADDON()Add this top-level field to swofty.json; requires stops Play while Classic Seasons 2017 is missing or off.
"requires": [
{ "id": "swofty.classic-seasons-2017" }
]3. Offer it in the livery picker
For an extra stock Red Bull picker choice, replace the previous implementation with this one, remove the 2017 requires field, and remove registry/layers.json from the data version. Supply archives/redbull_repaint.erp for the stock model. A special livery creates its picker and unlock rows; the string record supplies its visible name.
#include <swofty/registry.hpp>
#include <swofty/systems/cars.hpp>
#include <swofty/systems/liveries.hpp>
#include <swofty/systems/ui.hpp>
using namespace swofty;
SWOFTY_REGISTER
{
ui::strings.add("lng_mod_rb_repaint", {
.text = { { "*", "Red Bull Repaint" } },
});
liveries::liveries.add("repaint", {
.vehicle = cars::vehicles["game/redbull_2025"],
.archive = file("archives/redbull_repaint.erp"),
.special = true,
.suffix = "auto",
.picker_name = "lng_mod_rb_repaint",
.unlock = liveries::Unlock::owned,
});
// The player selects this entry in the livery picker.
}
SWOFTY_ADDON()The core allocates the archive suffix and stat id; use a unique picker key to avoid colliding with a stock special livery.
4. Let a player drop it in
A player can drag a livery .serps package or game-file zip onto the importer, which creates a livery record and a layer on the base car. Applies to adds another car as a target, such as F1 2017 Red Bull (Classic Seasons 2017), and keeps the stock car. The picker lists only cars whose model the livery fits, and saves the choice in importer.json for re-imports. An author can declare the target car in the .serps package.
// The layers for an imported mod mod.rb-repaint after Applies to adds the 2017 Red Bull
{
"vehicle": {
"game/redbull_2025": { "livery": "mod.rb-repaint/repaint" },
"swofty.classic-seasons-2017/redbull": { "livery": "mod.rb-repaint/repaint" }
}
}On the 2017 car, the import competes with Classic Seasons by load order. Making mods covers building a .serps package.
Try it
Keep one of the three versions. For C++, build the DLL from inside mod.rb-repaint/ with native/build.sh from the addon template:
native/build.shFor Without code, omit the native build and remove operations from swofty.json. From the folder containing mod.rb-repaint/, install, enable, and run:
swofty addons install ./mod.rb-repaint
swofty addons enable mod.rb-repaint
swofty run --applyOpen Time Trial and choose the stock Red Bull for step 1, F1 2017's Red Bull for step 2, or Red Bull Repaint in the stock car's livery picker for step 3. Restart the game after changing these boot-time records.
Check swofty/loader.log for the corresponding entries. For the stock repaint:
[registry] vehicle game/redbull_2025: edit by mod.rb-repaint changed /livery -> mod.rb-repaint/repaint
[registry] vehicle swofty.classic-seasons-2017/redbull: /livery set by the variant; layer on game/redbull_2025 from
mod.rb-repaint not inherited for this fieldFor the direct 2017 repaint:
[registry] vehicle swofty.classic-seasons-2017/redbull: edit by mod.rb-repaint changed /livery -> mod.rb-repaint/repaintFor the special livery, the allocated suffix and stat id can differ:
[registry] livery mod.rb-repaint/repaint: special, wep_override _lx01, stat id 22 (se_livery), ownedWhen something's missing
- Classic Seasons 2017 is off: the step 2 addon has a required dependency. The launcher names it before Play and stops the launch until it is available.
- The target car record is gone: the hard
vehiclereference leaves the livery unresolved. A layer that fails reference validation is dropped, leaving the base and other valid layers in place. - The repaint addon is off: the player sees the livery underneath it; the special picker choice is absent.
Dependencies distinguish missing addon requirements from unresolved records.
Publish
Package your chosen version and follow Publishing to publish mod.rb-repaint to the Addon Browser.