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.






Sunday, May 31, 2020

RPG: Multiplayer Characters

Player and non-player characters are now communicating over the network!


As you can see in the screenshot, items are not being shared between game instances yet.

The type, position, speed, heading, armament, animation, and killed state of characters are sent between games. The position of network characters are dead-reckoned based off the speed and heading of their last update packet to keep the movement smooth and limit packets on the network.


I'm actually quite happy with how smooth the motion is over the network. It's on par with similar network games. Up next will be to send effects and items over the network.


Wednesday, April 29, 2020

RPG: Multiplayer Connect & Chat

Multiplayer work has begun in the RPG!

After selecting your character, you pick if you're single player or networked.


My goal is that you will be able to seamlessly go between a single player experience and playing with your friends.

- If "Single Player", then it starts as normal.
- If "Private Server", then it starts the game as a TCP server and will accept client connections.
- If "Private Client", then it will connect to a TCP server.
- If "Public Client", then it will connect to an Internet accessible server. I don't know how feasible this mode will be. For now I'm intending the game to be primarily LAN (Local Area Network) play like Diablo 1. Even if the Internet play shows promise, I want to keep the LAN play fully functional.

I started 2 instances of the game. One as a "Private Server" with a player called "Host". The second instance is with the player called "Player" connecting as a "Private Client" to the server.


And when I click "Start", it attempts to connect to the server. If successful, it starts the game for the client!

On the Server (left window), it announces "Player" has arrived.


You can see sharing character positions is not yet working, but I do have chat messages between the servers and clients functioning. Press enter to bring up the chat box, type in your message, press enter, and it gets sent.


There is no set limit to the number of players that may connect. It'll be interesting to see how well it scales as the numbers of players grow.