Asset for Unity

HTML and CSS for Unity. C# instead of JavaScript.

DevCore UI Engine draws your game's interface from the languages the web already taught everyone. Components are compiled ahead of time, Svelte-style: no virtual DOM, no diffing, and no garbage-collector work per frame.

Hud.dcue
<script lang="cs">
    using MyGame;

    [Tick] float health => Hero.Health;
    [Tick] int gold => Hero.Gold;
</script>

<div class="bar" class:low={health < 25}>
    <div class="fill" style:width="{health}%"></div>
</div>
<span class="gold">{gold:N0}</span>

<style>
    .fill { background: #3ddc97; transition: width 0.2s }
    .low .fill { background: #ff5c5c }
</style>

Illustration: a component and the kind of HUD it draws.

1draw call for a whole page, whatever is on it
0 Ballocated per frame in steady state, enforced by tests
1/64 pxis how closely layout is compared with Chromium
38scripts shaped exactly like HarfBuzz, on Unicode 17 data

How it works

A component is one file. Saving it compiles it.

A .dcue file holds a C# script, markup and a scoped style. When you save, the editor compiles it into a C# class beside it. Nothing is parsed at runtime: a build ships no markup, no style sheets and no locale files.

  • [State] fields are reactive. Changing one updates exactly the text, attribute or style that reads it.
  • Styles are scoped. A component's <style> reaches only its own elements.
  • Game code reaches the UI by name. Q<T>() finds an element or a component, without allocating.
Counter.dcue
<script lang="cs">
    [State] int count;
    [Derived] string label => count + " clicks";
</script>

<button query:api="counter" onclick={() => count++}>
    {label}
</button>

<style>
    button { padding: 8px 16px; background: #2d6cdf }
    button:hover { background: #3b7bef }
</style>
Game code
var app = DevCoreApp.Current;

var shop = app.Q<Shop>("shop");     // a component
shop.gold += 100;                   // updates this frame

var label = app.Q("gold-label");    // an element
label.ClassList.Add("flash");

What is inside

A browser-grade UI stack, built for a frame budget

Everything below is part of the engine: its own layout, its own text stack, its own renderer. No web view, no native plugin.

Measured

Side by side with UI Toolkit

Milliseconds of UI time per frame, both showing the same content in a Windows player (Mono). Lower is better. Zero bytes are allocated per frame in every DevCore scenario.

ScenarioDevCore UI EngineUI Toolkit
Empty page0.19 ms0.19 ms
Idle shop page, 400 cards0.21 ms0.40 ms
Minimap: 1,000 markers moved1.92 ms2.65 ms
Timers: 200 texts changing5.35 ms8.27 ms
Health bars: 300 widths (layout)3.66 ms5.65 ms
Theme switch, 1,600 elements4.45 ms50.78 ms
Long list, 10,000 virtual rows0.55 ms0.78 ms
Transitions: 200 tiles, color and scale0.52 ms1.58 ms
Building a page (warm)62 ms75 ms
Managed memory kept7.2 to 9.8 MB0.6 to 3.5 MB

UI Toolkit keeps less memory, and an empty page costs the same in both. Numbers move with hardware and content; the performance guide says how to measure your own.

Verified

Compared with the browser, not judged by eye

The engine follows the specifications the way Chromium implements them. Its test suite compares it with Microsoft Edge and with HarfBuzz, and treats any difference as a bug.

3,000+laid-out elements match the browser's boxes exactly
9,000+computed style values match the browser's
20,000texts in 38 scripts shaped identically to HarfBuzz
503text-editing steps replayed against the browser

Tooling

See the change before Unity recompiles

Live Preview

A window that shows a page or a component outside Play mode, with device presets, dark mode, touch, language and direction switches.

Hot reload that keeps state

Styles are swapped in place, pages rebuilt, components recompiled in memory and replaced while their [State] stays.

Inspector

The element tree with matching rules, computed values, the box model, live-editable component state, listeners, layers and frame timings.

VS Code extension

Completion, hover documentation, go to definition and errors while typing, for the C# in the script and in the template. Imports and usings are written for you.

Locale editor

Every key against every language in one table: search, find missing or unused texts, edit and see it in the preview at once.

One menu

Every editor command of the engine lives under Tools → DevCore. Creating things is also in the usual right-click menus.

Before you choose

What it does not do

Better to read this here than to find it in the middle of a project. The full list, with the platforms that were verified, is in the guide.

  • No JavaScript. Logic is C#; pages are not web pages and existing web apps do not run.
  • Built-in Render Pipeline. URP and HDRP are not supported yet.
  • Windows and WebGL are verified. Android builds but has not been run on a device; macOS, Linux, iOS and consoles have not been built.
  • Some CSS is missing. Multi-column, vertical writing, @container, @layer, color-mix(), subgrid and scroll snapping.
  • Font formats. TTF, OTF and TTC are read; WOFF, WOFF2 and variable fonts are not.

From import to a first screen

The guide starts with the demo scene and a first component, and takes you through apps, styles, input and locales.