Sunday, March 4, 2018

RPG: Initial AI & Multiple Levels

Two of my recent goals were to redo the memory management and implement an initial artificial intelligence.

Memory restructuring is complete - now using C++'s shared/weak_ptrs. I still have a few "new"s in there, but for anything that is created and destroyed during playtime those have all been swapped out. It will be significantly easier to split the game logic into multiple threads and support network play now.

(Initial) Artificial Intelligence

I also have finished an initial AI for the non-player characters. It's still VERY simple, but basically every character has a self allegiance. Trees are "cultural", squirrels are "wildlife", human civilians are "human civilians", and my current bad guys are "demons". Then each character has an allegiance rating to each allegiance type.

For example, the player could be neutral with "wildlife", friendly to "human civilians", and evil to "demons". Squirrels would keep their distance, civilians would walk up and talk, and demons would attack.

This unarmed civilian is walking up to talk to me...

But this armed guy is tagged as a demon and is attacking me...

Alternatively, the player could be friendly with "wildlife", evil to "human civilians", and friendly to "demons". Squirrels would approach, civilians would flee, and demons would say hi.

I'm still working on how the allegiance is dynamically changed. Ideas include feeding wildlife would increase your stance with them. Killing civilians would obviously make them hate you. And then to get on a demons good side? Sacrifices maybe?

Multiple Levels

In addition to the "whole world" 360 degree longitudes by 180 degree latitudes, I want the player to be able to go to additional level depths - such as underground cave systems or floors of buildings. I can now tag terrain tiles as pathways to go further down or up in depth.

This unbelievable crude buildings has a door on the south side.

Walking into that door transports the player to the same latitude & longitude, but to a different depth.

There is a tile to the south so the player may leave the building.

The inside terrain tiles are treated identically to the outside. Characters can be added, equipment can be dropped, etc. And you can still zoom out to see the whole world (at that map level).

I have a rudimentary edit mode in the game that lets me add characters to the map and save those to file. But my current map editor is making changes to what looks like bad ASCII art in Notepad, and it's holding me back. An in-game map editor may be in the next major update (multiple textures on characters is on hold for now).

Monday, February 26, 2018

RPG: Inventory

For my inventory system, I want to mimic the systems typically found in action RPGs, but they do have flaws I want to address.


Although there is some fun playing the Tetris minigame in Diablo 1 and 2, it does pull from the core mechanic of the game. So I'm going with a backpack where you can hold up to 10 items regardless of shape. (I might make it so you can page through and hold 20 or 30 items, we'll see how important inventory becomes...)

The downside is you can hold 10 broadswords or 10 rings, but either way you'll be maxed out of space. That will probably be ok. If the balance doesn't work well, I could implement an idea of encumbrance and/or weight to solve the issue. That way you'd be limited to maybe 3 broadswords before being over encumbered whereas 10 rings would no problem. I'll see how the game develops before implementing that.


For money, I'm having a separate purse that the player carries. Any money picked up will just go into that purse and not take up backpack slots. I'll set a maximum that can be held at a single time (to be determined as the game play gets worked out).

When someone carrying coins dies, a purse is left on the ground that can be picked up. Clicking the purse will transfer those coins into your own.


I think I've got a solid solution for Health and Mana potions. Diablo had the issue where you could put them on your belt, but they inevitably overwhelmed into your inventory. Thus taking the player back to Tetris and away from core gameplay.

But why are potions so freaking diluted with water? Concentrate that stuff, have a single potion bottle, and just take swigs of it when you need to!

In this screenshot the player has 7 drinks of health potion left and 3 drinks of mana potion left. 10 maximum for each.

And I've never been a fan of variable sized potions. Diablo/similar games had it balanced so that when your maximum hit points went up enough to take advantage of the bigger bottles also coincided when those bigger bottles became available also coincided with when you got enough money to afford them. So... what was the point? You'd always just get the best ones available.

If you take a swig of a health potion in my game, you get full health regardless of your maximum hit points. Sure I could make it so your maximum health went up and you could "buy" a bigger potion bottle, but it would be the same issue as in Diablo. By the time max hp goes up and bigger bottles become available your money is already up, so it's all an unnecessary wash.

And concerning health rejuvenating on its own - although it's convenient, it kills tension and disrupts gameplay (just flee for a bit, wait, then run back with full health). So I have zero plans on making health go up on its own. I don't think I can have mana go up on its own either as it will inevitable have the same issues as health. If you're trapped in a cave with low health and no supplies, I want you to keep that tension until you're actually out of the cave.


I loved Diablo 2's concept of swappable weapons. Have the bow at long range then a quick key press and you're ready for melee combat. Awesome. Diablo 3 ruined it... I played as a wizard and it didn't matter if I was holding a sword or a wand, it was shooting magic bolts. (Seriously I don't know how the designers degraded the game that severely.) So what weapons you're holding will matter in my game, and I'll present good reasons to equip a variety.

All Together

And the current version of the inventory panel....

Friday, January 26, 2018

RPG: Tile Edges & Mouse

A lot has been improved since the last post on the RPG!

For one, I was introduced to the program Aseprite which has helped immensely with the art. My terrain tiles still aren't good, but at least they're not embarrassing!

And I've made four big code changes:

1. Tiles (such as ocean or grass) will now draw edge overlays onto neighboring tiles to smooth out the transitions. The overlays are also animated so the waves of water coming on and off the beach have movement.

2. You can perform basic melee attacks.

Here I've chopped down a tree and killed the guy on the beach.

3. Finished all movement via the mouse. Movement now mimics Diablo - click somewhere to go there, click on a guy to walk to him and attack, or click on an item to walk over and pick it up. If you're holding an item and you click on the map, drop the item in that direction. Keyboard movement is still supported and I still plan on adding joystick support, but the mouse movement is very nice.

No that isn't a giant sword on the ground, it's what I'm currently holding in my hand (tracks with the mouse cursor). If I click on the ground I'll place it down (and the sword sprite will scale down in size) or I can click it into my inventory window to wield it or put it in my backpack.

4. Some internal code changes with how I'm handling user inputs and executing those actions. Those changes enabled a single click to perform compound actions such as walk up to item/character and pick up/kill it.

Goals for next major update:

1. The memory management is currently not thread safe, so trying to scale up the number of items by making it multi-threaded is not feasible. I'm reworking my memory management now to support that.

2. A character's head, body, arms, legs, and feet are all in one sprite, but I really want the player's image to reflect the loaded equipment. If a sword is in the player's left hand, it should show in the left hand of the player. If the player is wearing red boots, then it should show red boots. If the player is holding 2 shields, then it should show holding 2 shields. Trying to use one sprite for all the possible equipment combinations is not feasible, so I'm going to experiment with drawing legs/feet separate from body separate from arms/hands separate from the head.

3. Implement a simple AI so characters will attack back.

Monday, December 18, 2017

Raspberry Pi Server: SVN Upgrade

My original plan was to upgrade my Raspberry Pi server to a new Pi 3, and use the original Pi 1 B+ for the Retro Pie. I've since backtracked for various reasons and put the Retro Pie SD card into the new Pi 3. So now my original server is back on the Pi 1 B+. The server had been working great except it was running out of disk space (only had a 4 GB SD Card).

Fairly simple to solve, I'll just use an external USB drive for storage! I plugged in a 32 GB USB drive, and now I needed to move my repository.

First I needed a folder to act as my reference location when I wanted to access the USB drive. It doesn't matter too much where, I went with: /media/usb

Created the folder with: sudo mkdir /media/usb
Set the ownership of the folder with: sudo chown pi /media/usb
Set the permissions of the folder with: sudo chmod 0777 /media/usb

After plugging in the USB device, I needed to know the device UUID by typing: sudo blkid

Then I needed to edit /etc/fstab for it to automount on boot: sudo nano /etc/fstab

For my new mount, I went with:
UUID=390A1652      /media/usb      vfat    uid=pi,gid=pi,umask=0000,sync,auto,nosuid,rw,nouser,nofail 0 0

As an alternative, I could specify to automount any USB drive that is plugged in as /dev/sda1. That seemed risky to me though as my current drive could change and the new drive could connect as /dev/sda1. That new drive wouldn't necessarily be vfat.

If I had wanted to mount any USB drive, the line would have read:
/dev/sda1        /media/usb      vfat    uid=pi,gid=pi,umask=0000,sync,auto,nosuid,rw,nouser,nofail 0 0

Lots of options and opinions on this:
uid & gid are my username; some references suggest entering the numeric value. You can check your account's id by typing: id -u and id -g. Turned out my pi user was 1000.
umask=0000 is the equivalent of chmod 0777 (everyone has read/write access).
sync has input and output be synchronously.
auto instructs the drive to mount automatically at bootup.
nosuid I don't understand, but one reference says: Block the operation of suid, and sgid bits.
rw to mount the drive with read-write access.
nouser permits only root to mount the filesystem.
nofail causes startup to not wait 90 seconds / error out if it fails to find the drive.

And finally reboot the Pi via: sudo reboot

The next task was to move my existing SVN repository to the external drive...

I stopped Apache which is used for SVN: sudo /etc/init.d/apache2 stop

I copied the repository over: cp -r repos /media/usb

Then I modified the Apache configuration to point to the new location of the SVN repository. The config file is located in /etc/apache2/mods-available, file dav_svn.conf: sudo nano /etc/apache2/mods-available/dav_svn.conf

My SVNParentPath was /home/pi/repos, I changed it to /media/usb/repos

Apache actually needs ownership of the repository folder, so I changed ownership to www-data: sudo chown -R www-data:www-data /media/usb/repos

And finally, restart Apache: sudo /etc/init.d/apache2 restart

I did a full restart to make sure everything came back up, and it did! So my SVN repository now has 32 GB to play with; far better than the few hundred MB from before.

The above instructions were mostly just for my reference in case I need to do this or similar again in the future, but I hope it can be of help to others!

Monday, December 11, 2017

Retro Pie

I've been playing some classic games on my laptop with emulators, but it's just not the same as on the T.V.. I had some time over the Thanksgiving holiday to do something about it. I've read many other sites using Retro Pie and decided to go with that.

I'm reusing my original Pi B+, but its existing 4 GB SD Card was inadequate for the task. So I picked up a new 16 GB card...

Downloaded Retro Pie off the website... Their instructions were fantastic:

Then got Win32 Disk Imager...

And used it to write the image to my SD card...

On the left is my existing Pi in its case, and on the right is the "Super Tinytendo" case I bought off Amazon for $20. The build quality on the Tinytendo is great. (From the reviews, it sounds like their first versions with rough 3-D prints. The one I bought however was injection modeled and of very high quality.) 

4 screws underneath to open the case...

And the Pi fits perfectly inside...

The power light in front is functional; the instructions were very simple and spelled out in the Tinytendo manual. The Power and Reset buttons are unfortunately not functional. It'd be interesting to make them so though.

I ended up overclocking my Pi B+ so it could handle SNES games better (more on that below). So out of precaution I added a heat sync from Adafruit over the CPU.

First boot!

RetroPie only shows emulators for the corresponding games it finds. So at first boot no emulators are shown; you have to load them up. ROMs can be added via USB, SFTP, or Samba share. Since I'm primarily a Windows user (uhg), I went the Samba route. The Samba Share was super easy to access and copy ROMs to. Just type \\retropie in file explorer and you're there!

After a reboot the appropriate emulators showed up!

Some of the SNES games were running a bit slow, so I decided to try overclocking. You can access the Raspberry Pi config options through the Retro Pie menu.

Selected the overclock option...

And set the overclock to Medium. The games are working reasonably well at this level so I'm hoping this will suffice.

I'm using two Logitech Gamepads for the controllers. They have a good layout for both NES and SNES systems (among others), but they also have a few additional buttons not used by those earlier consoles. I'm using the rear-most left button as my hotkey button. If I push hotkey + rear left then it loads my last save state; hotkey + rear right saves my current state, and hotkey + start quits the current game.

The Pi rounds up a nice collection for entertainment - Switch (newest) on the left, N64 (the best) in the middle, and NES/SNES (the classic) on the right.

Thursday, November 23, 2017

RPG: Map

Unfortunately the idea of using real world photos for a RPG was short lived. I continued for another couple weeks but the shortfalls just too heavily outnumbered the benefits.

Biggest upside of the photos was the beautiful static images the game could have, but you want the world to feel alive. I did have some limited success with rain effects and varying the lighting to give a little bit more movement into the world, so that probably could have been sufficiently resolved. However I had 2 problems that could not be overcome...

1. If I wanted to setup a shop, inn, or whatever fantasy style building, I had to hope it already existed on the trails (which it wouldn't be). Otherwise it would be a huge amount of photoshopping to add a building realistic enough to blend into the scene to not just one photo but several photos at a variety of angles and distances (with vegetation / scenery blocking parts of the building)..

2. Movement had to be in discrete steps. (In my prototype I had taken photos roughly every 20 feet, which is fine for turn based but not for real time.) And trying to merge multiplayer and turn based in what is essentially a first person dungeon crawler just doesn't work out. My son can play Diablo style games, so if I want him to enjoy the game with me I need something real time.

And thus, the game has been redesigned! Thankfully not much code was thrown out. In fact what the game is now is what I had originally played around with when first learning SFML several years ago. So I replaced the real-world location code with the "whole world" map code I had written before.

It looks much more like a modern action role playing game:

Please forgive my awful developer art. I'm focusing on code now!

You can walk around with WASD. Unexplored areas are completely gray, but there is a fog of war for areas you've previously explored (shaded darker). Characters such as yourself, trees, or buildings can be on the game map. Also equipment can be dropped onto or picked up from the map. I have draw order working nicely - you can walk behind trees for example. The game prevents you from walking through trees (based on a radius) or buildings (based on a width/depth).

In the above screenshot, I've picked the sword up off the ground. I can now equip it or put it in my backpack.

You can use the mouse scroll wheel to zoom in or out of the map.

You can actually zoom out enough to see the entire world...

A player can traverse the entire globe. For the past several weeks I've been steadily making improvements, and I'm really liking the results. Terrain tiles and characters are animated. (Water can have waves, trees can sway in the breeze, and the player's feet move as you walk around.)

At this point I've got a very solid plan for the game.

The 5 second pitch is: Growing up you had the dream of mapping the entire world. And now that you're older, you've decided to do just that. But quite a lot of things can happen to someone exploring a whole world...

So the scope has increased, but a playable version shouldn't take too much longer. I can create a world with monsters to fight, inns to stay at, etc. relatively quickly. But this also gives me room to go much further. I could have warring kingdoms that you could join sides in or try to resolve in other ways. I could have the classic evil mage in the tower threatening nearby lands you may want to defeat. I could have a small farm community that you run across and decide is where you want to put down your roots. (Inspired by Stardew Valley...) But I don't want to get into too much scope creep yet; for now it's build a world you can run around in and kill monsters & improve yourself.

Tuesday, October 24, 2017

Rocket Launcher

Launching Estes rockets is fun; really fun. When I was younger I had a proper launch setup with rocket stand and handheld launcher. At some point those got lost and/or thrown out. The past few years to launch a rocket I just grabbed a long coil of wire and a 9-volt battery. Connect the wire to the Estes igniter, hold the battery against the wires, and lift off!

I'd like my son to have a slightly more... authentic(?) experience.

For the launcher, I want a nicely packaged box, with "ready" indicator light, launch button, and most importantly a safety key switch. That way I can hold onto the key while hooking the wires up to the igniter (without worrying about my son pressing launch prematurely).

Other than the key switch, all the other parts were leftovers from prior projects.

Drilled the holes for the key switch, light, and push button.

Quick and easy crimp the wires together. (There is a hole in the side for the long wire that goes out to the rocket.)

Wiring diagram for those that can't follow the above mess...

When the key is turned, the light illuminates signalling that the rocket is armed. Press the red button and electricity goes out to the igniter to launch.

And it works! There was basically no wind so it landed feet from the launch site.

Next up is a proper launch stand!