Files
aiscape/modernized-client
2025-09-06 08:33:20 -07:00
..
2025-09-06 08:33:20 -07:00
2025-09-06 08:33:20 -07:00
2025-09-06 08:33:20 -07:00
2025-09-06 08:33:20 -07:00
2025-09-06 08:33:20 -07:00
2025-09-06 08:33:20 -07:00
2025-09-06 08:33:20 -07:00
2025-09-06 08:33:20 -07:00
2025-09-06 08:33:20 -07:00
2025-09-06 08:33:20 -07:00
2025-09-06 08:33:20 -07:00
2025-09-06 08:33:20 -07:00
2025-09-06 08:33:20 -07:00

OpenOSRS Modernized Client

Agent-Friendly RuneScape Client - A clean, modernized version of the OpenOSRS client designed specifically for AI agents to enjoy playing Old School RuneScape.

🎯 Project Overview

This project brings the obfuscated OpenOSRS/RuneLite client into the modern age with clean, well-documented APIs that enable AI agents to interact with RuneScape efficiently and enjoyably. The client provides comprehensive automation capabilities while maintaining the core game experience.

🏗️ Architecture

Core Components

ModernizedClient (Entry Point)
├── ClientCore (State Management)
├── GameEngine (Game Loop & Network)
├── AgentAPI (Clean Game Interaction)
├── ScriptingFramework (Automation)
└── PluginManager (Extensibility)

Key Features

  • Clean API Layer: Direct, type-safe access to game world data
  • Event-Driven Architecture: Real-time game state monitoring
  • Scripting Framework: Full automation capabilities for gameplay
  • Plugin System: Extensible functionality for agent enhancement
  • Thread-Safe Design: Concurrent operation support
  • Performance Optimized: 50 FPS game loop with monitoring

🚀 Quick Start

Prerequisites

  • Java 17 or higher
  • Gradle 7.0+
  • OpenOSRS game client files

Build and Run

# Clone and build
cd /home/ra/openosrs/modernized-client
./gradlew build

# Run the client
./gradlew run

Basic Agent Interaction

// Get the main client instance
ModernizedClient client = new ModernizedClient();
client.start();

// Access the Agent API
AgentAPI api = client.getAgentAPI();

// Basic game queries
Position playerPos = api.getPlayerPosition();
int hitpoints = api.getHitpoints();
boolean inCombat = api.isInCombat();

// Interact with the world
api.walkTo(new Position(3200, 3200, 0));
GameObject tree = api.getClosestGameObject(1278); // Oak tree
api.interactWithObject(tree, "Chop down");

🤖 Agent API Reference

Player Queries

// Player stats and state
Position getPlayerPosition()
int getHitpoints() / getMaxHitpoints()
int getPrayer() / getMaxPrayer()
int getSkillLevel(Skill skill)
boolean isInCombat()
int getCurrentAnimation()

World Interaction

// NPCs
List<NPC> getNPCs()
NPC getClosestNPC(int npcId)
CompletableFuture<Boolean> interactWithNPC(NPC npc, String action)

// Objects
List<GameObject> getGameObjects()
GameObject getClosestGameObject(int objectId)
CompletableFuture<Boolean> interactWithObject(GameObject obj, String action)

// Ground Items
List<GroundItem> getGroundItems()
GroundItem getClosestGroundItem(int itemId)
CompletableFuture<Boolean> pickupItem(GroundItem item)

Inventory Management

// Inventory operations
Item[] getInventory()
boolean hasItem(int itemId)
int getItemCount(int itemId)
CompletableFuture<Boolean> useItem(int slot)
CompletableFuture<Boolean> dropItem(int slot)

// Equipment
Item[] getEquipment()
Item getEquipmentSlot(EquipmentSlot slot)

Movement

// Navigation
CompletableFuture<Boolean> walkTo(Position position)
CompletableFuture<Boolean> runTo(Position position)

