For some reason it says info isnt a part of frame, but its weird because when I write the script like this script.Parent.Parent.I it auto corrects it to script.Parent.Parent.Info which means it is in that location. Please help.
--player
local player = game.Players.LocalPlayer
local stats = player:WaitForChild("leaderstats")
local stat = player:WaitForChild("stats")
local gold = stats:WaitForChild("Gold")
local damage = stat:WaitForChild("Damage")
--item
local hero1 = stat:WaitForChild("Hero 1")
--fake item
local item = script.Parent.Parent.Info
local cost = item:WaitForChild("Cost")
local owned = item:WaitForChild("Owned")
local reward = item:WaitForChild("Reward")
script.Parent.MouseButton1Click:connect(function()
cost.Value = ((hero1.Value / 1) * 2) * 100
if gold.Value >= cost.Value then
gold.Value = gold.Value - cost.Value
hero1.Value = hero1.Value + 1
end
end)
while true do
wait(1)
cost.Value = ((hero1.Value / 1) * 2) * 100
owned.Value = hero1.Value
script.Parent.Text = "Purchase : $" .. cost.Value
script.Parent.Parent.Owned.Text = "Owned : " .. owned.Value
gold.Value = gold.Value + reward.Value * hero1.Value
end

2 comments
Try using WaitForChild or add/subtract another parent from it. Ex. item = script.Parent.Parent:WaitForChild("Info")
The other option is to have a wait() and then use :FindFirstChild('Info'). Depending on if you use a script to spawn the info or if it is already pre-existing you may need to delay the scripts search for it. Otherwise as long as everything is how it is supposed to be in case sensitivity your script looks like it should be working.