-- stud friend! -- Social Living Shapes local Players = game:GetService("Players") local RunService = game:GetService("RunService") local player = Players.LocalPlayer local folder = workspace:FindFirstChild("CuboidObjects") if not folder then folder = Instance.new("Folder") folder.Name = "CuboidObjects" folder.Parent = workspace end local cuboids = {} local selected = nil local size = 4 local currentColor = Color3.fromRGB(255,255,255) local FACE_DISTANCE = 100 ------------------------------------------------ -- PHRASES ------------------------------------------------ local phrases = { "๐Ÿ˜€", "๐Ÿ˜ƒ", "๐Ÿ˜„", "๐Ÿ˜", "๐Ÿ˜†", "๐Ÿ˜…", "๐Ÿคฃ", "๐Ÿ˜‚", "๐Ÿ™‚", "๐Ÿ™ƒ", "๐Ÿซ ", "๐Ÿ˜‰", "๐Ÿ˜Š", "๐Ÿ˜‡", "๐Ÿฅฐ", "๐Ÿ˜", "๐Ÿคฉ", "๐Ÿ˜˜", "๐Ÿ˜—", "๐Ÿ˜š", "๐Ÿ˜™", "๐Ÿ˜‹", "๐Ÿ˜›", "๐Ÿ˜œ", "๐Ÿคช", "๐Ÿ˜", "๐Ÿค‘", "๐Ÿค—", "๐Ÿคญ", "๐Ÿซข", "๐Ÿซฃ", "๐Ÿคซ", "๐Ÿค”", "๐Ÿซก", "๐Ÿค", "๐Ÿคจ", "๐Ÿ˜", "๐Ÿ˜‘", "๐Ÿ˜ถ", "๐Ÿซฅ", "๐Ÿ˜ถโ€๐ŸŒซ๏ธ", "๐Ÿ˜", "๐Ÿ˜’", "๐Ÿ™„", "๐Ÿ˜ฌ", "๐Ÿ˜ฎโ€๐Ÿ’จ", "๐Ÿคฅ", "๐Ÿ˜Œ", "๐Ÿ˜”", "๐Ÿ˜ช", "๐Ÿคค", "๐Ÿ˜ด", "๐Ÿ˜ท", "๐Ÿค’", "๐Ÿค•", "๐Ÿคข", "๐Ÿคฎ", "๐Ÿคง", "๐Ÿฅต", "๐Ÿฅถ", "๐Ÿฅด", "๐Ÿ˜ต", "๐Ÿ˜ตโ€๐Ÿ’ซ", "๐Ÿคฏ", "๐Ÿค ", "๐Ÿฅณ", "๐Ÿฅธ", "๐Ÿ˜Ž", "๐Ÿค“", "๐Ÿง", "๐Ÿ˜•", "๐Ÿซค", "๐Ÿ˜Ÿ", "๐Ÿ™", "โ˜น๏ธ", "๐Ÿ˜ฎ", "๐Ÿ˜ฏ", "๐Ÿ˜ฒ", "๐Ÿ˜ณ", "๐Ÿฅบ", "๐Ÿฅน", "๐Ÿ˜ฆ", "๐Ÿ˜ง", "๐Ÿ˜จ", "๐Ÿ˜ฐ", "๐Ÿ˜ฅ", "๐Ÿ˜ข", "๐Ÿ˜ญ", "๐Ÿ˜ฑ", "๐Ÿ˜–", "๐Ÿ˜ฃ", "๐Ÿ˜ž", "๐Ÿ˜“", "๐Ÿ˜ฉ", "๐Ÿ˜ซ", "๐Ÿฅฑ", "๐Ÿ˜ค", "๐Ÿ˜ก", "๐Ÿ˜ ", "๐Ÿคฌ", "๐Ÿ˜ˆ", "๐Ÿ‘ฟ", "๐Ÿ’€", "โ˜ ๏ธ", "๐Ÿ‘ป", "๐Ÿ‘ฝ", "๐Ÿค–", "๐Ÿ’ฉ", "๐Ÿคก", "๐Ÿ‘น", "๐Ÿ‘บ", "๐Ÿ‘ถ" } ------------------------------------------------ -- GUI ------------------------------------------------ local gui = Instance.new("ScreenGui") gui.Name = "CuboidUI" gui.ResetOnSpawn = false gui.Parent = player.PlayerGui local function makeButton(text,x,y,func) local b = Instance.new("TextButton") b.Size = UDim2.new( 0, 60, 0, 20 ) b.Position = UDim2.new( 0, x, 0, y ) b.Text = text b.TextScaled = true b.Parent = gui b.MouseButton1Click:Connect(func) return b end ------------------------------------------------ -- FACE SYSTEM ------------------------------------------------ local function setFace(part,text) local old = part:FindFirstChild("Face") if old then old:Destroy() end local face = Instance.new("BillboardGui") face.Name = "Face" face.Size = UDim2.new( 0, 70, 0, 70 ) face.AlwaysOnTop = true face.Parent = part local label = Instance.new("TextLabel") label.Size = UDim2.fromScale( 1, 1 ) label.BackgroundTransparency = 1 label.Text = text label.TextScaled = true label.Parent = face end ------------------------------------------------ -- SPEECH ------------------------------------------------ local function speak(part) local old = part:FindFirstChild("Speech") if old then old:Destroy() end local bubble = Instance.new("BillboardGui") bubble.Name = "Speech" bubble.Size = UDim2.new( 0, 130, 0, 35 ) bubble.StudsOffset = Vector3.new( 0, 3, 0 ) bubble.AlwaysOnTop = true bubble.Parent = part local text = Instance.new("TextLabel") text.Size = UDim2.fromScale( 1, 1 ) text.BackgroundTransparency = 1 text.TextScaled = true text.Text = phrases[ math.random( 1, #phrases ) ] text.Parent = bubble task.delay( 3, function() if bubble then bubble:Destroy() end end ) end ------------------------------------------------ -- DISTANCE FACE HIDING ------------------------------------------------ local function updateFaceDistance() if not player.Character then return end local root = player.Character:FindFirstChild( "HumanoidRootPart" ) if not root then return end for _,c in pairs(cuboids) do local face = c.Object:FindFirstChild( "Face" ) local speech = c.Object:FindFirstChild( "Speech" ) local distance = ( root.Position - c.Object.Position ).Magnitude if face then face.Enabled = distance <= FACE_DISTANCE end if speech then speech.Enabled = distance <= FACE_DISTANCE end end end ------------------------------------------------ -- COLORS ------------------------------------------------ local colors = { {"Red",Color3.fromRGB(255,0,0)}, {"Orange",Color3.fromRGB(255,120,0)}, {"Yellow",Color3.fromRGB(255,255,0)}, {"Lime",Color3.fromRGB(100,255,0)}, {"Green",Color3.fromRGB(0,255,80)}, {"Cyan",Color3.fromRGB(0,255,255)}, {"Blue",Color3.fromRGB(0,100,255)}, {"Purple",Color3.fromRGB(150,0,255)}, {"Pink",Color3.fromRGB(255,0,170)}, {"White",Color3.fromRGB(255,255,255)}, {"Gray",Color3.fromRGB(120,120,120)}, {"Black",Color3.fromRGB(0,0,0)} } for i,c in ipairs(colors) do makeButton( c[1], (i-1)%4*65, 150+ math.floor((i-1)/4)*25, function() currentColor = c[2] end ) end ------------------------------------------------ -- SPAWN CUBOID ------------------------------------------------ local function spawnCuboid(shape) local part = Instance.new("Part") part.Name = shape.." Cuboid" part.Size = Vector3.new( size, size, size ) if shape == "Sphere" then part.Shape = Enum.PartType.Ball elseif shape == "Cylinder" then part.Shape = Enum.PartType.Cylinder elseif shape == "Wedge" then part.Shape = Enum.PartType.Wedge end part.Color = currentColor part.Position = player.Character.HumanoidRootPart.Position + Vector3.new( math.random(-10,10), 5, math.random(-10,10) ) part.Parent = folder local data = { Object = part, Type = shape, Mode = "Stare", IdleTime = 0, Sleeping = false, NormalFace = ":P", MoveTimer = 0, Direction = Vector3.zero, SpeechTimer = math.random(5,12), Bonk = false, SocialTimer = 0, LastBlock = 0, LastSpawn = 0, SpawnPoints = {}, HomePosition = part.Position } table.insert( cuboids, data ) -- alive instantly setFace( part, ":P" ) ------------------------------------------------ -- SELECTION ------------------------------------------------ local click = Instance.new("ClickDetector") click.MaxActivationDistance = 60 click.Parent = part click.MouseClick:Connect(function() selected = data print( shape.." selected" ) end) ------------------------------------------------ -- BONK ------------------------------------------------ part.Touched:Connect(function(hit) if data.Bonk then return end if hit:IsDescendantOf(folder) then return end data.Bonk = true setFace( part, "o_O" ) task.delay( 1, function() data.Bonk = false if data.Mode=="Stare" then setFace(part,":P") elseif data.Mode=="Wonder" then setFace(part,":)") elseif data.Mode=="Attack" then setFace(part,">:(") elseif data.Mode=="Follow" then setFace(part,":D") elseif data.Mode=="Social" then setFace(part,":D") end end ) end) end ---------------------------------- -- FUNCTIONS ---------------------------------- local function buildBlock(c) if tick() - (c.LastPlank or 0) < 0.3 then return end c.LastPlank = tick() local block = Instance.new("Part") block.Name = "StudBlock" block.Anchored = true block.Size = Vector3.new(4,4,4) block.Material = Enum.Material.Plastic block.Color = c.Object.Color block.Position = Vector3.new( math.floor(c.Object.Position.X/4 + 0.5) * 4, math.floor((c.Object.Position.Y-4)/4 + 0.5) * 4, math.floor(c.Object.Position.Z/4 + 0.5) * 4 ) block.Parent = folder end local function buildSpawn(c) c.SpawnPoints=c.SpawnPoints or {} if tick()-(c.LastSpawn or 0)<60 then return end c.LastSpawn=tick() local spawn=Instance.new("SpawnLocation") spawn.Anchored=true spawn.Size=Vector3.new(6,1,6) spawn.Position= c.Object.Position- Vector3.new(0,2.5,0) spawn.Neutral=true spawn.Color=c.Object.Color spawn.Parent=folder table.insert( c.SpawnPoints, spawn ) end local function checkVoid(c) if c.Object.Position.Y>-100 then return end local closest local dist=math.huge for _,spawn in ipairs(c.SpawnPoints or {}) do if spawn.Parent then local d= (c.Object.Position- spawn.Position).Magnitude if d= 10 then c.Sleeping = true setFace( part, "-_-" ) else setFace( part, ":P" ) end local other = findNearbyCuboid(c) if other and other.Mode=="Stare" then local d = ( other.Object.Position -part.Position ).Magnitude if d < 20 then part.CFrame = CFrame.lookAt( part.Position, other.Object.Position ) if math.random(1,200)==1 then speak(part) end end end end ------------------------------------------------ -- WONDER ------------------------------------------------ if c.Mode=="Wonder" then c.IdleTime=0 c.Sleeping=false setFace( part, ":)" ) c.MoveTimer -= dt if c.MoveTimer <= 0 then c.MoveTimer = math.random(2,5) c.Direction = Vector3.new( math.random(-10,10), 0, math.random(-10,10) ).Unit end part.AssemblyLinearVelocity = c.Direction*8 if c.Type=="Cube" or c.Type=="Wedge" then part.CFrame = CFrame.lookAt( part.Position, part.Position+c.Direction ) end checkGap(c) randomSpawn(c) checkVoid(c) end ------------------------------------------------ -- ATTACK ------------------------------------------------ if c.Mode=="Attack" then c.IdleTime = 0 c.Sleeping = false setFace( part, ">:(" ) if target then local direction = ( target.Character.HumanoidRootPart.Position -part.Position ).Unit part.AssemblyLinearVelocity = direction*18 if c.Type=="Cube" or c.Type=="Wedge" then part.CFrame = CFrame.lookAt( part.Position, part.Position+direction ) end if (part.Position - target.Character.HumanoidRootPart.Position) .Magnitude < 5 then target.Character.Humanoid:TakeDamage(5) end end end ------------------------------------------------ -- FOLLOW ------------------------------------------------ if c.Mode=="Follow" then c.IdleTime=0 c.Sleeping=false setFace( part, ":D" ) if target then local direction = ( target.Character.HumanoidRootPart.Position -part.Position ).Unit part.AssemblyLinearVelocity = direction*10 if c.Type=="Cube" or c.Type=="Wedge" then part.CFrame = CFrame.lookAt( part.Position, part.Position+direction ) end end end ------------------------------------------------ -- SOCIAL MODE ------------------------------------------------ if c.Mode=="Social" then c.IdleTime=0 c.Sleeping=false local other = findNearbyCuboid(c) if other then local distance = ( other.Object.Position -part.Position ).Magnitude if distance > 8 then local direction = ( other.Object.Position -part.Position ).Unit part.AssemblyLinearVelocity = direction*7 setFace( part, ":D" ) else part.AssemblyLinearVelocity = Vector3.zero part.CFrame = CFrame.lookAt( part.Position, other.Object.Position ) setFace( part, ":D" ) c.SpeechTimer -= dt if c.SpeechTimer <= 0 then speak(part) c.SpeechTimer = math.random(8,15) end end end end end end) ------------------------------------------------ -- SPAWN BUTTONS ------------------------------------------------ makeButton( "Cube", 10, 20, function() spawnCuboid("Cube") end) makeButton( "Sphere", 75, 20, function() spawnCuboid("Sphere") end) makeButton( "Cyl", 140, 20, function() spawnCuboid("Cylinder") end) makeButton( "Wedge", 205, 20, function() spawnCuboid("Wedge") end) ------------------------------------------------ -- SIZE BUTTONS ------------------------------------------------ makeButton( "+", 270, 20, function() size += 2 end) makeButton( "-", 335, 20, function() size = math.max( 2, size-2 ) end) ------------------------------------------------ -- MODE BUTTONS ------------------------------------------------ makeButton( "Stare", 10, 100, function() if selected then selected.Mode="Stare" selected.IdleTime=0 setFace(selected.Object,":P") end end) makeButton( "Wonder", 75, 100, function() if selected then selected.Mode="Wonder" selected.IdleTime=0 setFace(selected.Object,":)") end end) makeButton( "Attack", 140, 100, function() if selected then selected.Mode="Attack" selected.IdleTime=0 setFace(selected.Object,">:(") end end) makeButton( "Follow", 205, 100, function() if selected then selected.Mode="Follow" selected.IdleTime=0 setFace(selected.Object,":D") end end) makeButton( "Social", 270, 100, function() if selected then selected.Mode="Social" selected.IdleTime=0 setFace(selected.Object,":D") end end)