GAME
GAME (Goals And Motivation Engine) - Gamification framework
Install / Use
/learn @fvergaracl/GAMEREADME
GAME (Goals And Motivation Engine)
<p align="center"> <img src="https://codecov.io/gh/fvergaracl/GAME/branch/main/graph/badge.svg?token=R0MGAOMUBU" alt="Codecov"> <img src="https://img.shields.io/badge/License-Apache_2.0-blue.svg" alt="License Apache 2.0"> <img src="https://img.shields.io/github/stars/fvergaracl/GAME" alt="GitHub Repo stars"> <img src="https://img.shields.io/github/v/tag/fvergaracl/game?color=green" alt="Last tag"> </p> <p align="center"> <img src="GAME_logo.png" alt="GAME Logo"> </p>GAME is an adaptive gamification engine designed to dynamically shape participation, incentives, and behavioral outcomes through programmable scoring strategies. It exposes APIs to manage games, tasks, point assignment, wallets, and strategy-driven scoring behavior.
What problem does GAME solve
Most gamification systems are static: rules and rewards are fixed, producing predictable engagement patterns and often reinforcing participation inequality.
GAME introduces adaptive gamification, enabling:
- Adaptive vs static gamification: scoring rules can react to behavior, context, or system state.
- Behavioral redistribution: incentives can shift participation toward under-engaged users, tasks, or areas.
- Spatial / incentive shaping: strategies can modify rewards dynamically based on distribution, performance, or context.
- Equity / participation optimization: reward structures can balance participation instead of amplifying inequality.
GAME is designed as a programmable incentive engine, not just a points API.
Architecture Overview
Request → Endpoint → Service → Strategy Engine → Repository → Database
Responsibilities
- Endpoints: HTTP interface, validation, authentication, orchestration.
- Services: business logic, transactional behavior, domain rules.
- Strategy Engine (
app/engine/): adaptive scoring logic and behavioral rules. - Repositories: persistence abstraction (SQLModel / SQLAlchemy).
- Database: PostgreSQL storage layer.
This layered design allows pluggable strategies, deterministic services, and reproducible behavior.
Strategy Model (Core Feature)
Strategies define how points and incentives are computed.
Types
- Deterministic strategies: fixed rule-based scoring.
- Adaptive strategies: dynamic scoring based on context, distribution, or system state.
Characteristics
- Strategies live in
app/engine/. - Strategies are pluggable and selected via
strategyId. - A game defines a base strategy, tasks may override it.
- Strategies can use inputs such as:
- task parameters
- historical behavior
- distribution state
- contextual metadata
Adding a new strategy (minimal steps)
- Create a new class in
app/engine/inheriting fromBaseStrategy. - Implement required scoring methods.
- Register strategy in the strategy registry.
- Use its
strategyIdin a game or task.
Integration Pattern
GAME can operate in two modes:
1. Full backend gamification platform
Use GAME as a complete gamification backend:
- manage games
- manage tasks
- assign points
- track wallets
- apply adaptive strategies
2. Scoring microservice
Use GAME only as an incentive / scoring engine:
- external system calls GAME to compute points
- GAME returns scoring outcome
- external system manages application logic
Production Considerations
- Use
ENV=prodwith secure secrets and externalized configuration. - Run Alembic migrations in CI/CD before deployment.
- Enable structured logging for observability.
- Use connection pooling for PostgreSQL.
- GAME is stateless → supports horizontal scaling behind a load balancer.
- Manage secrets via environment variables or secret manager (not
.envin prod).
Failure Modes & Reliability
GAME is designed to behave safely under failure scenarios:
- Idempotent operations where applicable.
- Safe under concurrent requests with transactional DB behavior.
- Supports retry-safe patterns.
- Handles partial failures (service / DB exceptions).
- Authentication failure produces deterministic response (no silent fallback).
- Consistency model: strong within transaction, eventual across distributed calls.
Python Compatibility
- Poetry constraint:
python = "^3.10"(effective range:>=3.10,<4.0) - CI currently runs Python
3.12.3 - Recommended local version: Python 3.12.x
Stack
- Python ≥ 3.10
- FastAPI + Starlette
- SQLModel + SQLAlchemy
- PostgreSQL
- Poetry
- Docker / Docker Compose
- Kubernetes (
kubernetes/) - Keycloak OAuth2 / OpenID Connect
Quick Start (Local)
Prerequisites
- Python + Poetry installed
- PostgreSQL running
- Keycloak (optional, required for protected endpoints)
Clone
git clone https://github.com/fvergaracl/GAME.git
cd GAME
Install
poetry install
Configure
cp .env.sample .env
Minimal .env:
ENV=dev
SECRET_KEY=change-me
DATABASE_URL=postgresql+psycopg2://root:example@localhost:5432/game_dev_db
ALEMBIC_DATABASE_URL=postgresql+psycopg2://root:example@localhost:5432/game_dev_db
KEYCLOAK_URL=http://localhost:8080
KEYCLOAK_REALM=game
KEYCLOAK_CLIENT_ID=game-api
KEYCLOAK_CLIENT_SECRET=change-me
# DB pool tuning (recommended for concurrent load)
SQLALCHEMY_ECHO=false
DB_POOL_PRE_PING=true
DB_POOL_SIZE=20
DB_MAX_OVERFLOW=40
DB_POOL_TIMEOUT_SECONDS=30
DB_POOL_RECYCLE_SECONDS=1800
Migrate DB
poetry run alembic upgrade head
Run API
poetry run uvicorn app.main:app --reload
Docs:
- Swagger → http://localhost:8000/docs
- ReDoc → http://localhost:8000/redocs
Keycloak OAuth (Dev)
Start infra:
docker-compose -f docker-compose-dev.yml up -d postgrespostgres keycloakgame
Run E2E in one command (loads .env, prepares auth when needed, runs pytest):
# Controlled E2E (isolated sqlite, deterministic, no real infra calls)
./scripts/run_e2e.sh
# Controlled + real-infrastructure E2E (real HTTP + PostgreSQL)
./scripts/run_e2e.sh --real
# Use a different env file (for example integrated environment)
./scripts/run_e2e.sh --env-file .env.integrated --real
Manual token/API key flow (optional):
TOKEN=$(curl -s -X POST "$KEYCLOAK_URL/realms/$KEYCLOAK_REALM/protocol/openid-connect/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "client_id=$KEYCLOAK_CLIENT_ID" \
-d "client_secret=$KEYCLOAK_CLIENT_SECRET" \
-d "grant_type=password" \
-d "username=game_admin" \
-d "password=$KEYCLOAK_USER_WITH_ROLE_PASSWORD" | jq -r '.access_token')
Create API key:
API_KEY=$(curl -s -X POST "http://localhost:8000/api/v1/apikey/create" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"client":"local-dev"}' | jq -r '.apiKey')
API Example (End-to-End)
Create game → create task → assign points → read user score.
# Create game
GAME_ID=$(curl -s -X POST "http://localhost:8000/api/v1/games" \
-H "X-API-Key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{"externalGameId":"game-001","platform":"web","strategyId":"default"}' \
| jq -r '.gameId')
# Create task
curl -s -X POST "http://localhost:8000/api/v1/games/$GAME_ID/tasks" \
-H "X-API-Key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{"externalTaskId":"task-login"}'
# Assign points
curl -s -X POST "http://localhost:8000/api/v1/games/$GAME_ID/tasks/task-login/points" \
-H "X-API-Key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{"externalUserId":"user-123"}'
# Read points
curl -s "http://localhost:8000/api/v1/users/user-123/points" \
-H "X-API-Key: $API_KEY"
Docker
docker-compose -f docker-compose-dev.yml up --build
docker-compose -f docker-compose-dev.yml down --remove-orphans
Integrated:
make integrated
make down
Tests & Coverage
poetry run pytest
poetry run pytest --cov=app --cov-branch
Unit tests
# Recommended: one-command unit test runner
./scripts/run_unit_tests.sh
# Stop on first failure
./scripts/run_unit_tests.sh --fail-fast
# Coverage (branch + html report)
./scripts/run_unit_tests.sh --cov --cov-branch --cov-report html
# Run specific unit file
./scripts/run_unit_tests.sh --file tests/unit_tests/services/test_user_points_service.py
# Show all options
./scripts/run_unit_tests.sh --help
E2E tests
# Recommended: one-command E2E runner (loads .env automatically)
./scripts/run_e2e.sh
# Include real-infrastructure E2E (requires API + PostgreSQL + Keycloak running)
./scripts/run_e2e.sh --real
# Same as above, but using .env.integrated
./scripts/run_e2e.sh --env-file .env.integrated --real
# Optional: direct pytest command for controlled E2E only
poetry run pytest tests/e2e -q -m "not e2e_real_http"
# Run a specific E2E test file
poetry run pytest tests/e2e/test_app_smoke_e2e.py -q
# Start E2E tests from a specific SQLite snapshot
poetry run pytest tests/e2e -q --e2e-base-snapshot /absolute/path/to/base_snapshot.sqlite
# Keep generated SQLite files for debugging
poetry run pytest tests/e2e -q --e2e-keep-db
# Run only real-infrastructure E2E for POST /apikey/create
./scripts/run_e2e.sh --real -- tests/e2e/test_apikey_create_flow_e2e.py -q
Load tests (k6)
# Recommended: one-command load runner (loads .env automatically)
./scripts/run_load_test.sh
# Preset: 1000 VUs mode
./scripts/run_load_test.sh --mode 1000
# Custom N VUs + custom scenario mix (A/B/C) + durations
./scripts/run_load_test.sh \
--vus 300 \
--mix-a 60 --mix-b 30 --mix-c 10 \
--warmup 20s --hold 2m --ramp-down 20s
# Use integrated env file
./scripts/run_load_test.sh --env-file .env.integrated --mode 100
# Show all options
./scripts/run_load_test.sh --help
# Pass extra native k6 args after
Related Skills
gh-issues
347.0kFetch GitHub issues, spawn sub-agents to implement fixes and open PRs, then monitor and address PR review comments. Usage: /gh-issues [owner/repo] [--label bug] [--limit 5] [--milestone v1.0] [--assignee @me] [--fork user/repo] [--watch] [--interval 5] [--reviews-only] [--cron] [--dry-run] [--model glm-5] [--notify-channel -1002381931352]
node-connect
347.0kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
oracle
347.0kBest practices for using the oracle CLI (prompt + file bundling, engines, sessions, and file attachment patterns).
taskflow-inbox-triage
347.0kname: taskflow-inbox-triage description: Example TaskFlow authoring pattern for inbox triage. Use when messages need different treatment based on intent, with some routes notifying immediately, some w
