If statement and Goto

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.
User avatar
milon
Party member
Posts: 472
Joined: Thu Jan 18, 2018 9:14 pm

Re: If statement and Goto

Post by milon »

darkfrei wrote: Sun Apr 18, 2021 12:05 pm If I have three states: LevelOne, LevelTwo and Pause, then I need to return from pause to first and second level, isn't that? Or Menu with submenues.
Each level shouldn't need it's own state. The states should be more like MainMenu & PlayingGame, and maybe LevelLoad too. Anything that functions as its own separate screen is a state. Anything that you overlay onto a state (Pause, Player Menu, HUD, etc) can be implemented easier as a push/pop stack. That way you can draw the whole stack if desired - and your Pause menu can still show the game in the background. When you're done with your Pause menu, you pop it off the stack and gameplay naturally resumes and you don't need to track where you came from, etc. The point of using states is that everything naturally flows from one state to the next - as long as you've defined your states well. The same goes for menus, their submenus, etc. I'm still learning this myself, but that's the advice I keep seeing.

As for the levels, I assume you want more than 2 levels total. Your current approach is fine for just 2 levels, but it'll get really cumbersome when you want to move beyond that. I'd suggest something like this:

Code: Select all

-- In MainMenu, when player selects New Game
gameLevel = 1
state = LevelLoad

-- In LevelLoad state
gameLoad(gameLevel)
state = PlayingGame

-- In PlayingGame, when the goal is reached
gameLevel = gameLevel + 1
gameLoad(gameLevel)
Obvious that's not an exact implementation. As I have time, I may expand my original example for my own learning as much as anyone else's.
Any code samples/ideas by me should be considered Public Domain (no attribution needed) license unless otherwise stated.
User avatar
milon
Party member
Posts: 472
Joined: Thu Jan 18, 2018 9:14 pm

Re: If statement and Goto

Post by milon »

Here's a demo of a state machine. The only states are Fail, Load, Menu, Play, and Quit. It will generate an arbitrary number of levels for the player. I threw in a couple fun effects like a fade-to-black transition in the Quit state. Most of the code is well structured (in my opinion, haha) but some of it is poor quality (like my main menu code). It was a really good learning experience for me to put that together!

I haven't implemented the overlays (or whatever a stack of drawable floating menus is called), but the states are the important thing here.

I'm releasing the .love file under CC0 - do whatever you like with it. :)

EDIT - Sorry to whoever downloaded that. Had a line of leftover code in there causing a crash on exit. Whoops! Fixed! :)
Attachments
state.love
Crappy game demonstrating a state machine
(10.37 KiB) Downloaded 215 times
Any code samples/ideas by me should be considered Public Domain (no attribution needed) license unless otherwise stated.
RNavega
Party member
Posts: 235
Joined: Sun Aug 16, 2020 1:28 pm

Re: If statement and Goto

Post by RNavega »

darkfrei wrote: Sun Apr 18, 2021 12:05 pm If I have three states: LevelOne, LevelTwo and Pause, then I need to return from pause to first and second level, isn't that? Or Menu with submenues.
I think there are two ways to approach that. Let's imagine the inconvenient scenario of:

"Your game is being played, then the player hits P for the Pause screen, which is a dark overlay on the game screen with 3 UI buttons -- for unpausing, or going to the main menu or exiting the game. You can still see the game screen underneath, it's just paused, and the background music is still playing but at a lower volume."

If you make the Pause screen a separate state then it needs to know what the gameplay state was rendering, or in other words, it needs access to the renderables so it can continue drawing them just like the gameplay state was drawing them. So there's some data, like a game "context", that is shared between all states. They can know from this context what is being drawn, animated, "sounded" (what audio is playing) etc.
I think this "context" is analogous to the Model part of the Model-View-Controller pattern.

Alternatively, if you introduce a sub-state abstraction (a state within a state), then the Pause screen is but a sub-state within the gameplay state. The Pause sub-state changes how its parent state behaves (pauses itself and draws the extra UI elements), so less information sharing between states is needed, more stuff can be kept private to each state.

I don't know which way is better, open to suggestions. EDIT: or maybe combine the best parts of both methods, shared game context + sub-states for more sophisticated behavior.
User avatar
tomxp411
Prole
Posts: 29
Joined: Thu Apr 08, 2021 5:41 pm

Re: If statement and Goto

Post by tomxp411 »

RNavega wrote: Tue Apr 27, 2021 3:34 pm Alternatively, if you introduce a sub-state abstraction (a state within a state), then the Pause screen is but a sub-state within the gameplay state. The Pause sub-state changes how its parent state behaves (pauses itself and draws the extra UI elements), so less information sharing between states is needed, more stuff can be kept private to each state.
Pause can be another full state, and inside of the Pause :draw() method, it can call the game :draw() to draw the game objects.... but NOT call the game's :update() to update the position of the game objects.

