Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Boss Bar API #371

Merged
merged 26 commits into from
Jun 20, 2023
Merged

Boss Bar API #371

merged 26 commits into from
Jun 20, 2023

Conversation

pepperoni21
Copy link
Contributor

@pepperoni21 pepperoni21 commented Jun 17, 2023

Description

Hey, I started working on this issue #337.

So far:

  • I created a crate "valence_boss_bar" and I moved this packet there
  • I initialized the plugin and added a system that removes the players when a boss bar is despawned.
  • I created/moved the boss bar components (BossBarTitle, BossBarHealth, BossBarStyle, BossBarFlags and BossBarViewers)
  • I added systems that handle the update of boss bar attributes and player disconnection
  • I documented the code
  • I made unit tests

Playground

I've tested the API in playground and it works fine.

mp4.mp4.online-video-cutter.com.mp4

crates/valence_boss_bar/src/components.rs Outdated Show resolved Hide resolved
crates/valence_boss_bar/src/lib.rs Outdated Show resolved Hide resolved
@Bafbi
Copy link
Contributor

Bafbi commented Jun 17, 2023

I tried to store Client objects directly inside the BossBarViewers struct but I realized it was a bad idea, now I just store bevy entities, is it how I should do?

Yes it's like in a db you put the id of what you want to ref.

How should I manage to add/remove viewers or update titles/health/style in a BossBar? I implemented methods for the BossBar struct to make these actions but I can't figure out how to send packets to the clients because I don't know how to turn my vector of bevy entities into Client objects.

When you use write_packet on the client, it's being put on a buffer to be send.

I basically forked my test file from the world_border's one, is it how I should spawn a BossBar?

No, BossBar are not link to the instance, but you should spawn a new bevy_entity

commands.spawn(BossBarBundle::new(...));

@dyc3
Copy link
Collaborator

dyc3 commented Jun 17, 2023

Regarding your questions

I tried to store Client objects directly inside the BossBarViewers struct but I realized it was a bad idea, now I just store bevy entities, is it how I should do?

Yes, that's how you should do it. Otherwise, you would be attempting to violate rust's aliasing rules.

How should I manage to add/remove viewers or update titles/health/style in a BossBar? I implemented methods for the BossBar struct to make these actions but I can't figure out how to send packets to the clients because I don't know how to turn my vector of bevy entities into Client objects.

You need to query for clients separately, and then you can use the Entity to look up the Client.

