Re: Multiple State Menus?

2020-08-12 Thread AudioGames . net Forum — Developers room : chrisnorman7 via Audiogames-reflector


  


Re: Multiple State Menus?

Hey all,I don't actually have anything useful to say at this point, but I wanted to thank the OP for asking the question, and all the awesome answers, because I'd forgotten about state-driven game development, and that was bad of me.Thanks for making me smart again! 

URL: https://forum.audiogames.net/post/560844/#p560844




-- 
Audiogames-reflector mailing list
Audiogames-reflector@sabahattin-gucukoglu.com
https://sabahattin-gucukoglu.com/cgi-bin/mailman/listinfo/audiogames-reflector


Re: Multiple State Menus?

2020-08-12 Thread AudioGames . net Forum — Developers room : camlorn via Audiogames-reflector


  


Re: Multiple State Menus?

To be honest this thread is now well into the territory of overengineering.  Only have one stack of states, make those states know how to call methods on the player or manipulate the game directly, and call it a day.  If you've understood that much, you know enough.patterns are like a menu at a restaurant.  You pick the ones that help you, and you leave the ones that don't.  This sort of "the game is on top of a stack of states and then routes to the player directly which also has a stack of states which..." thing is really complicated, and unless it's buying you something at the current moment you should leave it and actually code the project.I've seen that book before.  It's aimed at experienced programmers who want to know how to make games.Super advanced input patterns like that which fully separate the input of the simulation from the simulation itself are useful.  You get the ability to abstract over whether something is controlled by AI or the network or the player.  You can pull off tricks like "and now the player controls the spaceship".  But for a basic game it's not needed, it involves rather a lot of moving parts, and I'd suggest only trying it after you've done a completed FPS or something, not now.  You still have trouble with data structures.In Python, circular references are fine.  The game can totally hold a list of players, all of which hold a reference to the game.  The garbage collector will handle it without a problem.  The cyclic references thing is only really painful in languages without a gc, because you then need to think about who frees what when and in what order, things like shared_ptr cannot save you because reference counting schemes can't deal with cycles, and if you get it wrong you crash.  When you see advice about keeping references to stuff in some specific fashion, start by finding out what language they're talking about.There is also a difference between ownership ('the game owns players) and referencing (players have a reference to the game).  What actually matters when you think about this stuff is ownership.  If owned things need references to their owner, that's fine.  The problem doesn't start with cyclic references, it starts when you can't clearly say "A owns B".  This is true even of garbage collected languages, because a lack of clear ownership usually means the inability to figure out what manages what.

URL: https://forum.audiogames.net/post/560704/#p560704




-- 
Audiogames-reflector mailing list
Audiogames-reflector@sabahattin-gucukoglu.com
https://sabahattin-gucukoglu.com/cgi-bin/mailman/listinfo/audiogames-reflector


Re: Multiple State Menus?

2020-08-12 Thread AudioGames . net Forum — Developers room : amerikranian via Audiogames-reflector


  


Re: Multiple State Menus?

To clarify, you suggest either having a class which observes the player, or allow for the player to have some callbacks to check for the necessary environment events?

URL: https://forum.audiogames.net/post/560695/#p560695




-- 
Audiogames-reflector mailing list
Audiogames-reflector@sabahattin-gucukoglu.com
https://sabahattin-gucukoglu.com/cgi-bin/mailman/listinfo/audiogames-reflector


Re: Multiple State Menus?

2020-08-12 Thread AudioGames . net Forum — Developers room : CAE_Jones via Audiogames-reflector


  


Re: Multiple State Menus?

Yeah, I always have game characters keep a reference to the game world, because I try to have the character class handle as much as possible when it comes to its activities and interactions.I also have the game itself keep a reference to the current map, and any recurring maps.I kinda skimmed the talk of the input -> character response connection. Are we talking about binding input to individual menu / player / etc instances? Because that seems kinda sketchy to me. Maybe I'm just too use to the way I primarily do it?Even in a more poll-oriented setup like BGT, or the event queue-but-no-eventHandlers situation with Pygame, I try to turn it into something that looks like Java's KeyAdapter (E.G., send key codes to key_pressed and key_released methods of the game class).Then, after some global hotkey checks (function keys and the like), I run the key codes through whatever I'm using to map keys to commands. It was KeyC, until that got way too confining and I had to switch to that keyconfig class nobody can figure out how to use for some reason, but the important thing is that, if the input is invalid and we are not in a state where arbitrary input is acceptable (entering text or in-game config or whatever), we return right then.Next, I check the game state. At some point, within my first few months of programming, I called this variable "loc", and just stuck with it ever since. These days, I just make an enum of all the "screens" the player could be on (logo / main menu / settings / paused / whatever).Sometimes, there is a feature, like dialog or in-game menus, which can be treated generically and ignore loc. Otherwise, I write code for handling input for each loc, and a default in case the game gets somewhere incomplete (or, like last week, if I copy code from another project and fail change the var names, and wind up in a weird state the game shouldn't ever be in).It's more than possible to save lots of unnecessary code with this style, because menus reliably handle input in a particular way, and all the loc-specific code needs to do is respond to whatever the menu actions change. This can be accomplished via callbacks, but I'm in the habit of just writing it in the code for that particular loc right after the call to the generic menu input method.If in-game menus are going to be a thing, and the generic menu object works fine for that, I either give it its own loc, or include a menu reference (defaulting to null / None), and if that's ever not null, do generic menu input as usual. So too with text scenes. I don't use any classes for those (I've tried it and found it a needless AP drain, but I get why it's a better option for people who actually have enough AP to shrug it off). Instead, Just have a string array, and parse the strings for any special things like playing sound, changing BGM, altering the map, etc. If the array is not empty, then we handle input for scenes.And scenes and in-game menus need to block the game from doing anything, which I usually do by just having the gameStep method return if either of those is the case. This does mean I can't have anything crucial at the end of gameStep. The only crucial things would tend to be updating BGM and updating the network, both of which ought to be handled somewhere earlier on the stack anyway.I did realize, though, after I tried to add online multiplayer on top of code designed with a local player in mind, that my general strategy might not separate input method and the game's response enough. As in, there needs to be a more abstract controller that does not know anything about the keyboard, network, or joysticks, which the keyboard, network and joysticks pass their inputs to via the event handlers. Otherwise, it's very easy to get into a situation where one input method is expected, or overrides the other, or you can only use a joystick if you have one connected, or online players interact with the keyboard in weird ways. In other words, never use if (key_down(KEY_RIGHT)), and never put the code for responding to pressing right in the function that responds to keyboard input. Instead, key_pressed converts KEY_RIGHT to GAME_RIGHT, and you send GAME_RIGHT to game_action.You'd think KeyC / keyconfig would separate input from the keyboard enough, but that only works if the input is being handled in a source-agnostic way, and not in the key_pressed function.TLDR: double-link anything that might need it, if it's not going to lead to infinite recursion. I use the word "generic" too much but "abstract" has a specific meaning that conflicts with how I want to use it here. Maybe "virtual" is the right term?

