issues

Guide for issues

loh-game issues

In @src/systems/ui/xp_drops.rs at line 93, Replace the panic-causing call to contexts.ctx_mut().expect("No EGui Context") with graceful error handling: call contexts.ctx_mut(), match or use if let Ok(ctx) = ... to obtain the egui::Context and on Err(QuerySingleError) perform the same early-return behavior used elsewhere in this function (e.g., return early or log and return) so the function does not panic when the EGui context is unavailable; reference the contexts.ctx_mut() call and the QuerySingleError result type when making the change.
In @src/systems/ui/pathing_overlay.rs at line 95, Replace the panicking call contexts.ctx_mut().expect("No Egui Context") with a non-panicking check and skip rendering when the Egui context is missing: call contexts.ctx_mut(), if it returns None return early from the system/function (or otherwise skip the .show(...) block), and if it returns Some(ctx) use that ctx in the .show(..., |ui| { ... }) invocation so the UI rendering never panics when the context is unavailable.
Same expect() concern for EGui context.
Both render_minimap and render_world_map use expect() which will panic if no context exists. Consider graceful handling as suggested for plugin_notifications.rs.
♻️ Suggested refactor
  • let ctx = contexts.ctx_mut().expect("No EGui Context");
  • let Some(ctx) = contexts.ctx_mut() else {
  • return;
  • }; Also applies to: 137-137
In @src/systems/ui/milestone_notifications.rs at line 91, The milestone notification code uses contexts.ctx_mut().expect("No EGui Context") which will panic if the Egui context is missing; change this to a non-panicking guard: check contexts.ctx_mut() for None and early-return (or skip rendering) so the system gracefully defers rendering to the next frame instead of crashing—locate the use of contexts.ctx_mut() and replace the expect call with an if-let or match that binds ctx when Some and otherwise returns/continues.
In @src/systems/ui/login.rs at line 115, The call to connect_events.write(ConnectToServerEvent) uses the wrong EventWriter API; replace the .write(...) invocation with .send(ConnectToServerEvent) on the EventWriter instance (connect_events) so the ConnectToServerEvent is dispatched correctly.
In @src/systems/world/resources.rs around lines 87 - 92, The HarvestAttemptEvent and other event structs are using the nonexistent Message trait and .add_message API; replace #[derive(Debug, Clone)] with #[derive(Event)] on HarvestAttemptEvent (and other event structs), remove any manual impl Message blocks, change all .add_message::() calls to .add_event::() and delete any use bevy::prelude::Message imports so the code uses Bevy 0.17's #[derive(Event)]
  • .add_event API consistently.
