Files
weirsoe-party-protocol/docs/ISSUE-312-LOBBY-FUPOGFAKTA-EXTRACTION-MAP.md

12 KiB
Raw Permalink Blame History

Issue #312 — FupOgFakta extraction map for logic currently living in lobby/

Parent: #311
Issue: #312

Purpose

This artifact documents the concrete FupOgFakta-specific logic that still lives in lobby/, separates it from true platform/session concerns, and names the intended destination ownership before any larger code move happens.

It is intentionally an inventory + extraction plan only. It does not perform the full move.

Architectural boundary this map is enforcing

The target boundary is already described in:

  • docs/plans/2026-03-09-fupogfakta-game-engine-design.md
  • docs/plans/2026-03-09-fupogfakta-implementation-plan.md
  • docs/ARCHITECTURE.md

Those docs consistently describe:

  • lobby/ as the platform layer for session lifecycle, player presence, host ownership, generic game-run orchestration, and transport-facing platform concerns.
  • fupogfakta/ as the game cartridge that owns question selection rules, round config semantics, lie/guess/reveal/scoreboard flow, answer mixing, scoring, and game-specific response/event payloads.

In other words:

  • Platform (lobby/) should know that a session exists and that a game can be started/observed.
  • Cartridge (fupogfakta/) should know what a lie is, what a guess is, how answers are mixed, when phases advance, and what payload shape those game phases expose.

Summary split

Generic platform/session concerns that belong in lobby/

These are not FupOgFakta-specific and should remain platform-owned:

  • Session code parsing/generation:
    • lobby/views.py::_generate_session_code
    • lobby/views.py::_normalize_session_code
    • lobby/views.py::_create_unique_session_code
  • Generic request parsing:
    • lobby/views.py::_json_body
  • Session lifecycle and player presence endpoints:
    • lobby/views.py::create_session
    • lobby/views.py::join_session
    • lobby/views.py::session_detail only for the generic session/player shell part
  • Generic ownership / host authorization checks
  • Generic session detail payload fields:
    • session.code
    • session.status
    • session.host_id
    • session.current_round
    • session.players_count
    • players[].id|nickname|score|is_connected
  • Generic i18n/error transport helper usage:
    • lobby/i18n.py
    • api_error(...)
  • Route mounting / namespace ownership in lobby/urls.py for platform routes only

FupOgFakta-specific logic currently misplaced in lobby/

These items are game-cartridge logic and should move behind fupogfakta/ ownership:

  • Round question selection by category and previously-used questions
  • Lie-phase payload construction and lie timer semantics
  • Mixed-answer preparation for bluff gameplay
  • Guess correctness / fooled-player detection
  • Bluff/correct-answer score resolution
  • Reveal payload construction
  • Reveal → scoreboard promotion rules
  • Start round / mix answers / submit lie / submit guess / calculate scores / reveal scoreboard / next round / finish game gameplay endpoints
  • Phase view-model booleans that encode FupOgFakta rules rather than generic platform readiness

Extraction map

Source file Current function / concern Why it is FupOgFakta-specific Intended destination / owner
lobby/views.py _build_player_ref(player) Helper is only used to shape FupOgFakta reveal payloads; not a generic platform concern today. fupogfakta/serializers.py or fupogfakta/payloads.py owned by cartridge.
lobby/views.py _build_reveal_payload(round_question) Encodes FupOgFakta reveal contract: lies, guesses, fooled-player refs, correct answer, prompt. fupogfakta/payloads.py::build_reveal_payload or equivalent cartridge response builder.
lobby/views.py _build_leaderboard(session) Current implementation is generic-ish, but used exclusively by FupOgFakta scoreboard/finish flow and coupled to that response shape. Short term: keep shared helper if multiple games will consume same contract; otherwise move to fupogfakta/payloads.py until a true shared scoreboard contract exists.
lobby/views.py _get_current_round_question(session) Depends on FupOgFakta RoundQuestion model and current-round semantics. fupogfakta/services/rounds.py or fupogfakta/queries.py.
lobby/views.py _select_round_question(session, round_config) Implements FupOgFakta question selection rules by category, active questions, and not-yet-used question set. fupogfakta/services/rounds.py::select_round_question.
lobby/views.py _build_lie_started_payload(session, round_config, round_question) Builds a FupOgFakta event/response contract for lie phase, including category, prompt, lie deadline, round question id. fupogfakta/payloads.py::build_lie_started_payload.
lobby/views.py _prepare_mixed_answers(round_question) Bluff-answer dedupe and shuffle is core FupOgFakta gameplay logic. fupogfakta/services/answers.py::prepare_mixed_answers.
lobby/views.py _resolve_scores(session, round_question, round_config) Applies FupOgFakta scoring rules for correct guesses and successful bluffs; depends on Guess, LieAnswer, ScoreEvent, points_correct, points_bluff. fupogfakta/services/scoring.py::resolve_scores.
lobby/views.py _maybe_promote_reveal_to_scoreboard(session) Encodes FupOgFakta reveal completion semantics and scoreboard transition trigger. fupogfakta/services/phases.py::maybe_promote_reveal_to_scoreboard.
lobby/views.py _build_phase_view_model(session, players_count, has_round_question) Most booleans are not platform-generic; they encode FupOgFakta phase names (lie, guess, scoreboard) and MVP constraints (3-5 players, round-question readiness, next-round/finish gating). Split: keep platform-shell fields in lobby/; move game-specific readiness/action flags to fupogfakta/payloads.py::build_phase_view_model or cartridge driver payload builder.
lobby/views.py start_round(request, code) Starts FupOgFakta round, binds category, creates RoundConfig, selects RoundQuestion, transitions to LIE, broadcasts phase.lie_started. fupogfakta/views.py or cartridge command handler behind a future GameDriver.on_game_start / round bootstrap service.
lobby/views.py show_question(request, code) Emits lie-phase question payload using FupOgFakta RoundQuestion and RoundConfig. fupogfakta/views.py or remove entirely once canonical driver flow owns the transition.
lobby/views.py submit_lie(request, code, round_question_id) Pure FupOgFakta gameplay endpoint: lie validation, deadline semantics, auto-advance to guess phase, phase.guess_started payload. fupogfakta/views.py::submit_lie (or cartridge intent handler).
lobby/views.py mix_answers(request, code, round_question_id) Manual FupOgFakta host action for lie→guess transition and answer mixing. fupogfakta/views.py short term; long term likely deleted in favor of cartridge-driven automatic transition.
lobby/views.py submit_guess(request, code, round_question_id) Pure FupOgFakta gameplay endpoint: validates answer choice, resolves correctness/bluff source, auto-calculates scores, transitions to reveal. fupogfakta/views.py::submit_guess plus fupogfakta/services/scoring.py and fupogfakta/services/phases.py.
lobby/views.py reveal_scoreboard(request, code) FupOgFakta reveal/scoreboard progression, not a generic platform capability. fupogfakta/views.py::reveal_scoreboard or cartridge phase service.
lobby/views.py start_next_round(request, code) FupOgFakta next-round bootstrap: copies prior RoundConfig, increments round, picks next question, re-enters lie phase. fupogfakta/services/rounds.py::start_next_round plus cartridge-owned endpoint/driver integration.
lobby/views.py finish_game(request, code) Current finish path is tied to FupOgFakta scoreboard semantics and winner payload. fupogfakta/views.py::finish_game until a truly generic platform finish contract exists.
lobby/views.py calculate_scores(request, code, round_question_id) Explicit FupOgFakta score resolution endpoint. fupogfakta/services/scoring.py and/or remove when fully absorbed by cartridge phase driver.
lobby/urls.py Gameplay routes for rounds, lies, guesses, scoreboard, finish These route names expose FupOgFakta-specific phase/actions from the platform namespace. Re-home under fupogfakta/urls.py or leave mounted under /lobby/sessions/... only as a temporary façade delegating to cartridge-owned code.
lobby/tests.py StartRoundTests, LieSubmissionTests, MixAnswersTests, GuessSubmissionTests, CanonicalRoundFlowTests, ScoreCalculationTests, RevealRoundFlowTests, SessionDetailRoundQuestionTests, SessionDetailPhaseViewModelTests, SmokeStagingCommandTests These test classes verify FupOgFakta game flow rather than platform mechanics. Move/split into fupogfakta/tests/ with only session creation/join/platform transport tests left in lobby/tests.py.
lobby/management/commands/smoke_staging.py End-to-end gameplay smoke through lies/guesses/finish Script executes one concrete game flow and should be cartridge-aware, not platform-owned. fupogfakta/management/commands/ or a shared smoke harness that delegates into cartridge-specific scenario runners.

