Skip to content

Commit 9f55628

Browse files
ap0ughtcmayfield
andauthored
docs: add open-source Countdown Engine SOA architecture
Adds the platform-neutral Countdown engine service-oriented architecture docs (from open-source-countdown-engine-soa.zip): SOA design, protocol, data models, round plugin API, decisions, roadmap, test strategy, and contributing template. Supports reuse of the Countdown engine outside the CYD firmware (desktop, mobile, web, test). Co-authored-by: Christopher Mayfield <cmayfield@users.noreply.github.com>
1 parent e04ef59 commit 9f55628

10 files changed

Lines changed: 1264 additions & 0 deletions

File tree

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Contributing
2+
3+
Thank you for contributing to the Countdown Engine.
4+
5+
## Before submitting changes
6+
7+
- add or update tests
8+
- keep platform code outside the core engine
9+
- preserve deterministic behavior
10+
- document new commands and events
11+
- version snapshot schema changes
12+
- avoid official television branding and copyrighted media
13+
14+
## Pull requests
15+
16+
A pull request should include:
17+
18+
- problem statement
19+
- design summary
20+
- tests
21+
- compatibility impact
22+
- migration notes when schemas change
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Core Data Models
2+
3+
```cpp
4+
struct MatchRules {
5+
std::string scoringPolicyId;
6+
uint32_t thinkingDurationMs;
7+
bool allowHouseRules;
8+
};
9+
10+
struct RoundResult {
11+
RoundId roundId;
12+
std::string roundType;
13+
std::optional<PlayerId> winnerId;
14+
std::map<PlayerId, int> scoreAwards;
15+
bool tie;
16+
};
17+
18+
struct MatchSnapshot {
19+
uint32_t schemaVersion;
20+
MatchState match;
21+
ByteBuffer currentRoundSnapshot;
22+
uint32_t checksum;
23+
};
24+
25+
struct CommandError {
26+
std::string code;
27+
std::string message;
28+
bool retryable;
29+
};
30+
31+
struct CommandResult {
32+
bool accepted;
33+
std::vector<EventEnvelope> events;
34+
std::optional<CommandError> error;
35+
};
36+
```
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Architecture Decisions
2+
3+
## ADR-001: Platform-neutral core
4+
5+
The engine contains no display, touch, network, or storage implementation.
6+
7+
## ADR-002: Command-event model
8+
9+
Clients submit commands. The engine validates them and emits events.
10+
11+
## ADR-003: Round plug-ins
12+
13+
Numbers, Letters, and Conundrum are independent modules behind one shared interface.
14+
15+
## ADR-004: Host-authoritative multiplayer
16+
17+
Only the current host commits authoritative state changes.
18+
19+
## ADR-005: Leader-based host ownership
20+
21+
The score leader becomes host between rounds. Ties retain the current host.
22+
23+
## ADR-006: Injected time and randomness
24+
25+
Clock and random sources are interfaces to support deterministic tests.
26+
27+
## ADR-007: Event replay
28+
29+
Accepted events can reproduce match state and support debugging, recovery, and audit.
30+
31+
## ADR-008: Separate content licensing
32+
33+
Conundrum word-and-hint packs may use a license separate from the engine.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# License Recommendation
2+
3+
Recommended engine license:
4+
5+
**Apache License 2.0**
6+
7+
Why:
8+
9+
- permissive use
10+
- explicit patent grant
11+
- suitable for libraries
12+
- suitable for embedded and commercial integrations
13+
- widely understood by open-source contributors
14+
15+
Content packs, dictionaries, graphics, music, and television-derived assets must be reviewed and licensed independently.
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# Multiplayer Protocol
2+
3+
## Authority model
4+
5+
One peer is authoritative at any time.
6+
7+
The authoritative peer:
8+
9+
- validates commands
10+
- emits events
11+
- assigns sequence numbers
12+
- publishes snapshots
13+
- commits scores
14+
- manages host transfer
15+
16+
## Message families
17+
18+
```text
19+
HELLO
20+
CAPABILITIES
21+
SYNC_REQUEST
22+
SYNC_SNAPSHOT
23+
COMMAND
24+
EVENT
25+
HOST_TRANSFER_PREPARE
26+
HOST_TRANSFER_ACK
27+
HOST_TRANSFER_COMMIT
28+
PING
29+
PONG
30+
ERROR
31+
```
32+
33+
## Required envelope fields
34+
35+
```text
36+
protocolVersion
37+
engineVersion
38+
matchId
39+
roundId
40+
senderPlayerId
41+
hostPlayerId
42+
hostTerm
43+
sequenceNumber
44+
messageType
45+
payload
46+
checksum
47+
```
48+
49+
## Duplicate protection
50+
51+
Commands should include a client-generated command ID.
52+
53+
The host stores recently processed command IDs and returns the original result when a duplicate arrives.
54+
55+
## Recovery
56+
57+
A peer requests a snapshot when:
58+
59+
- it reconnects
60+
- it detects a sequence gap
61+
- it receives a newer host term
62+
- its local checksum differs
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Open-Source Countdown Engine
2+
3+
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.
4+
5+
This package defines the architecture, contracts, data models, plug-in system, synchronization model, and implementation roadmap for a reusable Countdown engine.
6+
7+
The engine is intentionally separate from any specific user interface or hardware platform.
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Roadmap
2+
3+
## Phase 1 — Engine foundation
4+
5+
- core types
6+
- commands and events
7+
- reducer pattern
8+
- deterministic random and time
9+
- serialization
10+
11+
## Phase 2 — Round modules
12+
13+
- Numbers
14+
- Letters
15+
- Conundrum
16+
17+
## Phase 3 — Match and multiplayer
18+
19+
- scoring
20+
- chooser flow
21+
- snapshots
22+
- authoritative host
23+
- leader-based host migration
24+
25+
## Phase 4 — Reference clients
26+
27+
- terminal client
28+
- desktop debug client
29+
- CYD client
30+
31+
## Phase 5 — Open-source readiness
32+
33+
- Apache-2.0 license
34+
- contribution guide
35+
- code of conduct
36+
- CI matrix
37+
- API docs
38+
- sample content
39+
- first stable release
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# Round Plug-in API
2+
3+
## Required interface
4+
5+
Every round plug-in must provide:
6+
7+
- unique type ID
8+
- version
9+
- initial-state factory
10+
- command handler
11+
- event reducer
12+
- snapshot serializer
13+
- result producer
14+
- completion flag
15+
16+
```cpp
17+
struct RoundDescriptor {
18+
std::string typeId;
19+
std::string version;
20+
std::string minimumEngineVersion;
21+
};
22+
23+
class IRoundPlugin {
24+
public:
25+
virtual ~IRoundPlugin() = default;
26+
27+
virtual RoundDescriptor descriptor() const = 0;
28+
virtual RoundState create(
29+
const RoundConfig& config,
30+
IRandomSource& random
31+
) const = 0;
32+
33+
virtual CommandResult handle(
34+
const RoundState& state,
35+
const RoundCommand& command,
36+
const CommandContext& context
37+
) const = 0;
38+
39+
virtual RoundState reduce(
40+
const RoundState& state,
41+
const RoundEvent& event
42+
) const = 0;
43+
44+
virtual RoundResult result(
45+
const RoundState& state
46+
) const = 0;
47+
};
48+
```
49+
50+
## Plug-in rules
51+
52+
A plug-in must not:
53+
54+
- draw UI
55+
- access hardware directly
56+
- call the system clock directly
57+
- access networking directly
58+
- mutate match totals directly
59+
- bypass command validation

0 commit comments

Comments
 (0)