I want to make my own gamestate library.

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
User avatar
Tesselode
Party member
Posts: 555
Joined: Fri Jul 23, 2010 7:55 pm

I want to make my own gamestate library.

Post by Tesselode »

I want to have a gamestate library that works like this:

Code: Select all

state = gamestate.new()

function state:load()
end

function state:update(dt)
end
The problem is I'm not sure how to link the gamestate functions to the love callbacks. I know it has something to do with metatables, but how exactly do you detect when a callback function is called?
SudoCode
Citizen
Posts: 61
Joined: Fri May 04, 2012 7:05 pm

Re: I want to make my own gamestate library.

Post by SudoCode »

You could probably get a good idea by looking through the existing gamestate libs. hump, maybe.
User avatar
Inny
Party member
Posts: 652
Joined: Fri Jan 30, 2009 3:41 am
Location: New York

Re: I want to make my own gamestate library.

Post by Inny »

The trick to "States" is the "StateMachine" that drives the states. In short, you have to have the lua callbacks call into the state machine. Here's a short example:

Code: Select all

GameState = {}
function GameState:update(dt) end

Statemachine = { current=GameState }
function Statemachine:update(dt)
  self.current:update(dt)
end

function love.update(dt)
  Statemachine:update(dt)
end
In my own personal projects, I like having the StateMachine be a stack/queue combination, meaning that I can ready a state that will start on the next update cycle, and then the states can send updates via the statemachine to each other. In practice, it means I can still have the GameState draw, even though the OptionsMenuState is at the top of the stack.
User avatar
IMP1
Prole
Posts: 43
Joined: Mon Oct 03, 2011 8:46 pm

Re: I want to make my own gamestate library.

Post by IMP1 »

The way I do it is this:

In another file, have your state:

Code: Select all

local state = {}
state.__index = state

function state.load()
    local this = {}
    setmetatable(this, state)
    -- this is the basic table that represents the state
    -- so initial values for properties of the state would be set here
    return this
end

function state:update(dt)
    -- update state here
end

function state:draw()
    -- draw state here
end

-- any other functions

return state
And in your main.love you'd have this:

Code: Select all

gamestate = require("path.to.your.state")
function love.load()
    state = gamestate.new()
end
-- etc. with update.
User avatar
Tesselode
Party member
Posts: 555
Joined: Fri Jul 23, 2010 7:55 pm

Re: I want to make my own gamestate library.

Post by Tesselode »

So far all of the suggestions require that you manually call functions for the current state in each callback. Is there a way I can automatically have it do:

Code: Select all

function love.load()
  current_state.load(dt)
end

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

etc...
I know hump.gamestate does this with the registerEvents function, I'm just not sure how.

Edit: If I am reading the hump.gamestate code correctly, this is where all the magic happens:

Code: Select all

for _, f in ipairs(callbacks) do
  love[f] = function(...) GS[f](...) end
end
User avatar
Kadoba
Party member
Posts: 399
Joined: Mon Jan 10, 2011 8:25 am
Location: Oklahoma

Re: I want to make my own gamestate library.

Post by Kadoba »

Basically it's just a shortcut for exactly what you were doing.

Code: Select all

function love.load()
  current_state.load(dt)
end

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

function love.draw()
  current_state.draw()
end

-- Same as above
local callbacks = {"load", "update", "draw"}
for k,v in pairs(calllbacks) do
   love[v] = function(...)
      if current_state[v] then current_state[v](...) end
   end
end
User avatar
Inny
Party member
Posts: 652
Joined: Fri Jan 30, 2009 3:41 am
Location: New York

Re: I want to make my own gamestate library.

Post by Inny »

It's more or less the norm to expect love.update call your library's update function. Love has no way to automatically register an event handler other than overwriting love.update.

For fun, you could have a function, or table with a __call or __index metatable, that does some basic routing of messages.

Code: Select all

Statemachine = setmetatable({}, {
  __index = function(self, message)
    if not self[message] then
      self[message] = function(...)
        current_state[message](...)
      end
    end
    return self[message]
  end
})
With this, it'll automatically generate the update, draw, keypressed, and so on event handlers as you need them. But I consider it a toy rather than something to base a library on.
Post Reply

Who is online

Users browsing this forum: Google [Bot] and 80 guests