It is finished

Rogue: Through The Veil

Rogue: Through The Veil is yet another roguelike. In this twist on the classic game, you are constrained to a dungeon of your normal, everyday monsters and items. However, just beyond the veil there exists a magical world where incredible creatures roam and mystical items await discovery. During your search for the Amulet of Yendor, you will discover how to go beyond the veil, transitioning between the realms of reality and the magical. You will be able to bring magical items back to the real world to aid you in your quest, but beware, the magical world is a dangerous place.

This game is one I've been thinking of since I discovered Rogue a few weeks ago, I'm so glad PyWeek just happened to be around the corner and with a perfect theme! Now I'm going to work flat out all week to try and get a minimal version of this running. Despite the description, there are still many unanswered questions as to how this game will work. It'll need some experimenting to get just right.

In-keeping with Rogue, it will use ASCII graphics, but I will also use colour. It will also have no sound. I'm going to be using tcod, which is a Python interface to libtcod library. The docs are here: https://python-tdl.readthedocs.io/en/latest/

I spend my days as a PhD candidate researching in the field of ontology/knowledge graphs with applications in systems, so also conducting research into systems thinking and mereology.  This means I'm looking forwards to Python 3.7's data-classes with keen-interest. I'm not going to use Python 3.7 for this because it has not been released yet, I am however going to try a programming style I've being mulling over as a result of my research into systems and ontology.

For this project I will use a class to represent a data-type, such as a "Potion of Healing" or "Snake". These classes will have no methods of their own, the only functionality I will give them will be in generating their properties, and perhaps nice __str__ methods. A class will be mutable and in Python I can access their instances in functions without passing them in explicitly, which is what I want. I will also use an ontological perspective on inheritance, so if I assert in a type hint that the arg: MovingObject, then it could also be any child class of MovingObject, such as Player. Child classes are not allowed to overwrite anything in their parent classes, they can only have additional properties and default values for existing properties.

Functions are considered to be mappings of global states, they don't belong to the thing that effects them, therefore no methods are used. Therefore, all functions will be public and able to act on any class that they are capable of acting upon. So the function "move" will be able to act on anything that has an x and y position, whether I intended it to or not. This is closer to reality, I currently have a burnt out old XBox providing the function "door-stop", I'm pretty sure if Microsoft coded the world it would not have had that function. I expect it will also offer greater flexibility and code re-use. This project will be an interesting proving ground for these ideas and a demonstration of how data-classes may be used from Python 3.7 onwards, I will be updating this project to use them at some point.

Finally, I'll be keeping a daily blog on progress at www.paulbrownmagic.com/blog

Enjoy your PyWeek, happy coding!
Paul

Awards


Vim keybindings!
Presented by mauve

Most respekt
Presented by knockupwood

Give this entry an award

Scores

Ratings (show detail)

Overall: 2.9
Fun: 2.6
Production: 3.3
Innovation: 2.8

33% respondents marked the game as not working.
Respondents: 8

Files

File Uploader Date
pyweek_complete.png
It is finished
PaulBrownMagic 2018/04/21 22:56
RogueThroughTheVeil.zipfinal
Source Code Submission
PaulBrownMagic 2018/04/21 22:53
ThroughTheVeil
Linux Packaged Version
PaulBrownMagic 2018/04/21 22:49
pyweek_day6map.png
New Map Features
PaulBrownMagic 2018/04/20 23:58
pyweek_day5.gif
Day 5: Nearly there
PaulBrownMagic 2018/04/19 20:19
pyweek_day4.gif
Day4 Both Worlds
PaulBrownMagic 2018/04/18 21:07
pyweek_day3.gif
Day3 Normal World
PaulBrownMagic 2018/04/17 22:35
pyweekTwoWorldsDay2.png
Day2 Normal World
PaulBrownMagic 2018/04/16 22:35
pyweekTwoWorldsDay1Magic.png
Day1 Magic World
PaulBrownMagic 2018/04/15 19:15
pyweekTwoWorldsDay1.png
Day1 Normal World
PaulBrownMagic 2018/04/15 19:14

Diary Entries

Day 1

Worked pretty much flat out today to put together the frame around which the game will be built. Github repo: https://github.com/PaulBrownMagic/TwoWorlds