🔧 Scripting Framework

Creating Scripts

public class MyScript extends AbstractScript {
    @Override
    protected void run(ScriptContext context) throws Exception {
        AgentAPI api = context.getAPI();
        
        while (!context.shouldStop()) {
            context.checkContinue(); // Check for interruption
            
            // Your script logic here
            if (api.getHitpoints() < 50) {
                // Heal logic
            }
            
            sleep(1000); // Wait 1 second
        }
    }
    
    @Override
    public ScriptMetadata getMetadata() {
        return new ScriptMetadata("My Script", "Description", "Author", "1.0", 
            Arrays.asList("category"));
    }
}

Running Scripts

ScriptingFramework scripting = client.getScriptingFramework();

// Register your script
scripting.registerScript("my-script", new MyScript());

// Start execution
String executionId = scripting.startScript("my-script");

// Monitor progress
ScriptStatus status = scripting.getScriptStatus(executionId);

// Stop if needed
scripting.stopScript(executionId);

Built-in Example Scripts

  • Woodcutting Script: Cuts oak trees and manages inventory
  • Combat Training Script: Fights NPCs with food consumption
  • Banking Script: Deposits/withdraws items from bank

🔌 Plugin System

Creating Plugins

public class MyPlugin extends AbstractPlugin {
    @Override
    protected void enable() {
        logger.info("My plugin enabled");
        
        // Register event listeners
        addEventListener("PLAYER_MOVED", this::onPlayerMoved);
        
        // Start background tasks
    }
    
    @Override
    protected void disable() {
        logger.info("My plugin disabled");
        // Cleanup resources
    }
    
    private void onPlayerMoved(Object eventData) {
        // Handle player movement event
    }
    
    @Override
    public PluginMetadata getMetadata() {
        return new PluginMetadata("My Plugin", "Description", "Author", "1.0",
            new ArrayList<>(), Arrays.asList("utility"));
    }
}

Using Plugins

PluginManager plugins = client.getPluginManager();

// Register plugin
plugins.registerPlugin(new MyPlugin());

// Enable/disable
plugins.enablePlugin("My Plugin");
plugins.disablePlugin("My Plugin");

// Check status
boolean enabled = plugins.isPluginEnabled("My Plugin");

Built-in Example Plugins

  • Auto-Heal Plugin: Automatically eats food when health is low
  • Performance Monitor Plugin: Tracks FPS and memory usage
  • Anti-Idle Plugin: Prevents logout with random actions
  • Experience Tracker Plugin: Monitors XP gains per session

📊 Event System

Available Events

// Player events
"PLAYER_MOVED"           // Player position changed
"PLAYER_TOOK_DAMAGE"     // Player lost hitpoints
"PLAYER_GAINED_XP"       // Experience gained
"PLAYER_INTERACTED"      // Player performed action

// World events
"NPC_SPAWNED"           // New NPC appeared
"OBJECT_CHANGED"        // World object state changed
"ITEM_DROPPED"          // Ground item appeared

// System events
"FRAME_RENDERED"        // Graphics frame completed
"NETWORK_PACKET"        // Network message received

Event Listeners

EventSystem events = clientCore.getEventSystem();

events.addEventListener("PLAYER_GAINED_XP", (eventData) -> {
    logger.info("Experience gained: {}", eventData);
});

🎮 Game Data Types

Core Types

Position(int x, int y, int plane)
NPC(int index, int id, String name, Position position, ...)
GameObject(int id, String name, Position position, ...)
Item(int itemId, String name, int quantity, ...)
GroundItem(int itemId, String name, int quantity, Position position, ...)

Enums

// Skills
Skill.ATTACK, Skill.DEFENCE, Skill.STRENGTH, Skill.HITPOINTS,
Skill.RANGED, Skill.PRAYER, Skill.MAGIC, Skill.COOKING,
Skill.WOODCUTTING, Skill.FLETCHING, Skill.FISHING, Skill.FIREMAKING,
// ... all 23 skills

