Build interactive e-learning. Publish to every format an LMS accepts.
Amarna Studio is an authoring tool for interactive e-learning. Describe the course and get a validated draft back, lay it out on a responsive canvas, branch it into scenarios, stage it as animated scenes, score its interactions, check it against WCAG — then publish a self-contained package that runs in any LMS.
Runs in the browser or as a desktop app. The AI layer works with no API key at all — and with your own key on any of eight providers if you have one.
Why it exists
Immersive training is stuck between slideware and custom builds.
Slide-based tools are fast and cheap and produce click-next courses that don't change behavior. Bespoke simulations change behavior and cost a project plan and a development team. Generic AI content tools are fast and shallow — video and prose, not interactivity, and no assessment worth the name.
Amarna Studio is built for the people who outgrew the first option and can't justify the second: instructional designers who need branching, variables and scored interactions, and the engineers who have to make the output actually pass an LMS conformance check.
What it does
Seven things, and the seams between them are the product.
Describe it, get a validated draft
Compose writes a Course Spec — objectives, screens, decisions and assessments — runs it through nine gates, repairs what fails, and only then compiles a real project. One run is one undoable change.
Canvas, layers, timeline
Pages → sections → layout containers, with 13 element types, rich text, per-breakpoint responsive overrides and a keyframe timeline. Undo and redo are backed by document patches, not screenshots of state.
A scenario graph, not a slide order
A node-graph editor with 9 node types: choice points, dialogue, condition gates, variable setters, random gates, merges and endings. Variables drive the path; characters and dialogue drive the story.
17 interaction types out of the box
Multiple choice through drag-and-drop, hotspot, matching, ordering, sorting and media annotation — plus a custom escape hatch. Each is independently scorable and weighted, and each reports to the LMS as a real interaction.
A screen, or a scene that plays
Any node can render as a real-time animated scene on a GPU canvas instead of text on a page — cast members with bodies that move, a procedural backdrop, a camera that frames the beat, lip sync. Same document, same assessment graph, same LMS tracking.
Accessibility while you author
A built-in WCAG validator, contrast checker, tab-order manager and caption editor, so problems surface before review rather than after. A rule-driven Learning Design Score grades the project across eight instructional-design categories.
One project, eleven targets
HTML5, SCORM 1.2, SCORM 2004 (3rd and 4th Edition), xAPI, cmi5, AICC, MP4/WebM/MOV renders, and a hosted review build. Every format's runtime exposes the same four tracking calls, so the course never branches on where it landed.
Send a course as a link
Publish to a public URL and anyone holding the link can open the course — no account, no LMS, no download. The link survives a re-publish and dies on a revoke.
Comments on the running course
Review builds are hosted behind an email gate with an in-place comment overlay and live threads. Stakeholders comment on the course as it runs, not on a screenshot of it.
Plugins in a real sandbox
Plugins run in a Web Worker with a startup timeout and a message-type allowlist, governed by a three-level permission model that decides network access and the termination deadline.
The AI layer
The model doesn't write the course file. It writes the thing above it.
A single default text element serialises to 56 required values, 37 of them geometry and presentation. Handing a model that document means asking it to author coordinates. So Compose inserts a tier above it: the model writes a small, ID-keyed Course Spec — objectives, screens, decisions, choices, feedback and assessment data — and a deterministic compiler turns that into a real project through the same factory functions the canvas uses. Geometry stops being a generation problem.
Eight providers, plus anything OpenAI-compatible
- Metered: Anthropic.
- Free tiers: Google AI Studio, Groq, OpenRouter, Cerebras, Mistral, Ollama Cloud.
- Local: Ollama — nothing leaves the machine.
- Custom: any OpenAI-compatible endpoint you point it at.
- No key at all: the built-in keyless provider produces a genuine brief-derived draft, so the whole loop is exercisable before you spend anything.
Receipts, not a spinner
- Provider, model and endpoint are named on the run before the first call — and a fallback says, in a sentence, why it fell back.
- Every outbound call is a row: URL, attempt, prompt size, status, latency, bytes, finish reason. Keys travel in a header and never reach that stream.
- Raw model output streams on three channels — reasoning, prose, and the document being written.
- Gate receipts record what passed, what failed and the evidence for each, and survive a reload: runs are journalled and replayable.
It writes from your source material
Attach policies, transcripts, SME documents (DOCX, PPTX, HTML, CSV, JSON, TXT, Markdown) and Compose retrieves from a per-project corpus rather than pasting a blob into the prompt. Retrieval is lexical — BM25 with rank fusion — so it needs no key, no network and no embedding bill. Every claim in the draft can be traced back to the passage it came from, and the grounding gate checks that it resolves.
PDF is not supported yet.
Agent, Edit, Ask, Reviewer, Director
- Agent — plans and executes multi-step work on a whole course.
- Edit — ID-addressed patch operations against the document you have. A batch that would break it is rejected whole, never half-applied.
- Ask — answers questions about the course without touching it.
- Reviewer — audits the teaching and returns anchored findings, changing nothing.
- Director — stages an existing course as animated scenes, and may emit staging operations only. Anything else it proposes is dropped and reported.
Every turn is one change, one history entry, one undo.
Animated scenes
The same course, played out instead of read.
A staged node renders as an animated scene on a GPU canvas rather than as text on a page: cast members with bodies that move, a procedural backdrop, a camera that frames the beat, effects. It is a presentation choice, not a second document — the same assessment graph, the same variables, the same LMS tracking. A course can stage one beat or all of them, and a project that stages nothing ships nothing extra.
The rule that makes Compose work applies here too: the model authors direction and a deterministic compiler owns geometry. A beat is ten fields — who, framed how, doing what, feeling what, saying what, and why the motion is there — and the compiler synthesises every bone transform, camera key, viseme cue and particle from that. The harness never emits shader or path data; effects are a catalog and the runtime owns the drawing. That is not a stylistic preference — on symbolic-graphics benchmarks a frontier model scores 84.8 and a 7B model scores 8.8, so a shader path would work on one paid provider and produce black canvases on every free tier.
You pick the house style. Ten looks — House, Vector, Paper Cutout, Prime Time, Classic TV, Heartland, Rubber Hose, Storybook, Newsprint and Noir — and each one is a whole construction, not a filter over the same drawing: how many heads tall the cast stands, how the eyes and mouth are built, whether the jaw hinges, whether limbs bend or pivot from a visible joint, how far a body squashes when it lands, and whether it is held on twos or on threes. Choose it on the brief or change it later; the whole production restages in one step you can undo.
Three backends, one frame producer
- WebGPU → WebGL2 → Canvas2D, picked at runtime. Canvas2D is not a token gesture: a package opened straight off a disk cannot upload a texture from a file beside it, and Canvas2D draws it anyway.
- The runtime is generated, not bundled — and it is written into a package only when that project actually stages a scene.
- Characters are the same people as their drawn portraits: a 17-joint body under the same seeded face, so a cast member looks identical in the editor, the graph, the scene and the published course.
- Lip sync is baked while authoring — text to phonemes to a 15-viseme set — so the package ships a lookup table instead of an audio model.
Nobody has to watch it frame by frame
- Flash rate, cut rate, beat length, actor count and particle budget are clamped while compiling, below the WCAG 2.3.1 threshold — and the compiler reports what it clamped. A compiler that cannot emit an unsafe scene needs no check that can fail.
- Reduced motion is a second compiled stream, not a media query — a query has nothing to act on when the motion is a camera transform inside a canvas — plus an in-content pause control.
- The accessibility mirror is an output of the compiler. There is no accessibility tree inside a canvas, so a description per beat is generated from the scene graph and written as real markup inside the canvas element. It is the screen-reader narration, the canvas fallback and the answer to "what does a learner with no GPU get" — all the same text.
Publishing
One project. Eleven targets. Tracking that actually reports.
Codegen produces the package; the host writes it. Every format's runtime exposes the same four functions — initialise, bookmark, report an interaction, finish — so nothing in the generated course branches on which LMS it landed in, and every bridge degrades to a no-LMS local mode, which is what makes a published package previewable outside one.
| Target | What it's for | Reports |
|---|---|---|
| HTML5 | A standalone web course — host it anywhere, or open it from disk. | Local progress and bookmark |
| SCORM 1.2 | The format most LMSs still ask for first. | Status, score, bookmark, interactions |
| SCORM 2004 (3rd Ed.) | Sequencing-aware SCORM for platforms that require it. | Status, score, bookmark, interactions |
| SCORM 2004 (4th Ed.) | The current SCORM revision. | Status, score, bookmark, interactions |
| xAPI (Tin Can) | Statements to any LRS; endpoint comes from the launch URL. | Statements, results, bookmark |
| cmi5 | The xAPI profile modern LMSs launch against. | Statements, results, bookmark |
| AICC | HACP for the legacy systems that still run on it. | Status, score, bookmark |
| MP4 · WebM · MOV | A rendered video cut of the course, for channels that can't run one. | — |
| Review build | Hosted behind an email gate with a live comment overlay. | Reviewer comments and threads |
| Public share link | A sandboxed copy at an unguessable URL — no account needed to open it. | — |
Specifications
The whole surface, in numbers.
Every figure below is a count of what is in the product today, not a roadmap. Where something is missing or advisory, it says so.
Authoring
- Element types
- 13
- Document model
- Pages → sections → containers
- Responsive
- Per-breakpoint overrides
- Rich text
- TipTap
- Animation
- Keyframe timeline
- Undo history
- Patch-based
Scenarios
- Node types
- 9
- Path logic
- Variables + conditions
- Randomisation
- Random gates
- Characters
- Cast with expressions
- Portraits
- Drawn, seeded, offline
- Validation
- Exhaustive path walk
Assessment
- Interaction types
- 17 + custom
- Scoring
- Per-interaction, weighted
- Feedback
- Per choice
- Objectives
- Mapped and gate-checked
- LMS reporting
- Real interaction records
AI (Compose)
- Providers
- 8 + custom
- Works with no key
- Yes
- Agents
- 5
- Gates
- 9 (4 blocking)
- Paths simulated
- up to 512
- Retrieval
- BM25, per project
- Source formats
- DOCX, PPTX, HTML, CSV, JSON, TXT, MD
Publishing
- Targets
- 11
- SCORM
- 1.2, 2004 3rd & 4th
- xAPI / cmi5 / AICC
- Yes
- Video
- MP4, WebM, MOV
- Packages
- Self-contained
- Public share link
- Sandboxed, revocable
Animated scenes
- Render backends
- WebGPU, WebGL2, Canvas2D
- Authored per beat
- 10 fields, no shader code
- Motion classes
- 8, declared per beat
- Character rig
- 17 joints, seeded
- Lip sync
- 15 visemes, baked
- Flash / cut safety
- Clamped at compile
- Reduced motion
- Second compiled stream
- Screen readers
- Per-beat text mirror
Accessibility
- WCAG validator
- Built in
- Contrast checker
- Built in
- Tab order
- Managed
- Captions
- Editor included
- Design scoring
- 8 categories
Data & storage
- Project format
- Plain JSON
- Desktop location
- Your own disk
- Document in the DB
- Never — metadata only
- Assets
- Beside the project
- Export
- Project + corpus together
Security posture
- API keys in the browser
- Never
- Key storage
- Encrypted, host-side
- Previews
- Sandboxed, opaque origin
- Shared courses
- Sandboxed, no same-origin
- Plugins
- Worker + allowlist
- Accounts
- Sessions, roles, admin
Accounts & plans
- Desktop sign-in
- Not required
- Web sign-in
- Email, OAuth, passkeys
- Roles
- Admin and user
- Plans
- Free, Pro, Team
- Metered
- Compose runs only
- Self-hosted
- Nothing metered
Interface
- Themes
- 27 (light, dark, system)
- Appearance controls
- 13
- Layouts
- Phone, tablet, desktop
- Command palette
- ⌘K
- Browser Back
- Works on every surface
- Reduced motion
- Follows the system
Where it runs
One backend, one interface, four ways to deploy it.
The desktop app, the browser, a container on your own infrastructure and a serverless deployment are the same backend and the same interface — not a cut-down web version of a desktop product. Where a host genuinely can't do something, the app hides the control rather than failing the call.
| Host | Best for | Notes |
|---|---|---|
| Desktop | Full capability — video export, native file handling, local model support. | Windows, macOS, Linux. Projects on your own disk. No account required, and the browser build hands the installer over rather than pretending the gap isn't there. |
| Browser | Nothing to install; open a link and author. | Signed in, with roles and an admin surface. No video export — that needs the desktop build, and the app says so instead of offering a button that fails. |
| Container | Self-hosting on your own infrastructure. | One long-lived process and one volume. Full progress streaming, no execution ceiling. Refuses to start on a public address without a signing key. |
| Serverless | Managed hosting with a database instead of a disk. | Same app on Postgres. Function time limits apply and video export is unavailable; long runs stay visible because every run is journalled and replayable. |
Open it and compose something.
The keyless provider means you can run the whole loop — brief, generation, gates, receipts, a compiled course, a published package — before you decide anything.