Extensions
An extension is a package that plugs into — and requires — one or more existing base systems. It cannot run on its own. Instead of shipping its own engine, it drops content into base systems that are already installed.
- Base system: a standalone, feature-complete system that ships an engine plus a registry or dispatch layer that auto-discovers content (e.g.,
Skill System,DevProducts Handler,Combat System). - Extension: a smaller package that adds entries into those base systems.
An extension is not a special package type — in the marketplace it's still a normal system/library. What makes it an extension is two things working together:
- It declares its base system(s) as required dependencies in
relevant_systems.json(always_on: true). - Its files and
Instructions.mdregister its content into those base systems rather than standing alone.
Note: extensions go by different names in different systems' docs (the DevProducts Handler calls its shop extensions "Connected Shop Libraries"). "Extension" is the umbrella term for all of them.
Walkthroughs by system family
Different base systems expose different extension points, so each family has its own concrete, end-to-end walkthrough. This page covers the shared contract; pick the family that matches what you're building:
| Walkthrough | Extension → base | What's distinctive |
|---|---|---|
| Skill extension | Fireball Skill → Skill System | Registry entry via Instructions.md, drop-in modules, VFX, animation upload |
| Shop extension | Cash Pack Shop → DevProducts Handler | Multiple required deps, drop-in shop section + product set, dev-product upload |
| Combat extension | Melee System → Combat System | Required and optional deps, drop-in moveset, animation upload |
The rest of this page is the contract every extension follows.
Step 1 — Declare required (and optional) systems
Use relevant_systems.json at the zip root. Mark every system your extension needs with always_on: true; mark systems that merely enhance it with always_on: false. The installer pulls required systems in first if missing, and offers optional ones as unchecked choices.
Melee System shows both in one file — Combat System and DamageHandler are required, NPC System is optional:
[
{
"display_name": "Combat System",
"unique_id": "144835c0-4f96-43ea-8707-8429b4f99b22",
"always_on": true,
"isInitiallyChecked": true
},
{
"display_name": "DamageHandler",
"unique_id": "ca59f635-993a-4741-8c81-c9f7370fbf48",
"always_on": true,
"isInitiallyChecked": true
},
{
"display_name": "NPC System",
"unique_id": "07473040-45dc-4afa-bb24-462e187d10ee",
"always_on": false,
"isInitiallyChecked": false
}
]Rules:
- List every system your extension needs to function — not just the obvious one.
always_on: true→ hard requirement, can't be unchecked.always_on: false→ optional; useisInitiallyCheckedto decide if it's pre-selected.- Use the real
unique_idfrom the marketplace registry — never a path or download URL. - Dependencies chain automatically: a base system's own
relevant_systems.jsonmay be[](standalone, like DevProducts Handler) or may list its dependencies (Combat System requires DamageHandler + NPC System).
See the relevant_systems.json page for the full contract.
Step 2 — Ship drop-in files into the base's extension points
Base systems expose folders they auto-discover. Put your extension's files there under the normal service-folder layout in Unpack_On_Source/, using unique names so extensions don't collide — that's what lets many extensions live in the same folder without editing each other.
Each family uses different extension-point folders (Skills/…, DevProductSets/, Shop/Sections/, Combat/…) — see the walkthroughs for the exact paths.
Binary assets destined for the DataModel (UI, VFX, models) go in Unpack_On_Roblox_Studio/, mirroring the base's asset hierarchy, one .rbxm per instance. A package may include an unpack_on_roblox_studio_meta.json manifest describing those exports. Folder rules are identical to any system — see How to add a template asset.
Step 3 — Register via Instructions.md
Drop-in files cover new, non-conflicting files. When an extension must add an entry to a shared file that may already exist (and may be shared with other extensions), do it in Instructions.md so the AI edits it idempotently ("if the file exists, add the entry; if not, create it").
Write instructions that state the required base system up front, give exact paths and concrete values, and spell out any required edits to shared files (e.g., ProfileTemplate.lua). See the Instruction Runner section in How to add a template asset.
Step 4 — Wire user-uploaded asset IDs with tokens
If your extension references assets the user must create under their own account (dev products, gamepasses, animations, sounds), ship them under To_Upload_By_User/ with a superbullet_metadata.json mapping a placeholder token to the real ID.
Two methods:
- Primary (
token+source_path) — the token is replaced in-place inside a Lua source file. Used by Cash Pack Shop (dev products) and Melee System (animations). - Fallback (
instruction_token) — the real ID is surfaced throughInstructions.mdinstead of a Lua file. Used by Fireball Skill (animation).
For the full contract and when to use each, see the dedicated pages: Developer products, Gamepasses, Animations, and Sounds.
metadata.json
Same file as any system. Real extensions fill in name and description too, not just version:
{
"name": "Melee System",
"description": "Melee combat with punches and kicks...",
"version_number": "1.0.3",
"created_by": "Superbullet"
}- Bump
version_number(semantic versioning) on every re-upload so the extension updates for everyone. - If the extension relies on behavior added in a specific base-system version, say so in
Instructions.md.always_onguarantees the base is installed, not that it's a particular version.
Shared checklist
relevant_systems.jsonlists every required system withalways_on: trueand a validunique_id; optional systems usealways_on: false.- Drop-in source files use unique names and live in the folders the base system auto-discovers.
Instructions.mdregisters into shared files idempotently, with exact paths and concrete values.- Any user-uploaded assets have a
To_Upload_By_User/**/superbullet_metadata.jsonwith correcttoken/source_path(orinstruction_token). - Binary DataModel assets are in
Unpack_On_Roblox_Studio/;.rbxmfilenames match instance names; no scripts there. metadata.jsonhasname,description, and a bumped semanticversion_number.