Skip to content

Add Gameplay bounded context model#140

Merged
bartul merged 1 commit into
masterfrom
gameplay-bc-model
May 27, 2026
Merged

Add Gameplay bounded context model#140
bartul merged 1 commit into
masterfrom
gameplay-bc-model

Conversation

@bartul

@bartul bartul commented May 27, 2026

Copy link
Copy Markdown
Owner

Part of #51.

Summary

  • Add the Gameplay bounded context interface model and compiling stubs.
  • Split Gameplay into Types, Commands, Events, State, Dependencies, and facade files.
  • Move Gameplay contract DTOs into Contract/Gameplay.fs and remove the old shared Contract.fs placeholder.
  • Add docs/gameplay.md with the event-modeling flow for game start orchestration.
  • Update AGENTS.md to reflect the new structure.

Notes

This is the first PR in the Gameplay initiative. Follow-up PRs should add behavior specs, handler implementation, and terminal host wiring.

Verification

  • dotnet fantomas .
  • dotnet build Imperium.slnx
  • dotnet test
  • dotnet run --no-build --project tests/Imperium.UnitTests/Imperium.UnitTests.fsproj -- --render-spec-markdown

Summary by CodeRabbit

  • New Features

    • Introduced Gameplay module infrastructure for managing game initialization, state tracking, and setup completion
    • Established integration with Rondel system for game positioning workflows
  • Documentation

    • Added comprehensive Gameplay module documentation with lifecycle flows and integration details
    • Updated repository guidelines with current architecture organization and module responsibilities

Review Change Stack

@coderabbitai

coderabbitai Bot commented May 27, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

This PR establishes the Gameplay bounded context by introducing contract types for cross-context messaging, core domain types (GameId, NationId, PlayerIds, PlayerRoster), game state model (GameStatus, GameplayState), command and event message shapes with contract transformations, dependency injection infrastructure, and public facade entry points (currently stubbed).

Changes

Gameplay Bounded Context Implementation

Layer / File(s) Summary
Contract definitions for cross-context communication
src/Imperium/Contract/Gameplay.fs
New Gameplay contract module defines StartGameCommand (GameId, Nations, PlayerIds), GameplayCommand union, and GameplayEvent with SetupCompleted for inter-context boundaries.
Domain identity and value types
src/Imperium/Gameplay/Types.fs, src/Imperium/Gameplay/Types.fsi
GameId, PlayerId, and NationId (six canonical nations) as private wrappers and discriminated unions with create/value/toString/tryParse helpers; PlayerRoster as private wrapper over PlayerId list with stubbed create and value accessors.
Game status and state model
src/Imperium/Gameplay/State.fs, src/Imperium/Gameplay/State.fsi
GameStatus (InSetup, InPlay) and GameInitialization (RondelStartingPositions) discriminated unions; GameplayState record holding game identity, nations, roster, lifecycle status, and completed initializations.
Command messaging: inbound and outbound
src/Imperium/Gameplay/Commands.fs, src/Imperium/Gameplay/Commands.fsi
GameplayCommand with StartGame case and contract-to-domain fromContract transformation (stubbed); GameplayOutboundCommand with SetRondelToStartingPositions case and domain-to-Rondel-contract toContract transformation (stubbed).
Event messaging: integration and inbound
src/Imperium/Gameplay/Events.fs, src/Imperium/Gameplay/Events.fsi
GameplayEvent with SetupCompleted case and toContract transformation (stubbed); GameplayInboundEvent with RondelPositionedAtStart case and fromContract transformation from Rondel contract (stubbed).
Dependency injection and handler facade
src/Imperium/Gameplay/Dependencies.fs, src/Imperium/Gameplay/Dependencies.fsi, src/Imperium/Gameplay/Gameplay.fs, src/Imperium/Gameplay/Gameplay.fsi
LoadGameplayState and CommitGameplayEffects function types; GameplayEffects record bundling state, events, and commands; GameplayDependencies record wiring load/commit; Gameplay public facade with execute and handle entry points (both unimplemented stubs).
Documentation and project configuration
AGENTS.md, docs/gameplay.md, src/Imperium/Imperium.fsproj
AGENTS.md updated with current module organization, contract/domain API details, and Gameplay facade stub status; new docs/gameplay.md with full Gameplay event model, lifecycle diagrams, and design notes; project file updated to include new Gameplay and Contract source files.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

Poem

🐰 A rabbit hops through bounded lines,
New commands and events align,
GameId, NationId with grace so fine,
The Gameplay context starts to shine!
Stubs await their test-driven rhyme. 🎮

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Add Gameplay bounded context model' accurately summarizes the primary change—introducing the Gameplay bounded context with its type definitions, command/event contracts, state models, and facade interfaces.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch gameplay-bc-model

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (1)
src/Imperium/Gameplay/Dependencies.fs (1)

9-18: ⚡ Quick win

Add XML docs to the new public dependency/effect types in the implementation file.

These public declarations are currently undocumented in .fs. Add /// comments so the implementation file meets the repository doc standard consistently.

