plato_demo.lua

------------------------------------------------
-- example using LÖVE (but as a pure Lua library
-- plato can be used with other game engines)
------------------------------------------------

local plato = require("plato")
local strands = require("strands")

-------------------------------------
-- demo dialogue from one of my games
-------------------------------------

-- set environment so that wait functions can be used as global
-- from within the dialogue
plato.set_environment(strands.get_default_environment())

-- functions that we'll define later
local say

-- set a callback so that when selecting an option the player
-- speaks the line, unless otherwise specified
plato.callbacks.select = function(text, extra)
    -- don't speak the line if `true` was passed to the option
    local noecho = extra[1]
    if not noecho then say("ines", text) end
end

local t = {
    main = function()
        if plato.once("first time") then
            return plato.go("intro")
        else
            say("ines", "I'm back.")
            return plato.go("options")
        end
    end,

    intro = function()
        say("ines", "...uncle Lee?")
        say("holeegram", "Young Ines! I haven't seen you in forever!")
        wait(1)
        say("ines", "...what happened to you?")
        say("holeegram", "I'm a HOLEEGRAM!")
        say("ines", "Of course you are.")
        say("ines", "But why? Did something happen to you?")
        say("holeegram", "Not at all, I just wanted to try something new.")
        say("holeegram", "I haven't felt this light since I was 105!")
        say("holeegram", "But enough about me.")
        say("holeegram", "I imagine you got here using my marvellous temporal navigator™.")

        -- pass extra argument to options so the line is not spoken (check intro2 for why)
        plato.option(1, [[I wouldn't call it "marvellous"...]], "intro2", true)
        plato.option(2, "You're lucky I cannot punch you.", "intro2", true)
        plato.option(3, "I'm here because you BUTT-DIALED a time machine.", "intro2", true)
        return plato.selection()
    end,

    intro2 = function()
        -- say this instead of the selected line
        say("ines", "...yes.")
        return plato.go("options")
    end,

    options = function()
        plato.option(1, "How far into the future are we?", function ()
            say("holeegram", "Hundreds of years!")
            return plato.go("options")
        end)
        plato.option_once(2, "fix", "Can you help me get out of this time tunnel?", function()
            say("holeegram", "Time tunnel?")
            say("ines", "You pressed your fancy button and disappeared, leaving me stranded.")
            say("ines", "Does that ring a bell?")
            say("holeegram", "Oh dear.")
            say("holeegram", "You'll have to be more specific.")
            say("holeegram", "I can think of at least five times that happened.")
            wait(1)
            say("ines", "Great.")
            say("ines", "The first one, I guess.")
            say("holeegram", "Ah, the Lake Fenfef trip!")
            say("ines", "Yep.")
            say("holeegram", "We'll need to fix your reality-fixing device™, right?")
            say("ines", "I don't know, YOU tell me.")
            wait(1)
            say("holeegram", "We'll need to fix your reality-fixing device™.")
            say("holeegram", "Put the device in the opening below me, so I can analyse it.")
            return plato.exit()
        end)
        plato.option(2, "What did you need to fix the device?", function()
            say("holeegram", "I need a MAGNET and the COIN from the museum.")
            say("ines", "Got it.")
            return plato.go("options")
        end)
        plato.option(3, "OK, see you later.", function()
            say("holeegram", "Or earlier!")
            return plato.exit()
        end)
        return plato.selection()
    end
}


-- setting up game loop to make things work
-------------------------------------------

-- note: this is not how it works in the actual game,
-- just a quick and dirty way to make things functional

function love.update(dt)
    plato.update(dt)
end

-- extract wait functions so they can be used in other functions
local wait_frame = strands.get_default_environment().wait_frame
local wait = strands.get_default_environment().wait

local current_text
local skip = false
local speed = 15 -- letters per second
say = function(character, text)
    current_text = string.format("%s: %s", character, text)
    local duration = math.max(1.5, #text/speed)

    -- wait duration but allow cutting the wait by setting skip to true
    local t = 0
    while t < duration do
        if skip then break end
        t = t + wait_frame()
    end
    -- clear text once the character has finished speaking
    current_text = nil
    skip = false
    -- wait a bit before next line of dialogue
    wait(.2)
end

function love.draw()
    if current_text then
        love.graphics.print(current_text)
    end

    local choices = plato.get_choices()
    if choices then
        love.graphics.setColor(.5, .5, .5)
        love.graphics.print("Press the number on the keyboard to select the option.", 0, 50)
        love.graphics.setColor(1, 1, 1)
        for i, c in ipairs(choices) do
            love.graphics.print(string.format("%d. %s", i, c), 0, 60 + 15*i)
        end
    else
        love.graphics.setColor(.5, .5, .5)
        love.graphics.print(
            plato.is_running() and "Press . (period) to skip lines." or "Press enter to (re)start the dialogue.",
            0,
            50
        )
        love.graphics.setColor(1, 1, 1)
    end
end

function love.keypressed(key)
    if key == "." and current_text then
        skip = true
        return
    end

    if not plato.is_running() then
        if key == "return" then
            plato.start(t)
        end
    else
        local choices = plato.get_choices()
        if choices then
            for i = 1, #choices do
                if key == tostring(i) or key == "kp" .. i then
                    plato.select(i)
                    return
                end
            end
        end
    end
end
generated by LDoc 1.5.0