Showing posts with label rpg. Show all posts
Showing posts with label rpg. Show all posts

Thursday, October 31, 2024

RPG: Automatic Server Detection

It has been a few years since the last update on my computer RPG, but it did have some progress this past month! It is a multiplayer game, but in prior versions you had to manually type in the IP address of the server you wanted to connect to.


Now, running servers will announce themselves over the network, and potential clients will pick up on those messages and display them as options to the player.


Instead of typing in values, just click the detected server and hit play!


Saturday, June 26, 2021

RPG: Skills

Stats in my game are things that can go up and down as you venture in the world. If you concentrate on melee combat, those stats will go up and spells will suffer. If you concentrate on spells, those stats will go up and melee combat will suffer. If you stay a balanced player using both, then all stats can be high, but it will be essentially impossible to keep them all maxed.

Skills though are something that you learn and never forget. Even getting knocked out, your stats may go down but your skills won't budge. Repeat from my post on stats: "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."

What I don't like:

I hate when games only allow you to pick a single skill to improve each time you level. I don't have a problem with requiring points in lower skills to unlock higher skills, but it's designed to force you to concentrate on one skill path. Trying to be a well rounded character or attempting to try all skills just means the "good" skills you want in the end game are never going to be as powerful as they could have been. This is my only real gripe with Diablo 2.

What I like:

A few decades ago, I played a MUD (text based Internet telnet game) that had the best implementation of skills I'd ever seen. They were all in categories and subcategories, and improving a single item in a subcategory would benefit everything in the tree.

For example say there were short swords, broadswords, longswords, daggers, and spears as available melee weapons. And say my character mostly used a short sword but just started using a broadcast. His skill tree may look something like this:

- Melee Weapons : 5
  - Swinging Weapons : 15
    - Short Sword : 30
    - Broadsword : 25
    - Longsword : 15
  - Thrusting Weapons : 5
    - Dagger : 5
    - Spear : 5

Using any melee weapon increases the overall "Melee Weapons" value a little. With how much my character has used short swords and broadswords, the overall value has reached 5. Any subcategory of "Melee Weapons" will be at least 5 as well. Since my character hasn't used thrusting weapons, it's a 5 and each thrusting weapon is 5. Which makes sense... although the motion of a swinging weapon is very different vs a thrusting weapon, someone highly experienced in one can likely pick up the related melee weapon very quickly.

Digging down a bit further, short sword is the highest (because that is what my character practiced with most) followed by broadsword (next highest). My character has never used a longsword, but because he has so much experience in swinging weapons, he automatically has a skill level of 15 in that.

This was absolutely something I wanted in my game. I haven't broken it out to specific weapons, but skills are now categorized with subcategories. Improving a skill in a subcategory ultimately helps all skills in that category.


Spells are broken out as well...


In the process of implementing the skills, I also added more capabilities. For defense, there is blocking and dodging. If you're holding a shield, it uses blocking. Otherwise it uses dodging. So now you can use shields in my game.


Additionally, the game now supports single handed weapons, two handed weapons, and dual wielding two single handed weapons. If you pick a weapon combination that is not acceptable, then it puts a red mask over the weapon so you know it's not in use.


In the above screenshot, I'm holding a single handed weapon and a two handed weapon. Since both hands are required for the two handed weapon, it's masked in red and I don't get its attack benefits. If I stop using the single handed weapon though...


It becomes available and I get its full attack benefit. How about the one handed weapon and a shield?


Now players can have interesting combinations of two handed weapons, dual wielding weapons, or mixing single handed weapons and shields. The more they use a certain combination they more they'll improve with it, but they can still switch to other weapon types without it being a complete loss.

Wednesday, May 26, 2021

RPG: Attack Types & Resistances

May has been a great month for improvements to the game. Invisible to the user was reworking memory to handle large numbers of terrain types, items, characters, and animations. Characters unarmed attack sounds were externalized along with timing of the weapon attacks. 

On the visible side to the user are Attack Types and Resistances.

There are 6 damage types: blunt (a club), piercing (a dagger, bow), slashing (a sword), water, fire, and electricity. The last three are used in spell attacks and magical weapons.

Each character has its own unarmed damage types. My "rats of unusual size" do piercing damage for their unarmed attack whereas my humans do blunt unarmed attacks. Swords do slashing damage. Any weapon or spell can have any combination of any value of damage types. For example a Blizzard spell does blunt and water damage.

