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 with PluginManager, sandbox, UI API, event system
  • systems/sdk/: SDK-focused plugin system using loh-sdk crate
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 permissions
Strategy (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:
  1. Merge plugin systems into single plugin_api/ with mode flag
  2. Add PluginMode enum:
    pub enum PluginMode {
      Production,  // Read-only, sandboxed
      Development, // Full automation for testing
    }
  3. Gate dangerous APIs (input simulation, state mutation) behind cfg(debug_assertions) or runtime mode check
  4. Rename for clarity:
    • plugin_api/ → Production mods/extensions
    • systems/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 GameData resource (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!, others error!)
Recommendation:
IMPORTANT
Centralize all data loading through DataPlugin
  1. Move all JSON loading to systems/data/mod.rs
  2. Expose typed resources: FishingData, SmithingData, etc.
  3. Standardize ID conversion in single string_to_id utility
  4. 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.rs
Issues:
  • 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 utilities
systems/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:
Each follows same pattern:
  1. Check player level
  2. Show materials/ingredients
  3. Color-code availability (GREEN/RED)
  4. "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
Recommendation: Document event flow clearly in agent-docs/event-architecture.md

6. Combat System Warnings

63 warnings in latest build, including:
  • Unused imports across multiple files
  • Unused variables (commands, inventory_query, etc.)
  • Unnecessary mut qualifiers
Recommendation: Run cargo clippy -- -W clippy::all and address systematically

Low 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% coverage

Action 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