reaction game

Home Read the Story Download Credits

Climb the ladder

7 January 2020

Sometimes the things that sound the most straightforward end up taking the most time. Adding a scoreboard was no exception. Its been quite the tour through the features of WPF, and I’ve for sure learnt a lot.

Ultimately I’ve ended up with a system that works and doesn’t look too bad.

photo

(high scores screen)

However, opening the high scores screen shows a severe performance issue. It can take a couple of seconds to load and display the scores. Sadly this is quite a noticeable delay.

If I’d been developing in WinForms I would have built the score table as a single control and painted everything on it. However, WPF lured me into composing the UI from lots of small controls. A full scoreboard ended up being composed of a few thousand elements. Honestly, it’s pretty impressive that it works at all; but, I’m still going to have to redo it to be more monolithic because I’ve clearly pushed the composition system past its limits.

I was, at least, able to share the majority of the code between the High Scores screen and the Game Ended screen, so now when you finish playing, you get to something like this:

photo

(entering a new high score)

It’s all tied together with some typing sound effects and works rather nicely, aside from the performance issue.

Scores

When playing, score points can be gained by achieving objectives, like collecting plasma or progressing through levels. Points can be lost by dying, and they tick out slowly with time - the quicker you play, the better the score.

I added a score counter to the screen so you can see this during the game, and also tweaked the display of the remaining lives indicator so that it all hangs together better.

photo

(heads up display of score and lives remaining)

Game Over!

Towards the end, I realised a hilarious oversight - you could only get a high score by winning. Of course, the whole point of a scoreboard system is to let you progress even when you don’t make it all the way to the end. Luckily, it was a minor tweak to merge the GameOver and Victory screens, and it also simplified the code a lot.

Persistence

It would suck if you lost your high scores when closing the game, so I also had to implement some data persistence. I’ve tried using the built-in user.config system, and whilst it largely works, it does have one rather unfortunate issue. If you launch the same binary from two different folders, the data isn’t shared between them. I haven’t, as yet, found a way to override this ‘feature’, and yet I also can’t imagine any scenario in which it would be the desired behaviour. So I’m somewhat confused.

For now, it works, and I’ve kept it well isolated, so if the above quirk gets too annoying, it won’t take much to replace it with some custom code. Seems to be a common trend lately - the out of the box functionality is so close to being what I want it is hard to throw away, and yet it isn’t quite good enough.

Keyboard Control

Along the way, I realised that keyboard navigation of the menus didn’t work at all. That’s kinda shit, so I took a few hours to clean it up and make sure all the menu functionality could be navigated with the keyboard. Of course, it’s a mouse-based game, so this is not critical, but it is nice to be at least able to escape out of the menus :)

Extras

Before tackling the scoreboard, I also added animation to explosions and introduced a first-class Time concept in place of just using long everywhere. Minor things that didn’t really need a post of their own :)

Up Next

I’ve been having quite a debate with myself lately. There is some ugly code in here that is begging to be clean up, and since this is my hobby project, I’m free to do that. But does being a hobby project mean I can indulge myself and clean up, or does it give me the freedom to ignore warts and keep going? Probably both, which doesn’t help with forcing me in either direction :D

At the moment I’m leaning towards cleaning stuff up. So I’m going to have a poke and get a feel for how much work is actually involved, if it’s not a lot then that’s next. Otherwise, I’m probably going to implement FullScreen mode.