Saturday 12 December 2020

Terrain map rewrite

Some time ago I had an idea to create a game object for terrain tiles as well, because it was easier to handle game messages, damage to terrain etc. But it was kind of a mistake which I'm now going to fix with another rewrite (or refactoring, how you want to call it). At this point even rewriting doesn't feel like a problem, because it's mostly rearranging source code to more logical units.

The new plan is a terrain map with Tile class tiles which is a more complex way to use an integer to show which terrain tile is in that place. With that you also need fov and automap data and so on. Then, when a terrain is changed (most often when damaged) a terrain game object is created in that place. This is going to solve another mistake I made when I removed location data from some game objects. It became incredibly annoying to work with objects that had a location and others which didn't.

I think it's important to rewrite when you feel something is not right. The irony in this case is that I got it almost right the first time, but then made a decision to rewrite it because the strange problems I had (and still have) with the game message routine. Game messages shouldn't affect the way terrain map routines are implemented at all and it's an important lesson. Each part of the system should work more or less independently at the internal level and external connections should not rely on that.

Sunday 22 November 2020

300 Days

The latest development idea I have applied to all my main projects is extremely simple but it seems to work in its own way. I've created a five-step rating for source files, which in C++'s case is usually the combination of header and .cpp file. The ratings are: ready, works, test, unfinished and sketchy. For example if the contents of file (usually a single class per file) require testing, I'm adding a line to the header file with #. Then I can search and list all files with that rating.

What I have noticed with #test files is that testing is way too underrated in development, at least in my experience. The "usual" way to test is I guess play the game and see if it seems to work ok. But I think it's more useful to test individual classes and see if everything works as it should. It's much more work, but when it's done you can move from the test level to "works" level, narrowing down the development size of the project.

Another good thing with this approach is that it gives a focus on things you need to implement and improve. You can't leave things "for later" if you want to move on the next level. Also with this you can have an estimate of how long it takes to move all files to let's say works level. In Kaduria the starting point with the rating was 309 days, if you give each level one day of development time which is reasonable. It underlines how the size of the project itself makes it difficult to finish a large scale roguelike in short amount of time and why games are usually created by a group of people.

Friday 14 August 2020

Those pesky mazes

Creating a maze or labyrinth routine is harder than you would think. At least when you go rogue from "homogenic" maze routine to more free style. The way I'm doing it is first create rooms that are special locations you need to find within the maze, then the maze system itself which is kind of corridors connecting those rooms. The problem is that maze can stop creating itself when it runs into a dead end created by itself. Currently I'm trying to solve this by creating several maze pieces that continue from current maze tiles, making sure everything is connected. However sometimes the maze simply doesn't reach all rooms, but it's possible to fix that by checking out if a room has a connection and then creating a "tunnel", which looks like someone had tunneled through the room walls and everything. It's the simplest solution, although you could create more sophisticated corridor routine as well. In this screenshot green corridors connect rogue rooms to the rest of the maze:

So it seems like everything is ok and there is often even room for additional features. But of course there is a special condition where maze creation fails, which I guess could be easy to fix. It happens when the maze begins from a room close to wall and stops short, then fails to find another starting point from the piece of short maze. Not yet certain why this happens, but even it does the level "kind of" works with tunnels connecting everything else, like in this example:

It could be possible to add Cornucopia system on top of this and still get a level, but it would not be a maze. I need to fix this last bug and then move on. My recent development strategy is simply go through each issue and keep fixing it until it's decent. That way I'm no longer pushing difficult problems to distant future.

Wednesday 24 June 2020

Static code analysis report

With Kaduria I have not been consistent in checking code quality until now. I was thinking that it can be done "later" when the project is in testing phase and using code analysis on such a large project can be tedious. But I have since then began to run at least CppCheck on the whole project.

The nice feature of static code analysis is that you can find some bugs for free. There is no need to find them yourself and waste time on that. It also improves code quality when you can remove unused functions and other things like that. Some warnings like missing explicit and override keywords can be annoying, but adding them also is an improvement in code quality.

