Sunday 28 December 2014

20 years of development

Kaduria was started somewhere around 1995. The first date in source code is from 1996, but that was after I started to record the original date when the source file was first created. This means that next year Kaduria will turn 20. Some people even doubt if this project is real. The sad thing is that it is an actual game project. Then again Kaduria is relatively young roguelike project, ten years younger than let's say Nethack which I guess is still heading for the next official version.

The development of Kaduria can be split into two distinctive phases, from 1995 to 2005 and from that to this day. In 2005 I switched from procedural C to object-oriented C++. Looking back I should have started the project from scratch and not try to refactor the old C code, but back then I had so little knowledge about C++ (OOP) that I don't know if it would have been any better solution.

Since I'm not a programmer Kaduria was somewhat difficult learning process from C to C++. I didn't make lot of mistakes, but there were some. Even I'm not a very good programmer the biggest problem was (and is) the content and handling vast amounts of data rather than programming itself. I think C++ was a good choice for me, because I can work better with the concepts of OOP and create better source code with it by strictly following some of the rules of object-oriented paradigm.

What I find funny about this whole story is that even after 20 years I've not seen any games like Kaduria. It tells how difficult it is to create new kind of major roguelike games. Even creating an old style roguelike game has proven to be hard, because there are only handful of them created after Nethack and Angband which both represent the two archetypes of roguelikes.

The development of Kaduria has now become much more about managing the project than programming, but there are still some algorithms to write as well. How long it will take depends on many things, including how early I want to release the first version which no doubt will not be the final one.

Thursday 18 December 2014

Walk routine

When implementing walking in Kaduria I've had my share of difficulties. The way I've broken it into parts is that you need to know when the player is in a corridor (or open area), where to turn in corridor when there are only one way to go and when to stop walking.

First two are kind of easy, although I did spend some time to write a routine to check when the player is in a corridor. What you need is first check if there are two walls on east-west or north-south sides. If not, you may still be in a corridor. To find out it you need to check 2x2 areas four times in the 3x3 box around the player and see if one of the areas is all floors. Then you are not in a corridor.

Turning in corridor is easy to determine, but when to stop is harder. I wanted the player to stop when either entering a corridor or leaving it. I still have to figure it out, but I think the key is in the way you take the first step. It should not be a part of the walking routine evaluation process at all, only the tiles after the first step

When to stop depends on many things, including what the player will detect (monsters, traps, dangerous terrain etc.). It's also silly to die in starvation when walking if you don't stop it. These signals increase the complexity of the routine which no doubt will require some work to complete.

I'm sure Kaduria will not have auto-explore feature. It's too much, it takes away the exploration. I think you should be able to navigate with pathfinding only between two places you already know.

Friday 5 December 2014

Start small with data

I've tried to force myself to work at least an hour at a time when developing Kaduria and it seems to get things done (slowly but surely), rather than those times when you start the IDE, look at the code for few minutes and then exit.

Returning to case of professions it's kind of silly business, because professions are built on top of skills (mainly), but the thing is I don't even know what skills there should be in total and how they actually work. You can always throw in some generic stuff, but it can become something you don't need later. It happened with some professions which there is no need since I removed hobbits from the game.

As always you should start small with data (or design if you want a fine name for it). My inability to build a solid RPG structure has certainly given me more problems than I actually need. But I guess the situation is not hopeless. The development process in this area is progressing slowly from fuzzy ideas to something more tangible.

Saturday 22 November 2014

Professions redesign

A while ago I decided to remove other races than human from playable characters, but it doesn't make a lot of sense. Also you can only play as male character. But now I have new plans to distribute professions to several humanoid type creatures and also for different genders. The idea is that you can't play let's say a female knight. It's silly and I hate games where gender is simply a choice for "equality" reasons.

Female professions will be exclusive for females and I think they are going to be more difficult if not even iron man (the irony...) style characters.

Well, the actual news is that I've finally started to complete the gameplay features. I have a "plan" for almost everything, but as in case of professions they have to be complete with all features. It's hard work to get that done (and I hate working).

Thursday 30 October 2014

Regaining motivation

I took couple of weeks off from programming, partly because I was a bit depressed during the process when I knew I was becoming unemployed. But somehow programming is my "safe place", it makes me enter a state of mind, just like when I'm painting. So it's easy to return even I wouldn't care so much about other aspects of game development.

