Narthenian, Part 3

Screenshot of Narthenian game with an innkeeper greeting the player

I managed to fit a couple of hours in today for adding innkeepers and staying at an inn to The Narthenian Conspiracy. Since inns charge for a stay, I had to add gold to the game, and let the player collect gold from slain monsters. I also added a new sprite that will be used for merchants and innkeepers. It looks more like a wizard or a gnome, or maybe a gnome wizard, but that’s the extent of my art skills.

Innkeepers are their own class, and Merchants will be also. I could probably avoid some unnecessary code duplication by making NPC an abstract class, and subclassing the already existing NPCs, Merchants, and Innkeepers from it. I would probably have to turn the NPC vector associated with each map into a vector of pointers in order to make use of polymorphism. Whatever. I’ll deal with the consequences of my design choices for now and learn the lesson for later.

Staying at an inn fades the screen to black, and then fades back in to the usual display as a simple visual effect for going to sleep. I did this simply by drawing a black rectangle over the screen with alpha going from 0 to 255 and back. It probably goes a little to quickly as it is, so I may come back and tweak it to take longer later. Initially, the screen went straight to black; fading out and in wasn’t working. I realized that SDL3 ignores the alpha channel when drawing rectangles unless you call SDL_SetRenderDrawBlendMode on the renderer and set it to SDL_BLENDMODE_BLEND. This is probably also the case for earlier versions of SDL, but I have always copied portions of textures rather than drawn plain rectangles.

I wanted to put in a sound effect for sleeping at the inn, but haven’t created the sound yet. I may go with a different approach, and have the game play a “chiptune” arrangement of Brahm’s Lullaby during the whole interaction with the innkeeper, rather than using a sound effect just during the sleeping state. That’s something I’ll decide on soon: I’m currently learning my way around MilkyTracker in order to put together some background music for the game (it will ultimately be in .wav or .mp3 files; I don’t feel like implementing a reader/player for .mod files or pulling in too many external libraries for a relatively simple game). In any case, the decision need not be permanent if I don’t like how it turns out.

The game is becoming a little more playable with the ability to sleep at an inn and recover HP, so that going out and fighting and leveling up can continue. There is a lot to go with tweaking enemy stats, adding more enemies, adding items and spells, adding quests, etc., etc., etc. But little by little there is more to the game. While I’m working on the music, I probably need to also finish up the Carathusia town map, and put together some maps for the floors of the castle. Anyway, it’s easy to get overwhelmed thinking about everything that still needs to be done. More fun to focus on the enjoyment of seeing the little steps forward.

Narthenian, Part 2

Dialog scene from the game

I got the initial framework for NPCs and dialog set up, and I have uploaded the code to Github. You can find the game in its current, very early state, at https://github.com/jstoddard/narthenian. There are only a couple of NPCs and very simple dialog at this point: They only say one thing at you. There are some data structures and framework for a more complicated dialog system in which there can be some back and forth, with the player selecting a keyword or phrase from a menu to continue the dialog, and with NPCs able to give the player an item or update a quest. These features, however, need a lot more work to be implemented.

NPCs are kept in a vector in the AreaMap in which they are located. In the drawing routine that is run each frame, the game iterates over the NPCs in the current map and identifies and draws the ones that are within the bounds of the screen. The game interprets an ENTER keypress, and in the future the A button on an XBox controller or corresponding button on another gamepad (this was already implemented in the BASIC prototype) as a command called “ACTION1.” When the game receives an ACTION1 command, it looks for an NPC in the tile that the player is facing. If an NPC is there, the game goes into dialog mode, which currently comprises displaying the NPC’s dialog on screen and waiting for the player to hit ENTER again (or SPACE a.k.a. “ACTION2”) before returning to the normal mode of letting the player wander around the map.

Before fleshing out the dialog system with the upcoming features, I will probably set up merchants and inkeepers so that the player can rest and buy weapons, armor, and other items. I think that doing so will go a long way toward making this early stage of the game somewhat fun to play—an important consideration, since I need to spend a lot of time playing it, even in its unfinished state, for testing and bug-catching. I am not sure yet whether I will subclass NPCs for these characters, or make separate classes for them. There are some tradeoffs to consider. If they are subclassed from NPC, a single loop can handle drawing of all three character types, and another single loop can handle the ACTION1 command as discussed above. However, the latter is somewhat complicated by the fact that a merchant or inkeeper will often be behind a counter, so checking will be a little different, and we will want to switch to a shopping system or sleep system that will probably be distinct from the dialog system. This can be handled by moving the checking and mode-switching code from the loop into virtual functions in the NPC class, and just having the loop call those functions instead. The Merchant and Inkeeper subclasses would just override the functions.

Well, I’ll decide what to do over the next day or two. Meanwhile, I have a couple more monsters to add to the world, as I think I mentioned in the last post.

Narthenian, Part 1

I think I’m going to keep a devlog of a simple tile-based RPG that I’m working on. Although it’s not a huge undertaking, progress is and will be slow, since it’s just a spare-time project worked on a few hours a week in order to learn a little bit of modern C++. The original prototype was actually written in QB64 Phoenix Edition, a somewhat-modernized variant of the QuickBasic language. Here is a video of that early prototype in action:

I have rewritten it in C, and have been adding additional features in hopes of eventually turning it into a complete game. The tiles are based on a set from Lanea Zimmerman, username “Sharm” on OpenClipArt.Org. The melee scenes—which now have a nicer background than seen on the video—are based on AI slop with some editing. I’m not proud of that, but that’s the current situation.

The game is currently being written on an old Lenovo Thinkpad purchased for $150 and running FreeBSD. I have gotten tired of plain text editors and command lines, and, remembering the nice programming environments from the days of QuickC and Turbo C++, I have opted to work in the CLion IDE and enjoy letting a program handle most of the housekeeping tasks, provide easy refactoring and debugging, and generally keeping things easy. It’s nice having nothing to prove through programming asceticism. Graphics are edited on a MacBook Pro. The maps, for now, are put together with a simple map editor written in QB64 Phoenix, and the sound effects are recorded from sounds generated in QB64 Phoenix. The sound effects are simple and could be generated directly in C++, but QB64’s sound statement is almost like working with an old Yamaha sound chip, allowing me to set tone, duration, effects, and noise, which is easier than generating the waveform directly.

The current state of the program is that the player can wander around the world and fight a couple of enemies (the serpent and gigarat seen in the video, with more designed and about to be added), level up, and switch maps (i.e., enter and exit a town). I’m currently working on setting up NPCs and dialog, after which I expect to upload the work-in-progress to Github. Items and quests are in the works together with NPCs and dialog, but I don’t know how complete they will be before the initial Github commit. Spells need to be implemented, but I’m not sure when that will happen. (I’m about to set up a Mage enemy, but it will be stuck on plain attacks for a while!) Saving and loading games will be added once all those things are working. The overworld map is also sort of sparse, and there’s only one unfinished town working so far, so there is still a long way to go before a reasonably complete RPG is ready to play.

I’ll put up screenshots and discuss the development process as things proceed. For now, here’s the general background story behind the game:

When the heavens and the underworld made a joint attack on the people of the earth, the six cities united under the leadership of Carathusia for defense. Narthenus, one of the greatest warriors of the Forest People, disapproved of his people’s decision to submit to Carathusia, and betrayed both his army and the joint army’s battle plans to the underworld. The traitor’s actions nearly brought an end to the world, but under the Carthusian general’s leadership, the six cities managed to save the mortal races.

The unified kingdom lasted for centuries, until four thousand years after the great war, when a cult calling themselves the Narthenians attempted to overthrow the kingdom and break up the rule of the people once again. Civil war lasted for many years until the cult was finally driven out, but not destroyed. The leader of the cult, Tarpeya, fled to the deserts in the north with her few remaining followers. Rumors from the desert city Erimea suggest that the cult has established camp in the western part of the desert.

Although Carathusia’s resources were nearly exhausted after the civil war, the king was troubled by the reported movements of the remaining Narthenians. Concerned that Tarpeya was up to something more than just hiding out, he summoned a young warrior who had distinguished himself in service during the civil war. The young hero was sent to investigate and advised to travel first to Adon, where the dungeon held a former adviser to Tarpeya who may know more about her activities.

The rest of the story will come out during the game. Please be aware that some of these posts will likely contain spoilers. I’ll try to note that at the top of posts, but I can’t promise I’ll be perfect…