Arkanoid On-Chain Game
Transitional example: This example uses an older Cougr pattern and is preserved for compatibility reference. For the current recommended approach, see
snake.
A practical example demonstrating how to use the cougr-core package to implement Arkanoid game logic on the Stellar blockchain via Soroban smart contracts.
Overview
This example showcases:
- ECS Architecture: Component-based design using Cougr-Core patterns
- On-Chain Game Logic: Complete Arkanoid implementation without graphical interface
- Soroban Integration: Smart contract deployment on Stellar blockchain
- Comprehensive Testing: Full test coverage of game mechanics
Game Components
Following the Cougr-Core ECS pattern:
- PaddleComponent: Horizontal paddle position
- BallComponent: Ball position and velocity
- BricksComponent: Grid of breakable bricks (10x5)
- ScoreComponent: Score, lives, and game state
Prerequisites
Required Tools
-
Rust (1.88.0 or later)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh rustup update -
Cargo (comes with Rust)
-
Stellar CLI
cargo install stellar-cli --locked -
WASM Target
rustup target add wasm32v1-none
Verify Installation
rustc --version
cargo --version
stellar --version
Setup
1. Clone Repository
git clone https://github.com/salazarsebas/Cougr.git
cd Cougr/examples/arkanoid
2. Install Dependencies
cargo update
Development
Build
# Standard build
cargo build
# Release build
cargo build --release
# WASM build
cargo build --target wasm32v1-none --release
# Stellar CLI build (recommended for deployment)
stellar contract build
Test
# Run all tests
cargo test
# Run tests with output
cargo test -- --nocapture
# Run specific test
cargo test test_init_game
Lint
# Format code
cargo fmt
# Run clippy
cargo clippy --all-features -- -D warnings
Deployment
1. Setup Testnet Account
Get test XLM from Friendbot:
# Generate a new keypair
stellar keys generate alice --network <NETWORK>
# Fund the account
stellar keys fund alice --network <NETWORK>
Or use the web faucet: https://faucet-stellar.acachete.xyz
2. Deploy Contract
# Build the contract
stellar contract build
# Deploy to testnet
stellar contract deploy \
--wasm target/wasm32v1-none/release/arkanoid.wasm \
--source alice \
--network <NETWORK>
Save the contract ID returned (e.g., <CONTRACT_ID>XXX).
3. Invoke Contract Functions
Initialize Game
stellar contract invoke \
--id <CONTRACT_ID> \
--source alice \
--network <NETWORK> \
-- init_game
Expected Output:
{
"paddle_x": 50,
"ball_x": 50,
"ball_y": 50,
"ball_vx": 1,
"ball_vy": -1,
"score": 0,
"lives": 3,
"game_active": true,
"bricks_remaining": 50
}
Move Paddle
# Move right (direction = 1)
stellar contract invoke \
--id <CONTRACT_ID> \
--source alice \
--network <NETWORK> \
-- move_paddle --direction 1
# Move left (direction = -1)
stellar contract invoke \
--id <CONTRACT_ID> \
--source alice \
--network <NETWORK> \
-- move_paddle --direction -1
Update Game Tick
stellar contract invoke \
--id <CONTRACT_ID> \
--source alice \
--network <NETWORK> \
-- update_tick
This advances the game by one frame:
- Moves the ball
- Checks collisions (walls, paddle, bricks)
- Updates score and lives
- Checks win/loss conditions
Get Game State
stellar contract invoke \
--id <CONTRACT_ID> \
--source alice \
--network <NETWORK> \
-- get_game_state
Check Game Over
stellar contract invoke \
--id <CONTRACT_ID> \
--source alice \
--network <NETWORK> \
-- check_game_over
Returns true if game is over, false otherwise.
Game Flow
- Initialize: Call
init_game()to set up the game state - Play Loop:
- Call
move_paddle(direction)to control the paddle - Call
update_tick()to advance the game - Call
get_game_state()to check current state
- Call
- Game Over: When lives reach 0 or all bricks are broken
Game Mechanics
Constants
- Field: 100x60 units
- Paddle: Width 15, Speed 3
- Ball: Speed 1
- Bricks: 10 columns × 5 rows (50 total)
- Lives: 3
Scoring
- Breaking a brick: +10 points
- Win condition: Break all bricks
- Loss condition: Lives reach 0
Collisions
- Top/Side Walls: Ball bounces
- Bottom Wall: Lose 1 life, ball resets
- Paddle: Ball bounces upward
- Bricks: Brick breaks, ball bounces, score increases
Troubleshooting
Rust Version Issues
rustup update stable
rustup default stable
Dependency Resolution Errors
cargo clean
cargo update
cargo build
WASM Build Failures
Ensure WASM targets are installed:
rustup target add wasm32v1-none
Stellar CLI Not Found
cargo install stellar-cli --locked --force
Network Errors
Use --simulate flag to test without deploying:
stellar contract invoke --id <CONTRACT_ID> --simulate -- init_game
Architecture
Cougr-Core Benefits
This example demonstrates how Cougr-Core simplifies on-chain game development:
- Component Pattern: Modular game data (Paddle, Ball, Bricks, Score)
- System Pattern: Organized logic (Physics, Collision, Scoring systems)
- Scalability: Easy to add features (power-ups, multiple balls)
- Clarity: Clear separation of data and operations
- Reusability: Components can be used across different games
ECS Systems
- PhysicsSystem: Updates ball position based on velocity
- CollisionSystem: Handles wall, paddle, and brick collisions
- ScoringSystem: Manages score, lives, and win/loss conditions
Testing
The test suite covers:
- ✅ Game initialization
- ✅ Paddle movement (left, right, bounds)
- ✅ Ball physics
- ✅ Wall collisions (top, sides, bottom)
- ✅ Paddle collision
- ✅ Brick breaking
- ✅ Scoring
- ✅ Lives system
- ✅ Game over conditions
- ✅ Inactive game state
Run tests with:
cargo test
CI/CD
GitHub Actions workflow automatically:
- Checks code compilation
- Runs formatting checks
- Runs clippy lints
- Executes all tests
- Builds WASM contracts
- Builds with Stellar CLI
License
MIT OR Apache-2.0