As per coding guidelines, src/Imperium/**/*.{fs,fsi} must “Use XML documentation comments (///) for all public types and functions.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/Imperium/Gameplay/Dependencies.fs` around lines 9 - 18, Add XML
documentation comments (///) above the public declarations LoadGameplayState,
GameplayEffects, CommitGameplayEffects, and GameplayDependencies describing
their purpose and parameters/fields: document that LoadGameplayState is a
function taking a GameId and returning Async<GameplayState option>; describe
each field on GameplayEffects (State, IntegrationEvents, OutboundCommands) and
their meanings; document CommitGameplayEffects as an async function that commits
GameplayEffects; and document GameplayDependencies as a record containing Load
and Commit. Keep comments concise and follow the repository's XML doc style.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/Imperium/Gameplay/Commands.fs`:
- Around line 15-16: The fromContract function currently throws with failwith
which converts contract conversion failures into exceptions; change it to return
a Result<StartGameCommand, string> instead by replacing failwith with a
Result.Error carrying a descriptive error string (or use Result.Ok when
conversion succeeds). Locate the fromContract function in the Gameplay.Commands
module and implement conversion logic that validates
Contract.Gameplay.StartGameCommand fields and returns Result.Ok <constructed
StartGameCommand> on success or Result.Error "<reason>" on any validation/parse
failure so all failures stay in the Result channel.

In `@src/Imperium/Gameplay/Events.fs`:
- Around line 26-27: The function fromContract (accepting
Contract.Rondel.PositionedAtStart) must not throw; replace the failwith with a
Result.Error returning an appropriate error string (e.g., "fromContract:
unhandled Contract.Rondel.PositionedAtStart" or include relevant contract data)
so the signature Result<RondelPositionedAtStartInboundEvent, string> is honored;
ensure you construct and return Ok with a RondelPositionedAtStartInboundEvent
when valid transformations are implemented or return Error with a descriptive
message otherwise.

In `@src/Imperium/Gameplay/Gameplay.fs`:
- Around line 10-12: The implementations of Gameplay.execute and Gameplay.handle
currently call failwith which throws immediately; instead return an Async
workflow that completes (or will raise inside the async if needed). Replace the
synchronous throws in the functions named execute and handle in module Gameplay
with async workflows (e.g. async { return () } as a placeholder) so both
functions have type Async<unit> and do not throw at call time.

In `@src/Imperium/Gameplay/Types.fs`:
- Line 79: PlayerRoster.create currently calls failwith even though its
signature is Result<PlayerRoster, string>; replace the exception with a
Result-returning implementation: for now return Error with a descriptive string
(e.g., "PlayerRoster.create not implemented") instead of throwing, or implement
the real creation logic to return Ok<PlayerRoster> on success and Error<string>
on failure; ensure the function signature (let create (_ids: Id list) :
Result<PlayerRoster, string>) is honored and use PlayerRoster.create as the
location to change.

---

Nitpick comments:
In `@src/Imperium/Gameplay/Dependencies.fs`:
- Around line 9-18: Add XML documentation comments (///) above the public
declarations LoadGameplayState, GameplayEffects, CommitGameplayEffects, and
GameplayDependencies describing their purpose and parameters/fields: document
that LoadGameplayState is a function taking a GameId and returning
Async<GameplayState option>; describe each field on GameplayEffects (State,
IntegrationEvents, OutboundCommands) and their meanings; document
CommitGameplayEffects as an async function that commits GameplayEffects; and
document GameplayDependencies as a record containing Load and Commit. Keep
comments concise and follow the repository's XML doc style.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: eac0b17d-bc88-4b8d-a338-a000a5da68a1

📥 Commits

Reviewing files that changed from the base of the PR and between 8abb4e8 and 7f38773.

📒 Files selected for processing (17)
  • AGENTS.md
  • docs/gameplay.md
  • src/Imperium/Contract/Contract.fs
  • src/Imperium/Contract/Gameplay.fs
  • src/Imperium/Gameplay/Commands.fs
  • src/Imperium/Gameplay/Commands.fsi
  • src/Imperium/Gameplay/Dependencies.fs
  • src/Imperium/Gameplay/Dependencies.fsi
  • src/Imperium/Gameplay/Events.fs
  • src/Imperium/Gameplay/Events.fsi
  • src/Imperium/Gameplay/Gameplay.fs
  • src/Imperium/Gameplay/Gameplay.fsi
  • src/Imperium/Gameplay/State.fs
  • src/Imperium/Gameplay/State.fsi
  • src/Imperium/Gameplay/Types.fs
  • src/Imperium/Gameplay/Types.fsi
  • src/Imperium/Imperium.fsproj
💤 Files with no reviewable changes (1)
  • src/Imperium/Contract/Contract.fs

Comment thread src/Imperium/Gameplay/Commands.fs
Comment thread src/Imperium/Gameplay/Events.fs
Comment thread src/Imperium/Gameplay/Gameplay.fs
Comment thread src/Imperium/Gameplay/Types.fs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant