class Rosegold::SpectateServer

Overview

A spectate server that allows Minecraft clients to connect and observe the bot's gameplay in real-time. Provides a "headless with headful feel" experience by forwarding packets, synchronizing world state, and replicating the bot's perspective including inventory, position, chunk data, and player interactions.

Note: This is in early development and not perfect. It provides essential functionality for debugging complex headless bots by allowing visual inspection of their behavior, but may have visual glitches, missing features, or synchronization issues.

Usage Example

# Initialize and start the spectate server
spectate_server = Rosegold::SpectateServer.new("127.0.0.1", 25566)
spectate_server.start

# Create and attach a Rosegold client to the spectate server
client = Rosegold::Client.new("play.example.com")
spectate_server.attach_client(client)

bot = Rosegold::Bot.new(client)
bot.join_game

# Now Minecraft clients can connect to localhost:25566 to spectate the bot
# The spectator will see everything the bot sees: world, inventory, entities, etc.

# You would do bot logic after joining the game, e.g.:
bot.move_to 10, 10

# To stop the spectate server prematurely:
spectate_server.stop

Defined in:

rosegold/spectate_server.cr

Constant Summary

BOT_MONITOR_INTERVAL = 50.milliseconds
DEFAULT_RENDER_DISTANCE = 3
DEFAULT_SIMULATION_DISTANCE = 3_u32
DEFAULT_SPECTATOR_ENTITY_ID = 2147483647

Configuration constants

DEFAULT_VIEW_DISTANCE = 3_u32
FORWARDED_PACKETS = {114_u8 => "SystemChatMessage", 17_u8 => "CloseWindow", 52_u8 => "OpenWindow", 8_u8 => "BlockChange", 77_u8 => "MultiBlockChange", 1_u8 => "SpawnEntity", 31_u8 => "EntityPositionSync", 46_u8 => "move_entity_pos", 49_u8 => "EntityRotation", 47_u8 => "move_entity_pos_rot", 95_u8 => "EntityEquipment", 94_u8 => "set_entity_motion", 92_u8 => "set_entity_data", 70_u8 => "remove_entities", 124_u8 => "update_attributes", 63_u8 => "PlayerInfoUpdate", 62_u8 => "PlayerInfoRemove", 110_u8 => "sound", 5_u8 => "block_destruction", 18_u8 => "SetContainerContent", 20_u8 => "SetSlot", 97_u8 => "UpdateHealth", 125_u8 => "EntityEffect", 71_u8 => "RemoveEntityEffect"}

Packet IDs for raw forwarding

INVENTORY_POLL_INTERVAL = 1.second
KEEP_ALIVE_INTERVAL = 20.seconds
Log = ::Log.for(self)

Constructors

Instance Method Summary

Constructor Detail

def self.new(host : String = "127.0.0.1", port : Int32 = 25566) #

Creates a new SpectateServer.

  • #host: IP address to bind to (default: "127.0.0.1")
  • #port: Port to listen on (default: 25566)

[View source]

Instance Method Detail

def attach_client(client : Rosegold::Client) #

Attaches a Rosegold client so spectators can observe its gameplay. Only one client can be attached at a time.


[View source]
def client : Rosegold::Client | Nil #

[View source]
def client=(client : Rosegold::Client | Nil) #

[View source]
def connections : Array(Rosegold::SpectateConnection) #

[View source]
def connections=(connections : Array(Rosegold::SpectateConnection)) #

[View source]
def detach_client #

[View source]
def host : String #

[View source]
def host=(host : String) #

[View source]
def port : Int32 #

[View source]
def port=(port : Int32) #

[View source]
def server : TCPServer | Nil #

[View source]
def server=(server : TCPServer | Nil) #

[View source]
def start #

Starts the spectate server and begins listening for connections. Spawns a fiber to handle connections asynchronously. Multiple spectators can connect simultaneously.


[View source]
def stop #

[View source]