Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions docs/countdown-engine-soa/CONTRIBUTING_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Contributing

Thank you for contributing to the Countdown Engine.

## Before submitting changes

- add or update tests
- keep platform code outside the core engine
- preserve deterministic behavior
- document new commands and events
- version snapshot schema changes
- avoid official television branding and copyrighted media

## Pull requests

A pull request should include:

- problem statement
- design summary
- tests
- compatibility impact
- migration notes when schemas change
36 changes: 36 additions & 0 deletions docs/countdown-engine-soa/DATA_MODELS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Core Data Models

```cpp
struct MatchRules {
std::string scoringPolicyId;
uint32_t thinkingDurationMs;
bool allowHouseRules;
};

struct RoundResult {
RoundId roundId;
std::string roundType;
std::optional<PlayerId> winnerId;
std::map<PlayerId, int> scoreAwards;
bool tie;
};

struct MatchSnapshot {
uint32_t schemaVersion;
MatchState match;
ByteBuffer currentRoundSnapshot;
uint32_t checksum;
};

struct CommandError {
std::string code;
std::string message;
bool retryable;
};

struct CommandResult {
bool accepted;
std::vector<EventEnvelope> events;
std::optional<CommandError> error;
};
```
33 changes: 33 additions & 0 deletions docs/countdown-engine-soa/DECISIONS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Architecture Decisions

## ADR-001: Platform-neutral core

The engine contains no display, touch, network, or storage implementation.

## ADR-002: Command-event model

Clients submit commands. The engine validates them and emits events.

## ADR-003: Round plug-ins

Numbers, Letters, and Conundrum are independent modules behind one shared interface.

## ADR-004: Host-authoritative multiplayer

Only the current host commits authoritative state changes.

## ADR-005: Leader-based host ownership

The score leader becomes host between rounds. Ties retain the current host.

## ADR-006: Injected time and randomness

Clock and random sources are interfaces to support deterministic tests.

## ADR-007: Event replay

Accepted events can reproduce match state and support debugging, recovery, and audit.

## ADR-008: Separate content licensing

Conundrum word-and-hint packs may use a license separate from the engine.
15 changes: 15 additions & 0 deletions docs/countdown-engine-soa/LICENSE_RECOMMENDATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# License Recommendation

Recommended engine license:

**Apache License 2.0**

Why:

- permissive use
- explicit patent grant
- suitable for libraries
- suitable for embedded and commercial integrations
- widely understood by open-source contributors

Content packs, dictionaries, graphics, music, and television-derived assets must be reviewed and licensed independently.
62 changes: 62 additions & 0 deletions docs/countdown-engine-soa/PROTOCOL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Multiplayer Protocol

## Authority model

One peer is authoritative at any time.

The authoritative peer:

- validates commands
- emits events
- assigns sequence numbers
- publishes snapshots
- commits scores
- manages host transfer

## Message families

```text
HELLO
CAPABILITIES
SYNC_REQUEST
SYNC_SNAPSHOT
COMMAND
EVENT
HOST_TRANSFER_PREPARE
HOST_TRANSFER_ACK
HOST_TRANSFER_COMMIT
PING
PONG
ERROR
```

## Required envelope fields

```text
protocolVersion
engineVersion
matchId
roundId
senderPlayerId
hostPlayerId
hostTerm
sequenceNumber
messageType
payload
checksum
```

## Duplicate protection

Commands should include a client-generated command ID.

The host stores recently processed command IDs and returns the original result when a duplicate arrives.

## Recovery

A peer requests a snapshot when:

- it reconnects
- it detects a sequence gap
- it receives a newer host term
- its local checksum differs
7 changes: 7 additions & 0 deletions docs/countdown-engine-soa/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Open-Source Countdown Engine

A platform-neutral, open-source game engine for building Countdown-style games across embedded devices, desktop applications, mobile apps, web clients, and automated test environments.

This package defines the architecture, contracts, data models, plug-in system, synchronization model, and implementation roadmap for a reusable Countdown engine.

The engine is intentionally separate from any specific user interface or hardware platform.
39 changes: 39 additions & 0 deletions docs/countdown-engine-soa/ROADMAP.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Roadmap

## Phase 1 — Engine foundation

- core types
- commands and events
- reducer pattern
- deterministic random and time
- serialization

## Phase 2 — Round modules

- Numbers
- Letters
- Conundrum

## Phase 3 — Match and multiplayer

- scoring
- chooser flow
- snapshots
- authoritative host
- leader-based host migration

## Phase 4 — Reference clients

- terminal client
- desktop debug client
- CYD client

## Phase 5 — Open-source readiness

- Apache-2.0 license
- contribution guide
- code of conduct
- CI matrix
- API docs
- sample content
- first stable release
59 changes: 59 additions & 0 deletions docs/countdown-engine-soa/ROUND_PLUGIN_API.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Round Plug-in API

## Required interface

Every round plug-in must provide:

- unique type ID
- version
- initial-state factory
- command handler
- event reducer
- snapshot serializer
- result producer
- completion flag
Comment on lines +7 to +14

```cpp
struct RoundDescriptor {
std::string typeId;
std::string version;
std::string minimumEngineVersion;
};

class IRoundPlugin {
public:
virtual ~IRoundPlugin() = default;

virtual RoundDescriptor descriptor() const = 0;
virtual RoundState create(
const RoundConfig& config,
IRandomSource& random
) const = 0;

virtual CommandResult handle(
const RoundState& state,
const RoundCommand& command,
const CommandContext& context
) const = 0;

virtual RoundState reduce(
const RoundState& state,
const RoundEvent& event
) const = 0;

virtual RoundResult result(
const RoundState& state
) const = 0;
};
```

## Plug-in rules

A plug-in must not:

- draw UI
- access hardware directly
- call the system clock directly
- access networking directly
- mutate match totals directly
- bypass command validation
Loading
Loading