<roblox version="4">
  <Item class="ReplicatedStorage" referent="0">
    <Properties>
      <string name="Name">ReplicatedStorage</string>
    </Properties>
  </Item>
  <Item class="ServerScriptService" referent="1">
    <Properties>
      <string name="Name">ServerScriptService</string>
    </Properties>
    <Item class="Script" referent="2">
      <Properties>
        <string name="Name">BuildServer</string>
        <token name="RunContext">0</token>
        <string name="Source"><![CDATA[local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local DataStoreService = game:GetService("DataStoreService")
local Lighting = game:GetService("Lighting")

local GRID = 4
local PLOT_SIZE = 72
local MAX_ITEMS = 100

local itemDefinitions = {
	Crate = {size = Vector3.new(4, 4, 4), color = Color3.fromRGB(166, 112, 67), material = Enum.Material.WoodPlanks, cost = 5},
	Wall = {size = Vector3.new(8, 8, 1), color = Color3.fromRGB(225, 214, 190), material = Enum.Material.Brick, cost = 10},
	Lamp = {size = Vector3.new(2, 8, 2), color = Color3.fromRGB(54, 63, 75), material = Enum.Material.Metal, cost = 15},
	Planter = {size = Vector3.new(6, 3, 6), color = Color3.fromRGB(126, 78, 49), material = Enum.Material.Wood, cost = 12},
}

local remotes = Instance.new("Folder")
remotes.Name = "BuildRemotes"
remotes.Parent = ReplicatedStorage

local placeRemote = Instance.new("RemoteEvent")
placeRemote.Name = "Place"
placeRemote.Parent = remotes

local deleteRemote = Instance.new("RemoteEvent")
deleteRemote.Name = "Delete"
deleteRemote.Parent = remotes

local noticeRemote = Instance.new("RemoteEvent")
noticeRemote.Name = "Notice"
noticeRemote.Parent = remotes

local definitionsFolder = Instance.new("Folder")
definitionsFolder.Name = "Definitions"
definitionsFolder.Parent = remotes
for name, definition in pairs(itemDefinitions) do
	local value = Instance.new("Vector3Value")
	value.Name = name
	value.Value = definition.size
	value:SetAttribute("Cost", definition.cost)
	value.Parent = definitionsFolder
end

local world = Instance.new("Folder")
world.Name = "BuildAndSaveWorld"
world.Parent = workspace

workspace.FallenPartsDestroyHeight = -80
Lighting.ClockTime = 15.5
Lighting.Brightness = 2
Lighting.EnvironmentDiffuseScale = 0.55
Lighting.EnvironmentSpecularScale = 0.65
Lighting.Ambient = Color3.fromRGB(104, 116, 128)

local atmosphere = Instance.new("Atmosphere")
atmosphere.Density = 0.24
atmosphere.Color = Color3.fromRGB(199, 222, 255)
atmosphere.Decay = Color3.fromRGB(116, 145, 176)
atmosphere.Parent = Lighting

local island = Instance.new("Part")
island.Name = "Island"
island.Size = Vector3.new(150, 8, 150)
island.Position = Vector3.new(0, -5, 0)
island.Anchored = true
island.Material = Enum.Material.Grass
island.Color = Color3.fromRGB(88, 142, 73)
island.Parent = world

local plot = Instance.new("Part")
plot.Name = "PlayerPlot"
plot.Size = Vector3.new(PLOT_SIZE, 1, PLOT_SIZE)
plot.Position = Vector3.new(0, 0, 0)
plot.Anchored = true
plot.Material = Enum.Material.Slate
plot.Color = Color3.fromRGB(86, 91, 94)
plot.Parent = world

local border = Instance.new("SelectionBox")
border.Adornee = plot
border.LineThickness = 0.08
border.Color3 = Color3.fromRGB(255, 208, 84)
border.SurfaceTransparency = 0.92
border.Parent = plot

local spawn = Instance.new("SpawnLocation")
spawn.Name = "WorkshopSpawn"
spawn.Size = Vector3.new(8, 1, 8)
spawn.Position = Vector3.new(0, 1, 29)
spawn.Anchored = true
spawn.Neutral = true
spawn.Material = Enum.Material.WoodPlanks
spawn.Color = Color3.fromRGB(236, 191, 102)
spawn.Parent = world

local builds = Instance.new("Folder")
builds.Name = "PlayerBuilds"
builds.Parent = world

local dataStore = DataStoreService:GetDataStore("BuildAndSave_v1")
local playerFolders = {}

local function snap(number)
	return math.round(number / GRID) * GRID
end

local function inPlot(position, size)
	local half = PLOT_SIZE / 2
	return math.abs(position.X) + size.X / 2 <= half and math.abs(position.Z) + size.Z / 2 <= half and position.Y >= 2 and position.Y <= 42
end

local function createItem(owner, itemName, position, rotation)
	local definition = itemDefinitions[itemName]
	if not definition then return nil end
	local part = Instance.new("Part")
	part.Name = itemName
	part.Size = definition.size
	part.CFrame = CFrame.new(position) * CFrame.Angles(0, math.rad(rotation), 0)
	part.Anchored = true
	part.Material = definition.material
	part.Color = definition.color
	part.TopSurface = Enum.SurfaceType.Smooth
	part.BottomSurface = Enum.SurfaceType.Smooth
	part:SetAttribute("OwnerUserId", owner.UserId)
	part:SetAttribute("ItemType", itemName)
	part:SetAttribute("Rotation", rotation)
	part.Parent = playerFolders[owner]

	if itemName == "Lamp" then
		local light = Instance.new("PointLight")
		light.Color = Color3.fromRGB(255, 220, 142)
		light.Range = 18
		light.Brightness = 2
		light.Parent = part
	elseif itemName == "Planter" then
		local plant = Instance.new("Part")
		plant.Name = "Plant"
		plant.Shape = Enum.PartType.Ball
		plant.Size = Vector3.new(4.5, 4.5, 4.5)
		plant.Position = position + Vector3.new(0, 3, 0)
		plant.Anchored = true
		plant.CanCollide = false
		plant.Material = Enum.Material.Grass
		plant.Color = Color3.fromRGB(64, 132, 65)
		plant:SetAttribute("OwnerUserId", owner.UserId)
		plant.Parent = part
	end
	return part
end

local function savePlayer(player)
	local folder = playerFolders[player]
	if not folder then return end
	local payload = {}
	for _, item in ipairs(folder:GetChildren()) do
		if item:IsA("BasePart") and item:GetAttribute("ItemType") then
			table.insert(payload, {
				t = item:GetAttribute("ItemType"),
				x = item.Position.X,
				y = item.Position.Y,
				z = item.Position.Z,
				r = item:GetAttribute("Rotation") or 0,
			})
		end
	end
	local ok, err = pcall(function()
		dataStore:SetAsync("u_" .. player.UserId, payload)
	end)
	if not ok then warn("Build save unavailable:", err) end
end

local function loadPlayer(player)
	local payload
	local ok, err = pcall(function()
		payload = dataStore:GetAsync("u_" .. player.UserId)
	end)
	if not ok then
		warn("Build load unavailable:", err)
		return
	end
	if type(payload) ~= "table" then return end
	for index, saved in ipairs(payload) do
		if index > MAX_ITEMS then break end
		if itemDefinitions[saved.t] and typeof(saved.x) == "number" and typeof(saved.y) == "number" and typeof(saved.z) == "number" then
			local position = Vector3.new(saved.x, saved.y, saved.z)
			if inPlot(position, itemDefinitions[saved.t].size) then
				createItem(player, saved.t, position, saved.r or 0)
			end
		end
	end
end

Players.PlayerAdded:Connect(function(player)
	local folder = Instance.new("Folder")
	folder.Name = tostring(player.UserId)
	folder.Parent = builds
	playerFolders[player] = folder
	player:SetAttribute("BuildCoins", 250)
	task.defer(loadPlayer, player)
end)

placeRemote.OnServerEvent:Connect(function(player, itemName, requestedPosition, rotation)
	local definition = itemDefinitions[itemName]
	local folder = playerFolders[player]
	if not definition or not folder or typeof(requestedPosition) ~= "Vector3" or typeof(rotation) ~= "number" then return end
	if #folder:GetChildren() >= MAX_ITEMS then
		noticeRemote:FireClient(player, "Plot limit reached")
		return
	end
	local coins = player:GetAttribute("BuildCoins") or 0
	if coins < definition.cost then
		noticeRemote:FireClient(player, "Not enough build coins")
		return
	end
	rotation = math.floor(rotation / 90 + 0.5) * 90 % 360
	local size = definition.size
	if rotation % 180 ~= 0 then size = Vector3.new(size.Z, size.Y, size.X) end
	local position = Vector3.new(snap(requestedPosition.X), snap(requestedPosition.Y - size.Y / 2) + size.Y / 2, snap(requestedPosition.Z))
	if not inPlot(position, size) then
		noticeRemote:FireClient(player, "Place inside your plot")
		return
	end
	local overlapParams = OverlapParams.new()
	overlapParams.FilterType = Enum.RaycastFilterType.Exclude
	overlapParams.FilterDescendantsInstances = {plot, island, spawn}
	local overlaps = workspace:GetPartBoundsInBox(CFrame.new(position) * CFrame.Angles(0, math.rad(rotation), 0), size - Vector3.new(0.2, 0.2, 0.2), overlapParams)
	for _, overlap in ipairs(overlaps) do
		if overlap:IsDescendantOf(builds) then
			noticeRemote:FireClient(player, "That space is occupied")
			return
		end
	end
	player:SetAttribute("BuildCoins", coins - definition.cost)
	createItem(player, itemName, position, rotation)
end)

deleteRemote.OnServerEvent:Connect(function(player, target)
	if typeof(target) ~= "Instance" or not target:IsA("BasePart") then return end
	if target:GetAttribute("OwnerUserId") ~= player.UserId then return end
	local itemName = target:GetAttribute("ItemType")
	if not itemDefinitions[itemName] then return end
	player:SetAttribute("BuildCoins", (player:GetAttribute("BuildCoins") or 0) + math.floor(itemDefinitions[itemName].cost / 2))
	target:Destroy()
end)

Players.PlayerRemoving:Connect(function(player)
	savePlayer(player)
	playerFolders[player] = nil
end)

game:BindToClose(function()
	for _, player in ipairs(Players:GetPlayers()) do savePlayer(player) end
end)
]]></string>
      </Properties>
    </Item>
    <Item class="Script" referent="3">
      <Properties>
        <string name="Name">PortfolioPolish</string>
        <token name="RunContext">0</token>
        <string name="Source"><![CDATA[local Players = game:GetService("Players")
local Lighting = game:GetService("Lighting")

local PROJECTS = {
	AetherDuel = {title = "AETHER DUEL", accent = Color3.fromRGB(67, 167, 255)},
	SkylineSprint = {title = "SKYLINE SPRINT", accent = Color3.fromRGB(45, 200, 255)},
	BomblineGrid = {title = "BOMBLINE GRID", accent = Color3.fromRGB(255, 193, 70)},
	SignalSiege = {title = "SIGNAL SIEGE", accent = Color3.fromRGB(55, 190, 255)},
	BuildAndSaveWorld = {title = "BUILD & SAVE", accent = Color3.fromRGB(255, 208, 84)},
	RailRushWorld = {title = "RAIL RUSH", accent = Color3.fromRGB(104, 205, 255)},
	FreightyardArena = {title = "TEAM SHOTGUN", accent = Color3.fromRGB(255, 133, 73)},
	CrystalFoundry = {title = "CRYSTAL FOUNDRY", accent = Color3.fromRGB(151, 103, 255)},
}

local function findProject()
	for name, config in pairs(PROJECTS) do
		local world = workspace:FindFirstChild(name)
		if world then return world, name, config end
	end
	for _ = 1, 100 do
		task.wait(0.1)
		for name, config in pairs(PROJECTS) do
			local world = workspace:FindFirstChild(name)
			if world then return world, name, config end
		end
	end
end

local world, projectName, config = findProject()
if not world then return end
workspace:SetAttribute("PortfolioProject", projectName)
workspace:SetAttribute("PortfolioTitle", config.title)
workspace:SetAttribute("PortfolioAccent", config.accent)

local polish = Instance.new("Folder")
polish.Name = "PresentationPolish"
polish.Parent = world

local function makePart(name, size, cframe, color, material, parent)
	local part = Instance.new("Part")
	part.Name = name
	part.Size = size
	part.CFrame = cframe
	part.Color = color
	part.Material = material or Enum.Material.SmoothPlastic
	part.Anchored = true
	part.TopSurface = Enum.SurfaceType.Smooth
	part.BottomSurface = Enum.SurfaceType.Smooth
	part.Parent = parent or polish
	return part
end

local function billboard(position, text, accent)
	local anchor = makePart("Landmark", Vector3.new(1, 1, 1), CFrame.new(position), accent, Enum.Material.Neon)
	anchor.Transparency = 1
	anchor.CanCollide = false
	local gui = Instance.new("BillboardGui")
	gui.Size = UDim2.fromOffset(420, 90)
	gui.AlwaysOnTop = false
	gui.MaxDistance = 260
	gui.Parent = anchor
	local label = Instance.new("TextLabel")
	label.Size = UDim2.fromScale(1, 1)
	label.BackgroundTransparency = 1
	label.Text = text
	label.TextColor3 = Color3.new(1, 1, 1)
	label.TextStrokeTransparency = 0.25
	label.Font = Enum.Font.GothamBlack
	label.TextScaled = true
	label.Parent = gui
end

local function barrier(size, position)
	local wall = makePart("SafetyBarrier", size, CFrame.new(position), Color3.new(1, 1, 1), Enum.Material.SmoothPlastic)
	wall.Transparency = 1
	wall.CanCollide = true
	wall.CanQuery = false
end

local function lamp(position, accent)
	makePart("LampPost", Vector3.new(1, 12, 1), CFrame.new(position + Vector3.new(0, 6, 0)), Color3.fromRGB(47, 53, 63), Enum.Material.Metal)
	local head = makePart("LampHead", Vector3.new(3, 1, 3), CFrame.new(position + Vector3.new(0, 12, 0)), accent, Enum.Material.Neon)
	head.CanCollide = false
	local light = Instance.new("PointLight")
	light.Color = accent
	light.Range = 24
	light.Brightness = 1.2
	light.Parent = head
end

local dressers = {}

dressers.AetherDuel = function()
	billboard(Vector3.new(0, 35, -49), "AETHER DUEL", config.accent)
	for _, position in ipairs({Vector3.new(-38, 2, 0), Vector3.new(38, 2, 0), Vector3.new(0, 2, -38), Vector3.new(0, 2, 38)}) do lamp(position, config.accent) end
	barrier(Vector3.new(116, 18, 2), Vector3.new(0, 8, -56)); barrier(Vector3.new(116, 18, 2), Vector3.new(0, 8, 56))
	barrier(Vector3.new(2, 18, 116), Vector3.new(-56, 8, 0)); barrier(Vector3.new(2, 18, 116), Vector3.new(56, 8, 0))
end

dressers.SkylineSprint = function()
	billboard(Vector3.new(0, 34, -150), "SKYLINE SPRINT", config.accent)
	for _, position in ipairs({Vector3.new(-185, 2, -168), Vector3.new(-90, 2, -168), Vector3.new(0, 2, -168), Vector3.new(90, 2, -168), Vector3.new(185, 2, -168)}) do lamp(position, config.accent) end
end

dressers.BomblineGrid = function()
	billboard(Vector3.new(0, 29, -82), "BOMBLINE GRID", config.accent)
	barrier(Vector3.new(170, 12, 2), Vector3.new(0, 5, -83)); barrier(Vector3.new(170, 12, 2), Vector3.new(0, 5, 83))
	barrier(Vector3.new(2, 12, 170), Vector3.new(-83, 5, 0)); barrier(Vector3.new(2, 12, 170), Vector3.new(83, 5, 0))
end

dressers.SignalSiege = function()
	billboard(Vector3.new(155, 39, 18), "PROTECT THE SIGNAL", config.accent)
	for _, position in ipairs({Vector3.new(-170, 1, -140), Vector3.new(-80, 1, 35), Vector3.new(45, 1, 55), Vector3.new(145, 1, 100)}) do lamp(position, config.accent) end
end

dressers.BuildAndSaveWorld = function()
	billboard(Vector3.new(0, 25, 36), "YOUR WORKSHOP", config.accent)
	for _, position in ipairs({Vector3.new(-43, 0, -43), Vector3.new(43, 0, -43), Vector3.new(-43, 0, 43), Vector3.new(43, 0, 43)}) do lamp(position, config.accent) end
end

dressers.RailRushWorld = function()
	billboard(Vector3.new(0, 53, 4), "RAIL RUSH", config.accent)
	for _, position in ipairs({Vector3.new(-18, 32, 8), Vector3.new(18, 32, 8), Vector3.new(-18, 30, -10), Vector3.new(18, 30, -10)}) do lamp(position, config.accent) end
end

dressers.FreightyardArena = function()
	billboard(Vector3.new(0, 29, -61), "FREIGHTYARD SHOWDOWN", config.accent)
	for _, position in ipairs({Vector3.new(-70, 0, -50), Vector3.new(-25, 0, 50), Vector3.new(25, 0, -50), Vector3.new(70, 0, 50)}) do lamp(position, config.accent) end
end

dressers.CrystalFoundry = function()
	billboard(Vector3.new(0, 28, 73), "CRYSTAL FOUNDRY", config.accent)
	for _, position in ipairs({Vector3.new(-32, 0, 35), Vector3.new(32, 0, 35), Vector3.new(-32, 0, 70), Vector3.new(32, 0, 70)}) do lamp(position, config.accent) end
end

if dressers[projectName] then dressers[projectName]() end

local colorCorrection = Instance.new("ColorCorrectionEffect")
colorCorrection.Name = "PortfolioColor"
colorCorrection.Brightness = 0.02
colorCorrection.Contrast = 0.08
colorCorrection.Saturation = 0.06
colorCorrection.Parent = Lighting

local function dressCharacter(character)
	local torso = character:WaitForChild("UpperTorso", 3) or character:WaitForChild("Torso", 3)
	if not torso or character:FindFirstChild("PortfolioArmor") then return end
	local folder = Instance.new("Folder")
	folder.Name = "PortfolioArmor"
	folder.Parent = character
	for _, offset in ipairs({-1, 1}) do
		local plate = Instance.new("Part")
		plate.Name = "ShoulderPlate"
		plate.Size = Vector3.new(1.5, 0.55, 1.8)
		plate.Color = config.accent
		plate.Material = Enum.Material.Metal
		plate.CanCollide = false
		plate.Massless = true
		plate.CFrame = torso.CFrame * CFrame.new(offset * 1.55, 0.75, 0)
		plate.Parent = folder
		local weld = Instance.new("WeldConstraint")
		weld.Part0 = torso
		weld.Part1 = plate
		weld.Parent = plate
	end
end

local function stabilizeCharacter(character)
	local humanoid = character:WaitForChild("Humanoid", 8)
	local root = character:WaitForChild("HumanoidRootPart", 8)
	if not humanoid or not root then return end

	-- Every portfolio map is generated by a server script. On a cold Studio play,
	-- Roblox can create the avatar before that map''s SpawnLocation is ready.
	local spawnLocation = world:FindFirstChildWhichIsA("SpawnLocation", true)
	if spawnLocation then
		root.AssemblyLinearVelocity = Vector3.zero
		root.AssemblyAngularVelocity = Vector3.zero
		root.CFrame = spawnLocation.CFrame * CFrame.new(0, 4, 0)
	end

	local forceField = Instance.new("ForceField")
	forceField.Name = "SpawnProtection"
	forceField.Visible = false
	forceField.Parent = character
	humanoid.Health = humanoid.MaxHealth

	local safeCFrame = root.CFrame
	local started = os.clock()
	local connection
	connection = game:GetService("RunService").Heartbeat:Connect(function()
		if not character.Parent or humanoid.Health <= 0 then
			connection:Disconnect()
			return
		end
		if root.Position.Y < -40 then
			root.AssemblyLinearVelocity = Vector3.zero
			root.AssemblyAngularVelocity = Vector3.zero
			root.CFrame = safeCFrame
			humanoid.Health = humanoid.MaxHealth
		end
		if os.clock() - started >= 8 then
			connection:Disconnect()
			if forceField.Parent then forceField:Destroy() end
		end
	end)
end

local function setupPlayer(player)
	player.CharacterAdded:Connect(function(character)
		task.spawn(stabilizeCharacter, character)
		task.spawn(dressCharacter, character)
	end)
	if player.Character then
		task.spawn(stabilizeCharacter, player.Character)
		task.spawn(dressCharacter, player.Character)
	end
end
Players.PlayerAdded:Connect(setupPlayer)
for _, player in ipairs(Players:GetPlayers()) do setupPlayer(player) end
]]></string>
      </Properties>
    </Item>
  </Item>
  <Item class="StarterPlayer" referent="4">
    <Properties>
      <string name="Name">StarterPlayer</string>
    </Properties>
    <Item class="StarterPlayerScripts" referent="5">
      <Properties>
        <string name="Name">StarterPlayerScripts</string>
      </Properties>
      <Item class="LocalScript" referent="6">
        <Properties>
          <string name="Name">BuildClient</string>
          <string name="Source"><![CDATA[local Players = game:GetService("Players")
local UserInputService = game:GetService("UserInputService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")

local player = Players.LocalPlayer
local mouse = player:GetMouse()
local remotes = ReplicatedStorage:WaitForChild("BuildRemotes")
local definitions = remotes:WaitForChild("Definitions")
local placeRemote = remotes:WaitForChild("Place")
local deleteRemote = remotes:WaitForChild("Delete")
local noticeRemote = remotes:WaitForChild("Notice")

local buildMode = false
local deleteMode = false
local selected = "Crate"
local rotation = 0
local preview

local gui = Instance.new("ScreenGui")
gui.Name = "BuildHUD"
gui.ResetOnSpawn = false
gui.Parent = player:WaitForChild("PlayerGui")

local panel = Instance.new("Frame")
panel.Size = UDim2.fromOffset(390, 140)
panel.Position = UDim2.new(0.5, -195, 1, -165)
panel.BackgroundColor3 = Color3.fromRGB(25, 31, 37)
panel.BackgroundTransparency = 0.08
panel.Parent = gui
Instance.new("UICorner", panel).CornerRadius = UDim.new(0, 16)

local title = Instance.new("TextLabel")
title.Size = UDim2.new(1, -24, 0, 34)
title.Position = UDim2.fromOffset(12, 8)
title.BackgroundTransparency = 1
title.Text = "BUILD & SAVE  •  B TO BUILD"
title.Font = Enum.Font.GothamBold
title.TextSize = 18
title.TextColor3 = Color3.fromRGB(255, 220, 128)
title.TextXAlignment = Enum.TextXAlignment.Left
title.Parent = panel

local status = Instance.new("TextLabel")
status.Size = UDim2.new(1, -24, 0, 24)
status.Position = UDim2.fromOffset(12, 43)
status.BackgroundTransparency = 1
status.Text = "Explore your workshop plot"
status.Font = Enum.Font.Gotham
status.TextSize = 14
status.TextColor3 = Color3.fromRGB(225, 230, 235)
status.TextXAlignment = Enum.TextXAlignment.Left
status.Parent = panel

local coins = Instance.new("TextLabel")
coins.Size = UDim2.fromOffset(150, 28)
coins.Position = UDim2.new(1, -162, 0, 10)
coins.BackgroundTransparency = 1
coins.Font = Enum.Font.GothamBold
coins.TextSize = 15
coins.TextColor3 = Color3.fromRGB(112, 224, 145)
coins.TextXAlignment = Enum.TextXAlignment.Right
coins.Parent = panel

local itemNames = {"Crate", "Wall", "Lamp", "Planter"}
for index, name in ipairs(itemNames) do
	local button = Instance.new("TextButton")
	button.Name = name
	button.Size = UDim2.fromOffset(84, 48)
	button.Position = UDim2.fromOffset(12 + (index - 1) * 92, 78)
	button.BackgroundColor3 = index == 1 and Color3.fromRGB(219, 155, 66) or Color3.fromRGB(56, 67, 78)
	button.Text = index .. "  " .. name .. "\n$" .. definitions:WaitForChild(name):GetAttribute("Cost")
	button.TextColor3 = Color3.new(1, 1, 1)
	button.Font = Enum.Font.GothamBold
	button.TextSize = 13
	button.Parent = panel
	Instance.new("UICorner", button).CornerRadius = UDim.new(0, 10)
	button.Activated:Connect(function()
		selected = name
		deleteMode = false
		for _, child in ipairs(panel:GetChildren()) do
			if child:IsA("TextButton") then child.BackgroundColor3 = Color3.fromRGB(56, 67, 78) end
		end
		button.BackgroundColor3 = Color3.fromRGB(219, 155, 66)
	end)
end

local function refreshCoins()
	coins.Text = "BUILD COINS  " .. tostring(player:GetAttribute("BuildCoins") or 0)
end
player:GetAttributeChangedSignal("BuildCoins"):Connect(refreshCoins)
refreshCoins()

local function destroyPreview()
	if preview then preview:Destroy(); preview = nil end
end

local function createPreview()
	destroyPreview()
	local definition = definitions:FindFirstChild(selected)
	if not definition then return end
	preview = Instance.new("Part")
	preview.Name = "PlacementPreview"
	preview.Size = definition.Value
	preview.Anchored = true
	preview.CanCollide = false
	preview.CanQuery = false
	preview.Material = Enum.Material.ForceField
	preview.Color = Color3.fromRGB(101, 214, 255)
	preview.Transparency = 0.35
	preview.Parent = workspace
end

RunService.RenderStepped:Connect(function()
	if not buildMode or deleteMode then destroyPreview(); return end
	if not preview then createPreview() end
	local hit = mouse.Hit.Position
	local baseSize = definitions[selected].Value
	local size = rotation % 180 == 0 and baseSize or Vector3.new(baseSize.Z, baseSize.Y, baseSize.X)
	preview.Size = size
	preview.CFrame = CFrame.new(math.round(hit.X / 4) * 4, math.round((hit.Y - size.Y / 2) / 4) * 4 + size.Y / 2, math.round(hit.Z / 4) * 4) * CFrame.Angles(0, math.rad(rotation), 0)
end)

UserInputService.InputBegan:Connect(function(input, processed)
	if processed then return end
	if input.KeyCode == Enum.KeyCode.B then
		buildMode = not buildMode
		deleteMode = false
		status.Text = buildMode and "CLICK place  •  R rotate  •  X delete" or "Explore your workshop plot"
		if not buildMode then destroyPreview() end
	elseif input.KeyCode == Enum.KeyCode.R and buildMode then
		rotation = (rotation + 90) % 360
	elseif input.KeyCode == Enum.KeyCode.X and buildMode then
		deleteMode = not deleteMode
		status.Text = deleteMode and "DELETE MODE  •  click your object" or "CLICK place  •  R rotate  •  X delete"
	elseif input.KeyCode.Value >= Enum.KeyCode.One.Value and input.KeyCode.Value <= Enum.KeyCode.Four.Value then
		selected = itemNames[input.KeyCode.Value - Enum.KeyCode.One.Value + 1]
		deleteMode = false
		destroyPreview()
	end
end)

mouse.Button1Down:Connect(function()
	if not buildMode then return end
	if deleteMode then
		deleteRemote:FireServer(mouse.Target)
	elseif preview then
		placeRemote:FireServer(selected, preview.Position, rotation)
	end
end)

noticeRemote.OnClientEvent:Connect(function(message)
	status.Text = tostring(message)
	task.delay(2, function()
		if status.Text == message then status.Text = "CLICK place  •  R rotate  •  X delete" end
	end)
end)
]]></string>
        </Properties>
      </Item>
      <Item class="LocalScript" referent="7">
        <Properties>
          <string name="Name">PortfolioPolish</string>
          <string name="Source"><![CDATA[local Players = game:GetService("Players")
local TweenService = game:GetService("TweenService")
local UserInputService = game:GetService("UserInputService")

local player = Players.LocalPlayer
local projectName = workspace:GetAttribute("PortfolioProject")
if not projectName then
	workspace:GetAttributeChangedSignal("PortfolioProject"):Wait()
	projectName = workspace:GetAttribute("PortfolioProject")
end

local title = workspace:GetAttribute("PortfolioTitle") or "NAKEL GAMEPLAY DEMO"
local accent = workspace:GetAttribute("PortfolioAccent") or Color3.fromRGB(68, 180, 255)
local instructions = {
	AetherDuel = "CLICK COMBO  •  E HEAVY  •  Q DASH  •  HOLD F BLOCK",
	SkylineSprint = "W/S THROTTLE  •  A/D STEER  •  SHIFT DRIFT  •  SPACE BOOST",
	BomblineGrid = "WATCH WARNING TILES  •  MOVE BEFORE THE BLAST",
	SignalSiege = "CLICK GOLD PADS  •  CLICK TOWERS TO SELECT  •  U UPGRADE",
	BuildAndSaveWorld = "B BUILD MODE  •  1–4 ITEM  •  R ROTATE  •  X DELETE",
	RailRushWorld = "E START  •  A/D CHOOSE ROUTE  •  SPACE JUMP",
	FreightyardArena = "CLICK FIRE  •  R RELOAD  •  USE COVER",
	CrystalFoundry = "CLICK OR E TO HARVEST  •  E AT STATIONS TO UPGRADE",
}

local gui = Instance.new("ScreenGui")
gui.Name = "PortfolioPresentation"
gui.IgnoreGuiInset = true
gui.ResetOnSpawn = false
gui.DisplayOrder = 100
gui.Parent = player:WaitForChild("PlayerGui")

local intro = Instance.new("Frame")
intro.Size = UDim2.fromScale(1, 1)
intro.BackgroundColor3 = Color3.fromRGB(7, 11, 18)
intro.Parent = gui

local line = Instance.new("Frame")
line.AnchorPoint = Vector2.new(0.5, 0.5)
line.Position = UDim2.fromScale(0.5, 0.58)
line.Size = UDim2.fromOffset(0, 3)
line.BackgroundColor3 = accent
line.BorderSizePixel = 0
line.Parent = intro

local heading = Instance.new("TextLabel")
heading.AnchorPoint = Vector2.new(0.5, 0.5)
heading.Position = UDim2.fromScale(0.5, 0.45)
heading.Size = UDim2.new(0.9, 0, 0, 80)
heading.BackgroundTransparency = 1
heading.Text = title
heading.TextColor3 = Color3.new(1, 1, 1)
heading.TextTransparency = 1
heading.Font = Enum.Font.GothamBlack
heading.TextScaled = true
heading.Parent = intro
local sizeConstraint = Instance.new("UITextSizeConstraint")
sizeConstraint.MaxTextSize = 46
sizeConstraint.MinTextSize = 24
sizeConstraint.Parent = heading

local subtitle = Instance.new("TextLabel")
subtitle.AnchorPoint = Vector2.new(0.5, 0.5)
subtitle.Position = UDim2.fromScale(0.5, 0.66)
subtitle.Size = UDim2.new(0.9, 0, 0, 40)
subtitle.BackgroundTransparency = 1
subtitle.Text = instructions[projectName] or "PLAYABLE PORTFOLIO PROTOTYPE"
subtitle.TextColor3 = Color3.fromRGB(188, 202, 219)
subtitle.TextTransparency = 1
subtitle.Font = Enum.Font.GothamBold
subtitle.TextSize = 14
subtitle.TextWrapped = true
subtitle.Parent = intro

TweenService:Create(heading, TweenInfo.new(0.35), {TextTransparency = 0}):Play()
TweenService:Create(line, TweenInfo.new(0.45), {Size = UDim2.new(0.5, 0, 0, 3)}):Play()
TweenService:Create(subtitle, TweenInfo.new(0.4), {TextTransparency = 0}):Play()
task.delay(1.8, function()
	TweenService:Create(intro, TweenInfo.new(0.45), {BackgroundTransparency = 1}):Play()
	TweenService:Create(heading, TweenInfo.new(0.3), {TextTransparency = 1}):Play()
	TweenService:Create(subtitle, TweenInfo.new(0.3), {TextTransparency = 1}):Play()
	TweenService:Create(line, TweenInfo.new(0.3), {BackgroundTransparency = 1}):Play()
	task.wait(0.5)
	intro:Destroy()
end)

if UserInputService.TouchEnabled then
	local touchHint = Instance.new("TextLabel")
	touchHint.AnchorPoint = Vector2.new(0.5, 1)
	touchHint.Position = UDim2.new(0.5, 0, 1, -10)
	touchHint.Size = UDim2.new(0.92, 0, 0, 26)
	touchHint.BackgroundColor3 = Color3.fromRGB(10, 16, 25)
	touchHint.BackgroundTransparency = 0.18
	touchHint.Text = "Desktop controls recommended for this portfolio build"
	touchHint.TextColor3 = Color3.fromRGB(213, 221, 232)
	touchHint.Font = Enum.Font.GothamMedium
	touchHint.TextSize = 11
	touchHint.Parent = gui
	Instance.new("UICorner", touchHint).CornerRadius = UDim.new(0, 8)
end
]]></string>
        </Properties>
      </Item>
    </Item>
  </Item>
</roblox>