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

Issues for 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

Issues: #1162, #2284

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:

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

Issues: #2861, #3157, #3035

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

Deprecated Functions

The following functions are deprecated. The existing functions continue to behave as before.

2.9 and Earlier2.10 and LaterIssue
imageSrc1At() through imageSrc3At()imageSrc1AtFromSrc0Pos() through imageSrc3AtFromSrc0Pos()#2813
imageSrc1UnsafeAt() through imageSrc3UnsafeAt()imageSrc1UnsafeAtFromSrc0Pos() through imageSrc3UnsafeAtFromSrc0Pos()#2813

Bug Fixes

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

Issues: #2736, #2831, #3446

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

Other New Features

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 ColorModeUnknown
ColorModeLight
ColorModeDark
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.AdvanceX
text.Glyph.AdvanceY
text.Glyph.Colored
Get a glyph's horizontal and vertical advance, and whether it is a color glyph. #3449, #3496
text.LazyGlyph
text.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.Composer
textinput.SessionOptions
textinput.Composition
textinput.Commit
Manage IME sessions and receive composition and committed text through callbacks. #3446

Deprecated APIs

2.9 and Earlier2.10 and LaterIssue
(*audio.Player).Close()(*audio.Player).PauseAndStopReading()#3509, #3510
text.Advance()text.AdvanceAt()#3456
textinput.Fieldtextinput.Composer#3446

Bug Fixes

In addition to the fixes below, this release includes all bug fixes from version 2.9.

Performance Improvements