Professor Oops

How colours mix

How colours mix

Colours mix like real paint because the game stores the light each one soaks up

Stir blue paint into yellow and you get green. Lay one wash over another and it goes darker. Touch a black marker dot with water and it splits into a blue ring, a pink band and a yellow middle. No code draws those rings or mixes those colours. They follow from how the game writes colour down: three numbers for every spot of paper, saying how much red, green and blue light the colour there soaks up.

A black marker dot on paper, wetted with a drop of water, separating into a blue outer ring, a pink band and a yellow centre, computed with the game's dye rule

Stirred paint lands between its two colours; washes laid over each other go darker

A screen makes colour by adding light. Red light plus green light looks yellow. Paint works the other way round. Each pigment soaks up part of the light, and what's left bounces back to your eye. Yellow paint soaks up blue light, blue paint soaks up red, and a mix of the two lets mostly green through.

Professor Oops keeps colour the paint way round. Every spot of paper holds three numbers: how strongly the colour there absorbs red, green and blue light. Those numbers are turned back into a colour only when the page is drawn.

That one choice gives two kinds of mixing for free, depending on where the colour lives. Colour soaked into the paper stacks. A wash over a dry wash adds its absorbance to the first, so the light has to get through both and comes back darker than either, like a glaze. Paint, ketchup and other thick stuff lying on top is stirred. Each spot of it stores its colour multiplied by how much of it there is, so when two blobs run together their colours average by volume. Nobody has to tell them to mix.

Colours mix like real paint because the game stores the light each one soaks up

For engineers

Colours mix like real paint because the game stores the light each one soaks up

Colour is stored per cell as optical density in three channels, after the Beer-Lambert law, and turned back into light only when the page is drawn. Paper adds absorbance, so layers multiply; goop keeps its colour premultiplied by its amount, so stirring gives a volume-weighted geometric mean with no mixing step. Dissolved dye is its own share of each channel, and each dye rides the water at its own speed, so a black marker dot splits into rings that nothing draws.

Under the hood
Stirred paint lands between its two colours; washes laid over each other go darker

Under the hood

Stirred paint lands between its two colours; washes laid over each other go darker

Every colour in the game is a hand-picked reflectance from 0 to 1 per channel. It is stored as absorbance (optical density), the negative logarithm of that reflectance, and drawn as its exponential. That is what the Beer-Lambert law describes, applied to three channels Swinehart 1962.

  • Paper: three absorbance values a cell over the whole grid (up to 512 × 384 cells, about half a millimetre a cell; 288 × 216 on a small phone). New colour adds to them.

  • Goop: its colour is kept multiplied by how much goop there is, and divided out only when drawn. Colour flows premultiplied with the volume, so mixing and conservation come with the flow, the way premultiplied alpha works for transparency.

layered: e−(A₁+A₂) = c₁ · c₂    stirred: e−((1−t)A₁ + tA₂) = c₁1−t · c₂t

So paper multiplies reflectances, and goop takes their volume-weighted geometric mean. The paint board's stir only speeds up what the flow already does.

Try it: mix two colours four ways The game's own rule

Pick two colours from the game's palette and slide how much of the second goes into the stir. What to look for: blue and yellow stirred come out green, where a screen's usual average comes out a dull grey-green. Laid over each other they go darker than either. (Layered lays one full unit of each colour's absorbance; built up takes two washes to the wash rule's ceiling.) Then try black and white: stirred, it stays dark, because this model has no scattering white (see where we simplify).

Two chosen colours shown mixed four ways: a screen-style RGB average, stirred as paint, layered as washes, and layered washes built up to the game's cap
  • Colour A
  • Colour B
  • RGB average
  • a screen's mix
  • Stirred
  • paint, goop
  • Layered
  • one on another
  • Built up
  • with the wash cap
Colour A
Colour B
50 %
lightness Y: average
—
stirred
—
layered
—
stirred A: red
—
green
—
blue
—
layered A: red
—
green
—
blue
—
In the game, a heap of yellow tube paint and a heap of blue, stirred into green with a palette knife where they meet, beside a yellow and a blue watercolour wash crossing into a darker, duller green
Two laws on one page. Tube paint stirred with the knife lands between its colours. Two watercolour washes crossing go darker than both.
Washes laid over each other go darker than both; stirred paint lands in between

Watercolour washes laid over each other read 0.183, darker than yellow (0.670) or blue (0.245) alone; stirred tube paint reads 0.479, between its 0.814 and 0.355.

Washes laid over each other go darker than both; stirred paint lands in between0.000.200.400.600.801.00yellow aloneblue aloneboth togetherlightness (luminance Y)Washes laid over each other go darker than both; stirred paint lands in between0.000.200.400.600.801.00yellow aloneblue aloneboth togetherlightness (luminance Y)
  • watercolour, one wash over the other
  • tube paint, stirred with the knife
  • paint brush, strokes crossed
Data table
Washes laid over each other go darker than both; stirred paint lands in between
watercolour, one wash over the othertube paint, stirred with the knifepaint brush, strokes crossed
yellow alone0.670.810.81
blue alone0.250.360.35
both together0.180.480.58

Source: Measured on the released engine. Automated tests check that stirred blue and yellow come out green, not grey.

Each tool lays colour its own way, so a scribbled patch never turns to mud

Dab real watercolour on the same spot again and again and it gets deeper, but it never turns black. In the game each drawing tool has its own rule for laying colour, and every rule levels off. A wash creeps up to a ceiling set by its own colour. A marker saturates instead of getting darker forever. Pencil levels off at a strength set by its colour and how hard it's pressed, and crayon stops adding once the spot is as dark as its own colour. So a patch a child goes over twenty times gets deeper but stays recognisably the colour the child chose.

The price is small and honest. Two thin glazes multiply almost exactly. Two washes built all the way up don't: each channel ends at the darker of the two ceilings.

Under the hood
Each tool lays colour its own way, so a scribbled patch never turns to mud

Under the hood

Each tool lays colour its own way, so a scribbled patch never turns to mud

Each stamp of a tool adds its colour, as absorbance, to the cell's. Every rule is a saturating curve, so the more colour a spot already holds, the less the next stamp adds:

  • Watercolour creeps toward a ceiling set by its own colour, and wax or soap in the paper keeps most of it off.

  • Marker pulls the spot toward its own colour instead of stacking on top.

  • Pencil levels off at a strength set by its colour and how hard it's pressed, and the paper's tooth decides how much it grips.

  • Crayon adds until the spot is as dark as the crayon itself, and lays wax as it goes.

  • Brush and tube lay goop; wet on wet, they tint what's there.

These rules are per tool. They share the storage, not the formula. Over thick goop a stroke tints the goop as well, and the tip picks up a little of what it touches, so a dirty brush is real state.

A wash levels off at its own ceiling; plain adding would run on toward blackOne stroke lays several stamps on a spot. The blue channel levels off at yellow's ceiling and the red at blue's; the plain sums run off the top of the chart.

After 60 stamps of yellow the blue channel levels off near 3.15; after 60 more of blue the red channel ends near 2.92, while the plain sums run past 6.

