Florida Man v1.0.0 Devlog #1: States and Floor Generation
So the jam is over, and I am now working on basically a full-scale reimplementation of the game, as previously mentioned. This has been annoyingly difficult, for a number of reasons, not the least being that I literally had to switch meds the day after the game was submitted (there is an Adderall shortage in the US as of the time of this post).
We can separate what I have done into two major tasks:
- Organization and standardization of the game's state system. (This is to make the code scalable and inherently prevent some bugs.)
- Rewriting the door placement code. (This is to partially resolve one of the major complaints about the game, which was the amount of backtracking.)
The first task here was long and tedious, but not difficult, per se.
The game should now have only one global variable, rather than several. All of the variables that would be persistent across a playthrough are going to be properly put in one class (or data referenced by that class), which should allow me to relatively easily solve two annoyances that came up in the jam: having to restart the program in order to play a new game, and not being able to save a game and continue later. Most things that should have classes are already planned out, now, and it is pretty clear what responsibility belongs to what.
A big structural change, however, is how game states (e.g. the title screen, gameplay) are handled. In the jam version, these were just assigned to a global variable which simply changed whenever. Now, however, there is the App class. It's a singleton (yes, I hear the groans, but it actually makes sense here), but it's not particularly strict about it; theoretically I've heard of ways to be more singleton-y using comparatively arcane Python features, but I am nowhere near a professional programmer (at least I hope, for the sake of civilizational infrastructure). The App class has a stack of one or more AppState objects, of which the top of the stack is accessed (this will be useful for allowing an options screen to pop up from both the title or gameplay). Each of these AppState objects has a stack of "substates", which function similarly.
Mind you, none of these are formal finite state machines. They do have on_enter and on_exit methods, which are called at the appropriate time, but you can access any state from any of the others without pre-defined transitions or whatnot. But it is an organizational improvement on just assigning a variable to a different State object.
Only the Pygame logo and the dedication are actually fully implemented, as of this post, but it's a start.
The latter task, of rewriting the door code while reimplementing the maze generator, was fairly short, but challenging.
So the maze generation algorithm, in both the jam version and the reimplementation, is what is called a recursive backtracker. This has some weird properties, as very thoroughly stated on this amazing website (pun intended). It has essentially the longest and most twisty passages of any of the algorithms, and while this is useful in the sense that you have to make the least decisions, often things just lead nowhere. This leads to all of the backtracking.
The original door concept was supposed to help with this, but it was naively implemented, and just made some random cell walls or passages into doors. This didn't turn out to be very helpful, and often led to doors just sticking out at the end of walls.
The solution to this is to place doors where there is low connectivity between cells in the maze. I made this harder than it needed to be by implementing two different versions of A* and then realizing my bug was with the code which actually iterates over each cell in the maze to find the highest distance between any two neighboring cells (for some reason it created (w x h) (w x h)-cell grids, which took about 25 seconds for a 16x16 maze and returned the wrong result).
The function that I came up with (called mue2 for "most unconnected... something" [I forget what]) works like this:
- Let there be a best distance, a best pair of coordinates, and a best direction.
- For each cell in the maze, look at its neighbors (regardless of walls):
- If the distance between the original cell and a neighbor is higher than the best distance, set the best distance, best coordinates, and best direction to the original cell's properties with regards to the neighbor.
- Return the best direction and the cell at the best coordinates.
For door placement, you just run mue2, place a door there, and repeat another five times (maybe will be slightly randomized; doors do not count as walls for A*). The first door is locked and will require a key (a new consumable).
The result looks something like this:
################################# # # # D # ### # # ### # # ##### ######### # # # # # # # # # # # # # # # ### # # # # # ####### ### # # # # # # # # # # # # ##### ########### # ### # # ### # # # # # # # # # # # #D####### ### # # ### # # # # # # # # # # # # # # # # # ##### ####### ### # # ### # # # # # # # # # # # # # # ### # # # # ####### # ### ### # # # # # # # # # # # #L# ##### # ##### # ##### # # # # # # # # # # # # # # # # ##### # ##### ### ### # # # ### # # # # # # # # # # # # ####### ####### # ###D### # # # # # # # # ####### ##### # ##### ##### ### # # # # # # # # ##### # ########### # # # ##### # # # # # # # # # # # # ####### # ### # ####### # # # # # # # # # # # # # # # # ### ##### ##### # ##### # # # # # # # # D # # # # ### # # # # ######### # ### # # # # # # # # # # # # # ####### # ####### # ####### # # # # D # # #################################
As you can see, I don't have screenshots yet; this is all entirely abstracted with a crude string representation.
Next time, I will probably talk more about generating the game's starting conditions and UI stuff.
Get Florida Man
Florida Man
Florida is forsaken. You wander the ruins.
Status | In development |
Author | Dallas J. Haugh |
Genre | Role Playing |
Tags | maze, Roguelike, Short, Singleplayer |
More posts
- Jam Postmortem & Possible RoadmapMar 31, 2023
Leave a comment
Log in with itch.io to leave a comment.