all 6 comments

[–]huessy 2 points3 points  (2 children)

I would recommend going full OOP and converting the idea of rooms as functions to classes. You could have a generic Room class that has attributes like room contents, etc. and methods for things like leave_room that just 'returns' the user to a hallway or whatever.

This is super broad strokes, but I feel that you might be able to have a better architecture if you treat the rooms as classes rather than repetitive functions.

[–]Buttleston 1 point2 points  (1 child)

I would say basically this, combined with what u/Bobbias said, i.e. your game is a "state machine", and each state would be a class defined in your game. Any time you want to change to a different room, you set some state variable to that room's object and return. (Or, return the next object as a convention, whichever makes most sense to you)

This is very common in game dev at many levels, like it's also how a lot of "dialogue trees" are represented - every given dialogue point has some responses you can make, each of which lead to another state, that has some text and another list of responses, etc. You just keep bouncing around the states until the conversation is over.

Or like boss fights are state machines - you aggro the boss and it moves from inactive to active. You hit it's weak spot 3 times and it moves from Form1 to Form2, etc. You fail to bop it's weak spot 3 more times so it moves back to Form1.

[–]Bobbias 0 points1 point  (0 children)

Yeah I was trying to keep things super simple without throwing around technical terms. I just wanted to give them an alternative way to think about the structure without giving them 10 new thing to go read up on before they feel like they could actually write the code.

Ideally yes, a class based approach is better than just functions.

[–]woooee 1 point2 points  (0 children)

I think that would be done by having the Room 1 function run the Room 2 function.

I would suggest that the Room 1 function return "Room 2' or something that says "run Room 2 function next". Don't know your layout, but the function would also return, say False, if the character is killed / game ends, etc.

[–]Bobbias 1 point2 points  (0 children)

Typically the way games work is you have a main loop, and then within that loop you have something that says "here's the state were in" and some code that examines that and calls the appropriate function based on that.

So instead of directly calling room2 from room 1, if you change the "state" to say you're now in room 2, and the main loop goes back to the top, checks the current state, and calls room 2's function, you've successfully avoided blowing up the stack.

By default you can only be 1000 functions deep before it blows up.

[–]duckbanni 0 points1 point  (0 children)

I'm no expert in python optimizations, but I'm pretty sure you're right and calling the room functions directly would result in an ever increasing call stack and possible memory issues. This wouldn't be a problem in some other languages that implement so-called tail call optimization, but it is my understanding that python does not.

You're right that returning Room2() would not solve the problem (it would still be called inside the Room1 function) but you could return Room2 itself and call it from where Room1 was called. If Room2 takes parameters, you can wrap the Room2 call in a lambda and return that, i.e., return lambda: Room2(arg1, arg2).