Skip to content
Pipfold

Nobody saw the confetti for half a year

· game · design

A shut box is the only event this game knows. There are no points to collect, no levels, no progression — just nine flaps that are down at the end or are not. Until this day that exact moment was the weakest spot in the whole game: one tap too many, an invisible effect, a borrowed sound.

The box waited at the moment of victory

You confirm combinations with a tap on the dice. That is right as long as you could still correct yourself. On the last move you cannot — it clears the box, there is nothing left to weigh up.

So at the moment of victory the box stood there with two upright, golden flaps, waiting for a confirmation whose only alternative was doing nothing.

KlappenRegeln.ist_schlusszug() now decides that in the core: valid and covers the last open flaps. The board executes it immediately — as a combination too, and under “plus and minus” with two target numbers.

And then I went looking for the confetti

_ende_konfetti() was in the code: twelve ColorRects falling across the box. Written some time in spring. I won a round to have a look at it and saw nothing. Second round, third time. Nothing.

It was broken three ways:

  1. The rectangles hung off _ende_overlay — and _ergebnis_spaeter() sets that very overlay invisible on the following line, showing it only 2.4 seconds later. The tweens ran for 1.5 seconds and cleaned themselves up. All of it behind an invisible parent node.
  2. The overlay is a VBoxContainer. That overrides any position you set — the rectangles would have ended up where the container puts them, not where they were meant to go.
  3. The maths was done against the full screen size. The overlay is a narrow strip along the bottom edge.

Any one of these three would have been enough. Together they survived half a year — because an effect you cannot see is indistinguishable from a modest effect. Nobody ever thought “something is missing”. You think “ah, subtle”.

Not repaired — deleted without replacement. Confetti are foreign coloured rectangles falling across a picture of wood. They have nothing to do with this game; they would be interchangeable. Every game has confetti.

The celebration is now the box itself

Kasten3D.siegwelle() raises every flap in turn by 42° and lets it fall back into the wood — a wave from the 1 to the highest flap, which turns there and runs back. Eighteen strikes, about 1.9 seconds.

turn · the melody starts here 123 456 789 987 654 321 outward — building up return — full, and louder
Bar height is the lift. The outward leg starts at 55 % and reaches full height at the last flap; the return runs at full height throughout and strikes louder. The wave comes back heavier than it went out.

No new geometry, no foreign rectangles over the picture: the same hinges and the same motion as shutting a flap, only bigger and in sequence.

Ingredient already there for now also does
flap hinges shutting, selection, hint the wave out and back
fall tween with impact one falling flap eighteen, in time
KlappenKlang.holz() the strike on a move a scale up and back down
the synth in klang.gd flap and dice a third voice: the marimba bar

Nothing in the image is new except the order. In the sound a single voice was added, and it is made the same way as the strike, only with pitch: a marimba bar, partials 1 : 3.9 : 10.4. All ten notes are one synthesised bar shifted by pitch_scale — which shortens the high notes by itself and length the bass under the final note.

The strikes of the wave run a major pentatonic upwards ahead of it: the flaps are the run-up, the first note is the landing. It starts at the turning point, and the return leg drums along underneath. Because the return takes the same flaps backwards, the scale falls again by itself — an arc, not a slide.

Under “reduced motion” the box stays still and the strikes still come. The rhythm is the celebration, not the wiggling.

How often this happens at all

Before it was decided how big the celebration could be, it had to be settled how rare it is. 20,000 simulated rounds per setup, played with the strategy the hint uses:

Setup win ≤ 2 points median
1–9 · 2 dice 6.8 % (1 in 14) 12 % 10
1–10 · 2 dice 3.9 % (1 in 25) 6 % 16
1–12 · 3 dice 6.2 % (1 in 16) 10 % 12
1–12 · 2 dice 0.37 % (1 in 270) 0.6 % 35

Due roughly every fourteen rounds. Rare enough for something big, frequent enough that it must not get in the way. That is why the celebration lasts two seconds and not five. Without this table it would have stayed a matter of taste.

The checks were deliberately made to fail

All three new guarantees were broken before they were allowed to stand: rule reverted → “final move did not fall by itself”; siegwelle() gutted → “0 strikes instead of 18”; lift turned down to 0.4° → “flaps barely rose”.

Two subtleties came out of that:

That is the lesson, and it is uncomfortably general: a guard that measures against its own target value checks nothing. It is always green, even when the target is zero.

The touchstone for any further idea here is therefore not “does that look good?” but “could the object do that?”

← Devlog