Banana Rogue has already 6 files that compile which can be seen as a minor success. It tells that once you get old C translated to C++ compiler it will be "fine" if we forget about memory management problems of C like raw arrays etc.
Function pointer stuff in daemon and daemons modules doesn't work, because the function signature has to match the pointer in C++ which is more strict about types. If I'm lucky it will be fixed by changing all 'void' functions to 'int' return value, even if they don't use it. Or check out if the functions actually are all void type.
The gui refactoring is almost ready. Most of the action happens in Window (previously WINDOW) struct of curses which I replaced with a class. Window is used inside io module through procedural function wrappers which makes it "easy-ish" to replace later with other type of implementation. Everything works in ascii level, the Window is simply a rectangle of ascii data. It's quite brilliant. The only connection to SDL2 will be Display which shows the window. Then also you need SDL2 in keyboard routines which are also simple in case of ascii codes. There will be some complications if you want to use modifier keys or any special keys like arrow keys, but it can't be too difficult to fix.
The rest of bigger problems are in save game routine, options module (which can be easy, I have skipped it) and linked list routines. The internal type for linked list data is surprisingly char* which is a mystery, because malloc itself is void type or typeless.
Sunday, 31 March 2019
Saturday, 23 March 2019
When otherwise
The strange 'when' keyword was just a macro for break;case pair which I think is cute. I may even keep that macro, but some macros may have to go. Oh, I'm talking about Banana Rogue, a derived game from Advanced Rogue. I've now gone through source files and mostly created missing header files. Somehow it was possible to compile the source without header files back in what year it was made, because they weren't missing from the source, otherwise there would have been #includes for them, right?
The year is also a mystery (well, guess I could google more about it...) because the source says it's 1985, but it can't be that early, right? Also, the xcrypt source code which is some kind of strange encrypting method for wizard's password is from 1994. I think 1990's is much better guess for this game, they just didn't put it into the source code, but kept some random year, maybe the year they started to work on this game.
Xcrypt can be removed, because it's used for networking (password) which is going to be removed also. The system they programmed this had some kind of built-in networking, this was I think before widespread use of internet as we know today.
What is quite surprising is how clean the source code actually is. There aren't too much parameters in functions and the game has only few datatypes. Probably the most dangerous one is the linked_list which is as mentioned before a linked list type and when you combine C's memory management to that it could be a source of bugs. It's maybe too big task to replace it with C++ version, but it's early to tell. Maybe the internal implementation can be changed.
I'm not too concerned about "destroying" the original source code, but at the same time it's silly to replace everything that looks "bad" from C++ perspective.
The year is also a mystery (well, guess I could google more about it...) because the source says it's 1985, but it can't be that early, right? Also, the xcrypt source code which is some kind of strange encrypting method for wizard's password is from 1994. I think 1990's is much better guess for this game, they just didn't put it into the source code, but kept some random year, maybe the year they started to work on this game.
Xcrypt can be removed, because it's used for networking (password) which is going to be removed also. The system they programmed this had some kind of built-in networking, this was I think before widespread use of internet as we know today.
What is quite surprising is how clean the source code actually is. There aren't too much parameters in functions and the game has only few datatypes. Probably the most dangerous one is the linked_list which is as mentioned before a linked list type and when you combine C's memory management to that it could be a source of bugs. It's maybe too big task to replace it with C++ version, but it's early to tell. Maybe the internal implementation can be changed.
I'm not too concerned about "destroying" the original source code, but at the same time it's silly to replace everything that looks "bad" from C++ perspective.
Sunday, 17 March 2019
Banana Rogue
The license of Advanced Rogue tells you can't use name Advanced if you derive from it so the project name could be Banana Rogue and in the story you work in a banana plantation, but want to escape hard working conditions in nearby deadly dungeon which sounds much better option.
I found rnd() function from main.cpp and it really looks like main could need some cleaning up. There is some kind of "network" code which is going to be removed. Also, there are signal handlers in case the program crashes which makes the player die from bug. I think it's better remove those also, because if the game crashes it's better to make it possible to load the game from possible existing save game.
This project really needs a gui module and there is already io.cpp which has things like msg for message output, but it could have everything gui related in it. I think the game doesn't have a "level" structure but it has at least four WINDOW arrays (which work as layers) which I think are from missing curses library. They are simply char arrays if I'm interpreting the code correctly.
I found another 'when' keyword switch-case which has the first keyword 'case' but the rest are 'when'. It's quite baffling, because I can't even find any mentions of 'when' being a keyword in C.
I found rnd() function from main.cpp and it really looks like main could need some cleaning up. There is some kind of "network" code which is going to be removed. Also, there are signal handlers in case the program crashes which makes the player die from bug. I think it's better remove those also, because if the game crashes it's better to make it possible to load the game from possible existing save game.
This project really needs a gui module and there is already io.cpp which has things like msg for message output, but it could have everything gui related in it. I think the game doesn't have a "level" structure but it has at least four WINDOW arrays (which work as layers) which I think are from missing curses library. They are simply char arrays if I'm interpreting the code correctly.
I found another 'when' keyword switch-case which has the first keyword 'case' but the rest are 'when'. It's quite baffling, because I can't even find any mentions of 'when' being a keyword in C.
Saturday, 16 March 2019
Confronting a vast cosmic mystery
It might be possible that the random Advanced Rogue source code that I downloaded from somewhere and started to work on could be obfuscated. One clue for this are the missing function declarations, but I've also seen a switch - case with two 'when' keywords. Or could it really be possible that it's written in some kind of special version of C?
Anyway, rather than trying to compile one file at a time (which is still not even possible) I've started to re-create header files for each file with functions it has. There are some functions that has to be replaced, but luckily more modern alternatives are possible without changing the call style. One of those is msg() which has a vararg style parameter list, but the syntax is different than it will be in the "modern" version and also I'm probably going to change the internal implementation to std::string, because it just looks like it's better that way.
The number of datatypes I've seen this far is reasonable, it's four: coord, object, thing and linked_list. The last one is a manual linked list as the name implies and it could be heterogeneous through void pointer magic, but I'm not sure yet. But it's using macros to allocate memory for objects. I'm not sure if it's useful to replace that with something safer, at least if it actually works.
Anyway, rather than trying to compile one file at a time (which is still not even possible) I've started to re-create header files for each file with functions it has. There are some functions that has to be replaced, but luckily more modern alternatives are possible without changing the call style. One of those is msg() which has a vararg style parameter list, but the syntax is different than it will be in the "modern" version and also I'm probably going to change the internal implementation to std::string, because it just looks like it's better that way.
The number of datatypes I've seen this far is reasonable, it's four: coord, object, thing and linked_list. The last one is a manual linked list as the name implies and it could be heterogeneous through void pointer magic, but I'm not sure yet. But it's using macros to allocate memory for objects. I'm not sure if it's useful to replace that with something safer, at least if it actually works.
Friday, 15 March 2019
Advanced Rogue
I was reading the source code of Nethack one day and noticed that I can also read source code better these days, mirroring my increased skills in programming. So I downloaded the source code of Advanced Rogue which I think was last updated in 1985. Rogue had quite a number of variants just like Angband later, but I've never played any of them.
The source code of ARogue seems to be quite small, but it's also old school C which means that weird way of writing function definitions and declarations. The plan is to rewrite the source code to C++ (not OOP, but keeping the procedural style) just for fun reasons and I've already on the way. Another "problem" I guess is curses which is an external library used in ARogue and it's not included, but can be replaced with SDL2 gui. It's possible that curses has also changed during all these years, so it's probably not going to work just like that. However I could even keep the old function names so in theory it's possible to replace SDL2 gui with curses, or whatever.
As a small mystery some functions are defined, but not declared in any of header files. Or in this case rogue.h which is I think one of the two header files the project has. Creating header files for functions defined in a .cpp file is another task in the list.
Other than that I think the majority of old C code should run in a modern C++ compiler, but we'll see it later. There are lots of pointer stuff in ARogue's source which can be a problem and also I'm going to replace memory management routines with C++ code.
The source code of ARogue seems to be quite small, but it's also old school C which means that weird way of writing function definitions and declarations. The plan is to rewrite the source code to C++ (not OOP, but keeping the procedural style) just for fun reasons and I've already on the way. Another "problem" I guess is curses which is an external library used in ARogue and it's not included, but can be replaced with SDL2 gui. It's possible that curses has also changed during all these years, so it's probably not going to work just like that. However I could even keep the old function names so in theory it's possible to replace SDL2 gui with curses, or whatever.
As a small mystery some functions are defined, but not declared in any of header files. Or in this case rogue.h which is I think one of the two header files the project has. Creating header files for functions defined in a .cpp file is another task in the list.
Other than that I think the majority of old C code should run in a modern C++ compiler, but we'll see it later. There are lots of pointer stuff in ARogue's source which can be a problem and also I'm going to replace memory management routines with C++ code.
Friday, 27 July 2018
Roguelike definition – what are we missing?
There is some debate about “the definition” of a roguelike. Some argue that a roguelike must meet a list of essential features, but even those features are different depending on who you ask. What I think we are missing is the feel of the genre. It’s easier to feel than you would think. When we see a platformer or a RPG we can feel it from couple of generic features. Platformers have platforms you jump on and role-playing games have a RPG system with character classes, stats etc.
I feel that the essential feature of a roguelike is a top-down tile map of the game world with turn-based tactical gameplay. The gameplay should also have some role-playing features, but to increase the feel it better have a complex role-playing system similar to Dungeons & Dragons system. When we look at a roguelike as subset of role-playing game it’s easier to get the proper feel about it. The difference between a regular RPG and roguelike is randomly generated game world and permadeath, although it’s possible for a RPG to have some random features and permadeath. In similar manner some roguelikes can have static locations and various ways to restore the character after death. Even the classical roguelike Nethack has ‘bones’ for giving back some items from a previous character.
ASCII graphics makes the game feel more like an old school roguelike, but it’s not a decisive feature. The reason roguelikes had ASCII graphics was mainly a technical limitation and in broad sense ASCII tiles are “graphics”, too. They are just a way to represent something. Some roguelikes implement both ASCII and tile modes which work interchangeably and make no difference to the gameplay itself.
It’s quite easy to feel when the game is not a roguelike. It may look like one, but it’s often missing the complexity and size of so called major roguelike. These games have their own genre title as roguelites, but in some cases it can be argued if they are simply adventure and/or (action) role-playing games with some roguelike features. Games like Spelunky are sometimes thought as roguelikes, but for me Spelunky feels a lot like platformer game, it just has randomly generated levels. Random generation is not a feature only for roguelikes, it can be used in all genres. What makes it a feature of a roguelike is the proper context.
The problem of a flexible interpretation has been a saturation of the genre with games that in fact are not roguelikes. Some developers use the genre name in marketing, because it’s easier to get visibility for your game when you have a clear genre for it. When even developers think their game is a roguelike the genre has regressed from major roguelikes as standard to something else. It’s “acceptable” to define your game as roguelike when you have one or more features of a roguelike taken out of context.
Let’s be honest. We can all feel when the game is a roguelike. It’s all that matters, for both developers and players.
I feel that the essential feature of a roguelike is a top-down tile map of the game world with turn-based tactical gameplay. The gameplay should also have some role-playing features, but to increase the feel it better have a complex role-playing system similar to Dungeons & Dragons system. When we look at a roguelike as subset of role-playing game it’s easier to get the proper feel about it. The difference between a regular RPG and roguelike is randomly generated game world and permadeath, although it’s possible for a RPG to have some random features and permadeath. In similar manner some roguelikes can have static locations and various ways to restore the character after death. Even the classical roguelike Nethack has ‘bones’ for giving back some items from a previous character.
ASCII graphics makes the game feel more like an old school roguelike, but it’s not a decisive feature. The reason roguelikes had ASCII graphics was mainly a technical limitation and in broad sense ASCII tiles are “graphics”, too. They are just a way to represent something. Some roguelikes implement both ASCII and tile modes which work interchangeably and make no difference to the gameplay itself.
It’s quite easy to feel when the game is not a roguelike. It may look like one, but it’s often missing the complexity and size of so called major roguelike. These games have their own genre title as roguelites, but in some cases it can be argued if they are simply adventure and/or (action) role-playing games with some roguelike features. Games like Spelunky are sometimes thought as roguelikes, but for me Spelunky feels a lot like platformer game, it just has randomly generated levels. Random generation is not a feature only for roguelikes, it can be used in all genres. What makes it a feature of a roguelike is the proper context.
The problem of a flexible interpretation has been a saturation of the genre with games that in fact are not roguelikes. Some developers use the genre name in marketing, because it’s easier to get visibility for your game when you have a clear genre for it. When even developers think their game is a roguelike the genre has regressed from major roguelikes as standard to something else. It’s “acceptable” to define your game as roguelike when you have one or more features of a roguelike taken out of context.
Let’s be honest. We can all feel when the game is a roguelike. It’s all that matters, for both developers and players.
Wednesday, 2 May 2018
Nethack 3.6.1 thoughts
I think this release was slightly underwhelming. They fixed couple of things and it took two years. On the other hand it's understandable when you look at the mess which is Nethack's source code. It's not easy to maintain I would guess. Even so I was expecting more gameplay changes, new stuff etc. but it looks like they "freeze" this version branch and the next one will have more changes so people who want to continue play 3.6.x can do that. There are people who believe some specific version to be the only real Nethack.
The way player character's name is highlighted when your HP is not full is a nice feature, it's something you'll notice right away. Other thing I noticed is that $ keyboard command doesn't work when picking up items, but I did comment out "Finnish keyboard" section in defaults.nh, maybe I should try to comment it again to see if it works. In Finnish keyboard $ is typed as AltGr + 4 and some other keyboard commands are also different. Also, the .exe was acting strange way when I started it the first time, it hanged for like five minutes and then Windows 10 smartscreen catched it, but I ran it anyway. It may be just the smartscreen, it's warning about everything.
Even I'm whining I actually like Nethack. It's really the only roguelike game I'm playing even I'm not a good Nethack player. I know what happens in the game later, I've seen gameplay videos and tried in wizard mode, but I probably like the beginning before Quest more than anything else. It's the way things start to go, sometimes you get very lucky and sometimes you get hardships. The first time I tried this version I managed to blow up my pet with a gas spore, and then turned into a werewolf. I also learned something new: when you kick a pile of gold it scatters around. I had to try that to pick up only gold, because $ key doesn't work.
One of the reasons why roguelikes are nice games is that you don't have to win. At least it's what I think about the genre. Those people who want to win will push it through by learning strategies you need to win this game, but I think when you don't learn them it can be just as fun.
The way player character's name is highlighted when your HP is not full is a nice feature, it's something you'll notice right away. Other thing I noticed is that $ keyboard command doesn't work when picking up items, but I did comment out "Finnish keyboard" section in defaults.nh, maybe I should try to comment it again to see if it works. In Finnish keyboard $ is typed as AltGr + 4 and some other keyboard commands are also different. Also, the .exe was acting strange way when I started it the first time, it hanged for like five minutes and then Windows 10 smartscreen catched it, but I ran it anyway. It may be just the smartscreen, it's warning about everything.
Even I'm whining I actually like Nethack. It's really the only roguelike game I'm playing even I'm not a good Nethack player. I know what happens in the game later, I've seen gameplay videos and tried in wizard mode, but I probably like the beginning before Quest more than anything else. It's the way things start to go, sometimes you get very lucky and sometimes you get hardships. The first time I tried this version I managed to blow up my pet with a gas spore, and then turned into a werewolf. I also learned something new: when you kick a pile of gold it scatters around. I had to try that to pick up only gold, because $ key doesn't work.
One of the reasons why roguelikes are nice games is that you don't have to win. At least it's what I think about the genre. Those people who want to win will push it through by learning strategies you need to win this game, but I think when you don't learn them it can be just as fun.
Subscribe to:
Posts (Atom)