Phone script erroring very irrelevant information

I’m making a LocalScript for an in-game phone, similar to what you see in games like Grand Theft Auto 5, and on roblox, “Da Hood”. I ran into an error on line 327, and it seems to make no sense, as the error is completely irrelevant from what the script is doing on line 327. Here is a screenshot of the error

On line 327, this is what the thread is doing: local result = sendCall:InvokeServer(rec)
I tried everything, I tried to check the serverscript that is recieving the remote, and I found nothing, I tried to use the find tool to search for CallInbound, but the script never tried to search for “CallInbound” inside of a ScreenGui. If you’d like to visualise the code better, feel free to copy and paste it into studio so you can use the find tool, and see it in proper coloring.

-- PhoneClient
local screen = script.Parent
local phone = screen:WaitForChild("PhoneLabel")
local phoneContent = game.ReplicatedStorage:WaitForChild("PhoneContent")
local elements = phoneContent:WaitForChild("Elements")
-- Elements for cloning
local plrBar = elements:WaitForChild("PlrBar")
local inMessage = elements:WaitForChild("InMessage")
local outMessage = elements:WaitForChild("OutMessage")
local sendCall = phoneContent:WaitForChild("SendCall")
local player = game.Players.LocalPlayer
local acceptButton = phone:WaitForChild("Answer")
local declineButton = phone:WaitForChild("Decline")
local callingEvent = script:WaitForChild("Calling")
local players = game.Players
local sentMessages = 0
local chatCooldown = 1
local lastChat = tick()
local declinedEevnt = script:WaitForChild("Declined")
local sendMessageRemote = phoneContent:WaitForChild("SendMessage")
local sendMsgButton = phone:WaitForChild("SendMessage")
local messageBox = phone:WaitForChild("MessageBox")
local tweenModule = require(game.ReplicatedStorage:WaitForChild("GlobalModules"):WaitForChild("TweenModule"))
local acceptedEvent = script:WaitForChild("Accept")
local callInbound = phoneContent:WaitForChild("SendCall")
local phoneStatuses = phoneContent:WaitForChild("PhoneStatuses")
local callStatus = phone:WaitForChild("CallStatus")
local recHeadshot = phone:WaitForChild("RecipientHeadshot")
local toggleButton = phone:WaitForChild("TogglePhoneButton")
local callerList = phone:WaitForChild("CallerList")
local settingsFrame = phone:WaitForChild("SettingsFrame")
local ringtoneBox = settingsFrame:WaitForChild("RingtoneId")
local backgroundBox = settingsFrame:WaitForChild("BackgroundId")
local settingsTab = phone:WaitForChild("SettingsTab")
local setPreferences = script:WaitForChild("SetPreferences")
local closeSettings = settingsFrame:WaitForChild("CloseSettings")
local preferenceFolder = player:WaitForChild("Preferences")
local wallpaperIdPref = preferenceFolder:WaitForChild("WallpaperId")
local ringtoneIdPref = preferenceFolder:WaitForChild("RingtoneId")
local setBackground = settingsFrame:WaitForChild("SetBackground")
local setRingtone = settingsFrame:WaitForChild("SetRingtone")
local resetBackground = settingsFrame:WaitForChild("ResetBackground")
local resetRingtone = settingsFrame:WaitForChild("ResetRingtone")
local inputService = game:GetService("UserInputService")
local messageFrame = phone:WaitForChild("MessageFrame")
local gamepasses = player:WaitForChild("Gamepasses")
local customPhone = gamepasses:WaitForChild("Custom Phone")
local mps = game:GetService("MarketplaceService")
local endCallRemote = phoneContent:WaitForChild("EndCall")
local hasPass = customPhone.Value

function setPassInfo()
	hasPass = customPhone.Value
end

customPhone.Changed:Connect(setPassInfo)

local elements = phone:GetChildren()
local callConnections = {}
local hiding = false
local hidden = true
local inCall = false
local hideTime = 0.4
local tweenTime = 0.35
local mainListCount = 0
local offsetStandard = 0.025
local messageGap = 0.2
local maxMessages = 4
local baseId = "https://www.roblox.com/Thumbs/Asset.ashx?width=420&height=420&assetId="
local defaultBackground = "http://www.roblox.com/asset/?id=5389495788"
local defaultRingtone = "rbxassetid://5371229916"
local plrNameTable = {}
local hiddenPos = UDim2.fromScale(phone.Position.X.Scale, 1.35)
local showPos = UDim2.fromScale(phone.Position.X.Scale, 1)
local imageButtons = {}

