Although CPU performance was improved to a solid 60 Hz, memory usage skyrocketed.
Thursday, October 29, 2020
Wednesday, September 30, 2020
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
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.
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
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
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 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...
Sunday, May 31, 2020
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
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.