duplicate plugin panic
Guide for duplicate plugin panic
Duplicate Plugin Panic Fix
Problem
After fixing the tracing-subscriber panic, the game crashed with a new error:
thread 'main' (21273) panicked at src/lib.rs:69:10:
Error adding plugin legends_client::systems::combat::CombatPlugin: : plugin was already added in applicationRoot Cause
Bevy's plugin system prevents duplicate plugin registration. The
CombatPlugin was being added in two places:- Top-level in
src/lib.rs(line 69):app.add_plugins(systems::combat::CombatPlugin) // [NEW] Combat System - Nested in
src/systems/player/mod.rs(line 93):impl Plugin for PlayerPlugin { fn build(&self, app: &mut App) { app.add_plugins(( inventory::InventoryPlugin, equipment::EquipmentPlugin, crate::systems::combat::CombatPlugin, // ← Duplicate! interactions::InteractionPlugin, )) // ... } }
Why this happened: During development,
CombatPlugin was initially added to PlayerPlugin because combat logic was tightly coupled with player systems. Later, it was refactored to be a top-level system, but the nested registration wasn't removed.Solution
Remove the duplicate
CombatPlugin registration from PlayerPlugin.Code Change
File:
src/systems/player/mod.rsBefore (lines 86-95):
impl Plugin for PlayerPlugin {
fn build(&self, app: &mut App) {
app.init_resource::<CombatConfig>()
.add_plugins((
inventory::InventoryPlugin,
equipment::EquipmentPlugin,
// Assuming movement and combat plugins are from a crate::systems::* path or similar
// and are intended to be added here.
// If these are not defined or are from a different module, this will cause a compile error.
// For now, I'm adding them as per the instruction's snippet.
crate::systems::combat::CombatPlugin, // ← Remove this
interactions::InteractionPlugin,
))After (lines 86-89):
impl Plugin for PlayerPlugin {
fn build(&self, app: &mut App) {
app.init_resource::<CombatConfig>()
.add_plugins((
inventory::InventoryPlugin,
equipment::EquipmentPlugin,
interactions::InteractionPlugin, // [NEW]
))Why Keep It in lib.rs?
CombatPlugin is now a core game system that:- Handles combat for all entities (players, NPCs, creatures)
- Manages combat stats, damage calculation, and attack styles
- Is used by multiple systems beyond just the player
Keeping it at the top level in
lib.rs makes it a first-class system alongside other core plugins like WorldPlugin, DataPlugin, and MagicPlugin.Verification
After applying the fix:
cargo run --bin legends_clientExpected output (no duplicate plugin panic):
warning: `legends_client` (lib) generated 17 warnings
Finished `dev` profile [optimized + debuginfo] target(s) in 24.74s
Running `target/debug/legends_client`
2026-01-05T15:04:15.024388Z INFO ThreadId(01) Telemetry initialized. Metrics at http://localhost:9000/metrics
2026-01-05T15:04:15.025050Z INFO ThreadId(01) No plugin public key found at secrets/plugin_pub.key.
2026-01-05T15:04:15.049447Z INFO ThreadId(01) Creating new window "Legends of Hastinapur" (Entity { index: 0, generation: 1 })
2026-01-05T15:04:15.054415Z INFO ThreadId(22) Loaded quest: The Lost Scroll
2026-01-05T15:04:15.054443Z INFO ThreadId(22) Loaded quest: Blood and SteelVerification Status: ✅ CONFIRMED - The game launches successfully and enters the game loop.
General Pattern: Avoiding Duplicate Plugins
Detection
Bevy will panic with a clear error message:
Error adding plugin <PluginName>: : plugin was already added in applicationPrevention Strategies
- Centralize core plugins in
lib.rsor a dedicatedGamePlugin - Document plugin ownership in comments:
// CombatPlugin is registered in lib.rs as a core system - Use plugin groups to avoid scattered registrations:
pub struct CoreGamePlugins; impl PluginGroup for CoreGamePlugins { fn build(self) -> PluginGroupBuilder { PluginGroupBuilder::start::<Self>() .add(CombatPlugin) .add(DataPlugin) .add(MagicPlugin) } }
Finding Duplicate Registrations
Use
grep to search for plugin additions:grep -rn "add_plugins.*CombatPlugin" src/Output:
src/lib.rs:69: .add_plugins(systems::combat::CombatPlugin)
src/systems/player/mod.rs:93: crate::systems::combat::CombatPlugin,This immediately reveals the duplicate.
Related Issues
- Tracing panic: See tracing_panic_fix.md for the previous startup crash
- Plugin architecture: Consider creating a
GamePluginthat groups all core systems to avoid future duplicates
Files Modified
src/systems/player/mod.rs(line 93): Removed duplicateCombatPluginregistration