Local value changing and not being detected?

Hello Everyone,

Before we begin, keep in mind I am new to Luau, so this may seem silly. I do not want to be spoon-fed, if you do find out the solution, please explain it to me so I can learn. :slightly_smiling_face:

Pretty much, I have a system that moves the FOV based on .PlaybackLoudness. It works fine, however, this music system has the ability to skip songs, which in turn changes the SoundId value in a Sound inside a folder. Here is my code for the system:

local RunService = game:GetService("RunService")

	
local Music = workspace.GlobalMusic_Folder:WaitForChild("Sound")






local CurrentCamera = workspace.CurrentCamera

local ScreenShakeSettings = {
	CameraMinFOV = 75,
	CameraMaxFOV = 100,
	CameraMaxVolume = 1200
}


game:GetService("RunService").RenderStepped:connect(function()
	local CurrentLoudness = Music.PlaybackLoudness
	local FOV = ScreenShakeSettings.CameraMinFOV + (ScreenShakeSettings.CameraMaxFOV - ScreenShakeSettings.CameraMinFOV) * (CurrentLoudness / ScreenShakeSettings.CameraMaxVolume)
	if FOV > 0 and FOV < 130 then
		CurrentCamera.FieldOfView = FOV
	end
end)

while true do
	print(Music.SoundId)
	wait(5)
end

It works very well, but when you skip a song, it plays the next song but does not do the screen effects, To debug it, I printed the Music.SoundId every 5 seconds. Even when moved to the next song, it prints the Id of the first song.

Here is what I did to try and fix it:

local RunService = game:GetService("RunService")

	
local Music = workspace.GlobalMusic_Folder:WaitForChild("Sound")


while wait(.5) do 

	Music = workspace.GlobalMusic_Folder:WaitForChild("Sound")	

end




local CurrentCamera = workspace.CurrentCamera

local ScreenShakeSettings = {
	CameraMinFOV = 75,
	CameraMaxFOV = 100,
	CameraMaxVolume = 1200
}


game:GetService("RunService").RenderStepped:connect(function()
	local CurrentLoudness = Music.PlaybackLoudness
	local FOV = ScreenShakeSettings.CameraMinFOV + (ScreenShakeSettings.CameraMaxFOV - ScreenShakeSettings.CameraMinFOV) * (CurrentLoudness / ScreenShakeSettings.CameraMaxVolume)
	if FOV > 0 and FOV < 130 then
		CurrentCamera.FieldOfView = FOV
	end
end)

while true do
	print(Music.SoundId)
	wait(5)
end

This just made the system not work at all.


This is probably a simple solution, however my brain is half fried and I couldn’t figure it out. Help would be greatly appreciated. If you need my music queue code or other info, let me know. Again:

Before we begin, keep in mind I am new to Luau, so this may seem silly. I do not want to be spoon-fed, if you do find out the solution, please explain it to me so I can learn.

Thank you very much! :grinning:

Did a bit more testing, I still have no idea why it’s happening.

I feel like we are missing a lot of context from this code example. For example, where is it telling the camera to be scriptable? What is telling the music to play? What is telling the music to skip when finished.

Is there some kind of other module involved?

This is a module that I created (in my framework) that deals with the music watching and moving to next track from end to end. It does not deal with the FOV stuff. I did that somewhere else and will digg it up. I just post as a ref for you to see an end to end playlist module solution - mainly to point out how much code is missing from what you posted!

local music = {
	isPlaying = false;
	isNextTrack = false;
	curTrackNum = 1;
	curTrack = {};
	curAudio = false;
	masterVolume = 1;
}

music.tracks = {
	
	[1] = {
		name = "SlamDunk",
		volume = 0.4,
		startTime = false,
		fadeInSpeed = 0,
		endTime = 40.12,
		fadeOutSpeed = 0,
		startDelay = 0,
	};
	
	[2] = {
		name = "SnowDigger",
		volume = 0.9,
		startTime = false,
		fadeInSpeed = 0,
		endTime = false,
		fadeOutSpeed = 0,
		startDelay = 0,
	};

}

music.watchMusic = function(_, player)
	
	_.trace('LocalPlayer: FallBounds / watchFalling')
	
	local INTERVAL = 0.1
	local nextStep = tick() + INTERVAL
	
	_.service.run.Heartbeat:Connect(function(dt)
		
		if (tick() >= nextStep) then
			
			nextStep = nextStep + INTERVAL
			
			if music.isPlaying and not music.isNextTrack then
				
				-- Fade out the track at a specified end time
				if music.curTrack.endTime ~= false then
					if music.curAudio.TimePosition >= music.curTrack.endTime then
						_.trace("Music: Fade / " .. music.curTrack.name)
						music.isNextTrack = true
						_.service.tween:Create(music.curAudio, TweenInfo.new(music.curTrack.fadeOutSpeed), {Volume = 0}):Play()
						wait(music.curTrack.fadeOutSpeed)
						music.curAudio:Stop()
						music.playNext(_, player)
					end
				end
				
				-- Switch and end of trrack
				if music.curAudio.TimePosition >= music.curAudio.TimeLength - 1 then
					_.trace("Music: Ended / " .. music.curTrack.name)
					music.isNextTrack = true
					music.curAudio:Stop()
					music.playNext(_, player)
				end

			end
			
		end
		
	end)
	
