Every custom fluXis skin is driven by a singleDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/InventiveRhythm/fluXis/llms.txt
Use this file to discover all available pages before exploring further.
skin.json file at the root of the skin folder. fluXis deserialises this file into a SkinJson object each time the skin is loaded, and every runtime decision — from how wide a column is to what color a “Flawless” judgement displays — is made by reading values from that object. If the file is absent, fluXis silently substitutes a fully defaulted SkinJson; if it exists but is malformed, an error is written to the runtime log and the Default skin is used instead.
Top-level fields
Metadata about the skin: its display name, creator, and accent color. This object is always written — even if you leave the section empty, fluXis will supply defaults. See info object below.
Per-keymode layout configuration for 1-key mode. Default
column_width: 132. See the Keymode Config page for all available fields.Per-keymode layout configuration for 2-key mode. Default
column_width: 126.Per-keymode layout configuration for 3-key mode. Default
column_width: 120.Per-keymode layout configuration for 4-key mode. Default
column_width: 114.Per-keymode layout configuration for 5-key mode. Default
column_width: 108.Per-keymode layout configuration for 6-key mode. Default
column_width: 102.Per-keymode layout configuration for 7-key mode. Default
column_width: 96.Per-keymode layout configuration for 8-key mode. Default
column_width: 90.Per-keymode layout configuration for 9-key mode. Default
column_width: 84.Per-keymode layout configuration for 10-key and above. Any map with 10 or more keys uses this block. Default
column_width: 78.Hex color strings for each of the six judgement tiers. See judgements object below.
Hex color strings for note snap-divisor highlighting (1/3, 1/4, 1/6, 1/8, 1/12, 1/16, 1/24, 1/48). See snap-colors object below.
A flat key-value dictionary that remaps asset lookup paths. The key is the default logical path that fluXis would normally look for (without extension), and the value is the replacement path to use instead. Both paths are relative to the skin folder root. See overrides dictionary below.
info object
Theinfo block identifies the skin to the player and to the game’s skin selector UI.
The display name of the skin. Shown in the skin selector list. If empty or absent, fluXis falls back to the skin’s folder name.
The name of the person who made the skin. Shown beneath the skin name in the selector.
A hex color string (e.g.
"#FF4FC8") used as an accent color for the skin in UI contexts that support it. An empty string means no accent override.The
path, SteamWorkshop, and IconTexture properties of SkinInfo are runtime-only and are never read from or written to skin.json. Do not include them in the file.judgements object
Thejudgements block controls the color displayed for each hit accuracy tier in the judgement animation, combo counter, and results screen. Every value is a CSS-style hex string.
Color for the Flawless tier — a perfect hit within the tightest timing window. Default is a bright cyan.
Color for the Perfect tier. Default is a teal-green.
Color for the Great tier. Default is a bright green.
Color for the Alright tier. Default is a bright yellow.
Color for the Okay tier. Default is an amber orange.
Color for the Miss tier. Default is a soft red.
GetColorForJudgement behavior
At runtime,SkinJson.GetColorForJudgement(judgement) picks the correct hex string for the given tier and parses it with Colour4.FromHex. If the hex string is invalid or cannot be parsed, the method silently returns Colour4.White rather than throwing. Keep your color strings well-formed to avoid invisible-white judgement text.
snap-colors object
Thesnap-colors block defines the colors used to tint notes in the editor and optionally during gameplay when a skin’s note textures implement ICanHaveSnapColor. Colors are keyed by beat divisor fraction as a JSON property name.
Color for notes snapped to a 1/3 beat divisor (third notes). Default is a coral red.
Color for notes snapped to a 1/4 beat divisor (quarter notes / straight beat). Default is a medium blue.
Color for notes snapped to a 1/6 beat divisor (sixth notes). Default is a lime green.
Color for notes snapped to a 1/8 beat divisor (eighth notes). Default is a golden yellow.
Color for notes snapped to a 1/12 beat divisor (twelfth notes). Default is a purple.
Color for notes snapped to a 1/16 beat divisor (sixteenth notes). Default is a mint green.
Color for notes snapped to a 1/24 beat divisor (twenty-fourth notes). Default is a hot pink.
Color for notes snapped to a 1/48 beat divisor (forty-eighth notes or finer). Default is a mid-grey, marking these as “non-standard” snaps visually.
Snap colors are ordered internally as an array:
[1/3, 1/4, 1/6, 1/8, 1/12, 1/16, 1/24, 1/48]. The GetColor(index) method takes a zero-based index into that array, not a raw divisor value. Invalid indices return Colour4.White. Results are cached after the first parse to avoid repeated hex parsing during gameplay.overrides dictionary
Theoverrides block is a flat JSON object where each key is a logical asset path (without file extension) and each value is a replacement path to use instead. Both paths are relative to the skin folder.
SkinJson.GetOverride(key) looks up the key and returns the replacement string, or null if no override exists. GetOverrideOrDefault(key) returns the replacement if found, or the original key unchanged — this is the call used in CustomSkin before appending a file extension and checking whether the file exists in storage.
GetKeymode behavior
SkinJson.GetKeymode(keyCount) maps an integer key count to its corresponding SkinKeymode block:
| Key count | Returns |
|---|---|
| 1 | 1k block |
| 2 | 2k block |
| 3 | 3k block |
| 4 | 4k block |
| 5 | 5k block |
| 6 | 6k block |
| 7 | 7k block |
| 8 | 8k block |
| 9 | 9k block |
| 10 or more | 10k block |
ArgumentOutOfRangeException. All maps with 10 or more keys share the 10k block.
Complete example
The followingskin.json is a complete, annotated example covering every top-level section. Only fields you want to change from the defaults need to be included.
Validation and error handling
What happens when skin.json is missing?
What happens when skin.json is missing?
If the skin folder does not contain a
skin.json, fluXis logs an informational message and uses a fully defaulted SkinJson object. All layout values, colors, and snap colors will be their built-in defaults. Asset loading continues normally using the files in the folder.What happens when skin.json has a JSON syntax error?
What happens when skin.json has a JSON syntax error?
A
JsonReaderException is caught by SkinManager, an error is written to the runtime log, and fluXis continues with the Default skin active instead. The broken skin will still appear in the skin list but will not change any visuals.What happens when a hex color string is invalid?
What happens when a hex color string is invalid?
Each color parse is wrapped in a
try/catch or a TryParseHex check. An unparseable hex value silently falls back to Colour4.White. Snap color parses are additionally cached, so a bad value is only attempted once per session.Can I add extra fields to skin.json?
Can I add extra fields to skin.json?
Yes — Newtonsoft.Json ignores unknown properties by default, so you can add comments-style fields or future-looking keys without breaking anything. Only the documented fields above are read by the game.
