# Objective
In Bevy 0.13, `BackgroundColor` simply tinted the image of any
`UiImage`. This was confusing: in every other case (e.g. Text), this
added a solid square behind the element. #11165 changed this, but
removed `BackgroundColor` from `ImageBundle` to avoid confusion, since
the semantic meaning had changed.
However, this resulted in a serious UX downgrade / inconsistency, as
this behavior was no longer part of the bundle (unlike for `TextBundle`
or `NodeBundle`), leaving users with a relatively frustrating upgrade
path.
Additionally, adding both `BackgroundColor` and `UiImage` resulted in a
bizarre effect, where the background color was seemingly ignored as it
was covered by a solid white placeholder image.
Fixes#13969.
## Solution
Per @viridia's design:
> - if you don't specify a background color, it's transparent.
> - if you don't specify an image color, it's white (because it's a
multiplier).
> - if you don't specify an image, no image is drawn.
> - if you specify both a background color and an image color, they are
independent.
> - the background color is drawn behind the image (in whatever pixels
are transparent)
As laid out by @benfrankel, this involves:
1. Changing the default `UiImage` to use a transparent texture but a
pure white tint.
2. Adding `UiImage::solid_color` to quickly set placeholder images.
3. Changing the default `BorderColor` and `BackgroundColor` to
transparent.
4. Removing the default overrides for these values in the other assorted
UI bundles.
5. Adding `BackgroundColor` back to `ImageBundle` and `ButtonBundle`.
6. Adding a 1x1 `Image::transparent`, which can be accessed from
`Assets<Image>` via the `TRANSPARENT_IMAGE_HANDLE` constant.
Huge thanks to everyone who helped out with the design in the linked
issue and [the Discord
thread](https://discord.com/channels/691052431525675048/1255209923890118697/1255209999278280844):
this was very much a joint design.
@cart helped me figure out how to set the UiImage's default texture to a
transparent 1x1 image, which is a much nicer fix.
## Testing
I've checked the examples modified by this PR, and the `ui` example as
well just to be sure.
## Migration Guide
- `BackgroundColor` no longer tints the color of images in `ImageBundle`
or `ButtonBundle`. Set `UiImage::color` to tint images instead.
- The default texture for `UiImage` is now a transparent white square.
Use `UiImage::solid_color` to quickly draw debug images.
- The default value for `BackgroundColor` and `BorderColor` is now
transparent. Set the color to white manually to return to previous
behavior.
# Objective
- Fixes#13811 (probably, I lost my test code...)
## Solution
- Turns out that Queue and PrepareAssets are _not_ ordered. We should
probably either rethink our system sets (again), or improve the
documentation here. For reference, I've included the current ordering
below.
- The `prepare_meshlet_meshes_X` systems need to run after
`prepare_assets::<PreparedMaterial<M>>`, and have also been moved to
QueueMeshes.
```rust
schedule.configure_sets(
(
ExtractCommands,
ManageViews,
Queue,
PhaseSort,
Prepare,
Render,
Cleanup,
)
.chain(),
);
schedule.configure_sets((ExtractCommands, PrepareAssets, Prepare).chain());
schedule.configure_sets(QueueMeshes.in_set(Queue).after(prepare_assets::<GpuMesh>));
schedule.configure_sets(
(PrepareResources, PrepareResourcesFlush, PrepareBindGroups)
.chain()
.in_set(Prepare),
);
```
## Testing
- Ambiguity checker to make sure I don't have ambiguous system ordering
# Objective
#12469 changed the `Debug` impl for `Entity`, making sure it's actually
accurate for debugging. To ensure that its can still be readily logged
in error messages and inspectors, this PR added a more concise and
human-friendly `Display` impl.
However, users found this form too verbose: the `to_bits` information
was unhelpful and too long. Fixes#13980.
## Solution
- Don't include `Entity::to_bits` in the `Display` implementation for
`Entity`. This information can readily be accessed and logged for users
who need it.
- Also clean up the implementation of `Display` for `DebugName`,
introduced in https://github.com/bevyengine/bevy/pull/13760, to simply
use the new `Display` impl (since this was the desired format there).
## Testing
I've updated an existing test to verify the output of `Entity::display`.
---------
Co-authored-by: Kristoffer Søholm <k.soeholm@gmail.com>
# Objective
- Fix issue #13821
## Solution
- Rewrote the test to ensure that it actually tests the functionality
correctly. Then made the par_read function correctly change the values
of self.reader.last_event_count.
## Testing
- Rewrote the test for par_read to run the system schedule twice,
checking the output each time
---------
Co-authored-by: Martín Maita <47983254+mnmaita@users.noreply.github.com>
# Objective
- Fixes https://github.com/bevyengine/bevy/issues/14003
## Solution
- Expose an API to perform updates for a specific sub-app, so we can
avoid mutable borrow the app twice.
## Testing
- I have tested the API by modifying the code in the `many_lights`
example with the following changes:
```rust
impl Plugin for LogVisibleLights {
fn build(&self, app: &mut App) {
let Some(render_app) = app.get_sub_app_mut(RenderApp) else {
return;
};
render_app.add_systems(Render, print_visible_light_count.in_set(RenderSet::Prepare));
}
fn finish(&self, app: &mut App) {
app.update_sub_app_by_label(RenderApp);
}
}
```
---
## Changelog
- add the `update_sub_app_by_label` API to `App` and `SubApps`.
---------
Co-authored-by: Jan Hohenheim <jan@hohenheim.ch>
# Objective
- When writing "in game" debugging tools, quite often you need the name
of an entity (for example an entity tree). DebugName is the usual way of
doing that.
- A recent change to Entity's Debug implementation meant it was no
longer a minimal {index}v{generation} but instead a more verbose auto
generated Debug.
- This made DebugName's Debug implementation also verbose
## Solution
- I changed DebugName to derive Debug automatically and added a new
(preferred) Display implementation for it which is the preferred name
for an entity. If the entity has a Name component its the contents of
that, otherwise it is {index}v{generation} (though this does not use
Display of the Entity as that is more verbose than this).
## Testing
- I've added a new test in name.rs which tests the Display
implementation for DebugName by using to_string.
---
## Migration Guide
- In code which uses DebugName you should now use the Display
implementation rather than the Debug implementation (ie {} instead of
{:?} if you were printing it out).
---------
Co-authored-by: John Payne <20407779+johngpayne@users.noreply.github.com>
Co-authored-by: Jan Hohenheim <jan@hohenheim.ch>
Co-authored-by: Andres O. Vela <andresovela@users.noreply.github.com>
fixes#13944
I literally just added `Did you forget to call SystemState::apply?` to
the error message. I tested it with the code snipped from the Issue and
yeah it works
# Objective
Fixes#13982
## Solution
~~Adds a new field to `bevy_log::LogPlugin`: `ansi: bool`~~
Documents the use of `std::env::set_var("NO_COLOR", "1");` to disable
colour output in terminals.
## Testing
Yes, all tests passed when I ran `cargo run -p ci -- test` and `cargo
run -p ci -- lints`
I have only tested the code on my Mac, though I doubt this change would
have any affect on other platforms.
---
# Objective
Closes#5943. Seems like Assets v2 solved this one.
## Solution
Added a test to confirm that using `Reflect::clone_value` and then
`FromReflect::from_reflect` on a `Handle<T>` both increment the strong
count.
## Testing
A new test was added to confirm behavior.
---------
Co-authored-by: Gino Valente <49806985+MrGVSV@users.noreply.github.com>
# Objective
Tight, in-frame generation, re-parenting, despawning, etc., UI
operations could sometime lead taffy to panic (invalid SlotMap key used)
when an entity with an invalid state later despawned.
Fixes#12403
## Solution
Move the `remove_entities` call after children updates.
## Testing
`sickle_ui` had a case that always caused the panic. Tested before this
change, after this change, and before the change again to make sure the
error is there without the fix. The fix worked. Test steps and used
commit described in issue #12403.
I have also ran every bevy UI example, though none of them deal with
entity re-parenting or removal. No regression detected on them.
Tested on Windows only.
* Fixes https://github.com/bevyengine/bevy/issues/13813
* Fixes https://github.com/bevyengine/bevy/issues/13810
Tested a combined scene with both regular meshes and meshlet meshes
with:
* Regular forward setup
* Forward + normal/motion vector prepasses
* Deferred (with depth prepass since that's required)
* Deferred + depth/normal/motion vector prepasses
Still broken:
* Using meshlet meshes rendering in deferred and regular meshes
rendering in forward + depth/normal prepass. I don't know how to fix
this at the moment, so for now I've just add instructions to not mix
them.
# Objective
`with_event` will result in unsafe casting of event data of the given
type to the type expected by the Observer system. This is inherently
unsafe.
## Solution
Flag `Observer::with_event` and `ObserverDescriptor::with_events` as
unsafe. This will not affect normal workflows as `with_event` is
intended for very specific (largely internal) use cases.
This _should_ be backported to 0.14 before release.
---
## Changelog
- `Observer::with_event` is now unsafe.
- Rename `ObserverDescriptor::with_triggers` to
`ObserverDescriptor::with_events` and make it unsafe.
# Objective
- Fixes#13702
- When creating a new window, its scale was changed to match the one
returned by winit, but its size was not which resulted in an incorrect
size until the event with the correct size was received, at least 1
frame later
## Solution
- Apply the window scale to its size when creating it
I updated my 'main' branch, which accidentally closed the original PR
#13747. I'm reopening the this from an actual branch on my repo like I
should have done in the first place. Here's the original info from the
first PR:
* * *
# Problem
The `file_watcher` feature panics if the file_watcher's path "assets" is
not present. I stumbled upon this behavior when I was actually testing
against `embedded_watcher`. I had no "assets" directory and didn't need
one for [my project](https://github.com/shanecelis/bevy_plane_cut).
```text
$ cargo run --example simple; # Runs fine.
$ cargo run --example simple --feature embedded_watcher; # Panics
thread 'main' panicked at /Users/shane/.cargo/registry/src/index.crates.io-6f17d22bba15001f/bevy_asset-0.14.0-rc.2/src/io/source.rs:503:21:
Failed to create file watcher from path "assets", Error { kind: PathNotFound, paths: ["/Users/shane/Projects/bevy_plane_cut/assets"] }
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
```
# Opinion
If a project runs without panicing, then adding the `file_watcher`
feature shouldn't cause it to panic.
# Suggested Solution
This PR suggests if the "assets" path does not exist, emit a warning
stating that the file watcher could not be created and why. All other
errors will be treated as before with a panic and a message.
```text
$ cargo run --example simple --feature embedded_watcher; # Panics
2024-06-08T08:55:11.385249Z WARN bevy_asset::io::source: Skip creating file watcher because path "assets" does not exist.
2024-06-08T08:55:11.385291Z WARN bevy_asset::io::source: AssetSourceId::Default does not have an AssetWatcher configured. Consider enabling the `file_watcher` feature.
```
The second warning is new and I'd prefer it didn't emit under this
condition, but I'll wait to see whether this is actually regarded as a
bug.
# Testing
No tests added. Compiled against my project and it demonstrated the
suggested behavior.
* * *
I changed the second warning to the following when the `file_watcher`
feature is present. When it's not present, it uses the same warning as
before.
```
024-06-09T01:22:16.880619Z WARN bevy_asset::io::source: Skip creating file watcher because path "assets" does not exist.
2024-06-09T01:22:16.880660Z WARN bevy_asset::io::source: AssetSourceId::Default does not have an AssetWatcher configured. Consider adding an "assets" directory.
```
This is an attempt to address issue #13725, which was about the
geometric primitives in the bevy_math crate lacking some detail in the
docs.
# Objective
Fixes#13725
## Solution
Added details to the docstrings. Mostly this consisted of specifying
that the primitives are centered on the origin, or describing how
they're defined (e.g., a circle is the set of all points some distance
from the origin).
## Testing
No testing, since the only changes were to docs.
Fixes#13701
After `winit` upgrade to `0.31`, windows were no longer correctly
resizing. This appears to just have been a simple mistake, where the new
physical size was being sourced from the `winit` window rather than on
the incoming `Window` component.
## Testing
Tested on macOS, but I'm curious whether this was also broken on other
platforms.
# Objective
Fixes#13866
## Solution
Add `insert_before` in **FixedMainScheduleOrder** and
**MainScheduleOrder**, add `insert_startup_before` in
**MainScheduleOrder**, applying the same logic as `insert_after`, except
for parameters naming and insertion index.
This is a followup to https://github.com/bevyengine/bevy/pull/13904
based on the discussion there, and switches two HashMaps that used
meshlet ids as keys to Vec.
In addition to a small further performance boost for `from_mesh` (1.66s
=> 1.60s), this makes processing deterministic modulo threading issues
wrt CRT rand described in the linked PR. This is valuable for debugging,
as you can visually or programmatically inspect the meshlet distribution
before/after making changes that should not change the output, whereas
previously every asset rebuild would change the meshlet structure.
Tested with https://github.com/bevyengine/bevy/pull/13431; after this
change, the visual output of meshlets is consistent between asset
rebuilds, and the MD5 of the output GLB file does not change either,
which was not the case before.
# Objective
- Make primitive meshing behavior consisten across platforms
- Avoid using sizes bigger than `u32` since these aren't even supported
for meshes
## Solution
- Use `u32` instead of `usize` for resolution/subdivisions/segments/etc
fields
---
## Changelog
- Change resolutions in primitive mesh builders from `usize` to `u32`
## Migration Guide
- All primitive mesh builders now take `u32` instead of `usize` for
their resolution/subdivision/segment counts
# Objective
Fixes#13920
## Solution
As described in the issue.
## Testing
Moved a custom transition plugin in example before any of the app-state
methods.
# Objective
Fixes#13933.
## Solution
Changed the return type.
## Testing
Fixed and reused the pre-existing tests for `inspect_entity`.
---
## Migration Guide
- `World::inspect_entity` now returns an `Iterator` instead of a `Vec`.
If you need a `Vec`, immediately collect the iterator:
`world.inspect_entity(entity).collect<Vec<_>>()`
# Objective
Fixes#13845
## Solution
Fix inline docs links inside `init_state` and `insert_state`.
## Testing
- Did you test these changes? If so, how?
Manually checked on `cargo doc` and `rust-analyzer lsp`.
# Objective
Fix a 9-slice asymmetric border issue that
[QueenOfSquiggles](https://blobfox.coffee/@queenofsquiggles/112639035165575222)
found. Here's the behavior before:
<img width="340" alt="the-bug"
src="https://github.com/bevyengine/bevy/assets/54390/81ff1847-b2ea-4578-9fd0-af6ee96c5438">
## Solution
Here's the behavior with the fix.
<img width="327" alt="the-fix"
src="https://github.com/bevyengine/bevy/assets/54390/33a4e3f0-b6a8-448e-9654-1197218ea11d">
## Testing
I used QueenOfSquiggles
[repo](https://github.com/QueenOfSquiggles/my-bevy-learning-project) to
exercise the code. I manually went through a number of variations of the
border and caught a few other issues after the first pass. I added some
code to create random borders and though they often looked funny there
weren't any gaps like before.
### Unit Tests
I did add some tests to `slicer.rs` mostly as an exploratory programming
exercise. So they currently act as a limited, incomplete,
"golden-file"-ish approach. Perhaps they're not worth keeping.
In order to write the tests, I did add a `PartialEq` derive for
`TextureSlice`.
I only tested these changes on macOS.
---
## Changelog
Make 9-slice textures work with asymmetric borders.
# Objective
- Make gizmos behavior consistent across platforms
## Solution
- Use `u32` instead of `usize` for resolution/subdivisions/segments/etc
fields
---
## Changelog
- Change resolutions in gizmos from `usize` to `u32`
## Migration Guide
- All gizmos now take `u32` instead of `usize` for their
resolution/subdivision/segment counts
# Objective
- Primitives should not use poorly defined types like `usize`,
especially since they are serializable
## Solution
- Use `u32` instead of `usize`
- The generic array types do not need to be changed because this size is
not actually stored or serialized anywhere
---
## Migration Guide
- `RegularPolygon` now uses `u32` instead of `usize` for the number of
sides
# Objective
This PR aims to improve error handling for log filters.
Closes#13850
## Solution
I changed the parsing of LogPlugin its filter to lossy, so that it
prints the directives with an error but does not skip them. I decided on
letting it gracefully handle the error instead of panicking to be
consistent with the parsing from an environment variable that it tries
to do before parsing it from the LogPlugin filter.
If the user decides to specify the filter by an environment variable, it
would silently fail and default to the LogPlugin filter value. It now
prints an error before defaulting to the LogPlugin filter value.
Unfortunately, I could not try and loosely set the filter from the
environment variable because the `tracing-subscriber` module does not
expose the function it uses to get the environment variable, and I would
rather not copy its code. We may want to check if the maintainers are
open to exposing the method.
## Testing
Consider the following bevy app, where the second of the 3 filters is
invalid:
```
use bevy::{log::LogPlugin, prelude::*};
fn main() {
App::new().add_plugins(DefaultPlugins
.set(LogPlugin {
filter: "wgpu=error,my_package=invalid_log_level,naga=warn".into(),
..default()
})
).run();
}
```
In the previous situation, it would panic with a non-descriptive error:
"called `Result::unwrap()` on an `Err` value: ParseError { kind:
Other(None) }", while only 1 of the 3 filters is invalid. When running
`cargo run`, it will now use the two valid filters and print an error on
the invalid filter.
> ignoring `my_package=invalid_log_level`: invalid filter directive
This error comes from `tracing-subscriber` and cannot be altered as far
as I can see.
To test setting the log filter through an environment variable, you can
use `RUST_LOG="wgpu=error,my_package=invalid_log_level,naga=warn" cargo
run` to run your app. In the previous situation it would silently fail
and use the LogPlugin filter. It will now print an error before using
the LogPlugin filter.
> LogPlugin failed to parse filter from env: invalid filter directive
## Changelog
- Added warning when using invalid filter in the RUST_LOG environment
variable
- Prevent the app from panicking when setting an invalid LogPlugin
filter
---------
Co-authored-by: Luc Drenth <luc.drenth@ing.com>
# Objective
Fixes#13917
## Solution
Changed `IntoSystemSetConfigs::chain_ignore_deferred`'s return type from
`SystemConfigs` to `SystemSetConfigs`
## Testing
Tried to run the `ecs_guide` example, where `chain` method is replaced
by `chain_ignore_deferred` method
---
# Objective
- Fix a typo in documentation for `Query::single_mut`
## Solution
- Change `item` to `items`
## Testing
- I built the documentation and it looked fine.
- Since this only affects a doc comment, no further testing should be
necessary.
---
## Changelog
> This section is optional. If this was a trivial fix, or has no
externally-visible impact, you can delete this section.
- Fixed a typo in the documentation for Query.
# Objective
- Fixes#11933.
- Related: #12280.
## Solution
- Specify that, after applying `AmbientLight`, the resulting units are
in cd/m^2.
- This is based on [@fintelia's
comment](https://github.com/bevyengine/bevy/issues/11933#issuecomment-1995427587),
and will need to be verified.
---
## Changelog
- Specified units for `AmbientLight`'s `brightness` field.
This change reworks `find_connected_meshlets` to scale more linearly
with the mesh size, which significantly reduces the cost of building
meshlet representations. As a small extra complexity reduction, it moves
`simplify_scale` call out of the loop so that it's called once (it only
depends on the vertex data => is safe to cache).
The new implementation of connectivity analysis builds edge=>meshlet
list data structure, which allows us to only iterate through
`tuple_combinations` of a (usually) small list. There is still some
redundancy as if two meshlets share two edges, they will be represented
in the meshlet lists twice, but it's overall much faster.
Since the hash traversal is non-deterministic, to keep this part of the
algorithm deterministic for reproducible results we sort the output
adjacency lists.
Overall this reduces the time to process bunny mesh from ~4.2s to ~1.7s
when using release; in unoptimized builds the delta is even more
significant.
This was tested by using https://github.com/bevyengine/bevy/pull/13431
and:
a) comparing the result of `find_connected_meshlets` using old and new
code; they are equal in all steps of the clustering process
b) comparing the rendered result of the old code vs new code *after*
making the rest of the algorithm deterministic: right now the loop that
iterates through the result of `group_meshlets()` call executes in
different order between program runs. This is orthogonal to this change
and can be fixed separately.
Note: a future change can shrink the processing time further from ~1.7s
to ~0.4s with a small diff but that requires an update to meshopt crate
which is pending in https://github.com/gwihlidal/meshopt-rs/pull/42.
This change is independent.
# Objective
- first part of #13900
## Solution
- split `check_light_mesh_visibility `into
`check_dir_light_mesh_visibility `and
`check_point_light_mesh_visibility` for better review
# Objective
- After #12582 , Bevy split visibleEntities into a TypeIdMap for
different types of entities, but the behavior in
`check_light_mesh_visibility `simply calls HashMap::clear(), which will
reallocate memory every frame.
## Testing
cargo run --release --example many_cubes --features bevy/trace_tracy --
--shadows
~10% win in `check_light_mesh_visibilty`
![image](https://github.com/bevyengine/bevy/assets/45868716/1bf4deef-bab2-4e5f-9f60-bea8b7e33e3e)
# Objective
The error messages that appear when a value cannot be serialized or
deserialized via reflection could be slightly improved.
When one of these operations fails, some users are confused about how to
resolve the issue. I've spoken with a few who didn't know they could
register `ReflectSerialize` themselves. We should try to clarify this to
some degree in the error messages.
## Solution
Add some more detail to the error messages.
For example, replacing this:
```
Type 'core::ops::RangeInclusive<f32>' did not register ReflectSerialize
```
with this:
```
Type `core::ops::RangeInclusive<f32>` did not register the `ReflectSerialize` type data. For certain types, this may need to be registered manually using `register_type_data`
```
I also added a separate error message if the type was not registered in
the type registry at all:
```
Type `core::ops::RangeInclusive<f32>` is not registered in the type registry
```
## Testing
You can test locally by running:
```
cargo test --package bevy_reflect
```
---
## Changelog
- Added error message for missing type registration when serializing
reflect data
- Changed error message for missing `ReflectSerialize` registration when
serializing reflect data
- Changed error message for missing `ReflectDeserialize` registration
when deserializing reflect data
# Objective
I got little confused by the document of `all_tuples!` because type
names of the parameter `T` and extracted names `Pn` are difference.
## Solution
I fixed type names of the document.
# Objective
While writing code for the `bevy_ecs` I noticed we were using a
unnecessarily stable sort to sort component ids
## Solution
- Sort component ids with a unstable sort
- Comb the bevy_ecs crate for any other obvious inefficiencies.
- Don't clone component vectors when inserting an archetype.
## Testing
I ran `cargo test -p bevy_ecs`. Everything else I leave to CI.
## Profiling
I measured about a 1% speed increase when spawning entities directly
into a world. Since the difference is so small (and might just be noise)
I didn't bother to figure out which of change if any made the biggest
difference.
<details>
<summary> Tracy data </summary>
Yellow is this PR. Red is the commit I branched from.
![image](https://github.com/bevyengine/bevy/assets/59848927/f1a5c95d-a882-4dfb-ac07-dd2922273b91)
</details>
<details>
<summary>Methodology</summary>
I created a system that spawn a 1000 entities each with the same 30
components each frame, and then I measured it's run time. The unusually
high number of components was chosen because the standard library [will
use a insertion sort for slices under 20
elements](0de24a5177/library/core/src/slice/sort.rs (L1048-L1049)).
This holds for both stable and unstable sorts.
</details>
# Objective
Fixes#13299
On Linux/X11, changing focus into a winit window will produce winit
KeyboardInput events with a "is_synthetic=true" flag that are not
intended to be used. Bevy erroneously passes them on to the user,
resulting in phantom key presses.
## Solution
This patch properly filters out winit KeyboardInput events with
"is_synthetic=true".
For example, pressing Alt+Tab to focus a bevy winit window results in a
permanently stuck Tab key until the user presses Tab once again to
produce a winit KeyboardInput release event. The Tab key press event
that causes this problem is "synthetic", should not be used according to
the winit devs, and simply ignoring it fixes this problem.
Synthetic key **releases** are still evaluated though, as they are
essential for correct release key handling. For example, if the user
binds the key combination Alt+1 to the action "move the window to
workspace 1", places the bevy game in workspace 2, focuses the game and
presses Alt+1, then the key release event for the "1" key will be
synthetic. If we would filter out all synthetic keys, the bevy game
would think that the 1 key remains pressed forever, until the user
manually presses+releases the key again inside bevy.
Reference:
https://docs.rs/winit/0.30.0/winit/event/enum.WindowEvent.html#variant.KeyboardInput.field.is_synthetic
Relevant discussion: https://github.com/rust-windowing/winit/issues/3543
## Testing
Tested with the "keyboard_input_events" example. Entering/exiting the
window with various keys, as well as changing its workspace, produces
the correct press/release events.
# Objective
- Fixes#13874
## Solution
- Confirm that the `StatesPlugin` is installed when trying to add
states.
- Skipped for state scoped entities, since those will warn about missing
states.
# Objective
Fixes#13854
## Solution
Removed the inaccurate warning. This was done for a few reasons:
- States not existing is now a valid "state" (for lack of a better term)
- Other run conditions don't provide an equivalent warning