VRMan3D Archive - How vrChristmas worked
VRMan3D Archive

The 3D screensavers of Fred Cass, known as VRMan, kept running on modern Windows.

Technical notes

How vrChristmas worked

The source code for VRMan's vrChristmas is gone. To rebuild it faithfully we took the finished screensaver apart and watched it run. This page records what we found.

Each finding is tagged measured when we read it from the program or from recordings of it running, or inferred when it is our best explanation of what the evidence shows. The browser version is built from these notes.

How we studied it

Everything here comes from the program VRMan published. Nothing was taken from other sources.

What is inside the file

38 modelsDirectX .x files in binary format: cabin, sleigh, snowman, train engine and boxcar, gingerbread man, candy cane, wreath, stars, fish, stocking, light-string pieces and more.
42 texturesBitmaps for the ground, tree, cards, train, flakes, glows and 16 frames of smoke.
20 songsMIDI files. See the music page.
1 videoA 151×111, 6.7-second animation. We have not yet seen where the program uses it.

The clock: one step per eight frames

measuredThe scene does not move every frame. The program draws eight frames, then runs one step of the simulation, then draws eight more. In a recording, exactly 8 frames fall between steps in 506 of 508 steps, and the picture does not change at all in between. Each step also spins everything that has a rotation set by moving the scene forward 7.5 units of time.

measuredDistances are per step, not per second: the train covers about 8 units every step whether the computer is fast or slow. So the screensaver ran faster on a faster graphics card. In our recording (software rendering, about 40 frames a second) that was about 5 steps a second; on a modern PC drawing 300 frames a second it would be about 37.

The opening camera move

measuredThe first 120 steps are a fly-in. The program builds two Direct3D animations, each with four position keys at times 0, 2, 4 and 12, and picks one at random. Each step it moves the animation clock forward 0.1 and the camera follows the curve until time 12, ending in front of the greeting card.

Path A(−2593, 371, 333) → (1200, 800, −1500) → (200, 150, −200) → (−70, 50, 0)
Path B(−461, 344, −1672) → (1200, 800, −1500) → (−100, 125, −500) → (−400, 50, −300)

inferredThe curve between keys is a cubic Hermite spline whose tangents are the chord slope between neighbouring keys, halved at the two ends. It matches the recorded camera positions to within about 40 units on average.

A t=0A t=2A t=4A t=12B t=0B t=2B t=4B t=12treecard
The two camera paths seen from above, with the spline we fitted to the recording. Heights are not shown.

measuredThe ground texture is also chosen at random each run: snow 9 times in 11; otherwise the web-page picture or the greeting-card picture.

The flying ornaments

measuredTwenty objects are in the scene: the train, and nineteen flyers. The flyers are a candy cane that leaves a smoke trail, two gingerbread men that each drag a string of ten lights, and sixteen random ornaments (stars, sleighs, snowmen, stockings, wreaths, a fish and others). The flyers' rules, read from the program:

SteeringEvery step the heading is nudged one-fifteenth of the way toward the current target, so the sharpest possible turn is about 3.8° a step. We measured the same maximum in the recordings.
SpeedEach step, 35 times in 100 the speed is multiplied by 0.988; otherwise 0.17 is added. Speeds drift upward, settling near 26 units a step.
TargetsA random point 14,000 units wide, 1,400 high. When an ornament gets within 150 units it picks another.
FlockingAbout one step in four, an ornament adopts another ornament's target, so the crowd drifts together.
CollisionsTwo ornaments closer than 25 units both tumble, lose a quarter of their speed and throw sparks.
Special movesNow and then an ornament spins on a random axis for 20 to 170 steps.

inferredThe decoration of the tree comes from one more rule: an ornament that dips below the ground is moved onto the tree, where it hangs still (speed 0) at a random height on the cone. Hanging ornaments take off again at random, about once every 430 steps. The gingerbread men first circle the tree through a ring of waypoints. That is why the tree is bare at first and fills up over the first minutes.

The camera

measuredAfter the fly-in the camera tracks the candy cane. Once in a while (about once in 1,024 steps) it chooses a new mode from a weighted list. The modes are named inside the program.

Tracking6 in 25. Glides toward the target, closing 1/128 of the gap each step, and holds about 150 units away.
Stationary7 in 25. Stays put and turns to look at the target.
Still4 in 25. Parks at (1000, 200, 200) and looks at the target.
Trailing3 in 25. Rides behind the target.
SlowTrack3 in 25. Like Tracking but closes only 1/256 of the gap each step.
Closeup2 in 25. Closes 1/15 of the gap each step and holds 60 units away.

The program also has Chase, Target and Cockpit views; we have not seen them chosen in our recordings.

The train

measuredA toy train (an engine and four boxcars) rolls on the ground at exactly 8 units a step. It always starts at the same place, (2500, 4, 2600), and in two separate recordings the first 500 steps were the same, so the opening of its route is fixed. It sweeps in toward the tree and then wanders around it. We recorded 2,176 steps of it.

start (2500, 2600)tree
The train's recorded path from above (2,176 steps). It enters from the far corner and then circles the tree.

inferredAfter the recorded stretch, the browser version steers the train toward random points near the tree, which is how its route looks in the recording.

Snow, smoke and lights

SnowmeasuredUp to 150 flakes (300 in heavy snow) are created about 3,000 units in front of the camera and fall; wind changes about once in a hundred steps. Four flake pictures are used.
SmokemeasuredA pool of 50 puffs, each shown as 16 pictures one after another. The candy cane drops a puff every step, the train's chimney now and then, and collisions throw several at once.
LightsmeasuredEach light string is ten wire pieces, 76 units apart, trailing behind a gingerbread man; every piece has a glow picture in red, yellow, blue or pink.
Colored lightinferredThe pink and blue wash on the snow near the tree in later minutes comes from real colored Direct3D lights following the light strings. The browser version does not reproduce this yet.

The music

measuredThe program picks a song with rand() % 20, asks Windows to play that MIDI resource, and when it ends picks again. Music can be turned off in Settings. See the music page.

What we do not know yet

If you worked on the original or have a copy of the source, please get in touch.

Download our working notes (plain text)