I have mainly tweaked the source code, trying to improve some technical things. I think it's important to maintain the source code in language level, because it then makes easier to create the actual game content. One thing I've noticed is that I don't use inheritance as much as would be possible. I realized it could be used relatively safely in type classes of game objects. They all share common functionality which could be put into a base class without breaking anything. The problem with inheritance is when it actually requires large scale changes. Then it may be a lot of work for no actual reason other than to improve OOP paradigm which in itself doesn't mean anything in context of game design. No one knows or cares what kind of paradigm was used to create the game.

Friday 10 October 2014

Mental note

The development of Kaduria has long been reduced to problem areas. There is a list of missing features and bugs, but also source code comments starting with note: as a reminder for later coding sessions. Which may come after a long, long time.

Fixing problem areas is often extremely tedious, but something you have to do. I spend way too much just looking at the problem and trying to think a solution when better approach is simply hack it as fast as possible. Things get worse if you have a mind of a perfectionist. Maybe the biggest philosophical lesson I've gained from roguelike development is trying to let it go and make something working. You can always improve it later when the basic stuff works.

Development is sure going to be "faster" in context of Kaduria now that I'm again unemployed. Maybe something will actually happen, because even I am getting a bit tired of this project.

Wednesday 1 October 2014

Procedural degeneration

I've degenerated back to procedural programming! Well, not entirely, but while I was reading stuff about functional programming it made me rethink some things in C++ and OOP. Classes are ok, but sometimes there are clumsy situations where you simply create a class without member variables (data) and use it as "empty" instance, then access functions to do something. It took some time for me to realize that these strange functions are actually... functions. Or "procedures" as in procedural paradigm.

Of course "pure" functions have been always lurking in C++ in form of the standard library (functions like printf etc.). But you can also write your own functions and use them in classes without breaking OOP principles. Functions that are good candidates are generic and algorithmic, they take in simple parameters and return simple values. It's possible to go further than that, but then it starts to be too much like traditional C with all problems it has.

In C++ context it's great to reduce some of burden from classes and also avoid copying source code in member functions when you could use external pure function in all similar places. If those functions are generic enough they can also be reused in other projects really easily, because they don't have any dependencies to the current project. So I've started to create a small function library for Kaduria (rather than creating any game content..) and already removed one of those clumsy empty classes. C++ has the neat feature of closing stuff in a namespace. I've named it "Function" so functions are called as Function::do_something(); which is not only clearly showing that the function library is used, but also protects from name clashes.

I think the function library will stay rather small, because OOP doesn't easily become functional, because member functions work closely with class data and if you try to make it generic function style it probably wont look nice.

Friday 29 August 2014

Redesign of the gameview screen

So I went to doctor and got heavy antibiotics for three weeks plus alpha blocker medicine. It's interesting stuff, supposed to loosen the muscles of pelvic floor, but since I'm special it's affecting to all my muscles, including heart which is of course a muscle. For couple of hours after taking the pill my heart speeds up for quite a bit. It's annoying, but supposedly not very dangerous. However it's working, I'm feeling lot better now.

I've planned the next feature also for some time and now started to implement it. It's the gameview screen (stats, messages, etc. around the gameview) which is going to be modernized to 1.6 aspect ratio. The current resolution is 800x600+ something, but it changed vertically bigger when I added 5 lines of messages. Since displays today are almost all 1.6 ratio it makes sense to change the screen for that size. Even more important it feels like I'm actually planning the screen for the first time, because this far it has only included some of the stats.

The extra space is probably going to have both equipment and inventory as tiles with drag and drop functionality. Yet the UI is kept such that there is no need to use mouse, it's entirely optional and will work at the same time with more traditional keyboard commands.

Saturday 16 August 2014

Stetson-Harrison project management

I was looking at the oldest files in the project and found two classes (four files) from 2009 that were not used anywhere. It's actually a problem in big projects that you can create multiple ways to do something and then some of that code is never used. These days I try to avoid writing anything for "future use", just as happened for those two classes.

It could be really nice to have an option to somehow mark files in the project different way. You know, when you have the list of files in the project you could mark "ready" files with green color (or something like that) and critical files with red, etc. Neither VC2010 or Code::Blocks has that feature. Some time ago I went to ask C::B developers if they could add that feature, but I got the typical "open source answer" to add it myself. No. You add it, you are the fucking developers of that piece of shit.

