SRB2Kart/Getting started with modding
Sonic Robo Blast 2 Kart is known for its ease of modability, even compared to its sister game Sonic Robo Blast 2, but due to key differences in how both games are structured and made, various systems are not completely the same, and require new skills to learn and new information to know. This page goes over various key things to know in order to start modding SRB2Kart.
General
SRB2Kart addons go into their own "SRB2Kart v1.x" section in the SRB2 Message Board, and their addon PK3 and WAD names are prefixed by a K
letter, or X
for cross-compatible mods between SRB2 and SRB2Kart. For example, K_MyMod_v1.wad
would be a mod that is designed and made for SRB2Kart. For more information, see the Filename Conventions thread, and more applicably, the Submissions Rules & Help forum, in the Message Board.
No matter the type of modding, using a lump editor is extremely recommended, such as SLADE.
As SRB2Kart is based on Version 2.1, it does not have any of the newer, more-convenient features that SRB2 has, such as SPR2 support for Sprites, UDMF for levels or Lua support for various systems within the game.
A list with various available editing features in SRB2Kart can be found in the Editing features section of the main SRB2Kart page.
Skins
- See also: SRB2Kart/Character WAD
Skins, also known as characters or racers, have various requirements to be met in SRB2Kart, needing sprites for various animations and UI elements, in addition to requiring sound effects for whether the characters do something specific, such as throwing an item or winning the race, and having their own specific racing-related stats. See SRB2Kart's Character WAD page for more information.
Character Lua
Lua scripts can be used to make characters stand out, such as Secondcolor and Simple AnimaL, which further extend their moddability. However, it should be noted that any Lua script loaded, even those from character WADs, will cause SRB2Kart to consider it a cheated game, and thus it will not allow players to play Time Attack with such mods. Characters without Lua are fine to load and play Time Attack with.
A workaround exists by way of using the Custom Gamedata addon, but although this will allow usage of major mods such as Lua scripts, it also moves the player's progress into a new save file, with no way of transferring the vanilla game's progress over. Players are suggested to first complete Time Attack's gold medals before playing with custom gamedata.
Kartmaker
Kartmaker is an open-source Windows executable designed to make the creation of Kart characters into a more friendly and straight-forward process. Kartmaker is a command-line program intended to be used as though a drag-'n'-drop application in which a directory in a user's file explorer is dropped onto the Kartmaker application and from this Kartmaker is able to produce a WAD based upon assets (such as images and sounds) within that dragged directory. The assets within the directory and how they are interpreted by Kartmaker is defined partly by a required properties.txt
file within the dragged directory and partly by limitations of Kartmaker itself. Additionally, the subdirectory containing the required properties.txt
will also be required to contain a sprites.png
. The sprites.png
file is a sprite-sheet representation of all frames of animation that will be included in the WAD produced by Kartmaker when processing the directory which contains this sprites.png
file along of course with its sibling properties.txt
file. The contents of sprites.png
are largely up to the interpretation of the developer altering properties.txt
, and so such details will be left to the below table one has no doubt noticed by now.
The aforementioned properties.txt
file is a JSON
-format text file which is parsed by Kartmaker's JSON
library to reinterpret files within the same directory as that properties.txt
file as lumps in the WAD that Kartmaker will produce from the assets in that directory. In properties.txt
, just as any JSON
-format file, one will find a series of key-value pairs formatted such that a string
literal name is on the left paired with a value of any type to the right of that string
literal name (examples may include "name": "example",
, "stats": [5, 5],
, "startcolor": 160,
). The keys in this collection of key-value pairs shall be the same keys across all variations of the properties.txt
file, however it is in the values of these keys that the developer of a WAD can customize how Kartmaker interacts with that developer's assets. Below is a table of each key one can expect to find in an iteration of properties.txt
(prefixed by a heirarchy of parental keys if present), examples of that value type in the context of the key itself, and how that key-value pair influences the WAD produced by Kartmaker when the directory containing the previously mentioned iteration of properties.txt
is processed by Kartmaker:
Key Path | Expected Value Type | Value Examples | Influence Over The WAD Kartmaker May Produce |
---|---|---|---|
name | string | "john", "mario_myversion_notyours", "mary-sue", "the_villain", "mister_100" | The data name of the character the WAD represents. This is how the game engine differentiates between character WADs loaded, so make sure to write a value that isn't likely to be present in any other iteration of properties.txt used by any other developer to produce a character WAD. Additionally, make sure that only lower-case/numerical/hyphen characters are used in the value and that there are no spaces in the value, either of these conditions being failed will lead to a character WAD failing to load in-engine. In the event one needs to use a space despite spaces being a forbidden character in the context of this key's value, underscores should be used in place of space characters, for example turning a phrase like this into a_phrase_like_this .
|
realname | string | "John", "Mario", "Mary-Sue", "The_Villain", "Mr._100" | The display name of the character the WAD represents. This is how the game engine will display the name of the character the WAD represents in all contexts where such a thing is neccessary such as on character select screens. Unlike the name key, it does not matter if the value for this key is used during the development of several different Kartmaker properties.txt file iterations as this key is not used in-engine to identify and marshall data unique to individual character WADs, the value of this key is purely cosmetic. However, similar to the name key, one must make sure there are no space characters present in the value for this key, replacing with underscores as one would do for the value of the name key all the same.
|
gfx_prefix | string | "JOHN", "MRIO", "MASU", "VLAN", "MR1H" | The data name prefix of the frame graphic lumps of the character the WAD represents. The value of this key on a surface level serves a similar purpose to the value of the name key in that the value of this key differentiates between which frames of animation belong to which character WADs. Much as with the value of the name key, make sure to write a value that isn't likely to be present in any other iteration of properties.txt used by any other developer to produce a character WAD or else the frame graphic lumps of one character WAD will conflict with the frame graphic lumps of one's own character WAD in a manner determined by the order in which the two conflicting WADs are loaded into memory in-engine. The value of this key must be completely upper-case, must only use alphanumeric characters, and must be 4 characters in length. It is common convention to make the value of this key read to be the same as a greatly abridged version of the value entered for the name key. If one's value for this key conflicts with the value of any existing known character WAD on the SRB2 Message Board, then the submission of the WAD containing the value for this key and by extension all data related to the character using the key's value will be rejected by judges of the board.
|
stats | int[2] | [1,9], [5,5], [4,7] | The speed and weight the character the WAD represents should handle at respectively in-engine. Both values of the 2-element integer array that the value of this key is should be between the integer values of 1 and 9 inclusive. If either value of the 2-element integer array that the value of this key is falls outside of the range of 1 to 9, then undefined behaviour shall occur in-engine and the character will not handle to a subjectively agreeable playable degree. |
startcolor | int | 160, 255, 0 | A representation of which colours in the frame graphic lumps inside of an example WAD produced by Kartmaker are to be the colours that change when a player chooses a skincolor in-engine. The value of this key is an integer index to one of the 256 colours of the PLAYPAL.lmp palette included as a sibling file alongside the Kartmaker executable with the first index of the 256 possible indexes starting at 0 and going up to 255 . The easiest way to imagine this if one is unfamiliar with the concept of arrays and indexing is that the PLAYPAL.lmp palette is a 2-D grid of 256 colours in which each tile on the grid not only represents a colour but also an index unique from any other tile in the grid that is some value from 0 to 255 . It does not matter if colours in the palette repeat or have some overlapping data because tiles in the grid are identified by their unique index and not their colour. By default, the colours and colour indices in the aforementioned PLAYPAL.lmp palette are identical to the colours and colour indices of the palette that SRB2Kart uses to render frame graphic lumps by-design. From the colour at the index of the value of this key in the PLAYPAL.lmp palette, 16 colours are read in sequential index order and it is this set of colours that are determined to be the colours that will change for a player when selecting a skincolor in-engine. For example, if the value of this key were to be 160 , then colours at indices from 160 to 175 in the PLAYPAL.lmp palette would be determined as the colours from one's frame graphic lumps to recolour when a player selects a skincolor in-engine. A value for this key that is less than 16 indices away from the maximum index of 255 will simply wrap the remainder indices back around to 0 . Altering PLAYPAL.lmp to be a different palette from what it is by-default will not affect how frame graphic lumps are recoloured in-engine as PLAYPAL.lmp merely exists for the reference of both the developer and other operations of Kartmaker itself, so in most scenarios it is best to leave the file alone and to its default state.
|
prefcolor | string | "red", "yellow", "white" | The name of the palette in-engine which skincolor should default to when one plays as the character this WAD represents. The simplest way to determine the value one desires for this key is to flick through palettes on a character selection screen within SRB2Kart and find the name of the palette one thinks would look best for their character's WAD as the display name of palettes in-engine is the same as the data name for those palettes.
|
transparent_colors | int[n%3==0] | [0,1,2,3,4,5], [0,1,2], [3,4,5] | A set of RGB values to determine which colours in the sprites.png sprite-sheet should be treated as transparent pixels when that file is processed by Kartmaker. Pixels from sprites.png with an alpha value other than 1 cannot be read properly by Kartmaker and so surrogate colours from an RGB palette must be surrendered as placeholder. However, with 16777216 possible colours in this palette as opposed to SRB2K's 256-colour palette, simply surrender a colour or series of colours that aren't in SRB2K's 256-colour palette and no disruption to one's development should occur. The array that this value is must be of a multiple of 3 in length as each value in the array represents one channel of an RGB colour. For example, an value of [100,115] for this key would not work because that is only enough information for Kartmaker to determine the R and G channels of one RGB colour whereas a value of [20,210,80] or [6,17,99,37,143,151] would work because those values are enough information to define exactly one RGB colour or two RGB colours respectively. Additionally, each value within the array that this value is must be an integer between 0 and 255 inclusively.
|
sprites_comment | string | "apple", "cherry", "soda" | A completely superfluous key-value pair only present in a standard properties.txt iteration as a way to communicate to the end developer some intention about this particular properties.txt iteration. The value of this key can be ignored entirely and left unchanged as it does not factor into the WAD output of Kartmaker processing a directory containing a properties.txt file at all.
|
sprite_size | int[2] | [80,80], [40,40], [256, 256] | The shared dimension, in pixels, of each frame of animation in the aforementioned sprites.png file sharing a directory with the properties.txt file these key-value pairs can be found within. Due to limitations of free-use libraries within the source code of Kartmaker, one cannot have a sprite_size in which the two values of the sprite_size multiply to be a value larger than 256*256 .
|
sprites | JSON | <variable> | A collection of keys of JSON type which each themselves are a collection of keys representing a frame lump graphic added to the WAD that is output by Kartmaker upon processing a properties.txt file. This key alone is quite useless to the end developer and is only used as reference within Kartmaker itself.
|
sprites\<variable> | JSON | <variable> | A collection of keys of varying types which defines a frame lump graphic to be added to the WAD that is output by Kartmaker upon processing a properties.txt file, in particular upon processing the parent sprites key of this key. Much like the sprites key, this key is largely useless to the end developer, however the name chosen for this key will be the name of the frame lump graphic that this data represents when processed into a WAD file by Kartmaker.
|
sprites\<variable>\offset | int[2] | [40,71], [0,0], [5,15] | The distance, in pixels, from the top-left corner of the frame lump graphic that the parent key of this key represents to consider the pivot point of the frame lump graphic. For example, with a sprite_size of [80,80] and a value for this key of [40,70] , the frame lump graphic that the parent key of this key represents would be 80px wide and 80px tall, and so the pivot point would be 40px from the left and 70px from the top of that frame lump graphic. Whatever value is used for this key, the pivot should be intended to be around the pixels of the frame lump graphic that represent the bottom of the centre of the frame's illustrated figure.
|
sprites\<variable>\layers | int[2][] | [[0,0], [80,0]], [[320,80],[50,100],[90,911]] | A collection of coordinate pairs used to read pixels from the aforementioned sprites.png sprite-sheet. Each element in this array is itself another array of 2 integer elements, and each of those 2 integer elements represent an offset, in pixels, from the top-left corner of the sprites.png sprite-sheet to read pixels from to produce the frame lump graphic that the parent key of this key represents. From each pair of 2 integer values in the array that is this key's value, sprite_size[0] pixels will be read horizontally in a rightwards direction and sprite_size[1] pixels will be read vertically in a downwards direction. Each pair of 2 integers in the array that the value of this key is will be read in reverse order of the array that the value of this key is, that is to say that the last pair in the array that the value of this key is will be read first and vice-versa.
|
sprites\<variable>\vibrate | boolean | false, true | When the value of this key is true , then the frame lump graphic that the parent key of this key represents will have a vibration graphical effect applied unto it, otherwise the value of this key will not alter the frame lump graphic that the parent key of this key represents. This is an optional key which, if omitted, will assume a value of false .
|
sprites\<variable>\flip | boolean | false, true | When the value of this key is true , then the frame lump graphic that the parent key of this key represents will be flipped horizontally, otherwise the value of this key will not alter the frame lump graphic that the parent key of this key represents. This is an optional key which, if omitted, will assume a value of false .
|
sprites\<variable>\heightfactor | int | 1, 2, 3, 4 | The vertical pixel size of the frame lump graphics that the parent key of this key represents will be divided by the value of this key. Sibling keys such as offset and layers are unaffected by the value of this key and can be written as though the value of this key were 1 and therefore had no effect on the outcome of the frame lump graphic the parent key of this key represented. This is an optional key which, if omitted, will assume a value of 1 .
|
gfx | JSON | <variable> | A collection of keys of integer array type used to capture various miscellaneous graphics from the sprites.png sprite-sheet. Useless on its own to the end developer, but required for Kartmaker to know where to find the collection's variable list of keys.
|
gfx\<variable> | int[6] | [492, 162, 16, 16, 0, 0] | A collection of integers used to capture various miscellaneous graphics from the sprites.png sprite-sheet. The name of the key will be the suffixed name of the graphic captured as a lump in the WAD Kartmaker produces based upon this properties.txt file. The exact intent of each integer is still a bit of a mystery to me, but I can define that, counting up from 0 , index 1 represents an offset in pixels from the top of sprites.png to read from, index 2 is how many pixels to read from that point horizontallly in a rightwards direction, and index 3 is how many pixels to read from that point verticlally in a downwards direction. Indices 0 , 4 , and 5 I personally as the author do not know the intent of.
|
sfx | JSON | <variable> | A collection of keys of string type which define where Kartmaker can find the sound effects the character the WAD that Kartmaker will produce is to represent. Useless on its own to the end developer, but required for Kartmaker to know where to find the collection's variable list of keys. |
sfx\<variable> | string | "/gloat.ogg", "/sounds/win.ogg" | Defines the relative path (starting from the path to the properties.txt file) at which Kartmaker can find one of several sound effect files to be included as lumps in the WAD Kartmaker will produce from information in this properties.txt file. The name given to the key for this value will be the suffix of the name the sound effect has inside the WAD file, the exact construction of the full name of the sound effect within the WAD file being irrelevant so long as each key within the parent key of this key has a distinct name from all other keys it shares a parent with. There are several rules which the file at the path provided as the value for this key must follow for SRB2Kart to be able to use the WAD representing this character without risk of a crash. Firstly, the sound file at the path of the value of this key must be in .ogg format and have the .ogg file extension. Secondly, the sound file at the path of the value of this key must be 16-bit, have a 44100Hz sample rate, and be in stereo. Thirdly, all sound effects an SRB2Kart character needs to rely on must be present in the character WAD even if the sound effect is silence. Lastly, and this is unrelated to the WAD itself but moreso the proper generation of the WAD, the parent key of this key is expected to have exactly 11 keys as its children with this key being 1 of those 11 keys. Each of those 11 keys needs a specific 2-character name and those names are as follows: GL , WI , LS , SL , H1 , H2 , A1 , A2 , B1 , B2 , HT .
|
Assuming all clauses of the above table detailing all the various key-value pairs of a standard properties.txt
file are accounted for and that all files references by properties.txt
are present as siblings of that file including the sprites.png
sprite-sheet defined to the filled clauses of that properties.txt
file, then the directory containing the properties.txt
file should be ready to be dragged onto the Kartmaker executable. If all has gone to plan, Kartmaker should almost immediately pop out a WAD file of the same name as the subdirectory the WAD file was based on as a sibling file to that directory.
In order to transform WAD files into PK3 files, it is recommended to use the WAD2PK3 or the convertpk3 utilities.
Levels
- See also: Zone Builder tutorial
Levels, also known as maps or tracks, are the backbone of SRB2Kart, as there would be nowhere to race in without them.
There's two distinct game modes in SRB2Kart that levels use, those being Race and Battle:
- Race levels have the players go through a closed circuit, or from a starting point to a definite end (officially known as a Sprint Race, or a Section Race by its map header), and they must complete all laps faster than others in order to win. These levels use Player Starts from 1 to 16 (where the 1st player start is the one farthest away from the Finish Line, and the 16th start is the closest one to it), have Random Item rows spread across every lap, utilise Checkpoints and Waypoints, and require more track design knowledge than Battle levels.
- Battle levels have the players duke it out in small, closed spaces with Random Items scattered about, and with Bumpers to act as a lives mechanic. Players start with three bumpers, and whoever is the last one standing is the one who wins. Additionally, players with no more bumpers instead go into an Attack or Protect mode where they will respawn as a playable Self-Propelled Bomb to hit players as, or to provide items to alive players, in order to come back into the game. Battle maps are considered a lot more simpler to create and design than Race maps, and only use Match Starts with no Checkpoints or Waypoints.
Zone Builder is the level editor of choice for creating levels. Since SRB2Kart is fundamentally different from SRB2, a different setup needs to be done in order for it to work properly for SRB2Kart. Guides related to Zone Builder include:
- Setting up Zone Builder for SRB2Kart can be found here.
- A level creation tutorial for Zone Builder can be found here.
- A video-based level creation tutorial made by SeventhSentinel can be found here.
Because of the game's finite number of map slots, a community-run tracker is maintained by community members Diggle and Mr.Logan, in order to prevent map slot overlap. If you are creating a new map, make sure to pick from one of the unused map slots. This tracker can be found here.
Level Design
Race tracks have much higher standards than Battle tracks, and because of it, various guides have been made so that creators can meet them:
- Kart Krew has made a Track Design tutorial for race levels, which can be found here.
- Every level is recommended to have a minimap, including Battle maps, which can be found here.
Random Item sets in Race levels have some recommendations to follow:
- Only 12 Random Items per normal set. For equal path splits, the items should be equally divided between each path. Wider roads can get away with more items, up to 16.
- Randomly distribute them in the area they are supposed to go. This makes Eggman Monitors much more effectively placed as decoys near actual items, and it also slightly incentivises light or acceleration characters in Time Attack, by changing the racing line needed each lap.
- Place them on a 64x64 grid. This makes their sprites have decent spacing, and encourages more committal racing lines.
- Do not make Random Items float above ground. This makes Eggman Monitors conspicuous when placed near them.
- Space item sets about 15 to 20 seconds apart, using Sonic's speed as a baseline. This encorages players to use what they're handed skillfully instead of constantly rerolling until they get lucky.
Encore Mode
Encore Mode is an unlockable mode in SRB2Kart, which horizontally flips the level's layout as well as remapping the colours of the level into something else, akin to Sonic Mania's Encore Mode. Custom levels can also change the level in various ways through the Encore Load linedef type 328.
- A tutorial for setting up Encore Mode can be found here.
Lua
Lua (also known as BLua, for being a version of Lua with less features) is the main scripting language used to interface with SRB2Kart, with the Wiki including pages for the game's Userdata Structures, Functions, Hooks and Global Variables and Constants. Modders new to scripting for SRB2Kart are suggested to take a look at the Freeslot, Object, State and Sprite pages as well, as this information is fundamental to understand how the game works under the hood.
Because the Wiki's general information is kept up to date with Version 2.2, scripters are suggested to click on a page's View History button at the top right of each page, to the left of the search bar, and load versions that are from around 2018 to 2019, as this information will be more accurate to Kart's Version 2.1 base.
In order to aid with scripting better, syntax highlighting and autocomplete options exist for Notepad++, which is recommended to use.