Attempt to concatenate string with Instance

Created a 1v1 system, when the game ends and I want to show the points and reward the winner this shows, no idea why need help urgently.

ClientSide:

ReplicatedStorage.EndMinigameEvent.OnClientEvent:Connect(function(yourPoints, theirPoints)
	--print("Minigame result received. Your points: " .. yourPoints .. ", Opponent's points: " .. theirPoints)
	print("Type of yourPoints: ", typeof(yourPoints))
	
	ResultUI.Visible = true
	tweenDown:Play()
	task.wait(1)
	ResultUI.YourPoints.Text = "Your Points: " .. yourPoints
	ResultUI.TheirPoints.Text = "Opponent's Points: " .. theirPoints 

	if yourPoints > theirPoints then
		confettiFrame.Visible = true
		startConfettiRain()
		ResultUI.Result.Text = "You Won!"
		ResultUI.Won.Visible = true
		SoundService:WaitForChild("Confetti"):Play()
		ReplicatedStorage:WaitForChild("1V1"):WaitForChild("CashYummy"):FireServer(player)
	
	elseif yourPoints < theirPoints then
		ResultUI.Result.Text = "You Lost!"
		ResultUI.Lost.Visible = true
	else
		setRandomImage()
		ResultUI.Result.Text = "It's a Tie!"
		playRandomSound()
		ResultUI.Tie.Visible = true
	end


end)

button.MouseButton1Click:Connect(function()
	
	ResultUI.Lost.Visible = false
	ResultUI.Won.Visible = false
	ResultUI.Tie.Visible = false
	confettiFrame.Visible = false
	
	
	
	tweenUp:Play()
	tweenUp.Completed:Wait()
	ResultUI.Visible = false
	
	if currentSound and currentSound.IsPlaying then
		currentSound:Stop()
		print("Sound stopped.")
	else
		print("No sound is currently playing.")
	end
	
	
end)

Serverside:

EndMinigameEvent.OnServerEvent:Connect(function(player, score)
	print("Minigame Is Over!")
	playerScores[player] = score


	local playersInChallenge = {}
	for otherPlayer, _ in pairs(playerScores) do
		if otherPlayer:GetAttribute("InChallenge") then
			table.insert(playersInChallenge, otherPlayer)
		end
	end

	if #playersInChallenge == 2 then
		local player1, player2 = playersInChallenge[1], playersInChallenge[2]
		local player1Score, player2Score = playerScores[player1], playerScores[player2]

		-- Send results to both players
		EndMinigameEvent:FireClient(player1, player1Score, player2Score)
		EndMinigameEvent:FireClient(player2, player2Score, player1Score)

		-- Enable movement again
		local function enableMovement(player)
			local character = player.Character or player.CharacterAdded:Wait()
			local humanoid = character:WaitForChild("Humanoid")
			humanoid.WalkSpeed = 24
			humanoid.JumpPower = 50
		end

		enableMovement(player1)
		enableMovement(player2)

		-- Clean up
		player1:SetAttribute("InChallenge", false)
		player2:SetAttribute("InChallenge", false)
		playerScores = {}
	end
end)
ResultUI.YourPoints.Text = "Your Points: " .. yourPoints

Line the error occurs on.

2 Likes

1 Like

“Attempt to concatenate string with Instance”
Your code was: ResultUI.YourPoints.Text = "Your Points: " .. yourPoints

So, yourPoints is an Instance.
Based on the ClientSide script, it’s received from OnClientEvent, so it’s the first parameter of :FireServer() on the ServerSide script.

Both have the same format, so we can conclude that player1Score and player2Score are both Instances.

So we retrieved the scores by indexing playerScores, but we got an instance as a result. So who set it to an instance value?

You got the score value from OnServerEvent, which is triggered by FireServer, Which you did not provide on your code… But this explanation should give you the bright side.

1 Like

whole server script

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")

