Skip to content
Pipfold

On a phone, every tap counted twice

· game · tooling

Till, on a phone: “when I roll an 11 (5+6) the flaps will not go down — nothing happens; on rolls like 5 (3+2) the 5 shuts fine.”

That sounds like a rules bug. Eleven is a sum of two flaps, five is a single one — if combinations do not work and single flaps do, then something is wrong with the check that permits combinations.

The wrong trail

So the rules core got looked at first. There was nothing there:

They were green because they call waehle_klappe() directly — that is, below the input layer. And on a computer nothing was ever broken. The bug existed only where no test was looking: in the input chain of a touch device.

The cause

project.godot has input_devices/pointing/emulate_mouse_from_touch set to true. Godot sends an additional mouse event for every touch. Spielbrett._auf_vp_input handled both kinds. So _tippe() ran twice per tap — and _toggle_klappe is a toggle.

One tap on flap 5 mouse · device = −1 the emulation touch · device = 0 the real tap selects the 5 deselects it again Selection afterwards: [ ] — empty, no error, no flicker
Two events per tap, a toggle in between. They cancel each other and exactly nothing is left — no error state, no message, no trace in the log.

Why it went unnoticed for so long

On a phone it only showed up on combinations, and that disguised it:

A single matching flap shuts on the first pass already — that is the one-tap rule. The phase jumps to WAIT_ROLL, and the second pass runs into nothing. So whoever rolled a 5 got through. Whoever rolled an 11 needed 5+6 — and never got through.

That asymmetry reads like a rule. “Combinations do not work” is a plausible statement about a game; “every second tap gets undone” is not something you arrive at from the outside.

The bug was only proven once a real InputEventScreenTouch ran through the input chain and what arrived was measured:

mouse(device=-1)   ← the emulation, selects flap 5
touch(device=0)    ← the real tap, deselects it immediately

Fixed

In scripts/spielbrett.gd the emulation is filtered out: mb.device == InputEvent.DEVICE_ID_EMULATION.

Rejected: “only handle mouse”. That would have been shorter and would have hung silently off a project setting — whoever switched emulate_mouse_from_touch off would have had a game with no controls at all. A fix that depends on a setting unrelated to it is a trap for the next person.

The guard

tools/pruefe_ui.gd_ein_tipp_zaehlt_einmal(). It reproduces exactly the broken situation — a roll of 11 with flaps 1–9, so no matching single flap — and pushes both events through the handler in the order a phone delivers them.

Cross-checked: with the fix removed from the game code it reports Fingertipp zählt doppelt: … steht [].

What follows from this for others

The same pattern sits in the shared mana toolkit and has not been touched there: mana_tisch_3d.gd:215, mana_bottom_bar.gd:118, builder_camera.gd:150 also handle mouse and touch. Pipfold uses none of them — whoever does probably has the same bug.

That belongs checked once at the toolkit and not fixed here in passing. A toolkit shared by six projects is the wrong place for a change you happen to need urgently in one of them.

And the real lesson: test runs that start below the input layer test the game — not playing it. Between waehle_klappe() and a finger on glass lies a chain nobody had tested, because it does not exist on a development machine.

← Devlog