How to add sounds to your asset template
This guide mirrors the animations process for packaging sounds so SuperbulletAI can guide users to re-upload them and wire the correct asset IDs.
Why re-upload is required
Due to Roblox platform permissions, sounds must be owned by the experience creator (you or your group). Even if a sound is included in a template, it must be re-uploaded under your account or group to be usable in your game.
Prerequisite: connect the SuperbulletAI plugin and server
For the assets to appear under ReplicatedStorage/To_Upload_By_User/Sounds in Studio, ensure the SuperbulletAI Plugin is installed and connected to the local SuperbulletAI server.
- Open the SuperbulletAI application to start the local server.
- In Roblox Studio, enable the SuperbulletAI plugin and confirm it shows as connected.
- If disconnected, the
To_Upload_By_User/Soundsfolder may not appear and validation will not work.
What you need to include in your zip
Place either raw audio files (.mp3, .ogg, or another Roblox‑supported format) or Sound Instances as .rbxm/.rbxmx under the required folder. Each .rbxm/.rbxmx should contain a single Roblox Studio Sound Instance.
TemplateSystem.zip
└─ To_Upload_By_User/
└─ Sounds/
├─ ButtonClick.mp3
├─ EngineStart.rbxm
└─ DoorOpenSFX.rbxmxNotes:
- Use one Roblox Studio
SoundInstance per file. - File format can be
.rbxmor.rbxmx. - Do not add scripts or extra folders here.
-. If you include raw audio files, you must reference them via
file_pathinsidesuperbullet_metadata.json.
Where these appear in Roblox Studio
When the template is opened in Studio, these will appear at:
ReplicatedStorage/To_Upload_By_User/SoundsYou’ll see each Sound instance ready to re-upload.
Warning: If the SuperbulletAI plugin is not connected to the local SuperbulletAI server, this folder may not appear and sounds cannot be validated. Open the SuperbulletAI application to start the server and reconnect the plugin in Studio.
How users re-upload sounds (Studio steps)
For each Sound under ReplicatedStorage/To_Upload_By_User/Sounds:
- Right-click the Sound.
- Choose: Save/Export → Save to Roblox...
- Name it clearly (e.g., "ButtonClick").
- Set the
Creatorcorrectly:- Use your Group if the game belongs to a group (recommended for team games).
- Use your personal account only if the game is under your user.
- Complete the upload.
Important: If ownership does not match your experience (e.g., uploaded under a different user), sounds may not play.
How SuperbulletAI uses the IDs
During extraction, SuperbulletAI detects entries in To_Upload_By_User/Sounds and prompts for the newly uploaded Audio IDs. The importer blocks progress until valid IDs are provided.
On save, the app writes a mapping (Lua or JSON) the systems can consume, for example:
-- ReplicatedStorage/SharedSource/Datas/AssetIds.lua
return {
Audio = {
ButtonClick = "rbxassetid://1122334455",
EngineStart = "rbxassetid://6677889900"
}
}How replacements are determined (path + placeholders)
- Source file path: Pre‑extraction. Start at the service root (e.g.,
ReplicatedStorage/SharedSource/...orServerScriptService/Server/...). TheUnpack_On_Source/root is implied; do not include it. - Placeholder pattern: Use unique, collision‑resistant tokens like
[===[ButtonClick]===]inside text files (Lua/JSON/etc.). - Key matching: The placeholder name (e.g.,
ButtonClick) should match the sound key shown in the Assets Modal. By default this is the file basename fromTo_Upload_By_User/Sounds/<Key>.rbxm(x). - Replacement value: Each
[===[<Key>]===]is replaced withrbxassetid://<UploadedId>.
Example (inline placeholder in Lua):
-- Before
local CLICK_SFX_ID = "[===[ButtonClick]===]"
-- After providing IDs (ButtonClick => 1122334455)
local CLICK_SFX_ID = "rbxassetid://1122334455"superbullet_metadata.json (token-to-file mapping)
Add a mapping file at To_Upload_By_User/Sounds/superbullet_metadata.json so the importer knows which audio file to upload and where to replace placeholder tokens. There are two methods for specifying replacements:
Method 1: Primary (token-based) — Replaces in Lua source files
Use this method when you want the asset ID inserted directly into your Lua code automatically.
| Field | Required | Description |
|---|---|---|
file_path | Yes | Path from zip root to the audio file |
source_path | Yes | Path to the Lua file containing the token |
token | Yes | Exact placeholder string to replace in the Lua file |
display_name | No | UI label in Assets Modal (defaults to file basename) |
[
{
"display_name": "Button Click",
"file_path": "To_Upload_By_User/Sounds/ButtonClick.mp3",
"source_path": "ReplicatedStorage/SharedSource/Datas/SampleSystemData.lua",
"token": "[===[ButtonClick]===]"
},
{
"display_name": "Engine Start",
"file_path": "To_Upload_By_User/Sounds/EngineStart.rbxm",
"source_path": "ReplicatedStorage/ClientSource/Client/VehicleSystem/SoundEffects.lua",
"token": "[===[EngineStart]===]"
}
]Method 2: Fallback (instruction_token) — Replaces in Instructions.md
Use this method when you want the asset ID communicated via instructions instead of automatic code insertion. The user will see the replaced IDs in the chat instructions and can manually copy them where needed.
| Field | Required | Description |
|---|---|---|
file_path | Yes | Path from zip root to the audio file |
instruction_token | Yes | Placeholder string to replace in Instructions.md |
display_name | Yes | UI label in Assets Modal |
token | Must be absent | If present, primary method is used instead |
source_path | No | Not needed (targets Instructions.md, not a Lua file) |
[
{
"instruction_token": "{{BUTTON_CLICK_SOUND_ID}}",
"display_name": "Button Click Sound",
"file_path": "To_Upload_By_User/Sounds/ButtonClick.mp3"
},
{
"instruction_token": "{{DOOR_OPEN_SOUND_ID}}",
"display_name": "Door Open Sound",
"file_path": "To_Upload_By_User/Sounds/DoorOpen.ogg"
}
]Instructions.md example (before upload):
After uploading, configure your sounds:
- Button Click Sound ID: {{BUTTON_CLICK_SOUND_ID}}
- Door Open Sound ID: {{DOOR_OPEN_SOUND_ID}}Instructions.md sent to chat (after upload):
After uploading, configure your sounds:
- Button Click Sound ID: rbxassetid://111222333
- Door Open Sound ID: rbxassetid://444555666When to use each method
| Use Case | Method |
|---|---|
| Asset ID needs to be inserted directly into Lua code | Primary (token) |
| Template creator has control over the Lua source files | Primary (token) |
| Automatic code integration is desired | Primary (token) |
| Asset ID should be communicated via instructions | Fallback (instruction_token) |
| User will manually copy the ID into their code | Fallback (instruction_token) |
| Template doesn't have a specific Lua file to modify | Fallback (instruction_token) |
Rules for primary method (token)
file_path(required): Full path from the zip root to the actual audio file to upload, including the leadingTo_Upload_By_User/Sounds/folder. Use forward slashes. Examples:To_Upload_By_User/Sounds/ButtonClick.mp3,To_Upload_By_User/Sounds/SFX/UI/ButtonClick.ogg.- Use
source_pathas a pre‑extraction path starting at the Roblox service root (e.g.,ReplicatedStorage/,ServerScriptService/), using forward slashes. TheUnpack_On_Source/root is implied; do not include it. - The
tokenis the exact placeholder string to replace. It must appear verbatim in the target file. - Provide one entry per placeholder occurrence you want replaced.
- Do not include the token string anywhere in the
source_pathor its folders/filename. Tokens must appear only inside file contents, never in paths. display_name(optional): Controls the label shown in the Assets Modal. If omitted, the UI uses the derived key (usually the file basename).
If the token is not found in the specified file, validation will fail and you'll be prompted to fix the path or the token.
Rules for fallback method (instruction_token)
file_path(required): Full path from the zip root to the audio file.instruction_token(required): The exact placeholder string to find and replace inInstructions.md. Use a distinctive format like{{SOUND_NAME_ID}}to avoid accidental matches.display_name(required for fallback): The label shown in the Assets Modal.- Do not include a
tokenfield — its presence activates the primary method instead. - The
instruction_tokenplaceholder must exist in yourInstructions.mdfile.
Best practices
- Not supported: shipping or mutating Roblox Studio
SoundInstances in marketplace content. Instances included underTo_Upload_By_User/Soundsare for user re‑upload only; SuperbulletAI does not edit Instance properties. - Do this instead: store Audio asset IDs in a source file (for example
ReplicatedStorage/SharedSource/Datas/AssetIds.lua) and createSoundInstances at runtime.
Example (runtime creation with lightweight memory footprint):
local AssetIds = require(ReplicatedStorage.SharedSource.Datas.AssetIds)
local function playSound(parent, key, volume)
local sound = Instance.new("Sound")
sound.SoundId = AssetIds.Audio[key]
if volume ~= nil then sound.Volume = volume end
sound.Parent = parent
sound.Ended:Once(function()
sound:Destroy()
end)
sound:Play()
return sound
end
-- usage
playSound(workspace, "ButtonClick", 0.6)Why: Creating sounds on demand avoids preloading many Sound instances at startup and reduces memory usage.
Checklist
- Each sound is either a raw audio file (
.mp3,.ogg, etc.) or a singleSoundinstance saved as.rbxm/.rbxmx. - Files live under
To_Upload_By_User/Sounds/. - You (or your group) re-upload each sound in Studio.
- Provide the resulting asset IDs when prompted by SuperbulletAI.
- Each metadata entry includes
file_pathpointing to the audio file to upload.