Showing posts with label pre-alpha-3. Show all posts
Showing posts with label pre-alpha-3. Show all posts

Saturday, September 3, 2011

Two of each

Wow, not only did I switch over to Google Chrome because Firefox was just full of bugs when working with Blogger, but Blogger has offered me the option to switch over to a new interface and now I can't find anything. Oh well, maybe this new interface will prove to be better. Blogger is not as good as WordPress IMHO, and I am starting to regret having created the blog on Blogger and not on WordPress.

Anyway, getting sidetracked.

I've been kind of busy, yet I think we can call pre-alpha-3 finished. I looked over the planned feature set and except for snow, buildings and crafting, everything is done. Instead of these MIA features, we have some new ones that were not planned. I'll probably post and updated feature list, but the important thing I need to talk about is that this model is not working.

Choosing a feature set that seems like a good idea and working for months to complete this list, while my plans for the game evolve naturally, often invalidating the list, is not a good idea. I would probably work if there was and organized developers team, but it is just me.

Instead, from now on I will set smaller goals that can be designed, tested and implemented in 1-6 weeks. The goals will also be able to be developed in fair isolation, so that the code base feels like getting and add-on, not a rewrite. Since there seems to be no escaping the subject of Dwarf Fortress anytime soon, I'll add fuel to fire and call these goals arcs. There are two types of arcs. The first type is meta arcs, that have no real content of their own, but consist of a lot of normal arcs. These meta arcs try to bring a big feature to the game, and the division into small arcs helps with developments and tracking.

Currently, I will be tracking four meat arcs:

  1. "Take". This arc consists of all the operations that involve a dwarf, a tool and doing one single action that changes the environment, often taking or modifying natural world resources. This is what I have been largely working on up until now and consists of all the operations one can do on walls, plants, stockpiles, etc. This meta arc is largely finished, but one last pass must be done on floor and wall building from boulders and bricks. Also, the carve list is not customizeable with the editor, which seems like missed potential.
  2. "Build". This meta arc consists out of one functional component that serves as the framework for defining and building structures and one arc for each building. I will be executing this meta arc based on plants: for each produce for a plant I will add the necessary workshops, checking of arcs as I go.
  3. "Wear": a meta arc governing a very complex wearable equipment and clothes system for dwarves.
  4. "Fight": the fighting model. I am not sure yet, but I am starting to feel like combat is going to be turn based. Think Heroes of Might and Magic, but with fights on the entire map and each dwarf having special attacks based on their weapon skill. An untrained fighter will just try his best to make contact. A trained fighter will have the option to try and take advantage of holes in the opponents defense and hit sensible spots, causing extra effects with a greater chance.

These four meta arcs are actually the post "Stoneage" version of the game. Rather than having to worry about the entire feature list, I have small goals that I can try and implement one by one.

I'm hoping this system will be easier to manage.

As for the IndieDB launch, I am working on it right now, but it won't be up today. Maybe not even tomorrow. Should have not scheduled something like this for the weekend.

PS: I am starting to like the new design for blogger. Still a bug or two. Give it more time...



Thursday, August 18, 2011

pre-alpha-3 – A* updates

Phil was kind enough to point out a link on the forums about A* and I also did some extra research, and I realized that obtaining the fastest A* algorithm is a very complicated task that depends on your exact needs. While the core of the algorithm is always the same, the small implementation details and data structures that are used count a lot. So I would have to rewrite everything form scratch and I don't want to do that right now, since my A* optimization was just so that I could fix the issues I talked about last time.

But I did do one more round of optimizations: I optimized the central node container. The recommendation is to use a priority queue but I do not think there is a name for the thing I am using. Anyway, I won't bore you with all the numbers. Suffice to say, that in release mode, with 700x700 maps, the algorithm finds a path in 45-50 ms with any kind of map: empty, maze or just random. Nice improvement. I'll leave it at that. At normal map sizes, it takes at most 10 ms and the average time over the usual distances is 3-4 ms.

This is when I realized that there is a huge bug in my algorithm that has been there from the start. I tried to fix it, but the fixed A* is about 8 times as slow as the broken one. My algorithm shouldn't even work. After some testing and experiments, I think my algorithm degrades to a very quirky version of Dijkstra's algorithm. This is probably why the performance degraded so much when the explorable region was big with my less then optimal container implementation.

I really should prove my conjuncture that my A* degrades to a Dijkstra's, but with the current performance I won't bother with it now. I'll leave it to when I do not have anything else to do.

Wednesday, August 17, 2011

pre-alpha-3 – Day 17 - More Stone Power

The polishing process continues.

I started by tackling the floor operations, fine tuning panels, adjusting skills, balancing, testing filters, etc.. This is the floor operations panel:


And this is the tool tip:


Short as always, but hopefully informative and enough to give you a starting point if this is the first time you pick up the game.

You may notice that the beatify option is not present for floors. I added the beautify options for walls to combat the frequent forgetting to issue an engrave action after a smooth action when engraving is the end result you are after. But I realized that this system is silly and adds complexity without adding depth. Combating such poor interface choices is one of the reasons why this project exists after all! I can already imagine the conversation between the expedition leader and a worker:
"Hello Myorlin! Do you see that wall over there?"
"Sure boss!"
"I want you to engrave it!"
"Can't do that boss!"
"Why?"
"Because it is not smoothed yet. You see, that wall has a very rough surface. A fellow dwarf was in a hurry to dig out a passage. I need a smooth surface to carve into, smooth as my bottle, that be the way how smooth it be must."
"Can't you smooth it first and then engrave it?"
"Sure I can! I can do anything! But you need to ask me to beatify the wall! You asked me to engrave it!"
"Beautify? What does that mean?"
"I take the wall, I engrave it, making sure that I smooth it out where needed. It is really efficient! It will even take me less time to do than first having to smooth it all and then engrave it! Alas, you asked me to engrave that wall. And listen to me: there is no way I can engrave it without it being smooth. If only you asked me to beatify it!" 
"You are an idiot!"
As you can see, any justification or rationalization can be thrown out the window: why can't you just give an engrave order, and if the wall is smooth the dwarf will start engraving, and if it is not, he will adjust the time needed to engrave dynamically based on the amount of work needed for the smoothing operation. This is what I did for floors and also applied the same principle to walls. So now engrave works on all non engraved walls, having a duration of 100%-130% based on now fast that dwarf could finish the operation. This is a perfect case where thinking stuff through and streamlining without loosing depth really pays of. I think the new system is even deeper.

But you may ask: if the engrave operation does not take a lot longer than a smooth, why would anyone smooth? Because smoothing and engraving have different outcomes. It is hard to see, but here we have a sample of some smooth floors arranged in a rectangular pattern:


And here we see the result of engraving:


Ah yes! Remember these patterns? These engraving patterns are actually the content of my first two third party mods. A while ago I asked for some engravings and this is what I got. It is a little bit hard to tell, but I used engravings to create the text "HELLO FROM DH!". The official engraving patterns will be slightly better suited for the visuals of the game, but the important thing is that I am running my main mod and two third party ones.

Another thing I have noticed is that the walls/floors duality inherited form DF can seem awkward at some moments. In DF it is less apparent, because floors are abstract and have no real height. But in an engine like mine, where floors have actual height, taking a short chunk of rock and calling it a floor and taking a higher chunk of stone and calling it a wall does not make that much sense. I'll think long and hard about it, but I can imagine a system where these chunks have different heights, and a floor is nothing more than shorter chunk. In this system different height blocks could be freely mixed.

Now on to bigger fish! With most systems greatly improved, there is but one system that I did not touch upon: A*. Now my A* is probably not the fastest out there, but it is fast enough. But it does have one huge disadvantage: the performance degrades direct proportionally not only to the length of the path (which is normal), but also based on the number of obstacles the algorithm can handle. These obstacles don't even have to be around the path. It would be great if I could improve this situation.

In order to properly test this, I'll create some custom worlds specially for A* testing:


Ohhh, look how cute and small it is! A single dwarf starts in one corner and I will give an order to dig something in an opposite corner. I just created a small map so you can see the shape.

I will be testing with 700x700 worlds. At such high map sizes A* is certainly a resource hog. Let's see some results where I measure the time it takes for the algorithm to do the path finding, in debug mode:

387.2084301 ms
388.3904938 ms
386.1530586 ms

So around 387 ms. It may be a resource hog, but it reasonably fast. It is going to be hard to improve it. I probably need to do tests on  a slower computer. I'll try a more complicated layout, forcing the dwarf to walk a long path though a simple maze:


Let's see the results for this pattern, but with a 700x700 map:
141.3050402 ms
141.6633958 ms
147.1755488 ms