The attack stats are shown to the user; unarmed my player only has a blunt attack of 0.2

Armed with a sword my player has a slashing attack of 1.

In addition to the attack type, each character has its own base resistance. For example trees are resistant to piercing and water damage. Items can adjust a character's resistance.

If I equip some armor, my blunt and piercing resistances go up.


Skills are next up to be revamped, and I already have significant progress on them. That however will wait for the June update.


Sunday, April 25, 2021

RPG: 3D Art Assets from Unity

I really like the Diablo 1 / Diablo 2 art style, but I don't have the time or skill to model that number of 3D characters. Even though I'm not using Unity as the game engine, it has an asset store with a huge library of 3D models that many of which match my desired art style. So, how about use the Unity art assets and just convert them into sprites for my game? I had no experience with Unity and I've got plenty of work to do without becoming a Unity expert, so I attempted the least amount of work possible to generate usable sprite sheets.

To generate the sprites from the 3D models, I found an asset called "Animation Baking Studio" for $24. As a test I found some free models that I'll likely replace in the future, but they're far better placeholders than the eyesores I had before.

My steps to produce a sprite sheet from a 3D model (written here for my own documentation just as much to help someone else!):

1. Create a new Unity project.

2. Wait for it to build...

3. Go to Window->Package Manager, under Packages select "My Assets". Import "Animation Baking Studio" and the desired art model.

4. Wait for the import...

5. Navigate to Assets->AnimationBakingStudio in the Project, double click Studio. Studio will be selected in the Hierarchy.

6. Delete the sample models under the Hierarchy.

7. Navigate to the desired asset model, drag from the Project folder into the Hierarchy window.

8. Select the new art model in Hierarchy, in the Inspector on the side, click add Component and select "Mesh Model (Script)".

9. Drag all desired animations into Mesh Model (Script) Animations list. This is so the AnimationBakingStudio will know which animations to apply to the character.

10. Select "Studio" under "Studio" in Hierarchy. In the Inspector "Models" section, drag the desired art asset in.

I'm still fine tuning the options to find what works best, but my current setup is as follows:

Main Camera:
  Perspective, Field of View 60 deg
  Relative Distance, 2
Directional Light: Directional light (Light)
  Follow Camera Rotation Checked
  Follow Camera Position Checked
Model Rotation:
  View Slope Angle 30
  Show Reference Tile Unchecked
  View Size 8
  Base Angle 0
  Angles checked: 0, 45, 90, 135, 180, 225, 270, 315
Shadow Type:
  None
Extractor:
  DefaultExtractor
Apply Variation:
  Unchecked
Show Preview:
  Checked
  Background Type: Checker
Resolution:
  X: 150, Y: 150
  Frame Size: 10
  Simulate: 0
  Delay: 0
Trim:
  Unchecked
  (Ensure Unified for All Frames is also Unchecked, otherwise a bug prevents it from generating the animations. Developer said they'll have the bug fixed in the next version though.)
Pack:
  Unchecked
Make Animation Clip
  Checked, Frame Rate 20, Interval 1
  Make Animator Controller Unchecked
  Make Prefab Unchecked
  Generate Normal Map Unchecked
File Name Prefix: Empty
Output Directory: As Desired

11. Once the options have been entered, click "Bake all models".

12. And wait for the render...

13. When it's complete, navigate to the sprite sheet folder and enjoy!

I made some modifications to how sprites are loaded in my game so I don't need to do any additional processing on the images. The game can load the Unity exported images as is; including even the files names. I still have some changes to make to support all the animation frames, but the proof of concept is overwhelming successful.

Again long term I'll likely not use these 3D art assets, but it's a gigantic step from where I was and now I've developed the process for potentially all future characters in the game.

There may be better ways to do this in Unity, but so far this has been the least amount of effort for greatest return I've found.




Sunday, March 28, 2021

RPG: Map Pins / Packaged Build / Sounds

Map Pins

This month had many improvements in the game. First off are Map Pins. I don't like the modern ARPG mechanic of "here's a quest you don't need to read, here's an arrow on your mini map pointing directly to the quest location, break everything there, and after that you'll get a new arrow with where to go next". Players don't read the quest text because there isn't any need to. On the other hand, modern players aren't going to get out the graph paper and take copious amounts of notes (nor should they have to).

I liked how Dragon Warrior on the NES did quests. You had to talk to the NPCs to get clues on where to go and what to do. But if you wanted to have any sort of break from the game, you were going to have to jot down a few notes to remember how everything came together for the next time you played. Just a few words and a marker on the map would suffice.

My game's presentation is of a giant map you're walking around on. What better way for a user to write down notes on quest items than as pins on a map. In the bottom right section under Notes, you can select to "Add Map Pin".


A dialog box will then appear where the map is centered asking for a name. (You can pan the map using the middle mouse button, so the map pins can be placed anywhere; not just where your player is.)


Give it a name, and the pin is placed! Multiple pins on the map...


Adding pins for areas I've never even been to but someone told me to go there...


You can toggle the visibility of the pins with the "Show Pins on Map" checkbox. Now someone can play the game, get a clue of a quest item, mark it on the map, and even if they don't play for weeks they'll have their notes loaded and ready to go. But at the same time it's not the modern complete hand-holding of a "go here arrow".  


Packaged Build

Something very important in software development (or anything really) is fast iteration and minimizing steps to deployment. When just debugging on my local computer it wasn't a big deal, but I commonly test this multiplayer with other computers. I've added a Post-Build event when compiling in Release to execute a batch file that packages the game up in a ready to deploy zip file.


One click in Visual Studio and I have a build ready for release...


It's not uploading anywhere (I'm not at that point yet), but that will be the natural addition to the script when the time comes.