The tools I'm using are CppCheck, Visual Studio's W4 warning level and static code analysis with clang option (you can turn it on in project settings). There are some commercial tools which could be nice, but I don't have the money for those, at least in scope of money I'm getting from game development (which is 0.00€). GCC has also compiler settings for static analysis, but at the moment I don't have GCC installed and for that I would have to figure out a way to compile Kaduria in GCC in clean way.

Static analysis is good at finding errors in logic like comparisons which are always true or false, but more complex things would possibly require some kind of artificial intelligence to detect the problem. Maybe it is the future of analysis tools.

Tuesday 19 May 2020

Progress and ideas

Something snapped in my brain a while ago and as the result I have almost completely stopped refactoring source code in all my projects. It means that the focus is now on the game design. I also figured out how to combine physics and traditional RPG system which also was a sudden realization.

Physics simulation in games is kind of weird subject, because games can never be completely physics based. If they were it would ruin "the hero" aspect of games, where the player character always seems to have some kind of special advantage over everything else. For example in most games the player never runs out of gas, but is always ready to do whatever it takes. Some games have a kind of stamina, but it's always limited to a certain level. The plan for Kaduria is not only have more realistic stamina effect but also long term fatigue which means you have to sleep to regain it.

There are lots of other ways I'm going to change the gameplay compared to a typical roguelike or a role-playing game. I'm not even sure if it's going to be a better gameplay, but I'm just so over the traditional style of roguelikes in particular where everything is based on getting tons of stuff (which in realistic terms you would never be able to carry anyway), killing thousands of monsters just like that etc. In Teemu I have deliberately chosen a traditional approach, because it's not a serious game, but Kaduria will be different.

Saturday 2 May 2020

User interface stuff

I feel that this project is going to be somewhere between old school ascii and "modern" graphical styles in the way how information is shown on screen in the main gameview. In traditional roguelikes you often have information packed in various status lines etc. which I guess become easier to understand once you get used to it. However it feels like mirroring that to a graphical roguelike isn't the best, or having packed information at all.

Graphical games can have icons to replace text, but in many cases it's worse. In any case, how much and what information is directly on screen is a matter of design which is harder than it seems. User interface design is difficult in all programs, not just in games. Luckily I've learned from my past mistakes and now adding something only if it's easier to have on screen all the time. But it's also a design decision, especially now when you have the space, assuming the gameview is small enough that space for stats etc. is available.

The design of "off-screen" information is just as important, and making it easy to access can remove the need for on-screen information.

Thursday 16 April 2020

Plant simulation

It looks like I have to rethink plant growth simulation, because it was too simple to work properly. If you can set up plant simulation it's one of the only places in roguelike development where you can then reduce the work in random generation by some dramatic amount. But for that to work the simulation needs data which is consistent with the dungeon layout, everything that contributes to growth of plants.

That's actually all I have to say about it. Well, other than in Kaduria the plant simulation is going to be quite detailed, because the amount of data the environment has. I'm not looking forward in clearing the mess I made, but when it's done at least something should work in this project.

Friday 3 April 2020

Namespaces and enums

I think I have not yet figured out how to use namespaces properly. Previously I often created a namespace for enums, but it does create problems with names especially if you open the namespace. If you put an enum into class it's much safer that way, because it exactly ties the enum into that class. It also removes the need to add another namespace for stuff, which in large projects is important, because anything you add into the project makes it harder to maintain.

Currently I'm using more generic namespaces to store data and sometimes functions. For example there are low level text routines in 'codex' namespace and data in namespaces like 'creaturedata' and 'itemdata'. The data in Kaduria is often simple structs which again is probably not the best way to handle it, but it's what it is. The way I now see namespaces is more like a tool to keep track of data and not so much to isolate it from global scope which in C++ is a bit overkill anyway, because you can access only the stuff you include in a .cpp file.

I guess the "proper" way to use namespace is how std:: namespace is used in standard template library, which is to denote a super large library. But the way I'm using namespaces seems to work, at least it doesn't add more confusion.

Sunday 8 March 2020

Three structure types