I've had problems with my health. Nothing major (I guess), but for couple of days I couldn't concentrate on anything. Sucks. I tried to go to doctor, but he is not in the house for thursdays or fridays. Public healthcare, you know. At monday I'm going to try again. I hate going to doctor, but enough is enough.

I try really hard to concentrate on fixing actual gameplay mechanics rather than fiddle around with source code quality (which is important in a way). When I refactored the map routines it broke stuff elsewhere. Funniest one was walk command (similar to 'g' in Nethack), pretty much everything broke in that routine.

Sunday 27 July 2014

Clean-up (x2)

The level generation is working again mostly. Some new bugs, but nothing major. Both FOV and light map routines are off for now until I have the energy to concentrate on them. Maybe it's best this way, I can directly see the topology of the level when creating level themes.

There are more important things to do anyway. Next task is mainly go through level themes and add more things, starting from basic topology and then moving on game object distribution. There is a "trick" involved in the process, an idea I had while working on the new version of Teemu. It's of course a secret.

I guess it's these warm days, but I was upset when I noticed that save game routines for each game object type has to be refactored. Most of them were easy to convert, but couple of them needs more work. When I get upset it sometimes makes me clean up places. It's a woman-like way to react, but who cares.

Sunday 20 July 2014

Tile class - part 6

It took almost two months to refactor multiple maps to a single one. But it's not over yet...

It's annoying that I made mistakes even I should have known better. The bounds check is less reliable now, because it's not built-in like it was before. I don't know what was I thinking. I guess it can be fixed for at least those getters that return a class type, because returning -1 is dumb. It could be possible to create a type for a tile outside level borders that acts like any regular type, but the way that you can't reach or use.

FOV is not working properly. There was a coordinate translation change so it maybe has something to do with that.

The next task is a clean-up to fix bugs.

Saturday 12 July 2014

Tile class - part 5

Mask maps are now mostly included in the Tile class. While refactoring terrain map I realized that Gameview class has to be refactored. It's a class that draws the final 17x17 tiles on screen. Previously it had both static and dynamic light maps copied into a special 35x35 buffer which includes nearby light sources still visible from that 17x17 view.

However I found out that there is no need to copy the light information to the gameview, or anything else, because Tile class can include them. Even dynamic light values can be stored in Tile and recalculated on a specific area around the player to show only light sources that can be visible to the player.

The original Gameview was a result of copying FOV data and then determining how tiles and light would be displayed, but FOV was moved away from Gameview even before I started this refactoring and I didn't figure out how much there was unneccessary copying until now. Another great thing is that the new code will completely remove difficult coordinate transformations. Also, tile graphics are now stored in Gameview which is a wrong place, because they belong to GUI class. Gameview wont become completely useless, because it still has the update map which speeds up displaying of tiles by remembering empty tiles from previous turn and not drawing them at all.

Even now the gameview routine is fast, but it's going to be really fast after this refactoring. Well, I'm going to need that speed to include lights that have FOV routine in them. At the moment lights are just simple spots that don't know anything about walls or other obstacles.

Wednesday 25 June 2014

Tile class - part 4

Dungeon (World) class is now cleared from game object maps. Yes, they were there, because object maps are just 'temp' pointers to the object, which are owned by the Level class in a linked list container. The map could also own these objects, but it would need dramatic changes in the way true object handles (vs. generic base class handle) are stored.

At that point I was able to run the game, but it wasn't very pretty to look at. Terrain tiles were missing, because Level::Show is now in Tile_Map class and terrain isn't there yet. The game also crashed a lot which is funny, because the usual code is rock solid. I believe it will sort out itself when everything is moved to their proper locations.

Terrain and masks are the big refactoring thing I'm now programming. It's more tedious than difficult, but some constructions are very different than before. Yet as I thought functions of Tile are shorter and easier to read as source code, because they don't require external gets from different map layers.

Saturday 14 June 2014

Tile class - part 3

The easy stuff like FOV and automap are now in Tile_Map class. There is a class hierarchy confusion with Tile and Tile_Map, because in Tile_Map class sometimes there are simple getters that return Tile information from (x, y) location. It's not always pretty as it happens to be with getters, but I now know better not to spend time trying to create a perfect class hierarchy.

I think the tricky part will be lighting routines, because I'm planning to rewrite them. What I need is a nice line-of-sight routine for lights and a math implementation to light areas. Both can be difficult, at least for a programmer like me. I think I'm not going to use the main FOV routine for lights, but who knows, it may be easy to change it to work with lights. I've been thinking about the wall problem. It's a "bug" where a light source can lit wall from the other side (as if coming through the wall), because walls are usually 1 tile wide. I have some kind of idea how to fix it, but it's too early to tell if it works.