URL: https://forum.audiogames.net/post/560673/#p560673




-- 
Audiogames-reflector mailing list
Audiogames-reflector@sabahattin-gucukoglu.com
https://sabahattin-gucukoglu.com/cgi-bin/mailman/listinfo/audiogames-reflector


Re: Multiple State Menus?

2020-08-11 Thread AudioGames . net Forum — Developers room : magurp244 via Audiogames-reflector


  


Re: Multiple State Menus?

Objects are not necessarily entirely isolated, since by their very nature they have to interact with other elements of the program. The player class for example may have to be aware of the environment for collision or interaction purposes, or vice versa, the environment being aware of the player for said purposes. While input could be funneled directly to the player class, the player class may in some way still have access to things like menu's or other classes.Part of the stuff I worked on when writing RTS's involved deciding how much information, if any, units would have for rendering or environmental data when pathfinding, or whether that would be handled by a centralized environment or unit handling class that would oversee the units themselves per faction.Given your hypothetical scenario of pressing enter for getting a read on your surroundings, that could be an input element that taps into map data the player class may have access to for collision or ID purposes to display that information, or it could have the player class call a function in your environment class that could ID the player and any nearby objects and dump text about them, or pass the call to an event handler up the chain that can refer it to the environment class.

URL: https://forum.audiogames.net/post/560615/#p560615




-- 
Audiogames-reflector mailing list
Audiogames-reflector@sabahattin-gucukoglu.com
https://sabahattin-gucukoglu.com/cgi-bin/mailman/listinfo/audiogames-reflector


Re: Multiple State Menus?

2020-08-11 Thread AudioGames . net Forum — Developers room : magurp244 via Audiogames-reflector


  


Re: Multiple State Menus?

Objects are not necessarily entirely isolated, since by their very nature they have to interact with other elements of the program. The player class for example may have to be aware of the environment for collision or interaction purposes, or vice versa, the environment being aware of the player for said purposes. While input could be funneled directly to the player class, the player class may in some way still have access to things like menu's or other classes.Part of the stuff I worked on when writing RTS's involved deciding how much information, if any, units would have for rendering or environmental data when pathfinding, or whether that would be handled by a centralized environment or unit handling class that would oversee the units themselves per faction.Given your hypothetical scenario of pressing enter for getting a read on your surroundings, that could be an input element that taps into map data the player class may have access to for collision or ID purposes to display that information, or it could have the player class call a function in your environment class that could ID the player and any nearby objects and dump text about them.

URL: https://forum.audiogames.net/post/560615/#p560615




-- 
Audiogames-reflector mailing list
Audiogames-reflector@sabahattin-gucukoglu.com
https://sabahattin-gucukoglu.com/cgi-bin/mailman/listinfo/audiogames-reflector


Re: Multiple State Menus?

2020-08-11 Thread AudioGames . net Forum — Developers room : amerikranian via Audiogames-reflector


  


Re: Multiple State Menus?

So, another question. This one is caused by a book, game programming patterns to be specific. The chapter in question can be found here.  I am planning to model my test game like this: the main class is a state within itself, having a stack  onto which it is going to push the menus and the game states.  The game is going to be another state class, which will have list of states on its own, in addition to performing necessary checks for objects and the player. Here is the problem: the way the book described it was that player handles their own input.  The game doesn’t care if you press a, your space key, it just passes it on to the player. The player internals pass it along to its current state, be it jumping, ducking, etc.  All good so far.  However, let’s suppose the following scenario: the player has a normal state. During the normal state they can press enter to get a short piece of text describing their surroundings, any objects nearby, passages, etc.  My question is, how? The player has only access to their internals, they do not have access to the map.  The game can’t check for specific input, since then we are coupling what the player can do to the main game class.  I am used to just writing hardwired code in a specific function within the main game to get the players input and respond accordingly, so thinking like this is new for me.  Anyways, back on topic. The book illustrated states accepting a reference to the player class and the current event. This way the states can act upon the player.  While I could apply the same logic to the map in python, or even to the entire game class itself, I do not believe that such approach is correct.  After all, the jumping state doesn’t really care for the list of current objects around the player.  So, the dilemma here is that the player needs access to information which they do not have, and references just don’t seem like the correct solution.  I still am feeling like I am viewing the problem in an incorrect light, and I will drop this if I am encouraged to do so. However, I would like to use this technique as I’ve seen, at least on paper, the elegance of following the pattern. I have tried googling, though most of what I found is a rehash of what I already know. My apologies if I’m missing something blatantly obvious.

URL: https://forum.audiogames.net/post/560614/#p560614




-- 
Audiogames-reflector mailing list
Audiogames-reflector@sabahattin-gucukoglu.com
https://sabahattin-gucukoglu.com/cgi-bin/mailman/listinfo/audiogames-reflector


Re: Multiple State Menus?

2020-08-11 Thread AudioGames . net Forum — Developers room : amerikranian via Audiogames-reflector


  


