Mash In is a brewday you write down before anything is hot, and then have to live with. You commit to a schedule — the mash rest temperatures and their lengths, the boil, when each hop charge goes in, how cold the fermenter runs — and press RUN. From there the brewhouse is in three dimensions and running on a clock, and your job is to steer it: four buttons, live, while the wort does what the chemistry says it will. It sits on the Beer library because it answers the question that library keeps asking sideways — where in the process does the flavour of a beer actually get decided?
How to play
The planning screen comes first. Pick a beer — a pilsner with nothing to hide behind, a hazy IPA built the opposite way round, a bone-dry saison with a hot, hungry farmhouse strain — and then write the program that gets you there. Each rest is a temperature and a number of minutes. The boil has a length. Every hop charge has a gram weight and a time. The fermenter has a set point. The plan screen predicts your OG, FG, ABV and IBU from those choices, so you can argue with the recipe before you commit to it.
Then you run it, and the plan meets reality. Each stage gives you three controls plus the vessel itself: heat the mash or hold it, raise or lower the hot liquor tank, push the kettle harder or back off, warm the fermenter or crash it. Things go wrong on their own schedule — a stalled mash, a stuck sparge, a hot break climbing the kettle wall toward a boil-over, diacetyl in the sample, a saison strain that quits with sugar still in the beer. Each has a window and a correct answer, and the game tells you which vessel to look at, not what to do. At the end you get a scored comparison of your OG, FG, ABV and bitterness against the style’s targets, with each miss explained.
The chemistry under the clock
The mash is modelled as two enzymes with different tastes in temperature. β-amylase works near 62 °C and makes maltose the yeast can eat; α-amylase runs hotter, liquefies starch far faster, and leaves dextrins yeast cannot touch. Both denature while they work — the hotter the rest, the faster they die — so a ninety-minute rest at 62 °C and a short rest at 68 °C give you genuinely different beers, one thin and dry, the other with body left in it. Skip the mash-out and the bed runs off less cleanly; push sparge water past 80 °C and you pull tannin out of the husks.
The kettle is just as literal. Alpha acid isomerises with boil time and plateaus around sixty minutes, so an early charge gives nearly all the bitterness it will ever give and a flameout charge gives essentially none — while hop oils evaporate, which is why aroma comes only from the last few minutes and the whirlpool. A slack boil isomerises slowly, so every time you knock the foam down to save the batch, it costs you IBU. Boil-off concentrates the wort, so boil length moves your gravity as well as your bitterness. And the ferment cellar runs its own model: temperature sets ester and fusel production, cold makes a lager strain drop out of suspension entirely, and a diacetyl rest only works if you warm the fermenter to 16 °C and hold it.
How it was built
Mash In is hand-written WebGL and JavaScript with no engine. The brewhouse was measured in Blender before it was written in GLSL, which is why the three vessels stand on the bench instead of hovering over it, and why the light finally has somewhere to have come from — you can see where it comes in now. The boil is allowed to be brighter than white, so the bloom over the kettle behaves like steam catching a window. The ferment cellar was added later as its own room on the same renderer, with its own nine numbers to watch.
The commit log keeps one good scar: a post-processing pass that was quietly taking the position attribute with it, which is the sort of bug that makes an entire brewhouse fold up. It has been fixed. The stuck sparge has not.