--[ A PLATFORM CALLED "TickBlox" BY SpectravaxISBACK! IT'S BASICALLY "TikTok" BUT IN Roblox! ] local Players = game:GetService("Players") local TweenService = game:GetService("TweenService") local UserInputService = game:GetService("UserInputService") local ContentProvider = game:GetService("ContentProvider") local player = Players.LocalPlayer local gui = Instance.new("ScreenGui") gui.Name = "TikTokFullGUI" gui.ResetOnSpawn = false gui.IgnoreGuiInset = false -- respect safe areas / topbars on mobile gui.DisplayOrder = 999 -- make sure it's on top gui.Parent = player:WaitForChild("PlayerGui") -- ======================== -- CONFIG (YOUR FINAL LIST) -- ======================== local rawIds = { 5608292559, 5608285055, 5608304953, 5608310319, 5670824523, 5608321996, 5670799859, } local videoIds = {} for _, id in ipairs(rawIds) do table.insert(videoIds, "rbxassetid://" .. tostring(id)) end local transitionTime = 0.3 local swipeThreshold = 80 local autoplayOnLoad = true -- ======================== -- UTILS (viewport-aware sizes) -- ======================== local camera = workspace.CurrentCamera local viewSize = camera and camera.ViewportSize or Vector2.new(1920,1080) -- dynamic tab height (pixel), with a sensible minimum local tabHeight = math.max(56, math.floor(viewSize.Y * 0.085)) -- Convenience to create full-scale frames that respect safe area local function makeFullFrame(parent) local f = Instance.new("Frame") f.Size = UDim2.fromScale(1, 1) -- scale-based sizing f.Position = UDim2.fromScale(0, 0) f.AnchorPoint = Vector2.new(0, 0) f.BackgroundTransparency = 1 f.Parent = parent return f end -- ======================== -- PAGES / NAV -- ======================== local pages = {} local function createPage(name) local f = Instance.new("Frame") f.Name = name f.Size = UDim2.fromScale(1, 1) f.Position = UDim2.fromScale(0, 0) f.BackgroundTransparency = 1 f.Visible = false f.Parent = gui pages[name] = f return f end local feedPage = createPage("Feed") local followingPage = createPage("Following") local searchPage = createPage("Search") feedPage.Visible = true -- bottom tabs (positioned using pixel height for stable placement) local tabs = Instance.new("Frame") tabs.Size = UDim2.new(1, 0, 0, tabHeight) tabs.Position = UDim2.new(0, 0, 1, -tabHeight) -- anchored to bottom tabs.BackgroundColor3 = Color3.fromRGB(20,20,20) tabs.BorderSizePixel = 0 tabs.Parent = gui local tabsLayout = Instance.new("UIListLayout") tabsLayout.Parent = tabs tabsLayout.FillDirection = Enum.FillDirection.Horizontal tabsLayout.HorizontalAlignment = Enum.HorizontalAlignment.Center tabsLayout.VerticalAlignment = Enum.VerticalAlignment.Center tabsLayout.SortOrder = Enum.SortOrder.LayoutOrder tabsLayout.Padding = UDim.new(0,6) local function createTab(text, page) local btn = Instance.new("TextButton") btn.Size = UDim2.new(1/3, -10, 1, -12) btn.Text = text btn.TextScaled = true btn.AutoButtonColor = true btn.BackgroundColor3 = Color3.fromRGB(40,40,40) btn.Parent = tabs btn.MouseButton1Click:Connect(function() for _,p in pairs(pages) do p.Visible = false end page.Visible = true end) return btn end createTab("Feed", feedPage) createTab("Following", followingPage) createTab("Search", searchPage) -- ======================== -- FEED - fullscreen container (subtracting bottom tab height) -- ======================== local container = Instance.new("Frame") container.Size = UDim2.new(1, 0, 1, -tabHeight) -- leave space for bottom tabs container.Position = UDim2.new(0, 0, 0, 0) container.AnchorPoint = Vector2.new(0,0) container.BackgroundColor3 = Color3.fromRGB(0,0,0) container.Parent = feedPage -- Black background that fits everything local bg = Instance.new("Frame") bg.Name = "BlackBackground" bg.Size = UDim2.fromScale(1, 1) bg.Position = UDim2.fromScale(0, 0) bg.AnchorPoint = Vector2.new(0,0) bg.BackgroundColor3 = Color3.new(0, 0, 0) bg.BorderSizePixel = 0 bg.Parent = container -- We'll use two VideoFrames to allow smooth swapping local front = Instance.new("VideoFrame") front.Size = UDim2.fromScale(1, 1) front.Position = UDim2.fromScale(0, 0) front.BackgroundTransparency = 1 front.Visible = false front.Parent = bg front.Volume = 1 front.Looped = true front.AnchorPoint = Vector2.new(0,0) local back = Instance.new("VideoFrame") back.Size = UDim2.fromScale(1, 1) back.Position = UDim2.fromScale(0, 0) back.BackgroundTransparency = 1 back.Visible = false back.Parent = bg back.Volume = 1 back.Looped = true back.AnchorPoint = Vector2.new(0,0) -- fallback image (shown only if video is unsupported) local fallback = Instance.new("ImageLabel") fallback.Size = UDim2.fromScale(1, 1) fallback.Position = UDim2.fromScale(0, 0) fallback.BackgroundTransparency = 1 fallback.Visible = false fallback.Parent = bg fallback.AnchorPoint = Vector2.new(0,0) -- ======================== -- Close button (top-right) - destroys everything -- ======================== local closeBtn = Instance.new("TextButton") closeBtn.Name = "CloseButton" closeBtn.AnchorPoint = Vector2.new(1, 0) -- anchor top-right -- placing it using scale so it adapts; size in pixels for tappable area closeBtn.Position = UDim2.new(1, -12, 0, 12) closeBtn.Size = UDim2.new(0, 48, 0, 48) closeBtn.Text = "X" closeBtn.Font = Enum.Font.GothamBold closeBtn.TextScaled = true closeBtn.BackgroundTransparency = 0.3 closeBtn.TextColor3 = Color3.new(1,1,1) closeBtn.Parent = bg closeBtn.ZIndex = 50 closeBtn.MouseButton1Click:Connect(function() -- completely destroy gui and cut everything cleanly if gui and gui.Parent then gui:Destroy() end end) -- right-side actions (positioned relative to container) local function makeActionBtn(label, y) local btn = Instance.new("TextButton") btn.Size = UDim2.new(0,60,0,60) btn.Position = UDim2.new(1, -80, 0, y) btn.AnchorPoint = Vector2.new(1, 0) btn.Text = label btn.TextScaled = true btn.BackgroundTransparency = 0.15 btn.Parent = bg return btn end local likeBtn = makeActionBtn("❤", 20) local favBtn = makeActionBtn("★", 100) local shareBtn = makeActionBtn("⤴", 180) -- simple visual feedback label (temporary onscreen notice) local function flashText(msg) local lbl = Instance.new("TextLabel") lbl.Size = UDim2.new(0.6,0,0,50) lbl.Position = UDim2.new(0.2,0,0.75,0) lbl.BackgroundTransparency = 0.25 lbl.BackgroundColor3 = Color3.fromRGB(0,0,0) lbl.TextColor3 = Color3.new(1,1,1) lbl.TextScaled = true lbl.Text = msg lbl.Parent = gui lbl.AnchorPoint = Vector2.new(0,0) delay(0.8, function() local t = TweenService:Create(lbl, TweenInfo.new(0.3), {TextTransparency = 1, BackgroundTransparency = 1}) t:Play() delay(0.35, function() if lbl and lbl.Parent then lbl:Destroy() end end) end) end -- ======================== -- STATE -- ======================== local currentIndex = 1 local isTransitioning = false -- helper to check VideoFrame support local function videoSupported() local ok, _ = pcall(function() local v = Instance.new("VideoFrame") v:Destroy() end) return ok end local hasVideoSupport = videoSupported() -- ======================== -- UTIL: set and play -- ======================== local function setVideoToFrame(frame, vid) if hasVideoSupport then frame.Video = vid frame.Visible = true else frame.Visible = false fallback.Visible = true fallback.Image = "rbxassetid://0" end end local function playFrame(frame) if hasVideoSupport then if frame.IsLoaded then frame:Play() else frame.Loaded:Connect(function() frame:Play() end) end end end local function stopFrame(frame) if hasVideoSupport then frame:Pause() end end -- ======================== -- PRELOAD -- ======================== pcall(function() ContentProvider:PreloadAsync(videoIds) end) -- ======================== -- Show initial video -- ======================== local function showInitial() if #videoIds == 0 then local label = Instance.new("TextLabel") label.Size = UDim2.fromScale(1, 1) label.BackgroundTransparency = 1 label.TextScaled = true label.TextColor3 = Color3.new(1,1,1) label.Text = "No videos in feed. Add video asset IDs." label.Parent = bg return end setVideoToFrame(front, videoIds[currentIndex]) front.Position = UDim2.fromScale(0,0) front.Visible = true if autoplayOnLoad then playFrame(front) end end showInitial() -- ======================== -- CROSSFADE / SWITCH -- ======================== local function switchToIndex(nextIndex, dir) if isTransitioning then return end if nextIndex < 1 or nextIndex > #videoIds then isTransitioning = false return end if nextIndex == currentIndex then return end isTransitioning = true setVideoToFrame(back, videoIds[nextIndex]) -- move back into place from above/below using scale offsets back.Position = UDim2.new(0,0, (dir == "up") and 1 or -1, 0) back.Visible = true playFrame(back) local tweenInfo = TweenInfo.new(transitionTime, Enum.EasingStyle.Quad, Enum.EasingDirection.Out) local t1 = TweenService:Create(back, tweenInfo, {Position = UDim2.new(0,0,0,0)}) local t2 = TweenService:Create(front, tweenInfo, {Position = UDim2.new(0,0, (dir == "up") and -1 or 1, 0)}) t1:Play(); t2:Play() delay(transitionTime + 0.02, function() stopFrame(front) front.Video, back.Video = back.Video, front.Video front.Playing, back.Playing = back.Playing, front.Playing front.Position = UDim2.fromScale(0,0) front.Visible = true back.Visible = false isTransitioning = false currentIndex = nextIndex end) end -- ======================== -- INPUT: swipe/tap -- ======================== local dragging = false local startY = 0 local lastY = 0 UserInputService.InputBegan:Connect(function(input, gameProcessed) if gameProcessed then return end if input.UserInputType == Enum.UserInputType.Touch or input.UserInputType == Enum.UserInputType.MouseButton1 then dragging = true startY = input.Position.Y lastY = startY end end) UserInputService.InputChanged:Connect(function(input) if not dragging then return end if input.UserInputType == Enum.UserInputType.Touch or input.UserInputType == Enum.UserInputType.MouseMovement then lastY = input.Position.Y end end) UserInputService.InputEnded:Connect(function(input, gameProcessed) if gameProcessed then return end if not dragging then return end dragging = false local delta = lastY - startY if math.abs(delta) >= swipeThreshold then if delta > 0 then local next = currentIndex + 1 if next <= #videoIds then switchToIndex(next, "up") else flashText("End of feed") end else local prev = currentIndex - 1 if prev >= 1 then switchToIndex(prev, "down") else flashText("Start of feed") end end else if hasVideoSupport then if front.IsLoaded then if front.Playing then front:Pause() flashText("Paused") else front:Play() flashText("Playing") end else front:Play() end else flashText("Video not supported on this platform") end end end) -- ======================== -- BUTTON ACTIONS -- ======================== likeBtn.MouseButton1Click:Connect(function() flashText("Liked") local tw = TweenService:Create(likeBtn, TweenInfo.new(0.12), {Size = UDim2.new(0,70,0,70)}) tw:Play() delay(0.12, function() TweenService:Create(likeBtn, TweenInfo.new(0.12), {Size = UDim2.new(0,60,0,60)}):Play() end) end) favBtn.MouseButton1Click:Connect(function() flashText("Favorited") end) shareBtn.MouseButton1Click:Connect(function() flashText("Shared") end) -- ======================== -- FOLLOWING / SEARCH PAGES -- ======================== local followLabel = Instance.new("TextLabel") followLabel.Size = UDim2.fromScale(1, 1) followLabel.BackgroundTransparency = 1 followLabel.TextColor3 = Color3.new(1,1,1) followLabel.TextScaled = true followLabel.Text = "Following feed - coming soon" followLabel.Parent = followingPage -- Search UI local searchBox = Instance.new("TextBox") searchBox.Size = UDim2.new(0.8,0,0,50) searchBox.Position = UDim2.new(0.1,0,0.06,0) searchBox.PlaceholderText = "Search video IDs (enter numbers)..." searchBox.TextScaled = true searchBox.Parent = searchPage local searchResults = Instance.new("TextLabel") searchResults.Size = UDim2.new(0.8,0,0.7,0) searchResults.Position = UDim2.new(0.1,0,0.2,0) searchResults.BackgroundTransparency = 1 searchResults.TextScaled = true searchResults.TextColor3 = Color3.new(1,1,1) searchResults.Parent = searchPage searchBox.FocusLost:Connect(function(enterPressed) local q = tostring(searchBox.Text) if q:match("%d+") then local found = {} for i,v in ipairs(videoIds) do if tostring(v):find(q) then table.insert(found, v) end end if #found == 0 then searchResults.Text = "No matches" else searchResults.Text = table.concat(found, "\n") end else searchResults.Text = "Type a number substring of the asset id to search" end end) -- ======================== -- HELPER: debug prints -- ======================== print("TikTok GUI loaded. Video support:", hasVideoSupport) print("Videos in feed:", #videoIds) for i,v in ipairs(videoIds) do print(i, v) end -- End of LocalScript