▶ Play the demo — self-contained HTML, no install required. Press spacebar to start. X to toggle classic ↔ remastered.
A web-based recreation of Second Reality (Future Crew, Assembly'93) built with WebGL2 shaders and Web Audio, paired with a timeline editor for sequencing and scrubbing through the demo in real time.
https://github.com/mtuomi/SecondReality — original source code
Second Reality is a legendary DOS demo by Future Crew that won the Assembly 1993 demo competition. It pushed 486-era PCs to their limits with hand-optimized x86 assembly, producing effects like voxel landscapes, plasma fields, 3D polygon flyovers, and glenz vectors — all perfectly synchronized to Skaven's tracker music.
This project rebuilds those effects using modern web technologies while staying faithful to the original 320×256 PAL aesthetic.
A bit of personal context — feel free to skip to the next section.
I was a young teenager when this demo came out. It blew my mind then, and it still boggles my mind today that a group of teenagers pulled this off in 1992-93. Sure, a lot of these effects haven't necessarily aged well or even look that impressive, but you have to put it into context. Very little available online resources. Michael Abrash's Graphics Programming Black Book didn't come out until 1997. A combination of creativity, ingenuity, genius, experimentation, trial and error and luck brought us this and many many other amazing demos.
I'll be honest, I probably peaked at Second Reality. I wanted to understand it, pull it apart, tinker with it. Graphics programming called to me in a way nothing else did. But life happened. I became a software engineer who occasionally dabbled with a few toy projects. Graphics was always on the sidelines, never quite in reach. One of many ideas filed under "I'll never have the time to do it or learn how to do it, but I'd love to one day..."
That is, until 2026. I'd spent years scoffing, denying, being frustrated, scared, and who knows what else, about... yes, LLMs. Around mid-2025 something fundamental shifted. I began relying on them more and more at work, at first in small projects that wouldn't justify the ROI. Results were good, then got better. By January 2026 I decided to go all-in. I've been writing code professionally since 2003 and tinkering with it since I was 14. As of March 2026 I have barely written a line of code myself. The ability to work on ambitious and complex ideas at the speed of thought is just astonishing to me.
Here's the thing: while I absolutely love writing code, my true passion has always been building systems. Most code I write and review isn't novel — I've seen it before, shaped slightly differently, wired differently, but it's all familiar. The real complexity lives in the architecture, the emerging concepts and sub-systems and how they all interconnect. Code has to be written for systems to exist, but that takes time, patience, and usually many build cycles. I don't want to know how much of my life has been spent waiting for builds and CI jobs to finish — never getting that time back.
LLMs like Claude fundamentally changed this for people like me. The physical constraints that lead to slow cycles still exist, but you can now parallelise across meaningful complex projects, focusing your attention on the systems you want to build rather than the boilerplate that connects them.
So this project. I didn't just sit down one day, fire up Claude and say "remaster Second Reality, let me know when you're done". What you see here is code 100% LLM-written and 100% supervised and directed by me. It's a joint effort where I drive the vision and architecture while Claude takes care of the maths and shader code I could never have gotten to on my own. At the same time, I'm turning this into a learning repository — creating per-effect guides for people like me, who wished they had them when they were just a kid.
This project is intentionally learning-focused and design-centric:
- Every effect is reverse-engineered from the original x86 assembly, understood deeply, and documented in a dedicated design doc before implementation begins.
- Design documents in
docs/effects/capture the how and why — algorithms, data layouts, projection maths, palette structures — not just the what. - Remastered variants are designed on paper first (
docs/effects/*-remastered.md) with architecture diagrams, shader breakdowns, and parameter tables before a line of GPU code is written. - A growing collection of learning guides uses the effects themselves as teaching material, unpacking real-time graphics techniques from first principles for anyone who wants to understand them.
The goal is not just to recreate Second Reality, but to make the techniques behind it accessible to anyone curious about graphics programming.
The project has two entry points:
- Player (
src/player/) — a standalone vanilla JS runtime that plays the demo fullscreen, synced to the original S3M soundtrack via Web Audio. - Editor (
src/editor/) — a React + Vite creative tool with a video-editor-style timeline for sequencing effects, authoring beat maps, and scrubbing through the demo.
Both share a common core (src/core/) that handles the orchestrator, clock, beat map, MOD player, and WebGL helpers.
graph TD
%% ── Assets ──
PJ[("project.json<br/>25 clips · transitions · beat map")]
S3M[("S3M Soundtrack<br/>MUSIC0 + MUSIC1")]
TEX[("Effect Assets<br/>Textures · Sprites · Binary data")]
%% ── Entry Points ──
subgraph Entry["Entry Points"]
Editor["<b>Editor</b><br/>React 18 · Vite · Tailwind · Zustand<br/>Timeline · Preview · Scrubbing"]
Player["<b>Player</b><br/>Vanilla JS · No build step<br/>Fullscreen 320×256"]
end
%% ── Core Runtime ──
subgraph Core["src/core/ — Shared Runtime (vanilla ES modules · zero dependencies)"]
Proj["<b>Project Loader</b><br/>Load & validate project.json<br/>Resolve clips & transitions"]
subgraph Audio["Audio Pipeline"]
MSync["<b>Music Sync</b><br/>80 named sync points<br/>3 playback regions<br/>time ↔ music position"]
ModPlay["<b>Mod Player</b><br/>Dual S3M engine<br/>Sample-counted Δt<br/>Music switching"]
AC["<b>AudioContext</b><br/>Web Audio API"]
end
Clock["<b>Master Clock</b><br/>AudioContext.currentTime<br/>Play · Pause · Seek"]
BeatMap["<b>Beat Map</b><br/>Beat/bar position (0.0–1.0)<br/>Nearest-beat snapping"]
Orch["<b>Orchestrator</b><br/>rAF tick loop<br/>Clip scheduling<br/>Effect pre-warming"]
Trans["<b>Transitions</b><br/>GLSL post-process overlays<br/>Fade · Flash · CRT · Checkerboard"]
WGL["<b>WebGL Helpers</b><br/>createShader · createProgram<br/>Fullscreen quad VAO"]
end
%% ── Effects Layer ──
subgraph FX["src/effects/ — init() · render(gl, t, beat, params) · destroy()"]
Reg["<b>Effect Registry</b><br/>registerEffect() · getEffect(name, variant)"]
Classic["<b>25 Classic Variants</b><br/>CPU software rasterize<br/>→ texSubImage2D<br/>320×256 faithful"]
Remastered["<b>22 Remastered Variants</b><br/>Full GLSL pipeline<br/>4K · Bloom · PBR · Raymarching"]
Bonus["<b>8 Bonus Effects</b><br/>Starfield · Fire · Tunnel<br/>Copper Bars · Grid · Wireframe"]
end
%% ── Output ──
Canvas["<b>WebGL2 Canvas</b><br/>Final composited output"]
Export["<b>tools/export.js</b><br/>→ Single self-contained HTML"]
%% ── Asset loading ──
PJ --> Proj
S3M --> ModPlay
TEX --> FX
%% ── Audio chain ──
MSync --> ModPlay
ModPlay --> AC
AC --> Clock
%% ── Core data flow ──
Proj --> Orch
Clock --> Orch
BeatMap --> Orch
%% ── Entry points drive the orchestrator ──
Editor --> Orch
Player --> Orch
%% ── Effect resolution ──
Orch --> Reg
Reg --> Classic
Reg --> Remastered
Reg --> Bonus
%% ── Render pipeline ──
Classic --> WGL
Remastered --> WGL
Bonus --> WGL
Orch --> Trans
Trans --> WGL
WGL --> Canvas
%% ── Distribution ──
Player -.-> Export
Core -.-> Export
FX -.-> Export
Each visual effect is a self-contained ES module with a three-method interface (init, render, destroy). The orchestrator pre-warms effects before their clip starts, ensuring zero-hitch transitions. Effects come in two variants:
- Classic — faithful 1:1 reproduction of the original algorithm at 320×256
- Remastered — optional enhanced version with modern techniques (4K, better lighting/shading)
| Layer | Technology |
|---|---|
| Rendering | WebGL2 (raw, no Three.js) |
| Audio | S3M playback via vendored webaudio-mod-player |
| Master clock | AudioContext.currentTime (sample-accurate) |
| Editor framework | React 18 + Vite + Tailwind CSS + Zustand |
| Post-processing | Framebuffer chain, full-screen GLSL passes |
No frameworks or bundlers required for the player — vanilla JS and raw WebGL.
All 25 parts of the original demo are implemented as classic variants:
| # | Effect | Original Part | Classic | Remastered |
|---|---|---|---|---|
| 1 | Scrolling landscape credits | ALKU | Done | Done |
| 2 | 3D polygon ships flyover | U2A | Done | Done |
| 3 | Pre-rendered explosion | PAM | Done | Done |
| 4 | Title card | BEGLOGO | Done | Done |
| 5 | Checkerboard fall | GLENZ_TRANSITION | Done | Done |
| 6 | Translucent rotating polyhedra | GLENZ_3D | Done | Done |
| 7 | Dot tunnel | TUNNELI | Done | Done |
| 8 | Circle interference | TECHNO_CIRCLES | Done | Done |
| 9 | Bars transition | TECHNO_BARS_TRANSITION | Done | — |
| 10 | Rotating bars | TECHNO_BARS | Done | Done |
| 11 | Troll picture | TECHNO_TROLL | Done | — |
| 12 | Mountain scroller | FOREST | Done | Done |
| 13 | Lens slide-in | LENS_TRANSITION | Done | — |
| 14 | Bouncing crystal ball | LENS | Done | Done |
| 15 | Rotozoom | LENS_ROTO | Done | Done |
| 16 | Plasma waves | PLZ_PLASMA | Done | Done |
| 17 | Plasma cube | PLZ_CUBE | Done | Done |
| 18 | Mini vector balls | DOTS | Done | Done |
| 19 | Mirror ball scroller | WATER | Done | Done |
| 20 | 3D sinusfield / voxel landscape | COMAN | Done | Done |
| 21 | Jelly logo | JPLOGO | Done | Done |
| 22 | 3D city flyover | U2E | Done | Done |
| 23 | End picture | ENDLOGO | Done | Done |
| 24 | Scrolling credits | CREDITS | Done | Done |
| 25 | Greetings scroll | ENDSCRL | Done | Done |
| Effect | Techniques |
|---|---|
| ALKU | Atmospheric purple horizon glow, dual-tier bloom, beat-reactive brightness |
| U2A | GPU polygon ships, palette-ramp texture lighting, hardware depth buffer, horizon glow, dual-tier bloom |
| PAM | Procedural lava core (plasma + voronoi cracks + orbiting embers), raymarched volumetric smoke with Beer-Lambert self-shadowing, dual-tier bloom |
| BEGLOGO | RLE-decoded image, palette-interpolated fade-from-white, CPU bilinear 4× upscale, beat-reactive brightness pulse |
| GLENZ_TRANSITION | GPU checkerboard fall, physics-driven bounce, dual-tier bloom |
| GLENZ_3D | GPU vertex pipeline, alpha blending, Phong/Fresnel glass, dual-tier bloom |
| TUNNELI | Gaussian-splat dots, depth-based neon gradients, additive blending, dual-tier bloom |
| TECHNO_CIRCLES | GPU texture-sampled interference, bilinear-filtered circles, smooth palette gradients, dual-tier bloom |
| TECHNO_BARS | GPU analytical bar geometry, 4-plane compositing via modular SDF, smooth popcount palette, dual-tier bloom |
| FOREST | Procedural Voronoi caustic water, FBM noise UV warping, foliage shadow undulation, HSV hue rotation, dual-tier bloom |
| LENS_LENS | Analytical Snell's law refraction, Blinn-Phong specular + Fresnel crystal ball, chromatic aberration, shared KOE visual treatment with LENS_ROTO, dual-tier bloom |
| LENS_ROTO | GPU rotozoom, bilinear filtering, Blinn-Phong specular + Fresnel lens material, beat-reactive eye glow, procedural nebula background, dual-tier bloom |
| PLZ_PLASMA | Full GLSL plasma computation, continuous palette interpolation, color theme presets, dual-tier bloom |
| PLZ_CUBE | GPU vertex pipeline, per-pixel Phong lighting, perspective-correct texturing, procedural plasma faces, dual-tier bloom |
| DOTS | Instanced sphere impostors, planar reflections, crystalline ground with layered value noise, HSL colouring, dual-tier bloom |
| WATER | Raymarched chrome spheres, procedural water surface, real-time reflections |
| COMAN | GPU fragment-shader VoxelSpace, dual height maps, column raymarching, atmospheric fog, 13 colour themes, dual-tier bloom |
| JPLOGO | Precomputed scroll-in, sine-table jelly bounce with per-scanline zoom, CPU bilinear 4× upscale |
| U2E | GPU polygon city, palette-ramp Gouraud shading, depth-based atmospheric fog, exhaust glow, raymarched volumetric nebula sky, dual-tier bloom |
| ENDLOGO | Palette-interpolated fade-from-white / fade-to-black, CPU bilinear 4× upscale |
| CREDITS | CPU picture+text compositing with per-screen palette swap, deceleration slide-in, CPU bilinear 4× upscale |
| ENDSCRL | CPU bitmap font scroll at 640×400, CPU bilinear 4× upscale |
Starfield, Copper Bars, Fire, Wireframe 3D, Vector Balls, Bouncing Bitmap, Grid, Tunnel
The docs/learning/ directory contains deep-dive tutorials that use effects from this project to teach real-time graphics programming. Each guide is self-contained with inline code snippets — readable on GitHub without cloning the repo. Every guide follows the same structure: an overview, numbered technical chapters building layer by layer, and a final learning-path chapter with hands-on exercises.
| Guide | Chapters | Topics |
|---|---|---|
| ALKU Remastered | 5 | Landscape scrolling, bitmap font rendering, palette fading, GPU compositing |
| U2A Remastered | 7 | Binary animation streams, polygon meshes, painter's algorithm, Gouraud shading, Sutherland-Hodgman clipping |
| PAM Remastered | 4 | FLI frame decoding, RLE codec, palette flash transitions, procedural lava/volumetric smoke |
| Glenz Remastered | 7 | Tetrakis hexahedron geometry, bounce/jelly animation, model-view-projection, alpha/Fresnel transparency, Blinn-Phong |
| Tunneli Remastered | 6 | Elliptical ring templates, perspective foreshortening, sinusoidal paths, Gaussian-splat point sprites |
| Techno Circles Remastered | 5 | EGA bit-plane circles, quarter-circle mirroring, bitwise OR interference, scanline distortion |
| Techno Bars Remastered | 5 | Modular-distance bar geometry, EGA 8-page bit-plane compositing, analytical overlap counting |
| Lens Lens Remastered | 6 | Snell's law refraction, displacement lookup tables, bounce physics, GPU refraction shader |
| Lens Roto Remastered | 5 | 2D rotation matrix rotozoom, GPU texture sampling, scripted animation curves, lens material |
| Plasma Remastered | 5 | Layered sine harmonics, dual-layer interleaved blending, procedural palettes with 21 theme matrices |
| PLZ Cube Remastered | 6 | Procedural plasma textures, interleaved vertex buffers, B-spline camera, per-pixel Blinn-Phong |
| Dots Remastered | 8 | Instanced sphere impostors, SDF lighting, planar reflections, Fresnel, bloom FBO pipeline |
| Water Remastered | 5 | POS displacement tables, interlaced rendering, GPU raymarching, SDF spheres, water ripples |
| Coman Remastered | 6 | Dual height maps, column-by-column VoxelSpace raymarching, GPU fragment-shader port, atmospheric fog |
| U2E Remastered | 6 | 42-object scene graph, polygon engine pipeline, animation bytecode, depth sorting, GPU palette textures |
Detailed technical design docs live in docs/effects/. Each effect has a classic doc and optionally a remastered doc:
| Doc | Effect |
|---|---|
| 01-alku.md | Opening credits landscape (classic) |
| 01-alku-remastered.md | Opening credits landscape (remastered) |
| 02-u2a.md | 3D ships flyover (classic) |
| 02-u2a-remastered.md | 3D ships flyover (remastered) |
| 03-pam.md | Pre-rendered explosion (classic) |
| 03-pam-remastered.md | Pre-rendered explosion (remastered) |
| 04-beglogo.md | Title card |
| 05-glenz-transition.md | Checkerboard fall |
| 05-glenz-transition-remastered.md | Checkerboard fall (remastered) |
| 06-glenz-3d.md | Glenz vectors (classic) |
| 06-glenz-3d-remastered.md | Glenz vectors (remastered) |
| 07-tunneli.md | Dot tunnel (classic) |
| 07-tunneli-remastered.md | Dot tunnel (remastered) |
| 08-techno-circles.md | Circle interference (classic) |
| 08-techno-circles-remastered.md | Circle interference (remastered) |
| 09-techno-bars-transition.md | Bars transition |
| 10-techno-bars.md | Rotating bars (classic) |
| 10-techno-bars-remastered.md | Rotating bars (remastered) |
| 11-techno-troll.md | Troll picture |
| 12-forest.md | Mountain scroller |
| 12-forest-remastered.md | Mountain scroller (remastered) |
| 13-lens-transition.md | Lens slide-in |
| 14-lens-lens.md | Bouncing crystal ball |
| 14-lens-lens-remastered.md | Bouncing crystal ball (remastered) |
| 15-lens-roto.md | Rotozoom (classic) |
| 15-lens-roto-remastered.md | Rotozoom (remastered) |
| 16-plz-plasma.md | Plasma waves (classic) |
| 16-plz-plasma-remastered.md | Plasma waves (remastered) |
| 17-plz-cube.md | Plasma cube (classic) |
| 17-plz-cube-remastered.md | Plasma cube (remastered) |
| 18-dots.md | Mini vector balls (classic) |
| 18-dots-remastered.md | Mini vector balls (remastered) |
| 19-water.md | Mirror ball scroller (classic) |
| 19-water-remastered.md | Mirror ball scroller (remastered) |
| 20-coman.md | 3D sinusfield |
| 20-coman-remastered.md | 3D sinusfield (remastered) |
| 21-jplogo.md | Jelly logo |
| 22-u2e.md | 3D city flyover |
| 22-u2e-remastered.md | 3D city flyover (remastered) |
| 23-endlogo.md | End picture |
| 24-credits.md | Scrolling credits |
| 25-endscrl.md | Greetings scroll |
Additional docs:
| Doc | Topic |
|---|---|
| docs/patterns/lazy-bake-scrubbing.md | Dual-mode engine pattern for delta-compressed animations |
| docs/TRACKER.md | Master project tracker with implementation checklist |
| docs/PROJECT_BRIEF.md | Original project brief and scope |
Player — open src/player/index.html in a browser (serve over HTTP for ES module support).
Editor:
cd src/editor
npm install
npm run devsrc/
core/ Shared runtime (orchestrator, clock, beatmap, modplayer, webgl)
effects/ One subfolder per effect (classic + optional remastered variant)
editor/ React + Vite editor UI
player/ Standalone vanilla JS player
assets/
project.json Demo timeline definition (clips, transitions, beat map)
MUSIC0.S3M Original Skaven soundtrack (part 1)
MUSIC1.S3M Original Skaven soundtrack (part 2)
effects/ Per-effect textures and sprite sheets
lib/
webaudio-mod-player/ Vendored S3M playback engine (MIT)
tools/ Asset extraction and project generation scripts
docs/
effects/ Per-effect design documents (classic + remastered)
learning/ Learning guides and tutorials
patterns/ Reusable engineering patterns
reference/ Code from the JS port used as implementation reference
- Original demo: Future Crew (1993) — Psi, Trug, Wildfire, Gore, Marvel, Skaven
- Music: Purple Motion (Jonne Valtonen) & Skaven (Peter Hajba) — S3M tracker modules
- JS reference port: covalichou/second-reality-js
- Code review: Fabien Sanglard's Second Reality series
This is a non-commercial fan recreation for educational and preservation purposes. The original Second Reality demo and its assets are the property of Future Crew / Futuremark.


























