1.2: Stroustrup Would be Proud; Knuth Would Not (and Windows Build at Last!)


First of all as the title mentions, there is a Windows build. More about that below but do check it out.

I didn't have a lot of time this week and what I did I mainly spent on enhancing performance.  A couple of people tried D.C.B.A(TV) and the one piece of feedback I consistently got is that it is really, really slow.  Which was mystifying to me as I have a fixed-step 60fps game loop which ought to be pretty responsive.  But I investigated further and found there were a couple of silly algorithmic mistakes which could kill performance.  BTW, if you don't know, good tools for investigating these kind of things  are cachegrind and callgrind from the [valgrind toolkit](https://valgrind.org/docs/manual/manual.html).

I was doing too much work in my draw code.  My map is a 40 x 80 2D array of Tile objects.  When I draw them I loop through this in a double for-loop and there is a calculation so that the player is always in the center of the screen (I.e. the camera follows the player.)  Based on this, each tile is individually drawn to the screen.

Problem 1 is that I was drawing the entire map and then throwing away the bits which were not on the visible screen.  The fix was to skip drawing if the tile is off-screen.

Problem 2 was that I was calculating the center position in every call to the function that draws a tile.  So for a 40 x 80 map that's 3200 times.  Moving it out of the for-loops meant it only had to be calculated 1 time.  A dramatic improvement!

The third problem surprised me.  I have code that calculates field of vision (FOV.)  It is called twice per draw session.  Once before the map is drawn to update which tiles are viewable and once afterwards to reset them in preparation for the next draw session.  The actions performed on a tile are different in each case and I got clever and had the FOV function take a lambda parameter which customized it for each use.  Very modern C++ but apparently rather slow.  Turning that into a bool and an if/else makes for more code but faster code.  In hindsight, I don't need to recalculate FOV every time I draw; I can defer until the player actually changes position but for now I have left it. 

Another potential problem I thought I might have is that I use mvwaddch(3curses) to draw each tile.  This moves the cursor to the new position and then prints the tile character.  But as the tiles are all in a row, I could save myself 79 moves by just moving once to the beginning of a row and then incrementing the position by one for each tile.  However this complicates the code and needlessly too as profiling shows it doesn't really make a difference.

I fixed a couple of places where PDCurses behaves a little differently from NCurses.  I also found a line of clever C++ code which Visual C++ evaluates differently from g++.  Making it boring fixed the problem and I can now make a clean build under Windows.

So now I'm pretty happy with the speed and can move on next week to adding features.  But my nephew who playtested for me says I am "old" and "not a gamer."  Can someone who meets his standards try this version and let me know how it goes?

Files

dcba - 1.2 Final 7DRL version for Windows 362 kB
53 days ago
dcba - 1.2 Final 7DRL version for Linux 1 MB
53 days ago

Get Dolorous Coronach of the Baleful Abyss (Taylor's Version)

Download NowName your own price

Leave a comment

Log in with itch.io to leave a comment.