It looks like the way I'm programming is reaching some kind of goal with how I'm now using three types of "structures" to manage a large scale project. First is type-style class, a small class with often only one variable, or something like Point or Rectangle classes. Creating your own types should be a priority in object-oriented programming anyway so I'm creating them when it makes sense. Which is almost always over using regular types. A great example is Point class, it's way better to create a class that holds x and y variables rather than use them as integers.

Second type is a regular class, not a type class but larger with more data and components. These are things like monster, item and level classes.

Third type is a procedure, which in C++ is just a function outside any class. Somehow I find these really useful in parts where you need some kind of action with object instances.

With these it feels like nothing is missing and I'm able to manage the source code better than ever before. Also, I've largely began to disconnect classes from "modular" files. I find that modules are useful, but only when you have a small class hierarchy (inheritance) or similar types of classes. For example I have Point, Coords, Rectangle and some other similar classes in one file, because they inherit from each other. You need to include the base classes anyway if you want to use any of them.

Sunday 1 March 2020

The RPG system

Most of the problems in this project seems to be in developing the role-playing system. It's a "simple" concept, most RPGs have some variables like health that is determined by monster type or internal stat like strength. But it's still complex enough to actually implement a new system without just copying an existing one. Even when you don't use an existing system it's still probably going to have health, stamina and the usual suspects.

Maybe that's the issue I have with it, I'm trying to think about how not to create just another RPG system. One way to try is more "realistic" system which is always going to fail, because realistic games just don't work, the player character has no chance to survive for long in that type of game world. Yet, I think some developers are annoyed by the fact that RPG systems are simple in the outside and they make the gameplay feel too much like you are working with numbers, and tactics revolve around trying to figure out how much HP the enemy is going to take in one turn etc.

However if I want to finish this project it's largely depending on RPG system which I now know is the core of a roguelike game, while many developers like myself focus too much on game world development (random generation routines) and leave RPG system as an afterthought. In a way this has been even more difficult to me, because I never really was that highly tactical player that can squeeze everything out from the resources you have in the game. Maybe the gameplay could reflect that philosophy by reducing the amount of close combat or even creating alternative ways to handle combat situations. In most radical solutions you could remove "mandatory" combat and create safe areas in the dungeon you could travel, leaving combat as an optional feature.

Whatever the solution will be, I doubt it's going to be a basic RPG system with a basic roguelike game. I would hate to create a game like that while other developers are just fine with it.

Sunday 19 January 2020

Is this... refactoring?

I think it is, but in a nice way. At least it doesn't feel that bad, and it's more like re-arranging the source code. The first step was actions as procedures, but it's also possible to create classes with an outlook at the basic data. For example today I programmed a look command to an external class Look. It takes in Level and Avatar (aka player) data and then determines different ways to look at things. The source code was largely previously both in Level and Avatar classes which increased their size and distributed functionality in lots of small member functions.

In comparison the Look class is focused and has only one public "entry point" function. This prevents confusion when you pass the data into class almost as if it was a procedure. From maintain perspective it's also easier, because when you need to fix something in looking you know where to find everything. Only low level routines are in Level and Player classes to return some atomic piece of data.

I don't know, maybe it took a good while to realize that actions should be detached from classes like Level to keep them simple, in cases where actions need two or more (large) classes in them. And also, that procedural style can be better in some situations which, undoubtebly, has been a troublesome concept for me to accept, since I have been such a fan and connoisseur of object-oriented programming.

Tuesday 7 January 2020

Actions in action

Now that I have programmed some actions as procedures it becomes clear how nice it is. And, since they largely maintain object-oriented paradigm it doesn't even break the code that way. It's almost like calling a library function from a class. It's great how actions like kicking or digging can be reduced to one linear function which is much easier to manage than when the code is spread in classes. It's such a simple concept, but it works.

This brings back an old argument that C is "better" than C++. In this case I would say it sure seems like it, but obviously it's not the whole story. Managing data and resources in classes is certainly better than C's procedural style.

The actions.cpp has 6 functions at the moment and it's 367 lines of code. I'm planning to keep everything in one file, because it seems quite fitting when they are only functions. The final size can be anything, but I doubt it will be an impossible amount of lines. The number of lines in this project is moderate, because the excellent quality of the code.