Timesharing between projects

Not sure if timesharing is 100% correct term, but it’s the best term I could think of. I’m a person who likes to tinker with lots and lots of different things. This is fun and there’s always something new to see and try out. The problem of course is that the nothing ever gets finished.

To try to remedy this, I decided to do a little experiment and divided my week between three projects: reading through Gödel, Escher, Bach: An Eternal Golden Braid,working with pyherc and learning Unreal Engine.  Monday and Thursday are reserved for GEB, Tuesday and Friday for pyherc and Wednesday and Saturday are for Unreal Engine. Sunday isn’t specifically for anything. On every given day, I would spend at least an hour or two working on the given subject.

After trying this for one week, I have spotted some problems with the idea. Especially coding is something that isn’t easy to constrain within fixed slot of time. Sometimes progress is quick and you want to keep working on more. Sometimes problem is so interesting that you would want to spend more time on it. And so on.. This happened on both times I was working on pyherc. I have there fairly interesting problem to solve, which requires quite a big rewrite of code. One evening twice a week is too short time to get really deep in the code and start cutting pieces and rearrange them differently.

However, with GEB this system is working fairly well. I read one evening and then spend two days mulling over the ideas and digesting them. Then I read some more and repeat the process. Concepts and ideas presented in GEB take me some time to really grasp after all.

On the Unreal side I haven’t made much of progress yet. I did get tools installed and simple example project compiled and running (even made a standalone .exe for Windows just for fun). But mostly my time is spent perusing the documentation and going through quick start guides. I’ll probably try and make something really simple eventually with it. Simple enough that I can actually finish it and complex enough that I have chance to try different things.

I’m also thinking that for the next week I’ll slightly adjust things and have consecutive days reserved for single subject. Then it would be GEB on Monday-Tuesday, pyherc on Wednesday-Thursday and Unreal on Friday-Saturday. Then depending on how things work out, I’ll keep doing that or try something slightly different. Eventually I should discover a way to do all three things and make progress on each of them (and have time for family, playing games and all the other things).

New rooms

This week I was busy adding new room into the game. First one was circular with nothing special in it. But that room serves as a base for couple other rooms:

Fountain is currently just a decorative element. Characters can pass through the square it occupies and it has no functionality at all in the game. Eventually players will probably be able to drink from it or drop items into it.

fountain

Second new room is a shrine. It shares the layout with fountain, but has an altar and couple of candles in it. Like fountain, the shrine is currently just a decorative feature. Future of it is pretty unclear still. The most obvious usages would be praying and sacrificing, but maybe I can come up with something more unique still.temple

There needs to be a place to store all the spellbooks and such. A library is a perfect place for that. Unlike shrine and fountain, the shelves are actually blocking players movement. I have an idea of special monster that would occupy libraries (no, not an orangutan though), but they need some fleshing out and some new code.

library

The last new room is graveyard. The layout is similar to library, but instead of shelves, there are graves. And graves actually have a function in game. With correct implements, it is possible to dig them up and reveal what have been buried in them. Some of the things are good, while other are not good at all.

graveyard

The nifty thing about the new rooms is that they are built on top of old room generators and parametrized. Shrines and fountains are generated by the same class, but with different settings. Libraries and graveyards are done in the same way:

(defclass LibraryRoomGenerator [SquareRoomGenerator]
  "generator for library rooms"
  [[--init-- (fn [self floor-tile corridor-tile walls decos rate feature-creator level-types]
               "default constructor"
               (-> (super)
                   (.--init-- floor-tile nil corridor-tile level-types))
               (setv self.walls walls)
               (setv self.decos decos)
               (setv self.rate rate)
               (setv self.feature-creator feature-creator)
               nil)]
   [generate-room (fn [self section]
                    (-> (super)
                        (.generate-room section))                    
                    (ap-each self.rows 
                             (when (<= (.randint random 1 100) self.rate)
                               (when self.walls 
                                 (section-wall section it (.choice random self.walls) "wall"))
                               (when self.decos
                                 (section-ornamentation section it (.choice random self.decos)))
                               (when self.feature-creator
                                 (self.feature-creator (:level section) 
                                                       (section-to-map section it))))))]])

First routines from SquareRoomGenerator create an empty room. After that LibraryRoomGenerator takes over and starts placing tiles (tomb stones in this case) on locations listed in rows collection. This collection was filled by SquareRoomGenerator, in order to make it easier to build rows of something in room in a way that there is walking space in between them. The last finishing touch is to call feature-creator if it has been supplied. In case of graveyard, it is an function that marks the square as a grave randomly populates it.

Another week, another set of commits

The past week was really productive and I got much done. Sadly, nothing that I did amounted to something that I could actually show (at least right now). I did some fine tuning to the fungi monsters and currently I’m happy with them. Sometimes I play the game just long enough to find a room that has some fungi and then just stand there and watch how it grows and evolves.

First real addition was a new player character. To make things more mysterious, this character is playable only during specific circumstances. It still needs some work on special powers and inventory, but the start is there (and new graphics).

Minor tweaks were done to speed up the game. I didn’t profile the difference, but in modern computers it’s not noticeable anyway. It’s just nice to know that the plumbing works and is efficient.

Last change is a big one and not yet finished. If you remember, I’m using dense data structure to represent playing world. Each level is a rectangle with each and every tile stored. The new structure is sparse populated and does not enforce any particular shape on the level. It even allows negative coordinates and growing levels during game. Since the change is pretty invasive, I’m doing it on a separate branch. Basic system is working, but things like line of sight and fireballs don’t work at all.

