Skip to content

instance.py

kiankyars edited this page Jul 7, 2025 · 1 revision

Current Problems with instance.py:

  1. 942 lines - Way too long
  2. Multiple responsibilities - Violates Single Responsibility Principle
  3. Hard to read and maintain
  4. Difficult to test individual components
  5. Tight coupling between different concerns

Refactoring Strategy: Break into Focused Classes

1. Core Instance Management (FactorioInstance - ~150 lines)

# fle/env/core/instance.py
class FactorioInstance:
    """Main orchestrator class - keeps only essential coordination logic"""
    
    def __init__(self, **kwargs):
        self.connection_manager = ConnectionManager(**kwargs)
        self.tool_manager = ToolManager(self.connection_manager)
        self.state_manager = StateManager(self.connection_manager)
        self.namespace_manager = NamespaceManager(self.connection_manager)
        # ... minimal coordination logic

2. Connection Management (ConnectionManager - ~100 lines)

# fle/env/core/connection.py
class ConnectionManager:
    """Handles RCON connections, server communication, and basic commands"""
    
    def __init__(self, address, tcp_port, **kwargs):
        self.rcon_client = self._connect_to_server(address, tcp_port)
    
    def connect_to_server(self, address, tcp_port):
        # Connection logic from current instance.py
    
    def send_command(self, command, *parameters):
        # Command sending logic
    
    def execute_transaction(self, transaction):
        # Transaction execution logic

3. Tool Management (ToolManager - ~150 lines)

# fle/env/core/tools.py
class ToolManager:
    """Handles tool loading, setup, and hook management"""
    
    def __init__(self, connection_manager):
        self.connection_manager = connection_manager
        self.controllers = {}
        self.pre_tool_hooks = {}
        self.post_tool_hooks = {}
    
    def setup_tools(self, lua_script_manager):
        # Tool setup logic from current instance.py
    
    def register_pre_tool_hook(self, tool_name, callback):
        # Hook registration logic
    
    def execute_pre_tool_hooks(self, tool_name, tool_instance, *args, **kwargs):
        # Hook execution logic

4. State Management (StateManager - ~120 lines)

# fle/env/core/state.py
class StateManager:
    """Handles game state, reset, initialization, and persistence"""
    
    def __init__(self, connection_manager):
        self.connection_manager = connection_manager
        self.initial_inventory = {}
        self.all_technologies_researched = True
    
    def reset(self, game_state=None):
        # Reset logic from current instance.py
    
    def initialise(self, fast=True):
        # Initialization logic
    
    def _reset(self, inventories):
        # Internal reset logic

5. Namespace Management (NamespaceManager - ~100 lines)

# fle/env/core/namespace.py
class NamespaceManager:
    """Handles Python namespace creation and management"""
    
    def __init__(self, connection_manager, num_agents=1):
        self.connection_manager = connection_manager
        self.namespaces = [FactorioNamespace(connection_manager, i) for i in range(num_agents)]
    
    def create_factorio_namespace(self):
        # Namespace creation logic from current instance.py
    
    def run_func_in_factorio_env(self, func):
        # Environment execution logic

6. Screenshot Management (ScreenshotManager - ~80 lines)

# fle/env/core/screenshots.py
class ScreenshotManager:
    """Handles screenshot capture and file management"""
    
    def __init__(self, connection_manager):
        self.connection_manager = connection_manager
    
    def screenshot(self, script_output_path, resolution="1920x1080", save_path=None, zoom=None):
        # Screenshot logic from current instance.py
    
    def _get_latest_screenshot(self, script_output_path, max_wait=2):
        # Screenshot file management logic
    
    def calculate_optimal_zoom(self, bounds, resolution="1920x1080"):
        # Zoom calculation logic

7. Warning Management (WarningManager - ~50 lines)

# fle/env/core/warnings.py
class WarningManager:
    """Handles game warnings and alerts"""
    
    def __init__(self, connection_manager):
        self.connection_manager = connection_manager
    
    def get_warnings(self, seconds=10):
        # Warning retrieval logic from current instance.py

Implementation Plan:

Phase 1: Extract Connection Management

  1. Create ConnectionManager class
  2. Move connection-related methods from FactorioInstance
  3. Update FactorioInstance to use ConnectionManager

Phase 2: Extract Tool Management

  1. Create ToolManager class
  2. Move tool setup and hook management
  3. Update dependencies

Phase 3: Extract State Management

  1. Create StateManager class
  2. Move reset and initialization logic
  3. Update state-related methods

Phase 4: Extract Other Managers

  1. Create remaining manager classes
  2. Move respective functionality
  3. Update all references

Phase 5: Clean Up Main Class

  1. Simplify FactorioInstance to orchestrate managers
  2. Remove duplicate code
  3. Improve documentation

Benefits of This Refactoring:

  1. Readability: Each class has a single, clear responsibility
  2. Testability: Each component can be tested independently
  3. Maintainability: Changes to one area don't affect others
  4. Reusability: Components can be reused in different contexts
  5. Debugging: Easier to isolate issues to specific components

File Structure After Refactoring:

fle/env/core/
├── __init__.py
├── instance.py          # Main orchestrator (~150 lines)
├── connection.py        # RCON and communication (~100 lines)
├── tools.py            # Tool management (~150 lines)
├── state.py            # Game state management (~120 lines)
├── namespace.py        # Namespace management (~100 lines)
├── screenshots.py      # Screenshot handling (~80 lines)
└── warnings.py         # Warning management (~50 lines)