Script don't run in actual Roblox game

Hi everyone,

I’m currently encountering an issue with a custom guitar system I developed, modeled similarly to how piano keyboards function. Everything works perfectly in Studio, but when I try to run it in an actual Roblox game, none of the functionality executes as expected.

The only outputs I see are:

print(player.Name .. "'s Client loaded")
print(player.Name .. "'s Server loaded")

Beyond these, nothing else seems to run.

Has anyone experienced a similar issue or know why this might be happening? Any help or insight would be greatly appreciated.

Thank you!

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local DataStoreService = game:GetService("DataStoreService")
local Players = game:GetService("Players")
local HttpService = game:GetService("HttpService")

local DS = DataStoreService:GetDataStore("Datastore_test1")

local CreateSheet = ReplicatedStorage:WaitForChild("CreateSheet")
local ReceiveSheets = ReplicatedStorage:WaitForChild("ReceiveSheets")
local SetFavorite = ReplicatedStorage:WaitForChild("SetFavorite")
local DeleteSheet = ReplicatedStorage:WaitForChild("DeleteSheet")

local function getKey(player)
	return "Sheets_" .. player.UserId
end

local function sendSheets(player, list)
	ReceiveSheets:FireClient(player, list)
end

Players.PlayerAdded:Connect(function(player)
	local key = getKey(player)
	local success, saved = pcall(function()
		return DS:GetAsync(key)
	end)
	if not success or type(saved) ~= "table" then
		saved = {}
	end
	for _, v in ipairs(saved) do
		if v.favorite == nil then v.favorite = false end
		if v.timestamp == nil then v.timestamp = 0 end
	end
	sendSheets(player, saved)
	
	print(player.Name .. "'s Server loaded")
end)

CreateSheet.OnServerEvent:Connect(function(player, name, sequence)
	local key = getKey(player)
	local success, stored = pcall(function()
		return DS:GetAsync(key)
	end)
	if not success or type(stored) ~= "table" then
		stored = {}
	end
	local newId = HttpService:GenerateGUID(false)
	local entry = {
		id = newId,
		name = name,
		sequence = sequence,
		favorite = false,
		timestamp = os.time()
	}
	table.insert(stored, entry)
	pcall(function()
		DS:SetAsync(key, stored)
	end)
	sendSheets(player, stored)
end)

SetFavorite.OnServerEvent:Connect(function(player, sheetId, newFav)
	local key = getKey(player)
	local success, stored = pcall(function()
		return DS:GetAsync(key)
	end)
	if not success or type(stored) ~= "table" then
		return
	end
	for _, v in ipairs(stored) do
		if v.id == sheetId then
			v.favorite = newFav
			v.timestamp = os.time()
			break
		end
	end
	pcall(function()
		DS:SetAsync(key, stored)
	end)
	sendSheets(player, stored)
end)

