Ebitengine 2.10 Release Notes
This document is a draft. v2.10.0 has not been released yet. The contents may change before the release.
v2.10.0
This release brings pure Go support to desktop platforms, application virtualization (VM), and shader precompilation. It also improves text rendering, IME input, and window operations.
Starting from Ebitengine 2.10, Go 1.25 or later is required.
Pure Go on Desktop Platforms
The macOS and Linux / BSD implementations no longer depend on Cgo. Ebitengine applications for desktop platforms can now be built with Go alone. A C compiler and development headers are no longer required. Cross-compiling for other operating systems is also easier. The Windows implementation already worked without Cgo.
OS APIs and shared libraries are called through PureGo. Runtime libraries are still required on platforms such as Linux. These include libraries for the window system, graphics, and audio. Builds for mobile platforms and some consoles still require Cgo.
Application Virtualization (VM)
Issue: #3438
An Ebitengine application can now run as a "guest" in a separate process. A "host" can control the guest. The host sends input to the guest and controls when the game updates and draws. The guest sends drawing commands to the host. The host executes them through its graphics backend. The host can also receive audio as a separate stream for each player.
The two main use cases are:
- Embedding another Ebitengine game. Display the guest game inside a host application, for example as a preview in a game editor.
- Automated testing from a program or an AI agent. Send input to the guest and advance the game by a specified number of ticks. Capture rendering and audio output to verify the results.
Not every Ebitengine application can run as a VM guest. The author must enable the ebitenginevmguest build tag or set ebiten.RunGameOptions.VMGuestEndpoint. This is deliberate. The VM feature makes it easy for an external program to manipulate an application. Some authors may not want to allow this, so the feature requires explicit opt-in.
The run-ebitengine-app-headless skill file is available for AI agents. With this skill, an AI agent can automatically debug your application. These tests are headless. No window appears during testing, so it does not interrupt your work. The agent can capture and inspect images of the guest's actual rendering output. It can also send input to reproduce bugs and examine audio output. After a code change, it can repeat the same operations to verify the fix.
The host uses the new experimental exp/vmhost package. Build the guest with the ebitenginevmguest build tag. At runtime, specify the host endpoint with the EBITENGINE_VM_ENDPOINT environment variable. This approach requires no source changes, but the application must be rebuilt. Alternatively, set ebiten.RunGameOptions.VMGuestEndpoint in your program without using the build tag.
Running as a guest is supported on desktop platforms. The guest does not use its own window or GPU. The host still needs a graphics environment to render. This VM feature does not include a software renderer for CI environments without a GPU. Use the same Ebitengine version for the host and guest. exp/vmhost is experimental, and its API may change in the future.
Shader Precompilation
The new experimental exp/shaderprecomp package allows applications to use precompiled shaders. This reduces runtime shader compilation work and can shorten loading times.
The shadercollector tool collects Kage sources from the specified packages. Dependencies are included as well. Mark the shaders to collect with dedicated directives or a manifest. The tool outputs sources for each graphics backend.
For DirectX and Metal, you must compile the output sources separately. Use the compiler for each platform to generate binaries. Register these binaries during application initialization. Existing ebiten.NewShader calls and drawing code can remain unchanged. See the shaderprecomp example for the steps.
Precompilation does not eliminate all runtime compilation. Kage sources are still converted to an intermediate representation. For OpenGL, conversion to GLSL can be done in advance. However, the GPU driver still compiles and links GLSL at runtime.
shadercollector also outputs an ID (SourceID) that identifies each shader source. This ID associates the original Kage source with its precompiled data. Even for the same Kage source, the ID may change between Ebitengine versions. Collect and precompile the shaders again when updating Ebitengine. exp/shaderprecomp is experimental, and its API may change in the future.
Kage Changes
New Features
- Added
for rangesupport for integers and fixed-size arrays (#2905, #1897). - Added support for the bitwise
&^and unary^operators (#2753). - Added functions such as
imageSrc1AtFromSrc0Pos. Their names explicitly indicate that they take coordinates of the 0th source image. Existing functions such asimageSrc1Atcontinue to behave as before (#2813). - Added
imageDstTextureSizeandimageSrc0TextureSizethroughimageSrc3TextureSize. These return the size of the texture containing the image (#3476).
Deprecated Functions
The following functions are deprecated. The existing functions continue to behave as before.
| 2.9 and Earlier | 2.10 and Later | Issue |
|---|---|---|
imageSrc1At() through imageSrc3At() | imageSrc1AtFromSrc0Pos() through imageSrc3AtFromSrc0Pos() | #2813 |
imageSrc1UnsafeAt() through imageSrc3UnsafeAt() | imageSrc1UnsafeAtFromSrc0Pos() through imageSrc3UnsafeAtFromSrc0Pos() | #2813 |
Bug Fixes
- Fixed compiler panics caused by division by zero in constant expressions. These now produce compilation errors (#3533).
- Comparing arrays with
==or!=now produces a compilation error. These comparisons were previously accepted, but shader compilation failed on some graphics backends (#3535).
Color Emoji and Text Rendering Improvements
Issues: #2649, #2956, #3456, #3457
The text/v2 package now renders color emoji. It uses bitmaps and color glyphs embedded in fonts. Your application must supply a font containing color glyphs.
Bidirectional text was already supported. This release fixes the visual order of mixed left-to-right and right-to-left text. The new text.AdvanceAt function returns the caret position for a specified position in the text. It also accounts for bidirectional text.
IME Input on More Platforms
The exp/textinput package now supports Linux / UNIX and Android / iOS. The new textinput.Composer delivers composition and committed text through callbacks. It can be used to integrate IME input into custom text editors and input fields.
The existing textinput.Field is deprecated. Use textinput.Composer for new input fields. exp/textinput remains experimental.
Window and Desktop Improvements
- Improved rendering during window resizing. Fixed distorted output and temporary black regions (#2615, #3477, #3478).
- Added support for querying the system's light or dark mode. Applications can also specify their preferred color mode. On desktops, this affects the window title bar's appearance (#3386, #3387, #3480).
- Applications can now run without showing a window. Window visibility can also be changed while the application is running (#3470).
- On Windows, icons embedded in the executable are now used automatically as window icons (#3459).
- On desktops, the
ebiten.AbsPatherinterface provides absolute paths for dropped files and directories (#3252).
Other New Features
- Linux can now render using a framebuffer device (fbdev) and EGL without X11 or Wayland. A compatible device and EGL driver are required. This can be used on handheld consoles and other devices without a window system (#3491).
- Added gamepad vibration support on Windows, macOS, and Linux. Windows supports XInput gamepads. macOS supports gamepads compatible with the GameController framework. Linux supports gamepads with rumble support (#2014).
(*audio.Player).SetVolumenow accepts values greater than 1 (#3359).- Added skill files for AI agents. They help with automated debugging through headless execution and with writing Kage shaders. Have your agent read the appropriate
SKILL.mdto use them.
New APIs
In addition to the new experimental packages exp/vmhost and exp/shaderprecomp, the main API additions are listed below.
| API | Description | Issue |
|---|---|---|
ebiten.AbsPather |
An interface for retrieving the absolute paths of dropped files and directories. | #3252 |
ebiten.ColorMode and ColorModeUnknownColorModeLightColorModeDark |
A type and constants representing color modes such as light and dark. | #3386 |
ebiten.SystemColorMode()ebiten.PreferredColorMode()ebiten.SetPreferredColorMode() |
Query the system color mode, and get or set the application's preferred color mode. | #3386, #3387, #3480 |
(*ebiten.ColorScale).Set()(*ebiten.ColorScale).SetWithColor() |
Set color scale factors from RGBA values or a color.Color. |
#3370 |
ebiten.CursorPositionF() |
Get mouse cursor coordinates as floating-point numbers. | #3394 |
ebiten.TouchPositionF()inpututil.TouchPositionFInPreviousTick() |
Get touch coordinates for the current or previous tick as floating-point numbers. | #3504 |
ebiten.IsCapsLockOn()ebiten.IsNumLockOn() |
Query whether Caps Lock and Num Lock are on. | #3506 |
ebiten.MaxImageSize() |
Get the device-dependent maximum image width and height in pixels. | #1734 |
ebiten.ScreenSize() |
Get the size in pixels of the screen image passed to Game.Draw. |
#2986 |
ebiten.RunOnMainThread() |
Run a function synchronously on the main thread. | #3385 |
ebiten.IsWindowVisible()ebiten.SetWindowVisible() |
Query window visibility and show or hide the window. | #3470 |
(*ebiten.Image).RecyclableSubImage()(*ebiten.Image).Recycle() |
Create reusable sub-images and return them after use to reduce allocations. | #3418, #3423 |
ebiten.RunGameOptions.VMGuestEndpoint |
Specify the host endpoint when running as a VM guest. | #3438 |
(*audio.Player).PauseAndStopReading() |
Pause audio playback and stop reading from the source. Wait for any ongoing read to finish. | #3510 |
text.AdvanceAt() |
Get the distance from the line origin to the caret at a byte position in the text. | #3456 |
text.Glyph.AdvanceXtext.Glyph.AdvanceYtext.Glyph.Colored |
Get a glyph's horizontal and vertical advance, and whether it is a color glyph. | #3449, #3496 |
text.LazyGlyphtext.AppendLazyGlyphs() |
Get glyph layout information while deferring image creation until needed. | #3450 |
text.VariationAxis(*text.GoTextFaceSource).AppendVariationAxes() |
Get a variable font's axes, including their minimum, default, and maximum values. | #3486 |
textinput.Composertextinput.SessionOptionstextinput.Compositiontextinput.Commit |
Manage IME sessions and receive composition and committed text through callbacks. | #3446 |
Deprecated APIs
| 2.9 and Earlier | 2.10 and Later | Issue |
|---|---|---|
(*audio.Player).Close() | (*audio.Player).PauseAndStopReading() | #3509, #3510 |
text.Advance() | text.AdvanceAt() | #3456 |
textinput.Field | textinput.Composer | #3446 |
Bug Fixes
In addition to the fixes below, this release includes all bug fixes from version 2.9.
- Fixed incorrect window sizes and fullscreen resolutions at fractional display scales. Also fixed blurry rendering in browsers (#2978, #2225, #2958).
- Fixed a black screen when fullscreen mode was set before startup on macOS. Also fixed disabling Vsync not working (#3508, #3392).
- Fixed button input not being recognized on some gamepads on macOS (#3471).
- Fixed modifier key states not being updated correctly. Also fixed wheel input not being smooth in browsers (#3422, #3453, #3460, #3467, #3390).
- Fixed lost IME input and issues when switching focus during composition (#3382, #3463, #3623).
- Fixed rendering restoration after OpenGL context loss on Android. Also fixed hangs when suspending an application (#3215, #3327, #3334).
- Fixed crashes during DirectX initialization under Proton / DXVK (#3489).
- Fixed scaled text being clipped at the destination edges. Also fixed data races when using the same font source concurrently (#3529, #3605).
- Fixed incorrect lengths and playback positions during audio resampling and seeking. Also fixed stream corruption (#3352, #3545, #3583, #3584, #3587, #3589, #3643).
- Other minor bug fixes.
Performance Improvements
- Changed GPU resource restoration to reduce the work needed to retain drawing history (#3090, #3215).
- Reduced texture atlas usage for vector graphics (#3358).
- Deferred glyph image creation in
text/v2to reduce unnecessary image creation and draw calls (#3450, #3455). (*ebiten.Image).RecyclableSubImageandRecycleallow sub-image objects to be reused. This reduces memory allocations.Recyclecan only be used on images created byRecyclableSubImage(#3418, #3423).- Reduced lock usage in window operations (#3403).
- Other minor performance improvements.