Map Loader
Key Required

Map Loader

99 Nights in the Forest 🔦TrolyScriptsTrolyScripts 744 views 41 executesUpdated Dec 7, 2025
Unrated
00
Lua Script•210 lines (5969 chars)
-- Load Map - Custom Tween Delay GUI version
-- LocalScript → StarterPlayerScripts

local Players = game:GetService("Players")
local TweenService = game:GetService("TweenService")
local RunService = game:GetService("RunService")

local player = Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local hrp = character:WaitForChild("HumanoidRootPart")

-- CONFIG
local Y_OFFSET = 100
local DEFAULT_TWEEN_TIME = 0.1
local MAP_FOLDER = workspace:WaitForChild("Map"):WaitForChild("Ground")
local RETURN_CHECK_DELAY = 1

-- STATE
local running = false
local stopRequested = false
local originalCFrame
local noclipConn
local userTweenDelay = DEFAULT_TWEEN_TIME

-- Toggle noclip
local function setNoclip(enabled)
	if enabled then
		if noclipConn then noclipConn:Disconnect() end
		noclipConn = RunService.Stepped:Connect(function()
			if player.Character then
				for _, v in ipairs(player.Character:GetDescendants()) do
					if v:IsA("BasePart") then v.CanCollide = false end
				end
			end
		end)
	else
		if noclipConn then noclipConn:Disconnect() noclipConn = nil end
		if player.Character then
			for _, v in ipairs(player.Character:GetDescendants()) do
				if v:IsA("BasePart") then v.CanCollide = true end
			end
		end
	end
end

-- Get closest unvisited part
local function getClosestPart(origin, parts, visited)
	local closest, minDist
	for _, p in ipairs(parts) do
		if p:IsA("BasePart") and not visited[p] then
			local dist = (p.Position - origin).Magnitude
			if not minDist or dist < minDist then
				minDist = dist
				closest = p
			end
		end
	end
	return closest
end

