| Crates.io | matchforge |
| lib.rs | matchforge |
| version | 0.1.0 |
| created_at | 2025-11-30 20:04:10.92422+00 |
| updated_at | 2025-11-30 20:04:10.92422+00 |
| description | A plug-and-play matchmaking SDK for multiplayer games |
| homepage | |
| repository | https://github.com/matchforge/matchforge-sdk |
| max_upload_size | |
| id | 1958759 |
| size | 703,939 |
๐ฎ A comprehensive, production-ready matchmaking SDK for multiplayer games with advanced MMR systems, intelligent queue management, real-time analytics, and enterprise-grade security.
Add this to your Cargo.toml:
[dependencies]
matchforge = "0.1.0"
For full features:
[dependencies]
matchforge = { version = "0.1.0", features = ["redis", "postgres", "telemetry", "security"] }
use matchforge::prelude::*;
use std::sync::Arc;
#[tokio::main]
async fn main() -> Result<()> {
// Create persistence layer
let persistence = Arc::new(InMemoryAdapter::new());
// Create managers
let queue_manager = Arc::new(QueueManager::new(persistence.clone()));
let party_manager = Arc::new(PartyManager::new(persistence.clone(), Arc::new(AverageStrategy)));
let lobby_manager = Arc::new(LobbyManager::new(persistence.clone()));
// Configure queues
let queue_config = QueueConfig {
name: "ranked_1v1".to_string(),
format: MatchFormat::one_v_one(),
constraints: MatchConstraints::strict(),
};
queue_manager.register_queue(queue_config).await?;
// Start matchmaking runner
let runner = MatchmakingRunner::new(
RunnerConfig::default(),
queue_manager.clone(),
persistence.clone(),
);
// Add player to queue
let player_id = Uuid::new_v4();
let rating = Rating::default_beginner();
let entry = queue_manager.join_queue_solo(
"ranked_1v1".to_string(),
player_id,
rating,
EntryMetadata::default(),
).await?;
// Start runner in background
tokio::spawn(async move {
if let Err(e) = runner.start().await {
eprintln!("Runner error: {}", e);
}
});
Ok(())
}
MatchForge SDK follows a modular, event-driven architecture designed for scalability and performance:
โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ
โ Game Client โโโโโถโ Queue Manager โโโโโถโ Matchmaking โ
โ โ โ โ โ Runner โ
โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ
โ โ
โผ โผ
โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ
โ Party Manager โ โ Lobby Manager โ
โ โ โ โ
โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ
โ โ
โผ โผ
โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ
โ Persistence โ โ Analytics โ
โ Layer โ โ Engine โ
โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ
โ โ
โผ โผ
โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ
โ Security โ โ Monitoring โ
โ Manager โ โ Service โ
โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ
MatchForge supports multiple rating algorithms:
Choose from multiple persistence backends:
use matchforge::prelude::*;
let persistence = Arc::new(InMemoryAdapter::new());
let queue_manager = Arc::new(QueueManager::new(persistence));
// Register queue
queue_manager.register_queue(QueueConfig {
name: "duel".to_string(),
format: MatchFormat::one_v_one(),
constraints: MatchConstraints::permissive(),
}).await?;
// Add players
let player1 = Uuid::new_v4();
let player2 = Uuid::new_v4();
let rating = Rating::new(1500.0, 300.0, 0.06);
queue_manager.join_queue_solo("duel".to_string(), player1, rating, EntryMetadata::default()).await?;
queue_manager.join_queue_solo("duel".to_string(), player2, rating, EntryMetadata::default()).await?;
// Find matches
let matches = queue_manager.find_matches("duel").await?;
println!("Found {} matches", matches.len());
use matchforge::prelude::*;
// Configure 5v5 queue
let queue_config = QueueConfig {
name: "team_5v5".to_string(),
format: MatchFormat::team_v_team(5),
constraints: MatchConstraints {
max_rating_difference: 200,
max_wait_time: Duration::from_secs(300),
role_requirements: vec![
RoleRequirement { role: "tank".to_string(), required: true },
RoleRequirement { role: "healer".to_string(), required: true },
],
},
};
use matchforge::prelude::*;
let party_manager = Arc::new(PartyManager::new(
persistence.clone(),
Arc::new(AverageStrategy),
));
// Create party
let leader_id = Uuid::new_v4();
let party = party_manager.create_party(leader_id, 4).await?;
// Add members
for _ in 0..3 {
let member_id = Uuid::new_v4();
party_manager.add_member(party.id, member_id).await?;
}
// Join queue as party
queue_manager.join_queue_party("ranked".to_string(), party.id, EntryMetadata::default()).await?;
use matchforge::prelude::*;
// Initialize analytics components
let analytics = Arc::new(AnalyticsMetrics::new(AnalyticsConfig::default()));
let report_generator = Arc::new(ReportGenerator::new(analytics.clone()));
let insight_engine = Arc::new(InsightEngine::new(analytics.clone()));
let dashboard_data = Arc::new(DashboardData::new(
analytics.clone(),
report_generator.clone(),
insight_engine.clone(),
));
// Generate dashboard
let dashboard = dashboard_data.generate_dashboard(None).await?;
println!("Dashboard: {} widgets", dashboard.widgets.len());
// Generate insights
let insights = insight_engine.generate_insights().await?;
for insight in insights {
println!("Insight: {} (Severity: {:?})", insight.title, insight.severity);
}
use matchforge::prelude::*;
// Generate comprehensive reports
let performance_report = report_generator.generate_report(
ReportType::Performance,
None,
ReportFormat::Json,
).await?;
println!("Performance Report: {}", performance_report.title);
println!("Key insights:");
for insight in &performance_report.data.summary.key_insights {
println!(" - {}", insight);
}
// Predictive analytics
let predicted_wait_time = analytics.predict_queue_wait_time("casual_1v1", 1500.0).await;
println!("Predicted wait time: {:.1} seconds", predicted_wait_time.as_secs_f64());
// Business intelligence
let retention = analytics.get_retention_analytics().await;
println!("Day 7 retention: {:.1}%", retention.day_7_retention * 100.0);
println!("Churn rate: {:.1}%", retention.churn_rate * 100.0);
use matchforge::prelude::*;
struct CustomRatingAlgorithm;
#[async_trait]
impl MmrAlgorithm for CustomRatingAlgorithm {
async fn update_ratings(&self, ratings: &[Rating], outcomes: &[Outcome]) -> Vec<Rating> {
// Implement your custom rating logic
ratings.to_vec()
}
}
// Use custom algorithm
let rating_manager = RatingManager::new(
persistence.clone(),
Arc::new(CustomRatingAlgorithm),
Arc::new(LinearDecay::new(1.0, 100.0)),
);
use matchforge::prelude::*;
#[cfg(feature = "redis")]
{
let redis_client = redis::Client::open("redis://localhost").unwrap();
let redis_adapter = Arc::new(RedisAdapter::new(redis_client).await?);
let queue_manager = Arc::new(QueueManager::new(redis_adapter));
}
use matchforge::prelude::*;
let security_config = SecurityConfig {
enable_authentication: true,
enable_authorization: true,
rate_limit_config: Some(RateLimitConfig {
max_requests: 100,
window: Duration::from_secs(60),
penalty_multiplier: 2.0,
max_penalty_duration: Duration::from_secs(300),
}),
anti_abuse_config: Some(AntiAbuseConfig::default()),
};
let security_manager = Arc::new(SecurityManager::new(security_config));
// Process request with security
let request = SecurityRequest {
method: "POST".to_string(),
path: "/api/queues/join".to_string(),
headers: HashMap::from([("Authorization".to_string(), "Bearer token123".to_string())]),
remote_addr: Some("127.0.0.1".to_string()),
user_agent: Some("game-client".to_string()),
};
let context = security_manager.create_context(&request).await?;
QueueConfig {
name: "competitive".to_string(),
format: MatchFormat::one_v_one(),
constraints: MatchConstraints {
max_rating_difference: 150,
max_wait_time: Duration::from_secs(120),
role_requirements: vec![],
},
}
RunnerConfig {
matchmaking_interval: Duration::from_secs(5),
max_matches_per_tick: 50,
lobby_timeout: Duration::from_secs(300),
cleanup_interval: Duration::from_secs(60),
}
AnalyticsConfig {
retention_period: Duration::days(90),
aggregation_interval: Duration::from_hours(1),
max_data_points: 10000,
enable_detailed_tracking: true,
enable_predictive_analytics: true,
}
SecurityConfig {
enable_authentication: true,
enable_authorization: true,
rate_limit_config: Some(RateLimitConfig {
max_requests: 100,
window: Duration::from_secs(60),
penalty_multiplier: 2.0,
max_penalty_duration: Duration::from_secs(300),
}),
anti_abuse_config: Some(AntiAbuseConfig {
max_abuse_score: 100.0,
ban_threshold: 50.0,
decay_rate: 0.1,
}),
}
MonitoringConfig {
metrics_interval: Duration::from_secs(10),
metrics_retention: Duration::from_hours(24),
alert_thresholds: AlertThresholds {
max_average_wait_time: 30000,
min_success_rate: 0.8,
max_error_rate: 0.05,
max_queue_size: 1000,
min_health_score: 70.0,
},
health_checks: HealthCheckConfig::default(),
}
# Run all tests
cargo test
# Run with specific features
cargo test --features "redis,postgres"
# Run integration tests only
cargo test --test integration
# Run with backtrace
RUST_BACKTRACE=1 cargo test
# Run all benchmarks
cargo bench
# Run specific benchmark
cargo bench -- matchmaking_benchmarks
# Generate benchmark report
cargo bench -- --output-format html
# Basic matchmaking example
cargo run --example basic
# Analytics dashboard example
cargo run --example analytics_dashboard
# Advanced analytics example
cargo run --example advanced_analytics
MatchForge is optimized for high-performance matchmaking with enterprise-grade scalability:
| Operation | Throughput | Latency (p50) | Latency (p99) | Memory Usage |
|---|---|---|---|---|
| Queue Join | 10,000 ops/sec | 0.1ms | 0.5ms | 50MB |
| Match Finding | 1,000 ops/sec | 1ms | 5ms | 100MB |
| Rating Update | 5,000 ops/sec | 0.2ms | 1ms | 75MB |
| Redis Read | 50,000 ops/sec | 0.05ms | 0.2ms | 25MB |
| Redis Write | 25,000 ops/sec | 0.1ms | 0.3ms | 30MB |
| Analytics Query | 500 ops/sec | 2ms | 10ms | 200MB |
let swiss_matcher = SwissMatcher::new(100.0, true);
let pairings = swiss_matcher.find_pairings(&entries, &scores, &previous_matchups);
let tournament_matcher = TournamentMatcher::new(
TournamentType::SingleElimination,
SeedingStrategy::ByRating,
);
let bracket = tournament_matcher.generate_bracket(entries, MatchFormat::one_v_one());
let adaptive_matcher = AdaptiveMatcher::new(
base_constraints,
max_wait_time,
expansion_factor,
);
// Predict queue overflow
let predicted_time = analytics.predict_queue_overflow_time("casual_queue").await;
// Predict player churn
let churn_risk = analytics.predict_player_churn_risk(player_id).await;
// Predict match quality
let quality_score = analytics.predict_match_quality(&match_candidates).await;
// Revenue analytics
let revenue_report = analytics.generate_revenue_report(time_range).await;
// Player segmentation
let segments = analytics.segment_players_by_behavior().await;
// LTV calculations
let ltv = analytics.calculate_player_lifetime_value(player_id).await;
FROM rust:1.70 as builder
WORKDIR /app
COPY . .
RUN cargo build --release
FROM debian:bookworm-slim
RUN apt-get update && apt-get install -y ca-certificates
COPY --from=builder /app/target/release/matchforge /usr/local/bin/
EXPOSE 8080
CMD ["matchforge"]
apiVersion: apps/v1
kind: Deployment
metadata:
name: matchforge
spec:
replicas: 3
selector:
matchLabels:
app: matchforge
template:
metadata:
labels:
app: matchforge
spec:
containers:
- name: matchforge
image: matchforge:latest
ports:
- containerPort: 8080
env:
- name: REDIS_URL
value: "redis://redis:6379"
- name: DATABASE_URL
value: "postgresql://user:pass@postgres:5432/matchforge"
# Prometheus + Grafana monitoring
apiVersion: v1
kind: ConfigMap
metadata:
name: matchforge-config
data:
prometheus.yml: |
scrape_configs:
- job_name: 'matchforge'
static_configs:
- targets: ['matchforge:8080']
We welcome contributions! Please see our Contributing Guide for details.
# Clone the repository
git clone https://github.com/your-org/matchforge-sdk
cd matchforge-sdk
# Install dependencies
cargo build
# Run tests
cargo test
# Run linting
cargo fmt
cargo clippy -- -D warnings
# Run examples
cargo run --example basic
This project uses rustfmt and clippy for code formatting and linting:
# Format code
cargo fmt
# Run linter
cargo clippy -- -D warnings
# Run all checks
cargo fmt && cargo clippy && cargo test
Please report bugs using the GitHub Issue Tracker with:
Feature requests are welcome! Please provide:
This project is licensed under the MIT License - see the LICENSE file for details.
| Feature | Description | Default | Status |
|---|---|---|---|
redis |
Redis persistence support | Optional | โ Stable |
postgres |
PostgreSQL persistence support | Optional | โ Stable |
telemetry |
Advanced telemetry features | Enabled | โ Stable |
security |
Security and anti-abuse features | Enabled | โ Stable |
analytics |
Advanced analytics and ML insights | Enabled | โ Stable |
wasm |
WebAssembly support | Optional | ๐ง In Progress |
graphql |
GraphQL API endpoints | Optional | ๐ Planned |
Click to watch our comprehensive getting started tutorial
๐ฎ MatchForge SDK - Building the future of multiplayer gaming matchmaking