Syncromesh/Window
Window creation and management.
Creates and manages SDL3/Vulkan windows. Most games open a single window at bootstrap time.
A window is only a presentation target. It does not automatically display the current board. Attach a board with Syncromesh/Board.attach(boardId, windowId) or attachOffset(...) before expecting entity renderables to appear.
Import #
import * as Window from 'Syncromesh/Window';Functions #
- The returned ID is used by Helix/Event and Helix/UserInterface for window-scoped operations.
- Entity renderables are drawn from attached boards. Use
Board.attach(Board.current(), windowId)for the current board, or attach a separately created board. - Pass
postFxto configure the initial post-processing chain.
window(options: WindowOptions): Promise<number>setPostFx(windowId: number, config: PostFxConfig): Promise<boolean>- The shader receives the window camera position and frame, viewport size, renderer time, and the supplied seed through the standard push constants.
- An optional texture is bound as the shader's primary sampler and loaded once when the background is installed.
- Use this for scene backgrounds that must remain independent of board lifecycle and composition.
setSceneBackground(windowId: number, config: SceneBackgroundConfig): Promise<boolean>clearSceneBackground(windowId: number): Promise<boolean>setPostFxEnabled(windowId: number, enabled: boolean): Promise<boolean>setPostFxPassEnabled(windowId: number, passId: string, enabled: boolean): Promise<boolean>setPostFxParam(windowId: number, passId: string, paramName: string, value: PostFxParam): Promise<boolean>patchPostFxParams(windowId: number, passId: string, params: Record<string, PostFxParam>): Promise<boolean>close(): Promise<void>WindowOptions #
widthnumber — Window width in pixels.heightnumber — Window height in pixels.titlestring — Window title.statestring optional — Set to"fullscreen"for a fullscreen window. Omit for windowed mode.postFxPostFxConfig optional — Initial post-processing configuration for this window.deviceSelector(request: VulkanDeviceSelectionRequest) => string | PromiseLike<string> optional — Selects a suitable GPU for this window; the callback has a five-second deadline.
window{ runtime, title, role, logicalWidth, logicalHeight, fullscreen, transparent, display }preferredDeviceIdstring — Discrete-first native recommendation.devicesVulkanDeviceCandidate[]
id, index, name, type, vendorId, deviceIdstring | numbersuitablebooleanrejections{ code: string, message: string }[]extensions, features, limits, memory, queueFamiliesobject
enabledboolean optional — Defaults totruewhenpostFxis supplied.passesPostFxPass[] — Ordered fullscreen shader passes. The output of each pass feeds the next pass.
vertstring — SPIR-V fullscreen vertex shader path.fragstring — SPIR-V fullscreen fragment shader path.seednumber — Unsigned 32-bit seed supplied to the shader.texturestring optional — Texture bound to the shader's primary sampler.textureSemantic`'colour' | 'color' | 'data'` optional — Texture colour-space handling. Defaults tocolour; usedatafor packed linear shader data.
idstring — Stable ID used by runtime update functions.vertstring — SPIR-V fullscreen vertex shader path.fragstring — SPIR-V fullscreen fragment shader path.enabledboolean optional — Defaults totrue.uiMode`'scene_only' | 'scene_and_ui'` optional —'scene_only'applies before the UI overlay when the renderer can split scene/UI draws. Omit or use'scene_and_ui'to process the composed frame.paramsRecord<string, PostFxParam> optional — Named shader parameters packed into post-FX uniform slots.
type`'float' | 'int' | 'bool' | 'vec2' | 'vec3' | 'vec4'` — Parameter type.valuenumber | boolean | number[] — Scalar value or vector components.
Examples #
import * as Board from 'Syncromesh/Board';
import * as Camera from 'Syncromesh/Camera';
import * as Window from 'Syncromesh/Window';
const windowId = await Window.window({
width: 1280,
height: 720,
title: 'My Game',
deviceSelector: async ({ devices, preferredDeviceId }) =>
devices.find(device => device.type === 'discrete' && device.suitable)?.id ?? preferredDeviceId
});
await Board.attach(Board.current(), windowId);
await Camera.setWindow(windowId);
// Fullscreen
const fsId = await Window.window({
width: 1920,
height: 1080,
title: 'My Game',
state: 'fullscreen'
});Bloom and Tonemapping #
Post-FX render targets use an HDR float format when supported, then the final pass should tonemap back to the window output. The bundled ACES tonemap shader is postfx_tonemap_aces.frag.spv; custom tonemapping is supported by replacing that fragment shader with your own fullscreen shader.
uiMode: 'scene_only' is intended for effects such as world bloom that should not process the UI. The current renderer split requires single-sample rendering; with MSAA active, scene-only effects may include UI.
import * as Window from 'Syncromesh/Window';
const VERT = '/rom/shaders/postfx/postfx_fullscreen.vert.spv';
const windowId = await Window.window({
width: 1280,
height: 720,
title: 'Space RTS',
postFx: {
enabled: true,
passes: [
{
id: 'engine-bloom',
vert: VERT,
frag: '/rom/shaders/postfx/postfx_bloom.frag.spv',
uiMode: 'scene_only',
params: {
threshold: { type: 'float', value: 1.0 },
intensity: { type: 'float', value: 0.6 },
radius: { type: 'float', value: 4.0 }
}
},
{
id: 'tonemap',
vert: VERT,
frag: '/rom/shaders/postfx/postfx_tonemap_aces.frag.spv',
uiMode: 'scene_and_ui',
params: {
exposure: { type: 'float', value: 1.0 }
}
}
]
}
});
await Window.setPostFxParam(windowId, 'tonemap', 'exposure', { type: 'float', value: 1.15 });