READABLE SOURCE
The code should still make sense when opened directly in View Source, without a build pipeline standing between reader and mechanism.
ENGINEERING LOG // VIEW SOURCE, THEN LOOK CLOSER
Six browser projects opened at the seams: what each experiment was trying to do, how the illusion is assembled, where the design holds, and what should change in the next revision.
▸ OPERATING PRINCIPLES
The code should still make sense when opened directly in View Source, without a build pipeline standing between reader and mechanism.
Every project must survive on static hosting. State stays local, interaction stays in the browser, and a server is never assumed.
Geometry, gradients, oscillators and behavioural rules do more work than downloaded art. Constraints become a visual language.
Microphones and audio contexts start only after a deliberate gesture. If a browser grants a capability, treat it as borrowed.
A collection of deliberately separable effects: starfield, typewriter, click sparks, microphone waveform, Konami sequence and a proximity-driven synthetic ghost.
Design intent. Make each effect understandable enough to steal. The page is a demonstration surface, but the real product is a set of small mechanisms a visitor can extract and reuse.
requestAnimationFrame.AnalyserNode with FFT size 512, then draws its time-domain data.The convincing part of the ghost is not volume alone. As it approaches, its spectrum opens, both oscillators rise, and tremolo becomes faster and deeper. Several correlated cues imply a physical source moving closer.
Every scheduled parameter ramps over 50 milliseconds. That tiny smoothing interval prevents the clicks produced by instantaneous changes in oscillator or gain values.
const closeness = clamp(1 - distance / 16, 0, 1);
const gain = 0.0001 + closeness * 0.16;
const cutoff = 220 + closeness * 2600;
const freqA = 110 + closeness * 90;
const freqB = freqA * 1.5;
const tremRate = 2.5 + closeness * 6.0;
const tremDepth = closeness * 0.05;
A vector arena shooter built from canvas paths, global entity arrays and three enemy behaviours that create readable pressure without an engine.
Design intent. Prove that enemy character comes from motion and timing before it comes from artwork. Every hostile is a few lines, rectangles and circles; its behaviour supplies the silhouette the geometry cannot.
3 + wave × 2. The spawn pool introduces Walkers and Tanks gradually rather than merely increasing health.The game favours immediate data structures over formal classes. That keeps the source short and readable: an enemy is an object literal, while its type selects drawing and steering behaviour.
Hit flashes, radial particles and temporary glitch lines carry impact feedback. They are cheap enough to generate procedurally and consistent with the vector aesthetic.
const count = 3 + wave * 2;
const pool = wave < 2
? ["SCOUT"]
: wave < 4
? ["SCOUT", "SCOUT", "WALKER"]
: ["SCOUT", "WALKER", "WALKER", "TANK"];
A generated first-person maze that guarantees a route, places its exit by graph distance, keeps its pursuer away from the opening move and turns proximity into sound.
Design intent. Random must never mean arbitrary. The layout can surprise the player, but the generator is responsible for solvability, meaningful separation between start and exit, and a fair opening interval before the ghost becomes dangerous.
The textures are also procedural: small hidden canvases generate brick and floor patterns, which become CanvasTexture objects. The maze therefore needs no image assets.
The minimap is a second rendering of the same grid state, not a screenshot of the 3D world. This keeps it cheap and makes game logic the single source of truth.
maze = generateMaze(31, 21);
const start = { x: 1, z: 1 };
const distance = bfsDistances(maze, start.x, start.z);
const exit = pickFarthestOpenCell(distance, maze);
const ghost = pickGhostSpawn(maze, exit, start);
A canvas aquarium where weighted local rules generate schooling, hunger redirects attention, predators create panic and a retro wrapper turns the simulation into a found appliance.
Design intent. The tank should feel inhabited without pretending to be biologically exact. Behaviour is layered: schooling establishes normality; appetite, predators and the pointer disturb it; damping lets the school find a new equilibrium.
The neighbour scan is quadratic, but the interface limits the main school to 60 fish. At that scale, the direct implementation is easier to read and remains fast enough.
Light cycles, rays, plants, bubbles, rocks and shells are all procedural. The simulator and its late-1990s portal wrapper are separate files, keeping presentation independent from behaviour.
// alignment
ax += (averageVX - fish.vx) * 0.24;
ay += (averageVY - fish.vy) * 0.24;
// cohesion
ax += (centreX - fish.x) * 0.08;
ay += (centreY - fish.y) * 0.08;
// separation is applied at close range before both
A Windows 2000 shell wrapped around a stubborn local assistant. The illusion comes from faithful interface grammar, delayed responses and a close button that refuses its job.
Design intent. Recreate the emotional logic of an old desktop rather than a pixel-perfect operating system. Familiar controls establish trust; the assistant violates that trust in small comic ways.
The page calls itself AI, but no model or network service is involved. The response delay and animated thinking state are theatrical timing devices; the actual engine is transparent and deterministic apart from response selection.
User input enters the transcript through textContent, while authored assistant messages use innerHTML to support command formatting. That separation prevents typed markup from becoming page markup.
for (const category in brain) {
if (category === "fallback") continue;
const hit = brain[category].keywords
.some(keyword => input.includes(keyword));
if (hit) return choose(brain[category].responses);
}
return choose(brain.fallback);
A cinematic Three.js anomaly assembled from procedural texture, fog, instanced buildings, layered particles, scheduled events and sound that waits to be invited in.
Design intent. Make a single object feel embedded in a world larger than the viewport. The cube barely needs to act; weather, distant infrastructure and rare aerial events imply that somebody else has been watching it for years.
InstancedMesh.The scene combines three depth cues: exponential fog hides the edge of the world, a layered skyline supplies scale, and rain sheets supplement individual rain particles near the camera.
Audio is explicitly enabled by button. Once granted, ambient wind loops while thunder, radio and UFO sounds are allocated as one-shot events.
const buildings = new THREE.InstancedMesh(
sharedBoxGeometry,
sharedBuildingMaterial,
54
);
dummy.position.set(x, height / 2, z);
dummy.scale.set(width, height, depth);
dummy.updateMatrix();
buildings.setMatrixAt(index, dummy.matrix);
▸ CROSS-PROJECT REPORT
Several projects pair a themed wrapper with a separate runtime: Unit Zero, the Aquarium, AI 2K and the Cube. The pattern works because the fiction can change without disturbing the simulation.
PATTERN // PRESENTATION ≠ ENGINEBullets, fish, food, bubbles, rain and ash all use direct arrays. At current scales this keeps code inspectable. Beyond those scales, spatial indexing and pools become the next architectural step.
THRESHOLD // SIMPLE UNTIL MEASUREDGenerated texture, geometry, movement and sound share the same visual constraints. The result feels authored because every subsystem speaks the same limited vocabulary.
RULE // FEWER ASSETS, STRONGER LANGUAGEThe Aquarium and 3D scenes use elapsed time; Unit Zero advances mostly per frame. Standardising on capped delta time would make behaviour consistent across 60, 90 and 144 Hz displays.
DEBT // FRAME-RATE INDEPENDENCEReusable scripts should assume their target elements may not exist. A component that exits quietly when absent is safer to share across a growing static site.
DEBT // NULL GUARDS + CLEANUPCanvas, WebGL, Web Audio, CSS animation and ordinary DOM events cover the entire catalogue. The browser is not merely the delivery layer; it is the creative toolchain.
STATUS // NO BACKEND REQUIRED