The biggest part will be terrain map routines. I'm trying to avoid Tile_Map becoming a kind of Level class itself and put only low level creation routines in it (things like shape primitives, rooms, etc.).

Wednesday 11 June 2014

Tile class - part 2

The refactoring from separate maps to a single map class with Tile class atomic has started. The bad news is that it can't be done quietly, so for a moment it's not possible to run the game. I'm not concerned about it however, because the refactoring "simply" consist of moving operations from maps to a map.

I've started from fov map and right away it was interesting to see how this refactoring is changing things. In the old system you get fov value from the fov map and then use it in the fov tracing routine. With Tile class you don't have to Get(x, y) from a map, instead the check is made in the Tile class itself which doesn't have location info. The tile doesn't know where it's located, but it of course knows everything on that tile, so fov check can be done simply by checking if the tile is blocking the fov (either by a terrain tile or some game objects). It makes some routines extremely simple compared to the old style.

Even better when Tile is the atomic of the map, it can hold any type of objects. Old maps were two types: int (or rather unsigned char) and game object type. I didn't want to write a template style map, that stuff is always so confusing. But now I can use type classes in the Tile for things like terrain tile. It's then easier to use verbose routines of type classes without first converting int map data to a specific type.

I think even now at the beginning of the refactoring it was a good idea to do this. As always this came a little too late, but I don't want to blame myself. It's possible to work with separate maps, but it starts to get complex when there are more than ten layers of maps. I also think that with Tile class it's easier to add new layers. It's the reason I started to think this refactoring, because I want to add at least two more layers (humidity and temperature maps).

Saturday 7 June 2014

Tile class

Today I was thinking about possibility to create a Tile class. The way it's now done is separate map instances for things like terrain, masks and game objects. When I started Kaduria it was a solution like anything else, but it has been difficult to manage maps since then. A combined Tile class would take lot of source code from Level class and place it in a smaller, more manageable class.

The bad thing about this is not a surprise: it's a big refactoring task. Is it really needed or should I just go with the current system? Maybe I should try to estimate the amount of work needed. It's maybe possible if you look at the calls to map handles, how and where they are used.

Saturday 31 May 2014

Bug hunting

Kaduria has 7 known bugs. It's not much, but some bugs can be annoying. This time I was fixing a bug that crashed when you threw more than one item on top of another. At first I thought it was a bug in stacking routine. Stacking sets a number to item's data, making it appear as "7 apples" etc. The good thing about this style is that items take less space, since 120 arrows is just one item.

Of course, the bug was not in that routine. I started to doubt it when the crash happened in the dynamic light map routine. It's checking items with light value, then displaying the light. Dynamic map makes it possible to throw a torch and see the light area in real time.

When the item is added to level there is a check for stacking. If suitable item is found, the original item is destroyed. As you can already guess, the original item handle was still in the item map, from where dynamic lighting is finding the handle... why it was there? I've found out that it's easier to actually change the item map when the item is flying, rather than use "a sprite" to represent the flying item. But the original map has to be restored after the item and the most important part is what happens when the item lands. Fixing the bug required two lines of code: set the item location to landing and update the item map.

The way stacking is done may be wrong, because each item has condition (physical, very exact). So any small damage to the item makes it incompatible with other, similar items. It may be possible that I have to reprogram stacking completely and use individual items which then are only displayed as a stack in the inventory and elsewhere.

Thursday 29 May 2014

Does editor font have to be monospace?

The answer is no. And as usual I learned this after 20 years of programming. Although in the first years most editors were text based so the only font type was monospace font. I've changed my editor font to Franklin Gothic Demi Cond and just look at it:

It's much better than monospace font. Monospace may be required in some languages but in C++ it doesn't matter, because tab spacing has no real meaning. Besides as you can see tabs wont disappear.

I think (and many others also do) monospace fonts are less readable than regular (proportional) fonts. Selecting more readable font is important, because it also increases the readablity of the source code.

Sunday 25 May 2014

Lights out

I wish I had more exciting news, but today I'm planning to remove light items from tools, because it's possible to put light items in tool and light slots, "double use" them. Usable items will also have a dedicated use command to use the item in the tool slot. It could be also nice to have a key for light slot to put off light fast if you need to hide in darkness. More direct keyboard commands is merrier.