Re: Multiple State Menus?

So, another question. This one is caused by a book, game programming patterns to be specific. The chapter in question can be found here.  I am planning to model my test game like this: the main class is a state within itself, having a stack  onto which it is going to push the menus and the game states.  The game is going to be another state class, which will have list of states on its own, in addition to performing necessary checks for objects and the player. Here is the problem: the way the book described it was that player handles their own input.  The game doesn’t care if you press a, your space key, it just passes it on to the player. The player internals pass it along to its current state, be it jumping, ducking, etc.  All good so far.  However, let’s suppose the following scenario: the player has a normal state. During the normal state they can press enter to get a short piece of text describing their surroundings, any objects nearby, passages, etc.  My question is, how? The player has only access to their internals, they do not have access to the map.  The game can’t check for specific input, since then we are coupling what the player can do to the main game class.  I am used to just writing hardwired code in a specific function within the main game to get the players input and respond accordingly, so thinking like this is new for me.  Anyways, back on topic. The book illustrated states excepting a reference to the player class and the current event. This way the states can act upon the player.  While I could apply the same logic to the map in python, or even to the entire game class itself, I do not believe that such approach is correct.  After all, the jumping state doesn’t really care for the list of current objects around the player.  So, the dilemma here is that the player needs access to information which they do not have, and references just don’t seem like the correct solution.  I still am feeling like I am viewing the problem in an incorrect light, and I will drop this if I am encouraged to do so. However, I would like to use this technique as I’ve seen, at least on paper, the elegance of following the pattern. I have tried googling, though most of what I found is a rehash of what I already know. My apologies if I’m missing something blatantly obvious.

URL: https://forum.audiogames.net/post/560614/#p560614




-- 
Audiogames-reflector mailing list
Audiogames-reflector@sabahattin-gucukoglu.com
https://sabahattin-gucukoglu.com/cgi-bin/mailman/listinfo/audiogames-reflector


Re: Multiple State Menus?

2020-08-07 Thread AudioGames . net Forum — Developers room : camlorn via Audiogames-reflector


  


Re: Multiple State Menus?

@21yes, along those lines.  Then you define a class Menu which is the same for all menus and which takes choices and callbacks in the constructor, and just make an instance and push it on whenever you need a menu.  Can pass the game into the instance of the menu or capture it in the lambdas for the callbacks or whatever else.The problem you think you have is "How do I make menus" but the problem you actually have is "How do I change what the keyboard input goes to".

URL: https://forum.audiogames.net/post/559314/#p559314




-- 
Audiogames-reflector mailing list
Audiogames-reflector@sabahattin-gucukoglu.com
https://sabahattin-gucukoglu.com/cgi-bin/mailman/listinfo/audiogames-reflector


Re: Multiple State Menus?

2020-08-07 Thread AudioGames . net Forum — Developers room : amerikranian via Audiogames-reflector


  


Re: Multiple State Menus?

So I have one more bit of clarification:@camlorn, you mentioned passing in item handlers to the items when it comes to the menu. Am I correct in the assumption that you had something like this in mind?class Game:

def __init__(self):
self.state_stack = []
#...

def handle_play(self):
"""Assume that this is the handle for the "Start game" function"""
self.pop() #Remove the menu state
self.push_back(mainGameState())If you meant to use this approach, where would one store all the handler functions? In the main app class because it has access to the state stack? It cannot be stored in the main menu state since then we're back to my original problem, being forced to write out each menu as a class with it's own handling methods. From your description in post 18 and from the bit of code you show in post 4, I think this is what you meant.

URL: https://forum.audiogames.net/post/559312/#p559312




-- 
Audiogames-reflector mailing list
Audiogames-reflector@sabahattin-gucukoglu.com
https://sabahattin-gucukoglu.com/cgi-bin/mailman/listinfo/audiogames-reflector


Re: Multiple State Menus?

2020-07-29 Thread AudioGames . net Forum — Developers room : TJ . Breitenfeldt via Audiogames-reflector


  


Re: Multiple State Menus?

I agree with camlorn, I did not really get a good grasp on state machines until recently, and it has driven me nuts, and I did not really feel like I could design a game with out that understanding. That is definitely not true, I just enjoy code design, and a state machine is a excellent way of handling the issue of event handling when working within a single game loop.It sounds like you have the right idea, I recommend looking at the resource I posted in post 13, that is what helped my break through with understanding state machines. As camlorn said, you probably won't use state machines for everything, but they definitely help in the overall working peaces, main menu, options menu maybe, the game etc... and anyone of those states may have their own state machine that it manages, such as a menu. If you use a menu for state machines versus just a list of strings, it allows you to add other types of elements to your menu than just text, such as a toggle button or text box. I set up my menu to take a string or an IState object, and I just created a BasicMenuItem class that takes a string as an argument. This way I can create a menu like normal menu.add("start game")and behind the scenes it is actually just creating a dummy state, passing the text in, and that text is read on focus. I could also say menu.add(ToggleButton())which will ad a toggle button to my menu which is just another state object.

URL: https://forum.audiogames.net/post/556648/#p556648




-- 
Audiogames-reflector mailing list
Audiogames-reflector@sabahattin-gucukoglu.com
https://sabahattin-gucukoglu.com/cgi-bin/mailman/listinfo/audiogames-reflector


Re: Multiple State Menus?

2020-07-28 Thread AudioGames . net Forum — Developers room : amerikranian via Audiogames-reflector


  


Re: Multiple State Menus?

I think I understand it now, it's just going to be a matter of me carrying this over into code. Thank you.

URL: https://forum.audiogames.net/post/556465/#p556465




-- 
Audiogames-reflector mailing list
Audiogames-reflector@sabahattin-gucukoglu.com
https://sabahattin-gucukoglu.com/cgi-bin/mailman/listinfo/audiogames-reflector


Re: Multiple State Menus?

2020-07-28 Thread AudioGames . net Forum — Developers room : camlorn via Audiogames-reflector


  


