Given the wait for release I took a little break from Lolife before coming back to it for final bug testing and polishing and it has proven worthwhile! I've made several fixes and improvements that I might not otherwise have spotted or thought of without the time away, and I figure a few of them will (hopefully) make for an interesting post.
A "fun" and rare bug
In Lolife I have an entity system (which I've written about before). Every enemy is a type of entity, but other things are entities too where I want them to share some of the logic (like breaking things with the sword).
Guards are entities that can be spoken with. I implemented this with an interact
event on the guard sprite. When you interact with a guard this event checks the targeted coordinates against the registered entities' coordinates to determine which entity is being spoken with, so an entity specific event can then be called allowing for different guards to have different dialogue despite sharing the same sprite.
When entering a room I register the entities it contains in the room script. There are up to 5 entities, and each has a set of variables associated with it. The main variables to consider are entity_n
, entity_n_x
, and entity_n_y
. entity_n
is the type of entity and entity_n_x
and entity_n_y
are the entity's coordinates.
Imagine a room that registers entity 1 and entity 2 where entity 2 is a guard. When the guard sprite is interacted with there is a chain of conditionals that first checks if the targeted coordinates are equal to those for entity 1, then for entity 2, etc. until they match. Naively I assumed, because 2 entities cannot occupy the same location in a room, this should work perfectly. Yet I found a bug where interacting with entity 2 was matching with the coordinates of entity 1 and therefore calling the wrong entity dialogue event (which in this particular case meant the guard's dialogue was missing).
How did this happen? It was the combination of a few things:
- When changing rooms I was resetting the
entity_n
variables back to 0 but not resetting the entity_n_x
and entity_n_y
variables.
- I was only conditionally registering entity 1 as it was not a regular enemy but a gate winch that can be permanently destroyed. Once destroyed I was only registring and therefore updating the variables for entity 2 (the guard).
- In the previous room I was registering another enemy as entity 1 and it was possible that this enemy's coordinates could clash with the coordinates of the guard.
In other words the entity_1_x
and entity_1_y
variables were remaining as the coordinates of that entity's last position in the previous room and this could (with very bad luck!) match with the coordinates of entity 2 in the new room, which would confuse the dialogue fetching script into trying to fetch dialogue for the wrong entity in the room!
Once I figured this out the fix was easy - I now just make sure to also reset the entity coordinate variables when moving rooms.
A sound effect in-joke
A late bit of extra content I have added is an item called the "Blessed Ring". Its effect is to sometimes prevent the player from being killed by a deadly blow (leaving them with 1HP instead). When this happens I of course wanted to play a little sound effect...
But the sound effects were all completed a while ago before I even had the idea for this item and I didn't want to go back to Vic (who has made all the music and sounds) with a new demand and a short deadline!
Instead I decided to search through the existing sound effects for one I might reuse. I quite like doing this actually - it's a bit like how the clouds and bushes are actually the same sprite in Super Mario Bros, it can be fun and rewarding to be clever in asset reuse!
We made every entity type have its own set of sound effects so there are unique sounds for each enemy being attacked and being killed. These are named like mouse damage
and mouse death
. As I mentioned above entities can be things other than enemies, and one such entity type is called block
. Block is literally a block that is found underground and you have to dig through by attacking it with your sword, Minecraft style. Thanks to the sound effect naming convention, destroying the block plays the sound block death
. Maybe you already get the joke...
I was looking for a sound effect to reuse when the Blessed Ring activates and prevents the player from dying, and here was a sound effect called block death
. Luck was clearly on my side as it sounds good in this new context too! So now you know the in-joke when that sound effect plays to tell you death was blocked 
An obtuse hidden mechanic
Mice are the most common enemy in Lolife and their behaviour was pretty simple:
- They moved about randomly
- They became alerted if the player attacked any entity in the room
- Once alerted they ran away from the player if the player moved within a certain radius
The new behaviour is this:
- They move about randomly
- They become alerted if the player attacks them directly
- Once alerted they run away from the player if the player moves within a certain radius
- If not yet alerted they can have one of two behaviours - either they ignore the player and move about randomly, or they are vigilant and will run away from the player if the player moves within a certain radius even without being alerted
What determines whether a mouse will be "vigilant" or not? It's randomly chosen for each mouse on entering a room with a chance equal to a hidden variable. That variable (the percentage chance of a mouse being vigilant) changes in the background every time a mouse is killed. If you kill a vigilant mouse the chance decreases by one percent. If you kill a non-vigilant mouse the chance increases by one percent.
In other words, it's player driven natural selection! Vigilant mice are actually easier to kill because their movement is more predictable, making them easier to chase down, but the more you kill the less likely they are to appear. It's self-balancing in that respect!
I don't really expect anyone to notice this when playing (at least not consciously), but I think it is fun regardless! And if you do know about it you can actually be selective in the mice you kill to push the balance one way or another (it min/maxes out at 1%/99% so you can't completely eradicate the two varieties, but you can get close).