[Library] st8.lua

Showcase your libraries, tools and other projects that help your fellow love users.
User avatar
s-ol
Party member
Posts: 1077
Joined: Mon Sep 15, 2014 7:41 pm
Location: Cologne, Germany
Contact:

[Library] st8.lua

Post by s-ol »

St8.lua
A tiny double-stacked state manging library for Lua/LÖVE

Concept
St8 keeps two Stacks of States:

Code: Select all

              Movement  `^` 
            Input State `Isecondary stack`
    Menu  -    Game     `I`  - Pause Menu Overlay 
    `--------------primary stack--------------->`
All States in the currently active Stack will run in parallel (i.e. receive events)

Usage
You can add and remove Stacks (elements on the primary stack) using `pause` and `resume`.
You can add and remove States (elements on the secondary stack) using `push` and `pop`.

All methods accept a variable number of arguments, these arguments will be passed on both to the last State/Stack and the new ones.
`init` and `pause` accept lists or single States as arguments.

Events
St8 covers all of LÖVE's callbacks (as of 0.9.2). Event callback methods receive one additional parameter (as the first one).
This is the return value of the State above the one receiving the event currently; For the topmost State it will always be `nil`.
The return value of the last State of the current Stack will be returned. This happens regardless of whether the LÖVE callback expects a return value and can be used to pass messages between States of a Stack.

View & Star on Github: https://github.com/S0lll0s/st8.lua

tbh I didn't even check if there already is a library with this concept (I'm on a bus and the network is really slow); but I did look for the name and it doesn't seem to be taken.

Feedback ofc appreciated!
Attachments
st8.lua
(4.18 KiB) Downloaded 143 times
st8-example.love
(4.97 KiB) Downloaded 194 times
Last edited by s-ol on Tue Mar 31, 2015 11:42 pm, edited 2 times in total.

s-ol.nu /blog  -  p.s-ol.be /st8.lua  -  g.s-ol.be /gtglg /curcur

Code: Select all

print( type(love) )
if false then
  baby:hurt(me)
end
User avatar
zorg
Party member
Posts: 3441
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: [Library] st8.lua

Post by zorg »

S0lll0s wrote:All States in the currently active Stack will run in parallel (i.e. receive events)
Could you elaborate further? I'm not sure i'm seeing how it could run "in paralell".
S0lll0s wrote:You can add and remove Stacks (elements on the primary stack) using `pause` and `remove`.
"pause"? How does pause mean adding a stack? To me, currently, it seems like a not so good choice, but i may be wrong...
S0lll0s wrote:tbh I didn't even check if there already is a library with this concept
The only one to come to my mind would be vrld's HUMP gamestates, and that is somewhat different.
I'll check this out more from home.
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
User avatar
rmcode
Party member
Posts: 454
Joined: Tue Jul 15, 2014 12:04 pm
Location: Germany
Contact:

Re: [Library] st8.lua

Post by rmcode »

Looks good!
zorg wrote:Could you elaborate further? I'm not sure i'm seeing how it could run "in paralell".
Small example: Imagine you let the player open an inventory or some other menu. You can create a new state (yay for clean code) and push it onto the stack. Now you can render the game state below the menu behind a blur shader (for a cool effect). This way you could pause the actual gameplay but continue to update animations for an even cooler effect.

Or you could reuse the same moving background for multiple different menus.

P.S.: My ScreenManager allows stacking of different states too.
User avatar
s-ol
Party member
Posts: 1077
Joined: Mon Sep 15, 2014 7:41 pm
Location: Cologne, Germany
Contact:

Re: [Library] st8.lua

Post by s-ol »

rmcode got it, I typed this up before he wrote but couldn't post because of bus-internet. Still:
zorg wrote:
S0lll0s wrote:All States in the currently active Stack will run in parallel (i.e. receive events)
Could you elaborate further? I'm not sure i'm seeing how it could run "in paralell".
Basically this allows sub-states (see ASCII-drawing above). All of them receive all events in a selectable order (selectable per event type).

In my current project there is a "game" state that draws and updates the map, and then there are multiple states for different states during each round (its a turn-taking game); things like "move character", "choose attack" etc. While these run, the map still gets updated. Because the callbacks pass a parameter to each other, events can mask each other:

Code: Select all

local specific, general = st8.new(), st8.new()
function specific.keypressed(p, key)
  if key == " " then
    foo()
    return true
  end
end

function general.keypressed(p, key)
  if p then return p end -- p is the true from above
  if key == " " then
    bar()
    st8.push(specific)
  end
end

st8.init(general)
-- space now runs bar() once, then too() every time it is pressed
Note that this behavior is purely cooperative, St8 doesn't enforce anything about 'p'.
zorg wrote:
S0lll0s wrote:You can add and remove Stacks (elements on the primary stack) using `pause` and `remove`.
"pause"? How does pause mean adding a stack? To me, currently, it seems like a not so good choice, but i may be wrong...
The current stack is paused and instead the new one is activated. Afterwards you can resume execution of the paused one. Terminology is a bit confusing here, better ideas welcome :D

s-ol.nu /blog  -  p.s-ol.be /st8.lua  -  g.s-ol.be /gtglg /curcur

Code: Select all