Re: Multiple State Menus?

@17Almost.  I would say it like this: there is a state machine that is currently active, and any state machine can change the currently active state machine to another one.  Every menu is a state machine.If you do "the currently active state machine" as the top of a stack, every state machine also has the ability to say "go to whatever state machine started me", i.e. menus get back buttons.  If you do it as a single variable, then state machines can only "return" to one hard-coded specific state machine.If you stop reading there, you'll probably be able to make progress.  However:Don't get hung up on state machines.  Think about them as event handlers.  Getting hung up on state machines is a good way to be frustrated for a long time.  What you're actually trying to solve isn't "how do i know which menu is open", it's "How do I send keyboard input to something random that wants the keyboard right now".  That might be a menu, or the main game input handler, or the fishing minigame or whatever, doesn't matter.  I learned this sort of thinking too long ago to know if this makes sense as something you can think about now, or if you're going to have to come back to it in 2 months and go "wow this other problem is like the menu thing, maybe I can solve them both by...".

URL: https://forum.audiogames.net/post/556440/#p556440




-- 
Audiogames-reflector mailing list
Audiogames-reflector@sabahattin-gucukoglu.com
https://sabahattin-gucukoglu.com/cgi-bin/mailman/listinfo/audiogames-reflector


Re: Multiple State Menus?

2020-07-28 Thread AudioGames . net Forum — Developers room : amerikranian via Audiogames-reflector


  


Re: Multiple State Menus?

So an update with a clarification:Menus hold other menus. States hold other states. Is that literally it?If so... yup I feel dumb.

URL: https://forum.audiogames.net/post/556426/#p556426




-- 
Audiogames-reflector mailing list
Audiogames-reflector@sabahattin-gucukoglu.com
https://sabahattin-gucukoglu.com/cgi-bin/mailman/listinfo/audiogames-reflector


Re: Multiple State Menus?

2020-07-28 Thread AudioGames . net Forum — Developers room : camlorn via Audiogames-reflector


  


Re: Multiple State Menus?

@15Immutable.js isn't much better.  While that's not O(n) on copying, it's pointer chasing like you wouldn't believe and rather a large increase in ram usage.  That doesn't matter so much here, but it certainly does matter for JS.Immutable state doesn't help with local reasoning in this instance.  The chain of updates is always the same, and there's not threads, there's not globals involved, etc.  You still have to end up in a debugger stepping through the code or adding prints everywhere or any of a variety of things along those lines.  It doesn't get what you're claiming it gets you when it comes to games.  Other kinds of applications, yes.  Games, no.  If it's one giant set of immutable state, you lose out on local reasoning.  Also most game functions need to modify multiple object so, to get that local reasoning, now they have to return multiple objects too, in some sort of update batch or something.  Then you don't know what's in the batch because you're just doing something like batch.apply() and now, again, you're back to using immutable data structures to implement mutability instead of just using mutability.I feel like you jumped on the functional programming bandwagon and never jumped off.  If this was so good for games, you'd find tons and tons of games using it, but that's not the case.  I can think of lots of places it is good for, there's a reason Elixir is popular, but it's not good for this.With respect to readonly variables to make up for the namedtuples, there's nowhere convenient to put them.  Now you have to maintain an entire separate thing to hold them.  Alternatively you make a class that manages the namedtuple and holds the readonly fields, but at that point you've got a mutable object again that copies all its data internally on every field update instead of just updating the field.Also, stop underestimating performance.  Those copies have to hit an allocator and a deallocator every time (even if it's immutable.js this is true).  Haskell went out  of their way to optimize their GC and compiler to deal with this, as did the Erlang runtime.  Most of the rest of the languages haven't.  Copying that namedtuple will: push the old one to the stack, do a hash to find _replace, push the fields being updated to the stack, call _replace, allocate a new tuple, copy the fields out of the old one,  push the return value to the stack, assign it to your variable, notice that the old one is no longer referenced, then hit an allocator to free it.  If Python's allocator is very good this won't be two kernel syscalls all the time and namedtupls will be implemented in C, but you're still going to be incredibly cache unfriendly, you're still flat out copying large chunks of ram, you're still going through several levels of indirection for *every* field update.  And because this is immutable data structures, you're probably doing that multiple times per object per game update.  It's a good way to start needing multiple gigabytes of ram bandwidth even in C++ where you can pack everything really tightly, and you can only count on 25 GB/s for the entire system put together.There is a reason immutable.js has a "please become temporarily mutable" escape hatch.  The performance hit of writing immutable data structures adds up incredibly quickly, and if you aren't aware of it and thinking about how to avoid all the unnecessary copies it will hurt you very badly.Python is fast enough for audiogames.  Python plus a 10x performance hit because you're trying to use immutable data structures is not.

URL: https://forum.audiogames.net/post/556293/#p556293




-- 
Audiogames-reflector mailing list
Audiogames-reflector@sabahattin-gucukoglu.com
https://sabahattin-gucukoglu.com/cgi-bin/mailman/listinfo/audiogames-reflector


Re: Multiple State Menus?

2020-07-28 Thread AudioGames . net Forum — Developers room : Dragonlee via Audiogames-reflector


  


Re: Multiple State Menus?