for i, v in pairs(elements) do
	if v.ClassName == "ImageButton" then
		table.insert(imageButtons, v)
	end
end

for i, v in pairs(imageButtons) do
	v.Activated:Connect(function()
		v.ImageColor3 = Color3.fromRGB(200,200,200)
	end)
end

setRingtone.Activated:Connect(function()
	setPreferences:FireServer(ringtoneBox.Text, nil)
end)

setBackground.Activated:Connect(function()
	setPreferences:FireServer(nil, baseId..backgroundBox.Text)
end)

resetRingtone.Activated:Connect(function()
	setPreferences:FireServer(defaultRingtone, nil)
end)

resetBackground.Activated:Connect(function()
	setPreferences:FireServer(nil, defaultBackground)
end)

function removePlr(plr, isFriend)
	local chosenList
	
	if isFriend == false then
		chosenList = callerList
		mainListCount = mainListCount - 1
	end
	
	local chosenButton = chosenList:FindFirstChild(plr.Name)
	
	if not chosenButton then
		print("No button existing, terminating function")
		
		return
	end
	
	local orderPos = chosenButton.OrderPos
	local orderPosVal = orderPos.Value
	
	chosenButton:Destroy()
	
	for i, v in pairs(chosenList:GetChildren()) do
		if v.OrderPos.Value > orderPosVal then
			v.OrderPos.Value = v.OrderPos.Value - 1
			
			v.Position = UDim2.fromScale(v.Position.X.Scale, v.Position.Y.Scale - offsetStandard)
		end
	end
end

function addPlr(plr, isFriend)
	local barClone = plrBar:Clone()
	barClone.Name = plr.Name
	barClone.Text = plr.Name
	local orderPos = barClone:WaitForChild("OrderPos")
	
	barClone.Activated:Connect(function()
		call(plr)
	end)
	
	if isFriend == false then
		local vertOffset = mainListCount*offsetStandard
		mainListCount = mainListCount + 1
		orderPos.Value = mainListCount
		barClone.Position = UDim2.fromScale(barClone.Position.X.Scale, vertOffset)
		
		barClone.Parent = callerList
	end
end

for i, v in pairs(players:GetChildren()) do
	if v ~= player then
		addPlr(v, false)
	end
end

players.PlayerAdded:Connect(function(plr)
	if plr ~= player then
		addPlr(plr, false)
	end
end)

players.PlayerRemoving:Connect(function(plr)
	if plr ~= player then
		removePlr(plr, false)
	end
end)

local headshotOffset = CFrame.new(0,0,5)
local connections = {}

settingsTab.Activated:Connect(function()
	if hasPass == true then
		settingsFrame.Visible = not settingsFrame.Visible
	else
		mps:PromptGamePassPurchase(player, customPhone.ID.Value)
	end
end)

closeSettings.Activated:Connect(function()
	settingsFrame.Visible = false
end)

function setHeadshot(plr, viewport)
	if viewport:FindFirstChildWhichIsA("Model") then
		viewport:FindFirstChildWhichIsA("Model"):Destroy()
	end
	
	local recChar = plr.Character:Clone()
	recChar.Parent = viewport
	local head = recChar:WaitForChild("Head")
	local humanoid = recChar.Humanoid
	humanoid:ChangeState(Enum.HumanoidStateType.PlatformStand)
	viewport.Camera.CFrame = CFrame.new(head.CFrame:ToWorldSpace(headshotOffset).p, head.Position)
end

