Pacman game script just in case ur bored
Key RequiredUniversal

Pacman game script just in case ur bored

Universal ScriptDcruzRaceDcruzRace 799 views 69 executesUpdated Oct 10, 2025
2.0/ 5(5 votes)
2340% Positive
Lua Script•312 lines (9765 chars)
-- Full Pac-Man GUI with unreachable pellet workaround
-- Place in StarterPlayerScripts

local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")
local player = Players.LocalPlayer
local guiParent = player:WaitForChild("PlayerGui")

-- === GUI ===
local screenGui = Instance.new("ScreenGui")
screenGui.Name = "PacManGame"
screenGui.ResetOnSpawn = false
screenGui.Parent = guiParent

local mainFrame = Instance.new("Frame")
mainFrame.Size = UDim2.new(0, 800, 0, 672)
mainFrame.Position = UDim2.new(0.5, -400, 0.5, -336)
mainFrame.BackgroundColor3 = Color3.fromRGB(10,10,40)
mainFrame.BorderSizePixel = 2
mainFrame.Parent = screenGui

local scoreLabel = Instance.new("TextLabel")
scoreLabel.Size = UDim2.new(1,0,0,30)
scoreLabel.Position = UDim2.new(0,0,0,-30)
scoreLabel.BackgroundTransparency = 1
scoreLabel.Text = "Score: 0"
scoreLabel.Font = Enum.Font.SourceSansBold
scoreLabel.TextSize = 22
scoreLabel.TextColor3 = Color3.new(1,1,1)
scoreLabel.Parent = mainFrame

-- === Fixed Map ===
local map = {
"1111111111111111111111111",
"1000001000001000001000001",
"1011111011111111111011101",
"1000000000001000000000001",
"1011110111101011110111101",
"1000000000000000000000001",
"1011111011111111111011101",
"1000001000000P0000010001",
"1111101110111011101111111",
"1000001000000000000010001",
"1011111111111111111111101",
"1000000000000000000000001",
"1011111011111111111011101",
"1000001000000000000010001",
"1111101110111011101111111",
"1000000000000000000000001",
"1011110111101011110111101",
"1000000000001000000000001",
"1011110111101011110111101",
"1000001000001000001000001",
"1111111111111111111111111",
}

local rows = #map
local cols = #map[1]
local CELL = 32
local dirs = {Up={dr=-1,dc=0}, Down={dr=1,dc=0}, Left={dr=0,dc=-1}, Right={dr=0,dc=1}}

-- === Maze, Pellets, Player, Ghost Positions ===
local pellets = {}
local pelletFrames = {}
local pelletCount = 0
local playerPos = {r=0,c=0}
local ghostPositions = {}

for r=1,rows do
    for c=1,cols do
        local cell = map[r]:sub(c,c)
        local x = (c-1)*CELL
        local y = (r-1)*CELL
        if cell=="1" then
            local wall = Instance.new("Frame")
            wall.Size = UDim2.new(0,CELL,0,CELL)
            wall.Position = UDim2.new(0,x,0,y)
            wall.BackgroundColor3 = Color3.fromRGB(20,20,200)
            wall.BorderSizePixel = 0
            wall.Parent = mainFrame
        elseif cell=="0" then
            pellets[r..","..c] = true
            pelletCount +=1
            local dot = Instance.new("Frame")
            dot.Size = UDim2.new(0,6,0,6)
            dot.Position = UDim2.new(0,x+(CELL/2-3),0,y+(CELL/2-3))
            dot.BackgroundColor3 = Color3.fromRGB(255,255,255)
            dot.BorderSizePixel = 0
            dot.Parent = mainFrame
            pelletFrames[r..","..c] = dot
        elseif cell=="P" then
            playerPos={r=r,c=c}
        end
    end
end
if playerPos.r==0 then playerPos={r=2,c=2} end

-- === Random Ghost Spawns ===
local openCells = {}
for r=1,rows do
    for c=1,cols do
        if map[r]:sub(c,c)=="0" then
            table.insert(openCells,{r=r,c=c})
        end
    end