local ChallengeEvent = ReplicatedStorage.ChallengeSystem:WaitForChild("ChallengeEvent")
local AcceptChallenge = ReplicatedStorage.ChallengeSystem:WaitForChild("AcceptChallenge")
local DeclineChallenge = ReplicatedStorage.ChallengeSystem:WaitForChild("DeclineChallenge")

local ChallengeSpots = game.Workspace:WaitForChild("ChallengeSpots")
local Spot1 = ChallengeSpots:FindFirstChild("Spot1")
local Spot2 = ChallengeSpots:FindFirstChild("Spot2")

local StartMinigameEvent = Instance.new("RemoteEvent", ReplicatedStorage)
StartMinigameEvent.Name = "StartMinigameEvent"

local EndMinigameEvent = Instance.new("RemoteEvent", ReplicatedStorage)
EndMinigameEvent.Name = "EndMinigameEvent"

-- Handle challenge requests
ChallengeEvent.OnServerEvent:Connect(function(player1, targetPlayerName)
	local targetPlayer = Players:FindFirstChild(targetPlayerName)

	if targetPlayer and not targetPlayer:GetAttribute("InChallenge") and not player1:GetAttribute("InChallenge") then
		-- Send the challenge pop-up to the target player
		AcceptChallenge:FireClient(targetPlayer, player1)
	end
end)

-- Handle challenge acceptance
AcceptChallenge.OnServerEvent:Connect(function(player2, challenger)
	if challenger and player2 then
		-- Set both players as "InChallenge"
		challenger:SetAttribute("InChallenge", true)
		player2:SetAttribute("InChallenge", true)

		-- Teleport both players to challenge spots
		challenger.Character:SetPrimaryPartCFrame(Spot1.CFrame)
		player2.Character:SetPrimaryPartCFrame(Spot2.CFrame)

		-- Disable movement for both players
		local function disableMovement(player)
			local character = player.Character or player.CharacterAdded:Wait()
			local humanoid = character:WaitForChild("Humanoid")
			humanoid.WalkSpeed = 0
			humanoid.JumpPower = 0
		end

		disableMovement(challenger)
		disableMovement(player2)

		-- Trigger the minigame on both players' screens
		StartMinigameEvent:FireClient(challenger, player2)
		StartMinigameEvent:FireClient(player2, challenger)

		print(challenger.Name .. " and " .. player2.Name .. " are now in a challenge!")
		task.wait(33.5)
		
		EndMinigameEvent:FireClient(challenger, player2)
		EndMinigameEvent:FireClient(player2, challenger)
	end
end)

-- Handle challenge decline
DeclineChallenge.OnServerEvent:Connect(function(player2, challenger)
	if challenger then
		print(player2.Name .. " declined the challenge from " .. challenger.Name)
	end
end)

local playerScores = {}

EndMinigameEvent.OnServerEvent:Connect(function(player, score)
	print("Minigame Is Over!")
	playerScores[player] = score

	-- Check if both players have submitted scores
	local playersInChallenge = {}
	for otherPlayer, _ in pairs(playerScores) do
		if otherPlayer:GetAttribute("InChallenge") then
			table.insert(playersInChallenge, otherPlayer)
		end
	end

	if #playersInChallenge == 2 then
		local player1, player2 = playersInChallenge[1], playersInChallenge[2]
		local player1Score, player2Score = playerScores[player1], playerScores[player2]

		-- Send results to both players
		EndMinigameEvent:FireClient(player1, player1Score, player2Score)
		EndMinigameEvent:FireClient(player2, player2Score, player1Score)

		-- Enable movement again
		local function enableMovement(player)
			local character = player.Character or player.CharacterAdded:Wait()
			local humanoid = character:WaitForChild("Humanoid")
			humanoid.WalkSpeed = 24
			humanoid.JumpPower = 50
		end

		enableMovement(player1)
		enableMovement(player2)

		-- Clean up
		player1:SetAttribute("InChallenge", false)
		player2:SetAttribute("InChallenge", false)
		playerScores = {}
	end
end)