function tweenToState(state)
	-- state can vary from CallIncoming, Browsing, Calling
	
	local state = phoneContent:WaitForChild("PhoneStatuses")[state]
	
	for i, v in pairs(elements) do
		local currentElement = state:FindFirstChild(v.Name)
		
		if currentElement then
			if string.find(v.ClassName, "Image") then
				tweenModule.Tween(v, {ImageTransparency = currentElement.ImageTransparency}, tweenTime)
				tweenModule.Tween(v, {ImageColor3 = currentElement.ImageColor3}, tweenTime)
			end
			
			if string.find(v.ClassName, "Text") then
				tweenModule.Tween(v, {TextTransparency = currentElement.TextTransparency}, tweenTime)
				tweenModule.Tween(v, {TextColor3 = currentElement.TextColor3}, tweenTime)
			end
			
			if string.find(v.Name, "Headshot") then
				tweenModule.Tween(v.Circle, {ImageTransparency = currentElement.Circle.ImageTransparency}, tweenTime)
				tweenModule.Tween(v, {ImageTransparency = currentElement.ImageTransparency}, tweenTime)
			end
			
			if string.find(v.Name, "Scroll") then
				if v.ScrollBarImageTransparency ~= currentElement.ScrollBarImageTransparency then
					tweenModule.Tween(v, {ScrollBarImageTransparency = currentElement.ScrollBarImageTransparency}, tweenTime)
				end
			end
			
			if v.ClassName ~= "UIAspectRatioConstraint" then
				v.ZIndex = currentElement.ZIndex
				
				if v.BackgroundTransparency ~= currentElement.BackgroundTransparency then
					tweenModule.Tween(v, {BackgroundTransparency = currentElement.BackgroundTransparency}, tweenTime)
				end
				
				if v.Position ~= currentElement.Position then
					tweenModule.Tween(v, {Position = currentElement.Position}, tweenTime)
				end
				
				v.Visible = currentElement.Visible
				
				if v.BackgroundColor3 ~= currentElement.BackgroundColor3 then
					tweenModule.Tween(v, {BackgroundColor3 = currentElement.BackgroundColor3}, tweenTime)
				end
			end
		end
	end
end

function showPhone()
	if hiding == true then return end
	hidden = true
	hiding = true
	tweenModule.Tween(phone, {showPos}, hideTime)
	
	wait(hideTime)
	hiding = false
end

function hidePhone()
	if hiding == true then return end
	hiding = true
	hidden = false
	tweenModule.Tween(phone, {hiddenPos}, hideTime)
	
	wait(hideTime)
	hiding = false
end

toggleButton.Activated:Connect(function()
	if hidden == true then
		showPhone()
	else
		hidePhone()
	end
end)

callInbound.OnClientInvoke = function(from)
	callingEvent:FireServer()
	setHeadshot(from, recHeadshot)
	callStatus.Text = from.Name.." is calling you"
	
	local function ended()
		for i, v in pairs(connections) do
			v:Disconnect()
		end
		
		callStatus.Text = ""
		endCallRemote:FireServer(from)
		
		connections = {}
		tweenToState("Browsing")
	end
	
	local function accepted()
		for i, v in pairs(connections) do
			v:Disconnect()
		end
		
		connections = {declineButton.Activated:Connect(ended)}
		acceptedEvent:FireServer()
		tweenToState("InCall")
		return true
	end
	
	local function declined()
		for i, v in pairs(connections) do
			v:Disconnect()
		end
		
		connections = {}
		tweenToState("Browsing")
		return false
	end
	
	table.insert(connections, declineButton.Activated:Connect(declined))
	table.insert(connections, acceptButton.Activated:Connect(accepted))
end