There's been more than month's break in development of Kaduria. Not unheard of, but it reflects the problems I have in my so called real life. It's bad enough to have a poor quality of life, but it's even worse to be aware of it. That awareness sucks the most I guess. So what to do? I have plans... but if they work as well as the plan of Kaduria, we might have to wait for some time before anything happens.

Friday 18 April 2014

Environmental awareness

In July 2011 I wrote about environment actions. They are still there, unfinished... but it's like that with large scale projects. Today I was looking at the thing again and decided to add an environment type to all objects as a general way to tell where the object is.

The object can sit on ground like it was another sunny day, but it can also be in number of other environments like lava, pit and even at the middle of air. Complexity requires generalization with another type of class on top of terrain types (or main types in this case, another generalization).

The way I try to tackle this is first make sure objects always know where they are. It's a good start. Then actions (the same actions left from July 2011) describes what happens when the environment changes. I think it's a plan that might work.

Monday 14 April 2014

@ work again

First day at work, my job is an office assistant (computers mainly). It's annoying. I can't put it any other way. Well yeah, it's only 6 hours a day, 5 days a week, but it still sucks. When I get older I feel like everything that takes my time from game development is bullshit.

The biggest problem is that even at my age I still have too many problems related to my life. You think they could have disappeared by now, but no, they don't go anywhere until you make them go away. I haven't been successful in that and I always think it is somehow reflecting to what I have achieved as a game developer. You need to get rid of distractions before you can concentrate on what you do the best.

Maybe there is something good in this situation, because I feel an urge to find something better. Maybe another, better job? I wish it would be that easy.

Tuesday 1 April 2014

Delayed events

The re-ordering (still under work) of Creature class has been a success. It has made things more clear and I have also improved parts that have been unfinished for a long time. I regret that I left Creature class alone for quite a long time, but then again when you go back you often see things new way and know better how to proceed.

Currently I'm trying to think how to implement events. I don't want to use them more than I have to, because they can be tricky. Most events will be for traps I guess but there is one for lighting a fuse of dynamite. Of course there are problems. The event is including data about the object, but it's not synchronized in all cases.

Let's say you lit the fuse of dynamite. There will be a delayed explosion event at the location of the dynamite. However the dynamite can get lost in case you put it into a container and move the container itself. The location of items inside it are not updated, because it would be too heavy for even modern computers to handle. Just imagine if all items of all monsters would update their location when monsters move.

There are couple of solutions. You could include the container's id in the event (using its location) or simply search the item from containers if it's not on ground when the explosion happens to synchronize the location. Whatever the solution, I think there must be a two-way notification from event to object and also object to event, because the object can be destroyed before it explodes or something else happens to it.

Friday 28 March 2014

Clarity

When I went through Monster class I suddenly realized it's a mess. Somehow you look at the source code and it's just not good. It's slightly depressing and also quite odd, because how didn't I see that earlier?

I'm going to re-order class functions and try to create a better arrangement from small functions to the high level functions for AI and actions. I guess it's not a surprise that Monster class is difficult, because it's a part of the player class, too. The way how inheritance (from Monster to Player) is done in this case is not the best, but when I was programming it I couldn't think of any better solution either and I still can't. I guess you should isolate the basic functions for both creatures and the player, without any reference or difference to the player.

I seem to run out of hours per day which is annoying. There is so much more to do each day. They say that when you get older it feels like time is running faster. I think they are right.

Thursday 27 March 2014

Keyboard commands

I started to look at how keyboard command help is displayed. In most roguelikes you get a long list of commands in black and white ascii display. I decided to try something different. Rather than having one continuous list of commands I placed them on categories and this is a part of the command window:

I think it's much easier to find commands now, compared to the plain list. I guess 'fire projectile' could be an action command, but those can be changed later.

Wednesday 26 March 2014

Farm Simulator 2016

Simulating plant life is interesting, but sadly quite complex subject to handle. I'm currently revisiting plant game object class and trying to improve it in moderate steps, not trying too hard to create a complete system, but build firm roots for it.

Sometimes I have jokingly called Kaduria a farm simulator which it's of course going to be. What could be more interesting that watch grass and other plants grow?

Even I have now Mac Mini as my music studio computer I think it's somewhat unstable and unpredictable kind of computer. No matter how much people complain about Win7 it's actually super stable once you get it to run steadily. I think only problem with PC/Windows is the way Windows penetrates hard drive all the time, making HD the part of PC most likely to break in a long run.

