64kramsystem / learn_bevy_ecs_by_ripping_off-code

Code for my mini-book "Learn Bevy's ECS by ripping off someone else's project"
MIT License
19 stars 2 forks source link

running port/15_Loot_02_better_combat and the using item results in a crash #2

Closed myers closed 2 years ago

myers commented 2 years ago

First off, thank you for this project.

If you run the final project, get an item and then attempt use it (number key) the game will crash

  Compiling rusty_roguelike-bevy v0.1.0 (/Users/myers/p/learn-rust/hands-on-rust/vendor/learn_bevy_ecs_by_ripping_off-code/port/15_Loot_02_better_combat)
    Finished dev [unoptimized + debuginfo] target(s) in 1.67s
     Running `target/debug/rusty_roguelike-bevy`
Initialized OpenGL with: 4.1 ATI-4.9.48, Shader Language Version: 4.10
thread 'TaskPool (10)' panicked at 'Attempting to create an EntityCommands for entity 1v0, which doesn't exist.', src/systems/use_items.rs:24:18
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
thread 'main' panicked at 'task has failed', /Users/myers/.cargo/registry/src/github.com-1ecc6299db9ec823/async-task-4.3.0/src/task.rs:426:45
thread 'main' panicked at 'Task thread panicked while executing.: Any { .. }', /Users/myers/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_tasks-0.7.0/src/task_pool.rs:77:21
myers commented 2 years ago
    app.add_system_set_to_stage(
        MonsterCombat,
        ConditionSet::new()
            .run_if_resource_equals(MonsterTurn)
            // FIXME monsters can't use items.  It seems like if we add this here it gets a 2nd copy of events
            // .with_system(use_items::use_items)
            .with_system(combat::combat)
            .into(),
    );
64kramsystem commented 2 years ago

Hi there! Thanks for your reports!! :smile:

I'll have a look at this and the other issue in the next days, then follow up :smile:

64kramsystem commented 2 years ago

Hm. The error has been introduced at stage 13_InventoryAndPowerUps_02_carrying_items. :thinking:

64kramsystem commented 2 years ago

Fixed. Thanks for your contribution :smile:

64kramsystem commented 2 years ago

First off, thank you for this project.

If you run the final project, get an item and then attempt use it (number key) the game will crash

  Compiling rusty_roguelike-bevy v0.1.0 (/Users/myers/p/learn-rust/hands-on-rust/vendor/learn_bevy_ecs_by_ripping_off-code/port/15_Loot_02_better_combat)
    Finished dev [unoptimized + debuginfo] target(s) in 1.67s
     Running `target/debug/rusty_roguelike-bevy`
Initialized OpenGL with: 4.1 ATI-4.9.48, Shader Language Version: 4.10
thread 'TaskPool (10)' panicked at 'Attempting to create an EntityCommands for entity 1v0, which doesn't exist.', src/systems/use_items.rs:24:18
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
thread 'main' panicked at 'task has failed', /Users/myers/.cargo/registry/src/github.com-1ecc6299db9ec823/async-task-4.3.0/src/task.rs:426:45
thread 'main' panicked at 'Task thread panicked while executing.: Any { .. }', /Users/myers/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_tasks-0.7.0/src/task_pool.rs:77:21

Just for your information, this problem is due to a mismatch in design between the source project and the port.

The source project uses components. On the first invocation of use_items, the message and item entities are despawned. The second invocation will therefore not any messages/items.

The port uses events though. So the first invocation will despawn the item entities. But the second call, due to how events work (that is, there are two listeners, and both will receive the same set of events), will cycle again, and try to despawn items which have already been despawned in the first invocation, causing the crash.

The corresponding part in the source project is described on page 254 of the book.

myers commented 1 year ago

I'm revisiting this, adding a log that would have messages like "A goblin strikes you", and I think that I'm running into the same problem: systems that's added multiple times in your app that are EventReader's, will get the same event for each time it's in the App. So for combat it's in the player turn and the monster turn, so each event will play twice.
Resulting in Ettins killing you with one blow as they hit twice.

64kramsystem commented 1 year ago

I'm revisiting this, adding a log that would have messages like "A goblin strikes you", and I think that I'm running into the same problem: systems that's added multiple times in your app that are EventReader's, will get the same event for each time it's in the App. So for combat it's in the player turn and the monster turn, so each event will play twice. Resulting in Ettins killing you with one blow as they hit twice.

Right! I've opened a new issue. Thanks for the notification :smile: