YESTERDAY I was somewhat worried about the state of the large volume of code that I’d produced, so today I shifted some around a bit. I’m still looking forward to properly tidying it up, but it’s good enough for the rush to the finish now. Plus I’m finding lots of opportunities for function reuse, sometimes I can just compose a couple of existing functions and get the feature I was aiming for. This makes me happy!
Through The Veil
I WAS excited to finally add in the name feature of the game. I’d got a lot of the structure for it built, but hadn’t actually implemented it. I decided to create a scroll, that when read, will transport the player between the magic and normal worlds. The scroll is a one use item, so if you exit the magic world via the usual stairs, you’ll end up in the next level in the normal world again. Later I plan to add a trap that’ll throw the user there unintentionally.
To implement the function of changing worlds was surprisingly simple. I just had to adapt my level incrementing function and make sure when the scroll was read it would trigger the function call. I did this by tying the output of that function to my game_state variable, which was simple enough.
When I make more features, I’ll be able to create even greater variation between the two worlds, but the different monsters and scrolls already make you both want to go to the magic world, and be cautious of it at the same time.
NOW WE can throw stuff. I was worried about how I was going to do this one, I shouldn’t have. It was just an adaptation of movement and attack functions. When I say adaptation, I mean I factored my existing code out into better functions, wrote a couple more I needed, and tied them together in a throw_item function. I’m really hoping that I’ll be able to repeat the same process when making my magic wands.
NAMES OF potions and scrolls are obfuscated in roguelikes until they are used or identified. I wasn’t sure how I was going to do this, so I checked on RogueBasin and found a Markov Chain Name Generator, but it was for Python 2. Luckily it was public domain and only need brackets around the print statements to work in Python 3! So I changed the seed values to Nordic names, implemented a class for “Name”, and created a few functions to get the required behaviour.
THIS ONE was an example of a “nice” feature that was more trouble than wanted. The idea is for the inventory to stack, so if there’s more than one of a particular item then it can go in the same slot with a count. But not all items, only projectiles, potions and scrolls. Later on, I may use the same method for charges of a magic wand. I thought about a lot of ways to do this, I could use defaultdict with lists, or some kind of tuple structure. In the end I went with a class, because it’s mutable and I don’t actually need the different objects, they’re all the same, I only need a count.
Using this class then meant each slot in my inventory was either an instance of this class, or None. Having the instance there required a lot of refactoring of my code as there was now a layer between the inventory and the item information. A bit of refactoring, playing and refactoring again, and I think those bugs are all squashed!
THERE IS still about 10 epics on my TODO list. Tomorrow the plan is to tackle magic wands, food, and permadeath. Our hero can’t actually die yet, which makes testing easy but game play a little less fun!