DeleteSheet.OnServerEvent:Connect(function(player, sheetId)
	local key = getKey(player)
	local success, stored = pcall(function()
		return DS:GetAsync(key)
	end)
	if not success or type(stored) ~= "table" then
		return
	end
	for idx, v in ipairs(stored) do
		if v.id == sheetId then
			table.remove(stored, idx)
			break
		end
	end
	pcall(function()
		DS:SetAsync(key, stored)
	end)
	sendSheets(player, stored)
end)
local Players = game:GetService("Players")
local UserInputService = game:GetService("UserInputService")
local ContextActionService = game:GetService("ContextActionService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local player = Players.LocalPlayer
local Tool = script.Parent.Parent:WaitForChild("Guitar")

local gui = Tool:WaitForChild("ScreenGui")
local frame = gui:WaitForChild("Frame")
local prototype = frame:WaitForChild("keyA")
local originalNoteSound = Tool:WaitForChild("NoteSound")
local reverbFX = originalNoteSound:WaitForChild("ReverbFX")
local soundPool = Tool:FindFirstChild("SoundPool")

local autoPlayFolder = frame:WaitForChild("autoPlay")
local sequenceBox = autoPlayFolder:WaitForChild("SequenceBox")
local playButton = autoPlayFolder:WaitForChild("PlayButton")
local loopButton = autoPlayFolder:WaitForChild("Loop")
local stopButton = autoPlayFolder:WaitForChild("Stop")

local sheetsFolder = frame:WaitForChild("sheets")
local sheetsFrame = sheetsFolder:WaitForChild("sheets")
local scrollingFrame = sheetsFrame:WaitForChild("ScrollingFrame")
local createSheetBtn = sheetsFrame:WaitForChild("createSheet")
local templateNameBox = sheetsFrame:WaitForChild("TemplateNameBox")

local CreateSheet = ReplicatedStorage:WaitForChild("CreateSheet")
local ReceiveSheets = ReplicatedStorage:WaitForChild("ReceiveSheets")
local SetFavorite = ReplicatedStorage:WaitForChild("SetFavorite")
local DeleteSheet = ReplicatedStorage:WaitForChild("DeleteSheet")

local errorText = gui:WaitForChild("error")
local succesText = gui:WaitForChild("succes")

local isWaitingForName = false
local guitarActive = false
local inputConn = nil
local unequipConn = nil
local isAutoPlaying = false
local cancelAuto = false
local loopEnabled = false

local character = player.Character or player.CharacterAdded:Wait()

local humanoid
local origWalkSpeed, origJumpPower
local defaultColors = {}

print(player.Name .. "'s Client loaded")

for _ = 1, 2 do
	while true do
		local info = ContextActionService:GetBoundActionInfo("RbxCameraKeypress")
		if info and info.inputTypes then
			ContextActionService:UnbindAction("RbxCameraKeypress")
			break
		else
			wait()
		end
	end
end

local NoteMap = {
	[Enum.KeyCode.Z] = { Pitch = 0.500, Reverb = { DecayTime = 1.0, WetLevel = 0.2 } },
	[Enum.KeyCode.X] = { Pitch = 0.561, Reverb = { DecayTime = 1.1, WetLevel = 0.25 } },
	[Enum.KeyCode.C] = { Pitch = 0.630, Reverb = { DecayTime = 1.2, WetLevel = 0.3 } },
	[Enum.KeyCode.V] = { Pitch = 0.667, Reverb = { DecayTime = 1.3, WetLevel = 0.35 } },
	[Enum.KeyCode.B] = { Pitch = 0.749, Reverb = { DecayTime = 1.4, WetLevel = 0.4 } },
	[Enum.KeyCode.N] = { Pitch = 0.841, Reverb = { DecayTime = 1.5, WetLevel = 0.45 } },
	[Enum.KeyCode.M] = { Pitch = 0.943, Reverb = { DecayTime = 1.6, WetLevel = 0.5 } },
	[Enum.KeyCode.A] = { Pitch = 1.000, Reverb = { DecayTime = 1.2, WetLevel = 0.3 } },
	[Enum.KeyCode.S] = { Pitch = 1.122, Reverb = { DecayTime = 1.4, WetLevel = 0.35 } },
	[Enum.KeyCode.D] = { Pitch = 1.260, Reverb = { DecayTime = 1.6, WetLevel = 0.4 } },
	[Enum.KeyCode.F] = { Pitch = 1.335, Reverb = { DecayTime = 1.8, WetLevel = 0.45 } },
	[Enum.KeyCode.G] = { Pitch = 1.498, Reverb = { DecayTime = 2.0, WetLevel = 0.5 } },
	[Enum.KeyCode.H] = { Pitch = 1.682, Reverb = { DecayTime = 2.2, WetLevel = 0.55 } },
	[Enum.KeyCode.J] = { Pitch = 1.887, Reverb = { DecayTime = 2.4, WetLevel = 0.6 } },
	[Enum.KeyCode.K] = { Pitch = 2.000, Reverb = { DecayTime = 2.6, WetLevel = 0.65 } },
	[Enum.KeyCode.Q] = { Pitch = 2.244, Reverb = { DecayTime = 2.8, WetLevel = 0.7 } },
	[Enum.KeyCode.W] = { Pitch = 2.520, Reverb = { DecayTime = 3.0, WetLevel = 0.75 } },
	[Enum.KeyCode.E] = { Pitch = 2.670, Reverb = { DecayTime = 3.2, WetLevel = 0.8 } },
	[Enum.KeyCode.R] = { Pitch = 2.996, Reverb = { DecayTime = 3.4, WetLevel = 0.85 } },
	[Enum.KeyCode.T] = { Pitch = 3.364, Reverb = { DecayTime = 3.6, WetLevel = 0.9 } },
	[Enum.KeyCode.Y] = { Pitch = 3.774, Reverb = { DecayTime = 3.8, WetLevel = 0.95 } },
	[Enum.KeyCode.U] = { Pitch = 4.000, Reverb = { DecayTime = 4.0, WetLevel = 1.0 } },
	[Enum.KeyCode.I] = { Pitch = 4.488, Reverb = { DecayTime = 4.2, WetLevel = 1.0 } }
}

local NoteNames = {
	[Enum.KeyCode.Z] = "C3",
	[Enum.KeyCode.A] = "C4",
	[Enum.KeyCode.K] = "C5",
	[Enum.KeyCode.U] = "C6",
	[Enum.KeyCode.X] = "D3",
	[Enum.KeyCode.S] = "D4",
	[Enum.KeyCode.Q] = "D5",
	[Enum.KeyCode.I] = "D6",
	[Enum.KeyCode.C] = "E3",
	[Enum.KeyCode.D] = "E4",
	[Enum.KeyCode.W] = "E5",
	[Enum.KeyCode.V] = "F3",
	[Enum.KeyCode.F] = "F4",
	[Enum.KeyCode.E] = "F5",
	[Enum.KeyCode.B] = "G3",
	[Enum.KeyCode.G] = "G4",
	[Enum.KeyCode.R] = "G5",
	[Enum.KeyCode.N] = "A3",
	[Enum.KeyCode.H] = "A4",
	[Enum.KeyCode.T] = "A5",
	[Enum.KeyCode.M] = "B3",
	[Enum.KeyCode.J] = "B4",
	[Enum.KeyCode.Y] = "B5"
}

local uiListLayout = frame:WaitForChild("UIListLayout")
uiListLayout.SortOrder = Enum.SortOrder.LayoutOrder

local entries = {}
for keyCode, name in pairs(NoteNames) do
	entries[#entries + 1] = { key = keyCode, name = name }
end
table.sort(entries, function(a, b)
	return a.name < b.name
end)

for index, entry in ipairs(entries) do
	local keyCode = entry.key
	local clone = prototype:Clone()
	clone.Name = "key" .. keyCode.Name
	clone.Text = keyCode.Name .. " - " .. entry.name
	clone.LayoutOrder = index
	clone.Parent = frame

	defaultColors[keyCode] = clone.TextColor3

	local pitchBox = clone:FindFirstChild("editFrame"):FindFirstChild("pitch")
	local reverbBox = clone:FindFirstChild("editFrame"):FindFirstChild("reverb")

	if pitchBox and NoteMap[keyCode] then
		pitchBox.Text = "Pitch: " .. tostring(NoteMap[keyCode].Pitch)
	end
	if reverbBox and NoteMap[keyCode] and NoteMap[keyCode].Reverb then
		local rv = NoteMap[keyCode].Reverb
		reverbBox.Text = "Reverb: " .. string.format("%.2f,%.2f", rv.DecayTime, rv.WetLevel)
	end

	if pitchBox then
		pitchBox.FocusLost:Connect(function(enterPressed)
			local newPitch = tonumber(pitchBox.Text)
			if newPitch and NoteMap[keyCode] then
				NoteMap[keyCode].Pitch = newPitch
			else
				pitchBox.Text = "Pitch: " .. tostring(NoteMap[keyCode].Pitch)
			end
		end)
	end

	if reverbBox then
		reverbBox.FocusLost:Connect(function(enterPressed)
			local text = reverbBox.Text
			local decay, wet = text:match("^%s*(%d*%.?%d+)%s*,%s*(%d*%.?%d+)%s*$")
			decay = tonumber(decay)
			wet = tonumber(wet)

			if decay and wet and NoteMap[keyCode] then
				if decay > 20 then decay = 20 end
				if wet > 20 then wet = 20 end

				NoteMap[keyCode].Reverb.DecayTime = decay
				NoteMap[keyCode].Reverb.WetLevel = wet

				reverbBox.Text = "Reverb: " .. string.format("%.2f,%.2f", decay, wet)
			else
				local old = NoteMap[keyCode].Reverb
				reverbBox.Text = "Reverb: " .. string.format("%.2f,%.2f", old.DecayTime, old.WetLevel)
			end
		end)
	end
end

prototype:Destroy()

loopButton.BackgroundColor3 = Color3.new(1, 0, 0)

local function setMovementLocked(lock)
	if humanoid then
		humanoid.UseJumpPower = true
		if lock then
			humanoid.WalkSpeed = 0
			humanoid.JumpPower = 0
		else
			humanoid.WalkSpeed = origWalkSpeed
			humanoid.JumpPower = origJumpPower
		end
	end
end

local function playNoteSound(noteInfo)
	local mainClone = originalNoteSound:Clone()
	mainClone.Parent = soundPool
	mainClone.Pitch  = noteInfo.Pitch or 1

	local rv = mainClone:FindFirstChild("ReverbFX")
	if rv and noteInfo.Reverb then
		rv.DecayTime = noteInfo.Reverb.DecayTime or rv.DecayTime
		rv.WetLevel  = noteInfo.Reverb.WetLevel  or rv.WetLevel
	end

	local silentTemplate = Tool:FindFirstChild("SilentHold")
	local silentClone = nil
	if silentTemplate then
		silentClone = silentTemplate:Clone()
		silentClone.Parent = soundPool
		silentClone.Volume = 0
		local rv2 = silentClone:FindFirstChild("ReverbFX")
		if rv2 then
			rv2.DecayTime = noteInfo.Reverb and noteInfo.Reverb.DecayTime or rv2.DecayTime
			rv2.WetLevel  = noteInfo.Reverb and noteInfo.Reverb.WetLevel  or rv2.WetLevel
		end
	end

	mainClone:Play()

	if silentClone then
		mainClone.Ended:Connect(function()
			silentClone:Play()
			mainClone:Destroy()

			local decay = (noteInfo.Reverb and noteInfo.Reverb.DecayTime) or (rv and rv.DecayTime) or 0
			spawn(function()
				task.wait(decay + 0.1)
				if silentClone and silentClone.Parent then
					silentClone:Destroy()
				end
			end)
		end)
	else
		local totalWait =
			(mainClone.TimeLength or 0)
			+ ((noteInfo.Reverb and noteInfo.Reverb.DecayTime) or (rv and rv.DecayTime) or 0)
			+ 1

		spawn(function()
			task.wait(totalWait)
			if mainClone and mainClone.Parent then
				mainClone:Destroy()
			end
		end)
	end
end

local function flashLabel(keyCode, color)
	local label = frame:FindFirstChild("key" .. keyCode.Name)
	if not label then return end
	label.TextColor3 = color
	task.delay(0.2, function()
		local defaultColor = defaultColors[keyCode]
		if defaultColor then
			label.TextColor3 = defaultColor
		end
	end)
end

local function onInputBegan(input, gameProcessed)
	if gameProcessed then return end
	if input.KeyCode == Enum.KeyCode.Backspace then
		guitarActive = not guitarActive
		if guitarActive then
			setMovementLocked(true)
		else
			setMovementLocked(false)
		end
		return
	end
	if isAutoPlaying then return end
	if not guitarActive then return end

	local noteInfo = NoteMap[input.KeyCode]
	if noteInfo then
		playNoteSound(noteInfo)
		flashLabel(input.KeyCode, Color3.new(0, 1, 0))
	end
end

local function parseSequence(sequenceText)
	local actions = {}
	local i = 1
	while i <= #sequenceText do
		local ch = sequenceText:sub(i, i)
		if ch == "[" then
			local close = sequenceText:find("]", i + 1, true)
			if close then
				local inside = sequenceText:sub(i + 1, close - 1)
				local numStr = inside:match("%-?%d+%.?%d*")
				local n = tonumber(numStr)
				if n then
					actions[#actions + 1] = { type = "delay", time = math.abs(n) }
				end
				i = close + 1
			else
				i = i + 1
			end
		elseif ch:match("%a") then
			local upper = ch:upper()
			local success, enumKey = pcall(function() return Enum.KeyCode[upper] end)
			if success and NoteMap[enumKey] then
				actions[#actions + 1] = { type = "note", key = enumKey }
			end
			i = i + 1
		else
			i = i + 1
		end
	end
	return actions
end

local function playSequence(actions)
	isAutoPlaying = true
	cancelAuto = false
	for _, action in ipairs(actions) do
		if cancelAuto then break end
		if action.type == "delay" then
			task.wait(action.time)
		elseif action.type == "note" then
			local noteInfo = NoteMap[action.key]
			if noteInfo then
				playNoteSound(noteInfo)
				flashLabel(action.key, Color3.new(1, 0, 0))
			end
			task.wait(0.15)
		end
	end
	isAutoPlaying = false
	cancelAuto = false
end

loopButton.MouseButton1Click:Connect(function()
	loopEnabled = not loopEnabled
	if loopEnabled then
		loopButton.BackgroundColor3 = Color3.new(0, 1, 0)
	else
		loopButton.BackgroundColor3 = Color3.new(1, 0, 0)
	end
end)

stopButton.MouseButton1Click:Connect(function()
	if isAutoPlaying then cancelAuto = true end
end)

playButton.MouseButton1Click:Connect(function()
	if not guitarActive or isAutoPlaying then return end
	local rawText = sequenceBox.Text or ""
	local actions = parseSequence(rawText)
	if #actions == 0 then return end
	spawn(function()
		if loopEnabled then
			while loopEnabled and not cancelAuto do
				playSequence(actions)
			end
		else
			playSequence(actions)
		end
	end)
end)

local function onUnequip()
	if inputConn then
		inputConn:Disconnect()
		inputConn = nil
	end
	if isAutoPlaying then cancelAuto = true end
	setMovementLocked(false)
	gui.Parent = script.Parent
	guitarActive = false
	if unequipConn then
		unequipConn:Disconnect()
		unequipConn = nil
	end
end

local function onEquip()
	humanoid = character:WaitForChild("Humanoid")
	origWalkSpeed = humanoid.WalkSpeed
	origJumpPower = humanoid.JumpPower
	guitarActive = true
	setMovementLocked(true)
	inputConn = UserInputService.InputBegan:Connect(onInputBegan)
	gui.Parent = player.PlayerGui
	unequipConn = Tool.Unequipped:Connect(onUnequip)
end

Tool.Equipped:Connect(onEquip)
Tool.Unequipped:Connect(onUnequip)

local sheetDataList = {}

local function sortSheets(list)
	table.sort(list, function(a, b)
		if a.favorite and not b.favorite then
			return true
		elseif b.favorite and not a.favorite then
			return false
		else
			return a.timestamp > b.timestamp
		end
	end)
end

local function clearScrollingFrame()
	for _, child in ipairs(scrollingFrame:GetChildren()) do
		if child:IsA("TextButton") then
			child:Destroy()
		end
	end
end

local function populateSheets(list)
	clearScrollingFrame()
	sheetDataList = list
	sortSheets(sheetDataList)
	for _, data in ipairs(sheetDataList) do
		local sheetBtn = script:WaitForChild("template"):Clone()
		local id = data.id or ""
		local nameText = data.name or ""
		sheetBtn.Name = "SheetBtn_" .. id
		sheetBtn.name.Text = nameText
		if data.favorite then
			sheetBtn.BackgroundColor3 = Color3.new(1, 1, 0)
		else
			sheetBtn.BackgroundColor3 = Color3.new(0, 1, 0)
		end
		sheetBtn.LayoutOrder = 0
		local pendingDelete = false
		local isHeld = false
		local favoriteToggled = false

		local function onInputBeganBtn(input)
			if input.UserInputType == Enum.UserInputType.MouseButton1 then
				isHeld = true
				favoriteToggled = false
				task.spawn(function()
					task.wait(0.5)
					if isHeld and not pendingDelete and not favoriteToggled then
						favoriteToggled = true
						SetFavorite:FireServer(id, not data.favorite)
						if not data.favorite then
							succesText.Visible = true
							succesText.Text = "Favorited '" .. nameText .. "'"
						else
							errorText.Visible = true
							errorText.Text = "Unfavorited '" .. nameText .. "'"
						end
						task.delay(2, function()
							errorText.Visible = false
							succesText.Visible = false
							errorText.Text = ""
							succesText.Text = ""
						end)
						sheetBtn.BackgroundColor3 = Color3.new(1, 1, 0)
					end
				end)
			elseif input.UserInputType == Enum.UserInputType.MouseButton2 then
				if not pendingDelete then
					pendingDelete = true
					sheetBtn.BackgroundColor3 = Color3.new(1, 0, 0)
				else
					pendingDelete = false
					if data.favorite then
						sheetBtn.BackgroundColor3 = Color3.new(1, 1, 0)
					else
						sheetBtn.BackgroundColor3 = Color3.new(0, 1, 0)
					end
				end
			end
		end

		local function onInputEndedBtn(input)
			if input.UserInputType == Enum.UserInputType.MouseButton1 then
				isHeld = false
				if pendingDelete then
					DeleteSheet:FireServer(id)
					errorText.Visible = true
					errorText.Text = "Deleted '" .. nameText .. "'"
					task.delay(2, function()
						errorText.Visible = false
						errorText.Text = ""
					end)
				elseif not favoriteToggled then
					sequenceBox.Text = data.sequence or ""
				end
			end
		end

		sheetBtn.InputBegan:Connect(onInputBeganBtn)
		sheetBtn.InputEnded:Connect(onInputEndedBtn)
		sheetBtn.Parent = scrollingFrame
	end

	local layout = scrollingFrame:FindFirstChildOfClass("UIListLayout")
	if layout then
		scrollingFrame.CanvasSize = UDim2.new(0, 0, 0, layout.AbsoluteContentSize.Y)
	end
end

ReceiveSheets.OnClientEvent:Connect(function(list)
	populateSheets(list)
end)

createSheetBtn.MouseButton1Click:Connect(function()
	if not isWaitingForName then
		isWaitingForName = true
		templateNameBox.Visible = true
		return
	end

	local rawName = templateNameBox.Text or ""
	local nameTrimmed = rawName:match("^%s*(.-)%s*$")
	if nameTrimmed == "" then
		templateNameBox.TextColor3 = Color3.new(1, 0, 0)
		task.delay(0.5, function()
			templateNameBox.TextColor3 = Color3.new(1, 1, 1)
		end)
		errorText.Visible = true
		errorText.Text = "Your name can't be blank."
		task.delay(2, function()
			errorText.Visible = false
			errorText.Text = ""
		end)
		return
	end

	for _, data in ipairs(sheetDataList) do
		if data.name == nameTrimmed then
			errorText.Visible = true
			errorText.Text = "A sheet named '" .. nameTrimmed .. "' already exists."
			task.delay(2, function()
				errorText.Visible = false
				errorText.Text = ""
			end)
			return
		end
	end

	local rawSequence = sequenceBox.Text or ""
	if rawSequence == "" then
		sequenceBox.TextColor3 = Color3.new(1, 0, 0)
		task.delay(0.5, function()
			sequenceBox.TextColor3 = Color3.new(1, 1, 1)
		end)
		errorText.Visible = true
		errorText.Text = "Your sheet can't be empty."
		task.delay(2, function()
			errorText.Visible = false
			errorText.Text = ""
		end)
		return
	end

	CreateSheet:FireServer(nameTrimmed, rawSequence)
	templateNameBox.Text = ""
	templateNameBox.Visible = false
	isWaitingForName = false
end)

Might be a problem with datastore permissions since In Studio, DataStores are simulated make sure your game is published onto roblox you don’t have to make it public just make it private.

other than that all i can think of is to try wrapping SetAsync and GetAsync calls in detailed pcall logging to check for failures.

local success, result = pcall(function()
    return DS:GetAsync(key)
end)
if not success then
    warn("GetAsync failed:", result)
end

But would that also affect my client sorry i’m lowkey slow…