-
Notifications
You must be signed in to change notification settings - Fork 7
Everest Core Latency Guide
Core's switch to a custom patched version of FNA left several people with questions on the topic of latency. This page attempts to serve as a reference resource for all matters latency related, for both legacy / vanilla and Core.
Input latency refers to the amount of time it takes for a made physical input to have effects on-screen. There are various different sources of latency:
- polling latency: the time it takes until the OS / games registers an input.
- update latency: the time it takes the game to update its internal game state after it has been made aware of an input.
- render latency: the time it takes for a graphics frame to finish rendering after the game's update, including the time it takes for the frame to pass through swapchains / etc.
- compositor latency: the time it takes for the OS to present a rendered frame to the user. It consists of the amount of time the OS needs to stitch together the contents of multiple windows into a single combined image.
- scanout latency: the time it takes for the final image to be transmitted to and displayed by the monitor.
One important fact to consider is that Celeste, both vanilla and modded, is incapable of running at a higher frame rate than 60FPS! The game will never poll for inputs more frequently than this, and as such the worst-case polling latency will never be below 16ms!
Traditionally, disabling VSync has been a go-to strategy to reduce latency in all sorts of games. This usually works because of several factors:
- Disabling VSync usually uncaps the update framerate of the game from the monitor refresh rate. This causes the game to poll for inputs more often, reducing polling latency and the time it takes for an input to affect new frames. However, because of the structure of Celeste's main loop, this does not apply to Celeste!
- Disabling VSync reduces scanout latency by removing the need to wait for the previous frame before displaying a new frame. While this is still a factor for Celeste, in practice this reduction accounts for less than 10ms of latency (less for higher refresh-rate monitors). Additionally, this reduction comes at the cost of introducing screen tearing and making the total latency less stable and more susceptible to latency jitter.
However, a non-insignificant portion of players still report an apparent decrease in latency when disabling VSync. This can be explained through an XNA quirk / bug, which will be discussed later.
Vanilla / Legacy Everest offers people two choices for the backend graphics framework which should be used by the game:
-
XNA: an obsolete graphics framework from Microsoft, which uses the D3D9 graphics API to render the game. This is the default framework on Steam.
-
FNA: an open-source reimplementation of XNA, which uses either the D3D11, OpenGL or Vulkan graphics API and is a lot more stable than XNA. This is the only version present on the Epic Games Store, and is used by the
opengl
Steam beta branch.For the purposes of this analysis, only the D3D11 renderer is considered, which is also the default on Windows. While some people have reported better latency using Vulkan, the need for this has become obsolete under Core.
For legacy Everest, XNA used to provide better fullscreen input latency than FNA. This is because of multiple different reasons:
-
XNA has no / drastically reduced compositor latency compared to the version of FNA in use by legacy Everest / vanilla. This is accomplished through the usage of "exclusive fullscreen", which bypasses the compositor to render frames directly to the monitor. FNA's swapchain passes the frame through the DWM compositor even when in fullscreen, resulting in one to two frames of additional latency.
-
XNA suffers from a bug / implementation quirk which causes the game to run at 61FPS when either vsync is disabled or a monitor with a higher refresh rate than 60Hz is being used. This slight increase in the game's speed (which includes the input polling rate) can "feel" like less latency than FNA / XNA with VSync enabled.
Note that because of XNA's flawed main loop, disabling VSync also causes the Celeste process to use more CPU resources than when it is enabled. This can mislead one into thinking that the actual game is outputting more frames and as such polling for inputs more often, same as with some other games. However, this is not the case - the game still remains locked at a 60/61Hz physics and graphics frame rate! These additional resources are in practice simply wasted busy-looping without any actual benefit.
-
For keyboard players using an IME (Input Method Editor), there may be a small delay due to the way FNA handles keyboard inputs. This happens even if the IME is set to e.g. English. This can be avoided by completely disabling the IME when playing Celeste.
Core Everest drops support for the XNA framework, instead only offering a patched version of FNA. These patches remove the compositor latency mentioned above, offering the same or better input latency than XNA did for (NOTE: only the D3D11 renderer has been patched this way). These patches not only apply to fullscreen, but might in some cases also apply to windowed mode.
Note though that all Everest installations contain a small vanilla installation within them. This install is used for the "Restart into Vanilla"-feature on the title screen, in addition to powering the "Vanilla" button in Olympus. It will continue to use either XNA or FNA, depending on what type of framework your base Celeste copy used when you installed Everest.
Also important to note is that Everest applies these latency reduction patches to FNA vanilla installs as well. This means that vanilla FNA installations contained within Everest Core installations also have the same reduced latency the modded install does! As such we recommend that new users, if given the choice, use FNA for their vanilla install as well, by switching to FNA before installing Everest.
Keyboard players using an IME (Input Method Editor) should disable the IME while playing Celeste (see above).
In addition to this, Everest offers so called "Compatibility Modes" for people who want to tweak Everest's latency behavior to match what they are used to. While all compatibility modes are available irrespective of what framework is actually being used by the vanilla install, each one is only intended to work with the corresponding vanilla framework type. The following compatibility modes are available:
-
None: no compatibility settings are applied.
-
Legacy FNA: disables the latency patches in both Everest and vanilla (if applicable). This is intended for migrating FNA runners who are used to the higher latency, but is not recommended for new players.
-
Legacy XNA: forces Everest (NOT vanilla!) to run at 61FPS. This is intended for migrating XNA runners who are used to the slightly higher game speed, for new players we instead recommend the usage of FNA vanilla installations so that vanilla will remain consistent with Everest at all times.
Note that this compatibility mode is decoupled from your VSync setting / your monitor's refresh rate, which means that through this mode one can obtain almost the same feeling of latency as on XNA, without having to disable VSync.
Everest's latency patches bypass compositor latency through usage of the Direct Flip presentation model. This provides the same reduced latency as exclusive fullscreen, without all the associated graphics jank which traditionally is associated with it.
However, Direct Flip may refuse to engage for some people because of one of numerous factors (graphics drivers, tiny / invisible overlay windows, etc.). For these people, Everest also implements legacy exclusive fullscreen support for both vanilla FNA and itself, which can be enabled from the mod options menu. Note though that you should only enable this option if Direct Flip does not work for you!
Home
Contributing
FAQ
Useful Links
Your First Custom Map
Your First Texture Pack
Mod Setup
Custom Maps
Texture Packs
Uploading Mods
Generated Dialog Keys
Reference Code Mod🔗
Vanilla Audio IDs
Character Portraits
Mod Structure
Debug Mode
Command Line Arguments
Environment Variables
Install Issues
Common Crashes
Latency Guide
everest.yaml Setup
Mapping FAQ
Map Metadata
Vanilla Metadata Reference
Adding Custom Dialogue
Overworld Customisation
Entity & Trigger Documentation
Custom Entity List🔗
Camera
Ahorn Scripts
Custom Tilesets
Tileset Format Reference
Stylegrounds
Reskinning Entities
Skinmods
Decal Registry
Chapter Complete Screen
Custom Portraits
Adding Custom Audio
Advanced Custom Audio
Code Mod Setup
Making Code Mods
Mod Settings
Everest Events
Understanding Input
Logging
Cross-Mod Functionality
Recommended Practices
Core Migration Guide
Lönn Integration🔗
Custom Events
Adding Sprites
Adding Preexisting Audio