@12 I think you are right that for that case you provided a mutable data structure is more convenient than a namedtuple. But the same in case of namedtuple isn't much worse to be considered impractical.About copying most of the world on each state update. I think that would end up being an exageration, because in that tuple for game state you only need to have  fields for the stuff that might actually change and the rest like the map you  just keep as a seperate read only variable.I actually just looked into implementation of namedtuple and it is slightly disappointing. For _replace it does copy all the fields, instead of just internally storing a diffto the base version of the namedtuple. That's how it is implemented in many other libraries, like Record in immutable.js. This does mean _replace is O(n) where n is number of fields instead of being constant.But it is still a shallow copy and at most you are looking at 20-30 fields for the typical audiogame, so it is still so cheap I wouldn't go looking for a better library because of that. But yeah you're right that the more important point is howit is actually used. The thing about forgetting to assign the new copy and having it lost in the ether is a real thing. But in practise I've found it much easier to debug this sort of bug compared to oteher other mutation bugs and that is because of the main advantage of immutable as I see it and that is local reasoning.If it is disappearing and the state doesnt change in an event we expect it to, we know where to look where the event is being handled and spotting the bug is fairly fast and the fix is straight forward.Last point. immutable introduces complexity in some areas like syntax for updating, but I think they take away a lot of complexity in other areas, such as being able to reason locally about state changes. Also immutable can be treated much the same as primitives which is to say as values instead of references. So, in many ways I think they simplify things for beginners.Anyway, I think you do bring up a lot of good points and I don't really want to derail this thread much more. I just wanted to point out that immutable should be seriously considered even for games as I think it has much to offer.

URL: https://forum.audiogames.net/post/556219/#p556219




-- 
Audiogames-reflector mailing list
Audiogames-reflector@sabahattin-gucukoglu.com
https://sabahattin-gucukoglu.com/cgi-bin/mailman/listinfo/audiogames-reflector


Re: Multiple State Menus?

2020-07-27 Thread AudioGames . net Forum — Developers room : amerikranian via Audiogames-reflector


  


Re: Multiple State Menus?

Thank you all for the responses. I will post on this again if something seems unclear after I had time to process it

URL: https://forum.audiogames.net/post/556184/#p556184




-- 
Audiogames-reflector mailing list
Audiogames-reflector@sabahattin-gucukoglu.com
https://sabahattin-gucukoglu.com/cgi-bin/mailman/listinfo/audiogames-reflector


Re: Multiple State Menus?

2020-07-27 Thread AudioGames . net Forum — Developers room : TJ . Breitenfeldt via Audiogames-reflector


  


Re: Multiple State Menus?

Hi, this is the implementation I am using for my state machine. I am using this for python, but it does not have to be.I took my implementation of my state machine from here:http://howtomakeanrpg.com/a/state-machines.htmlIt is still a bit of a work in progress as I continue working on my environment, but this has been working great for me so far.I modified it a bit, but it is the same idea, here is my implementation:here is my state.py from abc import ABC, abstractmethodfrom typing import Callablefrom pygame.event import Eventclass IState(ABC):    @abstractmethod    def setup(self, *args, **kwargs) -> bool:        """This method is called once when the state changes to initialize the  state before the state starts running. False is returned if this state can not be entered."""    @abstractmethod    def update(self, delta_time: float) -> bool:        """This gets called every frame when the state is active, used to update the innerworkings of the state. This method also returns a boolean to signify it is time to shutdown the system if False."""    @abstractmethod    def handle_input(self, event: Event, change_state: Callable[[str, any], None]) -> bool:        """This gets called every frame when the state is active, checking for keyboard input, and switching states as needed. True is returned if the event has been handled, false if not."""    @abstractmethod    def exit(self) -> bool:        """This method is called once when the state changes, just before the new state is initialized, before the state switch. False is returned if this state cannot be exited."""Here is my state_machine.py it includes an empty state class, which is just a filler to act as a default state to avoid some conditional complexityfrom typing import Callablefrom pygame.event import Eventfrom state import IStateclass EmptyState(IState):    def setup(self) -> bool:        return True    def update(self, delta_time: float) -> bool:        return True    def handle_input(self, event: Event, change_state: Callable[[str, any], None]) -> bool:        return True    def exit(self) -> bool:        return Truefrom typing import Dictfrom pygame.event import Eventfrom state import IStatefrom empty_state import EmptyStateclass StateMachine:    def __init__(self) -> None:        self.states: Dict[str, IState] = {}        self.current_state: IState = EmptyState()    def add(self, key: str, state: IState) -> None:        self.states[key] = state    def remove(self, key: str) -> None:        del self.states[key]    def clear(self) -> None:        self.states.clear()    def change(self, key: str, *args: any, **kwargs: any) -> None:        if self.current_state.exit():            next_state: IState = self.states[key]            if next_state.setup(*args, **kwargs):                self.current_state = next_state    def update(self, delta_time: float) -> bool:        return self.current_state.update(delta_time)    def handle_input(self, event: Event) -> bool:        return self.current_state.handle_input(event, self.change)And here is an example of my main loop using this state machineI have a helper module I am using to wrap my input handling to make some things easier to deal with.import pygamefrom pygame import Surfacefrom pygame.time import Clockfrom state_machine import StateMachinefrom utils import input_managerfrom ui import MainMenuWINDOW_TITLE: str = "My Game"WIDTH: int = 360HEIGHT: int = 480FRAMES_PER_SECOND: int = 30pygame.init()pygame.mixer.init()screen: Surface = pygame.display.set_mode((WIDTH, HEIGHT))pygame.display.set_caption(WINDOW_TITLE)clock: Clock = pygame.time.Clock()def main() -> None:    state_machine: StateMachine = StateMachine()    setup(state_machine)    run_main_loop(state_machine)    pygame.quit()def setup(state_machine: StateMachine) -> None:    input_manager.set_key_repeat()    audio_manager.auto_load_sounds()    state_machine.add("main_menu", MainMenu())    state_machine.change("main_menu")def run_main_loop(state_machine: StateMachine) -> None:    is_running: bool = True    while is_running:        milliseconds: float = clock.tick(FRAMES_PER_SECOND)        is_running = state_machine.update(milliseconds)        for event in pygame.event.get():            if event.type == pygame.QUIT:                is_running = False            elif input_manager.is_key_pressed(event, pygame.K_w) and input_manager.is_modifier_pressed(pygame.KMOD_CTRL):                is_running = False            elif input_manager.is_key_pressed(event, pygame.K_F4) and input_manager.is_modifier_pressed(pygame.KMOD_ALT):                is_running = False            if input_manager.is_key_pressed(event) or input_manager.is_key_released(event):                state_machine.handle_input(event)        pygame.time.wait

Re: Multiple State Menus?