The biggest part of the day has been spent of the dungeon generation. I've opted for a quite traditional 3x3 grid of rooms. I'm generating them by choosing a width and height at random, then placing the room within a bounded section at random. From there I'm using a depth-first search or breadth-first search to create a spanning tree of the rooms. I'm making doors to the rooms on the fly as need, so there's only one door per side and the passages connecting the doors are distinct from the rooms. Once I've got a spanning tree I know all rooms are connected, but I want there to be a chance of loops in the paths and the chance to have loops through rooms too, so I choose a few other random connections and add them in too.

The tcod library I'm using makes it relatively easy to work with the map, it'll work out if a tile can be walked on or if it's transparent for me, but I had to add in whether it had been explored yet or not to get fog-of-war. From there I'm just calling tcods drawing functions to handle all the gui and user input.

Now I have a player who can move around and explore a dungeon, in the magic world or real world. Next I need to make some gui additions such as the health bar, xp info, level info and message panel. Then it's on to monsters and items.

Normal World

Magic World

Add a comment

Day 2: There be monsters here!

Today the progress was slower than I had wanted. First I had to learn how the D&D combat system worked to inform my monster and player classes before coding a combat system.

But I've added the basic HUD GUI information system and the monsters for the normal world levels. I'm happy with the HUD, monsters movement, and melee combat is working. Tomorrow I need to make my magic monsters. There's still a few tweeks to do, I've added some dispositions to my monster behaviour through flags in the data, which need passing to the class when they're generated. Then I can take them into account in my movement/waking behaviours.  I also realised I need to implement the health regen, I can't test the later levels without dying!

I'm a bit worried some features that would be nice to include, such as projectiles and unique monster behaviours might not make it in within the week. There's a lot to do with making monsters, and then items in terms of deciding what they'll be!
Day2 Rogue: Through The Veil


Add a comment

Day 3: Menus, Items, and better combat.

Okay, so today I began with the simple task of creating monsters for the magic world. With that out of the way I started on improving the melee combat system, balancing out strength and chance to hit. That led me into implementing levelling up when gaining experience and increasing HP. That then reminded me I need HP to regenerate, so I did that too.

With lots of those little jobs out of the way I made armours and weapons, not only did I need to make them, but I then had to incorporate them into the combat and levelling up. With these in the game I wanted to make an inventory screen, so I did. I made the function reusable too, so I automatically got a controls screen too. Bonus! It's starting to become a playable game now. You can wonder through the dungeons, fighting monsters, and getting better weapons and armour.

Finally I made the scrolls, I had no idea how to do these at first, but implementing the functions to put on armour and change the weapon being wielded gave me the interactions and framework to figure out how to do them. So I've got "most" of the scrolls done.

There's still lots to do, I need to implement the disguised names for scrolls, which will also apply to potions and wands, and I've still got some functions to add in. Not all the specialist monster behaviours are implemented yet either. Plus there's still the big decision to make on how we're going to transition between the normal and magical worlds. But there's some hope now that it will be achievable within the week!

Day3 Rogue: Through The Veil

Add a comment

Day 4: Through The Veil We Go!

Today's biggest achievement has to be the transitioning between worlds. I have included this mechanic as a scroll that will transport you when read. I intend to also make a trap that'll accidentally throw you in too, when you've not planned for it! Going to the magic world spawns a new dungeon at the same level as the normal world dungeon you were in, going back returns you to the next dungeon you would have been in, i.e., the next normal level.

At the moment the only real differences are in the monsters and the scrolls that you find, I've kept potions neutral. Of course, the monsters and scrolls in the magic world are a significant difference to both tempt the player there and keep them cautious of going. But this will be changing. I intend to only have magic wands in the magic world and normal weapons/armour in the normal world. Before I can do that, I need to code some magic wands! My projectile code should underpin the wands quite well.

So I made lots of other progress today too, my git logs show scrolls, projectiles, name generation and a stacking inventory for today. I don't remember what I did with the scrolls?! But I've used a Markov Chain based name generator, seeding it with old Norse names, to obscure the names of potions and scrolls until they are used or identified. The inventory got fancier too, items now stack so you can have 30 arrows, and not just one!  Implementing both these features led to a bit of bug squashing as the underlying data structures changed. I also spent a bit of time doing very basic, rushed refactoring. By which I mean I copied and pasted some functions into different files for a more sensible structure. Still looking forward to really tidying up the code when the challenge is complete!