function call(rec)
	if inCall == true then return end
	tweenToState("Calling")
	callingEvent:FireServer()
	
	local result = sendCall:InvokeServer(rec)
	-- Turn vibration and ringtone off after yielding until a response
	-- (The thread will only get here after the user responding to the call)
	
	callingEvent:FireServer()
	sentMessages = 0
	
	if result == true then
		inCall = true
		
		local function ended(fromClient)
			for i, v in pairs(connections) do
				v:Disconnect()
			end
			
			inCall = false
			callStatus.Text = ""
			
			if fromClient == true then
				endCallRemote:FireServer(rec)
			end
			
			connections = {}
			tweenToState("Browsing")
		end
		
		table.insert(connections, endCallRemote.OnClientEvent:Connect(function()
			ended(false)
		end))
		
		local function sendMessage(msg)
			if tick() > lastChat + chatCooldown then
				lastChat = tick()
			else
				return
			end
			
			sendMessageRemote:InvokeServer(msg)
			local newMessage = outMessage:Clone()
			newMessage.Parent = messageFrame
			sentMessages = sentMessages + 1
			newMessage.Text = msg
			local top = sentMessages - 4
			newMessage.OrderPos.Value = sentMessages
			local newMessages = sentMessages - 1
			
			if sentMessages > maxMessages + 1 then
				newMessage.Position = UDim2.fromScale(newMessage.Position.X.Scale, newMessage.Position + (newMessages*messageGap))
			else
				for i, v in pairs(messageFrame:GetChildren()) do
					if v.OrderPos.Value >= top then
						v:Destroy()
					else
						v.Position = UDim2.fromScale(v.Position.X, v.Position.Y - messageGap)
					end
				end
			end
		end
		
		local function recieveMessage(msg)
			local newMessage = inMessage:Clone()
			newMessage.Parent = messageFrame
			messageBox.Text = ""
			sentMessages = sentMessages + 1
			newMessage.Text = msg
			local top = sentMessages - 4
			newMessage.OrderPos.Value = sentMessages
			local newMessages = sentMessages - 1
			
			if sentMessages > maxMessages + 1 then
				newMessage.Position = UDim2.fromScale(newMessage.Position.X.Scale, newMessage.Position + (newMessages*messageGap))
			else
				for i, v in pairs(messageFrame:GetChildren()) do
					if v.OrderPos.Value >= top then
						v:Destroy()
					else
						v.Position = UDim2.fromScale(v.Position.X, v.Position.Y - messageGap)
					end
				end
			end
		end
		
		inputService.InputBegan:Connect(function()
			local filteredString = game.Chat:FilterStringAsync(messageBox.Text, player, rec)
			
			sendMessage(filteredString)
		end)
		
		sendMsgButton.Activated:COnnect(function()
			local filteredString = game.Chat:FilterStringAsync(messageBox.Text, player, rec)
			
			sendMessage(filteredString)
		end)
		
		sendMessageRemote.OnClientInvoke = function(msg)
			recieveMessage(msg)
		end
		
		local function accepted()
			for i, v in pairs(connections) do
				v:Disconnect()
			end
			
			connections = {declineButton.Activated:Connect(function()
					ended(true)
				end)
			}
			
			acceptedEvent:FireServer()
			tweenToState("InCall")
			return true
		end
	else
		tweenToState("Browsing")
	end
end

any help is appreciated.

1 Like

The issue seems to be in the call function on this line.

local result = sendCall:InvokeServer(rec)

My best guess is that your issue is where this InvokeServer is being handled.

Also, on line 415 check how you capitalized Connect.

Oh, thanks for saving me from having to deal with that capitalization error, but as for the main error of this topic, I’ve tried to look in the script that recieves the invoke, nothing seems to be off.

Can you show that script so I can look it over? I can’t see how the issue could be coming from anywhere but the script where it’s received.

What is the variable rec that is passed into the call function?

Ok, here it is:

local events = game.ReplicatedStorage:WaitForChild("PhoneContent")
local sendCall = events:WaitForChild("SendCall")
local sendMsg = events:WaitForChild("SendMessage")

sendCall.OnServerInvoke = function(plr, rec)
	print(plr, rec)
	if not rec then return false end
	
	local callInbound = rec.PlayerGui.PhoneGui.CallInbound
	print(callInbound)
	local result = callInbound:InvokeClient(rec, plr)
	print(result)
	
	return result
end

sendMsg.OnServerInvoke = function(plr, rec, msg)
	sendMsg:InvokeClient(rec, msg)
end

I only added the prints now to check if it’s problematic.

The recipient (I need to get to 30 characters)

I’m going to run a 2 player test to see the result of the print debugging

local callInbound = rec.PlayerGui.PhoneGui.CallInbound

is your issue. Present in the receiving code.

You want it to be local callInbound = rec.PlayerGui.PhoneGui.SendCall

Well there’s your problem.

local callInbound = rec.PlayerGui.PhoneGui.CallInbound

The server shouldn’t be handling UI functions. You should connect that to another RemoteEvent or RemoteFunction and have the client handle it. Apart from that, you’re trying to print an object? What’s the purpose of that?

It appears that “CallInbound” itself is supposed to be a RemoteFunction. I would move that to ReplicatedStorage and work with it from there.

Oh, thank you alot for your time, I’ll fix it up :smiley:

I added it because I had an old plan to use another system, but when I switched to my new one, I forgot to remove the old code.