Sounds

A while ago I had added random sounds that game characters could play (birds chirping from trees). Last month I added sounds when you got hurt. I had considered sounds to be a minor part of the game, but the more I played with them the more ideas I had.

All the code handling loading sounds and what sounds to use has now been externalized. Terrain tiles can now play sounds (waves on the beach), different sounds play depending on what you're moving on (walking on gravel vs walking on dirt vs walking on stone), and attack sounds play when using weapons. All volumes are adjusted based on your distance from them source of the sound.


These few additions have really made the world more immersive. When standing in the town, a street musician could be playing a song (fairly loud if you're close by). The beach isn't far off so you can hear the waves on the shore but much quieter than the musician. Then occasionally you'll hear birds chirping from the trees. If you walk through town on the path you get a unique sound for it.

Since the birds chirping is random and the volumes are based on your distance, it sounds very natural and immersive. (And if you cut down all the nearby trees, you won't hear birds singing anymore!) Sounds went from a minor part of the game to something that can be really key to the gameplay.







Sunday, February 28, 2021

RPG: Various Updates

Various updates this month to the game:

  • Packet counter to debug network message traffic.

Which was used to dramatically reduce the number of packets sent over the network so it's far more efficient.

  • Fixed bugs with the new collision detection / avoidance and pathfinding.
  • Now playing "hurt" sound effects when the player is hit by a monster.


Saturday, January 30, 2021

RPG: Pathfinding

This month I decided to tackle pathfinding, and it came out really well. The world is a giant grid of tiles - some you can walk through, some you can't, and some you can only walk into from certain directions.

I'm using the A* algorithm to find paths from a character's current position to its destination. The A* algorithm as implemented is smart enough to know which tiles can only be entered by limited directions.

In addition to the A* algorithm to pathfind the static tiles, there are also obstructions of dynamic characters that can be in the way. And those obstructions can be of 2 shapes - circular (tree for example) or rectangle (bed for example).

If the moving character encounters one of these dynamic obstructions, it traverses around the obstruction in the shortest route possible to stay on its A* path.


Enemies are far more deadly now; you can't just hide behind a tree and get them stuck. Also it's now trivial for me to have villagers pathfind across town to accomplish various activities throughout the day.


Thursday, October 29, 2020

RPG: Memory Reduction

 Although CPU performance was improved to a solid 60 Hz, memory usage skyrocketed.


Each depth of the map has a ground tile and a canopy (roof) tile. When rendering the scene, the ground tile is drawn followed by characters followed by the canopy tile. That way a building roof can be drawn over characters.

For now we have 5 depths (that will grow) and 4 animations for terrain (that will likely increase as well). So: 5 depths x 2 (ground/canopy) x 4 (animations) = 40 tile maps.

I was generating at startup every one of those tile maps. That actually turned out to be totally unnecessary and very memory wasteful. To update all the tiles in a tile map from one level to another (8 in total) only takes a fraction of a second - barely noticeable. So I've replaced 40 tile maps with just the 8 that are in a single depth and the player has a trivial pause when the view switches between depths..

The difference in memory usage is unbelievable - 93% less:


There were lots of graphical glitches with canopies, walking to the edges of building, and other UI elements not redrawing properly that I've also now fixed. Even though the game still looks awful, the underlying engine drawing it is becoming much more capable.

Also did a network test, 3 players all fighting in the world together!


The network test went great. Found a handful of bugs (including an especially funny one of dead players that weren't resurrected quickly getting transported to the middle of the world based on monster respawn logic) but the game was really fun.













Wednesday, September 30, 2020

RPG: Quest for 60 Hz

As I implemented more and more features, the performance went down and down. It got to the point that if I zoomed out all the way, my frame rate would drop to about 1 Hz. In my last post I detailed how my drawing went from thousands of individual draw calls to just a handful for the map. My performance jumped to the upper 30s but still far from where it should be.

The most CPU intensive operation was still drawing, but it was the user interface this time. Every frame every control item (button, text, bar, graphic) was redrawn; each having its own draw call. I reworked the drawing routine to draw all of those controls onto a single texture generated dynamically. Now instead of recalculating / redrawing all the controls every frame, I'm drawing the single dynamic texture every frame. If a control changes (text, visibility, color, etc.), then just that one control is updated onto the dynamic texture. After that change, I was able to get 60 Hz.... most of the time.

The last bottleneck was a simple bug in the A.I. logic that caused entities to check what to do every frame rather than every other second. Once that issue was fixed, I achieved 60 Hz in all cases in the game. Wohoo!

(Frame rate in the capture shows 58, but it's bouncing around 60.)

The CPU is still working harder than I'd like it to. I want the game to be able to run on relatively low powered computers, and I think lower end processors will fail to reach 60 Hz. So more to do, but at least right now it's buttery smooth for development!

Monday, August 31, 2020

RPG: Start of Tile Map, Respawning

Tile Map

Despite the game having poor graphics, I was still having major frame rate issues when the player zoomed out to view the whole map. And each additional feature was making the situation worse. (Surprise, surprise - making over 360x180=64,800 draw calls every frame was slow.)

The solution in SFML (Simple Fast Media Library, the library I'm using) is to make a TileMap. Create a single texture that has all the images your map is going to use. Then instruct the TileMap of which image from the TileMap texture are to be added on the larger game world and where. Have the video card handle all the rendering in one draw call from the TileMap as opposed to 64,800 individual draw calls. (It was actually far more calls than that...)

The result is an order of magnitude increase in performance. Previously when zoomed out frame rates were low single digits. Now I'm reliably getting upper 30s. Performance is still lower than it should be, but there is much room for improvement to pull that up to 60.

The drawing overhaul is not complete. Fog of war and terrain borders aren't even implemented yet, but the new drawing is such a major improvement that it's on the short list to be finished.

Respawning

Previously once a monster was killed, its equipment could be picked up by the player but future versions of that monster wold not have the equipment. For example, only the first instance of the rat killed had a rat hide. The load code has been reworked such that monsters that have been recreated regain their default equipment. This same rat has now been killed twice, leaving behind 2 rat hides.


Lots of other small changes have been made this past month: fixes to networking code, cleanup of items, and the start of a more user friendly store.

The goal for next month is to complete the new drawing routines and the store revamp.

Friday, July 31, 2020

RPG: Hover Info Over Objects

Not too much to show on this RPG update. I am now adding mouse hover labels / hit point bars (when appropriate) to objects on the map.

Mouse over an item tells you what it is...


Mouse over the bed to tell you what happens when you interact with it (including health bar on the off chance you want to break your bed)...


If you mouse over a NPC, it tells you what happens when you interact with it...


If you mouse over an enemy, then you see its health (and nothing happens if you try to interact with it)...


I'm still not entirely sure how I want to handle labels and if they should include what happens when you click to interact, but the options are there now to tweak it.

Other than some minor code cleanup, that's the whole update this month!

Saturday, June 27, 2020

RPG: Multiplayer Items & Effects

Items and effects are now communicating over the network!

Items


The server or the client can pickup or drop an item and that change is reflected across the network. Anything on the ground is managed by the server. Anything held by a player is managed by that game's client.


Next I command the lower right game client to pick up the sword and the upper left game server to pickup the healing potion.


Changes reflect on both games! Lots of cleanup to do in the code, but it's working great.


Effects


Effects are not purely visual (drawing of flames on the ground), they also include abilities such as healing or damaging.

Screenshot of the client putting down a flame wall...


I let my server player get injured...


Then my client player heals him...


A visual effect is drawn on the player receiving the heal on both games and the target player's health increases.