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

Optional component for Instance used to control time, weather, world border, etc. #210

Open
2 of 3 tasks
Tracked by #288
rj00a opened this issue Feb 4, 2023 · 9 comments · May be fixed by #526
Open
2 of 3 tasks
Tracked by #288

Optional component for Instance used to control time, weather, world border, etc. #210

rj00a opened this issue Feb 4, 2023 · 9 comments · May be fixed by #526
Labels
good first issue Good for newcomers

Comments

@rj00a
Copy link
Member

rj00a commented Feb 4, 2023

It would be convenient if Instance had some optional components for controlling state which is typically expected to be global to the instance. This includes the time of day, whether or not time is paused (doDaylightCycle), The world border for the instance, the weather (raining or thundering), etc.

My current thinking is that we can have the following components:

  • TimeOfDay
  • Weather
  • WorldBorder

Might be more convenient to make these components smaller for the purpose of change detection. Not sure.

@rj00a rj00a added the good first issue Good for newcomers label Feb 4, 2023
@rj00a rj00a changed the title [ECS] Optional component for Instance used to control time, weather, world border, etc. Optional component for Instance used to control time, weather, world border, etc. Feb 12, 2023
@rj00a
Copy link
Member Author

rj00a commented Mar 8, 2023

Might be more convenient to make these components smaller for the purpose of change detection.

Yes, each field that needs change detection should be its own component. Bundles can be used to make this more convenient.

@rj00a rj00a mentioned this issue Mar 12, 2023
56 tasks
dyc3 pushed a commit that referenced this issue Mar 16, 2023
<!-- Please make sure that your PR is aligned with the guidelines in
CONTRIBUTING.md to the best of your ability. -->
<!-- Good PRs have tests! Make sure you have sufficient test coverage.
-->

## Description

<!-- Describe the changes you've made. You may include any justification
you want here. -->

An implementation of basic weather systems.

The weather component attached to a world instance would be handled for
all clients, except those that have their own weather component; these
clients would be handled separately.

## Test Plan

<!-- Explain how you tested your changes, and include any code that you
used to test this. -->
<!-- If there is an example that is sufficient to use in place of a
playground, replace the playground section with a note that indicates
this. -->

<details>

<summary>Playground</summary>

```rust
fn handle_command_events(
    instances: Query<Entity, With<Instance>>,
    mut exec_cmds: EventReader<CommandExecution>,
    mut commands: Commands,
) {
    for cmd in exec_cmds.iter() {
        let msg = cmd.command.to_string();
        let ent = instances.single();

        match msg.as_str() {
            "ar" => {
                commands.entity(ent).insert(Rain(WEATHER_LEVEL.end));
            }
            "rr" => {
                commands.entity(ent).remove::<Rain>();
            }
            "at" => {
                commands.entity(ent).insert(Thunder(WEATHER_LEVEL.end));
            }
            "rt" => {
                commands.entity(ent).remove::<Thunder>();
            }
            _ => (),
        };
    }
}
```

</details>

<!-- You need to include steps regardless of whether or not you are
using a playground. -->
Steps:
1. Run `cargo test --package valence --lib -- weather::test`

#### Related
Part of #210
Past approach #106

<!-- Link to any issues that have context for this or that this PR
fixes. -->
@arseeeeN
Copy link

How should doDaylightCycle be implemented? Should gamerules in general just be attached to the instance or should they be entities?

@dyc3
Copy link
Collaborator

dyc3 commented May 12, 2023

I'd consider that to be vanilla functionality, which would be out of scope for valence. Do gamerules get conveyed to clients and affect them in any way? If not, gamerules are definitely out of scope.

@arseeeeN
Copy link

That makes sense, so the developers that use Valence would handle the updating of the time of day themselves? Including sending that information to the players of course.
Should the time of day be a field of the InstanceInfo struct or a component that could be spawned alongside the entity of the Instance component?

@dyc3
Copy link
Collaborator

dyc3 commented May 13, 2023

Valence would be the one sending packets. As the issue says, the desired solution is a TimeOfDay component that goes on the entity that has the Instance. A system inside valence would then be able to handle sending those packets.

Weather is already implemented, you can use that for reference.

@MrlnHi
Copy link
Contributor

MrlnHi commented May 18, 2023

I'd consider that to be vanilla functionality, which would be out of scope for valence. Do gamerules get conveyed to clients and affect them in any way? If not, gamerules are definitely out of scope.

reducedDebugScreen or however it's called gets conveyed to clients (and actually makes a difference). Other than that I can't think of any tho

rj00a pushed a commit that referenced this issue Jun 15, 2023
## Description

Basic implementation of world border
World border is not enabled by default. It can be enabled by inserting
`WorldBorderBundle` bundle. Currently, this PR only implements world
borders per instance, I'm considering expanding this per client.
However, the same functionality can be achieved by Visibility Layers
#362

<details>
<summary>Playground:</summary>

```rust
fn border_controls(
    mut events: EventReader<ChatMessageEvent>,
    mut instances: Query<(Entity, &WorldBorderDiameter, &mut WorldBorderCenter), With<Instance>>,
    mut event_writer: EventWriter<SetWorldBorderSizeEvent>,
) {
    for x in events.iter() {
        let parts: Vec<&str> = x.message.split(' ').collect();
        match parts[0] {
            "add" => {
                let Ok(value) = parts[1].parse::<f64>() else {
                    return;
                };

                let Ok(speed) = parts[2].parse::<i64>() else {
                    return;
                };

                let Ok((entity, diameter, _)) = instances.get_single_mut() else {
                    return;
                };

                event_writer.send(SetWorldBorderSizeEvent {
                    instance: entity,
                    new_diameter: diameter.diameter() + value,
                    speed,
                })
            }
            "center" => {
                let Ok(x) = parts[1].parse::<f64>() else {
                    return;
                };

                let Ok(z) = parts[2].parse::<f64>() else {
                    return;
                };

                instances.single_mut().2 .0 = DVec2 { x, y: z };
            }
            _ => (),
        }
    }
}
``` 
</details>

example: `cargo run --package valence --example world_border`
tests: `cargo test --package valence --lib -- tests::world_border`


**Related**
part of #210
@tachibanayui
Copy link
Contributor

Is anyone already working on time of day? I want to take a shot at implementing it.

@arseeeeN
Copy link

I initially wanted to work on it but couldn't find the time, so feel free to take over.

@rj00a rj00a linked a pull request Jun 17, 2023 that will close this issue
@tachibanayui tachibanayui linked a pull request Sep 17, 2023 that will close this issue
@rj00a rj00a linked a pull request Sep 17, 2023 that will close this issue
@1bacon
Copy link

1bacon commented Dec 25, 2023

I'd consider that to be vanilla functionality, which would be out of scope for valence. Do gamerules get conveyed to clients and affect them in any way? If not, gamerules are definitely out of scope.

reducedDebugScreen or however it's called gets conveyed to clients (and actually makes a difference). Other than that I can't think of any tho

For completeness:
Only reducedDebugInfo, doLimitedCrafting and doImmediateRespawn are sent to the Client.

All others are checked by the server internally.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
good first issue Good for newcomers
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants