Tuesday, May 29, 2018

RPG: Stats

Typical RPG Approach


I'm taking a very different approach compared to typical role playing games when it comes to stats (strength, intelligence, wisdom, constitution, dexterity, charisma). In most games, you start off with a beginning set of stats - possibly random, possibly with some user decision. Then as you "level up", your stats either increase automatically or you have some ability to pick which ones to increase. In some extreme circumstances, death may reduce your stats but normally they only go up.

In response to the "typical" way of doing things...

  • I hate randomly assigned stats. I shouldn't be crippled in the game for the next 20 hours because a random number generator didn't go my way in the first 20 seconds.
  • Although picking which stats increase when you level up is nice, it's usually fairly meaningless. Unless there was some kind of equipment with a minimal stat I was short on, I would just spread them fairly evenly (maybe a little extra into intelligence if I was a wizard or dexterity if I was a rogue). Still fairly meaningless.
  • I don't like the idea that an intelligence or charisma number could determine how I could make decisions in the game. Although Fallout has some funny scenes with that, again I don't want a poor decision early on to ruin the next 20 hours.
  • I don't like permanent penalties such as death reducing a value. Penalties should always be recoverable in time.


My Approach


I'm going with just 4 stats:
Strength - Primarily for melee weapons.
Dexterity - Primarily for ranged weapons.
Focus - Primarily for spells.
Constitution - Your body's current toughness (separate from health).



The values of each stat will be much more fluid and vary based on your recent actions. When you start the game, you're a very young, relatively weak, and inexperienced adventurer so your strength, dexterity, focus, and constitution will all be low. As you swing your sword around, your strength will go up and thus deal more damage. As you use a bow, your dexterity will go up and thus aim better. As you use magic spells, your focus will go up and thus require less energy for a given spell. And as you survive marching the wilderness, your constitution will go up.

Maybe at first you were a sword user, but decided later on to go for ranged attacks instead. Over time from disuse, your strength will decrease but your dexterity would increase quickly. Same goes if you switch to just casting spells, your focus will increase but your strength and dexterity will go down. It will be possibly to try and exercise all three - regularly cast a spell, shoot an arrow, then do a finishing blow with a sword. But then you get into the jack of all trades, master of none situation. It will be very difficult to max all 3 of them.

After using just my sword...


After casting many spells and disregarding weapons...



But how will a player get permanently better over time?

That will be taken care of by skills! (Which I haven't gotten to yet...) How well your action does will be based on your stat + your skill. And your skills never go down. Think of it this way: You never forget how to ride a bike, but if you haven't been on one in a couple years you're not going to win the Tour De France.

Concerning using just focus instead of separate intelligence and wisdom for spells... Regardless if I'm praying to a god for divine intervention, reaching out to nature for help, or just materializing fireballs out of my hands, all of those requires focus. Is there really a benefit in splitting them up into separate stats?


Constitution & Death


Constitution is a bit different. Constitution will influence how much damage you take for a given blow. Instead of 30% of your health, maybe you only take 20%. Constitution will steadily go up and up and up. But if you get knocked unconscious, it will drop like a rock. Then you'll have to take an extended time to get it back up. Here's the deal though - you go into a boss fight with high constitution and get knocked down. Sure you can heal your hit points instantly, but your constitution has taken a blow and if you jump right back into the fight you'll be weaker than the last time.

Constitution after fighting for awhile...


After getting knocked down / dying...


This approach to constitution is how I want to give consequences to death without totally demoralizing the player and causing them to rage quit.

  • If there are no penalties for death and you start 15 seconds away from your corpse, then you can jump right back into the same battle and possibly win it - who cares if you die, it really didn't matter.
  • If death is permanent or very serious and you get struck down, then screw this game, it just wasted hours of my life building up this character so I'm going to do something else.
  • If death hits your recoverable constitution but has minimal other consequences, then you still REALLY don't want to die, but you also don't hate the game for stealing your time if you do. You just need to take a break from that boss fight - build up your skills while your stats improve - then go back after him.


Other Improvements


In addition to adding stats in the game, I did lots of code cleanup of tactics and made it so you can pickup health and energy potions off the ground.


Monday, April 30, 2018

RPG: Tactics

I now have a solid foundation for the tactics code and many tactics/spells already implemented.

The latest user interface...


One key aspect I want in my game is to have no set "good" or "evil". You have alignments with certain groups of people, but those are dynamic based on your actions. In Diablo / similar games, you left click on an orc for your basic attack, but you can also safely left click on a blacksmith to sell your equipment. I want you to be able to talk to an orc or attack a blacksmith.

To accomplish this, I've dedicated the left mouse button to "Interact" and the right mouse button to your selected "Tactic".

Left clicking on the ground, an item, or a character is your basic "Interact". If you click on the ground, you'll walk there. If you click on a bag of coins, you'll pick them up. If you click on a chest, you'll attempt to open it. If you click on a door, you'll enter it. And eventually if you click on a person, you'll attempt to communicate.

Right clicking on the ground, an item, or a character does your selected "Tactic". At the lower right of the screen, you can select your active tactic (highlighted in red). If you right click on that blacksmith when the weapon tactic is selected, you'll attack him. You could even click to heal someone that would normally be a foe. (There are keyboard shortcuts for the tactics.)


The tactics are grouped by row...

Row #1: General


Attack - Use your wielded weapon - sword or ranged weapon.

Lock Pick - Pick the lock of a chest. (Chests can be unlocked - single left click opens them. Or locked - require hitting many times with a weapon or use of the lock pick skill.)


Row #2: Arcane Spells (Wizard)


Teleport - Instantly jump to somewhere else that you have vision on.


Flame Wall - Create a ring of fire that lasts several seconds somewhere on the map. Characters within the fire take continuous damage.



Row #3: Divine Spells (Cleric)


Heal - Heal yourself or a target character.

Protection - Create a protective ring around yourself or a target character.


Presence - Show the relative alignment of nearby characters.


Holy Bolt - Request a bolt of lightning to come down on a target character.


Resurrect - Bring a target character back to life.


Row #4: Nature Spells (Druid)


Entangle - Vines come up out of the ground slowing down the movement of those nearby.



You can see the game engine now supports effects that not only draw on the screen but also can affect characters (slow them down, deal damage, etc.).

My preferred role has always been Cleric (and hence why I've already filled out all the cleric types skills), but I've never been a fan of having to choose a specific path and being prevented from stepping outside it. Anyone is able to learn & become skillful at all the tactics. I'll go into stats later; but I'll use those to help balance between someone primarily a magic user vs someone primarily a fighter vs someone that is a jack of all trades / master of none.

Also, I hate warm up times / other preventative measures to keep you form taking advantage of all the skills you know. If you have the Energy, then you can use a tactic/spell. (Doubtful I mentioned this before, but my Mana is now considered Energy - doing a tactic will decrease your Energy. And the cost of tactics varies - Heal costs less Energy than Resurrect for example.)

I've jotted down many other ideas for tactics, and I am fully expecting to have all 20 slots filled for the game. Halfway there already!

Sunday, April 1, 2018

RPG: Terrain & Canopies

Lots of work has been completed on the RPG recently, so I'm trying to catch up on development posts now.

The game had all the terrain types hard coded. To get any kind of new terrain to show required creating the textures, adding new variables, calling functions to load those variables, and adding in switch cases to know where to load those textures. Took way too long.

The new method has a single text file that points to all the terrain types available.


The game loading function goes through each line of that file to parse the corresponding dat file for a specific terrain type.


Oceans happen to have 4 animated frames to give the illusion of waves. There are additional sprites for the ocean depending on how it borders neighboring textures (corners and sides). Those additional sprites are drawn when necessary to avoid hard edges for terrain such as water or grass.

The second line of the Ocean.dat has "o" - which is the code for this terrain type. The game's TerrainMap file is a 360x180 matrix of code letters that determine how the world looks.


There are so many unique variables a single block of terrain needs, I will inevitable go to a binary format. But for now just a large ASCII map is convenient.

In addition to the externalized terrain types, I've added a new concept called "canopies". Canopies are overlaid above the terrain to mimic things such as building roofs, but they don't block character movement.


Loading of canopies is handled very similar to terrain. There is a list of the canopy types.


And folders of each canopy type that contain a dat file and texture.


And finally the canopy map.


So although not much to look at now, these major changes allow me to greatly accelerate development.

The next post will be a significant one though! I've got a control scheme pretty well worked out and am in the process of implementing skills / spells.

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.

Backpack


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.

Money


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.


Potions


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.

Weapons


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!