Mavericks (I think it's the name of latest MacOSX or whatever) has crashed already twice, something that almost never happens to Win7 itself. I think OSX's unix background gives it some kind of ancient feel if you know what I mean.

Saturday 8 March 2014

Level themes - static or random?

One of the huge tasks in Kaduria are various level themes. As I mentioned earlier I gave up on trying to create a single engine to produce all level themes. I couldn't do it, it was out of my reach and also quite difficult to admit, since I'm such a genius.

But problems don't stop there. You still have to create themes that have the distinctive look, yet try to be as random as possible to increase replay value. It's a difficut task and I'm having problems even trying to create all themes in somewhat static form (always including some key elements).

This is a problem that gets harder if you want it. I could just let it go and create static themes and possibly even remove permadeath from the game. That way the player could complete each game and never have to run the first levels again and again. But removing permadeath would change the gameplay to more traditional RPG rather than roguelike, where permadeath is an essential feature, possibly even the most important of the key features.

Another possibility is create only few static themes and much more random type themes, or maybe select from couple of themes to get more variation in static themes as well.

Friday 7 March 2014

Mask map class

I'm back to Kaduria. It's useful to switch projects when something gets boring and you feel stuff is not going to proceed. Returning to project after a break often works, because it's then easier to get new ideas and solutions to problems.

Currently I'm working on the mask map problem and as terrain map it really needs a derived map class with a set of routines to return abstracted (the verbose public interface I have mentioned often) information rather than using enum mask values everywhere.

I have also developed a slightly different kind of way to look at todo list items and evaluate their importance and also the ways how to solve them. I think I'm now much less concerned about good (or even perfect) solutions. I've started to use a kind of sketch solution just to make something work. I believe it's much better than just staring at some item in the list and getting nowhere with it.

Thursday 6 February 2014

Action mode

One of the artificial intelligence ideas I have is action mode which has one selected at a time. In basic mode the character is adventuring or walking. Then there are modes like running and also sleeping (in voluntary way rather than fainting). The action mode has a big impact on what you can do at the moment so if you are climbing up from a pit you can't do anything else.

There might be a problem when you are floating on air and try to sleep. I was thinking of how to do that, but I guess the location itself can be an indicator that you are floating. Without it the floating could also be an action mode which would then make sleeping impossible when floating. Well, that's the stuff we roguelike developers need to think.

I like the idea of action mode, because you can choose between walking and running etc. Running will spend stamina (and food) faster, but you can use the faster moving speed when needed. The action mode will be displayed on screen all the time so you don't have to check it out from some stats screen.

I've tried to concentrate on AI programming and action mode is hopefully going to clear some confusion in that part. Sometimes it can be difficult to figure out what belongs where, because there are stats, then affects (illness, burn wounds, etc.), different motivations for creatures, current task and action mode. It's possible that I forgot something. Most of that stuff has effect on something else. It's not obvious that the gelatinous cube is on fire while swimming and at the same time eating bisquits and tea.

Friday 24 January 2014

Data-driven class design

As if my normal posts weren't boring enough, this one is about programming. I'm a big fan of OOP (object-oriented programming) and have tried to apply it in my projects. But working with a legacy project like this I'm constantly fixing style mismatches with traditional C's linear programming style.

One of the basic ideas and building blocks in Kaduria is a data-type class that has a simple value stored (usually with accompanying enum list) and a verbose public interface. As an example there is a problem I'm working on right now. It's the mask value for mask map. In plain old C you would use enums like this:

if (mask_map->Get(x, y)==maskWall) Do_Something();

(Actually I'm using coordinate parameter for location, and x, y is used here for clarity.)

That maskWall is a "linear" or plain data. Using a datatype class things change a bit:

K_Mask_Type m=mask_map->Get(x, y);
if (m.Is_Wall()) Do_Something();

It's doing exactly the same thing, just with minor difference of using class and a getter routine. The m value is simply the mask value in the map, stored into K_Mask_Type as the only variable which then can point to the data associated to mask value. Is_Wall() can look something like this:

bool K_Mask_Type::Is_Wall()
{
  return mask_data[type].is_wall;
}

But it can also be a switch statement or any other way to handle data.

The problem with first way, old school C, is that you might want to add another mask type which is also a wall. When you do it you need to write changes in all places using that statement, for example like this:

int m=mask_map->Get(x, y);
if (m==maskWall || m==maskCorridor_Wall) Do_Something();

As you can guess, the great thing in class style is that you can add the new mask type, but Is_Wall() can include it and you don't have to search for those if statements in the source code.

It's not all good, because you can have legacy code that has both styles mixed and it can require more than just simple if statements to be changed. Also, the way the class itself is written can become complex as you add verbose functions for each of features. In this case the getter/setter syndrome is not actually that big problem, because that's the way it is supposed to work anyway. You can go wrong with class functions, too. But often they hold a logic which works through the project and when you add something it's less likely that something breaks elsewhere.

The verbosity of class functions is not something I would have thought means anything when I was still learning OOP, but it's of course a powerful way to write source code along with "class as type" classes. Often when people think of classes they are already thinking inheritance and other more advanced things that in my opinion are less important! In fact when you get to the next level you try to avoid inheritance at all costs, because it's a complex topic in which many things can go wrong, starting from the way you plan the class hierarchy. For some people it goes as far as inventing their own meta-language using templates.

I think many C++ books are to be blamed on how we see classes and immediately associate inheritance and "easy" re-use to them. Far more important is the data-driven idea: hide the raw data in the class and use (verbose) public interface to avoid refactoring through the source code when something changes. And as we know in case of roguelikes there always will be changes.

Wednesday 22 January 2014

The hatch

On halfway of nine selected todo items I ran into a problem. There are some door type (lid) objects on top of stairs or sewers. Those objects are created on the same map as other objects that don't move, including stairs. When you create a hatch lid on stairs and open it the stairs are not displayed. More than that it also affects to object interactions (collision detection etc.).

The layer system of maps is already complex, but I could solve this by creating another layer for door type objects. Or I could create a stacked object map with std::list for each tile. Whatever the solution were it would also include collision detection logic etc. In other words a lot of work.

I was thinking of this for a while and decided to skip it. Just skip it for now. Lids are needed for sewers and in rare cases for stairs. It's not an important feature right now and because it's pretty big change to the engine I want to make sure that other more basic features are done first.

Wednesday 15 January 2014

Update areas rewrite

There are rectangle areas dividing screen in parts and update each of them when their flag is set. At least with software mode of SDL this is a good idea, because it certainly does speed up the game compared to full screen update. Besides not only updates, the background graphics are also re-drawn when something happens in that area.

I've been refactoring those areas, because I needed to change message output to 5 lines and scrolling mode. The ancient nature of GUI was revealed when I noticed that almost all actual output to those areas were hard wired with another set of coordinates. So.. this is how it looks now:


Those purple dotted lines show the areas as debug method to actually see where they are. I already fixed the small map, but as you can see the gameview is in wrong place and stats also (and some areas itself), displaying only the last line: Water. This is a minor fix however. From now on the content coordinates are retrieved from the area data only and in future I can easily change the locations of areas if needed. One possible option I can think of already is switching the places of location (bottom line) and messages.

Saturday 11 January 2014

When it's done

The first item of 10 hour todo list was easy. Then I realized before doing anything else I have to fix the message routine, just like I did for Teemu. This time of course I can use new parts of Teemu's routine, but even then there are work to do with Kaduria's message system. Like with level generation I once thought it would be nice to create a complete engine for messages, but it became too complex and unwieldy for what it was supposed to do. So, rather than trying to make the system work in one way I'm using several different ways that all ultimately use the core routine.

People often ask when Kaduria is ready. It's getting annoying. For a long time I've planned to release the game without telling anyone. Just download the first version in the homepage of Kaduria and let it be there until someone finds it. Let people keep asking when it's released and all the time it's there.

Wednesday 8 January 2014

News

I have a new plan for Kaduria which is choose some items in todo-list and give them an id and estimated development time. Then follow that order and try to implement them. It should be easy and I already chose ten hours of programming for nine items.

Some items can't be implemented without knowing stuff related to them. It's the difficult part of game programming when you don't have a detailed plan or you don't yet know how stuff is going work with other stuff. It's also something I have to concentrate on better.

Those 9 items are about 20% of all unfinished items in the list, not counting level themes. The reason for that is that level themes are too big to be in todo list anyway, first they have to be broken into smaller pieces, because many level generation techniques are reused in other themes. That 20% is not accurate also because there are more "todos" written in the source code directly.

This new plan should be better than just looking at the source code puzzled what to do next.