Next week will be the last one before the release. The main goal is to finish the new level structure and then clean up the code base a little bit more (there’s always something that needs fixing). I also would like to continue with Adderall and write some more test programs.

status update

This week was pretty busy again in terms of everything else but coding. But I did manage to get some coding done too and fungi are finally ready to be unleashed into wild. I’m pretty happy how they turned out so far (they probably will change in the future).

There are two types of fungi currently, regular ones and great ones. Regular ones will attack everything around them (they can even attack diagonally, somethign that other creatures can’t do) that is not a regular fungi and slowly spread. When there’s a big group of regular fungi, they might combine and form a great fungi. These are much stronger than regular ones, but don’t spread around. They will also fight regular fungi. The result is that they form interesting patterns in rooms and limit the spread.

Attack of the fungi

In addition to coding fungi, I have been learning to use Adderall (the logic language, not the drug). Progress is slow, but definitely very interesting. I might soon try and convert some of the room generation code into it, just to see how it feels like.

Hopefully the next week will not be as busy as this one. The plan is to add a new character class (that is playable only under specific circumstances) and optimize the event passing a bit. There’s still two more weeks until the next release and things are shaping up fine.

Squishing bugs

In the past week I mainly concentrated on squishing old bugs that have been lurking around way too long. Most of them were actually easy after sitting down and looking them properly. But there’s one (#38, to be precise) that wasn’t like that. Easy on the surface and should have been cleared in 5 minutes, but after poking around it a bit I had to conclude otherwise. There’s two classes called Damage in the game. One of them is used to create status effect that damages the target while other one is used to represent damage taken in combat. The latter one has code that takes damage modifiers into account (resistances and weaknesses in particular) and handles armour too. The first one has just a simple subtraction of hit points that should be fixed.

Since I like to keep amount of duplicated code in minimum, I extracted resistance and armour logic into a separate class that I placed in rules package (since that’s where it should go, right?). Of course this in the end caused a circular reference because rules are referencing the model (where damage effect is located) and model is referencing rules where new class for resistances and armour handling is now located. On top of that I tried to rename Damage to DamageEffect to make it easier to distinguish it from the Damage that is used to represent damage in combat. The end result was too big refactor in one go that didn’t work at all. So in the end I rolled everything back and started proceeding with smaller steps: first renaming Damage to DamageEffect and then continuing with rest of the changes.

I probably will place the new damage class in the model package even, since it’s more of a value object in the end after all. Whole division to model vs. rules is sometimes a bit unwieldy anyway, I really should look into that more at some point. Now the model is a bit anemic and some people consider that to be an anti-pattern.

Status update

The past week was really busy one. I’m trying to actually finally graduate this spring and that means writing the last papers and studying for the last exams. What time I had left from that, I spent on building up the animation framework. All the old animations (the little what I had) have been converted to the new system and some new ones are on their way.

In addition to that, I did some really minor clean up for the code in general, like fixed the imports. There is a handy utility called isort, that can do that for you with minimum effort. Although you probably still want to have enough tests to check that nothing broke.

Status update

Another week flew past like nothing before. But I did manage to get some coding done here and there. I created an account at Gemnasium and now dependencies of pyherc are automatically tracked. If there is a newer version of a library that I use, I’ll get a notifaction about it.

First trap is working now and being used in the game. If a player, or any other creature for that matter, steps into a pit, he is immediately killed. No saves, no magical items can save him. Luckily those pits are big and easily visible.

Version 0.11 was released this weekend. I’m trying to switch into mode where I release more often, but with smaller amount of changes. This hopefully stops me from doing too large features in a one go.

Final thing I started working with is the dungeon restructure. Originally the game was about descending into dungeons under city of Herculeum. At some point I switched over to escaping from a prison style game. This means that the dungeon needs to change somewhat (no point of starting next to stairs that will take you out of the prison).

Status update

After releasing 0.10 last week, I have been fixing up little things that bothered me. I updated Hy to latest version (0.9.12) and fixed some annoying AI bugs in the process. Rats and firebeetles are finally able to attack and damage the player.

Previously it was possible that a level generator placed a monster directly where stairs are located. This of course prevented player from ever entering the level. Now it is possible for the player to enter, if any of eight tiles surrounding the stairs is empty.

Monsters have learned to shuffle past each other. This is very helpful when two creatures meet in a narrow corridor. Previously they would just stand there and wait until the passage was clear, which of course never happened. Now they happily shuffle past each other and continue their journey.

I started working on a new feature: pits. These will be first traps that the game will have. There is a new room generator that can generate rooms with large pits in the middle and narrow corridor going around. Pits themselves don’t do anything yet, player and monsters can walk over them without any effects. But they look nice nevertheless.

Herculeum_022_crop

Whole trap system is still pretty much in thinking stage. I might try my hand at logic programming, because it could be such a nice tool for this. Some traps are triggered when a character steps on them, while some are triggered for flying creatures too. Having to keep track of movement modes, special effects and magical items might be a bit too convoluted, but expressing them as facts and queries could make it easier to tackle. That remains to be seen though.

Finally, command line got couple changes. First, Qt interface is now the default instead of the curses. Curses one hasn’t been receiving much of love lately and has fallen a bit behind in terms of features. The bigger change is that starting level can now be specified on command line. That helps testing new stuff, because I don’t have to play through all the levels just to see that new room was not generated this time.