architecture-analysis
Guide for architecture-analysis
Architecture Analysis - Legends of Hastinapur
Executive Summary
This document outlines architectural issues identified in the
loh-game codebase and proposes solutions to improve maintainability, modularity, and scalability.Critical Issues
1. Plugin System Redundancy ⚠️
Issue: Two parallel plugin systems exist with overlapping functionality:
plugin_api/: Full-featured Lua plugin system withPluginManager, sandbox, UI API, event systemsystems/sdk/: SDK-focused plugin system usingloh-sdkcrate
Impact:
- Code duplication (~500+ lines of similar Lua binding code)
- Confusion for plugin developers (which system to use?)
- Maintenance burden (bug fixes need to be applied twice)
- Both systems are active in
lib.rs(lines 46-47)
Recommendation:
CAUTION Consolidate into single plugin architecture with environment-based permissionsStrategy (Per User Clarification):
Production Mode: Plugins are read-only (player mods, UI extensions, data visualization)
- Can read game state (player stats, inventory, world entities)
- Can render UI overlays and notifications
- Cannot send inputs or automate actions
- Sandboxed Lua environment with strict permissions
Development/Testing Mode: Plugins can have automation capabilities
- All production permissions +
- Can simulate player inputs (for automated testing)
- Can modify game state (for debugging)
- Can execute scripted test scenarios
- Useful for QA automation and regression testing
Recommended Implementation:
- Merge plugin systems into single
plugin_api/with mode flag- Add
PluginModeenum:pub enum PluginMode { Production, // Read-only, sandboxed Development, // Full automation for testing }- Gate dangerous APIs (input simulation, state mutation) behind
cfg(debug_assertions)or runtime mode check- Rename for clarity:
plugin_api/→ Production mods/extensionssystems/sdk/→ Development automation (can be merged with mode flag)Benefits:
- Single codebase to maintain
- Clear security boundary (production = read-only)
- Enables automated testing during development
- Prevents cheating/botting in production
2. Data Loading Architecture 📊
Issue: Mixed approaches for game data loading:
- Some systems load JSON directly in their modules (fishing.rs:88, farming.rs:150)
- Some use centralized
GameDataresource (data/mod.rs) - ID conversion (string→u32 hashing) happens inconsistently
Impact:
- Hard to track what data is loaded when
- Potential for duplicate file reads
- Error handling inconsistencies (some systems
warn!, otherserror!)
Recommendation:
IMPORTANT Centralize all data loading throughDataPlugin
- Move all JSON loading to
systems/data/mod.rs- Expose typed resources:
FishingData,SmithingData, etc.- Standardize ID conversion in single
string_to_idutility- Add validation layer (schema checking, duplicate ID detection)
Implementation:
// In data/mod.rs
#[derive(Resource)]
pub struct SkillsData {
pub fishing: FishingDatabase,
pub smithing: SmithingDatabase,
pub cooking: CookingDatabase,
pub farming: SeedDatabase,
}
// Skills plugins just query this resource
fn handle_fishing(
fishing_data: Res<SkillsData>,
// ...
) {
let spot_data = &fishing_data.fishing.spots;
// ...
}3. Skills Module Organization 🏗️
Current Structure:
systems/skills/
├── mod.rs (has SkillSystemsPlugin)
├── fishing.rs (has FishingPlugin)
├── smithing.rs (has SmithingPlugin)
├── cooking.rs (has CookingPlugin)
├── farming.rs (has FarmingPlugin)
├── woodcutting.rs
├── mining.rs
├── brewing.rs
└── magic.rsIssues:
- Each skill file has its own data structures (+events +systems +plugin)
- Duplicate patterns across skills (level check, inventory check, XP gain)
- 500-1000 lines per skill file (farming.rs: 391 lines, smithing.rs: 381 lines)
Recommendation:
TIP Extract common skill logic into shared utilitiessystems/skills/ ├── mod.rs ├── common/ │ ├── skill_check.rs // Reusable level/tool checks │ ├── xp_rewards.rs // Standard XP granting │ └── inventory_ops.rs // Common inventory operations ├── gathering/ │ ├── fishing.rs │ ├── woodcutting.rs │ └── mining.rs └── production/ ├── smithing.rs ├── cooking.rs └── brewing.rs
4. UI Code Duplication 🎨
Issue: Crafting menus have repetitive patterns:
- crafting_ui.rs:50-90: Smelting UI
- crafting_ui.rs:97-147: Smithing UI
- crafting_ui.rs:149-200: Cooking UI
- farming_menu_ui.rs:22-70: Farming UI
Each follows same pattern:
- Check player level
- Show materials/ingredients
- Color-code availability (GREEN/RED)
- "Craft 1" / "Craft All" buttons
Recommendation:
// Generic crafting UI component
fn render_recipe_list<T: RecipeTrait>(
ui: &mut egui::Ui,
recipes: &[T],
inventory: &Inventory,
skills: &Skills,
on_craft: impl Fn(&T, u32),
) {
// Shared UI logic
}Medium Priority Issues
5. Event System Architecture
Observation: Mix of direct event handling and SDK event bridging
- Some events are handled directly by game systems
- Some are bridged to SDK (systems/sdk/events.rs)
- Plugin API has its own event queue (plugin_api/manager.rs:17)
Recommendation: Document event flow clearly in
agent-docs/event-architecture.md6. Combat System Warnings
63 warnings in latest build, including:
- Unused imports across multiple files
- Unused variables (
commands,inventory_query, etc.) - Unnecessary
mutqualifiers
Recommendation: Run
cargo clippy -- -W clippy::all and address systematicallyLow Priority / Technical Debt
7. String ID Migration Incomplete
Some systems still use
u32 IDs directly:- Loot tables
- NPC definitions
- Quest system
Recommendation: Complete migration to string IDs for all game content
8. Missing Documentation
Key modules lack doc comments:
plugin_api/modules (0 doc comments)systems/skills/modules (minimal comments)- Event structs lack field documentation
Recommendation: Add
rustdoc to CI pipeline, enforce 80% coverageAction Plan
Phase 1: Critical Fixes (Week 1)
- Document plugin system split (create
agent-docs/plugin-architecture.md) - Centralize data loading in
DataPlugin - Create skill utility module (
skills/common/)
Phase 2: Code Quality (Week 2)
- Create generic crafting UI components
- Fix all clippy warnings
- Add rustdoc comments to public APIs
Phase 3: Tech Debt (Week 3)
- Complete string ID migration
- Create event architecture diagram
- Refactor UI system for reusability
Metrics
Current State:
- Lines of Code: ~15,000 (estimated from file counts)
- Compilation Warnings: 63
- Build Time: Unknown (needs profiling)
- Plugin Systems: 2 (redundant)
Target State:
- Reduce code duplication by 30%
- Zero compilation warnings
- Single, well-documented plugin architecture
- Build time < 30s (needs baseline)
Last Updated: 2026-01-05
Status: DRAFT - Needs team review
Status: DRAFT - Needs team review