Releases: Far-Beyond-Dev/Horizon
Release v0.42.4
Update Cargo.toml
Release v0.42.3
Release
Release v0.42.2
Update Cargo.toml
Release v0.42.1
What's Changed
- Pass uuid to instace.register_object and type_name of GorcObject mus… by @ddurieux in #297
- Bump Versions by @tristanpoland in #298
New Contributors
Breaking changes
- Must update plugins to
horizon_event_system0.23.0
Full Changelog: v0.42.0...v0.42.1
Release v0.42.0
Update Cargo.toml
Release v0.41.0
🌌 Horizon Game Server — Release v0.41.0
🚀 Overview
This release represents a significant refactor and improvement to Horizon’s core logic and event system, including major internal restructuring, spatial optimization, and test coverage expansion.
🧩 Major Changes
Core Architecture
-
Refactored the Horizon main logic:
-
Split the application into separate
lib.rsandmain.rsmodules for improved modularity and testability. -
Core initialization and runtime logic now reside in
lib.rs. -
CLI startup and configuration handling remain in
main.rs.
-
-
This prepares the server for easier embedding, library usage, and custom binaries.
Cargo & Versioning
-
Updated Cargo.toml files across multiple crates to align dependencies and metadata.
-
Bumped version to
0.41.0.
⚙️ GORC (Game Object Region Controller) System
Spatial Tracking & Distance Filtering
-
Fixed and improved GORC spatial tracking and distance filtering logic.
-
Events now correctly respect player-to-object propagation distances.
-
Reduced unnecessary updates for distant entities.
-
Resolved issues where movement handlers produced stale positions or incorrect distance calculations.
-
Runtime Stability
-
Fixed runtime issues in GORC related to entity updates under high event density.
-
Improved performance when large numbers of entities enter or leave event zones.
🧪 Testing Enhancements
Regression and Integration Tests
-
Added distance filtering regression tests to validate movement and event propagation accuracy.
-
Expanded integration test suite to cover realistic movement and zone-based event emission.
-
Introduced new realistic_movement_test.rs and zone_event_test.rs for simulation-level verification.
-
Modularized test layout (
tests/mod.rs) for improved maintainability.
🧍 Player Plugin Updates
-
Fixed issues in
plugin_player/src/handlers/movement.rscausing incorrect motion updates. -
Improved precision and synchronization with GORC’s new filtering logic.
🧠 Internal Improvements
-
Emitters system updated to align with refined GORC event flow.
-
Simplified several internal APIs for event emission and propagation.
-
Refactor core logic into lib.rs and main.rs
-
Add distance filtering regression tests
-
Improve GORC spatial tracking
-
Fix GORC runtime issues
-
Bump to version 0.41.0
🧾 Commit Highlights
Release v0.40.0
Horizon v0.40.0 Release Notes
Overview
Horizon v0.40.0 represents a complete architectural evolution, delivering both foundational type-safety improvements and advanced performance optimizations. This release replaces string-based replication with compile-time validated systems while introducing zone virtualization and fixing critical event system gaps.
Type-Safe GORC System
New Type-Based Architecture
The GORC system now uses compile-time validated data structures instead of runtime string matching:
// Define zone data structures
#[derive(Clone, Debug, Serialize, Deserialize)]
struct PlayerCriticalData {
pub position: Vec3,
pub health: f32,
}
impl GorcZoneData for PlayerCriticalData {
fn zone_type_name() -> &'static str { "PlayerCriticalData" }
}
// Define main object with typed zones
#[derive(Clone, Debug, Serialize, Deserialize)]
struct GorcPlayer {
pub critical_data: PlayerCriticalData, // Zone 0
pub detailed_data: PlayerDetailedData, // Zone 1
}
// Implement with explicit zone mapping
impl_gorc_object! {
GorcPlayer {
0 => critical_data: PlayerCriticalData,
1 => detailed_data: PlayerDetailedData,
}
}Secure Client-Server Communication
New gorc_client: event category creates security boundaries between untrusted client input and server state:
events.on_gorc_client(
luminal_handle,
"Asteroid",
3,
"mine",
|event: GorcEvent, client_player: PlayerId, connection: ClientConnectionRef, instance: &mut ObjectInstance| {
if !connection.is_authenticated() {
return Err(EventError::HandlerExecution("Not authenticated".to_string()));
}
// Process validated mining action
Ok(())
}
).await?;Zone Event System Fixes
Complete Event Coverage
Resolved Issues:
- Missing zone entry events for existing players when objects spawn nearby
- Missing zone events when objects move toward stationary players
- Inconsistent event delivery causing desynchronization
New Automatic Behaviors:
// Object creation triggers automatic zone notifications
let object_id = gorc_instances.register_object(new_object, position).await;
// Existing players automatically receive zone entry events
// Object movement generates events for stationary players
events.update_object_position(object_id, new_position).await?;
// Affected players receive zone entry/exit events
// Enhanced player movement maintains compatibility
events.update_player_position(player_id, new_position).await?;Performance Improvements
Spatial Indexing Optimization
Algorithmic Enhancement:
- Before: O(n) linear search through all objects
- After: O(log n) quadtree-based proximity queries
Measured Performance Gains:
Object Count | Old Time (ms) | New Time (ms) | Improvement
-------------|---------------|---------------|------------
100 | 2.1 | 0.3 | 7x faster
500 | 12.4 | 0.6 | 20x faster
1000 | 28.7 | 0.9 | 32x faster
2000 | 67.3 | 1.2 | 56x faster
Zone Check Optimization
Inner zone optimization reduces redundant calculations:
- 75% reduction in zone checks for multi-zone objects
- Smart spatial queries using adaptive radius sizing
- Hysteresis implementation prevents zone boundary oscillation
Architecture Redesign
// Previous implementation
spatial_index: Arc<RwLock<HashMap<GorcObjectId, Vec3>>>
// Current implementation
spatial_index: Arc<RwLock<SpatialPartition>>
object_positions: Arc<RwLock<HashMap<GorcObjectId, Vec3>>>
zone_size_warnings: Arc<RwLock<HashMap<GorcObjectId, f64>>>
virtualization_manager: Arc<VirtualizationManager>Zone Virtualization System
Automatic High-Density Optimization
Zone virtualization merges overlapping zones in crowded areas to reduce spatial indexing load:
[gorc.virtualization]
enabled = true
density_threshold = 0.3 # Merge threshold
overlap_threshold = 0.3 # Minimum overlap required
max_virtual_zone_radius = 1000.0
check_interval_ms = 1000
max_objects_per_virtual_zone = 20Dynamic Zone Management
Merge Operations:
- Automatic detection of overlapping zones exceeding density thresholds
- Optimal bounding circle calculation for merged zones
- Event-driven merge notifications
Split Operations:
- Object movement tracking for split detection
- Automatic virtual zone decomposition when objects separate
- Performance-based splitting when zones exceed size limits
Edge Case Handling
Comprehensive testing covers virtualization edge cases:
- Rapid merge-split cycles during dynamic scenarios
- Boundary condition management for overlapping zones
- Concurrent operation support under heavy load
- Configuration validation for extreme parameter values
Runtime System Migration
Luminal Async Runtime
Migration from tokio::runtime::Handle to luminal::Handle resolves cross-DLL async conflicts:
// Previous approach
let tokio_handle = context.tokio_handle();
tokio_handle.spawn(async move { ... });
// Current approach
let luminal_handle = context.luminal_handle();
luminal_handle.spawn(async move { ... });This change ensures stable plugin architecture across dynamic library boundaries.
Hierarchical Event Routing
New PathRouter treats event keys as hierarchical paths:
- O(log n) handler lookups instead of linear scans
- Efficient similarity searches for debugging missing handlers
- Improved developer experience during handler registration
Configuration System
Comprehensive GORC Settings
Production-ready configuration with full validation:
[gorc.general]
max_objects = 10000
max_players = 1000
max_channels_per_object = 8
auto_optimize_zones = true
optimization_interval_ms = 5000
debug_logging = false
[gorc.spatial]
world_bounds = [-10000.0, -10000.0, -1000.0, 10000.0, 10000.0, 1000.0]
max_quadtree_depth = 10
max_objects_per_node = 8
enable_caching = true
cache_expiry_ms = 30000
[gorc.network]
max_batch_size = 1000
channel_frequencies = [60.0, 30.0, 15.0, 5.0]
enable_compression = true
compression_threshold = 1024
network_timeout_ms = 5000
[gorc.monitoring]
enable_stats = true
stats_interval_ms = 10000
enable_profiling = false
track_memory_usage = true
slow_operation_threshold_us = 1000Configuration Presets
Built-in presets for deployment scenarios:
- High Performance: 50K objects, 5K players, aggressive virtualization
- Development: Extensive debugging, profiling enabled
- Low Resource: Optimized for constrained environments
- Testing: Minimal overhead, virtualization disabled
Player Plugin Redesign
Modular Handler Architecture
Complete replacement of gorc_example_plugin with production-ready plugin_player:
impl SimplePlugin for PlayerPlugin {
async fn register_handlers(&mut self, events: Arc<EventSystem>, context: Arc<dyn ServerContext>) -> Result<(), PluginError> {
let luminal_handle = context.luminal_handle();
// Core lifecycle management
self.register_connection_handlers(Arc::clone(&events), context.clone(), luminal_handle.clone()).await?;
// Real-time gameplay handlers
self.register_movement_handler(Arc::clone(&events), luminal_handle.clone()).await?;
self.register_combat_handler(Arc::clone(&events), luminal_handle.clone()).await?;
self.register_communication_handler(Arc::clone(&events), luminal_handle.clone()).await?;
self.register_scanning_handler(Arc::clone(&events), luminal_handle).await?;
Ok(())
}
}Enhanced Event Handlers
Movement Handler:
events.on_gorc_client(
luminal_handle,
"GorcPlayer",
0, // Critical channel
"move",
move |gorc_event, client_player, connection, object_instance| {
// Security validation
if !connection.is_authenticated() {
return Err(EventError::HandlerExecution("Unauthenticated request".to_string()));
}
// Process movement with automatic replication
object_instance.object.update_position(new_position);
Ok(())
}
).await?;Combat Handler:
events.on_gorc_client(
luminal_handle,
"GorcPlayer",
1, // Combat channel
"attack",
move |gorc_event, client_player, connection, object_instance| {
// Validate weapon authorization
if attack_data.player_id != client_player {
return Err(EventError::HandlerExecution("Unauthorized weapon fire".to_string()));
}
// Broadcast to nearby players
Ok(())
}
).await?;Credits
- @tristanpoland - GORC virtualization system, zone event fixes, configuration system
- @haywoodspartan - Type-safe GORC architecture, security model implementation
- @a-catgirl-dev - Player plugin redesign, testing infrastructure
- @Tuafo - Spatial indexing overhaul
- @DoctorWhoFR - Testing, documentation, sample project
Release v0.40.0-rc2
🚀 Horizon v0.40.0-rc2
🎯 Overview
Horizon v0.40.0-rc2 marks an overhaul of the event and replication system, introducing a robust, type-safe GORC architecture and a new production-ready player plugin. This release fundamentally enhances security, performance, and developer experience by replacing string-based replication with a compile-time-validated, type-driven system. Key changes include a new secure gorc_client: event category for client-to-server communication and a switch to the luminal async runtime to ensure stability for cross-DLL plugin execution.
✨ Major Features
📦 New Player Plugin (plugin_player)
A new, modular plugin_player has been introduced, replacing the old gorc_example_plugin. It serves as the new standard for player management and demonstrates the best practices of the new GORC architecture. It features a clean separation of concerns with dedicated handlers for connection, movement, combat, communication, and scanning.
Modular Handler Registration in plugin_player:
// In plugin_player/src/lib.rs
impl SimplePlugin for PlayerPlugin {
async fn register_handlers(&mut self, events: Arc<EventSystem>, context: Arc<dyn ServerContext>) -> Result<(), PluginError> {
let luminal_handle = context.luminal_handle();
// Register core server event handlers for player lifecycle management
self.register_connection_handlers(Arc::clone(&events), luminal_handle.clone()).await?;
// Register GORC client event handlers for real-time gameplay
self.register_movement_handler(Arc::clone(&events), luminal_handle.clone()).await?;
self.register_combat_handler(Arc::clone(&events), luminal_handle.clone()).await?;
self.register_communication_handler(Arc::clone(&events), luminal_handle.clone()).await?;
self.register_scanning_handler(Arc::clone(&events), luminal_handle).await?;
Ok(())
}
}🔒 Type-Safe GORC Replication System
The GORC system has been completely redesigned to be type-safe, eliminating runtime string matching for properties. This improves performance, prevents typos, and provides compile-time validation. Game objects are now defined with explicit data structs for each replication zone.
New GorcZoneData Trait and impl_gorc_object! Macro:
// 1. Define zone data structures
#[derive(Clone, Debug, Serialize, Deserialize)]
struct PlayerCriticalData {
pub position: Vec3,
pub health: f32,
}
impl GorcZoneData for PlayerCriticalData {
fn zone_type_name() -> &'static str { "PlayerCriticalData" }
}
#[derive(Clone, Debug, Serialize, Deserialize)]
struct PlayerDetailedData {
pub level: u32,
}
impl GorcZoneData for PlayerDetailedData {
fn zone_type_name() -> &'static str { "PlayerDetailedData" }
}
// 2. Define the main object with typed zones
#[derive(Clone, Debug, Serialize, Deserialize)]
struct GorcPlayer {
pub critical_data: PlayerCriticalData, // Zone 0
pub detailed_data: PlayerDetailedData, // Zone 1
}
// 3. Implement type-based GorcObject
impl_gorc_object! {
GorcPlayer {
0 => critical_data: PlayerCriticalData, // Explicit zone assignment
1 => detailed_data: PlayerDetailedData, // Compile-time validated
}
}🛡️ Secure Client-to-Server GORC Routing (gorc_client:)
A new, secure event category gorc_client: has been introduced to handle events initiated by clients that target server objects. This creates a clear security boundary between untrusted client input and trusted server-internal gorc_instance: events.
New on_gorc_client Handler Registration:
// Register a handler for a client attempting to mine an asteroid
events.on_gorc_client(
luminal_handle,
"Asteroid",
3,
"mine",
|event: GorcEvent, client_player: PlayerId, connection: ClientConnectionRef, instance: &mut ObjectInstance| {
// Security: Validate that the client is authenticated and close enough to mine
if !connection.is_authenticated() {
return Err(EventError::HandlerExecution("Not authenticated".to_string()));
}
// Update object state if valid
println!("Player {} is mining asteroid {}", client_player, event.object_id);
Ok(())
}
).await?;🔧 Technical Improvements
luminal Async Runtime for Cross-DLL Stability
The event system and plugins have migrated from tokio::runtime::Handle to luminal::Handle. This change resolves critical async runtime conflicts when loading plugins as dynamic libraries (DLLs), ensuring a stable and reliable plugin architecture.
Hierarchical PathRouter for Events
A new PathRouter has been implemented for event handler lookups. It treats event keys as hierarchical paths (e.g., core:player:connected), enabling faster lookups and efficient similarity searches for debugging missing handlers, which significantly improves developer experience.
Native GORC Message Routing
The server's message router now natively understands the {"type": "gorc_event", ...} format directly from clients. This bypasses the legacy ClientMessage wrapper, reducing parsing overhead and simplifying client-side code.
Critical Bug Fixes
- GORC Deadlock: A deadlock in
GorcInstanceManager::update_player_positionthat occurred during lock contention has been resolved. - Merciless Shutdown: The server now supports a "merciless shutdown." Sending a second shutdown signal (e.g., Ctrl+C) will cause an immediate exit, which is useful when a graceful shutdown hangs.
- Reliable Shutdown: The main server task is now explicitly aborted on shutdown to ensure it terminates reliably across all platforms.
⚠️ Breaking Changes
New Type-Safe GORC System
- All
GorcObjectimplementations must be migrated from the old string-based property system to the new type-based zone system usingGorcZoneDatastructs and theimpl_gorc_object!macro.
Async Runtime Change to luminal
- Plugins requiring an async runtime handle must now use
context.luminal_handle()instead ofcontext.tokio_handle(). Asynchronous operations within plugins should be spawned on this handle.
Unified Client Event Handler API
- The signatures for all
on_clienthandlers have been unified. They must now accept(event, player_id, connection)as arguments, providing full context for every client event.
Removal of gorc_example_plugin
- The outdated
gorc_example_pluginhas been removed. Developers should now use the new, more comprehensiveplugin_playeras a reference and foundation.
Update horizon_event_system
- Update
horizon_event_systemto0.21.0-rc3
🔄 Migration Guide
For GorcObject Implementors
- Define Zone Structs: For each replication channel, create a struct containing the relevant properties. Implement the
GorcZoneDatatrait for each.#[derive(Clone, Debug, Serialize, Deserialize)] struct MyObjectCriticalData { pub position: Vec3; } impl GorcZoneData for MyObjectCriticalData { ... }
- Update Main Object: Refactor your main object struct to contain these new zone data structs as fields.
- Use New Macro: Replace your manual
GorcObjectimplementation with theimpl_gorc_object!macro, mapping zone numbers to your new data fields.
For Plugin Developers
- Update Async Calls: Find all usages of
context.tokio_handle()and replace them withcontext.luminal_handle(). Useluminal_handle.spawn(...)for async tasks. - Update Client Handlers: Update all
on_clienthandler signatures to accept(event, player_id, connection).// Old events.on_client("chat", "message", |event: ChatEvent| { ... }).await?; // New events.on_client("chat", "message", |event: ChatEvent, player_id: PlayerId, conn: ClientConnectionRef| { ... }).await?;
- Switch to
gorc_client: For handlers processing client actions on objects, switch fromon_gorc_instanceto the newon_gorc_clientAPI to benefit from the enhanced security model.
📊 Benefits
- Enhanced Type Safety: Eliminates an entire class of runtime errors related to string-based property names.
- Improved Performance: Zero runtime string operations and a faster
PathRouterreduce CPU overhead during event processing. - Superior Security Model: The
gorc_client:category creates a clear, enforced boundary between untrusted client input and the trusted server state. - Stable Plugin Architecture: The switch to
luminalprovides a robust foundation for a cross-platform, dynamically loaded plugin ecosystem.
🚀 Performance Improvements
- Zero Runtime Strings: The new type-safe GORC system completely avoids string allocations and comparisons in the hot path of object replication.
- Efficient Handler Lookup: The
PathRouteruses a tree-based structure, offering O(log n) lookups instead of a linear scan, which is especially beneficial for debugging. - Optimized Client Messages: Native GORC event routing reduces server-side parsing overhead.
🔬 Use Cases
Secure Player Interaction
A player fires their ship's weapons. The client sends a gorc_client:GorcPlayer:1:attack event. The server's on_gorc_client handler validates that the player owns the ship and has ammo before executing the attack.
// Client sends a secure GORC event
events.on_gorc_client(luminal_handle, "GorcPlayer", 1, "attack",
|event, player_id, conn, instance| {
// ... security validation ...
Ok(())
}
).await?;Type-Safe Object Replication
A space asteroid's health is reduced b...
Release v0.40.0-rc1
Update Cargo.toml
Release v0.39.0
🚀 Horizon v0.39.0
🎯 Overview
Horizon v0.39.0 introduces server-wide broadcast functionality and improves musl target compatibility for static binary builds. This release adds essential communication tools for server-wide announcements while streamlining cross-platform deployment options.
✨ Major Features
📡 Server-Wide Broadcasting
New broadcast functionality enables messages to be sent to all connected clients simultaneously:
EventSystem Broadcasting:
// Broadcast events to all connected clients
let announcement = ServerAnnouncement {
message: "Server maintenance in 5 minutes".to_string(),
priority: "high".to_string(),
timestamp: current_timestamp(),
};
match events.broadcast(&announcement).await {
Ok(client_count) => println!("Announcement sent to {} clients", client_count),
Err(e) => println!("Broadcast failed: {}", e),
}Connection Manager Broadcasting:
impl ConnectionManager {
/// Broadcasts a message to all currently connected clients
pub async fn broadcast_to_all(&self, message: Vec<u8>) -> usize {
let connections = self.connections.read().await;
let connection_count = connections.len();
for &connection_id in connections.keys() {
self.sender.send((connection_id, message.clone()));
}
connection_count
}
}Client Response Broadcasting:
impl ClientResponseSender for GameServerResponseSender {
/// Broadcasts data to all currently connected clients
fn broadcast_to_all(&self, data: Vec<u8>) -> Pin<Box<dyn Future<Output = Result<usize, String>> + Send + '_>> {
Box::pin(async move {
let client_count = self.connection_manager.broadcast_to_all(data).await;
Ok(client_count)
})
}
}🏗️ Enhanced musl Target Support
Improved compatibility for static binary builds with conditional dependency configuration:
Conditional Dependencies:
# Use mio-runtime only for musl targets to avoid monoio compatibility issues
[target.'cfg(target_env = "musl")'.dependencies]
horizon_sockets = { workspace = true, default-features = false, features = ["mio-runtime"] }
# Use default features (including monoio) for other targets
[target.'cfg(not(target_env = "musl"))'.dependencies]
horizon_sockets = { workspace = true }Streamlined Release Targets:
Removed musl targets from CI release pipeline to focus on stable glibc builds:
- Removed:
x86_64-unknown-linux-musl - Removed:
aarch64-unknown-linux-musl - Removed:
i686-unknown-linux-musl - Removed:
armv7-unknown-linux-musleabihf - Kept: All glibc GNU targets for maximum compatibility
🔧 Technical Improvements
Broadcast Implementation Details
pub async fn broadcast<T>(&self, event: &T) -> Result<usize, EventError>
where
T: Event + serde::Serialize,
{
// Serialize event data once using serialization pool
let data = self.serialization_pool.serialize_event(event)?;
let broadcast_data = (*data).clone();
// Send to all clients via client response sender
match sender.broadcast_to_all(broadcast_data).await {
Ok(client_count) => {
// Update stats tracking
let mut stats = self.stats.write().await;
stats.events_emitted += 1;
Ok(client_count)
},
Err(e) => Err(EventError::HandlerExecution(format!("Broadcast failed: {}", e)))
}
}Default Trait Implementation
Added default broadcast implementation to ClientResponseSender:
pub trait ClientResponseSender {
// Existing methods...
/// Default implementation provides working fallback
fn broadcast_to_all(&self, _data: Vec<u8>) -> Pin<Box<dyn Future<Output = Result<usize, String>> + Send + '_>> {
// Returns 0 clients reached - implementations should override
Box::pin(async move { Ok(0) })
}
}Performance Optimizations
- Single Serialization: Events serialized once then cloned for each client
- Efficient Distribution: Messages queued through connection manager's broadcast system
- Stats Tracking: Broadcast events properly counted in event system statistics
- Debug Logging: Broadcast operations logged with client count information
⚠️ Breaking Changes
Event System Version Bump
[dependencies]
horizon_event_system = "0.20.0" # Updated from 0.19.0ClientResponseSender Trait Extension
Added new broadcast method (with default implementation for backward compatibility):
pub trait ClientResponseSender {
// New method - has default implementation
fn broadcast_to_all(&self, data: Vec<u8>) -> Pin<Box<dyn Future<Output = Result<usize, String>> + Send + '_>>;
}🔄 Migration Guide
For Plugin Developers
-
Update Dependencies:
horizon_event_system = "0.20.0"
-
Use Broadcasting (Optional):
// Broadcast server announcements let announcement = serde_json::json!({ "type": "announcement", "message": "Welcome to the server!", "timestamp": current_timestamp() }); let client_count = events.broadcast(&announcement).await?; println!("Sent welcome message to {} players", client_count);
-
Custom Response Senders:
// Override default broadcast implementation if needed impl ClientResponseSender for MyResponseSender { fn broadcast_to_all(&self, data: Vec<u8>) -> /* future */ { // Custom broadcast implementation Box::pin(async move { Ok(0) }) } }
For Server Operators
# Standard update process
git pull origin main
cargo build --release
# For musl static builds (if needed)
cargo build --release --target x86_64-unknown-linux-musl📊 Benefits
- Server-Wide Communication: Broadcast announcements, alerts, and updates to all players
- Efficient Distribution: Single serialization with optimized message delivery
- Better Static Builds: Improved musl target compatibility for containerized deployments
- Performance Tracking: Broadcast events counted in system statistics
- Flexible Implementation: Default trait methods maintain backward compatibility
- Streamlined Releases: Focus on stable glibc targets for better reliability
🚀 Performance Improvements
- Optimized Serialization: Events serialized once then distributed efficiently
- Lock-Free Broadcasting: DashMap-based connection tracking for high-throughput scenarios
- Smart Memory Management: Arc-based data sharing reduces memory overhead
- Efficient Target Builds: Conditional dependencies optimize for deployment environment
🔬 Use Cases
Server Announcements
// Global server messages
events.broadcast(&ServerMessage {
text: "Server restart in 10 minutes",
type_: MessageType::Warning,
}).await?;Event Broadcasting
// Game-wide events
events.broadcast(&WorldEvent {
event_type: "dragon_spawn",
location: Vec3::new(100.0, 0.0, 200.0),
}).await?;Administrative Tools
// Mass notifications
events.broadcast(&AdminNotification {
message: "New content update available",
requires_restart: false,
}).await?;📚 New APIs
EventSystem
// Broadcast to all connected clients
broadcast<T: Event + Serialize>(&self, event: &T) -> Result<usize, EventError>ConnectionManager
// Broadcast raw data to all connections
broadcast_to_all(&self, message: Vec<u8>) -> usizeClientResponseSender Trait
// Broadcast with default implementation
fn broadcast_to_all(&self, data: Vec<u8>) -> Pin<Box<dyn Future<Output = Result<usize, String>> + Send + '_>>🔄 Backward Compatibility
- All existing event handling continues working unchanged
- New broadcast methods have default implementations where applicable
- Connection management APIs remain fully compatible
- Configuration files require no changes
- Plugin interfaces preserved with additive changes only
🙏 Contributors
- Tristan Poland (Trident_For_U) - Server-wide broadcasting system, musl target compatibility improvements, optimized message distribution, and enhanced deployment support
📋 Next Steps
For developers adopting broadcasting features:
- Implement server announcement systems for better player communication
- Use broadcasts for game-wide events and notifications
- Consider musl builds for containerized or static deployments
- Explore broadcast-based features like global chat or server events
Full Changelog: v0.38.2...v0.39.0