-- GUI creation
local function createGui()
	local gui = Instance.new("ScreenGui")
	gui.Name = "LoadMapGui"
	gui.ResetOnSpawn = false
	gui.Parent = player:WaitForChild("PlayerGui")

	local frame = Instance.new("Frame")
	frame.Size = UDim2.new(0, 330, 0, 200)
	frame.Position = UDim2.new(0.5, -165, 0.5, -100)
	frame.BackgroundColor3 = Color3.fromRGB(30, 30, 30)
	frame.Active = true
	frame.Draggable = true
	frame.Parent = gui

	local title = Instance.new("TextLabel")
	title.Size = UDim2.new(1, 0, 0, 34)
	title.BackgroundColor3 = Color3.fromRGB(50, 50, 50)
	title.TextColor3 = Color3.new(1, 1, 1)
	title.Font = Enum.Font.SourceSansBold
	title.TextSize = 20
	title.Text = "Load Map"
	title.Parent = frame

	local start = Instance.new("TextButton")
	start.Size = UDim2.new(0.8, 0, 0, 36)
	start.Position = UDim2.new(0.1, 0, 0.25, 0)
	start.BackgroundColor3 = Color3.fromRGB(0, 170, 0)
	start.TextColor3 = Color3.new(1, 1, 1)
	start.Font = Enum.Font.SourceSansBold
	start.TextSize = 18
	start.Text = "Start"
	start.Parent = frame

	-- NEW: Tween Delay TextBox
	local delayBox = Instance.new("TextBox")
	delayBox.Size = UDim2.new(0.8, 0, 0, 32)
	delayBox.Position = UDim2.new(0.1, 0, 0.45, 0)
	delayBox.BackgroundColor3 = Color3.fromRGB(50, 50, 50)
	delayBox.PlaceholderText = "Tween Delay (Default: 0.1)"
	delayBox.Text = ""
	delayBox.TextColor3 = Color3.new(1, 1, 1)
	delayBox.Font = Enum.Font.SourceSans
	delayBox.TextSize = 16
	delayBox.Parent = frame

	local loading = Instance.new("TextLabel")
	loading.Size = UDim2.new(1, 0, 0, 30)
	loading.Position = UDim2.new(0, 0, 0.63, 0)
	loading.BackgroundTransparency = 1
	loading.TextColor3 = Color3.new(1, 1, 1)
	loading.Font = Enum.Font.SourceSans
	loading.TextSize = 16
	loading.Text = "Loading: 0/0 | ETA: 00:00"
	loading.Parent = frame

	local stop = Instance.new("TextButton")
	stop.Size = UDim2.new(0.8, 0, 0, 34)
	stop.Position = UDim2.new(0.1, 0, 0.8, 0)
	stop.BackgroundColor3 = Color3.fromRGB(200, 0, 0)
	stop.TextColor3 = Color3.new(1, 1, 1)
	stop.Font = Enum.Font.SourceSansBold
	stop.TextSize = 16
	stop.Text = "Stop"
	stop.Visible = false
	stop.Parent = frame

	-- Tween path logic
	local function runTweenPath()
		local grounds = {}
		for _, g in ipairs(MAP_FOLDER:GetChildren()) do
			if g:IsA("BasePart") then table.insert(grounds, g) end
		end
		if #grounds == 0 then return end

		-- Get user delay value
		local val = tonumber(delayBox.Text)
		userTweenDelay = val and math.clamp(val, 0.01, 10) or DEFAULT_TWEEN_TIME

		running = true
		stopRequested = false
		originalCFrame = hrp.CFrame
		setNoclip(true)
		start.Active = false
		stop.Visible = true

		local visited = {}
		local total = #grounds
		local currentIndex = 0
		local startTime = tick()

		while running and not stopRequested and currentIndex < total do
			local closest = getClosestPart(hrp.Position, grounds, visited)
			if not closest then break end

			currentIndex += 1
			visited[closest] = true

			-- ETA update
			local elapsed = tick() - startTime
			local avgPer = elapsed / currentIndex
			local remaining = math.max((total - currentIndex) * avgPer, 0)
			local minutes = math.floor(remaining / 60)
			local seconds = math.floor(remaining % 60)
			local etaText = string.format("%02d:%02d", minutes, seconds)
			loading.Text = string.format("Loading: %d/%d | ETA: %s", currentIndex, total, etaText)

			-- Tween +Y_OFFSET above
			local targetPos = closest.Position + Vector3.new(0, Y_OFFSET, 0)
			local tween = TweenService:Create(hrp, TweenInfo.new(userTweenDelay, Enum.EasingStyle.Linear), {CFrame = CFrame.new(targetPos)})
			tween:Play()
			tween.Completed:Wait()
			task.wait(0.02)
		end

		-- Return to original
		setNoclip(false)
		stop.Visible = false
		start.Active = true
		running = false

		local function returnToOriginal()
			if hrp then hrp.CFrame = originalCFrame end
		end
		returnToOriginal()

		task.delay(RETURN_CHECK_DELAY, function()
			if (hrp.Position - originalCFrame.Position).Magnitude > 2 then
				returnToOriginal()
			end
		end)
	end

	start.MouseButton1Click:Connect(function()
		if running then return end
		runTweenPath()
	end)

	stop.MouseButton1Click:Connect(function()
		if not running then return end
		stopRequested = true
		running = false
		setNoclip(false)
		stop.Visible = false
		start.Active = true
		if hrp then hrp.CFrame = originalCFrame end
	end)
end

createGui()

Features & Information

Made By TrolyScripts (@Pur6leTheTroly) Please Follow On Roblox And Subscribe on Youtube! (Not Begging)

Community Comments (1)

TrolyScriptsTrolyScriptsDec 8, 2025

Join Our discord : https://discord.gg/7RpZ7wpm8

More Scripts for 99 Nights in the Forest 🔦