ReplicatedStorage:WaitForChild("1V1"):WaitForChild("CashYummy").OnServerEvent:Connect(function(player)
	ReplicatedStorage:WaitForChild("Remotes"):WaitForChild("UIRemotes"):WaitForChild("CashEvent"):FireClient(player)
	local playerCash = ServerStorage.PlayerCash:FindFirstChild(player.Name)
	if playerCash then
		playerCash.Value = playerCash.Value + 2000
	end
end)
1 Like

I need the Clientsided script that used :FireServer() on EndMinigameEvent remote

1 Like
ReplicatedStorage.StartMinigameEvent.OnClientEvent:Connect(function(opponent)
	points = 0
	print("Minigame started.")
	-- Start the 3-2-1 countdown
	startCountdown(3)
	-- Start the game countdown
	KickingUI.Bar.Visible = true
	startGameCountdown()
	KickingUI.Bar.Visible = false
	print("Minigame ended.")


	-- Send the points to the server for both players
	ReplicatedStorage.EndMinigameEvent:FireServer(points)
	
end)


2 Likes

Did you perhaps delete some parts of the code? Or is there any other line modifying points variable?

1 Like

the problem is here where you are setting the player instance into the table and not a value

see your using the player as the key here
so otherplayer is your key _ should be the value

here, whole client matchmaking code…

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local TweenService = game:GetService("TweenService")
local SoundService = game:GetService("SoundService")
local UserInputService = game:GetService("UserInputService")
local Players = game:GetService("Players")

local player = Players.LocalPlayer
local PlayerGui = player:WaitForChild("PlayerGui")
local MinigameUI = PlayerGui:WaitForChild("MinigameUI")

local BeforeStartCountdown = MinigameUI:WaitForChild("Countdown")
local inGameCountdown = MinigameUI:WaitForChild("CountdownMiniGame")

local ResultUI = MinigameUI:WaitForChild("ResultUI") -- Result UI for showing the score after the game ends

local points = 0

local TweenService = game:GetService("TweenService")
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")

local KickingUI = PlayerGui:WaitForChild("Football_KickerFrame")
local Bar = KickingUI:WaitForChild("Bar")
local Arrow = Bar:WaitForChild("Arrow")
local Target = Bar:WaitForChild("Target")
local arrowTween

-- References for ball and animation
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local football = ReplicatedStorage:WaitForChild("Football")
local FootballEvent = ReplicatedStorage:WaitForChild("1V1"):WaitForChild("FootballEvent")  -- RemoteEvent to notify server
local playKickAnimationEvent  = ReplicatedStorage:WaitForChild("1V1"):WaitForChild("KickAnimation") 
local footballMissEvent = ReplicatedStorage:WaitForChild("1V1"):WaitForChild("FootballMissEvent")

local soundFolder = SoundService:WaitForChild("LowTaperFade") -- Replace with the name of your folder containing sounds
local imageFolder = ReplicatedStorage:WaitForChild("LowTaperFade")
local images = imageFolder:GetChildren()
local currentSound = nil

local frame = ResultUI
local button = frame:WaitForChild("ExitButton") -- Replace with your button's name

local tweenInfo = TweenInfo.new(1, Enum.EasingStyle.Quad, Enum.EasingDirection.Out)

-- Define positions
local startPosition = UDim2.new(0.339, 0, -0.5, 0) -- Start position (off-screen)
local targetPosition = UDim2.new(0.339, 0, 0.181, 0) -- Target position

-- Set the frame's initial position
frame.Position = startPosition

-- Tween the frame down
local tweenDown = TweenService:Create(frame, tweenInfo, { Position = targetPosition })
-- Tween the frame back up
local tweenUp = TweenService:Create(frame, tweenInfo, { Position = startPosition })

