Game State Management and menu sounds

I wanted to add menu sounds to the Game State Management sample code I used in my AppWeek game, to make it play small clicks when changing the menu selection and bigger clicks when moving from one screen to another.

Menu selection sounds were easy: add SoundEffect.Play calls after the selectedEntry-- and selectedEntry++ lines in MenuScreen.HandleInput.

It wasn't so obvious how to add sounds for changing screen. I had maybe a dozen screens to deal with, but it felt like hundreds! If I tried to change each individual screen, I was worried I would miss some places and end up with bugs where one particular menu could be missing a sound if you cancelled it.

How about if I call SoundEffect.Play from the ScreenManager.AddScreen and GameScreen.ExitScreen methods? That catches everything with just two lines of code.

Trouble is, it caught a little too much:

  • I got two sounds when loading a game session, first when the LoadingScreen activated, then again when loading finished and the GameplayScreen took over
  • I got unwanted sounds when the NetworkBusyScreen went away after network operations such as joining a session
  • I got unwanted sounds when my title screen timed out and went to the main menu
  • I got unwanted sounds if network errors popped up a MessageBoxScreen

What is the underlying pattern here?

  • All these unwanted sounds occur when screens are activated or deactivated due to program controlled state changes
  • I only want sounds when screen transitions occur as a direct result of the user pressing a button


I changed the InputState helper to remember whether MenuSelect, MenuCancel, or PauseGame had been pressed within the last frame, and made ScreenManager.AddScreen and GameScreen.ExitScreen only trigger sounds if one of these inputs was detected. I can't make up my mind whether this was a valid solution or an ugly hack (perhaps a little of both?), but it was certainly a tiny amount of code to get the result I wanted!

Comments (5)

  1. nstod says:


    Would it make sense to add a couple bool properties to GameScreen called SoundOnExit and SoundOnCreation?  This could default to true, and in the LoadingScreen screen (and the others you mentioned), just set these properties to false?  Do you think that would work?

  2. ShawnHargreaves says:

    That would work for many screens, but not for things like MessageBoxScreen, which can often be brought up in response to a user button press (eg. the "are you sure you want to quit?" prompt), but also sometimes come up for other reasons (such as the "host ended the session" or "network error" messages).

  3. Ron says:


    I get an error when I try to open the Game State Management sample code.  GS 3.1 tries to automatically convert it but fails because it says it cannot be converted.  Something about permissions need to be changed on the solution file to allow modification….


  4. ShawnHargreaves says:

    Sounds like some of your files are set to read-only? You can change them to writable using Explorer.

  5. Ron says:

    Boy do I feel stupid!  As it turns out, all of the files in the archive are indeed marked as read-only.  I did not expect this, since the half dozen or so other samples I played with had worked just fine.  I apologize for such a noob error on my part.  Thanks for your time!

Skip to main content