A wash levels off at its own ceiling; plain adding would run on toward black0123456020406080100120stamps on one spot (60 of yellow, then 60 of blue)absorbanceblue wash startsA wash levels off at its own ceiling; plain adding would run on toward black0246050100stamps on one spot (60 of yellow, then 60 …absorbanceblue wash starts
  • red channel
  • green channel
  • blue channel
  • red, plain sum
  • green, plain sum
  • blue, plain sum
Data table
A wash levels off at its own ceiling; plain adding would run on toward black
stamps on one spot (60 of yellow, then 60 of blue)red channelgreen channelblue channelred, plain sumgreen, plain sumblue, plain sum
0000000
10.0020.0140.1840.0020.0140.184
20.0030.0270.3580.0030.0280.368
30.0050.0410.5220.0050.0420.553
40.0060.0530.6760.0060.0560.737
50.0080.0660.8220.0080.070.921
60.010.0780.960.010.0841.105
70.0110.0891.0890.0110.0981.289
80.0130.1011.2120.0130.1121.474
90.0140.1121.3270.0150.1261.658
100.0160.1221.4360.0160.1391.842
110.0170.1331.5390.0180.1532.026
120.0190.1431.6350.0190.1672.21
130.020.1531.7270.0210.1812.395
140.0220.1621.8130.0230.1952.579
150.0230.1711.8940.0240.2092.763
160.0250.181.9710.0260.2232.947
170.0260.1892.0430.0270.2373.132
180.0280.1972.1110.0290.2513.316
190.0290.2062.1760.0310.2653.5
200.0310.2132.2360.0320.2793.684
210.0320.2212.2930.0340.2933.868
220.0330.2292.3470.0360.3074.053
230.0350.2362.3980.0370.3214.237
240.0360.2432.4460.0390.3354.421
250.0380.252.4910.040.3494.605
260.0390.2562.5340.0420.3634.789
270.040.2632.5740.0440.3774.974
280.0420.2692.6120.0450.3915.158
290.0430.2752.6480.0470.4045.342
300.0450.2812.6820.0480.4185.526
310.0460.2872.7140.050.4325.71
320.0470.2922.7440.0520.4465.895
32.576
330.0490.2982.7720.0530.46
340.050.3032.7990.0550.474
350.0510.3082.8240.0570.488
360.0530.3132.8480.0580.502
370.0540.3182.8710.060.516
380.0550.3222.8920.0610.53
390.0570.3272.9120.0630.544
400.0580.3312.9310.0650.558
410.0590.3362.9480.0660.572
420.060.342.9650.0680.586
430.0620.3442.9810.0690.6
440.0630.3482.9960.0710.614
450.0640.3513.010.0730.628
460.0650.3553.0230.0740.642
470.0670.3593.0360.0760.656
480.0680.3623.0470.0780.67
490.0690.3653.0590.0790.683
500.070.3693.0690.0810.697
510.0710.3723.0790.0820.711
520.0730.3753.0880.0840.725
530.0740.3783.0970.0860.739
540.0750.3813.1050.0870.753
550.0760.3843.1130.0890.767
560.0770.3863.1210.0910.781
570.0790.3893.1280.0920.795
580.080.3923.1340.0940.809
590.0810.3943.140.0950.823
600.0820.3963.1460.0970.837
610.2470.4533.1460.2670.914
620.4030.5083.1460.4360.992
630.550.5593.1460.6061.069
640.6880.6083.1460.7751.147
650.8190.6543.1460.9451.224
660.9420.6983.1461.1151.301
671.0590.7393.1461.2841.379
681.1690.7793.1461.4541.456
691.2720.8163.1461.6241.534
701.370.8523.1461.7931.611
711.4630.8853.1461.9631.688
721.550.9173.1462.1321.766
731.6320.9483.1462.3021.843
741.7090.9763.1462.4721.921
751.7831.0043.1462.6411.998
761.8521.033.1462.8112.075
771.9171.0543.1462.9812.153
781.9781.0773.1463.152.23
792.0361.13.1463.322.308
802.0911.123.1463.4892.385
812.1431.143.1463.6592.462
822.1911.1593.1463.8292.54
832.2371.1773.1463.9982.617
842.2811.1943.1464.1682.695
852.3221.213.1464.3382.772
862.361.2253.1464.5072.849
872.3971.243.1464.6772.927
882.4311.2543.1464.8463.004
892.4641.2673.1465.0163.082
902.4941.2793.1465.1863.159
912.5231.2913.1465.3553.237
922.551.3023.1465.5253.314
932.5761.3133.1465.6943.391
942.61.3233.1465.8643.469
94.86
952.6231.3323.1463.546
962.6451.3413.1463.624
972.6651.353.1463.701
982.6851.3583.1463.778
992.7031.3663.1463.856
1002.721.3733.1463.933
1012.7361.383.1464.011
1022.7511.3863.1464.088
1032.7661.3933.1464.165
1042.7791.3993.1464.243
1052.7921.4043.1464.32
1062.8041.4093.1464.398
1072.8161.4143.1464.475
1082.8261.4193.1464.552
1092.8361.4243.1464.63
1102.8461.4283.1464.707
1112.8551.4323.1464.785
1122.8641.4363.1464.862
1132.8721.443.1464.939
1142.8791.4433.1465.017
1152.8861.4473.1465.094
1162.8931.453.1465.172
1172.91.4533.1465.249
1182.9061.4563.1465.326
1192.9111.4583.1465.404
1202.9171.4613.1465.481

Source: Arithmetic from the game's watercolour rule at full brush, with the palette's yellow and blue.

Water makes marker run but leaves pencil and crayon where they are

Pour water over a real drawing and the marker runs while the pencil and crayon stay put. Marker ink is dye, and dye dissolves. Pencil and crayon are solid pigment pressed into the paper.

The game keeps the same difference. Beside its three colour numbers, every spot records how much of that colour is dissolved dye and how much is held in the fibres. Water may move only what isn't held, and dye is never held. Each tool says what it lays. Marker ink is all dye. Watercolour is part dye and part pigment grains. Coloured pencil, grey pencil and crayon are almost entirely held.

So a wash brushed over a pencil drawing blooms right through, and the line is still there when it dries. Pour water on pencil or crayon and over 95 % of the line stays, which an automated test checks. Rub the same pencil line and it smudges, because graphite sits loose on the fibres. Crayon hardly smudges.

One spot of paper cut open, from the top layer down

Floating film

Oil, marbling ink.

Moves on the water's surface.

Goop

Paint, ketchup, mud. Its colour is kept together with how much of it there is.

Flows on its own, stains the paper below.

Water

Standing water and wetness in the fibres.

Carries whatever is free.

The paper itself

All the colour soaked in, split into:

  • Dye: moves with water, each dye at its own speed.

  • Free pigment: the rest of the colour. Moves, more slowly.

  • Held: water can't move it.

  • Loose: a rubbing finger can.

  • Wax, soap: keep washes and bleach off.

Under the hood
Water makes marker run but leaves pencil and crayon where they are

Under the hood

Water makes marker run but leaves pencil and crayon where they are

In every cell and every colour channel, water may move whatever colour isn't held, and the held part can never eat into the dye. Held colour is kept per channel, so a wash laid over a pencil line is as free to run as on blank paper.

Each dry medium says two things about what it lays: how much of it the fibres hold, and how much sits loose for a finger to smudge. All of them are almost fully held. Grey pencil is the loosest, coloured pencil smudges a little, crayon hardly at all, and melted wax not at all.

Crayon resist works through the wash rule, not by keeping water out. Wetness under crayon matches bare paper, but the colour stays off the wax, and a test checks that a wash over crayon stays clearly lighter than the wash beside it.

Marker is all dye; pencil and crayon are almost all held

Marker is 100 % dissolved dye and watercolour half dye, half free pigment; coloured pencil holds 98 %, grey pencil 97 % and crayon 99 % in the fibres.

Marker is all dye; pencil and crayon are almost all held020406080100MarkerWatercolourColoured pencilGrey pencilCrayonshare of the colour, %Marker is all dye; pencil and crayon are almost all held020406080100MarkerWatercolourColoured penc…Grey pencilCrayonshare of the colour, %
  • dissolved dye (runs)
  • free pigment (moves slower)
  • held in the fibres (stays)
Data table
Marker is all dye; pencil and crayon are almost all held
dissolved dye (runs)free pigment (moves slower)held in the fibres (stays)
Marker10000
Watercolour50500
Coloured pencil0298
Grey pencil0397
Crayon0199

Source: The shares each drawing tool lays in the game.

A marker dot splits into rings because its dyes travel at different speeds

Draw a black dot, drop water on it and wait. A blue ring spreads out, a pink band follows, and a yellow patch stays in the middle. Science teachers call this chromatography. Black ink is a mix of dyes, and each one clings to the paper fibres by a different amount.

In the game a dye is one of the three colour channels. The dye that soaks up red light is the cyan one, green's is the magenta, blue's is the yellow. Whenever water moves between two spots of paper, each dye goes along at its own share of the water's speed. In a black marker the cyan dye nearly keeps up with the water, the magenta lags well behind and the yellow hardly moves. The water code has no idea what a marker is, and nothing draws a ring. The rings come out of three speeds.

The speeds were chosen so the rings show clearly, so they are tuned, not measured. In the released game every marker splits with black's three speeds. next update Each ink gets its own: green splits into yellow outside blue, purple into pink outside blue, brown into yellow, pink and a little blue.

Under the hood
A marker dot splits into rings because its dyes travel at different speeds

Under the hood

A marker dot splits into rings because its dyes travel at different speeds

The water pass runs about 30 times a second over the wet parts of the page. Between every pair of neighbouring cells, each dye goes along with the water that moved, scaled by that dye's own speed. A dye's speed comes from how strongly it clings to the fibres, the same idea as the retention factor in a chemistry lab's paper chromatography, except that ours are typed in rather than measured.

  • Dye moves freely only once the paper is properly damp; on barely damp paper it creeps.

  • A gentle evening-out between wet neighbours softens the rings.

  • Near a drying edge, water and dye are pulled toward the drier side, which is what leaves the blue ring at the edge.

Colour and dye are kept in step, so the dye's colour is moved exactly once and nothing is made or lost. Parts of the page with no dye in them skip this work altogether. An automated test wets a black dot and finds the cyan ring well outside it, with the dot's total colour kept.

next update Every marker colour gets its own three speeds, so green, purple, brown and red each split their own way.

Try it: a marker dot in a drop of water The game's own rule

A drop has just landed on a black marker dot. Tap the paper to add another drop, or press Add a drop. What to look for: the cyan dye rides out with the water's edge and dries there as a blue ring, the magenta stops halfway, the yellow hardly leaves the dot. The readout gives how far out each dye sits on average and checks none is lost. The water's spread, the dye rule and every rate are the game's; the drop soaking in and the drying are simplified. Green, purple, brown and red show each ink's own split next update.

A marker dot on paper, with water spreading from it and each colour of dye travelling at its own speed
Marker
8
3×
time on the page
—
mean distance, cells: cyan
—
magenta
—
yellow
—
dye kept
—
A black marker dot under a drop of water in the game, opened into a blue ring, a pink band and a yellow centre.
The real thing, in the game. A black marker dot a minute after a drop of water.

A watercolour wash stays its own colour right up to its darker rim

A wash's dye has no reason to split. In a wash, free dye goes at the same speed in all three channels, so a blue wash stays blue to its edge. In an automated test, every spot of a blue, red or yellow wash 30 seconds into drying is within 3° of hue of the middle.

The pigment half is grains, and grains only ride along while the paper is properly wet. As a wash dries, its thin edge empties first, water flows out toward it and brings colour with it. In the game's test a dried wash's rim is 1.3 to 2.5 times as dark as its middle, as in a dried coffee drop Deegan 1997. The picture of water in the sheet carrying pigment to the edges comes from early computer watercolour Curtis 1997; the game gets there with a much simpler local rule. Wet a dried wash again and it blooms in its own colour.

Under the hood
A watercolour wash stays its own colour right up to its darker rim

Under the hood

A watercolour wash stays its own colour right up to its darker rim

Each pass, about 30 times a second, runs in JavaScript and as a WebAssembly twin that a test holds to the same result:

  • Water flows down differences in wetness, faster where the paper's fibre is denser, so fronts come out ragged.

  • Evening out: colour slowly evens between neighbours that are both wet.

  • Grains ride a share of the water's flow that grows quickly with wetness, so they need properly wet paper.

  • Edge pull: where one side is drier, water and colour are pulled toward it, capped so it stays stable. This is the coffee-ring effect.

  • Tide mark: where wet meets dry, a faint brownish line is added. It is the one term here that makes colour.

An automated test holds the dye in a watercolour to within a ten-thousandth per channel over a minute on wet paper, in JavaScript and in the WebAssembly kernel alike.

The rim of a drying wash grows darker than its middle

A watercolour dab goes from 1.02 at 20 s to 2.54 at 180 s; an ink drop from 1.44 at 20 s to 4.15 at 60 s.

The rim of a drying wash grows darker than its middle01234050100150seconds after laying itrim ÷ centre (darkness)The rim of a drying wash grows darker than its middle01234050100150seconds after laying itrim ÷ centre (darkness)
  • watercolour dab
  • ink drop
Data table
The rim of a drying wash grows darker than its middle
seconds after laying itwatercolour dabink drop
201.021.44
601.154.15
1802.54

Source: Measured on the released engine. An automated test holds a dried wash's rim to 1.3 to 2.5 times the inside.

Dye moves in damp paper; pigment grains need it wet

Free dye is carried at its full 0.9 share from a wetness of 0.2; pigment grains reach their 0.5 share only at a wetness of 0.5.

Dye moves in damp paper; pigment grains need it wet0.00.20.40.60.81.00.00.20.40.60.81.0wetness of both cellsshare carried with the waterDye moves in damp paper; pigment grains need it wet0.00.20.40.60.81.00.00.20.40.60.81.0wetness of both cellsshare carried with the water
  • free dye
  • pigment grains
Data table
Dye moves in damp paper; pigment grains need it wet
wetness of both cellsfree dyepigment grains
000
0.020.090.0008
0.040.180.0032
0.060.270.0072
0.080.360.0128
0.10.450.02
0.120.540.0288
0.140.630.0392
0.160.720.0512
0.180.810.0648
0.20.90.08
0.220.90.0968
0.240.90.1152
0.260.90.1352
0.280.90.1568
0.30.90.18
0.320.90.2048
0.340.90.2312
0.360.90.2592
0.380.90.2888
0.40.90.32
0.420.90.3528
0.440.90.3872
0.460.90.4232
0.480.90.4608
0.50.90.5
0.520.90.5
0.540.90.5
0.560.90.5
0.580.90.5
0.60.90.5
0.620.90.5
0.640.90.5
0.660.90.5
0.680.90.5
0.70.90.5
0.720.90.5
0.740.90.5
0.760.90.5
0.780.90.5
0.80.90.5
0.820.90.5
0.840.90.5
0.860.90.5
0.880.90.5
0.90.90.5
0.920.90.5
0.940.90.5
0.960.90.5
0.980.90.5
10.90.5

Source: The shape of the game's own rules for what the water carries.

Red cabbage juice works as a real acid test, turning pink with vinegar and blue-green with baking soda

Red cabbage juice is a real acid detector. Lemon turns it pink, baking soda turns it blue and then green. In the game, a spot soaked with cabbage juice stores no colour for it at all. It stores how much dye is there. Each time that part of the page is packed for the screen, the game reads how acidic the spot is and looks the colour up in a chart.

The chart has 141 shades, one for every tenth of a pH unit from 0 to 14. They are blended from 8 hand-picked colours, in the order published cabbage charts give. The shades are ours, so we say the colour is looked up from a chart, not computed from chemistry.

Because the colour is never stored, it can never go out of date. Add soda and the spot changes colour the next time it's redrawn. Turmeric and tea work the same way, as a shift from their own stain colour. A blob of blueberry on soap turns blue-green, because goop carrying a dye reads how far the paper under it is from neutral. An automated test checks it.

Under the hood
Red cabbage juice works as a real acid test

Under the hood

Red cabbage juice works as a real acid test

When a part of the page is packed for the screen, each cell's amount of cabbage dye is multiplied by the chart's entry for the pH there, and added to the colour as absorbance.

The chart is built once when the game starts. Between two hand-picked colours it blends in reflectance, the light that comes back, and only then turns the result into absorbance, so the in-between shades look like real mixtures. A small lookup table means no logarithms while drawing. Turmeric and tea work the same way, but add only their shift away from their colour at neutral. The pH reading itself is covered in Chemistry and pH.

Try it: the cabbage colour chart The game's own rule

Drag along the strip or use the pH slider. What to look for: the colour is the chart's entry times the amount of dye, so more juice gives a deeper shade from the same entry; only the pH moves you along the chart. The ticks under the strip are the 8 hand-picked knots.

The red cabbage colour chart from pH 0 to 14, with the chosen pH marked and a large swatch of its colour on paper
  • pH 0 · acid
  • 7 · neutral
  • alkaline · 14
  • on paper
3
pH
—
1.00
table entry
—
absorbance per unit: red
—
green
—
blue
—
added: red
—
green
—
blue
—
In the game, paper stained purple with red cabbage juice, with a pink spot where vinegar was dropped and a blue spot round a little white heap of baking soda
One dye, three colours. A drop of vinegar and a pinch of baking soda on cabbage-stained paper. The blue round the soda is the next update's next update; in the released game the same soda turns it blue-green.

Bleach and sunlight fade colours unevenly, so black marker turns orange before it goes pale

Draw a bleach pen over black marker and it doesn't just go paler. It turns red-brown, then orange, then pale yellow, the way real bleach-pen art does. The game's bleach takes absorbance out faster in red and green than in blue. Black loses its yellow part last, so the in-between colours appear on their own. Crayon or soap under the colour keeps most of the bleach off, and every bit of colour it removes uses some of the bleach up, so a small drop on a dark patch runs out.

Bleach is a named rule in the game's table of reactions, so this part is written chemistry, not emergent chemistry. What it shares with everything else is that it reads the colour numbers, whatever put the colour there. Rust in the paper bleaches just like marker.

Sunlight fades too. Leave a page for a week in a sunny window and the dyes fade, reds and yellows first. Whatever lay on the paper, a sticker, tape, a leaf or a blob of paint, keeps its patch dark, and you get a sun print. In the released game the fade is three flat factors on every uncovered colour, pencil included. next update The fade depends on what made the colour. Marker dye takes the full fade, crayon and coloured pencil much less, grey pencil none, and the paper itself yellows a little.

Under the hood
Bleach and sunlight fade colours unevenly

Under the hood

Bleach and sunlight fade colours unevenly

Bleach shrinks absorbance exponentially, channel by channel, at a different rate in each: fastest in red, slowest in blue. That one difference is why black passes through brown and orange on its way to pale yellow.

  • The rate grows with the bleach's strength and how wet the paper is, and wax or soap in the paper keeps most of it off.

  • Bleach wears off in wet paper, and every bit of colour it takes out uses some of it up.

  • Goop on top fades by its own material: food a lot, paint, mud, wax and plastic hardly. Cabbage dye fades too.

Sun in the released game: every uncovered cell keeps a fixed share of its colour in each channel, so reds and yellows fade most, and the paper yellows a touch. Anything lying on the paper counts as full shade.

next update The fade runs on every time skip, scaled by how much UV reaches the page and for how long. Dye takes the full fade; held colour is spared by its medium's lightfastness, with graphite fully lightfast. A lamp gives a small fraction of a window's UV, and bare paper yellows slowly over its first couple of weeks.

Try it: bleach on marker stripes The game's own rule

Black, red and blue marker stripes, with an invisible white crayon stripe drawn down the right. Two drops of bleach have just landed. Tap to drop more, or press Drop bleach. What to look for: black goes through brown and orange to pale yellow, thinner bleach at a drop's edge leaves an orange ring, and the colour under the crayon stays. The drop's size is ours; the fading, the bleach used up and the wax's protection are the game's rule. In the game bleach also travels with the water; here it stays where it lands.

Black, red and blue marker stripes on paper with a white crayon stripe, fading through brown, orange and yellow where bleach was dropped, except under the crayon
2.5
×0.25
bleach left
—
colour taken out
—
In the game, three bleach-pen lines across a black marker patch: each fades to pale with red and orange edges, but where it crosses a white crayon stripe under the ink it stays dark red-brown
Bleach-pen art. Black marker fades through red and orange to pale. Where the lines cross a white crayon stripe under the ink, the wax keeps most of the bleach off and the black only turns dark brown.
A week in a sunny window, now and in the next update

Worked from the game's own fade rule (arithmetic, not a screenshot): each swatch is a solid patch on the game's paper colour. In the released game a week of sun applies the same three factors to everything uncovered. The next update next update fades by what made the colour and yellows the paper.

Colours before and after a week in a sunny window, now and in the next update
  • A week of sun
  • Before
  • now
  • next update
  • Red marker
  • Yellow marker
  • Blue marker
  • Black marker
  • Grey pencil
  • Red crayon
  • Bare paper

The page on screen is drawn from those numbers, not kept as a picture

The page you see isn't stored as a picture. The game keeps only the numbers: absorbance, dye, wetness, goop height and the rest. The simulation runs in a background worker. It packs the parts of the page that changed into small square tiles and hands them to the graphics chip, which turns absorbance back into colour for every pixel, lights it with the room's light and adds relief and shine.

Some things get their look only at that moment. Cabbage colour is looked up then. Grease stains, salt crust and wires get their colour then, and oil floating on water is folded into what's under it. Because these are worked out at drawing time, they can't drift out of step with the simulation.

Wet paper is drawn darker, as wet paper looks. Clear goop like honey or oil is looked through, not painted over. Its colour is the light that comes back up through it, so honey or oil over a dried ketchup stain doesn't pale it. When you save a picture, the same shader draws the page again with sharper edges and pigment settling into the paper's grain, detail that exists only in the saved picture.

Under the hood
The page on screen is drawn from those numbers, not kept as a picture

Under the hood

The page on screen is drawn from those numbers, not kept as a picture

Colour reaches the graphics chip as absorbance, not as colour, and the chip filters it smoothly between cells. Filtering absorbance makes an edge between two cells blend as a geometric mean, the same way the paint itself mixes. Goop's colour and its amount are filtered separately and divided afterwards, so a thin edge gets no dark fringe; it is the premultiplied-alpha trick again.

The shader then works the colour out per pixel: absorbance back to light on the paper's own colour and fibre, wet spots darkened, goop laid over it with see-through goop letting what's under it show, and finally ambient shade, shadow, the room's light and a highlight.

On a busy page at a low detail setting, the changed tiles are sent under a per-frame budget, the longest-waiting ones first, and the tiles under the child's hand always go. The picture stays responsive where the child is looking.

From the simulation's numbers to the screen

Numbers in the worker

Absorbance, dye, wetness, goop and the rest, simulated in a background Web Worker.

Pack what changed

Only tiles that changed. Cabbage, grease, salt and wire get their colour here; floating oil is folded in.

Hand over

Handed to the main thread without copying.

Smooth

Filtered as absorbance, so cell edges blend like paint.

Shade

Absorbance back to light, wet darkening, goop over it, shadow, light, shine.

Screen

A child's painting, from a handful of numbers a spot.

Water, fire, bleach, tape and ants all act on the same colour, whoever put it there

Water, fire, bleach, smudging fingers, tape, stencils, sponges, ants and dogs all read or write the same colour channels. None of them asks who put the colour there. That's where the surprises come from: the water doesn't know about markers, and the bleach doesn't know what drew the colour it fades. Where we did write a special rule, such as bleach, iron-gall ink or the cabbage chart, it reads the shared numbers, never which tool put the colour there. Each tool's way of laying colour is its own rule, but they all write into the same numbers.

3
Numbers per spot of paper for the colour you see there, however many colours went into it.
2
Ways colours mix, stacking in paper and stirring in paint, from that one way of writing colour down.
512×384
Spots of paper on a large screen, each about half a millimetre across.
141
Cabbage shades in the colour chart, blended from 8 hand-picked colours.
30/s
Passes a second of water and colour through the wet parts of the page; calm patches go less often.

Shared: acid element → cabbage chart

Run a battery through salty water on paper soaked in cabbage juice

The paper turns pink at one clip. The circuit writes acid; the chart reads it; neither knows the other.

Electricity · pinned by a test

Shared: tannin + iron in the paper

Leave a rusty pin in damp, tea-stained paper

Blue-black ink forms where water brings the tea to the rust, slower under a puddle.

Chemistry and pH · pinned by tests

Shared: free colour + surface flow

Touch a soapy drop to a wet watercolour

The paint is pushed back into a ring, because surface flow moves whatever colour is free.

Runny, sticky and oily · pinned by a test

Shared: carried colour

Let a cat walk out of a paint puddle

Paw prints fade step by step as the paws run out of paint, by the same carrying rule balls, tyres and rollers use.

Animals with their own minds · pinned by a test

Shared: water wicking faster through salt

Touch a wet brush to a salty glue line

The colour races along the line and the crust takes it on.

Water in paper · pinned by a test

Shared: wax in the paper

Draw in crayon, then brush a wash or bleach over it

The crayon lines stay clean: wax keeps off the wash and most of the bleach.

Pencil, crayon and paper · pinned by tests

The game keeps paint mixing like paint and layers going darker, and skips the rest

Real colour is a spectrum of light meeting particles that absorb and scatter it. On a child's tablet we keep the part people recognise, that paint mixes like paint and layers go darker, and spend nothing on the rest. These are the trades we made, and what they cost.

In real life. Pigments absorb bands of a spectrum, and mixes depend on the whole spectrum

In the game. Three channels, worked on display values directly

Why that's enough. Cheap, fits a texture, runs on phones. Blue and yellow make green because of how the palette's colours were picked: its blue takes most red, its yellow most blue. Lost: colours that match in one light and not another, and true reflectance.

In real life. Paint scatters light as well as absorbing it Kubelka 1931

In the game. Absorption only. A published pigment-mixing method Sochorová 2021 was considered and ruled out by its licence

Why that's enough. One number per channel, and both mixing laws are a single add or average. Lost: white is weak. Black and white stirred half and half come out about 0.28 grey, where a screen average gives 0.525. White crayon can't lighten a dark wash.

In real life. Glazes multiply exactly

In the game. Each channel creeps up to a ceiling set by the colour itself

Why that's enough. Dabs stay true and never turn to mud. Thin glazes still nearly multiply; two washes built all the way up end at the darker of the two ceilings in each channel, not at their sum.

In real life. How inks separate depends on the dyes, the solvent and the paper

In the game. Three tuned speeds per ink

Why that's enough. The rings must show. Not predictive. In the released game every marker uses black's speeds, so a yellow marker's yellow dye hardly runs.

In real life. Pigment is grains of many sizes

In the game. A share of the water's flow that grows with wetness

Why that's enough. Gives the coffee-ring rim. No particle sizes; granulation appears only in saved pictures.

In real life. Cabbage colour is chemistry

In the game. A chart of 8 hand-picked shades, in the order published charts give

Why that's enough. Reads clearly and can't go stale. No kinetics, no history: acid gone means pink gone.

In real life. Each dye fades at its own rate in light

In the game. Three factors per channel; next update one lightfastness per medium

Why that's enough. Readable: reds and yellows go first, blues last. That tendency is coded for every dye, and any cover counts as full shade, which gives crisp sun prints.

In real life. A stain moves colour from the liquid into the fibres

In the game. The paper gains colour; the goop doesn't lose any

Why that's enough. Cheap: nothing has to be booked between the two layers. So stains copy, and with the tide mark and iron-gall ink they're among the few places colour is made.