Learning

Lua + LÖVE: Make a Game · Reference

LÖVE callbacks and API map

A focused map of the LÖVE 11.5 callbacks and modules used by Orbit Runner.

This is a focused map, not a replacement for the official LÖVE wiki. It covers the APIs used in the course and the decision behind each one.

Core callbacks

function love.load()
  -- once: create resources and initial application state
end

function love.update(dt)
  -- every frame: advance simulation; dt is elapsed seconds
end

function love.draw()
  -- every frame: draw the current state
end

function love.keypressed(key, scancode, isrepeat)
  -- once per key press (plus repeats if enabled by the OS/framework)
end

function love.textinput(text)
  -- text entry; better than keypressed for names and chat
end

function love.resize(width, height)
  -- window dimensions changed when resizable
end

function love.focus(hasFocus)
  -- pause or respond when focus changes
end

function love.quit()
  -- final hook; return true to prevent quitting
end

Callbacks must be defined at top level on the love table. Do not call love.load, love.update, or love.draw yourself during ordinary use.

Input

love.keyboard.isDown("left", "a") -- current held state
love.mouse.getPosition()           -- current x, y
love.mouse.isDown(1)               -- current primary button state

Use polling for continuous actions. Use callbacks such as love.keypressed, love.mousepressed, and love.textinput for discrete events.

Common key names: "return", "escape", "space", "left", "right", "up", "down", "lshift", "rshift".

Window and dimensions

Prefer conf.lua for initial settings:

function love.conf(t)
  t.identity = "my-game"
  t.version = "11.5"
  t.window.title = "My Game"
  t.window.width = 960
  t.window.height = 540
  t.window.resizable = false
  t.window.vsync = 1
end

At runtime:

local width = love.graphics.getWidth()
local height = love.graphics.getHeight()
local width, height = love.graphics.getDimensions()
love.window.setMode(1280, 720, {resizable = true})

Drawing

In LÖVE 11.x, color channels range from 0 to 1.

love.graphics.setBackgroundColor(0.04, 0.03, 0.08)
love.graphics.setColor(1, 0.83, 0.47, 1)

love.graphics.circle("fill", x, y, radius)
love.graphics.rectangle("line", x, y, width, height)
love.graphics.line(x1, y1, x2, y2)
love.graphics.polygon("fill", x1, y1, x2, y2, x3, y3)
love.graphics.print("Text", x, y)
love.graphics.printf("Centered", x, y, width, "center")

Later calls draw over earlier calls. Set color before the operations it should affect, then reset to white before drawing un-tinted images or text.

Convert byte colors:

love.graphics.setColor(love.math.colorFromBytes(84, 231, 215))

Transform stack

love.graphics.push()
love.graphics.translate(offsetX, offsetY)
love.graphics.rotate(angleInRadians)
love.graphics.scale(2, 2)
-- transformed drawing
love.graphics.pop()

Always balance push with pop. Keep HUD drawing after the world transform has been restored.

Fonts and images

Load resources once:

local font = love.graphics.newFont(24)
local image = love.graphics.newImage("ship.png")

Use them while drawing:

love.graphics.setFont(font)
love.graphics.draw(image, x, y, rotation, scaleX, scaleY)

The image origin defaults to its top-left. To rotate around its center:

love.graphics.draw(
  image,
  x,
  y,
  rotation,
  1,
  1,
  image:getWidth() / 2,
  image:getHeight() / 2
)

Randomness and time

love.math.random()        -- decimal in [0, 1)
love.math.random(1, 6)    -- integer from 1 through 6
love.math.setRandomSeed(12345)

love.timer.getTime()      -- high-resolution seconds
love.timer.getFPS()       -- recent frames per second

Use dt from love.update for simulation. Use getTime for measurement and profiling.

Audio

local pickup = love.audio.newSource("pickup.wav", "static")
local music = love.audio.newSource("music.ogg", "stream")

pickup:stop()
pickup:play()

music:setLooping(true)
music:setVolume(0.6)
music:play()

Use static sources for short effects and streams for long music. Create sources outside the update/draw loop.

Filesystem

LÖVE reads game assets from the source/archive and writes to its save directory.

if love.filesystem.getInfo("save.txt", "file") then
  local text = love.filesystem.read("save.txt")
end

local success, message = love.filesystem.write("save.txt", "42")
print(love.filesystem.getSaveDirectory())

Set a stable t.identity in conf.lua before writing saves.

Application control

love.event.quit()

For version inspection:

local major, minor, revision, codename = love.getVersion()
print(major, minor, revision, codename)

The course targets stable LÖVE 11.5. The official version history records releases and the 11.5 page lists its changes.