Thursday, 14 November 2019

Lighting issue

I'm working on fov and lighting as you should after 110 years of development. I have a new fov routine, but there is a problem in lighting. When each tile has independent fov and light values it will create a situation where the wall is lit from the opposite side. Imagine there is a lamp in a room and the room's door is closed. You can still see the wall lit when you are outside the room, because the lamp has to lit the "inside" walls of rooms as well. Obviously, the inside and outside walls are the same, since roguelike 2D maps usually have it that way.

I don't recall any games that have gradual lighting and how they solved it, if at all. I guess one way to try is have data for each facing of a wall, but it may get complicated. More so if the light source is on the wall itself, as some kind of wall lamp. Then things get even more complicated, unless you give the light source information about which side of the wall it is.

Whatever the solution, I have to do something about both fov and lighting finally, because in a weird way having both fov and lighting helps in dungeon design, because everything looks very different if you don't have fov on in particular.

Sunday, 13 October 2019

Progress on dungeon generation

Back in some years I ran into trouble with a large scale data-driven system developed for the dungeon generation. It seems like data-driving works best in local, isolated contex just like many other things in programming. Since then I've been breaking the data-driven system into level theme classes, using only some data-driven parts.

The good thing is that most sub-systems can be run directly from theme classes with some minor changes in the way data is passed into them.

In the past I used to think that level generation is complex, but in reality it's quite simple. As always the main point is first making a decision what the level actually contains, rather than thinking about doing it later. When you say "I'm going to do it later" you are in trouble.

Most of the building blocks are ready and about half of the themes have a basic structure. There is even a simple street generation routine for town levels where I made an observation that by storing and comparing distances from previous locations you can space the things without having to do it manually. However after all these years it's hilarious when you proceed to the next level you realize there is more to it.

I'm going to be happy if the basic structures of all themes are ready before the end of this year, because after that it's much easier to add the rest with sub-systems that mostly work by filling in the rest of the free space.

Monday, 9 September 2019

Coordinates rewrite

Each object used to store coordinate data, but for objects that don't move I thought having that data in the object itself was a waste of space. Obviously there has been complications when coordinates were removed from some object types. The way I'm storing game objects are in a list, because it's an easy way to keep them in ownership of the level. The display map is doing most of the work by having only handles to visible objects.

Since items (those items you pick up in the game) work a bit different way I have to write a unique list for them. The generic list did have some static_casts to item class for that reason and I guess it's good to remove those routines. There are some other object types that use coordinates in that context, but they are easier to fix I think.

There is also a change in the way I'm documenting issues in the source code. I used to write "note:" followed by explanation in the source code, but those seem to disappear in the code. I think it's better to create an issue list with number for each issue and then fix them the same way as bugs. That way you can see the list growing and if you don't do anything it's going to be infinitely long.

Saturday, 3 August 2019

Plan for graphics tiles

Since I got my new computer and Blender 2.80 has been released I have an idea to recreate game object tiles in 3D. It may sound like a bad idea, but I think it's not that difficult. Items will probably be the easiest, because there are lots of parts that can be modified and copied (like handles and blades of weapons etc.). Besides not many people know that I am a 3D artist/animator myself, I just didn't get jobs from that area but have been mainly working in office environment for years.

I haven't tried this before, but I know there are some things to consider. First you need to match some kind of grid with items so when you render let's say 512x512 with 32x32 tiles the items are in their own "tiles" and don't bleed to others. Then again it's quite easy to fix if that happens by moving or scaling that object. The second problem is I guess the scale, because 32x32 tiles can only have certain amount of detail. This in fact can make the whole process easier, because you don't need a lot of detail and items need large, possibly even cartoonish parts in them.

The great thing about 3D is that it's easy to rotate and scale objects if you need to change their perspective (viewed from top in the actual game) or colors (materials). And on top of that you can create matching shadows and lighting for all items in a matter of seconds. Well, the downside is that modelling is kind of difficult and slow, although I'm pretty good at it.

It would be nice to have new graphics put in the game as soon as they are made, but it requires some changes. I need to change the .wst format to a regular image format and then copy new tiles over old ones when they are made. Some object graphics can be put into one image to have less image files to handle. The new system has to be programmed for all tiles, but copying tiles from .wst to image is not a big problem, it just means I have to succeed in this 3D idea. But I think it's the right way to proceed, because drawing tiles in 2D is even harder.

Tuesday, 16 July 2019

Back to game design

After finding solutions to some technical things I've returned to creating content or more like trying to get things playable. It feels a bit weird, yet nice. At the moment I'm working on character creation which involves some RPG system design as well, with skills in particular.

The RPG system is going to focus on gear and skills, not in experience because there is none except in skills (as a limited way to advance). I never liked experience based systems myself so this is an attempt to try something different. I guess you could look at getting better gear as "experience" of sort.

I feel like the technical solutions I've reached are not going to change this time, for real. At least not in a dramatic way like before.

Sunday, 16 June 2019

What I learned about inheritance today

Working on the game object class hierarchy I was confronted with a problem that I had not been able to solve - until now. The solution is I guess kind of hack, but I think it's only fitting. So when you inherit from another branch of class(es) the "main" branch can't use the class in that other branch without virtual functions defined in the base class. These functions can use either components which is a common way to use classes when you are not sure about inheritance, or derived classes, both using function wrappers which is bad, because it can generate duplicate or similar code.

My solution is a virtual function in the base class that returns the slice of the derived class from another inheritance hierarchy. The base class obviously returns zero for non-existing slice, but any derived class can return the proper part of it simply with return this. Slicing doesn't matter when you return pointers, it just works. When the sliced class is abstract enough it doesn't cause problems with decoupling it from the host class. Real life examples are things like the opener part of an object such as door. It can have status (open, closed, etc.) and lock data as in case of this game, and another example is the actual container in objects that can contain items. Both "slices" are abstract in the sense that they don't need information about the host object when they are used. The routines that use them can have the host object pointer as well and it's the case here, because you may need to do things to base class object as well like change the graphics frame when door is opened or closed.

The reason for all this is remove "empty" virtual functions and functionality from base classes and other classes in the hierarchy that are not using some derived class functionality. With this new way to handle some aspects of game objects I can split the main hierarchy to object types that use only the functions they have and it's possible without writing multiple wrapper functions to each class, because those classes are virtual parts themselves.

Friday, 10 May 2019

Class hierarchy of game objects

The structure of game object classes is something I'm going to rewrite, maybe before source code release. The problem was that I believed the "common" knowledge that you should avoid inheritance and especially multiple inheritance in C++, and use components, not only as in component based approach but as datatypes inside the class. But if you are using classes and OOP, then what is the point of that? There is no point and not only that it has made the game object tree quite difficult to maintain.

But what about things like the dreaded diamond? It is a silly thing to dread, because any advanced programmer can't make that kind of simple mistake in inheritance. The real difficult thing is the class hierarchy itself, because you need to make independent branches that don't rely on some base class data if the class is not inherited from "main" branch.

How you split classes is part of the hierarchy problem. For example if you have fountains should they be a separate class that has water contain ability or should they be a part of some more generic container type class? The way objects behave is I think a good way to split, but even then some features are more generic than others. It's not easy to create a well behaving class hierarchy, but it's certainly not impossible or something you should avoid.

I think when people go for solutions like component based design it's a solution to problem that never existed. The way OOP works is just one way to do things, that's it. If you want to do something else, that's ok, but it's irresponsible to create assumptions about OOP that are not true.