Script execution in replicated storage is weird

The scripts and sounds works weirdly in replicated storage.
Sounds play automatically in replicated storage on start, client scripts as well, legacy scripts copied from replicated storage doesn’t play.

What I would achieve:
I would make my projectile have sound. I have projectile templates in the replicated storage. I clone them and shoot them. It works.
It has sound and it is parented to the projectile. I want these sounds play automatically when the bullet is spawned.

The desired structure:
Bullet
–Sound (Sound)
----SoundPlay (Script)

SoundPlay script content (it doesn’t rly matter regarding the problem)

 script.parent:Play()

Problems:

  • sounds plays automatically at the replicated storage at game start
  • scripts with Client RunContext runs automatically in the replicated storage at game start
  • scripts with Legacy RunContext doesn’t play when cloned

My steps so far:
I have the projectile. I parented a sound under it and sat it into Playing. It is not good because it runs at start. Then I sat the playing to false and added a script that starts the sound.
But it doesn’t work when I clone the projectile. I sat the script runcontext to client. Now the script runs when I copy it, but it runs at the start in the replicated storage as well. So the sounds plays at the start.
Now my hotfix is that I modified my script like this:

if script:IsDescendantOf(game.ReplicatedStorage) then
	return
end
script.parent:Play()

This works, but feels like a hack. Is this typical Roblox behavior, or am I missing something?
Is my wish to have automatic sound play in a template is too unusual for Roblox?

This is my full script now. Just a reference to show what I would achieve.

if script:IsDescendantOf(game.ReplicatedStorage) then
	return
end

local soundList : string = {}

for _,c in ipairs(script.Parent:GetChildren()) do
	if c:IsA("StringValue") then
		table.insert(soundList, c.Value)
	end
end
local speaker : Sound = script.Parent
local speakerTarget : BasePart = speaker.Parent

if speakerTarget:IsA("Model") then
	speakerTarget = speakerTarget.PrimaryPart
end

--settings coming here
if #soundList > 0 then	
	speaker.SoundId = soundList[math.random(1, #soundList)]
end

if script.Parent:FindFirstChild("minVolume") and script.Parent:FindFirstChild("maxVolume") then
	speaker.Volume = math.random(script.Parent.minVolume.Value, script.Parent.maxVolume.Value)
end

--setting end
local soundP = workspace:FindFirstChild("SoundInstances")
if not soundP then
	soundP = Instance.new("Folder")
	soundP.Name = "SoundInstances"
	soundP.Parent = workspace
end

local holder = Instance.new("Part")
holder.Parent = soundP
holder.Position = speakerTarget.Position
holder.Transparency = 0
holder.CanCollide = false
holder.CanTouch = false
holder.CanQuery = false
holder.Anchored = false
holder.Massless = true

if script.Parent.doFollow and script.Parent.doFollow.Value then	
	local weldConstraint = Instance.new("WeldConstraint")
	weldConstraint.Parent = speakerTarget
	weldConstraint.Part0 = speakerTarget
	weldConstraint.Part1 = holder
end

speaker.Parent = holder

speaker.Ended:Connect(function(id)
	holder:Destroy()
end)

speaker:Play()

The approach of checking if the script is in ReplicatedStorage might work well. For me, I would disable the script and have the script cloning the bullet enable it manually.

If you have many variants of these bullets, you might consider looking into the factory design pattern. (External site)

Is the cloning being done on the client? It might explain why the legacy RunContext scripts aren’t working as they are server scripts.

1 Like

yo! I know the factory design pattern, but not sure where can I use up here. The bullets have many variants, but they have the same code.

Yes, I clone the projectiles on the client. I implemented a projectile system which doesn’t instantiate the bullets on the server just on the clients and only if they are nearby. There are different templates for the different bullets. And the artists working on these. So I just wanted to give them most straightforward solution that would be similar to what we can do in Unity.
Anyway It is working now I just don’t like it.

2 Likes

If they have the same code, you can store the script separately and clone & parent them into the bullet when the game is running.

Glad to hear that it is working! Unfortunately cannot do much without the server intervening if you want that legacy script to run.

What does the legacy script do? If you can find a way, you could rely on RemoteEvents instead!

1 Like

I use these scripts as components to trigger animations and particle systems and to start sounds. some of the abilities have multiple sounds with delays. so this is why i don’t handle them with the same script.

2 Likes