2020-07-27 Thread AudioGames . net Forum — Developers room : camlorn via Audiogames-reflector


  


Re: Multiple State Menus?

The only way to make a game work on top of namedtuples is to copy most to all of the world on every update.  This is slow enough that I would hesitate slightly to do it in C++, and very much more in Python.  You're right that _replace exists, but that's still less ergonomic than enemy.x += 5, and more to the point you have two choices, neither of which is pretty:You can use a dict that holds objects by id,and update the objects there, which means that everything everywhere has to remember to go through the dict and put the updates in the right place.You can have everything return copies, and remember to always assign the copy to the old field (and if you don't, the update will silently vanish into the ether, never to be seen again).If I do enemy.x += 5, it always clearly updates.  But in either of the above cases you have to remember to do an extra thing to not drop updates.  This isn't convenient.  There's a reason that people don't generally let immutable data structures invade their entire app.  The gains w.r.t. threading/concurrency don't apply to this discussion, the gains w.r.t. comparison only apply if the language isn't doing a by-value comparison anyway, and the loss is that unless you use it perfectly all the time your updates just mysteriously don't happen and there's no way to find out where.  If Python had an equivalent of Rust's ability to warn if you disregard a return value this might be a different discussion, but namedtuples introduce complexity for no gain, *especially* for someone who's at this level of development.By all means use them somewhere, and menu entries are a good place, but not for every game entity.

URL: https://forum.audiogames.net/post/556053/#p556053




-- 
Audiogames-reflector mailing list
Audiogames-reflector@sabahattin-gucukoglu.com
https://sabahattin-gucukoglu.com/cgi-bin/mailman/listinfo/audiogames-reflector


Re: Multiple State Menus?

2020-07-27 Thread AudioGames . net Forum — Developers room : Dragonlee via Audiogames-reflector


  


Re: Multiple State Menus?

@10 namedtuples are actually very convenient and ergonomic. If you want to create a new namedtuple that just has a subset of fields different from another namedtuple, you can use the _replace method like this:GameState =namedtuple('GameState', ['hp', 'etc'])first = GameState(hp = 100, etc = "...")second = first._replace(hp = first.hp - 1) first.hp == second.hp # False first.etc == second.etc # Truenamedtuples dont have per-instance dictionaries so they take up as much space as a tuple.I haven't actually been able to find a performance breakdown specifically for using it for state, just for creation and member access... but if they are implemented similarly to other immutable record types like in many other languages then the extra cost is very negligible save for instances where nano seconds per iteration loop matter.But the performance argument is still kind of moot in my opinion, since if the kind of performance gain from using a mutable data structure over a namedtuple really mattered, then you would either have to use a specialized library or something other than python anyway.

URL: https://forum.audiogames.net/post/556047/#p556047




-- 
Audiogames-reflector mailing list
Audiogames-reflector@sabahattin-gucukoglu.com
https://sabahattin-gucukoglu.com/cgi-bin/mailman/listinfo/audiogames-reflector


Re: Multiple State Menus?

2020-07-27 Thread AudioGames . net Forum — Developers room : camlorn via Audiogames-reflector


  


Re: Multiple State Menus?

@9Convenience and ergonomics matter.  Namedtuples aren't super convenient if you're going to change a bunch of fields all the time.  Also, the performance penalty is probably higher than you're giving it credit for, though I haven't specifically benchmarked it.Immutable data structures have lots of advantages, but not so much in games, and you really need a good library for it for anything complicated.For entries in a menu they're fine, but I wouldn't suggest that people go doing their entire game that way, and that's what that post was about.

URL: https://forum.audiogames.net/post/556023/#p556023




-- 
Audiogames-reflector mailing list
Audiogames-reflector@sabahattin-gucukoglu.com
https://sabahattin-gucukoglu.com/cgi-bin/mailman/listinfo/audiogames-reflector


Re: Multiple State Menus?

2020-07-27 Thread AudioGames . net Forum — Developers room : Dragonlee via Audiogames-reflector


  


Re: Multiple State Menus?

@6 just a small note. not sure why namedtuples being immutable means they dont apply. for me, namedtuples are really the best go to for defining composite data types, not just for less boiler plate but also specifically for their immutability. Immutable data structures are much better for handling state because they make it possible to just reason about code locally and not have to worry about spooky mutation at a distance.there is always the argument of performance, but truth is that the extra cost is negligible and only really matters in a scenario where there is super high frequency mutation of state. in which case you can do local mutation that doesn't leak into the outer context. if a tree fall in the woods and noone hears it, does it really make a sound, am I right?

URL: https://forum.audiogames.net/post/556021/#p556021




-- 
Audiogames-reflector mailing list
Audiogames-reflector@sabahattin-gucukoglu.com
https://sabahattin-gucukoglu.com/cgi-bin/mailman/listinfo/audiogames-reflector


Re: Multiple State Menus?

2020-07-27 Thread AudioGames . net Forum — Developers room : chrisnorman7 via Audiogames-reflector


  


Re: Multiple State Menus?

OK, so I copied this menu implementation from my Earwax project, which probably does all the menu stuff you want, assuming you're happy to use Pyglet.I removed all of the imports, since they will probably just confuse the issue.@attrs(auto_attribs=True)
class MenuItem:
"""An item in a menu."""

# The title of this menu item.
title: str

# The function which will be called when this item is activated.
func: 'ActionFunctionType'

# The function which will be called when this item is selected.
on_selected: Optional[Callable[[], None]] = Factory(lambda: None)


@attrs(auto_attribs=True)
class Menu:
"""A menu which holds multiple menu items which can be activated using
actions."""

# The title of this menu.
title: str

# Whether or not it should be possible to dismiss this menu.
dismissible: bool = Factory(lambda: True)

# The player's position in this menu.
position: int = Factory(lambda: -1)

# The list of MenuItem instances for this menu.
items: List[MenuItem] = attrib(default=Factory(list), init=False)

@property
def current_item(self) -> Optional[MenuItem]:
"""Return the currently selected menu item. If position is -1, return
None."""
if self.position != -1:
return self.items[self.position]
return None

def add_item(
self, title: str, func: 'ActionFunctionType', **kwargs
) -> MenuItem:
"""Add an item to this menu. All arguments are passed to the
constructor of MenuItem."""
mi: MenuItem = MenuItem(title, func, **kwargs)
self.items.append(mi)
return mi

def show_selection(self) -> None:
"""Speak the menu item at the current position, or the title of this
menu, if position is -1.

This function performs no error checking, so it will happily throw
errors if self.position is something stupid."""
item: Optional[MenuItem] = self.current_item
if item is None:
tts.speak(self.title)
else:
tts.speak(item.title)
if item.on_selected is not None:
item.on_selected()

def move_up(self) -> None:
"""Move up in this menu."""
self.position = max(-1, self.position - 1)
self.show_selection()

def move_down(self) -> None:
"""Move down in this menu."""
self.position = min(len(self.items) - 1, self.position + 1)
self.show_selection()

def activate(self) -> OptionalGenerator:
"""Activate the currently focused menu item."""
if self.current_item is None:
return None
return self.current_item.func()There's a Window class, which has push_menu (for pushing a menu onto the stack), pop_menu (for popping a menu of fthe stack), replace_menu (for replacing the most recent menu with the one you supply), and clear_menus (for removing all menus).You can have extra functions run when you move over the items, in case you want to play sounds or something. There's also default hotkeys for moving through menus, activating items, and escaping from the menu, assuming that menu.dismissible evaluates to True.Hope this helps somewhat.

URL: https://forum.audiogames.net/post/555985/#p555985




-- 
Audiogames-reflector mailing list
Audiogames-reflector@sabahattin-gucukoglu.com
https://sabahattin-gucukoglu.com/cgi-bin/mailman/listinfo/audiogames-reflector


Re: Multiple State Menus?

2020-07-26 Thread AudioGames . net Forum — Developers room : kjsisco via Audiogames-reflector


  


Re: Multiple State Menus?

Okay I understand.

URL: https://forum.audiogames.net/post/555879/#p555879




-- 
Audiogames-reflector mailing list
Audiogames-reflector@sabahattin-gucukoglu.com
https://sabahattin-gucukoglu.com/cgi-bin/mailman/listinfo/audiogames-reflector


Re: Multiple State Menus?

2020-07-26 Thread AudioGames . net Forum — Developers room : camlorn via Audiogames-reflector


  


Re: Multiple State Menus?

@5Kind of.  In the sense of object oriented programming, sometimes, depending what you're doing.  For example RPGs often map well to that model.But you don't have to use classes because you're thinking in object oriented programming.  They're also just convenient if you need some collection of event handlers or something and 90% of them are going to be defaults, which is what we're using them for here.  In practice you can wrap these classes in a show_menu(choices) function that takes the choices, handles pushing and popping from the stack, etc. and not have to know that the object even exists as a concrete class.Think of them like, I dunno, modules that can be instantiated.  Or bags where we just throw all the menu/input handling stuff.  No one is proposing that the entire game be object oriented or anything right now.But all that said, for most things people here do, classes are very much the right tool for the job because the alternative is tons of globals everywhere, and things like entity component systems are really only beneficial once you know enough that you're the one answering the questions instead of asking them and only really matter if you're trying to draw graphics for a complex 3D game.  If you have a game that has objects, i.e. enemies, swords, etc., making them classes that inherit from something that knows how to interact with physics will get you very far.But also this is Python and in Python classes are the closest thing to structs unless you deal with namedtuples, and since namedtuples are immutable they're not generally applicable.

URL: https://forum.audiogames.net/post/555783/#p555783




-- 
Audiogames-reflector mailing list
Audiogames-reflector@sabahattin-gucukoglu.com
https://sabahattin-gucukoglu.com/cgi-bin/mailman/listinfo/audiogames-reflector


Re: Multiple State Menus?

2020-07-26 Thread AudioGames . net Forum — Developers room : kjsisco via Audiogames-reflector


  


Re: Multiple State Menus?

I am a bit new to game development but I've been writing software for a while and I can't help but think that the methods put forth are to object-heavy.  Is this common in creating games?

URL: https://forum.audiogames.net/post/555779/#p555779




-- 
Audiogames-reflector mailing list
Audiogames-reflector@sabahattin-gucukoglu.com
https://sabahattin-gucukoglu.com/cgi-bin/mailman/listinfo/audiogames-reflector


Re: Multiple State Menus?

2020-07-26 Thread AudioGames . net Forum — Developers room : camlorn via Audiogames-reflector


  


Re: Multiple State Menus?

But the key insight that I think Amerikranian is missing is that things are much easier if it's not a finite state machine.  Model your game as a stack of input handlers:class InputHandler:
def on_input(event):
pass

def on_active(self):
pass

def on_inactive(self):
passWhere on_active is called when it's pushed onto the stack, and on_inactive is called when it's popped from the stack *or* when it's no longer the top.  You can break these callbacks up any way you want, i.e. have dedicated ones for not the top and not on the stack, etc etc etc.  When the game starts push the main menu, when the player selects play pop it and push the main game state, when menus open push the menu, when the player goes back pop the top of the stack.  You can implement this as a Python list with .append and .pop, and the top of the stack is always stack[-1] because in Python negative indices let you index from the end of the list.The menu itself becomes a class that inherits InputHandler, and takes a list inn the constructor of this form:[
("item 1", item_1_handler),
("item 2", item_2_handler(),
   # etc
]Where the handlers are callback functions, that take whatever arguments you want to give them.  For stuff like inventories, build the list dynamically.This will get you pretty far, and for specialized stuff you can write specialized classes.  But the main point is finite state machines aren't for everything.

URL: https://forum.audiogames.net/post/555777/#p555777




-- 
Audiogames-reflector mailing list
Audiogames-reflector@sabahattin-gucukoglu.com
https://sabahattin-gucukoglu.com/cgi-bin/mailman/listinfo/audiogames-reflector


Re: Multiple State Menus?

2020-07-26 Thread AudioGames . net Forum — Developers room : CAE_Jones via Audiogames-reflector


  


Re: Multiple State Menus?

I'm confused. Why not just have a standardized menu class, and make all the menus instances of that class? Generally, menus have two types of items in them: things you activate, and things with adjustable values. There are several ways to handle that, but I'm still using my solution from the ancient times of 2008 (unless I made that earlier and forgot? ... Yeah, actually; I made that in 2007 for a CS assignment, then ported it to BGT and Python after catching a few vulnerabilities to NPE and IooBE that made it past the instructor.)Since every game needs unique menus (mostly; I just copy the same voice options for everything), I don't bother with a factory class or functions, and just initialize everything in one big block when starting the program. However, I can definitely see situations where you'd need to generate menus on the fly, so of course you'd want additional methods / functions / if you're feeling really crazy, classes to account for those. Come to think of it, I did do something like that for in-game movelists in ECTAS.

URL: https://forum.audiogames.net/post/555758/#p555758




-- 
Audiogames-reflector mailing list
Audiogames-reflector@sabahattin-gucukoglu.com
https://sabahattin-gucukoglu.com/cgi-bin/mailman/listinfo/audiogames-reflector


Re: Multiple State Menus?

2020-07-26 Thread AudioGames . net Forum — Developers room : philip_bennefall via Audiogames-reflector


  


Re: Multiple State Menus?

I had to implement something similar a little while ago. I did it in C++ so I'm not sure how it translates to Python, but I had a generic menu class and a factory. The factory would populate the menu with its options, and would use function objects (usually created via lambdas) to store the action that should be performed for each option. So the menu state would go on top of the stack of states in the engine, and would automatically add the appropriate state to the stack when the user made a choice.So in summary you have a generic menu class that remembers its options and their resulting states via std function objects that are assigned at construction time.There are definitely other methods to solve the same problem and I'm sure there are better solutions than the one I went with, but I figured I'd share it anyway in case it helps some.Kind regards,Philip Bennefall

URL: https://forum.audiogames.net/post/555750/#p555750




-- 
Audiogames-reflector mailing list
Audiogames-reflector@sabahattin-gucukoglu.com
https://sabahattin-gucukoglu.com/cgi-bin/mailman/listinfo/audiogames-reflector


Multiple State Menus?

2020-07-26 Thread AudioGames . net Forum — Developers room : amerikranian via Audiogames-reflector


  


Multiple State Menus?

So as I have been working more with states, one question arose. Right now, I have to create individual classes for pretty much everything. Pause menu, main menu, options menu, etc. My question is... can I generalize those states and make them all fall into a category of one menu state?Right now, my implementation is akin to something like this:class BaseMenu:
#...
def process_choice(self):
passThe main menu could look something like this:class MainMenu(BaseMenu):
#...
def process_choice(self):
if self.choice == 0:
self.next_state = STATE_PLAYING
#other choices go belowThe disadvantage to this approach is that I have to create classes for all the menus currently in my application. The only thing that changes here is the process_choice logic, so I wonder if I could simplify this?Thinking a bit more on the idea yields me a dictionary with a choice as it's key and state as it's value, i.e:{
0: STATE_PLAYING,
1: STATE_OPTIONS_MENU,
#...
}While that approach is okay, I wonder if there is a better way of doing this.Passing a callback would centralize the logic into one class, i.e:class MenuDecisions:
def resolve_main_menu(self, choice):
if self.choice == 0:
self.next_state = STATE_PLAYING
#other choices go belowIt will not get rid of the overarching problem of having specific states for every single thing, however.One other piece information I think is important to the question:The states are stored within a master list in my main application class. I considered giving the menu a reference to the states, except that does not really solve my issue. I would still be forced to somehow alert the menu of the results of user decision.Edited, fixed one of the code examples to demonstrate inheritance, realized that I failed to point it out.

