Any site — not just this one — can embed a TCE: the only hard dependency is the embed route of the registry that hosts the package. A package must be portable to any website with no framework and no build step on the embedding side.
| Page | Route | Embedder writes JS? |
|---|---|---|
| Zero-script embed | /tce-elements/{namespace}/{name} |
No |
| Fullscreen single element | /tce/{name}, /tce-packages/{id}/view |
No (server-rendered) |
| The desktop | / (below the site header), /v3 (bare) |
No (server-rendered) |
| Installed at runtime | the desktop's package manager | No |
The baseline every package supports: one <script> tag per package on an otherwise unrelated
page, and as many element tags as wanted:
<script src="https://game-object.de/tce-elements/tobidot/tce-clock"></script>
<tce-clock></tce-clock>
The page writes no JavaScript. Tag order does not matter; custom-element upgrade is not order-dependent.
GET /tce-elements/{namespace}/{name} serves the package's IIFE build
(dist/index.global.js) as application/javascript — not an ES module, so a plain
<script src> without type="module" works. The script is the package's own entry script
(Lifecycle: Bootstrapping); on
execution it
TceRoot.package_loader()),TceRoot.bind_self), andinit(): registers its tag immediately — tags already in the DOM upgrade and render
their static shell right away — and asserts its library contracts, which may finish later.Short form: /tce-elements/{name} expands to the registry's own default namespace
(config/tce.php). Any other publisher is addressed with the two-part form.
A package's library dependencies are not auto-injected by its script. The embedder adds
them as their own <script> tags, dependencies first:
<script src="https://game-object.de/tce-elements/tobidot/dll-tce-file-system"></script>
<script src="https://game-object.de/tce-elements/tobidot/tce-notepad"></script>
This is deliberate: a page embedding several elements that share a library must load that
library once, as one instance in the page's one loader — not once per element, privately.
A package waits for its dependencies with with_binding()/has_binding() against the shared
loader, which is satisfied the moment the dependency's own script has run. If a required
dependency never binds, with_binding rejects after its bounded timeout with a message naming
the identifier and the <script> tag to add; the package reports that through TceRoot.report
and an element shows it in its own shadow DOM. "Hangs forever with no visible error" is not an
acceptable failure mode for an embedder who does not have this codebase open.
Without a version the route serves the latest upload (cached briefly). With
/tce-elements/{namespace}/{name}@{major}.{minor}.{patch} it serves exactly that version, as an
immutable, long-cached response. Anything beyond a quick demo pins a version.
A script served from /tce-elements/... cannot find its dist/ from its own URL. The route
therefore prefixes the script with one line recording the package's real content root in
window.tobidot.content_roots["namespace/name"], and resolve_asset_url uses it
(Assets & Build).
/tce/{name} (latest element version of that name in the site's default namespace) and
/tce-packages/{id}/view (one specific upload) render a bare page containing exactly the
zero-script embed: the package's declared dependency graph as <script> tags in load order
(dependencies before dependents, each once), then the package's own tag, filling the viewport.
Link externally to /tce/{name} so the link follows new versions.
The homepage is the same mechanism with tce-desktop as the embedded element: the server
renders the desktop's dependency chain (tce-icon, tce-window, tce-bootloader,
dll-tce-settings, …) plus the default applications as script tags, then
<tce-desktop data-apps="…" data-app-icons="…">. /v3 is the same page without the site
header. No bundler and no page-specific bootstrap script run on either page. While no
tce-desktop is published, the homepage is the site's regular homepage and /v3 answers 404.
Three more attributes dress the desktop, each a comma-separated list of package names:
data-window-decoration="tce-flames,tce-cat" for every window's decoration slot,
data-effects="tce-klabautermann,tce-snowfall" for the desktop's own effects slot and
data-tray="tce-clock" for its task-bar-icons slot
(Declaration: Slots as Attributes). The named packages are
ordinary packages: they need their own <script> tag on the page or to be installed through the
package manager — the desktop only names them, and a name it cannot load is a warning, never a
broken desktop. The same choices, and the attributes each composed element is created with, are
edited in the properties dialog ("Desktop Properties…" on the desktop menu; tce-inspector is a
dependency of the desktop) or in the Settings program, and are remembered across reloads.
Everything the desktop remembers — background, composition, component and icon attributes,
requested icons — is a file below /system/tce-desktop/ in dll-tce-file-system, a dependency of
the desktop. A file that cannot be read counts as missing and the page's defaults apply; storage
never breaks the desktop.
The desktop's package manager (tce-bootloader) reads the public registry
(Publishing & Discovery), lists every package,
and installs one by injecting its embed script with TceRoot.load_script('/tce-elements/{namespace}/{name}')
— dependencies first, each only if not yet bound. Installing is therefore exactly the
zero-script embed performed at runtime; there is no second loading mechanism.
The installed set is recorded in dll-tce-file-system (a dependency of the package manager) as
/system/tce-bootloader/installed.json: a JSON array of namespace/name in install order, every
dependency before the packages that need it, and only what was installed through the package
manager — never what the page itself embeds. The package manager's own boot (its init(), run
when its script loads, not when a window opens) re-installs every recorded package the same way,
in that order. A package that fails to re-install is reported and skipped; the others still
install. Activating an installed package right after a reload simply waits for its binding.
<script src> embed — this is the baseline.<script> tags, dependencies first.dll-tce-file-system, never in
localStorage.