The new in-game overlay / console activated by the backtick key (`).
Work Since Last Devlog
- Integrated those things I wrote in a test environment into the main codebase:
- Shut off writing logs to disk if over X bytes emitted in a certain timeframe
- Back up config before writing new file
- (What was finished of the) sound channel system
Config / Logging / Debug
- Plugged the config system into several engine modules. It’s been a slow, tedious process, and I’m going to have to double-check every single setting at some point, but it’s a necessary change for advancing the project.
- Extended the config file format to support multiple values per key, separated by whitespace. This is needed to specify multiple input keys / gamepad buttons per action.
- Started work on a command line argument parser. I have about a dozen switches plugged in. Most don’t do anything yet, but it’s nice to disable vsync and window borders without digging through the ever-changing config file.
- Started work on a simple built-in backtick debug console. This should help with development and troubleshooting: since the resolution increase, I can no longer view the game plus a terminal window at the same time. I have the following more or less done:
- Display recent log messages with scrollback and line coloring, with an option to feed console messages back to the logger.
- Input prompt for typing debug commands (only a few simple one-word commands implemented so far, though — but it’s enough to start getting rid of undocumented debug keys and debug options in the pause menu.)
- Command history
- Marquee display at the top of the screen, to alert the user of new messages when the full console isn’t open. Lines fade out after a few seconds.
- Tore out the old music and sound source files. The new audio module can play static sounds, but as a whole it isn’t quite ready yet. I need to think about how music and ambient sounds should be implemented.
- For channels, began work on supporting changes per-frame, which includes ADSR volume envelopes, pitch / pan slides, and a rudimentary volume attenuation when a sample loops. The granularity is not the best — you wouldn’t want to use this for sequencing music, or building any kind of chain of sounds that absolutely must be synced — but it might help squeeze some extra life out of some samples. I also began adding LÖVE low / high / band pass filters, and some support for OpenAL effects, but this was more than I could chew for one night. (But wow, those effects sound really neat.) I spent a good chunk of time hunting down the descriptions for the effects in the OpenAL Effects Extension Guide, which includes important info on the types, ranges and default params. (e: 6/Sept/2019: looks like the defaults will be applied as long as you specify at least the type and volume of the effect, so you don’t need to go digging through the guide for all of the parameters just to test the effects out.)
- Added some basic doubled sound prevention. I’ll need to do more adjustments when I have more of a game to use as a basis for testing. For now, if a sound is triggered, and the following conditions are met, an existing, similar sound is overwritten:
- Sound is already playing on a channel
- Channel has been playing for less than a certain amount of time, like 0.15 seconds
- Has a pitch within -1/+1 semitones of the new sound’s starting pitch
- Has a panning position within ~50% the range of the new sound’s panning
- The sound on the existing channel is of equal or lower priority than the new sound
- Added an engine flag to force exactly one logic tick per frame, so that an engine user who wants to make a variable-timestep game can disable the fixed timestep scheme without rewriting the main loop. This is just a hack but may be useful in some circumstances.
- Added a secondary timescale variable to the main loop, so that the game developer can implement variable time-stretching effects without messing with the user-facing Time Scale setting.
- Fixed an oversight with time scaling where the scaled delta time was being passed to things which should have been getting the real delta time. DT entities now respond to keyboard input correctly, regardless of how fast or slowly interior logic ticks are being processed.
The codebase feels a little less familiar to me now, what with several new module additions and an overall reorganization this month. I should review where I’m at this upcoming week and figure out next steps.
I learned about how Lua’s debug.debug() console can be called easily from within LÖVE, as long as a terminal is attached to the process. The main thread halts, and you can type Lua commands directly, and then exit by typing cont. Might be useful for debugging, though it’s not a full shell with command history and stuff. I don’t plan on including this in non-development releases (though it’d be trivial for someone to add the call back in.)
I overlooked an important caveat with the Lua string library: it basically handles strings on a per-byte basis with no regard to encoding. This works OK if you are only using the ASCII portion of UTF-8, but if you call string.sub() on a string with multi-byte UTF-8 characters, you can corrupt the string and cause an error*. LÖVE includes the Lua 5.3 utf8 library to help get the correct offsets. So I’ll have to review all string library calls at some point and make sure they’re OK.
* “UTF-8 decoding error: Not enough space”
Plans For Next Post
I’ll try to be ambitious this upcoming week:
- Finish up the new audio module and get music + ambient sounds working
- Proper gamepad support
- Roadmap figured out, for real, next Sunday
(e 6/Sept/2019: Notes on using default parameters for effects)