Download index.html from DiamondVi/cookie-1: direct link, hf CLI and curl.
- Browser
- Download file 68.5 kB
-
https://huggingface.co/spaces/DiamondVi/cookie-1/resolve/main/index.html
- Command line
-
hf download hf://spaces/DiamondVi/cookie-1/index.html
-
curl -L -o index.html https://huggingface.co/spaces/DiamondVi/cookie-1/resolve/main/index.html
68.5 kB
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Ultimate Roblox Cookie Clicker Guide</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
| <style> | |
| /* Custom styles remain the same */ | |
| .gradient-bg { background: linear-gradient(135deg, #f6d365 0%, #fda085 100%); } | |
| .cookie-btn { transition: all 0.2s ease; transform-style: preserve-3d; } | |
| .cookie-btn:hover { transform: scale(1.05) rotate(5deg); box-shadow: 0 10px 20px rgba(0,0,0,0.2); } | |
| .cookie-btn:active { transform: scale(0.95); } | |
| .progress-bar { transition: width 0.5s ease; } | |
| .skin-card { transition: all 0.3s ease; } | |
| .skin-card:hover { transform: translateY(-5px); box-shadow: 0 10px 25px rgba(0,0,0,0.1); } | |
| .monster-hunger { animation: pulse 2s infinite; } | |
| @keyframes pulse { | |
| 0% { transform: scale(1); } | |
| 50% { transform: scale(1.05); } | |
| 100% { transform: scale(1); } | |
| } | |
| .tooltip { | |
| position: relative; | |
| } | |
| .tooltip-text { | |
| visibility: hidden; | |
| width: 200px; | |
| background-color: #555; | |
| color: #fff; | |
| text-align: center; | |
| border-radius: 6px; | |
| padding: 5px; | |
| position: absolute; | |
| z-index: 1; | |
| bottom: 125%; | |
| left: 50%; | |
| margin-left: -100px; | |
| opacity: 0; | |
| transition: opacity 0.3s; | |
| } | |
| .tooltip:hover .tooltip-text { | |
| visibility: visible; | |
| opacity: 1; | |
| } | |
| .code-tab { | |
| display: none; | |
| } | |
| .code-tab.active { | |
| display: block; | |
| } | |
| </style> | |
| </head> | |
| <body class="gradient-bg min-h-screen font-sans"> | |
| <div class="container mx-auto px-4 py-8"> | |
| <!-- Header --> | |
| <header class="text-center mb-12"> | |
| <h1 class="text-5xl font-bold text-white mb-4">Ultimate Roblox Cookie Clicker Guide</h1> | |
| <p class="text-xl text-white opacity-90">Create a feature-packed cookie clicking game with achievements, skins, global leaderboards, and Cookie Monster!</p> | |
| </header> | |
| <!-- Navigation --> | |
| <nav class="bg-white rounded-lg shadow-lg p-4 mb-8"> | |
| <ul class="flex flex-wrap justify-center gap-4"> | |
| <li><a href="#basic-setup" class="px-4 py-2 bg-amber-500 text-white rounded-lg hover:bg-amber-600 transition">Basic Setup</a></li> | |
| <li><a href="#cookie-design" class="px-4 py-2 bg-amber-500 text-white rounded-lg hover:bg-amber-600 transition">Cookie Design</a></li> | |
| <li><a href="#achievements" class="px-4 py-2 bg-amber-500 text-white rounded-lg hover:bg-amber-600 transition">Achievements</a></li> | |
| <li><a href="#skins" class="px-4 py-2 bg-amber-500 text-white rounded-lg hover:bg-amber-600 transition">Skins</a></li> | |
| <li><a href="#leaderboard" class="px-4 py-2 bg-amber-500 text-white rounded-lg hover:bg-amber-600 transition">Leaderboard</a></li> | |
| <li><a href="#cookie-monster" class="px-4 py-2 bg-amber-500 text-white rounded-lg hover:bg-amber-600 transition">Cookie Monster</a></li> | |
| </ul> | |
| </nav> | |
| <!-- Main Content --> | |
| <main class="bg-white rounded-lg shadow-xl p-8"> | |
| <!-- Basic Setup Section - Enhanced --> | |
| <section id="basic-setup" class="mb-12"> | |
| <h2 class="text-3xl font-bold text-amber-800 mb-6 border-b-2 border-amber-200 pb-2">1. Basic Game Setup</h2> | |
| <div class="grid md:grid-cols-2 gap-8"> | |
| <!-- Part 1 - Enhanced --> | |
| <div class="bg-amber-50 p-6 rounded-lg border-l-4 border-amber-400"> | |
| <h3 class="text-xl font-semibold text-amber-700 mb-4">Creating the Base Game</h3> | |
| <div class="mb-6"> | |
| <h4 class="font-medium text-gray-800 mb-2">Detailed Steps:</h4> | |
| <ol class="list-decimal pl-5 space-y-3 text-gray-700"> | |
| <li> | |
| <strong>Create a new Roblox place:</strong> | |
| <ul class="list-disc pl-5 mt-1 text-sm"> | |
| <li>Open Roblox Studio</li> | |
| <li>Select "Baseplate" as your starting template</li> | |
| <li>Save your place with a descriptive name</li> | |
| </ul> | |
| </li> | |
| <li> | |
| <strong>Set up the GUI structure:</strong> | |
| <ul class="list-disc pl-5 mt-1 text-sm"> | |
| <li>In Explorer, go to StarterGui</li> | |
| <li>Insert a ScreenGui (rename to "MainGUI")</li> | |
| <li>Add a Frame inside (set Size to 1,1 scale)</li> | |
| <li>Configure background transparency (0.5-0.8)</li> | |
| </ul> | |
| </li> | |
| <li> | |
| <strong>Cookie display setup:</strong> | |
| <ul class="list-disc pl-5 mt-1 text-sm"> | |
| <li>Add TextLabel for cookie count</li> | |
| <li>Set font to "Gotham Black" (size 24-36)</li> | |
| <li>Position at top-center of screen</li> | |
| <li>Add shadow effect with TextStroke</li> | |
| </ul> | |
| </li> | |
| <li> | |
| <strong>Cookie button creation:</strong> | |
| <ul class="list-disc pl-5 mt-1 text-sm"> | |
| <li>Insert ImageButton (200x200 pixels)</li> | |
| <li>Upload cookie image (PNG with transparency)</li> | |
| <li>Add hover/click effects (scale, rotation)</li> | |
| <li>Center on screen with AutoButtonColor=false</li> | |
| </ul> | |
| </li> | |
| </ol> | |
| </div> | |
| <div class="p-4 bg-gray-100 rounded"> | |
| <div class="flex border-b border-gray-300 mb-3"> | |
| <button class="code-tab-btn px-4 py-2 font-medium text-amber-700 border-b-2 border-amber-500" data-tab="basic-local">LocalScript</button> | |
| <button class="code-tab-btn px-4 py-2 font-medium text-gray-600" data-tab="basic-server">ServerScript</button> | |
| </div> | |
| <div id="basic-local" class="code-tab active"> | |
| <h4 class="font-medium text-gray-800 mb-2">LocalScript for Click Handling:</h4> | |
| <pre class="bg-gray-800 text-green-300 p-3 rounded text-sm overflow-x-auto"> | |
| local Players = game:GetService("Players") | |
| local player = Players.LocalPlayer | |
| local cookieButton = script.Parent.CookieButton | |
| local cookieCount = script.Parent.CookieCount | |
| -- Initialize cookie value (will be synced with server) | |
| local cookies = 0 | |
| -- Create a remote event for server communication | |
| local remoteEvent = Instance.new("RemoteEvent") | |
| remoteEvent.Name = "CookieClickEvent" | |
| remoteEvent.Parent = game.ReplicatedStorage | |
| -- Click handler with visual feedback | |
| cookieButton.MouseButton1Click:Connect(function() | |
| -- Visual feedback | |
| cookieButton:TweenSize(UDim2.new(0.9, 0, 0.9, 0), "Out", "Quad", 0.1) | |
| task.wait(0.1) | |
| cookieButton:TweenSize(UDim2.new(1, 0, 1, 0), "Out", "Elastic", 0.5) | |
| -- Play sound if available | |
| if cookieButton:FindFirstChild("ClickSound") then | |
| cookieButton.ClickSound:Play() | |
| end | |
| -- Fire to server | |
| remoteEvent:FireServer() | |
| end) | |
| -- Update display when cookies change | |
| local function updateDisplay(newCount) | |
| cookies = newCount | |
| cookieCount.Text = "Cookies: " .. formatNumber(cookies) | |
| end | |
| -- Helper function to format large numbers | |
| local function formatNumber(num) | |
| if num >= 1000000 then | |
| return string.format("%.1fM", num/1000000) | |
| elseif num >= 1000 then | |
| return string.format("%.1fK", num/1000) | |
| end | |
| return tostring(num) | |
| end | |
| -- Listen for server updates | |
| game.ReplicatedStorage:WaitForChild("CookieUpdate").OnClientEvent:Connect(updateDisplay)</pre> | |
| </div> | |
| <div id="basic-server" class="code-tab"> | |
| <h4 class="font-medium text-gray-800 mb-2">Server-Side Cookie Management:</h4> | |
| <pre class="bg-gray-800 text-green-300 p-3 rounded text-sm overflow-x-auto"> | |
| local Players = game:GetService("Players") | |
| local ServerStorage = game:GetService("ServerStorage") | |
| local ReplicatedStorage = game:GetService("ReplicatedStorage") | |
| -- Create remote events | |
| local clickEvent = Instance.new("RemoteEvent") | |
| clickEvent.Name = "CookieClickEvent" | |
| clickEvent.Parent = ReplicatedStorage | |
| local updateEvent = Instance.new("RemoteEvent") | |
| updateEvent.Name = "CookieUpdate" | |
| updateEvent.Parent = ReplicatedStorage | |
| -- Player data management | |
| local playerData = {} | |
| local function onPlayerAdded(player) | |
| -- Initialize player data | |
| playerData[player] = { | |
| cookies = 0, | |
| clickMultiplier = 1, | |
| autoClickers = {} | |
| } | |
| -- Create leaderstats | |
| local leaderstats = Instance.new("Folder") | |
| leaderstats.Name = "leaderstats" | |
| leaderstats.Parent = player | |
| local cookiesStat = Instance.new("IntValue") | |
| cookiesStat.Name = "Cookies" | |
| cookiesStat.Value = 0 | |
| cookiesStat.Parent = leaderstats | |
| -- Send initial data to client | |
| updateEvent:FireClient(player, 0) | |
| end | |
| -- Handle cookie clicks | |
| clickEvent.OnServerEvent:Connect(function(player) | |
| local data = playerData[player] | |
| if not data then return end | |
| -- Calculate cookies to add (with multiplier) | |
| local cookiesToAdd = 1 * data.clickMultiplier | |
| -- Update player data | |
| data.cookies = data.cookies + cookiesToAdd | |
| player.leaderstats.Cookies.Value = data.cookies | |
| -- Update client | |
| updateEvent:FireClient(player, data.cookies) | |
| end) | |
| -- Clean up when player leaves | |
| local function onPlayerRemoving(player) | |
| playerData[player] = nil | |
| end | |
| -- Connect events | |
| Players.PlayerAdded:Connect(onPlayerAdded) | |
| Players.PlayerRemoving:Connect(onPlayerRemoving)</pre> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Part 2 - Enhanced --> | |
| <div class="bg-amber-50 p-6 rounded-lg border-l-4 border-amber-400"> | |
| <h3 class="text-xl font-semibold text-amber-700 mb-4">Auto-Clicker Upgrades</h3> | |
| <div class="mb-6"> | |
| <h4 class="font-medium text-gray-800 mb-2">Upgrade System Design:</h4> | |
| <ul class="list-disc pl-5 space-y-2 text-gray-700"> | |
| <li><strong>Upgrade Types:</strong> | |
| <ul class="list-disc pl-5 mt-1 text-sm"> | |
| <li>Click Multipliers (2x, 5x, 10x)</li> | |
| <li>Auto-Clickers (Grandma, Oven, Factory)</li> | |
| <li>Temporary Boosts (30min 2x cookies)</li> | |
| </ul> | |
| </li> | |
| <li><strong>Cost Scaling:</strong> | |
| <ul class="list-disc pl-5 mt-1 text-sm"> | |
| <li>Base cost * (1.15^owned)</li> | |
| <li>Example: First grandma costs 10, next 11.5, then 13.2, etc.</li> | |
| </ul> | |
| </li> | |
| <li><strong>Visual Feedback:</strong> | |
| <ul class="list-disc pl-5 mt-1 text-sm"> | |
| <li>Highlight affordable upgrades</li> | |
| <li>Show purchase confirmation</li> | |
| <li>Visual effect on purchase</li> | |
| </ul> | |
| </li> | |
| </ul> | |
| </div> | |
| <div class="p-4 bg-gray-100 rounded"> | |
| <div class="flex border-b border-gray-300 mb-3"> | |
| <button class="code-tab-btn px-4 py-2 font-medium text-amber-700 border-b-2 border-amber-500" data-tab="upgrade-client">Client UI</button> | |
| <button class="code-tab-btn px-4 py-2 font-medium text-gray-600" data-tab="upgrade-server">Server Logic</button> | |
| </div> | |
| <div id="upgrade-client" class="code-tab active"> | |
| <h4 class="font-medium text-gray-800 mb-2">Upgrade Shop UI:</h4> | |
| <pre class="bg-gray-800 text-green-300 p-3 rounded text-sm overflow-x-auto"> | |
| -- In a LocalScript connected to your upgrade buttons | |
| local ReplicatedStorage = game:GetService("ReplicatedStorage") | |
| local upgradeEvent = ReplicatedStorage:WaitForChild("UpgradeEvent") | |
| local updateEvent = ReplicatedStorage:WaitForChild("CookieUpdate") | |
| local upgrades = { | |
| { | |
| name = "Grandma", | |
| desc = "Bakes 0.2 cookies per second", | |
| baseCost = 10, | |
| owned = 0, | |
| rate = 0.2, | |
| button = script.Parent.GrandmaButton | |
| }, | |
| -- Add more upgrades | |
| } | |
| -- Initialize UI | |
| local function updateUpgradeUI() | |
| for _, upgrade in pairs(upgrades) do | |
| local cost = math.floor(upgrade.baseCost * (1.15 ^ upgrade.owned)) | |
| upgrade.button.Text = string.format("%s\nCost: %d\nOwned: %d", | |
| upgrade.name, cost, upgrade.owned) | |
| -- Grey out if unaffordable | |
| if playerCookies < cost then | |
| upgrade.button.BackgroundColor3 = Color3.fromRGB(200, 200, 200) | |
| else | |
| upgrade.button.BackgroundColor3 = Color3.fromRGB(100, 200, 100) | |
| end | |
| end | |
| end | |
| -- Handle purchases | |
| for _, upgrade in pairs(upgrades) do | |
| upgrade.button.MouseButton1Click:Connect(function() | |
| local cost = math.floor(upgrade.baseCost * (1.15 ^ upgrade.owned)) | |
| if playerCookies >= cost then | |
| upgradeEvent:FireServer(upgrade.name) | |
| else | |
| -- Play error sound | |
| end | |
| end | |
| end | |
| -- Update when cookies change | |
| updateEvent.OnClientEvent:Connect(function(cookies) | |
| playerCookies = cookies | |
| updateUpgradeUI() | |
| end)</pre> | |
| </div> | |
| <div id="upgrade-server" class="code-tab"> | |
| <h4 class="font-medium text-gray-800 mb-2">Server Upgrade Handling:</h4> | |
| <pre class="bg-gray-800 text-green-300 p-3 rounded text-sm overflow-x-auto"> | |
| local ReplicatedStorage = game:GetService("ReplicatedStorage") | |
| local upgradeEvent = Instance.new("RemoteEvent") | |
| upgradeEvent.Name = "UpgradeEvent" | |
| upgradeEvent.Parent = ReplicatedStorage | |
| -- Define server-side upgrade data | |
| local upgradeData = { | |
| ["Grandma"] = { | |
| baseCost = 10, | |
| rate = 0.2, | |
| type = "auto" | |
| }, | |
| ["2x Multiplier"] = { | |
| baseCost = 100, | |
| multiplier = 2, | |
| type = "click" | |
| } | |
| } | |
| -- Handle upgrade purchases | |
| upgradeEvent.OnServerEvent:Connect(function(player, upgradeName) | |
| local data = playerData[player] | |
| if not data or not upgradeData[upgradeName] then return end | |
| local upgrade = upgradeData[upgradeName] | |
| local owned = data.upgrades[upgradeName] or 0 | |
| local cost = math.floor(upgrade.baseCost * (1.15 ^ owned)) | |
| if data.cookies >= cost then | |
| -- Deduct cookies | |
| data.cookies = data.cookies - cost | |
| player.leaderstats.Cookies.Value = data.cookies | |
| -- Apply upgrade | |
| if upgrade.type == "auto" then | |
| table.insert(data.autoClickers, { | |
| name = upgradeName, | |
| rate = upgrade.rate, | |
| nextTick = time() + 1 | |
| }) | |
| elseif upgrade.type == "click" then | |
| data.clickMultiplier = data.clickMultiplier * upgrade.multiplier | |
| end | |
| -- Update client | |
| ReplicatedStorage.CookieUpdate:FireClient(player, data.cookies) | |
| end | |
| end) | |
| -- Auto-clicker processing | |
| local function processAutoClickers() | |
| while true do | |
| local currentTime = time() | |
| for player, data in pairs(playerData) do | |
| for _, clicker in pairs(data.autoClickers) do | |
| if currentTime >= clicker.nextTick then | |
| data.cookies = data.cookies + clicker.rate | |
| player.leaderstats.Cookies.Value = data.cookies | |
| clicker.nextTick = currentTime + 1 | |
| end | |
| end | |
| end | |
| wait(0.1) | |
| end | |
| end | |
| -- Start the auto-clicker loop | |
| spawn(processAutoClickers)</pre> | |
| </div> | |
| </div> | |
| <div class="mt-4 p-3 bg-amber-100 rounded border-l-4 border-amber-500"> | |
| <h4 class="font-medium text-amber-800 mb-2">Pro Tip:</h4> | |
| <p class="text-sm text-amber-700">Use a ModuleScript to store all upgrade data for easy maintenance. This allows you to balance game economics without touching the core logic.</p> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- Cookie Design Section - Enhanced --> | |
| <section id="cookie-design" class="mb-12"> | |
| <h2 class="text-3xl font-bold text-amber-800 mb-6 border-b-2 border-amber-200 pb-2">2. Creating an Appealing Cookie</h2> | |
| <div class="grid md:grid-cols-2 gap-8"> | |
| <!-- Visual Design - Enhanced --> | |
| <div class="bg-amber-50 p-6 rounded-lg"> | |
| <h3 class="text-xl font-semibold text-amber-700 mb-4">Advanced Visual Design</h3> | |
| <div class="mb-6 grid grid-cols-2 gap-4"> | |
| <div class="bg-white p-4 rounded-lg shadow"> | |
| <h4 class="font-medium text-gray-800 mb-2">Particle Effects</h4> | |
| <ul class="list-disc pl-5 text-sm space-y-1"> | |
| <li>Cookie crumbs on click</li> | |
| <li>Golden sparkles for critical clicks</li> | |
| <li>Steam effect for hot cookies</li> | |
| <li>Trail effect when dragging</li> | |
| </ul> | |
| </div> | |
| <div class="bg-white p-4 rounded-lg shadow"> | |
| <h4 class="font-medium text-gray-800 mb-2">Sound Design</h4> | |
| <ul class="list-disc pl-5 text-sm space-y-1"> | |
| <li>Crunch sound on click</li> | |
| <li>Cha-ching for purchases</li> | |
| <li>Positive ding for achievements</li> | |
| <li>Background bakery music</li> | |
| </ul> | |
| </div> | |
| <div class="bg-white p-4 rounded-lg shadow"> | |
| <h4 class="font-medium text-gray-800 mb-2">Animation Types</h4> | |
| <ul class="list-disc pl-5 text-sm space-y-1"> | |
| <li>Squish on click</li> | |
| <li>Rotation when idle</li> | |
| <li>Bounce when cookies added</li> | |
| <li>Celebration for milestones</li> | |
| </ul> | |
| </div> | |
| <div class="bg-white p-4 rounded-lg shadow"> | |
| <h4 class="font-medium text-gray-800 mb-2">Visual Feedback</h4> | |
| <ul class="list-disc pl-5 text-sm space-y-1"> | |
| <li>Floating +1 cookies</li> | |
| <li>Screen shake on big clicks</li> | |
| <li>Color pulses for bonuses</li> | |
| <li>Glow effects for active boosts</li> | |
| </ul> | |
| </div> | |
| </div> | |
| <div class="flex justify-center space-x-6"> | |
| <div class="text-center"> | |
| <div class="w-24 h-24 rounded-full bg-amber-200 border-4 border-amber-400 mx-auto mb-2 flex items-center justify-center"> | |
| <i class="fas fa-cookie-bite text-amber-700 text-3xl"></i> | |
| </div> | |
| <p class="text-sm font-medium">Default Cookie</p> | |
| </div> | |
| <div class="text-center"> | |
| <div class="w-24 h-24 rounded-full bg-blue-200 border-4 border-blue-400 mx-auto mb-2 flex items-center justify-center relative"> | |
| <i class="fas fa-cookie-bite text-blue-700 text-3xl"></i> | |
| <div class="absolute -inset-1 rounded-full border-2 border-white animate-ping opacity-75"></div> | |
| </div> | |
| <p class="text-sm font-medium">Animated Cookie</p> | |
| </div> | |
| <div class="text-center"> | |
| <div class="w-24 h-24 rounded-full bg-purple-200 border-4 border-purple-400 mx-auto mb-2 flex items-center justify-center"> | |
| <i class="fas fa-cookie-bite text-purple-700 text-3xl"></i> | |
| <div class="absolute inset-0 rounded-full bg-white opacity-20 animate-pulse"></div> | |
| </div> | |
| <p class="text-sm font-medium">Glowing Cookie</p> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Animation Code - Enhanced --> | |
| <div class="bg-amber-50 p-6 rounded-lg"> | |
| <h3 class="text-xl font-semibold text-amber-700 mb-4">Advanced Effects Implementation</h3> | |
| <div class="mb-6"> | |
| <h4 class="font-medium text-gray-800 mb-2">Particle System Setup:</h4> | |
| <pre class="bg-gray-800 text-green-300 p-3 rounded text-sm overflow-x-auto"> | |
| -- Create particle emitter for cookie | |
| local particleEmitter = Instance.new("ParticleEmitter") | |
| particleEmitter.Name = "CookieParticles" | |
| particleEmitter.Parent = cookieButton | |
| -- Configure particles | |
| particleEmitter.Texture = "rbxassetid://242842629" -- Crumb texture | |
| particleEmitter.LightEmission = 0.5 | |
| particleEmitter.Size = NumberSequence.new({ | |
| NumberSequenceKeypoint.new(0, 0.5), | |
| NumberSequenceKeypoint.new(1, 0) | |
| }) | |
| particleEmitter.Transparency = NumberSequence.new({ | |
| NumberSequenceKeypoint.new(0, 0), | |
| NumberSequenceKeypoint.new(1, 1) | |
| }) | |
| particleEmitter.Lifetime = NumberRange.new(0.5, 1) | |
| particleEmitter.Rate = 0 -- We'll emit manually | |
| particleEmitter.Speed = NumberRange.new(20, 50) | |
| particleEmitter.SpreadAngle = Vector2.new(45, 45) | |
| particleEmitter.Rotation = NumberRange.new(0, 360) | |
| -- Emit particles on click | |
| cookieButton.MouseButton1Click:Connect(function() | |
| particleEmitter:Emit(10) -- Emit 10 particles | |
| -- Also emit golden particles for critical clicks | |
| if math.random() < 0.1 then -- 10% chance | |
| local goldenEmitter = cookieButton:FindFirstChild("GoldenParticles") | |
| if goldenEmitter then | |
| goldenEmitter:Emit(20) | |
| end | |
| end | |
| end)</pre> | |
| </div> | |
| <div> | |
| <h4 class="font-medium text-gray-800 mb-2">Advanced Click Animation:</h4> | |
| <pre class="bg-gray-800 text-green-300 p-3 rounded text-sm overflow-x-auto"> | |
| local UserInputService = game:GetService("UserInputService") | |
| local TweenService = game:GetService("TweenService") | |
| -- Click animation with squash effect | |
| cookieButton.MouseButton1Down:Connect(function() | |
| -- Squash vertically, stretch horizontally | |
| local squashTween = TweenService:Create( | |
| cookieButton, | |
| TweenInfo.new(0.1, Enum.EasingStyle.Quad, Enum.EasingDirection.Out), | |
| {Size = UDim2.new(1.1, 0, 0.9, 0)} | |
| ) | |
| squashTween:Play() | |
| end) | |
| -- Release animation with bounce | |
| cookieButton.MouseButton1Up:Connect(function() | |
| -- First return to normal size quickly | |
| local returnTween = TweenService:Create( | |
| cookieButton, | |
| TweenInfo.new(0.1, Enum.EasingStyle.Quad, Enum.EasingDirection.Out), | |
| {Size = UDim2.new(1, 0, 1, 0)} | |
| ) | |
| returnTween:Play() | |
| -- Then add a little bounce | |
| task.wait(0.1) | |
| local bounceTween = TweenService:Create( | |
| cookieButton, | |
| TweenInfo.new(0.3, Enum.EasingStyle.Elastic, Enum.EasingDirection.Out, 0, false, 0), | |
| {Size = UDim2.new(1.05, 0, 1.05, 0)} | |
| ) | |
| bounceTween:Play() | |
| end) | |
| -- Drag effect (cookie follows mouse slightly) | |
| local dragConnection | |
| cookieButton.MouseEnter:Connect(function() | |
| dragConnection = UserInputService.InputChanged:Connect(function(input) | |
| if input.UserInputType == Enum.UserInputType.MouseMovement then | |
| local mousePos = game:GetService("Players").LocalPlayer:GetMouse() | |
| local buttonPos = cookieButton.AbsolutePosition | |
| local center = buttonPos + cookieButton.AbsoluteSize/2 | |
| -- Calculate offset from center | |
| local offset = (mousePos - center) / 10 -- Divide to reduce movement | |
| -- Apply offset with tween for smooth movement | |
| TweenService:Create( | |
| cookieButton, | |
| TweenInfo.new(0.2, Enum.EasingStyle.Quad, Enum.EasingDirection.Out), | |
| {Position = UDim2.new(0.5, offset.X, 0.5, offset.Y)} | |
| ):Play() | |
| end | |
| end) | |
| end) | |
| cookieButton.MouseLeave:Connect(function() | |
| if dragConnection then | |
| dragConnection:Disconnect() | |
| -- Return to center | |
| TweenService:Create( | |
| cookieButton, | |
| TweenInfo.new(0.5, Enum.EasingStyle.Elastic, Enum.EasingDirection.Out), | |
| {Position = UDim2.new(0.5, 0, 0.5, 0)} | |
| ):Play() | |
| end | |
| end)</pre> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- Achievements Section - Enhanced --> | |
| <section id="achievements" class="mb-12"> | |
| <h2 class="text-3xl font-bold text-amber-800 mb-6 border-b-2 border-amber-200 pb-2">3. Advanced Achievements System</h2> | |
| <div class="grid md:grid-cols-2 gap-8"> | |
| <!-- Achievement Design - Enhanced --> | |
| <div class="bg-amber-50 p-6 rounded-lg"> | |
| <h3 class="text-xl font-semibold text-amber-700 mb-4">Achievement Types & Progression</h3> | |
| <div class="mb-6"> | |
| <h4 class="font-medium text-gray-800 mb-2">Achievement Categories:</h4> | |
| <div class="grid grid-cols-2 gap-4"> | |
| <div class="bg-white p-3 rounded shadow"> | |
| <h5 class="font-semibold text-amber-600">Milestones</h5> | |
| <ul class="text-sm mt-1 space-y-1"> | |
| <li>Bake 100 cookies</li> | |
| <li>Bake 1,000 cookies</li> | |
| <li>Bake 1,000,000 cookies</li> | |
| </ul> | |
| </div> | |
| <div class="bg-white p-3 rounded shadow"> | |
| <h5 class="font-semibold text-amber-600">Upgrades</h5> | |
| <ul class="text-sm mt-1 space-y-1"> | |
| <li>Purchase first upgrade</li> | |
| <li>Own 10 grandmas</li> | |
| <li>Max out all upgrades</li> | |
| </ul> | |
| </div> | |
| <div class="bg-white p-3 rounded shadow"> | |
| <h5 class="font-semibold text-amber-600">Special</h5> | |
| <ul class="text-sm mt-1 space-y-1"> | |
| <li>Critical click (1% chance)</li> | |
| <li>Feed Cookie Monster 10 times</li> | |
| <li>Play for 24 hours total</li> | |
| </ul> | |
| </div> | |
| <div class="bg-white p-3 rounded shadow"> | |
| <h5 class="font-semibold text-amber-600">Secret</h5> | |
| <ul class="text-sm mt-1 space-y-1"> | |
| <li>Click 100 times in 10 seconds</li> | |
| <li>Find hidden cookie</li> | |
| <li>Bake negative cookies</li> | |
| </ul> | |
| </div> | |
| </div> | |
| </div> | |
| <div> | |
| <h4 class="font-medium text-gray-800 mb-2">Reward Structure:</h4> | |
| <div class="bg-white p-4 rounded-lg shadow"> | |
| <div class="flex items-center mb-3"> | |
| <div class="w-10 h-10 rounded-full bg-yellow-100 flex items-center justify-center mr-3"> | |
| <i class="fas fa-coins text-yellow-600"></i> | |
| </div> | |
| <div> | |
| <h5 class="font-semibold">Cookie Rewards</h5> | |
| <p class="text-xs text-gray-600">Instant cookie bonuses</p> | |
| </div> | |
| </div> | |
| <div class="flex items-center mb-3"> | |
| <div class="w-10 h-10 rounded-full bg-blue-100 flex items-center justify-center mr-3"> | |
| <i class="fas fa-tachometer-alt text-blue-600"></i> | |
| </div> | |
| <div> | |
| <h5 class="font-semibold">Permanent Multipliers</h5> | |
| <p class="text-xs text-gray-600">Increase cookie production</p> | |
| </div> | |
| </div> | |
| <div class="flex items-center"> | |
| <div class="w-10 h-10 rounded-full bg-purple-100 flex items-center justify-center mr-3"> | |
| <i class="fas fa-palette text-purple-600"></i> | |
| </div> | |
| <div> | |
| <h5 class="font-semibold">Exclusive Skins</h5> | |
| <p class="text-xs text-gray-600">Unique visual customization</p> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Achievement Code - Enhanced --> | |
| <div class="bg-amber-50 p-6 rounded-lg"> | |
| <h3 class="text-xl font-semibold text-amber-700 mb-4">Achievement System Implementation</h3> | |
| <div class="mb-6"> | |
| <h4 class="font-medium text-gray-800 mb-2">Achievement Data Structure:</h4> | |
| <pre class="bg-gray-800 text-green-300 p-3 rounded text-sm overflow-x-auto"> | |
| -- In a ModuleScript called "AchievementData" | |
| local AchievementData = {} | |
| AchievementData.list = { | |
| { | |
| id = "first_cookie", | |
| name = "First Cookie", | |
| desc = "Bake your first cookie", | |
| goal = 1, | |
| reward = {type = "cookies", amount = 10}, | |
| icon = "rbxassetid://123456", | |
| category = "milestone", | |
| hidden = false | |
| }, | |
| { | |
| id = "cookie_tycoon", | |
| name = "Cookie Tycoon", | |
| desc = "Bake 1,000,000 cookies", | |
| goal = 1000000, | |
| reward = {type = "skin", id = "golden_cookie"}, | |
| icon = "rbxassetid://654321", | |
| category = "milestone", | |
| hidden = false | |
| }, | |
| { | |
| id = "critical_click", | |
| name = "Critical Click!", | |
| desc = "Get a critical click (1% chance)", | |
| goal = 1, | |
| reward = {type = "multiplier", amount = 0.1}, | |
| icon = "rbxassetid://789012", | |
| category = "special", | |
| hidden = true | |
| } | |
| -- Add more achievements | |
| } | |
| return AchievementData</pre> | |
| </div> | |
| <div> | |
| <h4 class="font-medium text-gray-800 mb-2">Achievement Tracking System:</h4> | |
| <pre class="bg-gray-800 text-green-300 p-3 rounded text-sm overflow-x-auto"> | |
| -- Server-side achievement tracking | |
| local AchievementData = require(script.Parent.AchievementData) | |
| local ReplicatedStorage = game:GetService("ReplicatedStorage") | |
| local Players = game:GetService("Players") | |
| local achievementEvent = Instance.new("RemoteEvent") | |
| achievementEvent.Name = "AchievementEvent" | |
| achievementEvent.Parent = ReplicatedStorage | |
| local playerAchievements = {} | |
| local function onPlayerAdded(player) | |
| -- Initialize player's achievement progress | |
| playerAchievements[player] = {} | |
| for _, achievement in pairs(AchievementData.list) do | |
| playerAchievements[player][achievement.id] = { | |
| progress = 0, | |
| unlocked = false | |
| } | |
| end | |
| -- Set up stat tracking | |
| player:SetAttribute("TotalClicks", 0) | |
| player:SetAttribute("CriticalClicks", 0) | |
| end | |
| local function checkAchievement(player, achievementId, progress) | |
| local achievement = AchievementData.list[achievementId] | |
| if not achievement or playerAchievements[player][achievementId].unlocked then | |
| return | |
| end | |
| -- Update progress | |
| playerAchievements[player][achievementId].progress = progress | |
| -- Check if achievement is completed | |
| if progress >= achievement.goal then | |
| playerAchievements[player][achievementId].unlocked = true | |
| giveReward(player, achievement.reward) | |
| achievementEvent:FireClient(player, achievementId) | |
| end | |
| end | |
| -- Example of tracking cookie milestones | |
| local function onCookiesChanged(player, cookies) | |
| for _, achievement in pairs(AchievementData.list) do | |
| if achievement.category == "milestone" and string.find(achievement.desc, "Bake") then | |
| checkAchievement(player, achievement.id, cookies) | |
| end | |
| end | |
| end | |
| -- Example of tracking critical clicks | |
| local function onCriticalClick(player) | |
| player:SetAttribute("CriticalClicks", player:GetAttribute("CriticalClicks") + 1) | |
| for _, achievement in pairs(AchievementData.list) do | |
| if achievement.id == "critical_click" then | |
| checkAchievement(player, achievement.id, 1) | |
| end | |
| end | |
| end | |
| Players.PlayerAdded:Connect(onPlayerAdded)</pre> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- Skins Section - Enhanced --> | |
| <section id="skins" class="mb-12"> | |
| <h2 class="text-3xl font-bold text-amber-800 mb-6 border-b-2 border-amber-200 pb-2">4. Advanced Skin System</h2> | |
| <div class="grid md:grid-cols-2 gap-8"> | |
| <!-- Skin Shop UI - Enhanced --> | |
| <div class="bg-amber-50 p-6 rounded-lg"> | |
| <h3 class="text-xl font-semibold text-amber-700 mb-4">Skin Shop Architecture</h3> | |
| <div class="mb-6"> | |
| <h4 class="font-medium text-gray-800 mb-2">Skin Types:</h4> | |
| <div class="grid grid-cols-3 gap-3 mb-4"> | |
| <div class="bg-white p-3 rounded text-center shadow"> | |
| <div class="w-12 h-12 rounded-full bg-amber-100 mx-auto mb-2 flex items-center justify-center"> | |
| <i class="fas fa-cookie text-amber-600"></i> | |
| </div> | |
| <p class="text-xs font-medium">Cookie Skins</p> | |
| </div> | |
| <div class="bg-white p-3 rounded text-center shadow"> | |
| <div class="w-12 h-12 rounded-full bg-blue-100 mx-auto mb-2 flex items-center justify-center"> | |
| <i class="fas fa-user text-blue-600"></i> | |
| </div> | |
| <p class="text-xs font-medium">Character Skins</p> | |
| </div> | |
| <div class="bg-white p-3 rounded text-center shadow"> | |
| <div class="w-12 h-12 rounded-full bg-purple-100 mx-auto mb-2 flex items-center justify-center"> | |
| <i class="fas fa-utensils text-purple-600"></i> | |
| </div> | |
| <p class="text-xs font-medium">Baker Tools</p> | |
| </div> | |
| </div> | |
| <h4 class="font-medium text-gray-800 mb-2">Unlock Methods:</h4> | |
| <div class="bg-white p-4 rounded-lg shadow"> | |
| <div class="flex items-center mb-3"> | |
| <div class="w-8 h-8 rounded-full bg-green-100 flex items-center justify-center mr-3"> | |
| <i class="fas fa-coins text-green-600 text-sm"></i> | |
| </div> | |
| <div> | |
| <h5 class="font-semibold">Cookie Purchase</h5> | |
| <p class="text-xs text-gray-600">Earned through normal gameplay</p> | |
| </div> | |
| </div> | |
| <div class="flex items-center mb-3"> | |
| <div class="w-8 h-8 rounded-full bg-yellow-100 flex items-center justify-center mr-3"> | |
| <i class="fas fa-trophy text-yellow-600 text-sm"></i> | |
| </div> | |
| <div> | |
| <h5 class="font-semibold">Achievement Reward</h5> | |
| <p class="text-xs text-gray-600">Complete special challenges</p> | |
| </div> | |
| </div> | |
| <div class="flex items-center"> | |
| <div class="w-8 h-8 rounded-full bg-red-100 flex items-center justify-center mr-3"> | |
| <i class="fas fa-gem text-red-600 text-sm"></i> | |
| </div> | |
| <div> | |
| <h5 class="font-semibold">Premium Currency</h5> | |
| <p class="text-xs text-gray-600">Optional real-money purchases</p> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <div> | |
| <h4 class="font-medium text-gray-800 mb-2">Skin Rarity System:</h4> | |
| <div class="grid grid-cols-4 gap-2 text-xs text-center"> | |
| <div class="bg-gray-100 p-2 rounded">Common</div> | |
| <div class="bg-blue-100 p-2 rounded">Uncommon</div> | |
| <div class="bg-purple-100 p-2 rounded">Rare</div> | |
| <div class="bg-yellow-100 p-2 rounded">Legendary</div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Skin System Code - Enhanced --> | |
| <div class="bg-amber-50 p-6 rounded-lg"> | |
| <h3 class="text-xl font-semibold text-amber-700 mb-4">Skin System Implementation</h3> | |
| <div class="mb-6"> | |
| <h4 class="font-medium text-gray-800 mb-2">Skin Data Module:</h4> | |
| <pre class="bg-gray-800 text-green-300 p-3 rounded text-sm overflow-x-auto"> | |
| -- In a ModuleScript called "SkinData" | |
| local SkinData = {} | |
| SkinData.cookieSkins = { | |
| { | |
| id = "classic", | |
| name = "Classic Cookie", | |
| texture = "rbxassetid://123456", | |
| price = 0, | |
| rarity = "common", | |
| ownedByDefault = true | |
| }, | |
| { | |
| id = "golden", | |
| name = "Golden Cookie", | |
| texture = "rbxassetid://234567", | |
| price = 10000, | |
| rarity = "rare", | |
| unlockMethod = "purchase" | |
| }, | |
| { | |
| id = "dragon", | |
| name = "Dragon Cookie", | |
| texture = "rbxassetid://345678", | |
| unlockMethod = "achievement", | |
| achievementId = "dragon_slayer", | |
| rarity = "legendary" | |
| } | |
| } | |
| SkinData.characterSkins = { | |
| -- Similar structure for character skins | |
| } | |
| return SkinData</pre> | |
| </div> | |
| <div> | |
| <h4 class="font-medium text-gray-800 mb-2">Skin Management System:</h4> | |
| <pre class="bg-gray-800 text-green-300 p-3 rounded text-sm overflow-x-auto"> | |
| local ReplicatedStorage = game:GetService("ReplicatedStorage") | |
| local Players = game:GetService("Players") | |
| local SkinData = require(script.Parent.SkinData) | |
| local skinEvent = Instance.new("RemoteEvent") | |
| skinEvent.Name = "SkinEvent" | |
| skinEvent.Parent = ReplicatedStorage | |
| local playerSkins = {} | |
| local function onPlayerAdded(player) | |
| -- Initialize player's skin data | |
| playerSkins[player] = { | |
| equippedCookie = "classic", | |
| equippedCharacter = "baker", | |
| ownedSkins = {} | |
| } | |
| -- Grant default skins | |
| for _, skin in pairs(SkinData.cookieSkins) do | |
| if skin.ownedByDefault then | |
| table.insert(playerSkins[player].ownedSkins, { | |
| type = "cookie", | |
| id = skin.id | |
| }) | |
| end | |
| end | |
| -- Load saved data from DataStore | |
| -- (Implementation similar to previous data saving examples) | |
| end | |
| -- Handle skin purchases | |
| skinEvent.OnServerEvent:Connect(function(player, action, skinType, skinId) | |
| if action == "purchase" then | |
| local skin = SkinData[skinType.."Skins"][skinId] | |
| if not skin or skin.unlockMethod ~= "purchase" then return end | |
| -- Check if player can afford | |
| if player.leaderstats.Cookies.Value >= skin.price then | |
| player.leaderstats.Cookies.Value = player.leaderstats.Cookies.Value - skin.price | |
| table.insert(playerSkins[player].ownedSkins, { | |
| type = skinType, | |
| id = skinId | |
| }) | |
| -- Notify client of successful purchase | |
| skinEvent:FireClient(player, "purchased", skinType, skinId) | |
| end | |
| elseif action == "equip" then | |
| -- Check if player owns this skin | |
| local ownsSkin = false | |
| for _, ownedSkin in pairs(playerSkins[player].ownedSkins) do | |
| if ownedSkin.type == skinType and ownedSkin.id == skinId then | |
| ownsSkin = true | |
| break | |
| end | |
| end | |
| if ownsSkin then | |
| playerSkins[player]["equipped"..skinType:sub(1,1):upper()..skinType:sub(2)] = skinId | |
| skinEvent:FireClient(player, "equipped", skinType, skinId) | |
| end | |
| end | |
| end) | |
| -- Grant achievement skins | |
| local function onAchievementUnlocked(player, achievementId) | |
| for _, skin in pairs(SkinData.cookieSkins) do | |
| if skin.unlockMethod == "achievement" and skin.achievementId == achievementId then | |
| table.insert(playerSkins[player].ownedSkins, { | |
| type = "cookie", | |
| id = skin.id | |
| }) | |
| skinEvent:FireClient(player, "unlocked", "cookie", skin.id) | |
| end | |
| end | |
| end | |
| Players.PlayerAdded:Connect(onPlayerAdded)</pre> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- Leaderboard Section - Enhanced --> | |
| <section id="leaderboard" class="mb-12"> | |
| <h2 class="text-3xl font-bold text-amber-800 mb-6 border-b-2 border-amber-200 pb-2">5. Global Leaderboard with Countries</h2> | |
| <div class="grid md:grid-cols-2 gap-8"> | |
| <!-- Leaderboard UI - Enhanced --> | |
| <div class="bg-amber-50 p-6 rounded-lg"> | |
| <h3 class="text-xl font-semibold text-amber-700 mb-4">Leaderboard Features</h3> | |
| <div class="mb-6"> | |
| <h4 class="font-medium text-gray-800 mb-2">Filtering Options:</h4> | |
| <div class="bg-white p-4 rounded-lg shadow mb-4"> | |
| <div class="flex flex-wrap gap-2"> | |
| <button class="px-3 py-1 bg-amber-500 text-white rounded-full text-xs">Global</button> | |
| <button class="px-3 py-1 bg-white border border-amber-300 rounded-full text-xs">United States</button> | |
| <button class="px-3 py-1 bg-white border border-amber-300 rounded-full text-xs">United Kingdom</button> | |
| <button class="px-3 py-1 bg-white border border-amber-300 rounded-full text-xs">Canada</button> | |
| <button class="px-3 py-1 bg-white border border-amber-300 rounded-full text-xs">Australia</button> | |
| <button class="px-3 py-1 bg-white border border-amber-300 rounded-full text-xs">Japan</button> | |
| </div> | |
| </div> | |
| <h4 class="font-medium text-gray-800 mb-2">Time Frames:</h4> | |
| <div class="bg-white p-4 rounded-lg shadow"> | |
| <div class="flex gap-2"> | |
| <button class="px-3 py-1 bg-amber-500 text-white rounded-full text-xs">All-Time</button> | |
| <button class="px-3 py-1 bg-white border border-amber-300 rounded-full text-xs">Daily</button> | |
| <button class="px-3 py-1 bg-white border border-amber-300 rounded-full text-xs">Weekly</button> | |
| <button class="px-3 py-1 bg-white border border-amber-300 rounded-full text-xs">Monthly</button> | |
| </div> | |
| </div> | |
| </div> | |
| <div> | |
| <h4 class="font-medium text-gray-800 mb-2">Player Badges:</h4> | |
| <div class="flex flex-wrap gap-2"> | |
| <div class="w-8 h-8 rounded-full bg-yellow-100 flex items-center justify-center"> | |
| <i class="fas fa-crown text-yellow-600 text-xs"></i> | |
| </div> | |
| <div class="w-8 h-8 rounded-full bg-silver-100 flex items-center justify-center"> | |
| <i class="fas fa-medal text-gray-600 text-xs"></i> | |
| </div> | |
| <div class="w-8 h-8 rounded-full bg-amber-100 flex items-center justify-center"> | |
| <i class="fas fa-award text-amber-600 text-xs"></i> | |
| </div> | |
| <div class="w-8 h-8 rounded-full bg-blue-100 flex items-center justify-center"> | |
| <i class="fas fa-flag text-blue-600 text-xs"></i> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Leaderboard Code - Enhanced --> | |
| <div class="bg-amber-50 p-6 rounded-lg"> | |
| <h3 class="text-xl font-semibold text-amber-700 mb-4">Leaderboard Implementation</h3> | |
| <div class="mb-6"> | |
| <h4 class="font-medium text-gray-800 mb-2">Country Detection:</h4> | |
| <pre class="bg-gray-800 text-green-300 p-3 rounded text-sm overflow-x-auto"> | |
| -- Server script to detect player country | |
| local HttpService = game:GetService("HttpService") | |
| local Players = game:GetService("Players") | |
| local function getPlayerCountry(player) | |
| -- Try to get from saved data first | |
| local success, savedCountry = pcall(function() | |
| return DataStore:GetAsync("PlayerCountry_"..player.UserId) | |
| end) | |
| if success and savedCountry then | |
| return savedCountry | |
| end | |
| -- Fallback to IP detection (requires HTTP enabled) | |
| local ip = player:GetRemote("GetRemoteEvent").InvokeClient(player, "GetIP") | |
| if ip then | |
| local success, geoData = pcall(function() | |
| return HttpService:JSONDecode(HttpService:GetAsync( | |
| "http://ip-api.com/json/"..ip.."?fields=countryCode" | |
| )) | |
| end) | |
| if success and geoData.countryCode then | |
| -- Save for future sessions | |
| pcall(function() | |
| DataStore:SetAsync("PlayerCountry_"..player.UserId, geoData.countryCode) | |
| end) | |
| return geoData.countryCode | |
| end | |
| end | |
| return "Unknown" | |
| end | |
| Players.PlayerAdded:Connect(function(player) | |
| player:SetAttribute("Country", getPlayerCountry(player)) | |
| end)</pre> | |
| </div> | |
| <div> | |
| <h4 class="font-medium text-gray-800 mb-2">Global Data Handling:</h4> | |
| <pre class="bg-gray-800 text-green-300 p-3 rounded text-sm overflow-x-auto"> | |
| -- Using DataStores for global leaderboard | |
| local DataStoreService = game:GetService("DataStoreService") | |
| local leaderboardStore = DataStoreService:GetOrderedDataStore("GlobalLeaderboard") | |
| local function updateGlobalLeaderboard(player, cookies) | |
| -- Update all-time leaderboard | |
| pcall(function() | |
| leaderboardStore:SetAsync(tostring(player.UserId), cookies) | |
| end) | |
| -- Update daily leaderboard (with today's date as key) | |
| local today = os.date("%Y-%m-%d") | |
| local dailyKey = "daily_"..today.."_"..player.UserId | |
| pcall(function() | |
| leaderboardStore:SetAsync(dailyKey, cookies) | |
| end) | |
| end | |
| -- Function to get leaderboard data | |
| local function getLeaderboardData(scope, country) | |
| -- scope can be "alltime", "daily", "weekly", "monthly" | |
| -- country can be country code or "Global" | |
| local data = {} | |
| local keyPrefix = "" | |
| if scope == "daily" then | |
| keyPrefix = "daily_"..os.date("%Y-%m-%d").."_" | |
| elseif scope == "weekly" then | |
| -- Similar implementation for weekly | |
| end | |
| -- Get top 100 entries | |
| local success, pages = pcall(function() | |
| if country == "Global" then | |
| return leaderboardStore:GetSortedAsync(false, 100, keyPrefix) | |
| else | |
| -- Filter by country would require additional data structure | |
| -- This is a simplified version | |
| return leaderboardStore:GetSortedAsync(false, 100) | |
| end | |
| end) | |
| if success then | |
| for _, entry in ipairs(pages:GetCurrentPage()) do | |
| local userId = entry.key:gsub(keyPrefix, "") | |
| table.insert(data, { | |
| userId = userId, | |
| cookies = entry.value | |
| }) | |
| end | |
| end | |
| return data | |
| end | |
| -- Example of player data saving | |
| game.Players.PlayerRemoving:Connect(function(player) | |
| updateGlobalLeaderboard(player, player.leaderstats.Cookies.Value) | |
| end)</pre> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- Cookie Monster Section - Enhanced --> | |
| <section id="cookie-monster" class="mb-12"> | |
| <h2 class="text-3xl font-bold text-amber-800 mb-6 border-b-2 border-amber-200 pb-2">6. Cookie Monster Game Mechanic</h2> | |
| <div class="grid md:grid-cols-2 gap-8"> | |
| <!-- Monster UI - Enhanced --> | |
| <div class="bg-amber-50 p-6 rounded-lg"> | |
| <h3 class="text-xl font-semibold text-amber-700 mb-4">Cookie Monster Features</h3> | |
| <div class="mb-6"> | |
| <h4 class="font-medium text-gray-800 mb-2">Monster States:</h4> | |
| <div class="grid grid-cols-3 gap-3 text-center text-xs"> | |
| <div class="bg-green-100 p-3 rounded"> | |
| <div class="w-12 h-12 mx-auto mb-2 bg-green-200 rounded-full flex items-center justify-center"> | |
| <i class="fas fa-smile text-green-600"></i> | |
| </div> | |
| <p>Happy (0-30%)</p> | |
| </div> | |
| <div class="bg-yellow-100 p-3 rounded"> | |
| <div class="w-12 h-12 mx-auto mb-2 bg-yellow-200 rounded-full flex items-center justify-center"> | |
| <i class="fas fa-meh text-yellow-600"></i> | |
| </div> | |
| <p>Hungry (31-70%)</p> | |
| </div> | |
| <div class="bg-red-100 p-3 rounded"> | |
| <div class="w-12 h-12 mx-auto mb-2 bg-red-200 rounded-full flex items-center justify-center"> | |
| <i class="fas fa-angry text-red-600"></i> | |
| </div> | |
| <p>Enraged (71-100%)</p> | |
| </div> | |
| </div> | |
| </div> | |
| <div> | |
| <h4 class="font-medium text-gray-800 mb-2">Feeding Mechanics:</h4> | |
| <ul class="list-disc pl-5 space-y-2 text-gray-700"> | |
| <li><strong>Basic Feed:</strong> 50 cookies - reduces hunger by 25%</li> | |
| <li><strong>Special Feed:</strong> 200 cookies - reduces hunger by 60%</li> | |
| <li><strong>Golden Feed:</strong> 1000 cookies - resets hunger to 0%</li> | |
| <li><strong>Auto-Feeder:</strong> Upgrade that automatically feeds when hunger reaches 50%</li> | |
| </ul> | |
| </div> | |
| </div> | |
| <!-- Monster Code - Enhanced --> | |
| <div class="bg-amber-50 p-6 rounded-lg"> | |
| <h3 class="text-xl font-semibold text-amber-700 mb-4">Cookie Monster Implementation</h3> | |
| <div class="mb-6"> | |
| <h4 class="font-medium text-gray-800 mb-2">Monster State Management:</h4> | |
| <pre class="bg-gray-800 text-green-300 p-3 rounded text-sm overflow-x-auto"> | |
| -- Server-side monster manager | |
| local monster = { | |
| hunger = 0, -- 0-100 | |
| lastFed = os.time(), | |
| hungerRate = 0.1, -- % per minute | |
| state = "happy", | |
| rampageThreshold = 90, | |
| isRampaging = false, | |
| rampageEndTime = 0 | |
| } | |
| -- Update hunger over time | |
| local function updateHunger() | |
| while true do | |
| local timePassed = os.time() - monster.lastFed | |
| monster.hunger = math.min(100, monster.hunger + (monster.hungerRate * (timePassed/60))) | |
| -- Update state | |
| if monster.hunger <= 30 then | |
| monster.state = "happy" | |
| elseif monster.hunger <= 70 then | |
| monster.state = "hungry" | |
| else | |
| monster.state = "angry" | |
| end | |
| -- Check for rampage | |
| if monster.hunger >= monster.rampageThreshold and not monster.isRampaging then | |
| startRampage() | |
| end | |
| -- Increase hunger rate over time (gets harder) | |
| monster.hungerRate = monster.hungerRate * 1.0001 | |
| -- Broadcast update to all players | |
| for _, player in ipairs(game.Players:GetPlayers()) do | |
| ReplicatedStorage.MonsterUpdate:FireClient(player, { | |
| hunger = monster.hunger, | |
| state = monster.state, | |
| isRampaging = monster.isRampaging, | |
| timeLeft = monster.rampageEndTime - os.time() | |
| }) | |
| end | |
| wait(60) -- Update every minute | |
| end | |
| end | |
| -- Start the hunger update loop | |
| spawn(updateHunger)</pre> | |
| </div> | |
| <div> | |
| <h4 class="font-medium text-gray-800 mb-2">Rampage System:</h4> | |
| <pre class="bg-gray-800 text-green-300 p-3 rounded text-sm overflow-x-auto"> | |
| local function startRampage() | |
| monster.isRampaging = true | |
| monster.rampageEndTime = os.time() + 300 -- 5 minutes to stop | |
| -- Alert all players | |
| for _, player in ipairs(game.Players:GetPlayers()) do | |
| ReplicatedStorage.RampageAlert:FireClient(player, true) | |
| end | |
| -- Start countdown | |
| local countdown = 300 -- 5 minutes | |
| while countdown > 0 and monster.isRampaging do | |
| countdown = countdown - 1 | |
| -- Update players every second | |
| for _, player in ipairs(game.Players:GetPlayers()) do | |
| ReplicatedStorage.MonsterUpdate:FireClient(player, { | |
| hunger = monster.hunger, | |
| state = monster.state, | |
| isRampaging = monster.isRampaging, | |
| timeLeft = countdown | |
| }) | |
| end | |
| -- Check if hunger was reduced below threshold | |
| if monster.hunger < monster.rampageThreshold then | |
| monster.isRampaging = false | |
| break | |
| end | |
| wait(1) | |
| end | |
| if monster.isRampaging then | |
| -- Monster eats all cookies | |
| for _, player in ipairs(game.Players:GetPlayers()) do | |
| player.leaderstats.Cookies.Value = 0 | |
| ReplicatedStorage.CookieUpdate:FireClient(player, 0) | |
| end | |
| -- Play animation/sound | |
| for _, player in ipairs(game.Players:GetPlayers()) do | |
| ReplicatedStorage.RampageEffect:FireClient(player) | |
| end | |
| end | |
| -- Reset monster | |
| monster.isRampaging = false | |
| monster.hunger = 0 | |
| monster.lastFed = os.time() | |
| -- Alert players rampage is over | |
| for _, player in ipairs(game.Players:GetPlayers()) do | |
| ReplicatedStorage.RampageAlert:FireClient(player, false) | |
| end | |
| end | |
| -- Handle feeding | |
| ReplicatedStorage.FeedMonster.OnServerEvent:Connect(function(player, feedType) | |
| local cost = 0 | |
| local reduction = 0 | |
| if feedType == "basic" then | |
| cost = 50 | |
| reduction = 25 | |
| elseif feedType == "special" then | |
| cost = 200 | |
| reduction = 60 | |
| elseif feedType == "golden" then | |
| cost = 1000 | |
| reduction = 100 | |
| end | |
| if player.leaderstats.Cookies.Value >= cost then | |
| player.leaderstats.Cookies.Value = player.leaderstats.Cookies.Value - cost | |
| monster.hunger = math.max(0, monster.hunger - reduction) | |
| monster.lastFed = os.time() | |
| -- Check if rampage was stopped | |
| if monster.isRampaging and monster.hunger < monster.rampageThreshold then | |
| monster.isRampaging = false | |
| end | |
| end | |
| end)</pre> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- Final Notes - Enhanced --> | |
| <section class="bg-amber-100 rounded-lg p-6 border-l-4 border-amber-500"> | |
| <h2 class="text-2xl font-bold text-amber-800 mb-4">Complete Implementation Roadmap</h2> | |
| <div class="grid md:grid-cols-3 gap-6"> | |
| <div class="bg-white p-4 rounded-lg shadow"> | |
| <h3 class="font-semibold text-amber-700 mb-3">Phase 1: Core Gameplay</h3> | |
| <ul class="list-disc pl-5 space-y-2 text-sm"> | |
| <li>Basic clicking mechanic</li> | |
| <li>Auto-clicker upgrades</li> | |
| <li>Simple cookie design</li> | |
| <li>Local leaderboard</li> | |
| </ul> | |
| </div> | |
| <div class="bg-white p-4 rounded-lg shadow"> | |
| <h3 class="font-semibold text-amber-700 mb-3">Phase 2: Progression</h3> | |
| <ul class="list-disc pl-5 space-y-2 text-sm"> | |
| <li>Achievements system</li> | |
| <li>Skin customization</li> | |
| <li>Global leaderboard</li> | |
| <li>Country selection</li> | |
| </ul> | |
| </div> | |
| <div class="bg-white p-4 rounded-lg shadow"> | |
| <h3 class="font-semibold text-amber-700 mb-3">Phase 3: Advanced Features</h3> | |
| <ul class="list-disc pl-5 space-y-2 text-sm"> | |
| <li>Cookie Monster mechanic</li> | |
| <li>Special events</li> | |
| <li>Social features</li> | |
| <li>Premium currency</li> | |
| </ul> | |
| </div> | |
| </div> | |
| <div class="mt-6 bg-white p-4 rounded-lg shadow"> | |
| <h3 class="font-semibold text-amber-700 mb-3">Optimization Checklist</h3> | |
| <div class="grid grid-cols-2 gap-4"> | |
| <div> | |
| <h4 class="font-medium text-gray-800 mb-2">Performance:</h4> | |
| <ul class="list-disc pl-5 space-y-1 text-sm"> | |
| <li>Use ValueObjects for frequently updated values</li> | |
| <li>Limit particle effects</li> | |
| <li>Optimize DataStore calls</li> | |
| </ul> | |
| </div> | |
| <div> | |
| <h4 class="font-medium text-gray-800 mb-2">Security:</h4> | |
| <ul class="list-disc pl-5 space-y-1 text-sm"> | |
| <li>Server-side validation</li> | |
| <li>Anti-exploit checks</li> | |
| <li>DataStore backup system</li> | |
| </ul> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="mt-6 text-center"> | |
| <button class="cookie-btn px-6 py-3 bg-amber-500 text-white rounded-full text-lg font-bold shadow-lg hover:bg-amber-600"> | |
| <i class="fas fa-rocket mr-2"></i> Launch Your Cookie Empire! | |
| </button> | |
| </div> | |
| </section> | |
| </main> | |
| <!-- Footer --> | |
| <footer class="mt-12 text-center text-white opacity-80 text-sm"> | |
| <p>© 2023 Ultimate Roblox Cookie Clicker Guide. All rights reserved.</p> | |
| <p class="mt-2">Created with <i class="fas fa-heart text-red-400"></i> for Roblox developers</p> | |
| </footer> | |
| </div> | |
| <script> | |
| // Tab functionality | |
| document.querySelectorAll('.code-tab-btn').forEach(btn => { | |
| btn.addEventListener('click', function() { | |
| const tabId = this.getAttribute('data-tab'); | |
| const container = this.closest('.bg-gray-100'); | |
| // Deactivate all tabs in this container | |
| container.querySelectorAll('.code-tab-btn').forEach(t => { | |
| t.classList.remove('border-b-2', 'border-amber-500', 'text-amber-700'); | |
| t.classList.add('text-gray-600'); | |
| }); | |
| // Hide all content in this container | |
| container.querySelectorAll('.code-tab').forEach(t => { | |
| t.classList.remove('active'); | |
| }); | |
| // Activate this tab | |
| this.classList.add('border-b-2', 'border-amber-500', 'text-amber-700'); | |
| this.classList.remove('text-gray-600'); | |
| document.getElementById(tabId).classList.add('active'); | |
| }); | |
| }); | |
| // Cookie button animation | |
| document.querySelectorAll('.cookie-btn').forEach(btn => { | |
| btn.addEventListener('click', function() { | |
| this.classList.add('animate-bounce'); | |
| setTimeout(() => { | |
| this.classList.remove('animate-bounce'); | |
| }, 1000); | |
| }); | |
| }); | |
| </script> | |
| <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=DiamondVi/cookie-1" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
| </html> |