High-level overview of how Cougr is organized. For usage, see README.md.
┌──────────────────────────────────────────────────────────────┐
│ game::SorobanGame (contract integration) │ Contract layer
├──────────────────────────────────────────────────────────────┤
│ app::GameApp │ Default runtime surface
├───────────┬───────────────┬──────────────────────────────────┤
│ ECS │ Accounts │ Standards │ ZK Proofs │
├───────────┴───────────────┴─────────────────┴────────────────┤
│ soroban-sdk 25.1.0 (no_std, WASM) │
└──────────────────────────────────────────────────────────────┘
game::SorobanGame (src/game.rs) bridges the ECS and Soroban contract models.
The SorobanGame trait provides load_world and save_world as default methods,
eliminating repetitive storage-key boilerplate from contract entrypoints. Wire up
once with impl_soroban_game!(MyContract, "key").
The companion helpers SimpleWorld::load_from_instance and save_to_instance
are the underlying primitives when you want finer control.
GameApp (src/plugin/mod.rs) is the default onboarding layer for complex
games. It owns a SimpleWorld, the scheduler, plugin registration, and runtime
resources in one place.
Two storage backends, same ComponentTrait interface:
| Backend | File | Strategy | Best for |
|---|---|---|---|
| SimpleWorld | src/simple_world/ |
Map<(EntityId, Symbol), Bytes> with dual Table/Sparse indexes |
General use, small entity counts |
| ArchetypeWorld | src/archetype_world/ |
Groups entities by component signature | Large entity counts, batch queries |
Both support typed access (get_typed<T>, set_typed<T>) and raw access (get_component, add_component).
Supporting systems:
- Query cache (
src/query/) — version-tagged, invalidates on world mutation - Hooks (
src/hooks.rs) — callbacks on component add/remove - Observers (
src/observers.rs) — event-driven reactions - Commands (
src/commands.rs) — deferred mutations during system execution - Scheduler (
src/scheduler/) — stage-based, dependency-aware system ordering - Change tracker (
src/change_tracker.rs) — per-component dirty flags - Plugins (
src/plugin/) — modular game logic bundles - Incremental storage (
src/incremental/) — only persist dirty entities
Three macros cover every component case:
| Macro | When to use |
|---|---|
impl_component! |
Fixed-size primitives (i32, u32, u64, u128, u8, bool, bytes32) |
impl_component_observed! |
Same as above, plus structured Soroban events on every set |
impl_rich_component! |
Complex types via XDR codec: Address, Vec, String, Option, nested structs |
impl_rich_component! requires #[contracttype] on the struct. The XDR serialisation is handled entirely by the Soroban SDK — no manual serialize/deserialize implementation is needed.
Rich components are stored in Soroban instance storage (not the ECS Map) but share the same entity ID space.
All ZK operations use Stellar Protocol 25 (X-Ray) host functions — the heavy crypto runs on the host, not in WASM.
- Groth16 (
groth16.rs) — proof verification via BN254 pairing - BLS12-381 (
bls12_381.rs) — G1 add/mul/MSM, pairing checks - Poseidon2 (
crypto.rs) — ZK-friendly hashing, behindhazmat-cryptofeature - Merkle trees (
merkle/) — SHA256 and Poseidon variants, sparse trees, on-chain proofs - Pedersen (
commitment.rs) — commitment scheme for hidden state - Game circuits (
circuits.rs,traits.rs) —GameCircuittrait + pre-built circuits (Movement, Combat, Inventory, TurnSequence) +CustomCircuitBuilder - ECS integration (
components.rs,systems.rs) —CommitReveal,HiddenState,ProofSubmissioncomponents with verification systems
Account abstraction layer with pluggable implementations:
CougrAccount (trait)
├── ClassicAccount — standard Stellar keypair
└── ContractAccount — smart contract wallet
├── SessionStorage — persistent session keys
├── RecoveryStorage — guardian-based recovery
├── DeviceStorage — multi-device key management
└── Secp256r1Storage — WebAuthn/Passkey keys
Key traits: CougrAccount, SessionKeyProvider, RecoveryProvider, MultiDeviceProvider.
SessionBuilder provides a fluent API for constructing scoped session keys. authorize_with_fallback handles graceful degradation from session keys to direct authorization.
Reusable contract standards for integrations that need explicit operational controls:
OwnableandOwnable2Stepfor owner-managed authorityAccessControlfor role-based authorization with delegated adminsPausablefor emergency stopsExecutionGuardfor serialized critical sectionsRecoveryGuardfor blocking sensitive paths during recovery windowsBatchExecutorfor bounded multi-operation flowsDelayedExecutionPolicyfor time-delayed operation queues
Each standard instance is keyed by a caller-supplied Symbol, which keeps storage deterministic and avoids collisions when a contract composes multiple modules.
Three layers ship inside the single cougr-core crate. Implementation lives in
src/{circuits,session,test}/; internal/cougr-core-* workspace members use
stubs for isolated cargo check -p runs.
| Public module | Source | Maturity | Feature |
|---|---|---|---|
cougr_core::circuits |
src/circuits/ |
Experimental | always |
cougr_core::session |
src/session/ |
Beta | always |
cougr_core::test |
src/test/ |
Beta | testutils |
Circuit builders: hidden_cards, fog_of_war, fair_dice, sealed_bid →
GameCircuitSpec. Examples: hidden_hand, fog_explorer, dice_duel,
blind_auction. See ADR 0006.
The test sandbox uses no_std + alloc with Soroban testutils — not std.
Enable with cougr-core feature testutils. Modules: GameHarness, Scenario,
WorldFixture, ReplayLog, SnapshotAssert. See ADR 0007.
| Flag | Enables |
|---|---|
hazmat-crypto |
Poseidon2 hash, BN254 curve ops (via soroban-sdk/hazmat-crypto) |
testutils |
cougr_core::test sandbox, MockAccount, Soroban test helpers |
debug |
Runtime introspection, metrics, state snapshots (src/debug/) |
Release builds are configured with LTO, opt-level = "z", and overflow-checks = true to keep artifacts optimized for constrained execution environments.
Primary target: wasm32v1-none.