URL: https://forum.audiogames.net/post/555740/#p555740




-- 
Audiogames-reflector mailing list
Audiogames-reflector@sabahattin-gucukoglu.com
https://sabahattin-gucukoglu.com/cgi-bin/mailman/listinfo/audiogames-reflector


Multiple State Menus?

2020-07-26 Thread AudioGames . net Forum — Developers room : amerikranian via Audiogames-reflector


  


Multiple State Menus?

So as I have been working more with states, one question arose. Right now, I have to create individual classes for pretty much everything. Pause menu, main menu, options menu, etc. My question is... can I generalize those states and make them all fall into a category of one menu state?Right now, my implementation is akin to something like this:class BaseMenu:
#...
def process_choice(self):
passThe main menu could look something like this:class MainMenu:
#...
def process_choice(self):
if self.choice == 0:
self.next_state = STATE_PLAYING
#other choices go belowThe disadvantage to this approach is that I have to create classes for all the menus currently in my application. The only thing that changes here is the process_choice logic, so I wonder if I could simplify this?Thinking a bit more on the idea yields me a dictionary with a choice as it's key and state as it's value, i.e:{
0: STATE_PLAYING,
1: STATE_OPTIONS_MENU,
#...
}While that approach is okay, I wonder if there is a better way of doing this.Passing a callback would centralize the logic into one class, i.e:class MenuDecisions:
def resolve_main_menu(self, choice):
if self.choice == 0:
self.next_state = STATE_PLAYING
#other choices go belowIt will not get rid of the overarching problem of having specific states for every single thing, however.One other piece information I think is important to the question:The states are stored within a master list in my main application class. I considered giving the menu a reference to the states, except that does not really solve my issue. I would still be forced to somehow alert the menu of the results of user decision.

URL: https://forum.audiogames.net/post/555740/#p555740




-- 
Audiogames-reflector mailing list
Audiogames-reflector@sabahattin-gucukoglu.com
https://sabahattin-gucukoglu.com/cgi-bin/mailman/listinfo/audiogames-reflector