Skip to content

Layers ​

A layer is a named <div> container managed by LayerManager. One renderer instance can declare as many layers as needed.

Configuration ​

ts
['@gwenjs/renderer-html', {
  layers: {
    background: { order: 0   },          // sky, parallax CSS animations
    bubbles:    { order: 20, coordinate: 'world' }, // world-space speech bubbles
    hud:        { order: 100 },          // health bar, score, minimap
  },
}]
FieldTypeDefaultDescription
ordernumberrequiredz-index. Must be unique across all renderers.
coordinate'screen' | 'world''screen''world' applies a camera transform to the layer each frame and enables syncWorldPosition() on handles.

How layers are mounted ​

LayerManager sorts all layers from all renderer plugins by order, then inserts them as children of the root container. Each <div> gets:

html
<div
  data-gwen-layer="renderer:html:hud"
  style="position:absolute; inset:0; z-index:100; pointer-events:none"
></div>

pointer-events: none is applied automatically on screen-coordinate layers so the DOM overlay does not block game input. Remove it on specific child elements when interactive UI is needed.

Per-entity slots ​

Inside each layer, every entity that calls useHTML(layerName) gets its own child <div>.

Screen layer — single div, slots are direct children:

html
<div data-gwen-layer="renderer:html:hud">
  <div data-gwen-slot="42" style="position:absolute"><!-- entity 42 content --></div>
  <div data-gwen-slot="43" style="position:absolute"><!-- entity 43 content --></div>
</div>

World layer — two-div structure: an outer clip div and an inner camera-transform div. Slots live inside the inner div so the camera transform is applied automatically:

html
<div data-gwen-layer="renderer:html:bubbles"
     style="position:absolute; overflow:hidden; /* viewport region */">
  <div style="position:absolute; transform-origin:0 0;
              transform:translate(vpW/2 - camX/zoom, vpH/2 - camY/zoom) scale(1/zoom)">
    <div data-gwen-slot="42" style="position:absolute"><!-- entity 42 content --></div>
    <div data-gwen-slot="43" style="position:absolute"><!-- entity 43 content --></div>
  </div>
</div>

Slots are allocated on first useHTML() call and released automatically on actor destroy.

See Camera Integration for how the inner transform is computed.