fn foo(clients: Query<Client>) {
    // Then you can look up the client using the entity
    clients.get(entity)

I basically forked my test file from the world_border's one, is it how I should spawn a BossBar?

For unit tests, operating directly on app.world is fine, but otherwise use bevy's Commands. You'll probably want to create a new entity instead of using an existing one.

@pepperoni21
Copy link
Contributor Author

I tried to store Client objects directly inside the BossBarViewers struct but I realized it was a bad idea, now I just store bevy entities, is it how I should do?

Yes it's like in a db you put the id of what you want to ref.

How should I manage to add/remove viewers or update titles/health/style in a BossBar? I implemented methods for the BossBar struct to make these actions but I can't figure out how to send packets to the clients because I don't know how to turn my vector of bevy entities into Client objects.

When you use write_packet on the client, it's being put on a buffer to be send.

I basically forked my test file from the world_border's one, is it how I should spawn a BossBar?

No, BossBar are not link to the instance, but you should spawn a new bevy_entity

commands.spawn(BossBarBundle::new(...));

Hey thanks for your help! The problem I have is that I don't know how to modify something in the Bundle. I could simply make a method to change a property but how am I supposed to send the packets then? Because since it's not a system I can't query anything right?

@pepperoni21
Copy link
Contributor Author

Hey thanks a lot for your help!

You need to query for clients separately, and then you can use the Entity to look up the Client.

fn foo(clients: Query<Client>) {
    // Then you can look up the client using the entity
    clients.get(entity)

So I have to do that in a system? But isn't a system supposed to be executed every tick? Or I should use something like an event?

For unit tests, operating directly on app.world is fine, but otherwise use bevy's Commands. You'll probably want to create a new entity instead of using an existing one.

Fine I will do that!

@Bafbi
Copy link
Contributor

Bafbi commented Jun 17, 2023

So I have to do that in a system? But isn't a system supposed to be executed every tick? Or I should use something like an event?

You want to send the packet when the bossbar is created or that an component change for that you can use changeDetection

fn foo(clients: Query<Client>, bossbar: Query<(UniqueId, ...), Added<BossBarBundle>>) { // not sure if you can put a bundle here, but if you can't use a component that uniquely identify a bossbar
    // you generates packets for each bossbar
    // Then you can look up each client of the bossbar to send them like you did before
}

@Bafbi
Copy link
Contributor

Bafbi commented Jun 17, 2023

Hey thanks for your help! The problem I have is that I don't know how to modify something in the Bundle. I could simply make a method to change a property but how am I supposed to send the packets then? Because since it's not a system I can't query anything right?

you don't make method to modify the component.
When someone use your plugin they can make system to modify what they want :
// Someone server code

fn update_bossbar(mob: Query<&Hp, &BossBarLink, Change<Hp>>, bossbar: Query<&mut BossBarHealth>) {
    for (hp, link) in mob {
        if let Ok(bossbar_health) = bossbar.get(link) {
            bossbat_health -= hp;
        }
    }
}

That will trigger a change detection on BossBarHealth that you can use to send the updatede packet

@pepperoni21
Copy link
Contributor Author

So I have to do that in a system? But isn't a system supposed to be executed every tick? Or I should use something like an event?

You want to send the packet when the bossbar is created or that an component change for that you can use changeDetection

fn foo(clients: Query<Client>, bossbar: Query<(UniqueId, ...), Added<BossBarBundle>>) { // not sure if you can put a bundle here, but if you can't use a component that uniquely identify a bossbar
    // you generates packets for each bossbar
    // Then you can look up each client of the bossbar to send them like you did before
}

That's exactly what I was looking for, thanks

@pepperoni21 pepperoni21 marked this pull request as ready for review June 18, 2023 08:00
crates/valence_boss_bar/src/lib.rs Outdated Show resolved Hide resolved
crates/valence_boss_bar/src/components.rs Outdated Show resolved Hide resolved
crates/valence_boss_bar/Cargo.toml Outdated Show resolved Hide resolved
crates/valence_boss_bar/src/components.rs Outdated Show resolved Hide resolved
crates/valence_boss_bar/src/lib.rs Show resolved Hide resolved
crates/valence_boss_bar/src/lib.rs Outdated Show resolved Hide resolved
crates/valence_boss_bar/src/lib.rs Show resolved Hide resolved
crates/valence_boss_bar/src/lib.rs Outdated Show resolved Hide resolved
crates/valence_boss_bar/src/lib.rs Outdated Show resolved Hide resolved
crates/valence_boss_bar/src/lib.rs Outdated Show resolved Hide resolved
crates/valence_boss_bar/src/lib.rs Outdated Show resolved Hide resolved
crates/valence_boss_bar/src/packet.rs Outdated Show resolved Hide resolved
Copy link
Member

@rj00a rj00a left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Graph in crates/README.md needs an update.

crates/valence_boss_bar/src/lib.rs Outdated Show resolved Hide resolved
crates/valence_boss_bar/src/lib.rs Outdated Show resolved Hide resolved
crates/valence_boss_bar/src/lib.rs Outdated Show resolved Hide resolved
crates/valence_boss_bar/src/lib.rs Outdated Show resolved Hide resolved
Copy link
Member

@rj00a rj00a left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

valence_boss_bar needs to be exported as boss_bar in the main valence crate. Also, please add an example to examples/.

@rj00a
Copy link
Member

rj00a commented Jun 20, 2023

Looks good, thanks.

@rj00a rj00a added this pull request to the merge queue Jun 20, 2023
Merged via the queue into valence-rs:main with commit 0f3e6f2 Jun 20, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants