Lua Scripting for RetroChallenges

Create custom challenges and track game progress with Lua scripts. Learn how to write scripts that automatically detect achievements and challenge completions.

📝

Getting Started with Lua Scripts

Lua scripts in RetroChallenges allow you to create custom challenges and automatically track game progress. These scripts run alongside your games and can detect specific conditions to trigger challenge completions.

Basic Script Structure

-- Example: Track lives in a platformer game
local function checkLives()
    local lives = memory.readbyte(0x075A) -- Memory address for lives
    if lives >= 5 then
        -- Challenge completed!
        local data = {
            username = "player",
            game = "Platform Game",
            challengeName = "Collect 5 Extra Lives",
            date = os.date("!%Y-%m-%dT%H:%M:%SZ")
        }
        -- Write completion data
        writeChallengeData(data)
    end
end

-- Run check every frame
while true do
    checkLives()
    emu.frameadvance()
end

Memory Reading Functions

RetroChallenges provides several functions to read game memory:

  • memory.readbyte(address) - Read a single byte
  • memory.readword(address) - Read a 16-bit word
  • memory.readdword(address) - Read a 32-bit double word
  • memory.readfloat(address) - Read a floating point number

Challenge Data Structure

When a challenge is completed, you should write data in this format:

{
    username = "player_name",
    game = "Game Title",
    challengeName = "Challenge Description",
    date = "2024-01-01T12:00:00Z",
    score = 1000, -- Optional
    time = 120.5 -- Optional (seconds)
}

Example: Score Tracking

-- Track high score achievement
local highScore = 0
local targetScore = 10000

local function checkScore()
    local currentScore = memory.readdword(0x075E) -- Score memory address
    
    if currentScore > highScore then
        highScore = currentScore
    end
    
    if highScore >= targetScore then
        local data = {
            username = "player",
            game = "Action Game",
            challengeName = "Reach 10,000 Points",
            score = highScore,
            date = os.date("!%Y-%m-%dT%H:%M:%SZ")
        }
        writeChallengeData(data)
        -- Stop checking after completion
        return true
    end
    return false
end

Tips for Writing Scripts

  • Always use emu.frameadvance() in your main loop
  • Test memory addresses thoroughly before finalizing
  • Include error handling for invalid memory reads
  • Use descriptive variable names
  • Comment your code for future reference