On my todo list for tomorrow there's food, wands and death. At the moment our adventurer doesn't actually die, which makes testing easy! But permadeath is a big feature in a roguelike, so it will be included. After that we''ll have most of the features required, but there's more that I'm wanting to add before the end of the challenge.

Day 4: ThroughTheVeil

Add a comment

Day 5: Nearly there

The basics are all done. My git log reads: Traps, Wands, Food, Permadeath, AmuletOfYendor, MonsterAbilities. So we have hidden traps that you probably don't want to accidentally trip over. Wands that do awesome stuff and can only be found in the magic world. When you die, like a true roguelike, you die. There's a nice farewell screen for you too. On the lighter-side, if you do somehow manage to complete the game, you can get the Amulet of Yendor and there is a nice congratulations screen for when you make it out, which you'll probably never see. And monsters now have annoying special behaviours, mostly in the magic world. I think the Siren has to be my favourite addition, that monster will lure you to them, which is a real pain at times!

All that's really left to do is adding spice, I've got a few more tweaks to add to combat, one more scroll to make work, and some additional features to add to the map. Then it's just balancing the combat, without the tweaks I want to add, it's a little too easy for the first few levels, at the moment. So some balancing will need to be done to make it more roguelike. After all, I have friends who've played Rogue for decades without ever completing it, just like the original authors.

Despite the rush, overall I have to say the approach I've taken to the programming has mostly being beneficial, using functions instead of methods. The two places it's bitten me is in using one movement function for both monsters and players; my code would be tidier if I separate those two out, and the ensuing combat functions.  Besides that, I got a nice groove on making scrolls, potions, wands, traps etc. After the competition I intend to abstract out a lot of that repeated code and the same for the actions repeated code. Looks like we should come in on time!

Just a little game play

Add a comment

Quiet day, it was sunny out!

Well, the weather has been delightful! But I didn't get as much done today. Thankfully, there's not much left to do!

Biggest chore of the day was generating mazes for such tiny rooms. In the end I gave up on all my ideas and borrowed from Mazify, which I found on GitHub. Besides that, I can now remove a room, replacing it with just a passage, so there's not always 9 rooms. Adds a bit of variety to the game play. I also found the levels were taking too long to play, which has many knock-on effects in terms of xp, monsters, and fun! So I've shrunk my maps down.

I've improved some of the interactions in the game, such as hunger messages now displaying in a pop-up. If I have time I'll do the same from traps as they're also easy to miss. Weapon enchantment now works better, and you can keep up with the weapon stats if you identify your weapon. Last thing I added was a shrinking FOV as you go down the dungeon, to make it a little more scary!

Not a big one today, I'm hoping to get some more time on it tomorrow. The deadline is looming!
Mazes and missing rooms

Add a comment

Rogue: Through The Veil, complete

Well, it's a last hour submission from me. I've being trying to chase down a segmentation fault bug. I think I've got it by isolating the calls to tcod, which uses C, and reducing the tcod functions I used.

So it's got everything I wanted when I set out to do this challenge. It's not complete, but it is what I hoped to achieve in a week. It has maps with different numbers of rooms, mazes and blocked passages/ hidden doors that have to be searched for. It has monsters that can drain hp, xp, armour and strength; lure the player; hide; and regen hp. It has wands, potions, scrolls, weapons, projectiles, armour and traps. Names of potions, scrolls and wands are obfuscated until identified, or used in the case of potions and scrolls. It has hunger, permadeath, and additional monster spawns every 80 moves or so.  The player regens hp, can level up with xp, and has a changeable level of strength, which can effect the outcome of combat.

I say it's not complete because I am still going to keep developing this game, there's additional features I'd like to add, such as rings, as well as playing with the transitions between the worlds. I'd also like to develop the monsters further, adding more specialist behaviours and perhaps changing some around.

Enjoy the game, but I wouldn't expect to win it. To get a feel for it you'll need to play it a few times, it's quite possible to play through a good number of levels without reaching the magic world. It's also possible to load the game, make just a couple of moves and walk into a trap throwing you there immediately. Magic world has better loot and harder monsters. To win the game, you'll probably need the loot from the magic world. Let me know how you do, if you find any bugs, what you think of it, and any ideas you have.

Rogue: Through The Veil, The End

Add a comment

Fullscreen Mode

I forgot to say, you can toggle fullscreen with Alt-Enter. It's nicer to play big!

Add a comment