A character earns belief in the gap between the question and the answer.
Rendering is the part everyone looks at. The part that decides whether anyone believes the character is the loop around it — listening, understanding, speaking, moving a face, and keeping the illusion alive while the model is still writing. We build that loop, inside products that also have accounts, data, billing and a release every week.
We work with product teams. Film, games and animation studios are served better elsewhere, and we say so on the first call. What we run in production is a tutor that talks to children in a browser, a digital employee with a speaking face, and photo-realistic patients a surgeon can rehearse on.
We built an Unreal Engine character that teaches children French, driven live by a language model with speech in and speech out, inside a browser — a sub-second spoken conversation loop.
It reaches the browser by pixel streaming, one GPU per concurrent user, with the DevOps to scale that up and back down as the timetable fills and empties.
There are no frame rates, polygon counts or cost-per-session figures on this page. None has been cleared for publication. The budget instrument below is schematic and labelled as such.
30 minutes, working session. Tell us what the character has to do, who is watching and on what hardware, and you leave with a one-page read either way. Nobody follows up more than once.
Six places a real-time character loses the room
Almost none of them are about how the character looks. Every one of them is engineering, and five of the six are timing.
The demo had all the time in the world
A rendered clip can be perfect because nothing is waiting for it. A character that answers a question shares a few hundred milliseconds with recognition, a model, synthesis and the rest of the application. The clip proves nothing about the product.
The face stops while the model thinks
The user does not experience latency. They experience the character going still, which reads as something worse than slow. A spinner would have been kinder, and an idle behaviour is kinder still.
The lip sync is synchronised and still reads wrong
A small, consistent offset between audio and mouth shape is perceived long before anyone can name it. It is a timing measurement, and no amount of extra geometry moves it.
It ran on the machine that built it
One user, a good GPU, a fast connection. Then it meets a classroom of five-year-old laptops on shared wifi, and the cost model turns out to have been written for a different product.
The rig and the runtime belong to different people
Assets arrive that cannot be afforded at the budget; engineering changes something that breaks the rig. Both sides are right, and nobody owns the line between them.
Eighteen months in, still a prototype
One person can run it, there is no release date, and the business that wanted a feature has an investigation instead. This is the most common ending, and it starts with an open-ended first engagement.
Drag the budget and watch what we would actually do
One turn of a conversation, drawn to scale. Six stages have to happen between a child finishing a sentence and the character starting to answer. Tighten the budget and the stages stop queuing politely and start overlapping — in the order we would really attack them.
Every stage finishes before the next one begins. It is the shape a first build always has, and it is honest work — it is simply the slowest arrangement of the same six things.
A second and a half of stillness. Old enough to look away, and looking away is the failure — not the milliseconds.
While the model is writing, the character still has to be alive: breathing, blinking, shifting weight, occasionally looking away and back. Idle behaviour is the cheapest thing on this page and it buys more perceived speed than any of the optimisations above.
A character that watches back
Distance, head angle, eye state and whether anyone is still looking — the signals that let a tutor notice a child has stopped paying attention. We prototyped on OpenCV, then benchmarked OpenCV with TensorFlow against OpenCV with MediaPipe on accuracy, stability and speed. MediaPipe won, and it went behind a clean API so the rest of the stack never has to care. Face-tracking case →
Where the engine runs is a business decision wearing a technical costume
This is the question that changes the product, and it belongs in week one rather than week thirty. There are three honest answers and they have very different bills.
The engine runs on a server and the user receives video. Any device with a browser can hold a full-quality character, which is the whole appeal — and the price is a GPU for every concurrent user. On this project this is what we built, together with the DevOps around it, so the fleet grows and shrinks with the timetable instead of sitting idle overnight.
The engine runs where the user is. Cost per user collapses and the constraint moves to the hardware in the room, which you now have to specify and support. This is the right answer for training and simulation, where the room is known.
A smaller character rendered in the browser directly. It gives up material and lighting fidelity and gains reach and a bill that barely moves with usage. Often the correct answer for a first release, and a decision to revisit rather than regret.
We model the cost per concurrent user at the number you actually expect, including the shape of the day and the idle time between sessions. The answer frequently changes the product before a line of engine code is written, which is the cheapest moment for it to change.
Four systems, and what was hard about each
Every one of these is live work with a case page behind it. There are no studio credits here because there are none to have.
Unreal · LLM · STT/TTS
Browser
An Unreal character that teaches, live, in a browser
A React front end, a Python back end and an Unreal Engine character joined into one real-time pipeline: the language model handles the conversation, speech recognition and synthesis handle the voice, and face tracking drives expression. The hard part was never the character — it was the shared budget, because everything has to land inside a loop fast enough that a child does not notice a seam. It was built modular from the first week, so a new agent launches without rebuilding the core. AI video agent case →
OpenCV · MediaPipe
TensorFlow
The perception layer, chosen by measurement
Real-time distance and head angle relative to the camera, to tell the tutor whether anyone is still there. We built the prototype on OpenCV, then benchmarked two pipelines against each other rather than picking by reputation. MediaPipe won on accuracy, stability and speed and went behind a clean API. The hard part is that this runs alongside everything else and has to stay cheap. Face-tracking case →
C# · React
AWS · GCP
Interactive 3-D patients from standard medical images
A rendering pipeline that turns standard medical images into interactive, photo-realistic patient representations a surgeon can explore in VR, for a Silicon Valley startup. Realism here is functional rather than aesthetic: a rehearsal on an inaccurate model is worse than no rehearsal at all. This is training and preparation software — it is not diagnostic, not clinically validated, and not cleared by any regulator. Medical 3-D case →
Speaking face
Optional
A face that has to be worth switching on
Natural voice and text conversation with an optional two- or three-dimensional speaking face, handling support work and acting across systems at the end of a conversation. The discipline is that the face is optional, so the product has to be good without it and better with it — which is a test most avatar projects never set themselves. Digital employee case →
A fifth piece of work sits next to these for a different reason. Digicots is a marketing site with hand-built JavaScript animation — no characters, no engine, no 3-D. It is here because it is the same discipline applied where most users actually are: holding a frame rate on a mid-range phone rather than on the machine the animation was authored on.

