Your world, one portal away.
Aeonis connects worlds on the web, in 3D or 2D. Visitors carry one passport, so they arrive verified in your world with their name and an avatar drawn to match your world’s style. No sign-up on your side.
Free during the preview. A person reviews every world before it goes live.
- Add your world
Its https address and a name.
- Prove it’s yours
Host a tiny file at
/.well-known/aeonis.json, or add one meta tag. - Paste the snippet
A 7 KB script (compressed) with no dependencies. It verifies each visitor and draws them in your world’s style.
Once approved, your world gets a portal on the Aeonis island and a card in Aeonis Search.
- Verified visitorsEach arrival carries a signed pass made only for your site. It expires after 5 minutes.
- An avatar that fits your worldNo setup. The snippet looks at how your world is drawn and returns the visitor to match: a scaled, recoloured 3D model, a pixel sprite in your palette, or a flat 2D figure.
- Nothing to runNo server, no API keys and no account system on your side.
- Never breaks your worldIf Aeonis can’t be reached, the snippet returns a guest and your world runs as usual.
- Recognisable everywhereThe same passport always gets the same colours, shape and badge, so visitors look like themselves in every world.
- Private by designNo email ever. Visitors share a display name, colours, a stamp count and a passport code unique to your world, only after they agree.
- A way homeEach visitor gets a return link to Aeonis, where their passport is stamped.
Connect your world
Sign in with your Aeonis Passport, add your world and get your snippet.
Developer guide
Three steps. Most worlds are done in ten minutes.
1. Prove you own the site
After you add your world you get a token. Serve it at https://your-site/.well-known/aeonis.json:
{"token":"aeonis-verify-…"}Or, if you can’t serve files at the root of your domain (for example a GitHub Pages project), add this tag to your world page:
<meta name="aeonis-verification" content="aeonis-verify-…">2. Paste the snippet
This is the whole integration, and it is the same for every kind of world. No setup and no style settings: read() verifies the pass in the browser (Ed25519, checked against /.well-known/jwks.json, made for your site, not expired) and removes it from the address bar. adapt() looks at how your page draws and returns the visitor in that form.
<script type="module">
const aeonis = await import('https://search.aeonis.pro/sdk/1.1.0/aeonis-passport.js').catch(() => null);
const visitor = aeonis ? await aeonis.read() : { guest: true, name: 'Guest' };
// … start your world as usual, then:
const look = aeonis ? await aeonis.adapt(visitor) : null;
// look.kind is '3d', 'pixel', 'vector', 'dom' or 'core'
</script>Load the SDK before you create your canvas or scene, and call adapt() once your world is on screen. What it looks at:
| Your world | What it detects | What you get |
|---|---|---|
| three.js (WebGL or WebGPU) | Scene size, character height (from rigged meshes when present), material type, roughness, lights and tone mapping | '3d': the avatar file plus apply(model), which recolours it with your scene’s own material type and scales it to fit |
| 2D canvas, pixel art | Crisp scaling (image-rendering, imageSmoothingEnabled), on-screen pixel size, art-pixel size, tile size and exact palette | 'pixel': a sprite sheet sized to your tiles and coloured from your palette (4 directions × 4 walk frames) plus draw() |
| 2D canvas, smooth | Main colours (k-means) and whether the art uses a few flat inks | 'vector': an SVG figure, flat and outlined in your inks when your art is flat, plus draw() and a suggested height |
| Plain web page, no canvas | No canvas found | 'dom': an SVG figure and element(), a ready-made name tag |
| Anything else (other engines, workers, cross-origin canvases) | Whatever it can | 'core': identity, colours, a badge and the avatar file. Draw it your own way |
Every look also carries identity (name, colours, seed, stamp count), glyph (a small badge) and detected (what the SDK found). The seed comes only from the name and colours, so the same passport looks like the same person in every world.
3. Draw the visitor
three.js
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
if (look?.kind === '3d') {
const gltf = await new GLTFLoader().loadAsync(look.glb);
look.apply(gltf.scene); // your materials, your scale, feet at y = 0
scene.add(gltf.scene);
const mixer = new THREE.AnimationMixer(gltf.scene);
mixer.clipAction(gltf.animations.find(a => a.name === 'idle')).play(); // also: walk, jog, talk, sit …
}2D canvas (the same code works for pixel art and smooth art)
function drawVisitor(ctx, x, y, dir, frame) { // x, y = feet, in canvas pixels
if (look?.kind === 'pixel') look.draw(ctx, x, y, dir, frame); // dir: 'down' | 'left' | 'right' | 'up', frame: 0–3
else if (look?.kind === 'vector') look.draw(ctx, x, y, look.height, dir === 'left' ? -1 : 1);
else drawYourOwnGuest(ctx, x, y); // your world keeps working without Aeonis
}Anything else
const { name, colors, seed } = look.identity; // build the visitor from these in your own engine
badge.src = look.glyph.url; // or show their badge
document.querySelector('#home').href = visitor.returnUrl; // and always offer a way back to AeonisOptional overrides exist if you want them: adapt(visitor, { style, target, tile, scale, palette, height }). Most worlds never need them. Version 1.0.0 of the SDK keeps working unchanged.
What the pass contains
| Field | Meaning |
|---|---|
name | The visitor’s display name (up to 24 characters). |
id | A passport code made only for your site (aps_…). The same visitor gets the same code each time, and a different one on every other world. |
avatar.glb | The avatar file: glTF 2.0 humanoid, 65 bones, 9 animation loops, CC0 1.0, about 150 KB compressed. Served with open CORS. |
avatar.colors | body and trim as #rrggbb. |
stamps | How many worlds the visitor has stamped in their passport (a number only). SDK 1.1.0 and later. |
returnUrl | Where to send the visitor home. Aeonis stamps their passport on arrival. |
guest | true when there was no pass, it failed verification or Aeonis couldn’t be reached. reason says why. |
Under the hood the pass is a JWT signed with Ed25519 (alg: EdDSA), iss https://search.aeonis.pro, aud your world’s origin, valid for 5 minutes. Browsers without Ed25519 support fall back to a check at /api/passport/verify. You can also copy the SDK file into your own project.
Questions
- Does it cost anything?
- No. Connecting a world is free during the preview.
- What does my world receive?
- Only what the visitor agreed to share: display name, avatar colours, stamp count and a passport code made only for your site. Never their email.
- Do I have to pick an avatar style?
- No. The snippet looks at your world and draws the visitor to match: a 3D model in three.js worlds, a pixel sprite in pixel-art worlds, a flat figure in smooth 2D worlds. For anything else you get the visitor’s name, colours and badge to draw your own way.
- What if Aeonis is down?
- Your world keeps working. The snippet returns a guest instead of an error, so nobody is locked out.
- Which worlds can be connected?
- Any world on the web, 3D or 2D, with an https address that opens in a normal browser tab. A person reviews each world before it goes live, and worlds that stop answering are hidden until they’re back.