Skill extension (Fireball → Skill System)
A worked example of a skill extension: a package that adds one skill to the Skill System base. Here it's Fireball Skill. Read the Extensions overview first for the shared contract; this page covers only what's specific to skills.
What it extends
The Skill System auto-discovers skills from a nested SkillRegistry/Categories/<MainCategory>/SubCategories/<SubCategory>.lua structure, and loads client/server skill modules by naming convention (<SkillName>Skill.lua). A skill extension drops in the modules + VFX and registers a data entry.
Step 1 — Declare the base system
One required dependency:
[
{
"display_name": "Skill System",
"unique_id": "12dec21f-2a22-406a-9197-71cfb9fb20cc",
"always_on": true,
"isInitiallyChecked": true
}
]The zip
Fireball_Skill/
├─ Instructions.md # registers the skill into SkillRegistry
├─ metadata.json # name, description, version, created_by
├─ relevant_systems.json # [ Skill System (always_on) ]
├─ Unpack_On_Source/
│ ├─ ReplicatedStorage/ClientSource/Client/SkillController/Components/Others/
│ │ Skills/MagicSkills/Fire/FireballSkill.lua # client skill module (drop-in)
│ ├─ ReplicatedStorage/SharedSource/Datas/SkillRegistry/
│ │ Categories/MagicSkills/init.lua # new category metadata (drop-in)
│ └─ ServerScriptService/ServerSource/Server/SkillService/Components/Others/
│ Skills/MagicSkills/Fire/FireballSkill.lua # server skill module (drop-in)
├─ Unpack_On_Roblox_Studio/
│ └─ ReplicatedStorage/Assets/Effects/SkillFXs/MagicSkills/Fire/Fireball/
│ Ball.rbxm Crack.rbxm Explosion.rbxm Ring.rbxm # VFX assets
└─ To_Upload_By_User/
└─ Animations/Fireball_Anim.rbxm + superbullet_metadata.jsonStep 2 — Drop-in files
- Client and server skill modules follow the base's naming convention
<SkillName>Skill.luaand live underSkillController/…/Skills/<Main>/<Sub>/andSkillService/…/Skills/<Main>/<Sub>/. The base loads them dynamically on first activation. - Category metadata is a new file, so it ships as a drop-in. If your skill introduces a new main category, include its
init.lua:
-- Unpack_On_Source/ReplicatedStorage/SharedSource/Datas/SkillRegistry/Categories/MagicSkills/init.lua
return {
MainCategoryName = "MagicSkills",
DisplayName = "🔮 Magic Skills",
Description = "Mystical powers and elemental spells",
}- VFX go in
Unpack_On_Roblox_Studio/, mirroring the base'sAssets/Effects/SkillFXs/<Main>/<Sub>/<Skill>/hierarchy, one.rbxmper effect.
Step 3 — Register the skill via Instructions.md
The sub-category file (SubCategories/Fire.lua) is shared — other fire skills may live there — so the skill entry is added via Instructions.md, not shipped as a drop-in:
-- Instructions.md tells the AI to add this to (create the file if missing):
-- src/ReplicatedStorage/SharedSource/Datas/SkillRegistry/Categories/MagicSkills/SubCategories/Fire.lua
{
SkillId = "MagicSkills.Fire.Fireball",
Name = "Fireball",
ActivationPattern = Enums.ActivationPattern.HOLD_BEFORE_FIRE,
Image = "rbxassetid://94815901029377",
Price = 8000,
Rarity = Enums.Rarity.EPIC,
SkillVariables = {
Cooldown = 10,
ChargeTime = 2,
Damage = 75,
AnimationId = "rbxassetid://79320616791930", -- replaced via To_Upload_By_User
},
}Step 4 — Animation upload (fallback method)
Fireball's casting animation must be uploaded by the user. It uses the fallback instruction_token method — the real rbxassetid:// is surfaced through Instructions.md rather than written into a Lua file:
[
{
"display_name": "Fireball Skill Animation",
"file_path": "To_Upload_By_User/Animations/Fireball_Anim.rbxm",
"instruction_token": "rbxassetid://79320616791930"
}
]See Animations for both upload methods.
Checklist
relevant_systems.jsonrequiresSkill System(always_on: true).- Client + server
<SkillName>Skill.luamodules are under the base'sSkills/<Main>/<Sub>/folders. - Category
init.luashipped only if you introduce a new main category. - VFX in
Unpack_On_Roblox_Studio/…/SkillFXs/<Main>/<Sub>/<Skill>/, one.rbxmper effect. Instructions.mdappends the skill entry toSubCategories/<Sub>.luaidempotently.- Animation mapped in
To_Upload_By_User/Animations/superbullet_metadata.json.