Here is another half new features half pre-alpha polish post.
Map renederer moved to its own widget
The map handling class was getting very cluttered, so I isolated all the map rendering, cursor management and mouse collision detection code into its own class and widget. This was done mostly with copy and pasting, but with a slight redesign of the interface for this widget, I will have a very good general map rendering component that can be dropped anywhere in the UI. This way I will be able to create multiple windows with different functionality and GUI, but which all show the same map, by simply inheriting from this base class. I will be creating an "AI Playground" mode soon with this facility.
Mining code given the final polishI talked about how I finished the mining skill and mining task last post. I went in again and made sure that it is well designed and bug free. During this pre alpha all the skills that I have in the game will start to affect their associated jobs. The reason that I am bringing this up again is that I am going to show the code for this task again. I usually don't show code here because I want to keep the blog non technical, but I have already shown this part of the code once and this is good opportunity to show how its complexity has changed over time:
Task scheduling is basically the most important part of a game like this (together with path-finding). Nevermind the performance. If your dwarves are doing something stupid you won't care that you have 300 FPS. Creating one task can be hard, and there are a lot of tasks, several of which interact and have multiple phases. So I came up with the above design to handle these complex tasks. Every tasks has such a class. The implementation is fairly simple for this task which defines the wall dig operation and all similarly complex tasks have such implementations. Other tasks like hauling and building of structures area lot more complex, but the idea is to have one centralized place where the task is defined and if something is wrong to know where to search for a bug. There is one more phase, tasks resolution, which must be defined for each task and is not visible in the screenshot, because it is not part of that class. Task resolution and task filter for each task is the only thing that separates one task from another and all tasks are handled 100% uniformly.
Let me explain in two words the task again. The constructor of the task tell it to use my own super smart task finding algorithm and bypass A* when the engine feels like this would be a benefit. Then we have "TestDwarf", which tells us if a dwarf is capable of doing this job. Other low level bookkeeping, things that are general for all tasks, like if a dwarf is idle or has enough energy and other conditions are handled outside of the task filter. In this case the test boils down to the mining skill having the mining labor enabled. Then we have "IsValidSource", which is called for each candidate task coordinate, to make sure that nothing unwanted slips in. We test and make sure we only dig walls, ramps and built walls. This check is mostly for the UI and also a failsafe. The final method, "OnSuccess" handles the actual adding of the task to the dwarf. It is only called if we have found a worthy dwarf and a task that he can reach. We test again the task type with an ASSERT this time. At this stage there is no way this test will fail. If it does, the entire scheduler had a big bug somewhere and the assertion will warn me about it. Needless to say, it never goes off. I am too good. We calculate the energy consumption and adjust it by the mining skill of the dwarf. We do the same for the duration of the task, taking into account the material we dig though and the skill of the dwarf. And we are done! In the task resolution section we have again simple things, like clearing out the cell and placing boulders if we dig though rock.
I promise not to have a lot of these code sections.
Skill system redesigned
I redesigned the skill system to be more flexible and rely lesson hard coding. Dwarves can have any number of skills and any skill can have any number of labors. In theory. In practice, the skill set is well established and created with the help of the editor:
You can use the editor to create a completely different set of skills, but the game won't function with them because I would have to also move the skill logic to the editor. But it is still a good tool to do all non-structural changes and maybe in the future provide internationalization. Together with the special tile editor, the skill editor is designed to be used only by people who know what they are doing. All other panels can be used by anyone and won't mess up the game too much.
Basic help system
This is the feature that gave the name for this post: I implemented a little hint system that will tell you why you don't have access to the task designation buttons if you have selected something wrong. I'll let the video do the explanation: