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.

Monday, 30 December 2019

Actions as procedures

There is one more technical thing I've tried and it actually works. The background for this "issue" is the way OOP can fragment the code if you need more than one class where any particular class doesn't have a "major" role. It can also be fragmented by inheritance.

If there is a complex action it can become quite annoying to implement in OOP fashion, but in C++ you don't have to, since it's a multi-paradigm language. A real life example is digging with pickaxe. It's happening both in Level class and Creature/Player class, but when you create a procedure (I'm trying to avoid the word 'function' here, because there are functional programmers stalking everywhere) and in this case only one procedure which takes Level, Creature, digging item and direction as parameters, it removes the confusion by unification of the code.

A procedure solves more than one problem. First it's making the code less fragmented and in this case the procedure becomes a linear collection of actions. It's also removing code from Level and Creature classes which often become large and difficult to maintain. Not only that, with C++ you can take care of a procedure not breaking OOP, because the procedure can use class code without any side effects of regular, non-functional style.

Obviously you could do this with OOP as well, using a special class to handle this the same way, but it's the exact same thing. Where this works really well are actions such as digging, but then again it does solve only a particular problem of complex structure. OOP in general is better for low level code, handling data etc.

Sunday, 15 December 2019

Year 2020 for Kaduria

Recently I've done right things and this project is going forward even it doesn't seem like it. The development is clearly shifting from technical stuff to content. I predict that 2020 will be difficult to Kaduria and also myself, because I have some real life problems. Well, the biggest problem is money as usual.