local confettiFrame = MinigameUI:WaitForChild("GameClick") -- Fullscreen frame to contain confetti
local confettiColors = {
	Color3.fromRGB(255, 0, 0),   -- Red
	Color3.fromRGB(0, 255, 0),   -- Green
	Color3.fromRGB(0, 0, 255),   -- Blue
	Color3.fromRGB(255, 255, 0), -- Yellow
	Color3.fromRGB(255, 165, 0), -- Orange
	Color3.fromRGB(128, 0, 128)  -- Purple
}

-- Function to create a confetti piece
local function createConfettiPiece()
	local confettiPiece = Instance.new("Frame")
	confettiPiece.Size = UDim2.new(0, math.random(10, 20), 0, math.random(20, 40)) -- Slightly wider strips
	confettiPiece.Position = UDim2.new(math.random(), 0, -0.1, 0) -- Random horizontal spawn, above screen
	confettiPiece.BackgroundColor3 = confettiColors[math.random(1, #confettiColors)] -- Random color
	confettiPiece.BorderSizePixel = 0
	confettiPiece.Rotation = math.random(0, 360) -- Initial random rotation
	confettiPiece.Parent = confettiFrame

	-- Tween to make the confetti fall with physics-like easing
	local fallDuration = math.random(3, 6) -- Slow fall duration
	local fallTweenInfo = TweenInfo.new(
		fallDuration,
		Enum.EasingStyle.Linear,
		Enum.EasingDirection.InOut
	)
	local fallGoal = { Position = UDim2.new(confettiPiece.Position.X.Scale, 0, 1.1, 0) } -- Fall off the screen
	local fallTween = TweenService:Create(confettiPiece, fallTweenInfo, fallGoal)

	-- Slight rotation during the fall
	local rotationTweenInfo = TweenInfo.new(
		fallDuration,
		Enum.EasingStyle.Linear,
		Enum.EasingDirection.InOut
	)
	local rotationGoal = { Rotation = confettiPiece.Rotation + math.random(-90, 90) }
	local rotationTween = TweenService:Create(confettiPiece, rotationTweenInfo, rotationGoal)

	-- Play the tweens
	fallTween:Play()
	rotationTween:Play()

	-- Cleanup the confetti piece after it falls
	fallTween.Completed:Connect(function()
		confettiPiece:Destroy()
	end)
end

-- Function to generate confetti rain
local function startConfettiRain()
	for i = 1, 100 do -- Number of confetti pieces
		task.spawn(function()
			createConfettiPiece()
			wait(math.random(0, 50) / 1000) -- Slight delay between spawns for randomness
		end)
	end
end


local function setRandomImage()
	-- Get all images in the folder
	local images = imageFolder:GetChildren()

	-- Check if there are any images in the folder
	if #images > 0 then
		-- Pick a random image
		local randomImage = images[math.random(1, #images)]

		-- Ensure it's a valid StringValue with an Image ID
		if randomImage:IsA("StringValue") then
			ResultUI.Tie.Image = "rbxassetid://" .. randomImage.Value
		else
			warn("Selected image is not a valid StringValue with an image ID.")
		end
	else
		warn("No images found in LowTaperFade folder!")
	end
end


-- Function to play a random sound
local function playRandomSound()
	-- Get all sounds in the folder
	local sounds = soundFolder:GetChildren()

	if #sounds > 0 then
		-- Pick a random sound
		local randomSound = sounds[math.random(1, #sounds)]

		if randomSound:IsA("Sound") then
			-- Stop the previous sound (if any)
			if currentSound and currentSound.IsPlaying then
				currentSound:Stop()
			end

			-- Play the new sound and set it as the current sound
			randomSound:Play()
			currentSound = randomSound
		else
			warn("Randomly selected item is not a Sound.")
		end
	else
		warn("No sounds found in the folder.")
	end
end

-- Example usage: Call the function




local function createNewTarget()
	Target.Position = UDim2.new(math.random((1-Target.Size.X.Scale)*1000)/1000, 0, 0, 0) -- random position

	if not arrowTween then
		local tweenInfo = TweenInfo.new(1, Enum.EasingStyle.Linear, Enum.EasingDirection.InOut, -1, true)
		arrowTween = TweenService:Create(Arrow, tweenInfo, {Position = UDim2.new(1, 0, 0, 0)})
	end
	arrowTween:Play()
end
createNewTarget()

local deb = false
local debclick = false

local function playKickAnimation()
	-- Assuming you have an animation in the player's humanoid
	local kickAnimation = Instance.new("Animation")
	kickAnimation.AnimationId = "rbxassetid://100710361198380"  -- Replace with actual animation ID
	local track = humanoid:LoadAnimation(kickAnimation)
	track:Play()
end

local function kickFootball()

	-- Fire RemoteEvent to server to create football
	FootballEvent:FireServer(character.HumanoidRootPart.Position + Vector3.new(0, 2, 5)) -- Position in front of the player

	-- Optional: Add a slight delay to allow football to be created before the next action
	wait(1)
end

-- Function to start the minigame countdown (3-2-1)
local countdownText = BeforeStartCountdown

countdownText.TextColor3 = Color3.fromRGB(255, 255, 255) 

-- Add sound effects for each countdown change
local countdownSound = game.SoundService.Boom

-- Flashy Countdown Animation Function
local function startCountdown(startTime)
	countdownText.Visible = true
	local countdownTime = startTime or 10 -- Default to 10 if no time is provided
	local tweenInfo = TweenInfo.new(1, Enum.EasingStyle.Linear, Enum.EasingDirection.InOut) -- Smooth tween animation

	for i = countdownTime, 1, -1 do
		countdownText.Text = tostring(i)

		-- Calcul
		-- Play sound
		countdownSound:Play()

		-- Wait for the tween to complete and for 1 second
		wait(1)
	end
	-- Final Countdown (0)
	countdownText.Text = "GO!"
	countdownText.TextColor3 = Color3.fromRGB(255, 255, 255) -- Green color
	wait(1)
	countdownText.Text = "" -- Clear the text after 1 second
end

-- Function to start the game countdown (30 seconds)
local function startGameCountdown()
	local timeRemaining = 30  -- Start the countdown from 30 seconds
	inGameCountdown.Visible = true
	while timeRemaining > 0 do
		inGameCountdown.Text = "Time Remaining: " .. timeRemaining
		if timeRemaining <= 10 then
			SoundService.Boom:Play()  -- Play dramatic sound every second in the last 10 seconds
		end
		wait(1)
		timeRemaining = timeRemaining - 1
	end
	inGameCountdown.Visible = false
	
end

KickingUI.Bar.TextButton.MouseButton1Click:Connect(function(plr)
	if not deb then
		deb = true
		arrowTween:Pause()
		playKickAnimationEvent:FireServer()
		-- Check if player is in range
		if Target.Position.X.Scale < Arrow.Position.X.Scale and Arrow.Position.X.Scale < Target.Position.X.Scale + Target.Size.X.Scale then
			print("In range")
			-- Play kick animation and kick the football
			playKickAnimation()
			kickFootball()
			points += 1
		else
			print("Not in range")
			-- Even if not in range, kick the football
			playKickAnimation()
			footballMissEvent:FireServer()
		end
		wait(1) -- Prevent rapid clicks
		createNewTarget()
		deb = false -- Reset debounce
	end
end)

-- Listen for the start of the minigame
ReplicatedStorage.StartMinigameEvent.OnClientEvent:Connect(function(opponent)
	points = 0
	print("Minigame started.")
	-- Start the 3-2-1 countdown
	startCountdown(3)
	-- Start the game countdown
	KickingUI.Bar.Visible = true
	startGameCountdown()
	KickingUI.Bar.Visible = false
	print("Minigame ended.")


	-- Send the points to the server for both players
	ReplicatedStorage.EndMinigameEvent:FireServer(points)
	
end)

-- Receive the game results from the server
ReplicatedStorage.EndMinigameEvent.OnClientEvent:Connect(function(yourPoints, theirPoints)
	--print("Minigame result received. Your points: " .. yourPoints .. ", Opponent's points: " .. theirPoints)
	print("Type of yourPoints: ", typeof(yourPoints))
	
	ResultUI.Visible = true
	tweenDown:Play()
	task.wait(1)
	ResultUI.YourPoints.Text = "Your Points: " .. yourPoints.Value
	ResultUI.TheirPoints.Text = "Opponent's Points: " .. theirPoints.Value

	if yourPoints > theirPoints then
		confettiFrame.Visible = true
		startConfettiRain()
		ResultUI.Result.Text = "You Won!"
		ResultUI.Won.Visible = true
		SoundService:WaitForChild("Confetti"):Play()
		ReplicatedStorage:WaitForChild("1V1"):WaitForChild("CashYummy"):FireServer(player)
	
	elseif yourPoints < theirPoints then
		ResultUI.Result.Text = "You Lost!"
		ResultUI.Lost.Visible = true
	else
		setRandomImage()
		ResultUI.Result.Text = "It's a Tie!"
		playRandomSound()
		ResultUI.Tie.Visible = true
	end


end)

button.MouseButton1Click:Connect(function()
	
	ResultUI.Lost.Visible = false
	ResultUI.Won.Visible = false
	ResultUI.Tie.Visible = false
	confettiFrame.Visible = false
	
	
	
	tweenUp:Play()
	tweenUp.Completed:Wait()
	ResultUI.Visible = false
	
	if currentSound and currentSound.IsPlaying then
		currentSound:Stop()
		print("Sound stopped.")
	else
		print("No sound is currently playing.")
	end
	
	
end)

if this is the problem what’s the solution?

Did adding “.Value” help anything? Or a new error?

Also, try changing this line:

To
print("Type of yourPoints: ", typeof(yourPoints), yourPoints.ClassName)

yes i tried that didn’t work. I will try changing that line.

error

 Players.Player2.PlayerScripts.MinigameHolder:292: attempt to index number with 'ClassName'

Also the code initially works, it gives me the error but it actually runs the code, any idea why this happens? But after time when someone does the 1v1 again it then doesn’t run the code…

is this from a print you setup?

The thing that doesn’t work is when the code access the points of both players it can’t find it but it does because when the game ends the values of the players minigames actually show up on the screen but after a couple times the code is ran it stops working, still getting the error everytime the values are used, so basically it still gives the issue of the yourpoints and theirpoints.

Based on the 2 scripts you provided, it can’t possibly be an error. Unless if there is another script firing EndMinigameEvent. Since points is still a number and it received an instance.

weird, those are the only 2 scripts that even use it.

Seems like i managed to fix the issue by converting the instance to a string.

ReplicatedStorage.EndMinigameEvent.OnClientEvent:Connect(function(yourPoints, theirPoints)
	--print("Minigame result received. Your points: " .. yourPoints .. ", Opponent's points: " .. theirPoints)
	print("Type of yourPoints: ", typeof(yourPoints))
	
	ResultUI.Visible = true
	tweenDown:Play()
	task.wait(1)
	ResultUI.YourPoints.Text = "Your Points: " .. tostring(yourPoints)
	ResultUI.TheirPoints.Text = "Opponent's Points: " .. tostring(theirPoints)

	if tostring(yourPoints) >  tostring(theirPoints) then
		confettiFrame.Visible = true
		startConfettiRain()
		ResultUI.Result.Text = "You Won!"
		ResultUI.Won.Visible = true
		SoundService:WaitForChild("Confetti"):Play()
		ReplicatedStorage:WaitForChild("1V1"):WaitForChild("CashYummy"):FireServer(player)
	
	elseif  tostring(yourPoints) <  tostring(theirPoints) then
		ResultUI.Result.Text = "You Lost!"
		ResultUI.Lost.Visible = true
	else
		setRandomImage()
		ResultUI.Result.Text = "It's a Tie!"
		playRandomSound()
		ResultUI.Tie.Visible = true
	end


end)
1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.