In @src/systems/ui/login.rs at line 101, The code uses EventWriter::write when emitting ClientRequestEvent; replace the call to request_events.write(ClientRequestEvent(data)) with request_events.send(ClientRequestEvent(data)) so the event is emitted via the correct EventWriter API (keep the ClientRequestEvent constructor/argument the same).
In @src/systems/ui/login.rs at line 31, The code currently uses contexts.ctx_mut().expect("No EGui Context") which will panic if the EGui context is unavailable; change this to pattern-match the Result and return early on error, e.g., use let Ok(ctx) = contexts.ctx_mut() else { return; } so the login UI system (where ctx is used) exits gracefully when the context is missing instead of panicking.
In @src/systems/ui/hover_text.rs at line 34, The code panics by calling expect() on contexts.ctx_mut() in the hover text system; change it to gracefully skip rendering when the Egui context is absent by checking the Option and returning early (e.g., use if let Some(ctx) = contexts.ctx_mut() or match to only run the rendering logic when ctx is Some), ensuring the rest of the system continues without a panic.
In @src/systems/tutorial.rs around lines 512 - 517, Remove the invalid impl Message for ... blocks for StartTutorialEvent, TutorialStepCompleteEvent, TutorialCompleteEvent, and SkipTutorialEvent; delete the four impl lines referencing Message and rely on Bevy's Event system (EventReader/EventWriter) or proper derives if you intended a deriveable type, ensuring no Message trait implementations remain in tutorial.rs.
In @src/systems/tutorial.rs around lines 496 - 499, The event registration calls currently use add_message for the tutorial events; replace each .add_message::(), .add_message::(), .add_message::(), and .add_message::() with .add_event::<...>() so the system registers these as events rather than messages (update the chain where these four entries occur to use .add_event for each specific event type).
In @src/systems/tutorial.rs around lines 416 - 420, The code uses add_item_events.write(...) but EventWriter requires .send(...); replace the .write call with add_item_events.send(AddItemEvent { entity: event.player, item: item_id(&item_reward.item_id), quantity: item_reward.quantity as i64 }); ensuring you call send on the add_item_events EventWriter when emitting AddItemEvent.
In @src/systems/tutorial.rs around lines 368 - 371, The code is calling EventWriter::write via complete_events.write(...) which is incorrect for Bevy's EventWriter API; replace the call with complete_events.send(TutorialCompleteEvent { player: event.player, tutorial_id: event.tutorial_id.clone() }) so the EventWriter sends the event using send() instead of write(); update the invocation where TutorialCompleteEvent is constructed (complete_events) accordingly.
In @src/systems/tutorial.rs around lines 141 - 144, The struct SkipTutorialEvent lost the Event derive; restore it by adding Event to the derive list for SkipTutorialEvent (e.g., #[derive(Event, Debug, Clone)]) and ensure the Event derive macro is in scope by importing the appropriate bevy event derive (e.g., bring the bevy Event derive into scope via the existing Bevy prelude or the correct bevy_ecs_macros import).
In @src/systems/tutorial.rs around lines 135 - 139, The TutorialCompleteEvent struct lost its Event derive; restore it by changing the derive to include Event (e.g. #[derive(Debug, Clone, Event)]) on the TutorialCompleteEvent declaration and ensure the Event derive macro is in scope (import from Bevy prelude or appropriate crate where Event is defined) so the type is registered as an ECS event.
In @src/systems/tutorial.rs around lines 128 - 133, The TutorialStepCompleteEvent struct lost the Event derive; restore it by adding Event to its derive list for TutorialStepCompleteEvent (e.g., #[derive(Event, Debug, Clone)]) and, if the Event derive macro is not in scope, import the appropriate derive (e.g., bring bevy's Event derive into scope via prelude or the crate that provides it) so the struct is recognized as an event type.
In @src/systems/tutorial.rs around lines 122 - 126, The StartTutorialEvent struct lost the Event derive; add Event back to its derive list (e.g., #[derive(Event, Debug, Clone)] on StartTutorialEvent) and ensure the Event derive macro is in scope by importing it (for example add use bevy::prelude::Event or the appropriate bevy event derive import used elsewhere in the crate).
In @src/systems/player/skills.rs around lines 100 - 103, Remove the invalid Bevy trait implementation by deleting the lines that implement the nonexistent Message trait: the two impl Message for XpGainEvent {} and impl Message for LevelUpEvent {} declarations; ensure no other references to Message remain (e.g., imports like use bevy::prelude::Message) and run a build to confirm the compiler no longer expects that trait.
In @src/systems/player/skills.rs around lines 50 - 55, The XpGainEvent struct lost the Event derive; restore it by adding Event to the derive on XpGainEvent (e.g., #[derive(Debug, Clone, Event)]) and ensure the Event derive macro is in scope (import the crate/module that exports the Event derive) so the XpGainEvent type is recognized as an event by the system.
In @src/systems/player/skills.rs around lines 43 - 44, The code calls app.add_message::() and app.add_message::(), but Bevy 0.17 removed add_message; replace those calls with app.add_event::() and app.add_event::() respectively so the XpGainEvent and LevelUpEvent are registered correctly with the Bevy App.
In @src/systems/player/inventory.rs around lines 236 - 241, Move the use bevy::prelude::Message; import from its current location near the bottom of the file into the module's top-level imports with the other bevy::prelude imports, then delete the now-duplicate use line that sits directly above the impl Message for AddItemEvent {} / impl Message for RemoveItemEvent {} / impl Message for DropItemEvent {} / impl Message for UseItemEvent {} blocks so those impls remain unchanged but the import is colocated with other module imports for clarity.
In @src/systems/network/mod.rs around lines 208 - 212, Remove the invalid manual implementations of the bevy::prelude::Message trait: delete the three impl blocks "impl Message for ServerMessageEvent {}", "impl Message for ClientRequestEvent {}", and "impl Message for ConnectToServerEvent {}". If these event types need to be messages, instead derive or implement the correct event/message pattern supported by Bevy (e.g., use #[derive(Message)] or register them as events via App::add_event::<...>()); do not provide empty manual impls for Message.
In @src/systems/network/mod.rs at line 187, Replace the incorrect EventWriter call: change the use of events.write(ServerMessageEvent(msg)) to events.send(ServerMessageEvent(msg)) so the EventWriter API is used correctly; locate the call that constructs ServerMessageEvent(msg) in the network system (EventWriter variable named events) and swap .write() for .send().
In @src/systems/network/mod.rs around lines 53 - 55, The code registers events using add_message; change those calls to add_event for the types ServerMessageEvent, ClientRequestEvent, and ConnectToServerEvent so the system uses the correct event registration API: replace .add_message::(), .add_message::(), and .add_message::() with .add_event::(), .add_event::(), and .add_event::() respectively.
In @src/systems/network/mod.rs around lines 34 - 35, The ConnectToServerEvent struct lost the Event derive; restore it by adding the Event derive to the derive list for ConnectToServerEvent (i.e., change #[derive(Debug, Clone)] to #[derive(Debug, Clone, Event)]) and ensure the Event derive macro is in scope (import the appropriate derive macro or module where Event is defined) so the struct continues to function as an event type.
In @src/systems/network/mod.rs around lines 18 - 19, The struct ClientRequestEvent lost its Event derive; restore it by adding Event to the derive list so it reads #[derive(Debug, Event)] for ClientRequestEvent and ensure the Event derive macro is in scope (import the crate/module that provides the Event derive, e.g., bring the appropriate bevy/prelude Event derive into scope) so the compilation and event system integration succeed.
In @src/systems/network/mod.rs around lines 14 - 15, The ServerMessageEvent struct lost its Event derive; restore it by adding the Event derive alongside Debug on ServerMessageEvent (i.e., derive Event) and ensure the Event derive macro is in scope so the type is registered as a Bevy event; update any relevant imports so the Event derive is available for the ServerMessageEvent struct.
In @src/systems/data/async_loader.rs around lines 550 - 552, Remove the invalid Message trait impl: delete the block "impl Message for LoadingProgressEvent {}" and the now-unused "use bevy::prelude::Message;" import (or keep the import only if used elsewhere) so LoadingProgressEvent is not incorrectly declared as implementing bevy::prelude::Message.
src/systems/combat/tests.rs Comment on lines +60 to +61 app.add_message::(); app.add_message::(); @coderabbitai coderabbitai bot 8 minutes ago ⚠️ Potential issue | 🟡 Minor
🧩 Analysis chain Use EventReader/EventWriter in tests for consistency with production code.
Tests register events with add_message::() but dispatch via manual send_event() and read using Events::get_reader() (lines 67, 79, 90-92). Production code in mod.rs uses EventReader/EventWriter system parameters. Refactor tests to use the same system parameter pattern for consistency.
Also applies to: line 100, 133-135
In @src/systems/combat/passives.rs around lines 249 - 252, The Message import is placed at the bottom next to the impls for PassiveTriggerEvent and StatusExpiredEvent; move the use bevy::prelude::Message line into the module's top-level import block so it is consolidated with other imports, and then keep the two impl Message for PassiveTriggerEvent {} and impl Message for StatusExpiredEvent {} declarations unchanged.
In @src/systems/combat/floating_damage.rs at line 109, Replace the panic-causing call that forces an Egui context with a graceful early exit: instead of using let ctx = contexts.ctx_mut().expect("No EGui Context");, check for presence (e.g., if let Some(ctx) = contexts.ctx_mut() { … } else { return; }) and skip the floating-damage rendering for that frame when the context is missing; update any downstream uses of ctx inside the same function/block to be inside the conditional branch.
In @src/systems/camera/mod.rs at line 179, Replace the panicking expect call on contexts.ctx_mut() with a defensive pattern: call contexts.ctx_mut() and match or use if let to handle None, deriving egui_params via ctx.wants_pointer_input() when Some(ctx) and using a sensible default (e.g., false) or early-return behavior when None; update the variable egui_params and any downstream logic that depends on it so it works with the non-panicking branch. Ensure you reference contexts.ctx_mut(), wants_pointer_input(), and the egui_params variable when making the change.
In @src/systems/camera/mod.rs around lines 3 - 9, Remove the exploratory commented-out imports and developer notes in src/systems/camera/mod.rs (e.g., the commented lines referencing use bevy::render::primitives::Aabb and use bevy::render::view::Visibility and the surrounding notes); leave only the actual needed imports and, if Aabb or Visibility are required, replace the commented attempts with the correct imports (e.g., use bevy::render::mesh::Aabb or use bevy::prelude::Visibility) or a single TODO comment with a ticket reference — do not keep the failed/import trial comments or developer notes in the file.
In @src/systems/audio/sfx.rs around lines 66 - 70, Move the use bevy::prelude::Message; import up into the module's top import block alongside the other use statements for consistency; update src/systems/audio/sfx.rs so Message is imported before the impl Message for PlaySfxEvent {} declaration (referencing the PlaySfxEvent type and the impl Message block) to keep imports organized.
In @src/systems/analytics/mod.rs around lines 52 - 54, Replace the generic window query and iterator usage with Bevy 0.17's PrimaryWindow pattern: change the query type to Query<&Window, With> (or use &mut Window if you need mutability) and replace the windows.iter().next() logic with windows.get_single() (handling the Result/Option it returns) so the system explicitly requests the primary window; update any variable names that reference windows to reflect the single primary window (e.g., window) and handle the err/none case similarly to the previous early return.
In @src/plugin_api/bevy_plugin.rs around lines 462 - 466, Replace the incorrect EventWriter call using interaction_events.write(...) with the proper send API: call interaction_events.send(...) passing the constructed crate::systems::api::InteractionEvent { source: player_entity, target, interaction_type: itype } instance; update any surrounding code that assumed write()’s return to use send() which returns () and ensure the symbol interaction_events (the EventWriter) is used with .send rather than .write.
In @src/plugin_api/bevy_plugin.rs around lines 280 - 281, Remove the stray debug println in the process_automation_commands path: delete the line printing "DEBUG: process_automation_commands skipping - Player query failed." and replace it with no output (or a proper logging call if necessary) so that the function no longer emits a debug STDOUT message when the player query fails; locate the println! in the process_automation_commands function in bevy_plugin.rs and remove it.
In @src/plugin_api/bevy_plugin.rs at line 91, Remove the loud tick debug print in tick_plugins_system: delete the println!("DEBUG: tick_plugins_system running. Player Query Single: {:?}", ...) or replace it with a conditional debug log (e.g., log::debug! / tracing::debug!) or wrap it with a runtime/compile-time guard such as if cfg!(debug_assertions) { ... } so it no longer floods the console on every tick; target the println invocation in tick_plugins_system for the change.
In @migrate_events.py around lines 51 - 57, The current derive-replacement logic can leave stray commas/spaces; update the block that computes new_derives and replacement_derive to robustly parse the derive list: extract the inner content from the derives string, split on commas, trim each item, filter out any item equal to 'Event' or empty, then join with ', ' to form new_derives; if the filtered list is empty set replacement_derive to the fallback '#[derive(Debug, Clone)]', otherwise set replacement_derive = f'#[derive({new_derives})]'. Use the existing variables new_derives and replacement_derive to replace the brittle replaces.
In @migrate_events.py at line 42, Remove the unused variable offset_corrections from migrate_events.py by deleting the assignment "offset_corrections = 0" (and any other unused occurrences of offset_corrections) so there are no dead variables; if the variable was intended for future logic, either implement that logic in the relevant function or add a clear TODO comment instead of leaving an unused assignment.
In @Cargo.toml at line 27, The Cargo.toml entry for the big-brain git dependency is unpinned which breaks reproducible builds; update the big-brain dependency line in Cargo.toml to reference a specific commit hash or an exact tag (e.g., add rev = "COMMIT_HASH" or tag = "vX.Y.Z") instead of the bare git URL, and verify that the chosen commit/tag is compatible with Bevy 0.17 before committing the change.
In @client_log.txt around lines 232 - 244, The systems capture_input_metrics, handle_add_friend, and handle_remove_friend are still using EventWriter (and send_client_requests uses EventReader) while ClientRequestEvent is registered as a message; replace those EventWriter/EventReader types with MessageWriter and MessageReader respectively in the system function signatures and any local variable types, update the corresponding use/import lines (bring MessageWriter and MessageReader into scope), and adjust any method calls if needed to the message API so the systems consume/produce messages instead of events.
In @migrate_events.py around lines 5 - 6, The open call explicitly passes the 'r' mode even though it's the default; change the line using open(filepath, 'r') in the code that reads file content to simply open(filepath) (e.g., in the block that assigns content = f.read()) so the explicit 'r' is removed while preserving the with context and the content = f.read() behavior.
In @migrate_events.py around lines 5 - 6, The open call explicitly passes the 'r' mode even though it's the default; change the line using open(filepath, 'r') in the code that reads file content to simply open(filepath) (e.g., in the block that assigns content = f.read()) so the explicit 'r' is removed while preserving the with context and the content = f.read() behavior.
The .send() → .write() replacement is overly aggressive.
The regex (\w+events?|writer).send( may incorrectly replace .send() calls on non-EventWriter types (e.g., channel senders, custom types with "events" in their name).
Consider removing this automatic replacement and relying on compiler errors to guide manual fixes, or use a more targeted pattern.
In @migrate_events.py around lines 99 - 103, The for-loop over os.walk uses an unused variable named dirs; rename it to _dirs in the loop header (for root, _dirs, files in os.walk("src")) to indicate it's intentionally unused and avoid linter warnings, leaving the rest of the logic (calling migrate_file(os.path.join(root, file)) and incrementing files_changed) unchanged.
In @README.md around lines 1 - 81, The README has markdown lint issues: add a blank line before and after each heading (e.g., "# Legends of Hastinapur - Game Client", "## 📁 Repository Structure", "## 🛠 Prerequisites", "### 1. Rust Toolchain", etc.), ensure fenced code blocks have a language specifier (use bash for shell snippets and plaintext or ```text where appropriate) and are surrounded by blank lines (e.g., the repository structure block, the git clone snippet, Mold installation, fallback RUSTFLAGS snippet, system dependencies and run/test examples); update each offending block and heading accordingly for consistent spacing and language tags.
In @src/systems/headless_stubs.rs around lines 29 - 78, The added registrations using app.add_message::() are wrong because the event types (e.g., NPCInteractionEvent, DropLootEvent, PickupItemEvent, PluginNotificationEvent, OpenBankEvent, DepositItemEvent, WithdrawItemEvent, PurchaseAttemptEvent, PurchaseSuccessEvent, PurchaseFailedEvent, ActivatePrayerEvent, DeactivatePrayerEvent, RestorePrayerEvent, HealEvent, MineRockEvent, FishCatchEvent, CookSuccessEvent, CookBurnEvent, EatFoodEvent, SmeltSuccessEvent, SmithSuccessEvent, ChopTreeEvent, SelectSpellEvent, CastSpellEvent, BrewSuccessEvent, DrinkBrewEvent, PlantSeedEvent, HarvestPatchEvent, CureDiseaseEvent, ClearPatchEvent) lack the required Message derive/trait bounds and the rest of the code still uses EventReader/EventWriter (old Bevy API). Fix by either (A) reverting to the old API: replace app.add_message::() with app.add_event::() so existing EventReader/EventWriter usages continue to compile, or (B) fully migrate: add #[derive(Message)] and ensure each event type meets Message: Send + Sync + 'static, then update all EventReader/EventWriter usages across the codebase to the new message reader/writer APIs; pick one approach and make the matching changes for all the listed event types referenced in the diff.
In @src/systems/player/interaction.rs around lines 44 - 48, The code mixes graceful early-return for camera_q (let Some((camera, camera_transform)) = camera_q.iter().next() else { ... return; }) with a panicking windows.iter().next().expect("No primary window"); make handling consistent by replacing the expect on windows with a non-panicking check: attempt windows.iter().next(), log an informational or error message and return early if None (similar to the camera check), so the system guarded by is_not_headless never panics when a window is absent.
Critical: Game logic now runs at frame rate instead of tick rate.
Removing run_if(on_event::()) causes tick_movement_system to execute every visual frame rather than once per game tick. This breaks the separation between game logic and visual interpolation:
Path consumption: Entire path processed in a single game tick across multiple frames Energy depletion: Energy costs deducted at 60+ fps instead of tick rate Frame-rate dependency: Movement logic now varies with frame rate The comments suggest migrating to messages, but tick_movement_system (lines 171-199) contains no message/event reader logic. Without gating, the system processes ActivePath entities unconditionally every frame.
In @src/systems/player/prayer.rs around lines 365 - 369, Move the use bevy::prelude::Message; import up into the file's existing import block with the other Bevy imports (so it lives alongside other bevy::prelude uses) and remove the duplicate use near the bottom; keep the three impl Message for ... lines (ActivatePrayerEvent, DeactivatePrayerEvent, RestorePrayerEvent) unchanged so they reference the globally imported Message.
In @src/systems/player/prayer.rs around lines 365 - 369, Move the use bevy::prelude::Message; import up into the file's existing import block with the other Bevy imports (so it lives alongside other bevy::prelude uses) and remove the duplicate use near the bottom; keep the three impl Message for ... lines (ActivatePrayerEvent, DeactivatePrayerEvent, RestorePrayerEvent) unchanged so they reference the globally imported Message.
In @src/systems/scenarios/mod.rs around lines 239 - 245, Move the bevy::prelude::Message import from the bottom of the file into the top import block with the other use statements, then relocate the three impl Message blocks so they directly follow the event struct/type definitions (i.e., immediately after the StartScenarioEvent/WaveStartedEvent/ScenarioCompletedEvent declarations) instead of at the end of the file; finally remove the duplicate impls currently at the bottom (the impl Message for StartScenarioEvent, impl Message for WaveStartedEvent, impl Message for ScenarioCompletedEvent).
In @src/systems/skills/brewing.rs around lines 486 - 492, Move the use bevy::prelude::Message; import to the top with other imports, remove the manual empty impls for BrewAttemptEvent, BrewSuccessEvent, and DrinkBrewEvent, and instead add #[derive(Message)] to each of those event struct definitions (BrewAttemptEvent, BrewSuccessEvent, DrinkBrewEvent) so they use the derive macro idiomatically and avoid the bottom-of-file manual impls.
In @src/systems/skills/smithing.rs around lines 382 - 389, The manual impls of the Message trait are redundant—delete the impl Message for SmeltOreEvent {}, impl Message for SmithItemEvent {}, impl Message for SmeltSuccessEvent {}, and impl Message for SmithSuccessEvent {} blocks and instead add #[derive(Message)] to the corresponding event structs (SmeltOreEvent, SmithItemEvent, SmeltSuccessEvent, SmithSuccessEvent); keep or add use bevy::prelude::Message if needed and remove the now-unneeded manual impl section.
In @src/systems/social/mod.rs around lines 45 - 47, The code silently drops serialization errors when calling serialize_packet(&GamePacket::AddFriendRequest(req)) and similar calls; change the block that currently does "if let Ok(data) = serialize_packet(...)" to match on the Result and log the Err (including error details and context like "failed to serialize AddFriendRequest") before returning/continuing; also resolve the Message/Event API mismatch by replacing EventWriter with MessageWriter (or change the registration to .add_event() if you intend to keep EventWriter) so the writer type matches the .add_message() registration; apply the same logging + writer-type fix to the other occurrences mentioned (src/systems/ui/login.rs and src/systems/analytics/mod.rs) and ensure the log messages include the packet variant and error details for easier debugging.
In @src/systems/ui/character_creation.rs around lines 111 - 116, The cleanup loop currently calls commands.entity(entity).despawn() which will orphan child entities; change both loops to use the recursive despawn API (e.g., commands.entity(entity).despawn_recursive()) so that CharacterPreview and its spawned children (body parts, hair) created by update_character_preview are removed together; update both uses where you iterate over query and cam_query, ensuring the CharacterPreview-rooted entities are destroyed with their children.
In @src/systems/ui/character_creation.rs around lines 236 - 239, The code currently calls commands.entity(entity).despawn() in the model_q loop which will orphan children created with with_children() (see the body/hair attachments in the block around lines 249-318); change the removal to recursively remove descendants—e.g. call the appropriate Bevy API to despawn children as well (replace despawn() with despawn_recursive() or first call despawn_descendants() then despawn() depending on your Bevy version) for each entity in the model_q iterator so parents and their attached children are removed together.
In @src/systems/ui/chat_ui.rs around lines 245 - 247, The call to CornerRadius::same currently uses an unnecessary cast (8.0 as u8) which truncates and then converts back; update the egui::Frame::default() chain (the .corner_radius(...) invocation that follows Color32::from_rgba_unmultiplied) to pass a float directly (e.g., 8.0) to CornerRadius::same so it uses the expected Into and remove the cast.
In @src/systems/world/triggers.rs around lines 285 - 289, The implementation of the Bevy Message trait for TriggerActivatedEvent is correct but the diff contains extra leading blank lines and an unnecessary comment; clean up by removing the extraneous empty lines and/or the "Migration: Implement Message for converted Events" line while keeping the import use bevy::prelude::Message; and the impl block impl Message for TriggerActivatedEvent {} intact so the marker trait remains in place.
In @src/systems/ui/xp_drops.rs at line 93, Replace the panic-causing call to contexts.ctx_mut().expect("No EGui Context") with graceful error handling: call contexts.ctx_mut(), match or use if let Ok(ctx) = ... to obtain the egui::Context and on Err(QuerySingleError) perform the same early-return behavior used elsewhere in this function (e.g., return early or log and return) so the function does not panic when the EGui context is unavailable; reference the contexts.ctx_mut() call and the QuerySingleError result type when making the change.
In @src/systems/ui/tutorial_arrows.rs around lines 142 - 145, ShowTutorialArrowEvent is consumed via EventReader in spawn_tutorial_arrow but no longer implements the Event trait; restore the Event derive on the ShowTutorialArrowEvent struct (i.e., derive Event alongside Debug, Clone) and remove the redundant impl Message block that was added for it (similar to the fix for RareDropEvent) so the event type is usable with Bevy's EventReader.
In @src/systems/ui/skills_ui.rs at line 98, Replace the unnecessary float-to-u8 cast in the corner radius call: locate the .corner_radius(egui::CornerRadius::same(4.0 as u8)) invocation and change it to use an integer literal accepted by CornerRadius::same, e.g. .corner_radius(egui::CornerRadius::same(4u8)) or .corner_radius(egui::CornerRadius::same(4)).
In @src/systems/ui/session_summary.rs around lines 105 - 107, The code uses the non-public CornerRadius::same API in the frame builder (.corner_radius(egui::CornerRadius::same(8.0 as u8))) which won't compile; replace that call with an explicit CornerRadius value such as .corner_radius(egui::CornerRadius { nw: 8.0, ne: 8.0, sw: 8.0, se: 8.0 }) (use f32 literals) in src/systems/ui/session_summary.rs and apply the same replacement for other occurrences across the codebase.
In @migrate_events.py around lines 5 - 6, The open call explicitly passes the 'r' mode even though it's the default; change the line using open(filepath, 'r') in the code that reads file content to simply open(filepath) (e.g., in the block that assigns content = f.read()) so the explicit 'r' is removed while preserving the with context and the content = f.read() behavior.
In @client_log.txt around lines 196 - 229, Plugin manifests for plugins/test_runner, plugins/e2e_skills_test, and plugins/e2e_combat_test are missing the required author field causing TOML parse/validation failures; open each plugin's manifest (the [plugin] table) and add an author entry (e.g., author = "Your Name") alongside existing name and version keys so the [plugin] table includes name, version, and author exactly as required.
In @src/systems/ui/chat_ui.rs around lines 284 - 286, The corner_radius call on egui::Frame::default() uses an unnecessary cast (egui::CornerRadius::same(8.0 as u8)); remove the cast and pass a float directly (egui::CornerRadius::same(8.0)) so the corner radius uses the correct f32/f64 literal consistently with the other frame usage.
In @src/systems/skills/mining/mining_tests.rs around lines 111 - 113, The test currently registers MineRockEvent, AddItemEvent, and XpGainEvent but is marked #[ignore] claiming E2E coverage that doesn't exist; either implement a mining E2E test that advances real Time and asserts mining level requirements (create a test analogous to the other skills' E2E tests that uses the same Time-advancement helper, fires MineRockEvent, awaits outcomes and verifies level gating and XP/AddItem behavior for MineRockEvent/AddItemEvent/XpGainEvent), or update the #[ignore] attribute’s message to honestly state the behavior is currently untested rather than claiming E2E coverage.
In @src/systems/player/equipment.rs around lines 181 - 186, Move the bevy::prelude::Message import and the impl Message for EquipItemEvent {} / impl Message for UnequipItemEvent {} declarations from the bottom of the file to immediately after the struct definitions for EquipItemEvent and UnequipItemEvent so the trait impls sit next to their types; then remove the duplicate import/impls at the file end to avoid redundancy.
In @src/systems/player/combat_interaction.rs around lines 17 - 18, Replace the panicking .expect() calls on camera_q.iter().next().expect("No camera") and windows.iter().next().expect("No primary window") with non-panicking early returns: check for Some(...) using if let or match, optionally log a warning, and return early from the function (or control flow) when the camera or primary window is missing so the system won't panic during startup/shutdown or when resources are temporarily unavailable.
In @src/systems/player/animations.rs around lines 101 - 102, The loop unnecessarily calls clone() on a Copy type (Entity); remove the redundant clone by iterating by value instead: replace the pattern "for child in children.iter() { let child = child.clone(); ... }" with either "for &child in children.iter() { ... }" or simply "for child in children { ... }" (or "for child in children.iter().copied() { ... }"), eliminating the explicit clone() call and keeping the rest of the code using child as before.
In @src/systems/loot/kill_tracker.rs around lines 227 - 231, The migration added an orphaned import and impl for Message (remove the use bevy::prelude::Message; and impl Message for RareDropEvent {}) because RareDropEvent uses #[derive(Event)] and is consumed via EventReader; delete this migration block so only the #[derive(Event)]-based event type remains and EventReader usage stays correct.
In @src/systems/ui/click_marker.rs at line 53, The call constructs Quat::from_rotation_x(std::f32::consts::FRAC_PI_2) for every marker; extract this constant rotation into a local variable (e.g., let ground_rot = Quat::from_rotation_x(std::f32::consts::FRAC_PI_2)) outside the marker loop and use ground_rot in the gizmos.circle call (the call invoking gizmos.circle(Isometry3d::new(pos, Quat::from_rotation_x(...)), ...)) to improve clarity and avoid repeated construction.
In @src/systems/ui/click_marker.rs around lines 63 - 66, The timer-based despawn currently checks marker.timer.is_finished() which stays true each frame; change this to marker.timer.just_finished() so the entity is despawned only on the tick the timer transitions to finished—update the conditional from marker.timer.is_finished() to marker.timer.just_finished() where marker.timer.tick(time.delta()) is called before commands.entity(entity).despawn().
In @src/systems/ui/combat_ui.rs at line 124, The call to painter.rect_stroke is incorrectly passing egui::StrokeKind::Middle into Stroke::new; update the invocation so Stroke::new only receives (width, color) and egui::StrokeKind::Middle is supplied as the final parameter to rect_stroke — i.e., locate the painter.rect_stroke(...) call (the one using Stroke::new and egui::StrokeKind::Middle) and move egui::StrokeKind::Middle out of Stroke::new into the rect_stroke parameter list while keeping the same width/color arguments.
In @src/systems/ui/crafting_ui_refactored.rs at line 24, The call contexts.ctx_mut().expect("No EGui Context") panics if the EGui context is missing; change it to handle absence gracefully by checking the Option/Result returned (e.g., if let Some(ctx) = contexts.ctx_mut() { ... } else { log::warn!("No EGui Context in crafting UI system"); return; }) so the system returns early instead of panicking; update the variable usage from the existing ctx expectation to the scoped ctx binding and add a short warning log before returning.
In @src/systems/ui/friends_ui.rs around lines 187 - 192, The PR mixes Bevy 0.17 event APIs with Cargo set to bevy = "0.15"; pick one target and make the code consistent: either upgrade to Bevy 0.17 and replace manual impl Message blocks with #[derive(Message)] on event structs (e.g., AddFriendEvent, RemoveFriendEvent, AddIgnoreEvent, RemoveIgnoreEvent, SendPrivateMessageEvent, FriendStatusUpdateEvent), change registrations to use add_message(...) and consumers like handle_friend_status_updates to use MessageReader (and update EventReader usages), or stay on Bevy 0.15 and revert registrations to add_event::<...>() and use EventWriter/EventReader types throughout (remove add_message usages and the #[derive(Message)]). Ensure the same event types and reader/writer APIs are used everywhere (registration, derives/impls, and handle_friend_status_updates).
#[derive(Debug, Clone, Message)] pub struct AddFriendEvent { pub name: String, }
In @src/systems/ui/guard_captain_shop.rs around lines 1 - 8, Remove the duplicate import and exploratory comment lines: delete the second redundant use bevy::prelude::*; and remove the commented-out // use bevy::render::camera::Viewport; (and its surrounding notes) so only one use bevy::prelude::*; remains alongside use bevy_egui::{egui, EguiContexts}; and use std::time::Instant;, keeping imports clean and minimal.
In @src/systems/ui/level_up_ui.rs at line 117, Replace the panic-causing call to contexts.ctx_mut().expect("No EGui Context") with an early return when the Egui context is missing: call contexts.ctx_mut() (or contexts.try_ctx_mut() if available) and if it returns None, return early from the function (mirroring the handling already used around lines 107-115) so the system degrades gracefully instead of panicking; update the local variable binding to use the Option-unwrap pattern (if let Some(ctx) = ...) and proceed only when ctx is present.
In @src/systems/ui/music_ui.rs around lines 19 - 27, The system parameters that currently use EventWriter for message-registered types must be changed to MessageWriter: replace any function parameters typed as &mut EventWriter and &mut EventWriter with &mut MessageWriter and &mut MessageWriter respectively (e.g., the UI system function in music_ui.rs that writes SetMusicModeEvent and PlayTrackEvent); also update the corresponding signatures/usages in the UI module where those same events are written so they accept and call MessageWriter instead of EventWriter.