Architecture Overview¶
This document describes the high-level architecture of Ansible Crafting, its package structure, key classes, and data flows.
See also: Development Guide for building and testing, Guidelines for coding conventions.
High-Level Architecture¶
Ansible Crafting is a client-server Minecraft mod for Fabric, Forge, and NeoForge that scans nearby inventories on the server, syncs the data to the client for display, and handles crafting requests that pull items from remote containers. The codebase uses Stonecutter + Modstitch for multi-version, multi-loader support from a single source tree.
flowchart TB
subgraph Server Side
SCANNER["InventoryScanner<br/>Scans nearby blocks"]
AGG["AggregatedInventory<br/>Merges all inventories"]
STATE["InventoryStateManager<br/>Persistent enable/disable"]
CRAFT["RemoteCraftingHandler<br/>Extracts items from containers"]
SESSION["CraftingSessionManager<br/>Tracks active crafting sessions"]
end
subgraph Network
SYNC_PKT["InventorySyncPacket<br/>Item data โ client"]
STATE_PKT["InventoryStateSyncPacket<br/>Enable/disable states โ client"]
TOGGLE_PKT["InventoryToggleRequestPacket<br/>Toggle request โ server"]
RESYNC_PKT["StateResyncRequestPacket<br/>Resync request โ server"]
end
subgraph Client Side
CACHE["ClientInventoryCache<br/>Stores synced item data"]
PANEL["InventoryPanelWidget<br/>Side panel UI"]
HIGHLIGHT["HighlightRenderer<br/>Block outline highlights"]
OVERLAY["InventoryOverlayRenderer<br/>Wifi status icons"]
SHADER["ShaderCompat<br/>Shader mod detection"]
TRACKER["InventoryPanelTracker<br/>Panel lifecycle"]
TEXTURES["AnsibleCraftingTextures<br/>Texture identifiers"]
end
subgraph Integrations
EMI["EMI Plugin<br/>Recipe transfer + exclusion zones"]
REI["REI Plugin<br/>Recipe transfer + exclusion zones"]
end
SCANNER --> AGG
AGG --> SYNC_PKT
STATE --> STATE_PKT
SYNC_PKT --> CACHE
STATE_PKT --> CACHE
CACHE --> PANEL
PANEL --> HIGHLIGHT
TOGGLE_PKT --> STATE
RESYNC_PKT --> STATE
EMI --> CRAFT
REI --> CRAFT
CRAFT --> SESSION
Package Structure¶
com.ansiblecrafting/
โโโ AnsibleCraftingMod โ Server-side mod entrypoint, lifecycle
โโโ ModResourceLocation โ Version-safe ResourceLocation factory
โโโ RegistryHelper โ Version-safe registry lookup utility
โโโ ServerTickHandler โ Per-tick inventory scanning orchestration
โโโ client/
โ โโโ AnsibleCraftingClient โ Client-side mod entrypoint
โ โโโ AnsibleCraftingTextures โ Texture ResourceLocation constants
โ โโโ ClientInventoryCache โ Client-side inventory data cache
โ โโโ HighlightRenderer โ 3D block highlight rendering
โ โโโ InventoryOverlayRenderer โ 3D inventory icon overlay rendering
โ โโโ ShaderCompat โ Shader mod detection (Iris/Optifine)
โ โโโ ui/
โ โโโ InventoryPanelTracker โ Panel visibility state tracking
โ โโโ InventoryPanelWidget โ Side panel UI widget
โโโ config/
โ โโโ ConfigScreenBuilder โ Cloth Config screen builder
โ โโโ ModConfig โ Configuration data class
โ โโโ ModMenuIntegration โ Mod Menu config screen provider
โโโ crafting/
โ โโโ ClientCacheRecipePopulator โ Client-side recipe ingredient populator
โ โโโ CombinedPlayerInventory โ Player + nearby inventory wrapper
โ โโโ CraftingSessionManager โ Per-player crafting session state (CraftingSession is a Java record)
โ โโโ GridSlotSourceHolder โ Tracks which container each grid slot's item came from
โ โโโ RemoteCraftingHandler โ Item extraction/insertion from nearby containers
โ โโโ VirtualInventory โ Read-only Container for recipe filling
โ โโโ VirtualSlot โ Single slot in a VirtualInventory
โโโ integration/
โ โโโ NearbyInventoryHelper โ Shared recipe viewer helper methods
โ โโโ emi/
โ โ โโโ AnsibleCraftingEmiExclusionArea
โ โ โโโ AnsibleCraftingEmiPlugin
โ โ โโโ AnsibleCraftingRecipeHandler
โ โโโ jei/
โ โ โโโ AnsibleCraftingJeiPlugin
โ โ โโโ JeiExclusionAreaHandler
โ โ โโโ JeiTransferHandler
โ โโโ rei/
โ โโโ ReiExclusionZoneProvider
โ โโโ ReiPlugin
โ โโโ ReiTransferHandler
โโโ inventory/
โ โโโ AggregatedInventory โ Merged view of all nearby container contents
โ โโโ CapabilityBackedInventory โ Forge/NeoForge capability wrapper
โ โโโ InventoryLookup โ Block entity โ Container resolution
โ โโโ InventoryScanner โ Nearby container discovery and caching
โ โโโ InventoryStateManager โ Per-inventory enable/disable persistence
โ โโโ InventoryToggleHandler โ Toggle request processing
โ โโโ StorageBackedInventory โ Fabric Transfer API wrapper
โโโ mixin/
โ โโโ AbstractRecipeScreenHandlerMixin โ Recipe placement injection
โ โโโ CraftingScreenHandlerMixin โ Crafting menu lifecycle hooks
โ โโโ client/
โ โโโ ContainerScreenMixin โ Generic container screen hooks
โ โโโ CraftingScreenMixin โ Crafting screen panel integration
โโโ network/
โโโ InventoryStateSyncPacket โ ServerโClient state sync
โโโ InventorySyncPacket โ ServerโClient inventory data sync
โโโ InventoryToggleRequestPacket โ ClientโServer toggle request
โโโ NetworkHandler โ Forge/NeoForge network channel setup
โโโ RemoteCraftFillRequestPacket โ ClientโServer craft request
โโโ StateResyncRequestPacket โ ClientโServer state resync request
โโโ StateSyncHelper โ State sync utility methods
Key Data Flows¶
Inventory Scanning and Sync¶
sequenceDiagram
participant Server as Server (tick loop)
participant Scanner as InventoryScanner
participant Agg as AggregatedInventory
participant Net as Network
participant Cache as ClientInventoryCache
participant Panel as InventoryPanelWidget
Server->>Scanner: scanInventories(player) every N ticks
Scanner->>Scanner: Find blocks with inventories within range
Scanner->>Agg: Aggregate all inventory contents
Agg->>Net: InventorySyncPacket (item stacks + positions)
Net->>Cache: Update cached item data
Cache->>Panel: Panel reads cache on render
Remote Crafting (via Recipe Viewer)¶
sequenceDiagram
participant Player as Player
participant EMI as EMI / REI
participant Handler as RecipeHandler
participant Mixin as CraftingScreenHandlerMixin
participant Remote as RemoteCraftingHandler
participant Container as Nearby Container
Player->>EMI: Click recipe to craft
EMI->>Handler: Transfer recipe to crafting grid
Handler->>Mixin: fillInputSlots() with remote sources
Mixin->>Remote: Extract items from remote inventories
Remote->>Container: Remove items from container slots
Remote->>Mixin: Place items in crafting grid
Player->>Mixin: Take crafted result
Mixin->>Remote: Return unused items to source containers
Inventory Toggle¶
sequenceDiagram
participant Player as Player (Client)
participant Net as Network
participant State as InventoryStateManager
participant PState as PersistentState (World Save)
Player->>Net: InventoryToggleRequestPacket (blockPos, enabled)
Net->>State: Toggle inventory at position
State->>PState: Persist to world save data
State->>Net: InventoryStateSyncPacket (updated states)
Net->>Player: Client updates overlay icons
Mixin Strategy¶
The mod uses four mixins to hook into Minecraft's crafting system and screen rendering:
| Mixin | Target | Purpose |
|---|---|---|
CraftingScreenHandlerMixin |
CraftingScreenHandler |
Injects remote inventory support into the crafting handler; implements GridSlotSourceHolder |
AbstractRecipeScreenHandlerMixin |
AbstractRecipeScreenHandler |
Extends recipe book to consider remote items |
CraftingScreenMixin |
CraftingScreen |
Injects the inventory panel into the crafting table screen |
ContainerScreenMixin |
HandledScreen |
Injects the inventory panel into container screens (chests, barrels, etc.) |
Mixin policy: No empty stub mixins. Every mixin must contain at least one functional injection. See Guidelines โ Mixin Best Practices.
Recipe Viewer Integration¶
Both EMI and REI integrations follow the same pattern:
flowchart LR
PLUGIN["Plugin Registration<br/>EmiPlugin / REIClientPlugin"] --> HANDLER["Recipe Transfer Handler<br/>Fills crafting grid from remote items"]
PLUGIN --> EXCLUSION["Exclusion Zone Provider<br/>Prevents recipe viewer overlapping panel"]
| Component | EMI | REI |
|---|---|---|
| Plugin | AnsibleCraftingEmiPlugin |
ReiPlugin |
| Transfer Handler | AnsibleCraftingRecipeHandler |
ReiTransferHandler |
| Exclusion Zone | AnsibleCraftingEmiExclusionArea |
ReiExclusionZoneProvider |
JEI is supported on Forge (1.20.1) and NeoForge (1.21.1+) via the integration/jei/ package.
Client-Server Boundary¶
All code is strictly separated by side:
| Side | Entry Point | Packages |
|---|---|---|
| Server (both dedicated + integrated) | AnsibleCraftingMod |
inventory, crafting, config, network, mixin |
| Client only | AnsibleCraftingClient |
client/*, client/ui/*, mixin/client/*, integration/* |
Client-only classes use @Environment(EnvType.CLIENT) to prevent loading on dedicated servers. Entry points are declared in fabric.mod.json:
{
"entrypoints": {
"main": ["com.ansiblecrafting.AnsibleCraftingMod"],
"client": ["com.ansiblecrafting.client.AnsibleCraftingClient"]
}
}
Persistent State¶
InventoryStateManager extends Minecraft's PersistentState to save per-inventory enable/disable toggles to the world save. This means:
- Toggle states survive server restarts
- Each world/dimension has its own state
- States are synced to clients via
InventoryStateSyncPacket