// Equipment slots
EquipmentSlot.HELMET, EquipmentSlot.CAPE, EquipmentSlot.AMULET,
EquipmentSlot.WEAPON, EquipmentSlot.BODY, EquipmentSlot.SHIELD,
// ... all equipment slots

🛠️ Development Guidelines

Best Practices

  1. Always check for null returns from API calls
  2. Use CompletableFuture.get() with timeouts for actions
  3. Implement proper exception handling in scripts and plugins
  4. Respect game timing - don't spam actions too quickly
  5. Clean up resources when stopping scripts/plugins

Performance Considerations

  • The game loop runs at 50 FPS for optimal performance
  • API calls are thread-safe but blocking operations should be async
  • Event listeners should be lightweight and fast
  • Use the provided sleep/wait utilities for timing

Thread Safety

  • All API methods are thread-safe
  • Game state is protected by concurrent data structures
  • Scripts run in their own threads
  • Plugin callbacks are synchronized

📁 Project Structure

modernized-client/
├── src/main/java/com/openosrs/client/
│   ├── ModernizedClient.java          # Main entry point
│   ├── core/                          # Core game systems
│   │   ├── ClientCore.java           # Central state management
│   │   ├── GameState.java            # Game world state
│   │   ├── PlayerState.java          # Player character state
│   │   ├── InventoryState.java       # Inventory management
│   │   └── EventSystem.java          # Event handling
│   ├── engine/                        # Game engine
│   │   ├── GameEngine.java           # Main game loop
│   │   └── NetworkEngine.java        # Network communication
│   ├── api/                          # Agent API layer
│   │   ├── AgentAPI.java             # Main API interface
│   │   ├── ApiDataClasses.java       # Data structures
│   │   └── ApiModules.java           # API implementations
│   ├── scripting/                    # Automation framework
│   │   ├── ScriptingFramework.java   # Script management
│   │   └── examples/                 # Example scripts
│   └── plugins/                      # Plugin system
│       ├── PluginSystem.java         # Plugin management
│       └── examples/                 # Example plugins
└── build.gradle                      # Build configuration

🔄 Migration from RuneLite

This client replaces the obfuscated gamepack with clean, agent-friendly interfaces:

RuneLite Component Modernized Equivalent
Client.java (obfuscated) ClientCore.java
Gamepack classes Clean API classes
Mixed injection system Direct API access
Limited automation Full scripting framework
Basic plugins Enhanced plugin system

🚨 Important Notes

Game Compliance

  • This client is designed for educational and agent research purposes
  • Ensure compliance with game terms of service
  • Automated gameplay should be used responsibly

Performance

  • The client is optimized for agent use, not human display
  • Graphics rendering is minimal to reduce overhead
  • Network optimization for efficient server communication

Security

  • No game file modification required
  • Clean separation between client and game data
  • Safe for use in controlled environments

🤝 Contributing

Adding New Scripts

  1. Extend AbstractScript
  2. Implement run() method with game logic
  3. Provide metadata for categorization
  4. Test thoroughly before submission

Adding New Plugins

  1. Extend AbstractPlugin
  2. Implement enable() and disable() methods
  3. Use event system for reactive behavior
  4. Document plugin capabilities

API Extensions

  1. Add new methods to appropriate API modules
  2. Ensure thread safety
  3. Provide comprehensive JavaDoc
  4. Include usage examples

📄 License

This project builds upon OpenOSRS and RuneLite codebases. Please respect their licenses and terms of use.

🆘 Support

For questions about using this client for agent development:

  1. Check the example scripts and plugins
  2. Review the API documentation
  3. Test in a development environment first
  4. Report issues with detailed reproduction steps

Ready to let your AI agent enjoy RuneScape? Start with the example scripts and build from there! 🤖⚔️