Keep in lobby/

  • Session creation/join and session-code lifecycle
  • Generic player membership/presence reads
  • Generic auth/host checks helpers (if extracted from views)
  • Generic API error/i18n plumbing
  • Future GameRun / driver orchestration, timers, and cartridge dispatch
  • A slim generic session_detail envelope that can embed cartridge payloads under a dedicated game key

Move to fupogfakta/

  • Round state queries
  • Question selection
  • Lie/guess/reveal/scoreboard/finish transition rules
  • Score calculation
  • Answer mixing
  • Gameplay payload/response builders
  • Gameplay endpoints and tests
  • Gameplay smoke command

Explicit boundary for session_detail

session_detail is currently mixed.

Generic part that should remain platform-owned

  • Session identity/status metadata
  • Player list / presence list
  • Generic host/player capability envelope if it is game-agnostic

FupOgFakta part that should move or be delegated

  • round_question payload
  • reveal payload
  • scoreboard payload
  • phase_view_model fields keyed to lie, guess, scoreboard, finished, question_ready, and 35-player MVP rules

A clean future shape would be:

{
  "session": {"code": "ABC123", "status": "active", "game_type": "fupogfakta"},
  "players": [...],
  "game": {
    "phase": "lie",
    "payload": {"round_question": {...}, "reveal": null, "scoreboard": null}
  }
}

That makes lobby/ the shell and fupogfakta/ the authority for game-state payloads.

Concrete extraction sequence

  1. Move pure helpers first
    • _get_current_round_question
    • _select_round_question
    • _prepare_mixed_answers
    • _resolve_scores
    • _build_lie_started_payload
    • _build_reveal_payload
  2. Move gameplay endpoints behind cartridge-owned service functions
    • submit_lie
    • submit_guess
    • start_round
    • start_next_round
    • finish_game
    • reveal_scoreboard
    • calculate_scores
  3. Slim session_detail into platform envelope + delegated cartridge payload
  4. Move gameplay tests out of lobby/tests.py
  5. Optionally leave compatibility routes in lobby/urls.py as a façade until clients are rewired

Risks this map is explicitly preventing

  • Moving only models but leaving hidden phase-transition rules in lobby/views.py
  • Treating session_detail as platform-generic while it still leaks cartridge payload semantics
  • Leaving scoreboard/reveal transition logic behind as an undocumented coupling
  • Splitting tests incorrectly so regressions stay "green" in lobby/ while FupOgFakta behavior silently drifts

Decision

For #311 / #312, the repository should treat the following as game-specific and extraction candidates:

  • round-question selection
  • lie/guess/reveal/scoreboard/finish transitions
  • answer mixing
  • score resolution
  • reveal/scoreboard payload builders
  • FupOgFakta-specific session-detail subpayloads
  • gameplay flow tests and smoke command

And it should treat the following as platform-generic:

  • session identity/lifecycle
  • player presence/membership
  • host authorization shell
  • generic error transport
  • future game-driver dispatch/orchestration

That is the explicit lobby vs fupogfakta boundary this issue needs before code extraction proceeds.