Combat extension (Melee System → Combat System)
A worked example of a combat / moveset extension: a package that adds a moveset to the Combat System base. Here it's Melee System (punches and kicks). Read the Extensions overview first for the shared contract. This family is the best example of optional dependencies and the primary token method for animations.
What it extends
The Combat System auto-discovers moveset data from SharedSource/Datas/Combat/ and loads attack logic from CombatController/CombatService components. A combat extension drops in its moveset data + attack handlers and (optionally) ships animations the user uploads.
Step 1 — Declare required and optional systems
Melee requires the Combat System and DamageHandler, and optionally enhances itself with the NPC System (for fighting NPCs). This is the reference example for mixing always_on: true and always_on: false:
[
{
"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
}
]- Required systems (
always_on: true) install first and can't be unchecked. - The optional NPC System (
always_on: false,isInitiallyChecked: false) is offered as an unchecked choice — the extension works without it, but gains NPC battles if included.
The zip
Melee_System/
├─ Instructions.md
├─ metadata.json # name, description, version, created_by
├─ relevant_systems.json # 2 required + 1 optional
├─ unpack_on_roblox_studio_meta.json # manifest for the Studio export below
├─ Unpack_On_Source/
│ ├─ ReplicatedStorage/ClientSource/Client/CombatController/Components/Others/NormalAttack.lua
│ ├─ ReplicatedStorage/SharedSource/Datas/Combat/AttackMoveset.lua # moveset data (drop-in)
│ ├─ ReplicatedStorage/SharedSource/Datas/Combat/PunchSettings.lua # equipped move config
│ └─ ServerScriptService/ServerSource/Server/CombatService/Components/Others/NormalAttack.lua
├─ Unpack_On_Roblox_Studio/
│ └─ ReplicatedStorage/Assets/Effects/Punches/PunchEffect.rbxm # hit VFX
└─ To_Upload_By_User/
└─ Animations/ Left_Jab.rbxm Right_Jab.rbxm Left_Front_kick.rbxm Right_Front_kick.rbxm
+ superbullet_metadata.jsonStep 2 — Drop-in files and the Studio manifest
AttackMoveset.luaholds the moveset data (and the animation ID placeholders — see Step 4).PunchSettings.luaselects which move is equipped; users can tweak it after install:
-- Unpack_On_Source/ReplicatedStorage/SharedSource/Datas/Combat/PunchSettings.lua
EquippedPunch = "Jab",
EquippedKick = "FrontKick",- Client and server
NormalAttack.luacomponents carry the attack logic. - The hit VFX ships in
Unpack_On_Roblox_Studio/, described by a root-levelunpack_on_roblox_studio_meta.jsonmanifest:
{
"version": 1,
"exports": [
{
"name": "PunchEffect.rbxm",
"targetService": "ReplicatedStorage",
"relativePath": "Assets/Effects/Punches",
"exportType": "instance",
"basePath": "ReplicatedStorage/Assets/Effects/Punches/PunchEffect"
}
]
}Step 4 — Animation upload (primary method)
Melee ships four animations. Unlike Fireball's fallback approach, Melee uses the primary token method for animations — each rbxassetid://… placeholder in AttackMoveset.lua is replaced in-place after upload. Multiple entries can target the same source file:
[
{
"file_path": "To_Upload_By_User/Animations/Left_Jab.rbxm",
"display_name": "Left Jab",
"source_path": "ReplicatedStorage/SharedSource/Datas/Combat/AttackMoveset.lua",
"token": "rbxassetid://117328173810607"
},
{
"file_path": "To_Upload_By_User/Animations/Right_Jab.rbxm",
"display_name": "Right Jab",
"source_path": "ReplicatedStorage/SharedSource/Datas/Combat/AttackMoveset.lua",
"token": "rbxassetid://121349669167393"
}
]Here the token is the full rbxassetid://… string (not a bare number) because that's exactly what appears in AttackMoveset.lua. See Animations for both methods.
Extensions can advertise further extensions
Melee's own docs point users to Melee Extensions (Hook, Straight, Uppercut, Elbow, Side Kick, Roundhouse, Knee) via a bundled doc (Combat/Documentations/ADD_MORE_MELEE_ANIMATIONS_EXTENSION.md). An extension can layer on top of another extension — the dependency chain in relevant_systems.json handles it the same way.
Checklist
relevant_systems.jsonmarks required systemsalways_on: trueand enhancersalways_on: false.- Moveset data + attack components are drop-in files under the Combat extension points.
unpack_on_roblox_studio_meta.jsondescribes each Studio export inUnpack_On_Roblox_Studio/.- Animation
tokenvalues in the upload metadata match therbxassetid://…placeholders inAttackMoveset.lua. metadata.jsonhasname,description, and a bumpedversion_number.