Preset operations
Presets are shorthand operations in mod.yaml. You write one line such as preset: menu-icons; the Carbon launcher expands it into one or more replace-file or replace-directory steps before patching your Roblox install at launch.
The launcher code is in project/carbon/Mods/ModPresetRegistry.cs. For working examples, copy patterns from project/builtin-mods/.
How presets run in the app
Section titled “How presets run in the app”- Discover: On the Mods page, Carbon loads bundled mods from the app install and community folders from your profile
mods/directory (Skeleton.Mods, typically<Carbon root>/mods/<id>/). - Configure: Toggles, dropdowns, and file pickers from
settingsrender on each mod card. Changes are saved toconfig.jsonin that mod’s state directory:- Community mods:
config.jsonlives next tomod.yamlinside the mod folder. - Built-in mods: read-only assets ship with the app; writable state (including
config.jsonand enable/disable) lives underbin/configs/mods/<mod-id>/(ModManager.BuiltinStateRoot).
- Community mods:
- Enable: Turning a mod on removes a
.disabledmarker from the state directory; turning it off writes that marker. Disabled mods are skipped entirely. - Apply on launch: When you start a session,
ModManager.ApplyEnabledModsresolves placeholders fromconfig.json, evaluateswhen/unless, expands presets, then merges or replaces files under the selected Roblox version folder. Higherprioritywins when two enabled mods target the same path.
If a preset path is wrong, the patch often fails quietly in-game. Compare your folder layout with a built-in mod that uses the same preset.
mode: merge vs single-file presets
Section titled “mode: merge vs single-file presets”| After expansion | Meaning |
|---|---|
replace-file |
One source file overwrites one Roblox-relative target. |
replace-directory with mode: merge |
Every file under source is copied into target, keeping other files in that folder. |
replace-directory with mode: replace-tree |
Replace the entire target tree (rare in built-ins; defaults to merge). |
Most bundle presets (sounds, menu-icons, skybox, …) expand to directory merge into a fixed Roblox root.
Preset catalog
Section titled “Preset catalog”These names are valid in operations[].preset (case-insensitive):
| Preset | Expands to | Default target root(s) | Built-in example |
|---|---|---|---|
cursor |
Four replace-file ops (same PNG to each path) |
Arrow cursor PNGs under content/textures/... |
Cursor Swapper (below) |
menu-icons |
replace-directory merge |
content/textures/MenuBar |
Menu Bar Pack (below) |
sounds |
replace-directory merge |
content/sounds |
movement-sounds, soft-ui-sounds |
skybox |
Two merges: .../cubemap → PC sky textures; .../dynamic → content/sky |
See skybox layout below | skybox-pack, night-sky |
dynamic-sky |
replace-directory merge |
content/sky |
(none) |
textures |
replace-directory merge |
content/textures (override with target) |
(none) |
fonts |
Two merges | content/fonts and PlatformContent/pc/fonts |
(none) |
ui-textures |
replace-directory merge |
ExtraContent/textures/ui (override with target) |
Narrow with target: ExtraContent/textures/ui/InGameMenu |
translations |
Single replace-file |
ExtraContent/translations/CoreScriptLocalization.csv |
(none) |
Optional fields on any preset operation:
source: Required. Path under the mod folder; may use{settingKey}placeholders.mode: Usuallymerge(default when omitted).target: Only for presets that support narrowing (textures,ui-textures).when/unless: Boolean setting keys; skip the operation when the condition fails.
Walkthrough: Menu Bar Pack (menu-icons)
Section titled “Walkthrough: Menu Bar Pack (menu-icons)”This is the smallest preset that still shows settings → folder merge → in-game UI.
1. Manifest
Section titled “1. Manifest”From project/builtin-mods/menubar-pack/mod.yaml:
apiVersion: carbon.mods/v1id: menubar-packname: Menu Bar Packauthor: Carbonversion: 1.0.0description: Reskin the top menu bar icons (home, chat, menu, leave, emote).priority: 8settings: - key: theme type: dropdown label: Icon theme description: Merges themed icons into content/textures/MenuBar. default: neon options: [neon, dark, minimal]operations: - preset: menu-icons source: assets/menu/{theme} mode: merge2. Asset layout
Section titled “2. Asset layout”Filenames must match what Roblox expects under content/textures/MenuBar:
menubar-pack/ mod.yaml assets/ menu/ neon/ icon_home.png icon_chat.png icon_menu.png icon_leave.png icon_emote.png dark/ ... minimal/ ...Carbon merges only the files you ship; it does not delete unrelated menu icons in the client.
3. In the desktop app
Section titled “3. In the desktop app”- Open Mods → Installed Mods.
- Enable Menu Bar Pack.
- Expand settings and pick Icon theme (
neon,dark, orminimal). The app writesthemetoconfig.jsonunderbin/configs/mods/menubar-pack/. - Launch a game. The top menu bar should show your themed PNGs.
neon-menubar is the same preset without settings, source: assets/menu points at a single folder.
Walkthrough: Cursor Swapper (cursor)
Section titled “Walkthrough: Cursor Swapper (cursor)”The cursor preset copies one PNG to four Roblox cursor paths (keyboard/mouse arrow + far variants). You do not list those paths yourself.
settings: - key: useCustom type: toggle label: Use custom cursor default: false - key: cursor type: dropdown label: Preset cursor default: pink options: [pink, blue, amber, mint, high-contrast, classic] - key: customCursor type: file label: Custom cursor PNG accept: image/png assetCategory: cursor
operations: - preset: cursor source: assets/cursors/{cursor}.png unless: useCustom - preset: cursor source: "{customCursor}" when: useCustomBundled presets are files like assets/cursors/pink.png. The Cursor sidebar section in the app is a dedicated UI for this mod; other mods use inline settings on the card.
assetCategory: cursor tells the file picker to validate PNG dimensions (see reference).
Expanded targets (from ModPresetRegistry):
content/textures/Cursors/KeyboardMouse/ArrowCursor.pngcontent/textures/Cursors/KeyboardMouse/ArrowFarCursor.pngcontent/textures/ArrowCursor.pngcontent/textures/ArrowFarCursor.png
Walkthrough: Skybox Pack (skybox)
Section titled “Walkthrough: Skybox Pack (skybox)”The skybox preset expects two subfolders under source:
assets/sky/night/ cubemap/ sky512_bk.tex sky512_dn.tex sky512_ft.tex sky512_lf.tex sky512_rt.tex sky512_up.tex dynamic/ clouds.dds sun.jpg ...settings: - key: preset type: dropdown label: Sky preset default: night options: [night, sunset, storm]operations: - preset: skybox source: assets/sky/{preset} mode: mergeCarbon merges cubemap/ into PlatformContent/pc/textures/sky and dynamic/ into content/sky.
Walkthrough: Movement sounds (sounds)
Section titled “Walkthrough: Movement sounds (sounds)”Drop .mp3 / .ogg files that use Roblox’s filenames into a folder and merge into content/sounds:
operations: - preset: sounds source: assets/sounds mode: mergeExample files from movement-sounds: action_jump.mp3, action_jump_land.mp3, action_footsteps_plastic.mp3.
When to use a preset vs replace-file
Section titled “When to use a preset vs replace-file”| Situation | Use |
|---|---|
| One known path (oof.ogg, one PNG) | type: replace-file |
Several paths driven by {theme} |
Multiple replace-file ops (see ingame-menu-pack) |
| Many files in one Roblox directory | preset: sounds, menu-icons, etc. |
| Same asset must hit multiple fixed paths | preset: cursor |
Debugging tips
Section titled “Debugging tips”- Enable one mod at a time while testing a new preset layout.
- After changing settings, launch again, patches apply at launch, not live in a running client.
- Compare
priorityif two mods touch the same directory (for example two sound packs). - Read launcher logs under
logs/if a mod is skipped as invalid (ModValidatorwarnings).
Next steps
Section titled “Next steps”- Mod authoring: folder layout and sharing zips
- mod.yaml reference: every setting type and operation field
- Built-in mods: copy-paste patterns from all 15 shipped mods