end
for i=1,4 do
    if #openCells==0 then break end
    local index = math.random(1,#openCells)
    table.insert(ghostPositions,openCells[index])
    table.remove(openCells,index)
end

-- === Player ===
local pac = Instance.new("Frame")
pac.Size = UDim2.new(0,CELL-4,0,CELL-4)
pac.BackgroundColor3 = Color3.fromRGB(255,255,0)
pac.Position = UDim2.new(0,(playerPos.c-1)*CELL+2,0,(playerPos.r-1)*CELL+2)
pac.Parent = mainFrame

-- === Ghosts ===
local ghosts = {}
local ghostColors = {Color3.fromRGB(255,0,0),Color3.fromRGB(255,184,255),Color3.fromRGB(0,255,255),Color3.fromRGB(255,184,82)}
for i=1,#ghostPositions do
    local ghost = Instance.new("Frame")
    ghost.Size = UDim2.new(0,CELL-4,0,CELL-4)
    ghost.BackgroundColor3 = ghostColors[i] or Color3.fromRGB(255,0,0)
    ghost.Position = UDim2.new(0,(ghostPositions[i].c-1)*CELL+2,0,(ghostPositions[i].r-1)*CELL+2)
    ghost.Parent = mainFrame
    table.insert(ghosts,{gui=ghost,pos={r=ghostPositions[i].r,c=ghostPositions[i].c},dir={dr=0,dc=0}})
end

-- === Blocked pellets positions to ignore for win ===
local blockedPellets = {
    "8,23", "9,23", "10,23"  -- adjust if needed to match exact unreachable dots
}

-- === Game State ===
local running = true
local gameEnded = false
local score = 0
local currentDir = nil
local renderConn, inputConn
local mobileConns = {}

local function canMove(r,c)
    return r>=1 and r<=rows and c>=1 and c<=cols and map[r]:sub(c,c)~="1"
end

local function movePlayer(r,c)
    playerPos={r=r,c=c}
    pac.Position = UDim2.new(0,(c-1)*CELL+2,0,(r-1)*CELL+2)
    local key=r..","..c
    if pellets[key] then
        pellets[key]=nil
        score +=1
        scoreLabel.Text = "Score: "..score
        if pelletFrames[key] then pelletFrames[key]:Destroy() end
        pelletCount -=1
    end
end

local function ghostChooseDir(g)
    local possible = {}
    for _,d in pairs(dirs) do
        local nr,nc=g.pos.r+d.dr,g.pos.c+d.dc
        if canMove(nr,nc) and not (g.dir.dr==-d.dr and g.dir.dc==-d.dc) then
            table.insert(possible,d)
        end
    end
    if #possible==0 then
        for _,d in pairs(dirs) do
            local nr,nc=g.pos.r+d.dr,g.pos.c+d.dc
            if canMove(nr,nc) then table.insert(possible,d) end
        end
    end
    if #possible>0 then
        table.sort(possible,function(a,b)
            local da = math.abs((g.pos.r+a.dr)-playerPos.r) + math.abs((g.pos.c+a.dc)-playerPos.c)
            local db = math.abs((g.pos.r+b.dr)-playerPos.r) + math.abs((g.pos.c+b.dc)-playerPos.c)
            return da<db
        end)
        g.dir = possible[1]
    end
end

-- === Cleanup & Restart ===
local function cleanup()
    running=false
    gameEnded=true
    if renderConn then renderConn:Disconnect() end
    if inputConn then inputConn:Disconnect() end
    for _,c in ipairs(mobileConns) do c:Disconnect() end
    if screenGui then screenGui:Destroy() end
end

local function showEndGame(msg)
    local overlay = Instance.new("Frame")
    overlay.Size = UDim2.new(1,0,1,0)
    overlay.BackgroundColor3 = Color3.fromRGB(0,0,0)
    overlay.BackgroundTransparency = 0.4
    overlay.Parent = screenGui

    local text = Instance.new("TextLabel")
    text.Size = UDim2.new(1,0,0.5,0)
    text.Position = UDim2.new(0,0,0.25,0)
    text.BackgroundTransparency = 1
    text.Text = msg
    text.Font = Enum.Font.SourceSansBold
    text.TextSize = 32
    text.TextColor3 = Color3.new(1,1,1)
    text.Parent = overlay

    local restart = Instance.new("TextButton")
    restart.Size = UDim2.new(0.3,0,0.15,0)
    restart.Position = UDim2.new(0.35,0,0.7,0)
    restart.BackgroundColor3 = Color3.fromRGB(60,60,160)
    restart.Text = "🔄 Restart"
    restart.TextColor3 = Color3.new(1,1,1)
    restart.Font = Enum.Font.SourceSansBold
    restart.TextSize = 26
    restart.Parent = overlay
    restart.MouseButton1Click:Connect(cleanup)
end

-- === Mobile Buttons ===
local mobileFrame = Instance.new("Frame")
mobileFrame.Size = UDim2.new(0,160,0,160)
mobileFrame.Position = UDim2.new(1,-180,0.5,-80)
mobileFrame.BackgroundTransparency = 1
mobileFrame.Parent = screenGui

local function makeBtn(sym,x,y)
    local b = Instance.new("TextButton")
    b.Size = UDim2.new(0,48,0,48)
    b.Position = UDim2.new(0,x,0,y)
    b.BackgroundColor3 = Color3.fromRGB(40,40,100)
    b.Text = sym
    b.Font = Enum.Font.SourceSansBold
    b.TextSize = 26
    b.TextColor3 = Color3.new(1,1,1)
    b.Parent = mobileFrame
    return b
end

mobileConns = {
    makeBtn("▲",56,0).MouseButton1Down:Connect(function() currentDir = dirs.Up end),
    makeBtn("◀",0,56).MouseButton1Down:Connect(function() currentDir = dirs.Left end),
    makeBtn("▶",112,56).MouseButton1Down:Connect(function() currentDir = dirs.Right end),
    makeBtn("▼",56,112).MouseButton1Down:Connect(function() currentDir = dirs.Down end),
}

-- === Keyboard Input ===
inputConn = UserInputService.InputBegan:Connect(function(input,gp)
    if gp or gameEnded then return end
    local k=input.KeyCode.Name
    if dirs[k] then currentDir = dirs[k] end
end)

-- === Game Loop ===
local ghostTimer,playerTimer=0,0
renderConn = RunService.RenderStepped:Connect(function(dt)
    if not running then return end
    playerTimer+=dt
    ghostTimer+=dt

    -- Player movement
    if playerTimer>0.15 and currentDir then
        local nr,nc=playerPos.r+currentDir.dr,playerPos.c+currentDir.dc
        if canMove(nr,nc) then movePlayer(nr,nc) end
        playerTimer=0
    end

    -- Ghost movement
    if ghostTimer>0.3 then
        for _,g in ipairs(ghosts) do
            ghostChooseDir(g)
            local nr,nc=g.pos.r+g.dir.dr,g.pos.c+g.dir.dc
            if canMove(nr,nc) then
                g.pos={r=nr,c=nc}
                g.gui.Position=UDim2.new(0,(nc-1)*CELL+2,0,(nr-1)*CELL+2)
            end
        end
        ghostTimer=0
    end

    -- Collision
    for _,g in ipairs(ghosts) do
        if g.pos.r==playerPos.r and g.pos.c==playerPos.c and not gameEnded then
            gameEnded=true
            running=false
            showEndGame("💀 Game Over!\nScore: "..score)
            return
        end
    end

    -- Win condition ignoring blocked pellets
    local remainingPellets = 0
    for k,v in pairs(pellets) do
        local blocked = false
        for _,b in ipairs(blockedPellets) do
            if k==b then blocked=true break end
        end
        if not blocked then remainingPellets +=1 end
    end
    if remainingPellets<=0 and not gameEnded then
        gameEnded=true
        running=false
        showEndGame("🏆 You Win!\nScore: "..score)
    end
end)

Features & Information

The first Game made with only scripts this is for games where you have to have patience and it's something to do

Community Comments (24)

DcruzRaceDcruzRaceOct 10, 2025

It looks like the photo I think it's the only script game on this website don't expect a first game to be detailed also for the three Pellets trapped you don't need those you win without collecting them as that's what I expect to happen I did play test it mobile supported tell me if they're is any problems with the script

kevin123kevin123Oct 10, 2025

ts so goated

Replying to @kevin123
DcruzRaceDcruzRaceOct 10, 2025

@kevin123 Thank you so much I'm trying to start a script game trend

DcruzRaceDcruzRaceOct 10, 2025

AI explanation this script is not originally AI I made all of the scripts but they're was that one section where it was impossible to get the pellet and it would take me hours to fix so I asked AI to workaround it And do whatever you can to fix the problem it ended up categorizing my script and made it easier to code too and I added some better Ghost AI so it would actually chase you I'm not those scripters who only use AI AI is a tool its meant to *ist not do everything for you

Replying to @DcruzRace
1nfinity1nfinityOct 10, 2025

@DcruzRace mostly everything in this script is ai lol

Replying to @1nfinity
DcruzRaceDcruzRaceOct 10, 2025

@1nfinity No? I added original code you can't prove that I used AI

Replying to @DcruzRace
1nfinity1nfinityOct 10, 2025

@DcruzRace the proof is that every single one of your posts includes you lying about "I only used ai to help me code!"

Replying to @1nfinity
DcruzRaceDcruzRaceOct 10, 2025

@1nfinity It actually did dude -_- I am a beginner coder Cut me some slack ok

Replying to @1nfinity
DcruzRaceDcruzRaceOct 10, 2025

@1nfinity Also the scripts you post I bet aren't even urs

Replying to @DcruzRace
1nfinity1nfinityOct 10, 2025

@DcruzRace ok then check the github I just updated the status and most of my scripts include some credit to my username and one of them even had a link to my github OBFUSCATED CODE BTW

Replying to @1nfinity
Unnamed_GooseUnnamed_GooseOct 10, 2025(edited)

@1nfinity He does have a lot of unnecessary comments but those could've been added when he asked the ai to fix his issue. The code quality isn't that good but nor is it bad enough to warrant such an observation. If you do not have any technical feedback nor any other suggestions regarding his codebase then please find your manners and shut up!

Replying to @Unnamed_Goose
1nfinity1nfinityOct 10, 2025

@Unnamed_Goose telling me to find my manners and then telling me to shut up in the same sentence all while defending someone who got mad over something that wasn't even an insult is saying a lot

Replying to @1nfinity
DcruzRaceDcruzRaceOct 10, 2025

@1nfinity I'm not Mad I'm just trying to see ur point on Why you think my entire script is AI

Replying to @1nfinity
Unnamed_GooseUnnamed_GooseOct 10, 2025(edited)

@1nfinity If you have a solid argument against the before mentioned reply please mention it.

xyrevexxyrevexOct 10, 2025

@DcruzRace AI, look at all the comments etc

Replying to @xyrevex
DcruzRaceDcruzRaceOct 10, 2025

@Astric I used AI to fix a bug in the mini game alright

Replying to @xyrevex
DcruzRaceDcruzRaceOct 10, 2025

@Astric Also I did make one script without AIs help All by myself

xyrevexxyrevexOct 11, 2025

@DcruzRace was the bug not having the game?

Replying to @xyrevex
DcruzRaceDcruzRaceOct 11, 2025

@Astric The bug was that the three pellets on the map were u*tainable -_-

Replying to @xyrevex
DcruzRaceDcruzRaceOct 11, 2025

@Astric Also the AI put Workaround not Pacman Game meaning it only generated a workaround

wdynwdynOct 12, 2025

* dude i *ing took like 10 keys out of my keyboard on this *ing script

Replying to @wdyn
wdynwdynOct 12, 2025

what the hell dawg

wdynwdynOct 12, 2025

I RAGED SO HARD

Replying to @wdyn
DcruzRaceDcruzRaceOct 13, 2025

@wdyn Are you okay

More Scripts for Universal Scripts