diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 00000000..e69de29b diff --git a/404.html b/404.html new file mode 100644 index 00000000..9f5db414 --- /dev/null +++ b/404.html @@ -0,0 +1,889 @@ + + + +
+ + + + + + + + + + + + + + +Info
+Explains how Sonic Riders' vanilla memory allocation system works.
+Todo
+To be added.
+Welcome to the Book of the Tweakbox (BOTT) for Riders Tweakbox. This page contains a collection of articles about the internals of both Riders Tweakbox itself, as well as Sonic Riders. The intended audience of this book is people wishing to work on Tweakbox, or wishing to understand Tweakbox and/or the base game.
+Page | +Description | +
---|---|
Introduction | +Describes the general structure/layout of Tweakbox' source code. | +
Overlay Helper APIs | +Useful APIs for creating menus in Tweakbox. | +
Heap | +Describes how Sonic Riders' memory allocator works. | +
Info
+Provides an introduction to Tweakbox' internal code structure, including how things are laid out.
+Info
+Provides a simplified top level view of how initialization happens in Tweakbox.
+The life of Tweakbox begins in Program.StartEx()
, this method is responsible for the following:
+- Setting up 3rd party libraries (e.g. one time method calls).
+- Fetching Reloaded dependencies [e.g. File Redirector to use with music].
+- Adjusting anything runtime related.
Program then delegates to Tweakbox
, which sets up Tweakbox' code.
The Tweakbox
component is responsible for the following [in order]:
+- Sanity checks (e.g. ensure files don't use vanilla compression).
+- Setting up UI Menus.
+- Initialising all IConfiguration
(s), ISingletonService
(s) & IController
(s) in this specific order.
Info
+Defines the common kinds/types of items you'll find in Tweakbox' source code.
+Note
+Unless stated otherwise, assume components are singletons, i.e. there is only ONE instance of each configuration in memory and it's reused everywhere.
+Info
+Stores an individual configuration for a component or a set of Tweakbox components.
+Within Tweakbox' source, you will find two types of configurations, Binary
and JSON
.
JSON
configurations are used when all of the data is known, and inherit from JsonConfigBase
which provides all of the backbone code for the configuration(s).
Example:
+
// JsonConfigBase inherits from IConfiguration and provides all needed boilerplate code.
+public class TextureInjectionConfig : JsonConfigBase<TextureInjectionConfig, TextureInjectionConfig.Internal>
+{
+ public class Internal
+ {
+ public bool DumpTextures = false;
+ public DumpingMode DumpingMode = DumpingMode.All;
+ public int DeduplicationMaxFiles = 2;
+ }
+
+ public enum DumpingMode
+ {
+ All = 0,
+ OnlyNew = 1,
+ Deduplicate = 2,
+ }
+}
+
Binary
configurations are typically used when the data:
+- Needs to be small.
+- Contains unknown values (e.g. Not fully reversed Sonic Riders' game structs).
Example Binary
configuration:
+
public unsafe class GearEditorConfig : IConfiguration
+{
+ private static GearEditorConfig _default = new GearEditorConfig();
+
+ /// <summary>
+ /// Extreme gears assigned to this config.
+ /// </summary>
+ public ExtremeGear[] Gears;
+
+ /// <summary>
+ /// Creates the default editor config.
+ /// </summary>
+ public GearEditorConfig()
+ {
+ Gears = new ExtremeGear[Player.OriginalNumberOfGears];
+ Player.Gears.CopyTo(Gears, Gears.Length);
+ }
+
+ /// <summary>
+ /// Creates a <see cref="GearEditorConfig"/> from the values present in game memory.
+ /// </summary>
+ public static GearEditorConfig FromGame() => new GearEditorConfig();
+
+ /// <summary>
+ /// Updates the game information with the gear data stored in the class.
+ /// </summary>
+ public unsafe void Apply() => Player.Gears.CopyFrom(Gears, Player.OriginalNumberOfGears);
+
+ /// <inheritdoc />
+ public Action ConfigUpdated { get; set; }
+ public byte[] ToBytes() => LZ4.CompressLZ4Stream(StructArray.GetBytes(Gears), LZ4Level.L12_MAX);
+
+ public void FromBytes(Span<byte> bytes)
+ {
+ var outputArray = new byte[StructArray.GetSize<ExtremeGear>(Player.OriginalNumberOfGears)];
+ var decompressed = LZ4.DecompressLZ4Stream(outputArray, bytes, out int bytesRead);
+
+ StructArray.FromArray(decompressed, out Gears, true, Player.OriginalNumberOfGears);
+ ConfigUpdated?.Invoke();
+ }
+
+ public IConfiguration GetCurrent() => FromGame();
+ public IConfiguration GetDefault() => _default;
+}
+
[Stores the whole array of all extreme gear data in Riders]
+Info
+Provides various utility functions to be used throughout Tweakbox.
+Also a singleton.
Example API(s):
+/// <summary>
+/// Keeps track of all music tracks provided by other mods (as well as the vanilla game)
+/// </summary>
+public class MusicService
+{
+ /// <summary>
+ /// Gets the name of a random alternative track for a given file name.
+ /// </summary>
+ /// <param name="fileName">The file name for which to get a replacement track.</param>
+ /// <param name="includeVanilla">Whether to include vanilla tracks or not.</param>
+ /// <param name="includePerStageTracks">Whether to include stage-specific tracks.</param>
+ /// <returns>Path to the replacement track.</returns>
+ public unsafe string GetRandomTrack(string fileName, bool includeVanilla, bool includePerStageTracks);
+
+ /// <summary>
+ /// Obtains all potential candidate tracks for a given stage.
+ /// </summary>
+ /// <param name="stageId">The stage index.</param>
+ /// <param name="files">List of files to add the candidates to.</param>
+ public void GetTracksForStage(int stageId, List<string> files);
+}
+
/// <summary>
+/// Converts Sonic Riders' PVRT texture format to DDS using the game's built-in converter.
+/// </summary>
+public class PvrtConverterService : ISingletonService
+{
+ /// <summary>
+ /// Converts a texture to DDS.
+ /// </summary>
+ /// <param name="pvrtData">The PVRT texture to convert.</param>
+ /// <returns>DDS data generated from PVRT.</returns>
+ public unsafe byte[] Convert(Span<byte> pvrtData);
+}
+
Info
+Controllers contain all the functionality that modifies directly how the game itself functions.
+These controllers usually 'hook' into the game code, by either replacing the method or injecting some assembly code.
Random Example(s):
+Controller | +Description | +
---|---|
MusicInjectionController | +Replaces the music track(s) that will be loaded by the game. | +
IgnoreTurbulenceController | +The 'C toggle' for ignoring turbulence if desired. | +
BorderlessWindowedController | +Toggles the game's Borderless Windowed state during startup and in real time. | +
RailController | +Controls the speed of the Rails. | +
AutoSectionController | +Automates Left+Right inputs during automated sections. | +
Within controllers there exists one special case, EventController
. This controller is implemented mainly in x86 assembly, split over multiple files and provides callbacks which you can subscribe to that modify various game behaviours.
For example:
+
EventController.SetRingsOnHit += SetRingsOnHit;
+private void SetRingsOnHit(Player* player) => player->Rings = 42;
+
Info
+Menus use the IComponent
interface and are created + registered during Tweakbox startup.
Random Example(s):
+Controller | +Description | +
---|---|
AboutMenu | +Renders the about page. | +
TweakboxSettings | +Renders the Tweakbox general settings menu. | +
SlipstreamDebug | +Shows slipstream data in real time. | +
In practice, all menus inherit from ComponentBase
or ComponentBase<TConfig>
, which provide a default implementation of IComponent
.
Sample dummy menu (via ComponentBase
):
+
// Renders
+public class DummyMenu : ComponentBase
+{
+ public override string Name { get; set; } = "Dummy Menu";
+ public override void Render()
+ {
+ if (ImGui.Begin(Name, ref IsEnabled(), 0))
+ {
+ // Code to render menu here
+
+ }
+
+ ImGui.End();
+ }
+}
+
If you need to have a config for this menu, use ComponentBase<TConfig>
.
// InfoEditorConfig is an IConfiguration
+public class InfoEditor : ComponentBase<InfoEditorConfig>, IComponent
+{
+ public override string Name { get; set; } = "Info Editor";
+
+ // Note the constructor, it passes some stuff to base class.
+ public InfoEditor(IO io) : base(io, io.InfoConfigFolder, io.GetInfoConfigFiles, ".json") { }
+
+ public override void Render()
+ {
+ if (ImGui.Begin(Name, ref IsEnabled(), 0))
+ {
+ // Provides the New/Delete/Load/Save part of the menu.
+ ProfileSelector.Render();
+
+ // Code to render menu here
+ }
+
+ ImGui.End();
+ }
+}
+
Info
+Custom Menus must be registered in Tweakbox.cs
to show in the overlay.
Example:
+
new MenuBarItem("Main", new List<IComponent>()
+{
+ // Your custom menu here.
+ Benchmark(() => IoC.GetSingleton<DummyMenu>(), nameof(DummyMenu)),
+
+ // Previously existing menus.
+ Benchmark(() => IoC.GetSingleton<NetplayMenu>(), nameof(NetplayMenu)),
+ Benchmark(() => IoC.GetSingleton<UserGuideWindow>(), nameof(UserGuideWindow)),
+ Benchmark(() => IoC.GetSingleton<AboutMenu>(), nameof(AboutMenu)),
+ Benchmark(() => IoC.GetSingleton<OpenSourceLibraries>(), nameof(OpenSourceLibraries)),
+})
+
Info
+Provides a listing of projects within the Tweakbox source code.
+Project | +Description | +
---|---|
Riders.Netplay.Messages | +Contains all code responsible for writing/reading individual messages over the network. | +
Riders.Netplay.Messages.Tests | +Test code for messages library; can be barebones at times. | +
Riders.Tweakbox.API.SDK | +Code for communicating with the Web Server providing server browser, ranking. | +
Riders.Tweakbox | +Main mod code. | +
Riders.Tweakbox.CharacterPack.DX | +Test/example mod for adding custom character behaviours. [Ports SRDX 1.0.1 char stats to Tweakbox] | +
Riders.Tweakbox.Gearpack | +Test/example mod for adding custom gear behaviours. [Ports all gears from all mods released before late 2021] | +
Riders.Tweakbox.Interfaces | +API for other mods to use. Recommend Reading: Dependency Injection in Reloaded-II | +
Sewer56.Hooks.Utilities | +Helper code for manipulating game functions with x86 assembly. | +
Sewer56.Imgui | +Helpers for creating menus. (Extensions for our Dear ImGui wrapper.) | +
Sewer56.SonicRiders | +API and definitions for hacking Sonic Riders | +
[Some projects have been omitted to keep the list simpler.]
+ + + + + + + + + + + + + +Info
+Provides a small listing of helpful classes that may be used for creating UI elements.
+Info
+Contains all custom controls made for the Reloaded UI.
+About
+The Tooltip
class can be used to display tooltips on individual UI elements.
(Using Tooltip.TextOnHover
to display tooltip on last rendered UI element)
About
+Allocates memory to use in controls that allow the user to manipulate text.
+var username = new TextInputData("", TextLength);
+
+// Calling 'Render' will give you a textbox.
+username.Render("Username");
+
The Render
method is just for convenience since TextBox
(InputText) is the most common control.
+You could use username.Pointer
with other text based controls as needed.
About
+Standalone widget for loading configuration files.
+Info
+Wrapper over some parts of the original API for easier drawing of UI elements. Could maybe use better name.
+// Make a control to edit an integer with a parameter
+Reflection.MakeControl(ref bufferSize, "Default Buffer Size");
+
This is defined as:
+
// Internal Definition
+public static bool MakeControl(ref Int32 value, string name)
+{
+ return ImGui.DragScalar(name, (int)ImGuiDataType.ImGuiDataTypeS32, (IntPtr) Unsafe.AsPointer(ref value), 1.0F, IntPtr.Zero, IntPtr.Zero, null, 1);
+}
+
About
+You can use this to render native DirectX textures inside the UI.
+Example usage:
+imageRenderer = new ImageRenderer();
+
+// TextureOut is `LPDIRECT3DTEXTURE9 *ppTexture` as seen in e.g. `D3DXCreateTextureFrom` APIs.
+var texturePtr = (IntPtr)(*currentImage.TextureOut);
+var texture = new Texture(texturePtr);
+var desc = texture.GetLevelDescription(0);
+imageRenderer.SetImageSize(new Vector2(desc.Width, desc.Height));
+imageRenderer.Render(texturePtr);
+
About
+Clickable piece of text that opens a link or file.
+Todo
+Hyperlinks could be improved (change colour on hover, change mouse cursor) etc.
+Use the Hyperlink.CreateText
API.
Info
+Contains helper classes related to setting up the layout of the windows and/or contents.
+WIP
+Note
+This API will probably be removed.
+In the past our Dear ImGui Wrapper which is made using CppSharp didn't have finalizers, which meant not using a using
statement or Dispose()
may have led to memory leaks. This is no longer the case so this class no longer has any use.
The format is based on Keep a Changelog +and this project adheres to Semantic Versioning.
+Please note that this project is not yet ready for public consumption. Netplay is still incomplete, buggy and a work in progress. I do not yet consider this project acceptable for normal end users.
+Please report any issues (especially crashes) using the guidelines provided in Reporting Issues.
+Do not ask for Tech Support (e.g. "How do I use this mod").
+The format is based on Keep a Changelog +and this project adheres to Semantic Versioning.
+Please note that this project is not yet ready for public consumption. Netplay is still incomplete, buggy and a work in progress. I do not yet consider this project acceptable for normal end users.
+Please report any issues (especially crashes) using the guidelines provided in Reporting Issues.
+Do not ask for Tech Support (e.g. "How do I use this mod").
+c45a435
de66326
4f2fb13
89c5711
291a56d
07fae38
7b25adb
44eaddd
b1a11b4
03cc5dc
64d159f
0e98422
13edec7
f012235
3985c01
09e4921
51e0730
f38833c
e512cce
7592027
7b52367
0539d1b
09ce4e0
c641028
b24e6e9
dbf4f27
816e8b7
539f4cc
f9bed60
57023a0
e2cf282
efeed89
7557505
ba30ac0
5522c04
42a1f2d
9888927
75c16d5
The format is based on Keep a Changelog +and this project adheres to Semantic Versioning.
+This document lists all changes
+This is a beta release. +It's huge, probably the biggest update since initial test builds but a beta version nonetheless.
+Some of the features of this release are not fully tested; as I am unfortunately stressed, lacking in time and with real life things to sort out.
+I'm willing to make some time to fix minor bugs but don't expect major development soon.
+Please note that this project is not yet ready for public consumption. +Netplay still has flaws. Very minor issues, but flaws nonetheless. +I do not yet consider this project to be of production quality.
+Please report any issues (especially crashes) using the guidelines provided in Reporting Issues.
+Do not ask for Tech Support (e.g. "How do I use this mod").
+Tweakbox 0.5.0 comes with many improvements with regards to how graphics and rendering are handled within the game.
+To name a few changes:
++
Version 0.5.0 extends many of the built-in game limits to better accomodate modern hardware and mods of the future.
+Examples include:
+* This limit is further extended to 2GB is a patch known as 'Large Address Aware' is applied to the game's exe file. In 0.5.0, this limit was set at startup. In 0.5.4+, this limit is configurable and accessible via Tweakbox Settings -> Startup
.
Tweakbox now ships with complete Discord information; including reporting both information about your current game status and your Netplay Session.
++
And of course, Discord invites are supported too:
+ +You can now more easily find games hosted by other people by using the built-in server browser.
+ +(This is just some test data)
+The Server Browser is powered by a home made, in house built web server which was made specifically for Riders.Tweakbox. There will be more features in the future such as Ranked Play, Elo-like Match Making Rating and Statistics Tracking. Those are already implemented server side.
+Support for various "Modifiers", or ways in which you can customize your own Netplay lobby have been added. For now, the features are limited but extended features will come in the future.
+ +Turbulence everywhere... even in running mode.
+Tweakbox now allows you to add custom ADX music to the game by creating external Reloaded-II mods.
+This allows you to provide alternative tracks to the game's default soundtrack.
When the game is about to play a music track, Tweakbox will randomly choose from one of your own music tracks.
+ +Tweakbox allows you to replace music using two modes:
+The example above shows per-stage music injection.
+There is no limit to this feature. If you want 20GB worth of 4000 music tracks or 500 music tracks for a single stage, be my guest.
+For more details, refer to Tweakbox' documentation.
Tweakbox now allows you to replace textures in real-time by hijacking function calls to the Direct3D 9 API.
+Similar to how Dolphin Emulator handles it, you can inject textures without the need to modify game files.
Textures are supported in the following formats:
+Creation of texture packs is easy, with a step by step guide available in the documentation.
+If you desire a bit more style, and wish to flex on the people emulating the GameCube version of the game, Tweakbox allows you to add basic animation to any texture:
+ + +For more details, refer to Tweakbox' documentation.
+You can also dump textures from the game as they are loaded in real-time.
+ +The texture dump tool comes with multiple modes; such as:
+Only New
mode which doesn't dump textures already dumped.Deduplication
mode, which puts textures with more than X duplicates in a Common
folder.Chances are that you wouldn't need to texture dump yourself though; as I've gone through the effort of dumping 3000+ textures on my own, with perfect dumps for every single stage.
+With the improved texture dumping tools and some clever usage of them, the texture archive I made in the span of a day is more complete and accurate than what's been available for the GameCube version over the last 2 years.
+Here's a link to my texture archive, it contains ~99% of all of the game's textures.
+Starting with 0.5.5+ Tweakbox also maintains a built-in texture cache to work around slow loading times of PNG textures.
+When a PNG is loaded for the first time and its mipmaps are generated, the texture will be converted to the optimal DDS.LZ4
custom format for future use. Subsequent uses of the texture will instead load from the cache which is many magnitudes faster. The conversion happens in the background and is multithreaded, so you should not notice a difference in first time load performance compared to previously loading a PNG (< 0.5.5).
Editing the original PNG image will cause the cached texture for that file to be invalidated, and a new DDS.LZ4
will be automatically created. Please note that the underlying cached DDS is uncompresed and eats memory for breakfast. Consider manually creating DDSes with DXT1 / DXT5 if you are working with e.g. Animated Textures. More info in the documentation.
Tweakbox now has a built-in, fully featured object layout editor; allowing you to:
+Oh, by the way, these itemboxes (and some others) are unused in the final game, hehehe.
+If you would like additional features, such as racing online with custom layouts, let me know.
By the way... you can also now play Battle Mode in regular race stages hehehe...
+The players now have their own individual pause menus, allowing you to restart and exit the race (if host) or disconnect from the current lobby.
+ ++
The pause menu after the results screen has also been replaced with a custom menu allowing the host to choose what to do next.
+In Netplay, Tweakbox will now make basic sanity checks such as:
+Tweakbox now allows you to edit turbulence physics and speeds. For every single variation of Turbulence used by the game.
+ +Of course, as with all features listed above and below, it syncs with host over Netplay.
+Tweakbox can now change the behaviour of some common objects in the game; for example:
+Tweakbox can now change how the game handles deceleration; overriding the game's built in exponential deceleration with alternative options.
+One of the options is Linear
deceleration; which makes you decelerate at a constant rate regardless of how far above top speed you are.
You can now spam your "JCBCDPC"dsdasdasfdsjdfuisdfhsid(s).
+ +The numbers in this screenshot are actually what Sonic Riders DX and Sonic Riders TE 1.3 use.
+The mod now allows you to boot directly into a race (no menu navigation required) with a specific stage, character and gear combination. This is incredibly useful when testing mods.
+The mod now allows you to return directly into the track select menu after returning from a race. +This works with all game modes, unlike the implementations in the current popular GameCube version mods.
+Various Tweaks
to Tweakbox Settings
. ... and more
+... and more
+ + + + + + + + + + + + + +The format is based on Keep a Changelog +and this project adheres to Semantic Versioning.
+This document lists all changes
+This is a beta release.
+This release mostly consists of additional polish in existing features, albeit there are some new toys to play with (one of them is really impressive!).
+Most of the features in this release have been tested, though there may be some odd things here and there around the edges; as I've still other things to do outside of Riders.
+Please report bugs (no matter how minor); I'll do what I can to test them in a timely manner.
+Please note that this project is not yet ready for public consumption. +Netplay still has flaws. Very minor issues, but flaws nonetheless. +I do not yet consider this project to be of production quality.
+Please report any issues (especially crashes) using the guidelines provided in Reporting Issues.
+Do not ask for Tech Support (e.g. "How do I use this mod").
+The staple feature of this patch.
+ +Tweakbox now supports the addition of fully custom gears; that is, having customized gears without having to replace the vanilla gears.
+Here's some details:
+What's left? +- Custom model support for custom gears. (Will implement on demand)
+Some minor improvements have been made to existing texture injection tools used in Riders; for example the introduction of the texture viewer tool.
+ +The texture viewer allows you to preview all currently loaded textures in real time; which makes the creation of texture packs or finding hashes for your custom textures more convenient.
+Oh, by the way, this is the debug menu font! It's not there in the console releases <3.
+ +It's also now possible reload textures in real time; allowing for changes to be seen without having to re-load the menu/stage; as well as see a list of all texture redirections that have been made. Useful stuff!
+Tweakbox now has the ability to display various widgets on the screen.
+Widgets can be pinned to any edge or corner of the screen and display information such as, FPS, Frame Time, CPU and Memory Usage to the screen.
+ +The user can add or remove as many widgets as they like.
+The layout of the settings menu has been cleaned up for better organization and accessibility. Related settings are now grouped together under expandable trees.
+ +Version 0.6.0 adds a feature which forces certain settings to be enabled while in Netplay mode:
+These features cannot be toggled while participating in Netplay; and are enabled to ensure consistency between all players.
+Come across a random player in Netplay? +Fear no more! You can talk now.
+*You even get notified if your Netplay window is minimized, win-win!.
+A few small changes here: +- You can customize the hotkey used to toggle passing input to the game. +- Blocking input passed to the game now works regardless of mod load order when used with Controller Hook. +- You can now make Tweakbox not pass inputs to game if any of its Windows are activated/being used.
+Starting with version 0.6.0, Tweakbox uses an upcoming C# 10 feature called Improved Interpolated Strings which allows for more efficient logging.
+Notably, if the log level/category for a specific message is not enabled, the string will not even be constructed at all; saving both time and unnecessary memory allocations without the need of writing repetive, redundant ugly checks on every log operation.
+Starting with version 0.6.0, there's a cool little utility for tracking allocations made to the game's native heap.
+ +This is a result of my study into how the game handles memory allocations.
+Sometimes it doesn't seem to work perfectly yet for the Front
side (if there's an issue, you'll experience game lag); as the front side of the heap wasn't really designed to be walked through, and game doesn't clean up properly sometimes. Most of the time however it works perfectly fine.
The back side works perfectly without issue.
+The "Race Settings" in Netplay Menu has now been moved to the Tweakbox Settings
menu and rebranded as Game Modifiers
.
These settings can now be applied to any race; not just netplay races.
+ +In addition, a number of new modifiers have been added, including:
+- Disable Attacks for First X
Milliseconds in Race.
+- No Screenpeeking (Netplay)
+- Custom Ring Loss on Death
+- Custom Ring Loss on Hit
+- No Turbulence
+- Slipstream
Starting with version 0.6.0, race loading times have been improved by up to 60%. +Previously loading an 8 player race has taken around 2.5 seconds, now it takes 1.5 seconds.
+Tweakbox now obsoletes a third party file caching mechanism from CRI Middleware originally used in Riders. This improves the initial cold boot startup time by around 10 seconds.
+Note: "Cold Booting"
refers to running the game after a PC restart or after some time has passed since last launch.
There's a collection of minor improvements related to animated textures:
+The archive consists of a list of raw DDS files compressed using lz4. + This significantly improves load times when many frames are used.
+The game will now use the first frame of the animated texture until loading of the remaining frames is ready. +This prevents stutters on loading animated textures outside of load screens (e.g. Character Select).
+The in-mod layout editor has received some minor improvements:
+Safe Mode: Prevents updating object data in real time to ensure moving some objects (e.g. Rings) does not lead to crashes.
+Autosave: The layout editor will now create an automatic save of the at regular time intervals. Useful in case you encounter a crash.
+The language of both the game's text and voice can now be changed on the fly. +Some changes (e.g. menu voices) are applied in real time, however others (e.g. localized menu assets) only apply after the next loading screen.
+Startup time of Tweakbox itself has been improved in verison 0.6.0, by approximately 75%. Startup now takes 0.7 seconds, instead of 1.2 seconds.
+When a model for a specific gear is missing (e.g. Sonic + Riders DX Advantage F); Tweakbox will now default to loading the default gear model for that gear type.
+i.e. For boards it will load Default Gear
, for skates it will load Darkness
and for bikes it will load E-Rider
.
This should prevent Tweakbox from crashing when from gear data from the GameCube mods are imported to Tweakbox. (Since those have custom model archives.)
+Tweakbox will now automatically decompress all game files on boot if it detects that they have not been previously decompressed.
+Preview features refer to currently "work-in-progress" features.
+These features are generally available in the current release but are not finalized and/or may have potential slight changes in the future.
+ + + + + + + + + + + + + +Starting with version 0.7.0, Tweakbox offers a built-in API which allows you to control Tweakbox functionality as well as perform certain other operations which affect the state of the game.
+Setup usually takes around 2 minutes if you know what you're doing. If you're new to programming however, it might take you a while, be patient!
+Refer to the Reloaded-II wiki ("Building Mods") for guidance.
+git clone --recursive https://github.com/Sewer56/Riders.Tweakbox.git
+
or add as git submodule
+git submodule add https://github.com/Sewer56/Riders.Tweakbox.git
+git submodule update --init --recursive
+
First add it to your solution by right clicking it. +
+and find Riders.Tweakbox.Interfaces.csproj
+
Then, add it as a project dependency to your Reloaded-II mod. +
+ +Edit your project's ModConfig.json
to include Riders.Tweakbox
as part of the ModDependencies
.
In your Start
function of the mod, grab an interface to the R-II.
// Get the API Controller
+_modLoader.GetController<ITweakboxApi>().TryGetTarget(out var apiAccessor);
+
+// Register to the tweakbox API
+var api = apiAccessor.Register($"{config.ModId}.{config.ModVersion}");
+
+// Use the API
+var gearApi = api.GetCustomGearApi();
+gearApi.RemoveVanillaGears();
+
Reloaded-II Documentation on Controllers
+For more examples, consider looking at the example Riders.Tweakbox.Gearpack
and Riders.Tweakbox.CharacterPack.DX
projects contained in this repository.
Tweakbox rewrites some game code to make features such as custom gears possible. Therefore, some fields in libraries such as Sewer56.SonicRiders
will need to be updated.
To obtain the updated pointers, use the GetPointers
method.
// Update Gear Data Pointer
+var pointers = modImpl.GetPointers();
+Sewer56.SonicRiders.API.Player.Gears = new FixedArrayPtr<ExtremeGear>((ulong)pointers.Gears.Address, pointers.Gears.NumItems);
+
// ICustomGearApi obtained via api.GetCustomGearApi();
+public class BlueStarIIDX : CustomGearBase, IExtremeGear
+{
+ private BoostProperties _boostProperties = new BoostProperties()
+ {
+ AddedBoostChainMultiplier = 0.15f,
+ AddedBoostDurationLv3 = 30
+ };
+
+ /// <summary>
+ /// Initializes this custom gear.
+ /// </summary>
+ public override void Initialize(string gearsFolder, ICustomGearApi gearApi)
+ {
+ // Import a custom gear exported from the built-in `Export Custom Gear`
+ // function in the gear editor.
+ var data = gearApi.ImportFromFolder(Path.Combine(gearsFolder, "BlueStarII DX"));
+
+ // Attach a class that overrides gear behaviours (via IExtremeGear)
+ data.Behaviour = this;
+
+ // Add the custom gear to the game!
+ gearApi.AddGear(data);
+ }
+
+ // IExtremeGear API Callback
+ public BoostProperties GetBoostProperties() => _boostProperties;
+}
+
If you need to get the location of your mod's folder...
+// In your mod's `Start` method.
+_modLoader.GetDirectoryForModId(MyModId)
+
public class Sonic : LateBoosterCharacter, ICustomStats
+{
+ private BoostProperties _boostProperties = new BoostProperties()
+ {
+ AddedBoostDurationLv2 = 60,
+ AddedBoostDurationLv3 = 60,
+ };
+
+ /// <summary>
+ /// Initializes this custom character.
+ /// </summary>
+ public void Initialize(Interfaces.ICustomCharacterApi characterApi)
+ {
+ Request = new ModifyCharacterRequest()
+ {
+ Behaviour = this, // Modifies the character behaviour.
+ CharacterId = (int) Characters.Sonic, // Character Index. See Sewer56.SonicRiders.Structures.Enums.Characters
+ CharacterName = "Sonic DX",
+ Stack = false // Does not combine with other mods.
+ };
+
+ // Modify your character!
+ characterApi.AddCharacterBehaviour(Request);
+ }
+
+ // Overrides for ICustomCharacter interface.
+ public ApiCharacterParameters GetCharacterParameters() => new ApiCharacterParameters()
+ {
+ SpeedMultiplierOffset = 0f
+ };
+
+ public BoostProperties GetBoostProperties() => _boostProperties;
+}
+
Usage: +
// Get API
+var characterApi = api.GetCustomCharacterApi();
+
+// Add character
+var sonic = new Sonic();
+sonic.Initialize(characterApi);
+
Here's an example of how you could implement character 'archetypes'/'classes' (categories) for a cleaner approach.
+Base Character Class: +
public abstract class CustomCharacterBase : ICustomCharacter
+{
+ public ModifyCharacterRequest Request { get; private set; }
+ public abstract string Name { get; }
+ public abstract Characters Character { get; }
+
+ /// <summary>
+ /// Initializes this custom character.
+ /// </summary>
+ public void Initialize(Interfaces.ICustomCharacterApi characterApi)
+ {
+ Request = new ModifyCharacterRequest()
+ {
+ Behaviour = this, // Modifies the character behaviour.
+ CharacterId = (int) Character, // Character Index. See Sewer56.SonicRiders.Structures.Enums.Characters
+ CharacterName = Name,
+ Stack = false // Does not combine with other mods.
+ };
+
+ // Modify your character!
+ characterApi.AddCharacterBehaviour(Request);
+ }
+}
+
Define the character class: +
// An implementation of Sonic Riders DX 1.0.0 Late Booster Character
+public abstract class LateBoosterCharacter : CustomCharacterBase, ICustomCharacter
+{
+ // These are all callbacks for the ICustomCharacter interface.
+ private BoostProperties _boostProperties = new BoostProperties()
+ {
+ AddedBoostDurationLv2 = 60,
+ AddedBoostDurationLv3 = 60,
+ };
+
+ public ApiCharacterParameters GetCharacterParameters() => new ApiCharacterParameters()
+ {
+ SpeedMultiplierOffset = 0f
+ };
+
+ public BoostProperties GetBoostProperties() => _boostProperties;
+}
+
Give the character that class (via inheritance): +
public class Sonic : LateBoosterCharacter, ICustomStats
+{
+ public override string Name { get; } = "Sonic DX";
+ public override Characters Character { get; } = Characters.Sonic;
+}
+
Riders.Tweakbox provides basic support for animated textures.
+In order to make an animated texture, you should create a folder with the name of the texture; and inside that folder, make files with file names corresponding to individual keyframes of the animation.
+The built-in texture animator will play back your animation, starting with the last frame of animation. As Riders runs at 60 frames per second, a file with the name of 060
, will run on the 60th frame.
Tip: When dealing with many textures, a tool like Bulk Rename Utility might come in handy.
+It is recommended to use this feature sparringly.
+High framerate animated textures are expensive on video memory, especially when paired with high resolutions. Going too far might make it hard for people with integrated graphics to run your mod.
+PLEASE OPTIMISE YOUR ANIMATED TEXTURES +The examples here use PNGs for clarity; when you release your textures, you should use native DDS files.
+Alternate between two colours using a specified time interval.
++
+In this scenario, the green texture for 30 frames (0.5 seconds) before switching to the red texture. After another 30 frames, you will go back to the green texture.
+Create Hyper Sonic by changing Super Sonic's texture every frame.
++
+[Frame 74 of the Animation]
+ + + + + + + + + + + + + +{"use strict";/*!
+ * escape-html
+ * Copyright(c) 2012-2013 TJ Holowaychuk
+ * Copyright(c) 2015 Andreas Lubbe
+ * Copyright(c) 2015 Tiancheng "Timothy" Gu
+ * MIT Licensed
+ */var Va=/["'&<>]/;qn.exports=za;function za(e){var t=""+e,r=Va.exec(t);if(!r)return t;var o,n="",i=0,a=0;for(i=r.index;i