Skip to main content

Overview

Chat commands allow players to interact with your plugin through in-game chat. Commands are triggered by typing /command_name in the YSFlight chat.

Registering Commands

Use the register_command() method to register a command in your plugin’s register() method:
def register(self, plugin_manager):
    self.plugin_manager = plugin_manager
    self.plugin_manager.register_command('refuel', self.refuel_handler, 
                                         "Allows you to get refueled", 
                                         alias="r")

Method Signature

plugin_manager.register_command
function
Registers a chat command with the plugin manager.Parameters:
command_name
str
required
The name of the command (without the / prefix). Players will type /command_name to trigger it.
callback
function
required
The function to call when the command is executed.
help_text
str
default:"No Description"
Description shown in the /help command output.
alias
str
default:"None"
Optional short alias for the command. For example, /r as an alias for /refuel.
If a command name is already registered, a warning will be logged and the registration will be ignored.

Command Callback Signature

All command callbacks must follow this signature:
def command_handler(self, full_message, player, message_to_client, message_to_server):
    # Your command logic here
    pass
full_message
str
The complete chat message including the command. For example, if the player types /refuel 5000, this will be "/refuel 5000".Parse arguments by slicing the string:
args = full_message.split()[1:]  # Get arguments after command
player
Player
The player who executed the command. Contains:
  • player.aircraft.id - Aircraft ID
  • player.iff - IFF value
  • player.aircraft.initial_config - Aircraft configuration data
  • player.streamWriterObject - Stream writer for sending data
message_to_client
list
List to append packets that should be sent to the player. Use this to send responses or game state changes.
message_to_server
list
List to append packets that should be sent to the server. Use this to modify game state server-side.

Built-in Commands

/help Command

The /help command is automatically registered and displays all available commands with their descriptions.
List of Available Commands:
/refuel [r] : Allows you to get refueled
/refueler [rf] : Allows other players to refuel from you
/fog : Sets fog color. Usage : /fog r,g,b
/sky : Sets sky color. Usage : /sky r,g,b

Sending Messages to Players

Use the YSchat module to send text messages:
from lib import YSchat

def my_command(self, full_message, player, message_to_client, message_to_server):
    response = YSchat.message("Command executed successfully!")
    message_to_client.append(response)
Alternatively, use the FSNETCMD_TEXTMESSAGE packet:
from lib.PacketManager.packets import FSNETCMD_TEXTMESSAGE

def my_command(self, full_message, player, message_to_client, message_to_server):
    response = FSNETCMD_TEXTMESSAGE.encode("Command executed!", True)
    message_to_client.append(response)

Parsing Command Arguments

Simple Arguments

def fog_command(self, full_message, player, message_to_client, message_to_server):
    try:
        # Parse "/fog 255,128,64" into [255, 128, 64]
        args = list(map(int, full_message[4:].split(',')))
        # Use args[0], args[1], args[2] for RGB values
    except:
        error = FSNETCMD_TEXTMESSAGE.encode("Invalid argument, usage /fog r,g,b", True)
        message_to_client.append(error)
        return

Space-separated Arguments

def time_command(self, full_message, player, message_to_client, message_to_server):
    # Parse "/time day" to get "day"
    requested = full_message[6:].lower()
    
    if requested == 'day':
        # Handle day time
        pass
    elif requested == 'night':
        # Handle night time
        pass
    else:
        error = FSNETCMD_TEXTMESSAGE.encode("Usage: /time <day|night>", True)
        message_to_client.append(error)

Sending Game Packets

Commands can send any game packet to modify the game state:

Changing Aircraft Fuel

from lib.PacketManager.packets import FSNETCMD_AIRCMD

def refuel(self, full_message, player, message_to_client, message_to_server):
    # Set fuel to 5000kg
    fuel_packet = FSNETCMD_AIRCMD.set_command(
        player.aircraft.id, 
        "INITFUEL", 
        "5000kg", 
        True
    )
    message_to_client.append(fuel_packet)

Changing Environment

from lib.PacketManager.packets import FSNETCMD_SKYCOLOR, FSNETCMD_FOGCOLOR