OK, OK... I may be fast enough. It is even faster this way, because while the path may be longer, it does not have enough place to explore. A* depends a lot more on the total space it explores until it finds its target than on the length of the path. Still, let's try and optimize it, but using the simple straight forward empty map, on which path finding takes around 387 ms.

The result is around 350 ms and for the maze map around 125. An OK improvement and now the engine can handle any number of obstacle types without affecting the performance. In case you are wondering, in release mode, on a 700x700 map going from one corner to the other on empty map the time is 210 ms and on maze map around 45 ms. I am really curious what the performance of the top A* algorithms out there is. Any hint would be appreciated!

These tests also revealed a few big bugs, like some visibility functions being able to go outside of the map. I hopefully fixed these bugs and I added some extra asserts to these functions and added a new map sanity check pass after map generation.

The A* chapter is not finished, but today's experiments certainly helped make DwarvesH a lot more stable.

Tuesday, August 16, 2011

pre-alpha-3 – Day 16 - Stone Power

Cheers to another very fruitful day of polishing and bug fixing!

*CHUGS DOWN A BOTTLE OF DWARVEN ALE*

I have slightly redesigned the editor: using the menus was very cumbersome because you had to swap a lot between all the tabs. I removed the menu and added a vertical toolbar that nicely takes advantage of today's widescreen predominance:


The icons are not that pretty, but they are fairly self-explanatory, have tool tips and are diverse enough to be easily memorized if all else fails. Now I can easily switch between the tabs and I'm thinking of assigning keyboard shortcuts to all the tabs.

This was a usability/cosmetics change. Now for the real deal: two of the action groups are now fully realized, being 100% parameterized with the appropriate skills and pretty much ready for QA. In my previous examples explaining task filters, you may have noticed that tasks used to depend on some field from a class called EngineParams. But there is a better place to define these constants: in the skill editor!


Here you can see that the mining labor from the miner skill gives 100 experience points, has a duration of 7200 seconds and consumes 0.01666666667 task specific energy (a second). Skills now gain XP, but I'll wait with actually implementing leveling up until I balance the game. Speaking of balance, the game is pretty poorly balanced right now. It will take a lot of play testing on my behalf and others until the balance improves. Just to give an example: two hours raw dig time is not a good value. The difference in energy and time between a novice and master miner is pretty much negligible. If you are not under attack you have plenty of time to use an inefficient dwarf for digging or take another dwarf from another task to finish quicker. With two hours, the game does not incentivize you enough to use the best dwarf for the job and thus you won't appreciate and get attached to your top workers. And you won't miss them when they die gruesome deaths. After a little play testing, I think that a duration of 6-8 hours is more aproriate for a skill 5 dwarf, and every point could knock off 20-30 minutes from that. This way your master miner will do a lot more wok than a novice. What do you think?

Here is another sample skill:


Stone detailing is still physical work, so you get an energy penalty, while in the case of gem setting you do not. The durations will get increased.

I also redesigned the skill system and now, for the first time, it is capable of handling any skill, not just a few that have their logic implemented in the game engine. There is one caveat though: these skills must be production skills, i.e. take any number of items, any workshop you wish (official or from a mod) and must produce some goods. With this new system, it is possible to create a mod that adds a new skill and a new industry to the game, and your dwarves will be able to learn and level up that skill.

With the skill system in place and task filters from the first two task categories using the system to its fullest, I went in and updated the interface for these categories.

This is the new "wall actions" panel:


Oooooooooops!!! This is the new "wall actions" panel:


Carve options have been removed and we have two new actions. These actions are not planned for 0.1, but they will be part of the final game, so I though I should add them now. But what do they do? Let's see if the popup helps a little:


"Fortify wall" is an operation with which you use a wooden log to better support the wall and the ceiling. In the future I'll implement wall and roof collapsing. I don't want this to be to stressful, so for average size rooms you won't need to fortify walls. But for huge rooms, you will probably need to. But you will still be able to use it anywhere, even if it is only cosmetic.

"Decorate walls" will allow you to place things on walls: wall carpets, metal plates, paintings, flags and what not. And in the far future, when steam punk mechanism, logical gates and "circuit boards" will be implemented, you will be able to place triggers on walls with this action. Until then, this option will serve only a cosmetic purpose. The difference between this and engraving is that engraving is a action that carves out small pieces out of the wall to form a pattern, while decorate takes a finished item and nails, glues or otherwise attaches it to a wall.

