Monday, 19 August 2013

Kickstarter roguelikes

There was a long post by URR (Ultima Ratio Regum) developer about Cult, a kickstarter RL project that now possibly has failed, because the developer can't create the game he was talking about.

What I find amazing is not why projects like Cult fails, but the way people are willing to support almost anything. In other words, let me phrase this carefully: people are idiots.

Well, there is nothing new in this, because people also buy poor commercial games. However they at least get something in return, an actual game.

Not just average developers try their luck with Kickstarter, but also old and young professional developers. One of the worst examples is Richard Garriott, one of my childhood heroes. He had the money to continue Ultima series when he wanted, but only when Kickstarter made it possible to ask money he did so.

Also, I want to correct something Darren Grey said about Kaduria in a comment. He included Kaduria to the list of big, over-scoped projects as he said. He is wrong. Kaduria was never an over-scoped project like, let's say, URR. The development time has been long for other reasons and rather than following the usual development history of a failed project it has followed a different path.

Wednesday, 7 August 2013

Theme park

Back to level themes. I have a plan to create quick versions of unfinished level themes, but even it seems to be hard. I need plans for my plan! I have a vague idea for each level theme, but it's not good enough. I think better way to handle this is plan each theme on paper as I have done for couple of them. Then it's easier to think how to implement features presented in the plan.

Level themes are difficult, because they involve content creation. Yes, that pesky content. I think even seasoned game developers can be surprised about the amount of content needed in a roguelike. No matter how random the creation process is you still need to design it. And the amount of design is multiplied by the number of level themes. On top of that I have ambitious ideas for level themes, most of them with special features.

Sunday, 4 August 2013

Stairs logic

Previously I had created a node system for levels which is a database of level themes and connections between them. After the introduction of "static" or special room types in some levels I had to re-think stairs creation in their actual form as objects in the level. This far the generation process found some empty floor and there you had it.

What I needed was some kind of way to tell stairs creation about static places for stairs. For that purpose it was easy to set up a list of "clues" for stairs. It's a coordinate set during the creation process and then retrieved when creating stairs. There could have been many ways to do this, but I chose this way, because you browse through node connections which then can be matched with the clue.

At first it returned a wrong location. It was a bit of a mystery, but finally I realized the location was not set correctly, because the room interior was created later than stairs clue was pushed into the list. Some of the interior was terrain generation (with Blueprint class) which I then moved to the routine which is creating the actual shape and terrain of the room.

Now it works and I can set up special locations for stairs. Of course, it's not yet done. Even random generation needs better "clues" where stairs should be created.


As this example is showing. The sign of stairs is created next to door. It should be quite easy to prevent this by removing that place from possible creation locations. The same also need to be done for walls, because doors also could be created into poor place, next to something that's in the room against the wall.

Wednesday, 31 July 2013

What I think about bugs

Good old captain told me "there will always be bugs". Those words ring in my ears. I think not, captain. In reality bugs are always a result of what you do. There are rare compiler bugs, but they are also often caused by stretching the limits of the language by using unneccessary complex programming style.

Programmers are egoistic people. They don't want to admit their own errors, but instead use excuses like "there will always be bugs". Programming languages like C have played a big role in this mess, because it lets you write poor quality code. However it's still you who suck, not the language.

When I look at some open source projects I can already tell why there are lots of bugs and developers spend huge amount of time trying to fix them. The problem is always how you could tell these people to learn better programming practices? It never works that way. It's always up to personal interest to learn more and try not to pretend like you know everything better which you don't if you produce large number of bugs.

Kaduria has four open bugs at the moment. Yes. Four, as in 4. I want to keep the number of bugs low, but also prevent them with strict programming rules. You can never rely on yourself as some kind of machine who never make mistakes, so it's important to follow rules that, if not always prevent, at least reduces errors. What those rules are depend on personal programming style and language, because some languages have features which almost always explain bugs.

I find it easier to become a better programmer, because then you spend far less time hunting those bugs you could have prevented. So keep this in mind: if your project has lots of bugs you suck.

Monday, 29 July 2013

It's a trap

There was this bug I wanted to fix. When you looked at a trap it was telling the name of the trap, like poison gas trap. But how could the player know that before stepping onto it? I had to fix that by adding "identified" flag in Trap class and returning a generic name like "pressure plate" if the trap was not identified.

Following the new std::string message style I wanted to make the generic name const. In C++ const is a immutable variable, something that can't be changed once it's set. The problem was that Get_Name() returned plain char* and it is a virtual function of 15 total game object classes. So there was some of that good old const correctness when I changed all those routines to return const char*. It wasn't that bad and at least now it's done.

I've had my personal issues with const correctness, because it's sometimes difficult to grasp the concept of const. It's not that I don't use const. I'm using it almost always when setting up local pre-calculated variables etc. because it really eliminates one way (a subtle one) to create bugs. But when using const in data it can create a long chain where everything else must also be const. However lately I've started to use const in my framework routines etc. so it's becoming easier to be correct.

The bug was fixed, but I started to think about how messages work in Creature class and I guess there are some things to consider. Sometimes messages are constructed for all creatures when in fact only player can generate the message. The message output can be limited to the player, but the message itself can be constructed for all actors and it can slow down the game when there is a large number of creatures in the level. It's something I have to remember when I get into details of the Creature class routines.

Saturday, 27 July 2013

The palace

Small room item creation bug was fixed. Rooms are now in a list which also means I can create the interior later. It's an idea I've had for rooms to form "houses" by checking out where a room is connected and then determining the room interior.

There was also a bug in a return value of one routine. I used int return value with -1 as failure and 0 as success. It doesn't sound bad, but it can be since I was thinking zero was failure when I called the routine. It's easy to make that mistake since I'm using zero for failure in routines that return object handle. In cases like this it's much safer to use bool as return value. This bug was only telling that there was no room to create item in a small room. It didn't do anything else.

The actual bug was in the search routine which had no room mask id included so the area of search could include tiles outside the room. In theory, because the room rectangle should be good enough. So this is one of the few bugs that were fixed by an accident. I don't know what happened.

I'm reading a booklet The Oxford Handbook of The Bronze Age Aegean. The famous Knossos palace is interesting, because it was kind of a labyrinth with no clear floor plan. Maybe it was also a castle of some sort, planned to make it easier to defend and confuse enemies. Or maybe it was built like that for religious reasons. Who knows, but the important thing is that it's like made for a roguelike level theme. What could be better than random placement of rooms without apparent logic? An ancient palace with hidden rooms, long corridors, mazes and stuff. And it's an idea from the real life.

Friday, 26 July 2013

Junk

It's often important to know exactly what is going on with routines, but it's also tedious to add debug information. I guess I need it now when I'm fixing a bug with room item creation. For some unknown reason the search is including areas outside the room. The bug has been there for a while and I noticed it only when removing all item creation other than when it creates junk items in "small" rooms.

Bugs like this are annoying, because you know the room is made into that spot. You can see it in the mask map and in the level. Nevertheless something is wrong. Maybe the room rectangle is stored incorrectly. Since small rooms are temporary objects I have to change it and store them in a list to view the data later and compare it to the actual level.