PICO-8
Main Menu Cartridge

Follow along with the video to learn how to control game states for a main menu!
The video moves quickly so pause whenever you need.
The video doesn't explain everything, but this page does!
Make sure you understand why this code works or you won't be able to make your own game states later!
After you made this main menu, change it up! Try some of the challenges below to spark some ideas!
Challenges!
After following the lesson, take on some of these challenges to test your knowledge and skills!
1. Add your main character to the Main Menu.
2. Add a background scene to the Main Menu.
3. Add other options, like "Select a Character".
4. Add another Game State before starting the actual game, such as an Options Menu.
Intro to Making a Main Menu!
Game Sprites!

Explanation of Code!
function _init() --add your variables here end
By setting up your variables inside of the
_init()
function, you can easily reset your game by calling_init()
, and the variables here have access to any custom functions you write. That might come in handy later so it's a good practice.
--variables scene="menu" x=63 y=63
The first variable is named
scene
. Then the equals sign tells the game to remember it with whatever we write next.scene
holds a word (technically called a "string") and that string is the name of the scene (technically called a "game state") that we want to run.
The next variables are named
x
andy
. Together these tell the game where the player character is positioned on the screen.
x=63
andy=63
because the screen has 128 pixels from left-to-right and top-to-bottom (# 0-127), so the screen center is at (63,63)These are used to draw the player character in the center of the screen at the beginning of the game.
--main update and draw
function _update()
if scene=="menu" then
update_menu()
elseif scene=="game" then
update_game()
end
end
function _draw()
if scene=="menu" then
draw_menu()
elseif scene=="game" then
draw_game()
end
end
_update()
makes changes to the game 30 times every second.
_draw()
runs after _update and draws to the game screen 30 times every second.
if scene=="menu" then
checks the "scene" variable for which state should be active.
You can do this for each game state that you want to create. Just add an
elseif
to the check for the other game states.
update_menu()
draw_menu()
update_game()
draw_game()
These are going to be our custom functions that become what _update()
and _draw()
will run, that are specific to the game state, when it is active.

--updates
function update_menu()
if btnp(❎) then
scene="game"
end
end
function update_game()
if btn(⬅️) then x-=1 end
if btn(➡️) then x+=1 end
if btn(⬆️) then y-=1 end
if btn(⬇️) then y+=1 end
if btnp(❎) then
scene="menu"
end
end
function update_menu()
creates a custom function for the specific updating of the Main Menu scene.
if btnp(❎) then
checks if the player pressed the X button and ignores if the player holds it down too long.
scene="game"
changes the "scene" variable so that the game state will change to the actual game scene.

function update_game()
creates a custom function for the specific updating of the Game scene.
if btn(⬅️) then x-=1 end ...
is the Simple Movement code.
Then we use the same check as in update_menu()
function for switching the game state back to the Main Menu, only for demonstration purposes.
You would probably want to have a Game Over scene or a Win scene after your Game scene, and not just from a click of a button.

--draws
function draw_menu()
cls()
print("press ❎ to start",30,63)
end
function draw_game()
cls()
spr(1,x,y)
end
function draw_menu()
creates a custom function for the specific drawing of the Main Menu scene.
cls()
clears the screen.
print("press ❎ to start",30,63)
writes the words "press X to start" at position (30,63) which is about center.

function draw_game()
creates a custom function for the specific drawing of the Game scene.
cls()
clears the screen.
spr(1,x,y)
simply draws the sprite #1 at the coordinates (x,y) which change in the update_game()
function based on the player's button presses.

--initialize
function _init()
--variables
scene="menu"
x=63
y=63
end
-->8
--main update and draw
function _update()
if scene=="menu" then
update_menu()
elseif scene=="game" then
update_game()
end
end
function _draw()
if scene=="menu" then
draw_menu()
elseif scene=="game" then
draw_game()
end
end
-->8
--updates
function update_menu()
if btnp(❎) then
scene="game"
end
end
function update_game()
if btn(⬅️) then x-=1 end
if btn(➡️) then x+=1 end
if btn(⬆️) then y-=1 end
if btn(⬇️) then y+=1 end
if btnp(❎) then
scene="menu"
end
end
-->8
--draws
function draw_menu()
cls()
print("press ❎ to start",30,63)
end
function draw_game()
cls()
spr(1,x,y)
end
-->8
is a new tab in Pico-8. They don't appear inside the Pico-8 code editor.

font