Carve options have been moved to their own panel:


The entire carving system has been greatly cleaned up. Only chairs and "cests" are passable. Some spell checking is still pending! And a couple of option are still missing. In a future version I'll replace these buttons with an icon grid, because some items can have multiple angles, like stairs.

And finally, the quick dwarf inspector now uses obscure three letter words to show you what dwarves are doing:


I hope I did not forget anything, like I did in the last post. I forgot to document how map caching now takes up to two multiplication less per tile, bringing the grand total to zero multiplication per tile. This should improve performance a little.

Monday, August 15, 2011

pre-alpha-3 – Day 15

Let me start by thanking again everyone who donated! Your help is greatly appreciated!

You may have noticed that this pre-alpha is longer that the previous ones and the number of altered subsystems and overall polish is higher than usual. One of the reasons why it is taking longer is graphics. During the last 10 days I spent a lot of time trying to find the best way to give DwarvesH a new and original look. During this process I tried several things, including outsourcing, and right now I'm not exactly sure with which artistic direction to continue, but soon you'll see some new samples.

But the main reason is that I have changed the way I work and what I do in such a phase. The initial plan was to go over the 0.1 feature list and make sure that as much as possible is working well and then to adjust the next feature set plan. But I changed this approach to one in which I try to make sure that every single feature that is on track to make it into the final design of the game is perfect and fully implemented, without using any placeholders. I have a vision for most of the features. The implementation of said features varies from zero (combat as an example) to placeholder implementation that will probably be drastically changed (weapons and weapon skills are already in the game, but I am not advertising this because I know that the system will be changed) to good implementation that might lack some depth and polish to finished features that will probably make it 1.0. If one one these finished but lacking polish features is something that I want to have in the final game, during this pre-alpha it will get finished and extensively tested.

In consequence, version 0.1 will have less features, but almost everything will be near final implementation and bug free.

So next time you will see the final shape of the plant system (and a little bit even today).

I am in a hurry to write this post because Firefox is driving me crazy with its Blogger bugs. Using the WYSIWYG editor has been lately a huge pain. I can barely insert an image without everything getting messed up and I can't use bullet points.



Added error reporting
During game start up, if something goes wrong, the game will print some messages on screen. This dialog is probably not the best looking thing out there, but it sure beats the game crashing, freezing or otherwise misbehaving:




Visually countable harvested plants
Now you can tell by looking at them how many harvested plants are left in a square. The graphics are just placeholder right now, and food stockpiles do not yet have this feature:



IPS improved
The Incremental Proxy Storage is my home brewed method of storing maps in a relatively very small space without sacrificing speed. Unlike other methods of squeezing out every single possible byte, this method still maintains an OOP interface to map access and thus is still pleasant to use. But it does have some disadvantages too: it is fairly verbose to create an object inside IPS for the first time, it is not too easy to change properties, it is very hard to change structure and it is vulnerable to order and count changes. The last two points relate to saving the map as a save game. I tried to fix these vulnerabilities: creating items is now very short, changing properties remains at the same difficulty, but now this difficulty applies also to changing structure. For the last two, I need to explain the save system.

I have separated the save file into two files: the first is the ruleset and IPS for your game and the second is your raw map, saved and compressed. DwarvesH is a complex game that is getting more and more complex, thus there is no way for me provide compatibility between save games from different versions. This is where the split into two components helps. If you want to migrate to a new version, you need to create a new map under the new version, copy over the new saved IPS together with only your old raw map from the previous version to a new location, and with a bit of luck, everything should work. This is the maximum level of compatibility that I can provide. Making a save game importer for all versions would be an extremely difficult task.

IPS has an item order vulnerability when doing the above method of updating a save game from a previous version. If you change the order of some items from the same category, this order will cascade and apply to all your derivative items creatable from the original items involved that have changed order. So let's say you have a version 0.3 save game on which you played for weeks. Version 0.4 comes, the IPS migration happens, but version 0.4 has swapped the order of blackberries with a mushroom. When you load, all blackberries will be mushrooms and the other way around. So too will be all the items that have as a base material one of the two items. There is no way around this and this misfeature is not that bad: it is a lot better to be able to load your fortress on which you have worked a lot and risk a few small changes then having to either restart the fortress on the new version or be forced to keep both versions installed on your disk. It is perfectly fine if some people choose two keep more versions, but you shouldn't have to be forced to. So this vulnerability of IPS can not be fixed.