end

music.play = function(_, player)
	
	-- Load the config
	music.curTrack = music.tracks[music.curTrackNum]
	
	if music.curTrack.startDelay > 0 then
		wait(music.curTrack.startDelay)
	end
	
	_.trace('Music: Play / ' .. music.curTrack.name)
	
	-- Get a pointer to the audio
	music.curAudio = player.PlayerGui.Audio.Music[music.curTrack.name]
	
	-- Set default volume
	music.curAudio.Volume = 0
	
	-- If at 0 then forward to TimePosition and fade in
	if music.curAudio.TimePosition == 0 then
		if music.curTrack.startTime ~= false then			
			music.curAudio.TimePosition = music.curTrack.startTime
			_.service.tween:Create(music.curAudio, TweenInfo.new(music.curTrack.fadeInSpeed), {Volume = music.curTrack.volume * music.masterVolume}):Play()
			music.curAudio:Play()
			music.isPlaying = true
			music.isNextTrack = false
		end
	end
	
	-- If timer at 0 and config.startTime false 
	if music.isNextTrack or not music.isPlaying then
		music.curAudio.Volume = music.curTrack.volume * music.masterVolume
		music.curAudio:Play()
		music.isPlaying = true
		music.isNextTrack = false
	end
	
end

music.playNext = function(_, player)	
	local numTracks = _.util.count(music.tracks)	
	music.curTrackNum += 1		
	if music.curTrackNum > numTracks then
		music.curTrackNum = 1
	end
	music.play(_, player)	
end

music.stop = function(_, player)
	music.curAudio:Stop()
	music.isPlaying = false
end

music.duck = function(_, player)
	if music.isPlaying then
		local duckLevel = (music.curTrack.volume * music.masterVolume) * 0.2
		_.service.tween:Create(music.curAudio, TweenInfo.new(0.5), {Volume = duckLevel}):Play()
	end
end

music.duckTo = function(_, player, duckTo)
	if music.isPlaying then
		local duckLevel = (music.curTrack.volume * music.masterVolume) * duckTo
		_.service.tween:Create(music.curAudio, TweenInfo.new(0.5), {Volume = duckLevel}):Play()
	end
end

music.unduck = function(_, player)
	if music.isPlaying then
		_.service.tween:Create(music.curAudio, TweenInfo.new(0.5), {Volume = music.curTrack.volume * music.masterVolume}):Play()
	end
end

return music

I’ll be back to update this post with the FOV stuff in a min.

It’s not included because it’s irrelevant. The camera is not the problem. I don’t know how to have the value update, that’s the issue. I am using a completely separate system.

What is the value that you do not know how to update?

When this moves to the next song, this value doesn’t change.

Just to clarify, you’re absolutely sure that the song itself is actually changing?

1 Like

Yup. The system works great, it’s just that the value isn’t changing.

I have no idea how that could ever work :slight_smile: Like, does it create some kind of collection? What is the iteration mechanism.

Again, that’s irrelevant. I need to know how I can have the variable update when the value changes.

I don’t think you have a clear idea on how coding works :wink: Context is never irrelevant. Code is a whole system. Just something I learned after 30 years of coding!

There’s a great coding quote that goes like this:

Don’t tell me your solution. Tell me your problem. If you only want to tell me your solution I can’t help you with your problem.

The reason I’m not including it as it’s a very long module with multiple different scripts. It’s not actually important. I can provide it, but it will just cause a bigger headache, as all that is important is the fact that it changes the SoundId of the Music sound object.

At a minimum we need to see the event that triggers local Music = workspace.GlobalMusic_Folder:WaitForChild("Sound") for it’s next iteration.

For example, you may have a global variable that is interfering in some way. We could never know that without a larger conext.

Mind clarifying what parts of this are in a modulescript?

Good point there. I completely overlooked that, it’s late here! :laughing: I’ll provide that tommorow.

This script itself isn’t in a module script however the part that plays the music and handles the skip commands are.

What’s being returned/stored by those modules?

should be in either a spawn function or a corountine function as its yielding the thread since its a loop

or, you could have the Music variable inside the RunService.RenderStepped listener

I’m suspicious about the scope of Music maybe the module does something weird so you only ever see one copy of it and then loose a handle to it on the next iteration.

local Music = workspace.GlobalMusic_Folder:WaitForChild("Sound")

Also super weird. Does the folder have 100 files all called Sound and a folder collection service passes to the next one.

Weird!