That's obviously not the only way to do it - it's just how I would do it.
User avatar
pgimeno
Party member
Posts: 3541
Joined: Sun Oct 18, 2015 2:58 pm

Re: If statement and Goto

Post by pgimeno »

There are stacked state libraries that call the previous events, see https://love2d.org/forums/viewtopic.php ... 27#p227627

In T2R I chose a simpler approach: always render to a canvas, and have a lower-level "hypervisor" that handles pause and quit. During pause, the canvas is drawn.
RNavega
Party member
Posts: 235
Joined: Sun Aug 16, 2020 1:28 pm

Re: If statement and Goto

Post by RNavega »

tomxp411 wrote: Tue Apr 27, 2021 3:47 pm Pause can be another full state, and inside of the Pause :draw() method, it can call the game :draw() to draw the game objects.... but NOT call the game's :update() to update the position of the game objects.
pgimeno wrote: Tue Apr 27, 2021 6:55 pm There are stacked state libraries that call the previous events, see https://love2d.org/forums/viewtopic.php ... 27#p227627

In T2R I chose a simpler approach: always render to a canvas, and have a lower-level "hypervisor" that handles pause and quit. During pause, the canvas is drawn.
Thanks guys, great info. This made me think some more about the responsibility of each state. You can design your game to put way more importance into the game model (its internal data), and less importance into the states, which can be more generic.

So you don't have a "level 1 state", but rather a "gameplay" state that doesn't know / care about what level is running, it just updates the game based on whatever level data is currently stored in the model. If that data happens to represent level 1 then you'll get level 1, but it could also be data representing level 2, 3 etc. and the gameplay state doesn't care what it is.
The pause state can use that same data to draw the game screen and the pause-screen UI elements, or it can ask whatever state is below it (in case of a stack) to draw the frame so it can draw its own graphics on top.

So each state is more like a tiny engine, processing the data in the game model in its own particular way.

An extreme version of this would be not having any states at all, or rather just a single generic state that executes whatever is in the model. If the model has some UI elements (organized in layers), it will draw them. If it has some autonomous actors (NPCs, enemies etc.), it will update them. But it doesn't really know what's happening.
I think this is closer to what the "Component" pattern proposes: https://gameprogrammingpatterns.com/component.html
User avatar
milon
Party member
Posts: 472
Joined: Thu Jan 18, 2018 9:14 pm

Re: If statement and Goto

Post by milon »

Generic states (instead of "level 1", "level 2", etc) is pretty much what I was talking about and making an example of in my post above. Have a look at the code to see one example of implementation.

My UI elements suck, but the game state design & implementation is pretty solid.
Any code samples/ideas by me should be considered Public Domain (no attribution needed) license unless otherwise stated.
RNavega
Party member
Posts: 235
Joined: Sun Aug 16, 2020 1:28 pm

Re: If statement and Goto

Post by RNavega »

milon wrote: Wed Apr 28, 2021 3:03 pm Generic states (instead of "level 1", "level 2", etc) is pretty much what I was talking about and making an example of in my post above. Have a look at the code to see one example of implementation.

My UI elements suck, but the game state design & implementation is pretty solid.
Wow, you're right! I should've read the older posts, you had said this before:
milon wrote: Mon Apr 19, 2021 6:22 pm The states should be more like MainMenu & PlayingGame, and maybe LevelLoad too. Anything that functions as its own separate screen is a state. Anything that you overlay onto a state (Pause, Player Menu, HUD, etc) can be implemented easier as a push/pop stack. That way you can draw the whole stack if desired - and your Pause menu can still show the game in the background. When you're done with your Pause menu, you pop it off the stack and gameplay naturally resumes and you don't need to track where you came from, etc. The point of using states is that everything naturally flows from one state to the next - as long as you've defined your states well. The same goes for menus, their submenus, etc. I'm still learning this myself, but that's the advice I keep seeing.
The states help you (the dev) organize things into coherent "sections", so we should find a balance between how much the game model/data influences the behavior of the game, and how much the state interpreting that data influences the same.
User avatar
dusoft
Party member
Posts: 482
Joined: Fri Nov 08, 2013 12:07 am
Location: Europe usually
Contact:

Re: If statement and Goto

Post by dusoft »

Xii wrote: Wed Apr 07, 2021 7:09 pm
pgimeno wrote: Wed Apr 07, 2021 4:09 pm it's not how it was designed to be used.
Citation needed.
You can even overload the framework functions, but why would you do that normally (except as a clever way for switching between states)?
Post Reply

Who is online

Users browsing this forum: No registered users and 16 guests