print( type(love) )
if false then
  baby:hurt(me)
end
User avatar
zorg
Party member
Posts: 3441
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: [Library] st8.lua

Post by zorg »

rmcode wrote:Small example: Imagine you let the player open an inventory or some other menu. You can create a new state (yay for clean code) and push it onto the stack. Now you can render the game state below the menu behind a blur shader (for a cool effect). This way you could pause the actual gameplay but continue to update animations for an even cooler effect.
This i do with hump.gs already, though that state manager is more limited than this it seems; but there, i just needed to refer to the state below the current, and call the callbacks of that from the current (topmost) state.
I'm guessing one could do more than just that with this library.
S0lll0s wrote:Basically this allows sub-states (...) All of them receive all events in a selectable order (selectable per event type).
So it's not really paralell, but more like definable-serial? Also, you do this by the "p" parameter in your example? I'd imagine one could do convoluted logic pathways with that like that...

Anyway, i'll try to bend my head around it, maybe i'll get how it works sooner or later :3

Btw, the ASCII drawing on your github made more sense than what's in this thread, at least to me :crazy:
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
User avatar
Jasoco
Inner party member
Posts: 3725
Joined: Mon Jun 22, 2009 9:35 am
Location: Pennsylvania, USA
Contact:

Re: [Library] st8.lua

Post by Jasoco »

This is basically what I do in my own projects. I have a main stack and each state can have its own sub stack if it needs to. And each state can optionally choose to pause both their update and draw callbacks individually. Of course I write it myself. It really is a great idea. Makes doing dialogs and other things so much easier. Each state has a focus and blur callback and I can have the state continue to update in the background but check to make sure it's actually focused in order to do certain things or forego certain things when it's in the background.

I even wrote it so I can unload one state and swap it with another, like for example, unload the title state and switch to the game state, the game state which would then include its own stack for each of the separate game states (Level, map, cutscene) and the main game state would store all the global game related data like score and lives and other stuff so I'm not constantly transferring it between states.

And each state can send arguments into newly pushed states which can then return arguments back into the previous states focus callback. (Like returning whether the user selected Yes or No in a dialog, etc...)

Everyone should use state stack managers in their game. It just makes things so much easier. Combined with animation, tweening and timer libraries and you can do some really good stuff super easily. (At the risk of going off topic I apologize in advance for showing off what I had planned on making a whole topic for months ago. Sorry I'll be ruining the funny visual jokes I sprinkled in.)


Everything is a new state. The inventory is a state. When a confirmation dialog pops up it's another state over that. Everything is a state if it needs to take focus from something else temporarily.

I put way too much work into that inventory system. And it's still not complete.

The reason I named him Jon Snow is because I was going to have it when he first started the game with no spells it would say "Jon Snow knows nothing" in the spells list.
User avatar
ivan
Party member
Posts: 1911
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

Re: [Library] st8.lua

Post by ivan »

Hey, I have something similar in my code,
although I have to point out someting about stacks in general:
when you represent "sub-stacks" as tables then you have
a structure that looks more like a 'tree' rather than a stack.
Tree-like example:

Code: Select all

{
  {
    splash_animation,
    play_sound
  },
  start_game
}
What I mean is, sub-stacks could easily be implemented by
pushing each sub-item on the stack followed by the number of items.
Flat stack example:

Code: Select all

{
  splash_animation,
  play_sound,
  2, -- last two elements are a "sub-stack"
  start_game
}
To pop the sub-stack you can just do something like:

Code: Select all

function pop_substack()
  -- pop the top
  local top = table.remove(stack)
  -- is it a sub-stack?
  if type(top) == "number" then
    -- pop N items
    for i = 1, top do
      pop_substack()
    end
  end
end
User avatar
s-ol
Party member
Posts: 1077
Joined: Mon Sep 15, 2014 7:41 pm
Location: Cologne, Germany
Contact:

Re: [Library] st8.lua

Post by s-ol »

ivan wrote:Hey, I have something similar in my code,
although I have to point out someting about stacks in general:
when you represent "sub-stacks" as tables then you have
a structure that looks more like a 'tree' rather than a stack.
-snip-
Well, it is kinda like a tree, but it has a fixed depth, which makes it very much unlike a tree :D
There only is one primary Stack and it only contains secondary Stacks who in turn only contain Leaves (States).

And why would I come up with such a complicated and weird way to store a tree? I even doubt that it's faster than nesting tables.

s-ol.nu /blog  -  p.s-ol.be /st8.lua  -  g.s-ol.be /gtglg /curcur

Code: Select all

print( type(love) )
if false then
  baby:hurt(me)
end
User avatar
Doctory
Party member
Posts: 441
Joined: Fri Dec 27, 2013 4:53 pm

Re: [Library] st8.lua

Post by Doctory »

@Jasoco (too lazy to quote)
that is so cooool
im gonna go make a small rpg now
User avatar
T-Bone
Inner party member
Posts: 1492
Joined: Thu Jun 09, 2011 9:03 am

Re: [Library] st8.lua

Post by T-Bone »

I don't want to get too off-topic here, but Jasoco, you really need to make a complete game. Your talents are mind-blowing.
Post Reply

Who is online

Users browsing this forum: No registered users and 25 guests