Articles

  • We have been testing a new metronome calibration path built around the Serene timing work.

    The process is familiar: the game plays a steady beat, the player taps along, and OutFox measures the difference between the expected beat and the input it received. From that, it can suggest a global offset.

    The awkward part is that people do not tap with machine-like consistency.

    Even an experienced player will have some variation between taps. A few may land early, a few late, and an otherwise useful test can contain one or two poor inputs. The older calibration logic could treat that spread too harshly and reject the result outright.

    We have changed that behaviour; the tool still warns when the taps are inconsistent, but it can now allow the tester to use the median result when the underlying timing remains stable. That keeps obviously noisy data visible without throwing away an otherwise useful measurement.

    We also corrected how the suggested offset is applied.

    When a tap arrives late, the measured difference is positive. The correction has to move in the opposite direction, so the applied global offset is negative. The previous flow did not make that relationship clear enough and could make a valid result appear backwards.

    The new path now shows and applies that correction consistently, calibration also works properly with the normal save and revert controls. A tester can try the suggested value, keep it if the result improves, or leave without the engine retaining a half-applied change.

    The aim is not to pretend that every set of human taps is perfect. It is to give the tester enough information to judge the result, while making sure OutFox applies that result correctly.

    The Serene metronome now handles variable taps more sensibly, gives clearer offset results, and fits properly into the engine’s existing settings flow.

  • While testing the new audio and timing work, normal gameplay was behaving well. SereneAudio and the gameplay position remained closely aligned, with no sign of the timing drifting during a song.

    SyncMachine was less convincing.

    After restarting its test, it would show a small but repeatable offset. Because the value stayed fixed rather than growing over time, we knew this was unlikely to be the audio path wandering out of sync.

    The problem was in how timing information was being passed between systems.

    One part of the engine recorded the song position at a particular moment. Another part received that value slightly later and treated it as though it described the current moment. The delay was small, but large enough for a calibration tool to notice.

    We corrected that handoff so the timing value remains tied to the moment it was measured and is interpreted correctly when another part of the engine uses it.

    That removed the fixed offset without adding another compensation value or changing normal gameplay timing to cover the problem.

    This distinction matters because calibration tools should measure the player and the hardware, not compensate for an internal disagreement inside the engine.

    The work also confirmed that the new gameplay timing path was stable. The problem was not SereneAudio drifting or the song position gradually separating during play. It was a specific transition between two older parts of the calibration flow.

    SyncMachine now receives timing information that represents the correct point in gameplay, rather than mixing values captured at slightly different moments.

    For players, that means calibration results should be more dependable, without asking them to correct an offset created by the engine itself.

    It was a small fault, but exactly the sort of thing that needs fixing before the newer timing systems can fully replace the older paths.

  • While testing SereneAudio, we noticed a small but repeatable stutter during gameplay.

    Because the audio system had just been replaced, that was the obvious place to start looking. We checked the output paths, buffering and timing measurements, but SereneAudio was behaving normally. There were no underruns, and nothing suggested that the music or sound scheduling was causing the problem.

    The stutter was still there, though, so we kept tracing it through the engine.

    It eventually led us away from the audio system and into background video playback.

    Some hardware-decoded videos were creating brief stalls when their frames were prepared for rendering. The delay was small, but it happened at the wrong point in the frame and was enough to disturb gameplay presentation.

    This is why the problem initially looked like a timing fault. The music continued correctly, but the moving notes were not being presented as evenly as they should have been.

    StillRiver helped us separate the two, the audio path remained stable during the stutter, while the video and rendering measurements showed where the extra work was occurring. Once we knew which path was responsible, we could fix the video handling rather than trying to compensate elsewhere in the engine.

    We have now changed how those video frames are prepared before reaching the renderer, reducing the work that was interrupting active gameplay.

    There was no need to adjust song timing, increase audio buffering or add another setting for players to manage. Those would only have hidden the symptom while leaving the actual fault in place.

    This was a useful reminder of why we measure several parts of the engine together.

    Audio, video, rendering and gameplay all run alongside one another. A fault in one system can easily look like a problem in another, especially when the effect is only a brief interruption rather than a complete failure.

    In this case, SereneAudio was doing its job.

    The stutter was coming from the video path, and that is where we fixed it.

  • Audio devices do not all report playback in the same way.

    Some drivers provide useful timing information. Others report estimates, buffered positions or values affected by additional layers between the game and the speakers. That makes audio timing more complicated than simply asking the sound device where the music is.

    Older parts of the engine relied heavily on those reports. That worked well enough on many systems, but it also meant that differences between drivers could affect how the engine understood playback.

    SereneAudio handles this more carefully.

    Rather than assuming that every backend provides the same quality of information, the new system checks how audio is being submitted and played across each supported output path. This allows us to account for differences between modern callback drivers, older polling systems and compatibility backends without allowing one unreliable report to disturb the rest of the engine.

    Recent testing exposed an underrun in one of the older paths. The problem was not simply a buffer that was too small. The backend was being fed using behaviour inherited from the previous audio system, which no longer matched the way SereneAudio operates.

    We corrected the feed path rather than hiding the fault behind a larger buffer and more latency.

    StillRiver was used throughout the testing to confirm that audio remained stable, that the device was receiving data at the expected rate, and that the change had not introduced clipping or unnecessary delay.

    For players, the result should be straightforward, audio should start reliably, remain stable, and behave consistently across different devices and operating systems. Keysounds should play cleanly, and older compatibility routes should continue working without holding newer hardware back.

    SereneAudio gives us a clearer and more dependable way to handle those differences.

    The complicated details stay inside the engine, where they belong.

  • You may have noticed us using the word Silver when talking about newer parts of the engine.

    It is worth explaining what we mean by that, because Silver does not mean finished.

    When a system reaches Silver grade, it means it has moved beyond being an experiment. We have run it through real engine paths, measured how it behaves, and reached a point where we are comfortable continuing to build on it.

    That is an important checkpoint, but it is still a checkpoint.

    Recent work on OutFox has involved replacing several older foundations rather than adding another layer on top of them. SereneAudio is taking over the audio path, SereneIO is replacing older input behaviour, the renderer has moved onto programmable and portable paths, and StillRiver gives us a clearer view of what the engine is doing while we make those changes.

    Work at that level does not move neatly from “broken” to “finished”.

    A system may be working correctly on the platforms and hardware we have tested, while still needing wider coverage. It may be stable during normal play but still have unusual charts, devices or modes left to check. It may also be doing its own job properly while another older part of the engine still depends on behaviour we intend to remove.

    Silver means the foundation is working well enough that we no longer consider it temporary.

    It has been measured, it has survived meaningful testing, and the remaining work is understood well enough for us to keep moving forward without pretending there are no gaps left.

    Gold is the higher bar.

    That requires broader testing across the systems we support, more edge cases resolved, fewer remaining dependencies on the older engine paths, and enough evidence that we can treat the work as mature rather than merely promising.

    This is why you may see us describe something as Silver while continuing to discuss fixes around it.

    That is not us moving the goalposts. It is us being clear about where the work has reached.

    Rhythm games are particularly unforgiving of vague confidence. Audio, input, timing, rendering and chart behaviour all affect the player at once. A system can look correct in isolation and still produce a problem when it meets a different driver, controller, platform or game mode.

    Calling something finished too early helps nobody.

    Silver tells you that the new path is real, useful and stable enough to build upon. It also tells you that we are still testing it before calling the job complete.

    That may not be as dramatic as declaring victory every time a component compiles, but it is a much more useful way to describe engineering progress.

    Silver is not Gold, it is the point where we know the new foundation can carry the next stage of the work.