In 1996, while I was living in Shimizu, Japan doing an English Teacher gig, a friend asked me to helkp him set up a Virtual IO VR Headset he had imported from the States. I didn't even know how to turn his PC on, but I read the instructions, we downloaded Netscape in a 14400 US Robotics modem, and figured out how to set up the headset. Unbeknownst to me, the CEO of Tokai Hightec was watching. On getting it going he offered me a job as technical support for their new business project to import and resell Virtual IO "i-glasses". One of his first instructions was for me to teach myself VRML, — I built a dragonfly in notepad.
His name is Tombo. She was originally built in Caligari TrueSpace, animated with keyframe interpolators, and she visited flowers across a green hill while her four wings beat independently. The version below was not an export of that but a hand codes .wrl file using nothing but MS notepad. It ran in Cosmo Player in Netscape on a Pentium with a CRT monitor. She was, by any measure of the time, delightful.
I hadn't seen her fly in nearly thirty years.
One Saturday night, with Claude Sonnet 4.6 as my co-pilot, I did again.
What We Built
The goal was simple in concept and genuinely hard in execution: a VRML V2.0 viewer that runs entirely in the browser, no plugins, no server, just HTML and Three.js.
VRML V2.0 is a rich format. It has:
- PROTO — reusable node templates with field substitution
- EXTERNPROTO — prototypes loaded from external files
- DEF/USE — named node definitions and instancing
- ROUTEs — event wiring between nodes
- TimeSensor + Interpolators — keyframe animation
- Background — skybox with six face textures
- Viewpoints — named cameras including ones mounted to animated objects
Every single one of those needed to work for Tombo to fly.
The Hard Parts
The tokeniser bug. Tombo's VRML file was authored on Windows in 1996. The EXTERNPROTO URL strings spanned multiple lines with \r\n line endings, meaning the opening " and closing " were on different lines. Our tokeniser regex "[^"]*" matched across newlines and swallowed the entire next EXTERNPROTO block as part of the URL token. The fix was changing it to "[^"\n]*" — quoted strings cannot cross line boundaries. One character.
PROTO scoping. Tombo has four wings, each a FlappingWing PROTO instance with its own TimeSensor, OrientationInterpolator, and ROUTE wiring. Our first implementation used a flat global node registry. Each instantiation overwrote Wing, orient_interp, and time — so only the fourth wing animated. The fix was giving each PROTO instantiation its own isolated node context and route list, with tickAnim running all of them independently.
The missing brace. During a debug-logging cleanup pass, a removal pattern consumed the closing } of the entire parseEXTERNPROTO function along with the else if block it was targeting. V8 matched the outer IIFE's opening { against the first stray } it found hundreds of lines later, making })(); at the end of the file "unexpected." Three hours of binary search with node -e 'new vm.Script(...)' to find one missing brace.
The Moment
When the geometry finally appeared — 83 meshes, 39,488 triangles, 9 animation routes — and Tombo lifted off the green hill and began her flight between the flowers, wings beating on all four independently — I felt something I wasn't expecting.
This wasn't just a technical achievement. It was a time machine.
The files are iitombo.wrl and parts.wrl. They are exactly as I left them. They were correct all along. Every problem we encountered was in the viewer, not the source. The VRML is authenticated by authorship — it worked in 1996, and now it works again.
What the Viewer Does Now
- Loads
.wrlfiles directly or.ziparchives with full path resolution (handles../../textures/traversal correctly) - Full PROTO/EXTERNPROTO support with scoped instantiation
- Animation engine: TimeSensor, PositionInterpolator, OrientationInterpolator, ROUTEs
- Viewpoints parsed from the scene — including mounted cameras that follow animated objects
- Background skybox with cube texture faces
- Debug console with selectable text log
- Wireframe toggle, skybox toggle, animation scrub bar
The viewer is open source under the TIC-OHSL license (free personal use, 2% revenue share for commercial use over $1M/year). It lives at git.theidea.club.
Tombo as Benchy
In 3D printing, a Benchy is a standardised test object. You print one and immediately know if your printer is calibrated — overhangs, bridges, curves, fine detail, all tested at once.
Tombo is our Benchy for the VRML viewer. She exercises every parser feature simultaneously: external file references, PROTO instantiation with field substitution, multiple independent animation loops, texture loading, viewpoint mounting. If she flies correctly, the viewer is correct.
She is flying.
Tools used: Claude Sonnet 4.6, Three.js r128, JSZip. The original scene files are circa 1996, authored in MS Notepad, and have not been modified.
Loading…