OneLiteFeatherNET / OneLiteFeatherNET/Voyager

feat(scoring): pool-based map point distribution for cosmetic currency

Open
#180 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

enhancement gameplay
Dominant language
Java
Stars
0
Forks
0
Avg merge
2d 21h
Merged PRs (30d)
12

Description

Description

The game designer has specified a new scoring model to replace (or augment) the time-bracket system introduced in Epic #168. Rather than awarding fixed bracket points per tier, a per-map point pool is distributed among all players who completed the map in that session, proportional to each player's finish time relative to a reference time.

This model decouples competitive performance feedback (medal tiers) from cosmetic currency reward, and makes the currency feel dynamic — the pool is finite and shared.

Mechanic Specification

Reference Time
  • Primary source: all-time fastest completion of the map, stored in map_records table (requires V4 migration).
  • Fallback (no record exists): fastest finisher of the current session becomes the reference for that session's pool distribution only. The record is then written to map_records so future sessions have a persistent reference.
Point Pool
  • Each map carries a fixed point pool (exact size and configurability TBD — see open questions).
  • At map-end, the pool is split among all players who completed the map in that session.
  • Distribution is proportional to performance vs the reference time: finishing at or faster than the reference time yields a larger share; finishing slower yields a smaller share.
  • The total distributed across all players must not exceed the pool (no inflation).
Currency
  • Points awarded by this system are a cosmetic currency used to purchase cosmetic items.
  • The currency name is TBD (see open questions).
  • This is distinct from any competitive leaderboard metric.
No-Completion Case
  • Players who did not complete the map receive no pool share.
  • DNF handling follows #170.

Open Questions (must be resolved before implementation)

  • Pool size: Fixed value (e.g. 1000 per map)? Configurable per map in MapDefinition? Or formula-based (e.g. base * number_of_rings)?
  • Split formula: Weighted proportional (each player's weight = referenceTime / playerTime)? Threshold-based buckets? Something else?
  • Slow-finisher floor: Do players finishing slower than the reference time always receive a reduced but non-zero share, or can the share reach 0 for extreme outliers?
  • Currency name: What is the cosmetic currency called in-game?
  • Medal tier coexistence: Does this pool system replace the DIAMOND/GOLD/SILVER/BRONZE bracket tiers (Epic #168) entirely, or do medal tiers continue as a separate performance feedback layer while the pool drives currency rewards?
  • Record write-back: Is the session-fastest written to map_records only when it beats the existing record, or always (first-time insert)?
  • Multi-map cups: Is the pool distributed per map or aggregated across the full cup?

Acceptance Criteria

  • MapDefinition has a configurable point pool value (exact type and default TBD per open questions above)
  • map_records table stores the all-time fastest completion per map; referenced at distribution time
  • PoolScoringStrategy (or equivalent) implements ScoringStrategy from the ADR-0007 sealed hierarchy introduced in PR #178
  • Pool distribution formula is unit-tested for: all players equal time, one player significantly faster, one player at exactly reference time, fallback (no pre-existing record)
  • Session-fastest is written to map_records when no prior record exists (and optionally when beaten)
  • Cosmetic currency amount is recorded on GameResultEntity and persisted
  • All open questions above are answered and reflected in updated MapDefinition + ADR
  • Existing bracket medal tiers (DIAMOND/GOLD/SILVER/BRONZE) either remain for feedback-only purposes or are explicitly removed — decision documented in ADR
  • ArchUnit tests still pass (no cross-module boundary violations)
  • Flyway migration adds map_records table (V4) and any new currency column(s) on game_results

Technical Details

  • The ScoringStrategy sealed interface (introduced in PR #178) is the correct extension point. Add a PoolScoringStrategy permit.
  • Distribution math runs in applyMapResults() after all finish times for a session are known.
  • The reference-time lookup must be async-safe (DB read at map-start or cached at session-start).
  • Component: ScoreComponent may need a cosmeticCurrencyEarned field (Java record, compact constructor validation).
  • Follow the ManisGame enum DSL pattern if a distribution-tier enum is introduced.

Dependencies

  • #168 — Zeit-Bracket scoring epic (active, PR #178 in review); ScoringStrategy sealed hierarchy and ScoreComponent fields originate here
  • map_records table — V4 Flyway migration (does not yet exist; blocks reference-time lookup)
  • #177 — Flyway migration infrastructure (merged before V4 migration can land)
  • #170 — DNF handling (determines which players are eligible for pool share)

Estimate

L

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with ADR-0007, the sealed ScoringStrategy hierarchy from PR #178, and the ScoreComponent and MapDefinition types. Trace applyMapResults(), the existing game-results persistence, and Flyway migration infrastructure before resolving the listed scoring and currency questions. Done means a documented decision in the ADR, V4 schema changes, persisted currency, unit tests for the specified cases, and passing ArchUnit tests.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, sql
Domain
backend, database, testing
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Needs clarification
Newbie friendliness
20/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.