Editorial illustration: Finding the Hakem with an ace

Finding the Hakem with an ace

The problem I needed to solve

Hakem selection needs to be visible, but its temporary cards must not become the final dealt hands. I kept this decision separate from the main deal.

Implementation in this snapshot

HokmHakemSelectionService.SelectHakem reveals cards along the seat order and selects the first ace as Hakem. HokmRevealedHakemCard records the revealed cards for presentation.

The design decision and its cost

The result gives the flow layer the selected seat and stage data. That separates finding the ace from animating it, so the animation does not rewrite selection rules.

Current boundaries

The service also reports failure when no ace is found. That matters for invalid data; a DeckDefinition named standard does not itself prove the required ace exists.

Revealing an ace without retaining a temporary hand

SelectHakem first resets the deck and optionally shuffles it through shuffleBeforeSelection. It advances from startingSeatId, recording each card with revealIndex, seat, team and card instance. The interface can display the actual reveal sequence rather than announce a Hakem after an unrelated flourish. Presentation timing is outside this service: the logical call completes selection, and the presentation layer decides how to show the resulting process.

On finding the first Ace, the service copies temporaryRevealedCards into a new list and clears its internal buffer. That snapshot is included in both HakemSelected and the Selected result, so cleanup preserves the presentation data. The cards are not deep-copied: CardInstance entries still refer to the drawn instances. Independence of the list differs from complete independence of every object it contains. That distinction prevents treating a simple copy as a persistence guarantee.

After success, the deck remains at the point following the ace draw; this method does not reset it again for the main deal. Game flow must connect selection and dealing deliberately rather than treat temporary cards as final hands. FailAndClear also retains a snapshot on failure, helping explain invalid data or an absent ace. A deck asset named standard is insufficient: without an actual ace, the loop can consume the deck and return failure.

What this stage taught me

For me, even a small stage needs a clear contract. Its logical result should be valid before presentation, and the presentation should show players that actual process.

Explore Dalo

Latest devlogs

Editorial illustration: Pasur launch and telemetry in the shared structure

Pasur launch and telemetry in the shared structure

Adding Pasur needs both a correct mode handoff and valid public telemetry.

Read article
Editorial illustration: Presenting selection and captures in Pasur

Presenting selection and captures in Pasur

Pasur motion should explain which hand card was played and which table cards were captured.

Read article
Editorial illustration: Pasur bot decisions from capture options

Pasur bot decisions from capture options

My teammate’s Pasur bot chooses among legal options without inspecting hidden opposing cards.

Read article
Dalo