405 lines
11 KiB
Markdown
405 lines
11 KiB
Markdown
# 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
|
|
|
|
```bash
|
|
# Clone and build
|
|
cd /home/ra/openosrs/modernized-client
|
|
./gradlew build
|
|
|
|
# Run the client
|
|
./gradlew run
|
|
```
|
|
|
|
### Basic Agent Interaction
|
|
|
|
```java
|
|
// 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
|
|
```java
|
|
// Player stats and state
|
|
Position getPlayerPosition()
|
|
int getHitpoints() / getMaxHitpoints()
|
|
int getPrayer() / getMaxPrayer()
|
|
int getSkillLevel(Skill skill)
|
|
boolean isInCombat()
|
|
int getCurrentAnimation()
|
|
```
|
|
|
|
### World Interaction
|
|
```java
|
|
// 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
|
|
```java
|
|
// 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
|
|
```java
|
|
// Navigation
|
|
CompletableFuture<Boolean> walkTo(Position position)
|
|
CompletableFuture<Boolean> runTo(Position position)
|
|
```
|
|
|
|
## 🔧 Scripting Framework
|
|
|
|
### Creating Scripts
|
|
|
|
```java
|
|
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
|
|
|
|
```java
|
|
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
|
|
|
|
```java
|
|
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
|
|
|
|
```java
|
|
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
|
|
|
|
```java
|
|
// 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
|
|
|
|
```java
|
|
EventSystem events = clientCore.getEventSystem();
|
|
|
|
events.addEventListener("PLAYER_GAINED_XP", (eventData) -> {
|
|
logger.info("Experience gained: {}", eventData);
|
|
});
|
|
```
|
|
|
|
## 🎮 Game Data Types
|
|
|
|
### Core Types
|
|
```java
|
|
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
|
|
```java
|
|
// 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!** 🤖⚔️ |