the CSS background color of the parent element that holds the canvas.
Applied during initialization to prevent a white flash before the first render.
Set to "transparent" to disable, or any valid CSS color value.
Optionalbatcher?: new (renderer: any) => WebGLBatchera custom batcher class, riding the quad/primitive slots on either
GPU backend — extend WebGLBatcher under WebGL, WebGPUBatcher
under WebGPU (addBatcher rejects a wrong-backend class loudly)
the default blend mode to use ("normal", "multiply", "lighter", "additive", "screen")
OptionalcameraClass?: new (minX: number, minY: number, maxX: number, maxY: number) => Camera2dDefault camera class instantiated for any Stage that does not
explicitly provide its own cameras. Set to Camera3d to opt
every stage in the app into perspective rendering by default. Stages
can still override per-instance via super({ cameras: [...] }) or
per-class via super({ cameraClass: Camera2d }). Built-in stages
(e.g. the loader screen) explicitly use Camera2d regardless
of this setting.
GPU-backend requirement. Camera classes whose
static defaultSortOn === "depth" (Camera3d and any subclass) need
a renderer with a depth buffer (renderer.supportsDepthBuffer —
WebGL 2 or WebGPU). Pairing such a cameraClass with
renderer: video.AUTO on a system where AUTO falls back to Canvas
emits a console.warn and produces a non-functional render. Pin
renderer: video.WEBGL (or WEBGPU) to make app.init() reject
instead.
whether 3D objects cast a soft "blob" shadow on the ground by default (#1515).
A ground shadow is what stops a character or prop reading as floating in a 2.5D scene — it answers "where is this standing", not "where is the light". It is deliberately not a simulated shadow; see Mesh#castGroundShadow.
This is the default for every Mesh, Sprite3d and
InstancedMesh; each can override it with its own
castGroundShadow (which wins), and level.load takes the same
option for one glTF scene (which wins over this).
Because it is a blanket opt-in, it skips meshes with no vertical
extent — a flat plane lying on the floor is the floor, and shadowing
it with itself would smear a blob across the whole ground. A per-object
castGroundShadow: true bypasses that safeguard, being an explicit
instruction.
On by default. Requires a GPU backend and a Camera3d, so a
2D game is untouched whatever this says — the Canvas renderer has no
depth buffer and the 2D-camera path draws none. Set it false to opt a
3D game out wholesale (a scene with baked lighting, or one bringing its
own shadows, would otherwise get two).
Optionalcompositor?: new (renderer: any) => WebGLBatchera custom batcher class (extend the active backend's base:
WebGLBatcher / WebGPUBatcher)
whether to display melonJS version and basic device information in the console
If true, treat WebGL as unavailable when the browser warns that a
context would perform dramatically worse than a native application
(a software rasterizer, a blocklisted driver). Note this is stricter
than the WebGL default, which is false.
The WebGPU backend honors it too, by rejecting a fallback
(software) adapter. The effect: under AUTO such a machine
gets the Canvas renderer, and under WEBGL / WEBGPU
app.init() rejects. Set to false to accept a software or
blocklisted context instead.
Enable the GPU procedural shader path for orthogonal tile layers
(backends advertising renderer.supportsShaderTileLayers — WebGL 2
and WebGPU). When true (default), eligible layers render via a
single quad per tileset + a fragment shader doing per-fragment GID
lookup, bypassing the per-tile draw loop entirely. Layers that
don't qualify (Canvas renderer, non-orthogonal,
collection-of-image tilesets, tilerendersize "grid", non-zero
tileoffset, oversampled beyond the shader's overflow window) fall
back to the legacy path automatically.
Set to false to disable globally.
enable high precision shaders (WebGL only). When false, shaders prefer "mediump" precision for better performance on some mobile GPUs, falling back to "lowp" if "mediump" is not supported. When true (default), the highest precision supported by the device is used. This setting is ignored by the Canvas renderer.
How many texture units the WebGL multi-texture batchers may use (#1585).
A batch can draw sprites from this many distinct textures before it has
to flush and start over, so a scene with more textures in flight than
this loses batching sharply. The pool used to be hardcoded to 16 — the
WebGL 2 spec floor for MAX_TEXTURE_IMAGE_UNITS, and roughly half
what current desktop and mobile hardware reports.
"auto" (default) — the device's reported limit, capped at 32.Raising it costs fragment-shader compile time and register pressure, because the batcher's shader unrolls one sampler and one branch per unit. Lowering it is the escape hatch if a driver misbehaves on wide sampler ladders.
Read at initialization only — the batchers compile their shaders
against this value, so unlike textureFilter there is no runtime setter.
WebGL only; the WebGPU backend sizes its own slot budget from its
per-stage binding limits, and the Canvas renderer has no batching.
The physics system to use. Accepts:
"builtin" (default) — the built-in SAT physics adapter"none" — disables physics; World.step skips the simulation,
the world container behaves like a pure scene graphPhysicsAdapter instance — e.g. new MatterAdapter() from
@melonjs/matter-adapter, or any third-party adapter{ adapter: PhysicsAdapter } — explicit form, reserved for
future per-app physics optionsThe adapter's physicLabel becomes world.physic so user code
can branch on the active engine without importing the concrete
adapter class (app.world.physic === "matter", etc.).
A hint to the user agent about which GPU to use on multi-GPU systems (discrete vs integrated). Browsers generally favour the low-power GPU unless asked otherwise, to preserve battery life.
"default" — no hint; let the user agent decide."low-power" — prefer the integrated GPU."high-performance" — prefer the discrete GPU. Note that browsers
only honour this for pages that handle context loss, since switching
GPU can drop the context; melonJS registers those handlers itself,
so the request is respected.The same hint (and the same values, minus "default") is used by
WebGPU's adapter request, so this setting is backend-neutral.
Renderer to use. Four built-in modes (constants from me.video):
await app.init() always
resolves under AUTO; the WebGPU attempt is a full adapter/device
negotiation awaited inside init(), falling through to the
synchronous candidates when it rejects. Under the Canvas tail the
GPU-only subsystems (Camera3d, retained meshes, ShaderEffect,
Light2d/Light3d shading, GPU tilemap) degrade or disable — gate on
the renderer capability flags (supportsDepthBuffer,
shaderLanguage, …) if your scene depends on them.app.init()
rejects when no adapter/device can be acquired — it never
substitutes another backend.app.init() rejects if a WebGL 2
context is unavailable (WebGL-1-only device, driver-blocklisted
GPU, perf-caveat failure, etc.) — fail fast rather than render a
stuck blank canvas.Or pass a custom Renderer subclass instance for full control.
enable scaling of the canvas ('auto' for automatic scaling)
screen scaling modes
the HTML Element to be used as the reference target when using automatic scaling (by default melonJS will use the parent container of the div element containing the canvas)
whether to enable sub-pixel rendering (avoid sprite flickering when using transforms)
Default texture magnification/minification filter, decoupled from
antiAlias (GPU backends — WebGL and WebGPU; the 2D Canvas
renderer has no per-texture filtering and ignores this).
antiAlias conflates two separate concerns: polygon-edge antialiasing
(MSAA) and texture sampling smoothness. This setting separates the
texture half out, so you can choose them independently — e.g. smooth
textures with no MSAA, or crisp pixel-art textures with MSAA edges.
"auto" (default) — follow antiAlias (linear when true, nearest
when false): unchanged behavior."nearest" — crisp/pixelated upscaling, regardless of antiAlias."linear" — smooth, regardless of antiAlias.This is the default for every texture; a Mesh can still override
it per-mesh via its own textureFilter setting (which wins).
// smooth textures but NO polygon-edge MSAA
const app = new Application(1024, 768, {
renderer: video.WEBGL,
antiAlias: false, // MSAA off
textureFilter: "linear", // textures still filtered smooth
});
// crisp pixel-art textures WITH MSAA-smoothed edges
new Application(1024, 768, {
renderer: video.WEBGL,
antiAlias: true, // MSAA on
textureFilter: "nearest", // textures stay crisp
});
whether to allow transparent pixels in the front buffer (screen).
whether to enable verbose mode (additional console output for debugging)
Optionalcanvas?: neverthe DOM parent element (or its string ID) to hold the canvas in the HTML file
an existing canvas element to use as the renderer target (by default melonJS will create its own canvas based on given parameters)
Optionalparent?: never
whether to enable or not video scaling interpolation. On the GPU backends this drives polygon-edge antialiasing (up to 4× MSAA) — on the canvas itself, and equally through post-effect chains, whose scene capture targets are multisampled to match, so adding a camera effect never switches edge smoothing off. Texture sampling smoothness is controlled separately by
textureFilter. Multisampled capture targets cost GPU memory (roughly 30 bytes per pixel at 4×, ~55 MB at 1080p on WebGL) — withantiAlias: falseno multisampled storage is ever allocated.