What the Unreal seat on this team actually covers
One product of ours runs on Unreal in production, and it is on this page. Behind it sits an engineer whose Unreal work goes a good deal wider than one character in a browser — which matters when the question is whether something is a feature or a research programme.
Animation Blueprints and state machines, motion matching, physical animation, control rigs built and adjusted by hand, backward solve for editing existing animation, montages, and IK setups for head, spine and interaction with the world. MetaHuman for stylised characters with realistic facial animation.
The Gameplay Ability System for abilities and attributes, Enhanced Input, data-asset-driven customisation, custom subsystems, and the perception and query systems behind anything that has to decide what to do next.
Nanite geometry with layers driven by procedural content generation, Chaos for destructible environments, physics asset setup, upscaling integrations, and profiling and optimisation across GPU, CPU and network — which is where a frame budget is either found or lost.
Modern C++ with the standard library, multithreading and vector maths under the engine work, and eight years of production software either side of it — React, Node, Next.js, Postgres — which is why a character here arrives inside an application rather than beside one.
Read this as depth on the seat rather than a second product. When we quote a piece of character work, this is the range the estimate is drawn from.
The character is a feature of an ordinary product
Somebody has to build the lesson: pick the video, write the text, make the audio, assemble the exercise. This screen has no engine in it and it is the reason the character has anything to say. Character work that ignores the software around it produces a demo; character work that plans for it produces a release. AI video agent case →
The work, as we actually sell it
Timelines are indicative ranges and depend on scope. Every one of these starts small enough to cancel.
Feasibility, in writing
1–2 WEEKSWhat has to run in real time, on which hardware, at what concurrency and at what cost per session — and whether it is possible before you fund it. You keep the document either way.
A responsive character, end to end
10–20 WEEKSInput, model, speech, animation and the behaviour that holds the illusion while one of them is slow — delivered as a working slice inside your product rather than a standalone demo.
Lip sync and viseme work
3–8 WEEKSAudio-driven mouth shapes, timing calibration and the offset correction that separates convincing from uncanny. Measured first, then adjusted, then measured again.
Delivery model and cost
2–4 WEEKSPixel streaming against local rendering against a lighter web path, with the cost per concurrent user modelled at your real volume. It frequently changes the product, which is the point of doing it early.
The pipeline between artists and engineers
3–8 WEEKSBudgets, naming, retargeting, import automation and a written boundary both sides agreed to — so the conversation in month two is about the product rather than about territory.
3-D from real data
10–20 WEEKSGeometry generated from imaging or scans, where the accuracy of the model is a requirement rather than a preference, and the pipeline has to produce it reliably rather than once.
Motion on the web
2–6 WEEKSAnimation and interaction that holds its frame rate on a mid-range phone, built in the browser, with the profiling to show that it does.
An engineering counterpart for your 3-D person
ONGOINGYour artist keeps the assets and the look. We take the budget, the pipeline, the runtime and the integration, and we write the line between the two down before anyone starts.
We test the device before we recommend it
Every delivery recommendation on this page comes from time spent with the thing itself — headsets, laptops, phones, the shared wifi in a room full of them. It is the least glamorous input into a cost model and the one that stops a plan from being written for a machine nobody in your audience owns. About Fluvius →
What you are probably thinking
Not ready to talk? Take the checklist.
One page, 12 questions to answer before you commit to a real-time character — the shared latency budget and who owns each stage of it, what the user sees while the model is thinking, the delivery model and its cost per concurrent user, the hardware your audience actually has, the lip-sync offset you are willing to accept, and who owns the line between the assets and the runtime.
Tell us what the character has to do, and who is watching.
A free 30-minute working session, not a sales call. Bring the thing the character has to do, the hardware your users actually have, and the concurrency you expect; we tell you what fits inside the budget and what does not. You keep a one-page read either way — the frame and latency budget, the delivery model we would recommend with its cost per concurrent user, and the one thing we would cut first.