def sky(self, full_message, player, message_to_client, message_to_server):
    args = list(map(int, full_message[4:].split(',')))
    sky_packet = FSNETCMD_SKYCOLOR.encode(args[0], args[1], args[2], True)
    message_to_client.append(sky_packet)

def fog(self, full_message, player, message_to_client, message_to_server):
    args = list(map(int, full_message[4:].split(',')))
    fog_packet = FSNETCMD_FOGCOLOR.encode(args[0], args[1], args[2], True)
    message_to_client.append(fog_packet)

Sending Damage

from lib.PacketManager.packets import FSNETCMD_GETDAMAGE

def damage_command(self, full_message, player, message_to_client, message_to_server):
    damage_packet = FSNETCMD_GETDAMAGE.encode(
        player.aircraft.id,  # Target aircraft
        1, 1,                # Damage part and strength
        player.aircraft.id,  # Source aircraft
        1, 11, 0,           # Damage parameters
        True                # with_size
    )
    message_to_client.append(damage_packet)

Command State Management

You can use instance variables to track command state:
class Plugin:
    def __init__(self):
        self.plugin_manager = None
        self.refueling_players = {}  # Track which players are refueling
    
    def register(self, plugin_manager):
        self.plugin_manager = plugin_manager
        self.plugin_manager.register_command('refuel', self.toggle_refuel)
    
    def toggle_refuel(self, full_message, player, message_to_client, message_to_server):
        if player in self.refueling_players:
            # Turn off refueling
            del self.refueling_players[player]
            msg = YSchat.message("Refueling disabled")
        else:
            # Turn on refueling
            self.refueling_players[player] = True
            msg = YSchat.message("Refueling enabled")
        
        message_to_client.append(msg)

Best Practices

Validate Input

Always validate and sanitize command arguments. Use try-except blocks for parsing.

Provide Feedback

Always send a response message to the player, even for errors.

Use Aliases

Provide short aliases for frequently used commands (e.g., /r for /refuel).

Clear Help Text

Write descriptive help text that includes usage examples.

Example: Complete Command Implementation

from lib import YSchat
from lib.PacketManager.packets import FSNETCMD_TEXTMESSAGE, FSNETCMD_AIRCMD

ENABLED = True

class Plugin:
    def __init__(self):
        self.plugin_manager = None
    
    def register(self, plugin_manager):
        self.plugin_manager = plugin_manager
        
        # Register command with alias and help text
        self.plugin_manager.register_command(
            'setfuel',
            self.set_fuel,
            "Set your aircraft fuel. Usage: /setfuel <amount>",
            alias="sf"
        )
    
    def set_fuel(self, full_message, player, message_to_client, message_to_server):
        try:
            # Parse fuel amount from command
            parts = full_message.split()
            if len(parts) != 2:
                raise ValueError("Invalid number of arguments")
            
            fuel_amount = int(parts[1])
            
            # Validate fuel amount
            max_fuel = int(player.aircraft.initial_config['WEIGFUEL'][:-2])
            if fuel_amount < 0 or fuel_amount > max_fuel:
                raise ValueError(f"Fuel must be between 0 and {max_fuel}")
            
            # Send fuel change packet
            fuel_packet = FSNETCMD_AIRCMD.set_command(
                player.aircraft.id,
                "INITFUEL",
                f"{fuel_amount}kg",
                True
            )
            message_to_client.append(fuel_packet)
            
            # Confirm to player
            confirm = YSchat.message(f"Fuel set to {fuel_amount}kg")
            message_to_client.append(confirm)
            
        except ValueError as e:
            # Send error message
            error = FSNETCMD_TEXTMESSAGE.encode(
                f"Error: {str(e)}. Usage: /setfuel <amount>",
                True
            )
            message_to_client.append(error)
        except Exception as e:
            # Catch unexpected errors
            error = FSNETCMD_TEXTMESSAGE.encode(
                "An unexpected error occurred.",
                True
            )
            message_to_client.append(error)
This command:
  • Validates the number of arguments
  • Parses the fuel amount as an integer
  • Checks the fuel is within valid range
  • Sends the fuel change packet
  • Provides clear error messages

Build docs developers (and LLMs) love