The count vulnerability is similar to the previous one, but this time the number of items changes, either because the new version added some new items, or because you are trying to change the mod loadout on a saved fortress. This vulnerability is fixed, but it does have some limits. IPS now intentionally has "holes" to accommodate more items. I added generous padding, but it is still possible to grow over its limits. This is a mechanism that protects fairly well against accidents, not against intention.



Reimplemented world generator
The old "incline hill" map generator was one of the first things I did with world generation. The code was old and not that easy to change, so I redid it in a way that hopefully bridges the gap between it and the random landscape generator. I still need some testing before I can start using the random one regularly. The new implementation also fixed an old and ugly bug.



New reachability algorithm
Ah yes: this is the star change of this post! As said in the past, A* is a poor choice for determining if two points can be connected by a path. If you know that at least a path exists between those two points, then A* is great not only at finding a path, but the shortest one. Maybe too good. It is sometimes weird to to see dwarves move with near clairvoyant path finding on an optimal path. Back in the day I added a little noise to it to provide a less "robotic" and a more "human" feel to it. Here I go again, ranting. So I use another algorithm that can tell me if two points are reachable and which caches this information for the entire map. I changed the algorithm itself to be faster and limited to the area that dwarves can explore at the current moments, so you can have any number of hidden enemy caves that have yet not been discovered without pathfinding taking a hit. Then I replaced the backbone worked of this algorithm: I went from a "vanilla" flood fill algorithm to a very fast scan line fill algorithm. The end result is that the new system uses barely any memory (while the old one ate it like crazy), and the speed in the reference interval for normal maps went from 35 ms to 8 ms.

As a test, I tried it out on a 6000 square meters map: again, barely any memory used and 270 ms speed. Pretty good! Wait... 6000 meters? That is more that last time. Well, all the performance, memory use and stability improvements that went into this pre-alpha had an indirect effect on the game, and the old limit of 4500 square meters is now exactly 10440 square meters! Again, I do not want to create such large maps. This is only a stress test. But it is good to know that without actively working to achieve this goal, the engine can now run maps with an area 5.3824 times as large as before. And the best part is that while last time I could not go over 4500 square meters area because of a weird segfault, this time the engine fails with a simple out of memory error. This error can traditionally be fixed by installing more RAM, but my case is different because I am near the limits of a 32 bit executable.

Wednesday, August 10, 2011

pre-alpha-3 – Day 10

Not every post can have something exciting in it. This goes double for posts in pre-alpha phases, when often you must do the low level fine tuning. The devil is in the detail, as they say.

Changelog: 

  • Coordinate system fully 3D now. Regular readers may be familiar with the fact that I already switched over to a 3D coordinate system for tasks. Well, this is a long and tricky process, and last time I made sure that interfaces were using 3D points and also the implementation was, when needed, but the really low level internals would still drop the Z coordinate. Now, the entire game uses 3D coordinates! Even the A* implementation takes such coordinates and returns a 3D path, but the actual path finding is still limited to a 2D plane. Trust me, having the game fully take advantage of all the Z levels will be a major announcement, not a small point in a changelog.
  • Task lists now actually use lists. Another pending internal change. This should be more efficient and better suited for task lists, where items constantly jump around.
  • Cleanup of DHCore continues. This package is starting to look pretty good and soon will be better suited as a general purpose library, rather than a single purpose (serve my game) library.
  • New action: beautify walls. Even when testing this has happened to me: I want to engrave some walls, give the smoothing command, get side tracked and realize later that I forgot to give the actual engrave command when smoothing was finished. This will undoubtedly happen in a real game for a lot of people. So I added the beatify command, that can only be applied on natural non-smoothed non-engraved walls and is basically a smooth combined with an engrave action, but executed as a single task. It also costs only 80% of the time it would take to first smooth and then engrave. Just a little quality of life thing. PS: The wall option panel is getting very crowded. It is probably time to separate the carve options to their own menu.


  • Started modularizing tasks resolution. Gah, I can't find a way to explain that in the language of mere mortals.
  • Implemented a high resolution timer. I have been having this problem for a long time: most timer objects, including Irrlicht if I am not mistaken, use this little thing: GetTickCount. A very useful function, but as said also in its documentation, it has a resolution of 10-16 milliseconds. This is great for most tasks, but sometimes it makes this function unusable. Let's say you have an A* implementation that takes 30 ms to find a path, and you would like to optimize it to only take 20. With a 10-16 ms resolution, you are utterly incapable of measuring such an improvement. After scouring the Internet, I put together a high resolution timer that is even less portable than the above Windows API function. This timer is even capable of using multiple CPU computers to improve the precision of the measurement. In theory. In practice I have no way of telling that. I ran a few artificial benchmarks to test it. In these tests I ran a test 10 times: wait 30 ms and measure the precision of the timer, logging the absolute difference between the 30 ms known interval and the measurement, and determining the total and average deviation. Here are the results, first for a average test:


As you can see, the high resolution times is extremely precise, while the normal timer, during ten tests, accumulated a  total error almost equal to the duration of a single test. Once in a while, you get lucky and GetTickcount returns quite an accurate results:


But the HR timer still has it beat and is very predictable. I do not know what resolution the sleep function I am using has, but if the HR timer is to be believed, it is quite accurate. Using this timer I am going to try and greatly improve the A* and reachability calculation algorithms one last time during this pre-alpha phase.
A long long time ago, in a galaxy far far away, somebody on the Internet thought that such massive changes to the task system went over without causing any bugs. And he was wrong! Surely there are a few new bugs that will get squashed. On the other hand, the new system also probably fixed a few existing bugs, like when you give the same order on two different Z levels.

And if you still want something exciting, later today I should be introducing the donation system!

Tuesday, August 2, 2011

pre-alpha-3 – Day 2 – A GUI without licht

Regular readers of my blog may be aware of the complicated history of the GUI backend in DwarvesH. Right now I am using a mishmash of regular Irrlicht widgets and widgets from my own custom lightweight GUI system created specially for the game.

Such a system is not going to cut it for release, and I removed all references to Irrlicht GUI code. The entire game now uses my own custom set of widgets. These widgets only rely on Irrlicht for drawing primitives and reading the user input, so it is very easy to port it to any toolkit under any platform.

Changelog:
  • Irrlicht no longer used for GUI.
  • Custom GUI system received a focus handling system. It is very rudimentary, but it does the job it has to well. Testing will iron out bugs and maybe I will expand upon it a little.
  • A fairly competent keyboard event handling system is in place to send key codes to widgets. It is slightly held down by the subpar focus system implementation in cases where key presses must be sent to the currently focused control
  • ListBox new custom widget, replacing the Irrlicht one. It handles item operations and responds to keyboard and mouse events. Does not have a scrollbar yet.
  • Dropdown combobox Irrlicht widget removed and it will not be replaced with an equivalent custom widget. I evaluated my GUI and right now I do not need this widget. I was using the Irrlicht one simply because it was available, not because it was needed. The layout for some windows was adjusted, replacing dropdowns with listboxes.
  • Rudimentary EditField custom widget added, replacing Irrlicht one. It is rudimentary because it does not yet handle the plethora of keyboard commands it should and does not support copy and paste.
  • All widget classes now have proper final names. Custom and Irrlicht widgets names sometimes clashed, so I had classes like Label and Label2. Now there is only one set of widgets and names no longer end in "2".
  • Mystery bug updates. DwarvesH has a special run flag that allows you to skip all world setup and dive directly into a random generated map. This is what I use for testing. Surely you do not believe that I click though N windows before I can dive into the game, do you? This flag is almost always turned on for me. But when I turn it off, the main menu is displayed and I can create a custom world. I noticed that when running the game with the flag off, once I get to my map, there is a steep FPS drop (around 100). Some resource must remain active during these menus that is a real performance bottleneck. I repeatedly failed to find the bug. Now, with the new GUI system the bug seems to have disappeared by itself. The map renders at the same speed with both setting of the flag. On the other and, I am experiencing a flat 20 FPS drop in both modes. I must investigate further. Something is still fishy around here.
  • INI file has new field for bits per pixel and vertical sync. The Irrlicht documentation claims that it can ignore the vertical sync flag silently. And so it does. Maybe it respects the flag only in fullscreen mode. Or maybe I must buy it flowers first. Take it out to a nice dinner. More investigation is required. Bits per pixel seems to be respected, not way to truly tell.
  • Removed the awkward top level control "activation".
  • Classed associated to top level windows no longer have a widget member variable to host all children widgets. These classes inherit now from the TopWindow class.

