Last week, I reported that I added the concept of Stamina to the party members in The Dungeon Under My House, my non-violent, first-person role-playing game and my second Freshly Squeezed Entertainment project.
I built off the resting mechanic to add sleep, plus addressed other things this past week.
Sprint 2024-24: Stamina and resting mechanics
Planned and complete:
Unplanned and complete:
- Defect: Dungeon rendering is too slow on Android
- Sleep in bedroom to restore stamina
Unplanned and incomplete:
- Show indicator when Friend has something to say
Since your party can use up their energy, I now have to handle the situation in which all of their energy is gone.
As I said last time, resting isn’t meant to be very efficient and should be seen by the player as a waste of time that they want to avoid. I talked about the party members becoming Exhausted.
I ended up creating some scripted dialogue whenever someone does become Exhausted. If multiple people become Exhausted at once, then a random party member is chosen as the speaker.
If any member isn’t Exhausted, then you get the option to rest or continue, and I’m still toying with the idea that non-Exhausted party members need to use more energy to “carry” the others.
But if everyone is Exhausted, then you are forced to rest.
Next, I realized that I was tired of dealing with the slow dungeon rendering. Ever since I added more wall, floor, and ceiling images to draw, the rendering of the dungeon has become quite stuttery.
I anticipated it was due to needing to read from different parts of memory to get the texture information for rendering, but I am glad that used a profiler because I discovered the real bottleneck was due to making and destroying copies of DungeonGridCell objects needlessly.
Each DungeonGridCell knows what type of floor and ceiling it has, so when I wanted to know what type of floor to draw, I would ask for that grid cell by index, but I was making a copy of it. Then I would ask for the floor type, then I would discard the copy.
These objects contain everything about a grid cell, though, so the copy was also getting the walls, any doors, any portals, any tags, the lighting that might be baked in, etc. Each object isn’t terribly large as a piece of data, but when you copy and destroy the object unnecessarily half a million times, it adds up to a lot of extra processing.
So I changed the code so I can ask for the floor and ceiling data by reference to the cell, eliminating a bunch of that extra unnecessary processing.
The next bottleneck in the rendering code was related to how the flashlight lighting was being processed. Similar to how I was doing processing unnecessarily on each pass, I was doing repeated calculations that didn’t need to be repeated.
Basically, lighting data for the dungeon is retrieved once, but then if the flashlight is being used, there are a number of modifications to the lighting that need to occur before the final lighting is used to determine how to render a specific dungeon cell. So the code iterates through the flashlight’s affected cells, figuring out if the cell in question should be lit up more by the flashlight or if the existing light is brighter.
And I was apparently doing this in the most inner loop despite the fact that the lighting calculations will be the same. Whoops.
If you recall, when I render the floor and ceiling, I go pixel by pixel, looping first over each row, then inside each row, I loop over each column. That’s the inner loop.
So I moved the flashlight lighting modification code outside of both loops, because all I need to know for the flashlight modification code is the current location of the party and the current lighting data, neither of which changes inside those loops.
And suddenly, I was delighted to find that the dungeon rendering code was fairly smooth again. At least, it is quite smooth on my desktop computer. On my Android phone, whereas before it was quite unplayable, it is now tolerable.
Then I worked on adding the ability to sleep to gain back all of your energy. I’m not sure if I’m happy about the user experience, but to make a long story short, I added a second option to the Rest menu to sleep for 10 hours in exchange for replenishing your party’s stamina.
Did you know that pre-teens need about 10 hours of sleep a night? It seems like a lot, but I suppose it makes sense that a kid with an 8pm bedtime won’t be waking up at 4am.
Anyway, I had to take into account that the rest of the Explorer’s Club might also be low on stamina, especially if the player had swapped out party members, so when you sleep, EVERYONE in the room gains back energy.
And I decided to make sure that the Sleep option is only available at night. My thinking was that letting you sleep at any time is both unrealistic and also allows for an abuse of the sleeping mechanic.
One thing I worry about is the idea that there are three party members but six potential friends who can be party members, and I really need more reasons for why choosing one over another matters.
Being forced to go without a particular character who has certain skills you wanted to leverage might be a good thing to have the player worry about, a nice side-effect of not being able to restore stamina whenever you desire.
By the end of the week, I found myself playing the game so far and trying to figure out what to focus on next. A major part of the game will be conversing with others, and I still need to work to make it more intuitive.
I spent time thinking through how to indicate on the screen when a character wants to say something to you and how you might interact with that character to get them to say it, but I’ll need to continue that work this coming week.
Thanks for reading!
—
Want to learn when I release The Dungeon Under My House, or about future Freshly Squeezed games I am creating? Sign up for the GBGames Curiosities newsletter, and download the full color Player’s Guides to my existing and future games for free!