A menu implemented with the new widget system. At this point, some options are functional, but the majority still need to be connected to engine variables.
Work Since Last Devlog
The new widget system is in, and I’ve fully removed the old widget code. Menus now operate independently of the game logic ticks, so changing the time scale doesn’t impact menu responsiveness.
I ported over the vertical menu widget, and made a ‘director’ widget which owns various config menus and handles top-level state changes:
- Being on the title screen in attract mode and displaying / fading out the game’s title art / logo
- Title screen menu
- Starting a new game session
- Quitting the game
- Accessing the pause menu
- Accessing the options menu, and sub-menus therein
- Asking the user for confirmation on guarded selections (“Are you sure?” prompts)
Previous states can be preserved by pushing a new state onto a stack table in the director widget, then popping it off when the user exits the menu. Doing this allows exiting one menu to return to the previous menu, so that for example the options panel can be accessed from both the title screen menu and the pause menu, and the confirmation box can be backed out of by choosing cancel.
I ported over the old system’s control entities, and made some new ones:
- Boolean checkboxes
- Sliders, presented as either just a number, or a slider-bar with a percentage value
- Radio buttons
I don’t have a solution for large list selections, other than to invoke another menu or send the user to a custom scene. The menus also do not scroll when there are more options than there is space to show them. It has just enough functionality to support a straightforward action game.
Each menu item that represents a configurable setting has an associated pair of get() / set() functions assigned at instantiation, which I’m dumping into a separate settings file. Most of these functions do a simple value return or an assignment to an engine variable, but some require additional steps to convert the data to the right format between the engine and the widget component. For example, there are two kinds of fullscreen mode (‘exclusive’ and ‘borderless’, besides running in a window) and two kinds of VSync (‘on’ and ‘adaptive’, besides being disabled.) Another aspect that needs conversion: internal ranges tend to be 0.0 – 1.0, whereas the widget slider values are integers by design.
I’ve decided not to expose the majority of engine config settings in the in-game menu system as it’s just way too much to deal with right now. I do have a button that opens the application save directory, and curious users can take a look at the config file which gets saved there.
What else did I do… I added an info field for menu items, to provide some additional explanation when you highlight them. I threw together some bleepy menu sound effects in MilkyTracker and Audacity, and applied the flanger DSP effect to them in LÖVE. I thought some more about how to do difficulty settings as well, though I’ve got nothing implemented on that front yet.
So this Director widget is not ideal in terms of implementation, but it’s a good step forward for getting a game out. The menus look, feel and sound more professional than what I threw together in Hibernator, and I have a way of making new menus, and making those menu options do things, that isn’t an enormous pain.
I’m posting this earlier than usual because I’m going to be out of town over the weekend, and won’t be touching this until I return. A break would probably be good at this point. In any case, I’m definitely feeling more confident now that there’s a stand-in title screen, options menu with submenus, and a spiffy tweened cursor sprite and synthesized menu sounds.
Plans For Next Post
- Same as last week, get all of the menus functional. Keyboard/Gamepad keybinding and video mode settings will probably have to be their own scenes with custom widgets.