Default Reward Presenter

defaultPresenter handles the reveal + collect phases for most reward batches. It runs the standard card flow: card spawn into #fx-floating → flip animation with igniteBloom + spawnBurst → punch settle on tap → fly-to-target (wallet counter or progress bar) with flyToTargetpulseTarget on landing and counter settle via displayOverride release.

Cards are staggered ~50ms apart during reveal so a batch reads as a sequence rather than a simultaneous pop.

Strategy pattern

Reward presentation uses a strategy pattern so the orchestrator stays free of if (source === 'pull') branches. RewardPresenter exposes two optional methods:

  • presentReveal(batch) — resolves when reveal animations are done (cards shown, bursts fired).
  • presentCollect(batch) — resolves when all fly-to animations and counter settles are done.

Either method may be absent — the orchestrator skips that phase. Presenters never advance the phase themselves; the orchestrator owns lifecycle.

Presenter selection

getPresenter(batch) resolves the right strategy from the batch’s PresentationHints:

  • revealMode: 'default' / collectMode: 'default'defaultPresenter.
  • revealMode: 'custom' / collectMode: 'custom' → source-specific presenter (currently only pullPresenter when batch.source === 'pull').
  • revealMode: 'none' / collectMode: 'none' → orchestrator skips the phase entirely.

pullPresenter is a pass-through: the pull engine owns its own reveal + collect lifecycle and runs its animations externally. The reward pipeline still uses the batch for counter and progress tracking, but doesn’t drive the visuals. This is acknowledged transitional debt — long-term the pull-engine reveal will be extracted into a proper presenter adapter alongside defaultPresenter.

Implementation status

Both presentReveal and presentCollect on defaultPresenter are currently stubbed — they resolve immediately. The orchestrator already calls them; the visual sequence (card spawn → flip → burst → fly-to-target → counter settle) is wired in once the FX layer is ready.

Source

  • src/starship-survivors/services/reward-presenters.tsRewardPresenter interface, defaultPresenter, pullPresenter, getPresenter().