Except for that strange bug and Irrlicht not doing what I tell it to, I am very happy with the way the GUI code is progressing. The code is much cleaner now that only one widgets system is in place. It still needs a lot of time to mature, but by version 0.3 I'm sure it will suit my needs perfectly. That is if I do not change the widgeting system! Again!

I'll leave you with a single screenshot of the GUI without Irrlicht. Notice the look of the widgets and the layout, not the generally outdated content of the window that has not been updated wit the new design for the game (but will be during theis pre-alpha phase):




Monday, August 1, 2011

pre-alpha-3 – Day 1

Since I just posted post number 50, I am only a few post away from the next pre-alpha and today is August the 1st, I decided to get started on the pre-alpha a little-bit early. I will also add a few new features, but in pre-alpha posts I'll just refine existing features and in normal post I'll add new ones. There is also going to be extensive testing. This is the final pre-alpha before 0.1, so by the end of it everything needs to be perfect. Or at least as perfect as a huge ham.

These posts may not seem that interesting, since a lot of the content is going to be a slightly detailed change log.

One thing that may be more interesting is that I am redesigning the old API from the support library. DwarvesH consists off three projects: a library, the game and the editor. The library was designed to only be used by myself and not to be made visible. The new design dictates that the library should be written as to allow any client to use its features. I'll try and make it public in the future. With this library anyone (with talent, skill and a lot of time on their hands) could implement a lot of features that are present in my game and the two would be compatible. And third party tools would have the advantage of never falling behind the official game, since all that would be needed is a recompilation once a new version of the library comes out. So the library must be very well designed, but at the same time must never sacrifice performance, even if it has to sacrifice readability.

The above paragraph for people familiar with Dwarf Fortress and the tools from that community: you do not need to reverse engineer the map format or write a tool like DFHack. DwarvesH will provide these for you though an API. The plan is to make this API public and write very little documentation for it. But C++ is very readable so you'll have no problems there. I may change my mind if a good reason comes up not to make it public (legal, hackers, greed, etc.). No deadline for the public API.

Changelog:
  • Map size is the same as advertised. If you are a programmer and are used to working with matrices, you may be familiar with the concept of bounding borders. The idea is to insert a dummy border with invalid data around you matrix, so you can compact bound and validity checks for points that are adjacent to your current point. It is both a performance, robustness and quality of life thing. The problem is that your matrix is a little bigger. Or in my case, a little smaller, since my 300x300 maps had an effective usable area of 298x298. This is corrected now and maps are created to compensate for this border with a plus 2 to each dimension.
  • The map is not dynamically allocated and structured as planes. Believe it or not, the map used to be statically allocated. The map is accessed so often that the only viable solution was to make it a global statically allocated entity. A new API has been introduced to give access to cells and floors. The whole game now uses the new API. The API uses natural coordinate orders, so we have x, y and respectively z, rather then the hardware memory layout dictated order of z, y and x. This was a huge change, and while things seem stable right now, there is a good chance I broke something. A positive side effect of this is that clients of the library, like the editor, no longer consume memory in order to store a map (unless they ask to), so the memory consumption of the editor has been drastically reduced.
  • Removed some outdated non-OOP style methods from the map handling API: TileIsEmpty, TileIsWalkable, FloorIsValid and FloorIsGrass. Proper OOP API is available.
  • In order to better prepare for beta testing and better simulate computationally intense maps, the map is always allocated as 700x700x100 (7002x702x102), even if you choose a smaller size. You can only use the size you selected (you do not know how much was actually allocated). This way I can test the game using a lot more RAM than needed. If it runs well while using a lot of RAM, it will run well when it uses less too. New RAM consumption for test phase is 320 MiB.
  • Rule set serialization code cleanup. -49 LoC.
  • The internal namespace that I was using was called "World". Now that the API is changing its format, the new namespace is called "DH". This may seem problematic, since I am changing the name of the game, but the engine is still called DwarvesH, DH for short.
  • Reachability cache moved into DH namespace.
  • MapGen class that stores the map creation parameters chosen by the user has been improved, moved to DH namespace, has its own source files and supports serialization. Once the overhauled save system is done, world creation parameters will be also saved into the savegame, even though they offer no practical purpose.
  • Removed extremely outdated snow code. Snow and snow remove operations have been removed from version 0.1. Initial biomes won't have appropriate temperature during winter to trigger snow fall.
  • Misc stuff moved to "util" module.