Skip to content

Releases: Far-Beyond-Dev/Horizon

Release v0.42.4

09 Jan 06:04

Choose a tag to compare

Update Cargo.toml

Release v0.42.3

02 Nov 18:41

Choose a tag to compare

Release

Release v0.42.2

02 Nov 16:32

Choose a tag to compare

Update Cargo.toml

Release v0.42.1

01 Nov 15:36
8ee5ed0

Choose a tag to compare

What's Changed

New Contributors

Breaking changes

  • Must update plugins to horizon_event_system 0.23.0

Full Changelog: v0.42.0...v0.42.1

Release v0.42.0

21 Oct 17:55

Choose a tag to compare

Update Cargo.toml

Release v0.41.0

21 Oct 17:37
5249f69

Choose a tag to compare

🌌 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.rs and main.rs modules 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.rs causing 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.


  • 🧾 Commit Highlights

    1. Refactor core logic into lib.rs and main.rs

    2. Add distance filtering regression tests

    3. Improve GORC spatial tracking

    4. Fix GORC runtime issues

    5. Bump to version 0.41.0


Release v0.40.0

05 Oct 01:32
1e9b22d

Choose a tag to compare

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 = 20

Dynamic 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 = 1000

Configuration 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

13 Sep 02:41

Choose a tag to compare

🚀 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_position that 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 GorcObject implementations must be migrated from the old string-based property system to the new type-based zone system using GorcZoneData structs and the impl_gorc_object! macro.

Async Runtime Change to luminal

  • Plugins requiring an async runtime handle must now use context.luminal_handle() instead of context.tokio_handle(). Asynchronous operations within plugins should be spawned on this handle.

Unified Client Event Handler API

  • The signatures for all on_client handlers 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_plugin has been removed. Developers should now use the new, more comprehensive plugin_player as a reference and foundation.

Update horizon_event_system

  • Update horizon_event_system to 0.21.0-rc3

🔄 Migration Guide

For GorcObject Implementors

  1. Define Zone Structs: For each replication channel, create a struct containing the relevant properties. Implement the GorcZoneData trait for each.
    #[derive(Clone, Debug, Serialize, Deserialize)]
    struct MyObjectCriticalData { pub position: Vec3; }
    impl GorcZoneData for MyObjectCriticalData { ... }
  2. Update Main Object: Refactor your main object struct to contain these new zone data structs as fields.
  3. Use New Macro: Replace your manual GorcObject implementation with the impl_gorc_object! macro, mapping zone numbers to your new data fields.

For Plugin Developers

  1. Update Async Calls: Find all usages of context.tokio_handle() and replace them with context.luminal_handle(). Use luminal_handle.spawn(...) for async tasks.
  2. Update Client Handlers: Update all on_client handler 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?;
  3. Switch to gorc_client: For handlers processing client actions on objects, switch from on_gorc_instance to the new on_gorc_client API 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 PathRouter reduce 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 luminal provides 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 PathRouter uses 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...

Read more

Release v0.40.0-rc1

13 Sep 02:36

Choose a tag to compare

Update Cargo.toml

Release v0.39.0

07 Sep 02:59

Choose a tag to compare

🚀 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.0

ClientResponseSender 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

  1. Update Dependencies:

    horizon_event_system = "0.20.0"
  2. 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);
  3. 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>) -> usize

ClientResponseSender 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