@@ 646,6 646,7 @@ dependencies = [
"bevy_egui",
"bevy_embedded_assets",
"console_error_panic_hook",
+ "web-time",
]
[[package]]
@@ 763,6 764,7 @@ dependencies = [
"bevy_pbr",
"bevy_reflect",
"bevy_render",
+ "bevy_sprite",
"bevy_time",
"bevy_transform",
"bevy_utils",
@@ 918,8 920,10 @@ dependencies = [
"bevy_sprite",
"bevy_state",
"bevy_tasks",
+ "bevy_text",
"bevy_time",
"bevy_transform",
+ "bevy_ui",
"bevy_utils",
"bevy_window",
"bevy_winit",
@@ 1293,6 1297,36 @@ dependencies = [
]
[[package]]
+name = "bevy_text"
+version = "0.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ef071262c5a9afbc39caba4c0b282c7d045fbb5cf33bdab1924bd2343403833"
+dependencies = [
+ "bevy_app",
+ "bevy_asset",
+ "bevy_color",
+ "bevy_derive",
+ "bevy_ecs",
+ "bevy_image",
+ "bevy_log",
+ "bevy_math",
+ "bevy_platform",
+ "bevy_reflect",
+ "bevy_render",
+ "bevy_sprite",
+ "bevy_transform",
+ "bevy_utils",
+ "bevy_window",
+ "cosmic-text",
+ "serde",
+ "smallvec",
+ "sys-locale",
+ "thiserror 2.0.12",
+ "tracing",
+ "unicode-bidi",
+]
+
+[[package]]
name = "bevy_time"
version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 1335,6 1369,40 @@ dependencies = [
]
[[package]]
+name = "bevy_ui"
+version = "0.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "110dc5d0059f112263512be8cd7bfe0466dfb7c26b9bf4c74529355249fd23f9"
+dependencies = [
+ "accesskit",
+ "bevy_a11y",
+ "bevy_app",
+ "bevy_asset",
+ "bevy_color",
+ "bevy_core_pipeline",
+ "bevy_derive",
+ "bevy_ecs",
+ "bevy_image",
+ "bevy_input",
+ "bevy_math",
+ "bevy_platform",
+ "bevy_reflect",
+ "bevy_render",
+ "bevy_sprite",
+ "bevy_text",
+ "bevy_transform",
+ "bevy_utils",
+ "bevy_window",
+ "bytemuck",
+ "derive_more",
+ "nonmax",
+ "smallvec",
+ "taffy",
+ "thiserror 2.0.12",
+ "tracing",
+]
+
+[[package]]
name = "bevy_utils"
version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 1783,6 1851,29 @@ dependencies = [
]
[[package]]
+name = "cosmic-text"
+version = "0.13.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e418dd4f5128c3e93eab12246391c54a20c496811131f85754dc8152ee207892"
+dependencies = [
+ "bitflags 2.9.1",
+ "fontdb",
+ "log",
+ "rangemap",
+ "rustc-hash 1.1.0",
+ "rustybuzz",
+ "self_cell",
+ "smol_str",
+ "swash",
+ "sys-locale",
+ "ttf-parser 0.21.1",
+ "unicode-bidi",
+ "unicode-linebreak",
+ "unicode-script",
+ "unicode-segmentation",
+]
+
+[[package]]
name = "crc32fast"
version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 2165,6 2256,38 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
[[package]]
+name = "font-types"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "02a596f5713680923a2080d86de50fe472fb290693cf0f701187a1c8b36996b7"
+dependencies = [
+ "bytemuck",
+]
+
+[[package]]
+name = "fontconfig-parser"
+version = "0.5.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bbc773e24e02d4ddd8395fd30dc147524273a83e54e0f312d986ea30de5f5646"
+dependencies = [
+ "roxmltree",
+]
+
+[[package]]
+name = "fontdb"
+version = "0.16.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b0299020c3ef3f60f526a4f64ab4a3d4ce116b1acbf24cdd22da0068e5d81dc3"
+dependencies = [
+ "fontconfig-parser",
+ "log",
+ "memmap2",
+ "slotmap",
+ "tinyvec",
+ "ttf-parser 0.20.0",
+]
+
+[[package]]
name = "foreign-types"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 2419,6 2542,12 @@ dependencies = [
]
[[package]]
+name = "grid"
+version = "0.15.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "36119f3a540b086b4e436bb2b588cf98a68863470e0e880f4d0842f112a3183a"
+
+[[package]]
name = "guillotiere"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 3430,7 3559,7 @@ version = "0.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22ec719bbf3b2a81c109a4e20b1f129b5566b7dce654bc3872f6a05abf82b2c4"
dependencies = [
- "ttf-parser",
+ "ttf-parser 0.25.1",
]
[[package]]
@@ 3800,6 3929,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3d6831663a5098ea164f89cff59c6284e95f4e3c76ce9848d4529f5ccca9bde"
[[package]]
+name = "rangemap"
+version = "1.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f60fcc7d6849342eff22c4350c8b9a989ee8ceabc4b481253e8946b9fe83d684"
+
+[[package]]
name = "rav1e"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 3882,6 4017,16 @@ dependencies = [
]
[[package]]
+name = "read-fonts"
+version = "0.29.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5ce8e2ca6b24313587a03ca61bb74c384e2a815bd90cf2866cfc9f5fb7a11fa0"
+dependencies = [
+ "bytemuck",
+ "font-types",
+]
+
+[[package]]
name = "rectangle-pack"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 3980,6 4125,12 @@ dependencies = [
]
[[package]]
+name = "roxmltree"
+version = "0.20.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6c20b6793b5c2fa6553b250154b78d6d0db37e72700ae35fad9387a46f487c97"
+
+[[package]]
name = "rstar"
version = "0.12.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 4022,6 4173,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2"
[[package]]
+name = "rustybuzz"
+version = "0.14.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cfb9cf8877777222e4a3bc7eb247e398b56baba500c38c1c46842431adc8b55c"
+dependencies = [
+ "bitflags 2.9.1",
+ "bytemuck",
+ "libm",
+ "smallvec",
+ "ttf-parser 0.21.1",
+ "unicode-bidi-mirroring",
+ "unicode-ccc",
+ "unicode-properties",
+ "unicode-script",
+]
+
+[[package]]
name = "ruzstd"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 4080,6 4248,12 @@ dependencies = [
]
[[package]]
+name = "self_cell"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0f7d95a54511e0c7be3f51e8867aa8cf35148d7b9445d44de2f943e2b206e749"
+
+[[package]]
name = "send_wrapper"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 4170,6 4344,16 @@ dependencies = [
]
[[package]]
+name = "skrifa"
+version = "0.31.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bbe6666ab11018ab91ff7b03f1a3b9fdbecfb610848436fefa5ce50343d3d913"
+dependencies = [
+ "bytemuck",
+ "read-fonts",
+]
+
+[[package]]
name = "slab"
version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 4310,6 4494,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0193cc4331cfd2f3d2011ef287590868599a2f33c3e69bc22c1a3d3acf9e02fb"
[[package]]
+name = "swash"
+version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5dce3f0af95643c855cdc449fbaa17d8c2cd08e0b00a49a6babcbe6e71667f3d"
+dependencies = [
+ "skrifa",
+ "yazi",
+ "zeno",
+]
+
+[[package]]
name = "syn"
version = "2.0.101"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 4321,6 4516,15 @@ dependencies = [
]
[[package]]
+name = "sys-locale"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8eab9a99a024a169fe8a903cf9d4a3b3601109bcc13bd9e3c6fff259138626c4"
+dependencies = [
+ "libc",
+]
+
+[[package]]
name = "system-deps"
version = "6.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 4334,6 4538,18 @@ dependencies = [
]
[[package]]
+name = "taffy"
+version = "0.7.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ab4f4d046dd956a47a7e1a2947083d7ac3e6aa3cfaaead36173ceaa5ab11878c"
+dependencies = [
+ "arrayvec",
+ "grid",
+ "serde",
+ "slotmap",
+]
+
+[[package]]
name = "target-lexicon"
version = "0.12.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 4572,6 4788,18 @@ dependencies = [
[[package]]
name = "ttf-parser"
+version = "0.20.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "17f77d76d837a7830fe1d4f12b7b4ba4192c1888001c7164257e4bc6d21d96b4"
+
+[[package]]
+name = "ttf-parser"
+version = "0.21.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2c591d83f69777866b9126b24c6dd9a18351f177e49d625920d19f989fd31cf8"
+
+[[package]]
+name = "ttf-parser"
version = "0.25.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2df906b07856748fa3f6e0ad0cbaa047052d4a7dd609e231c4f72cee8c36f31"
@@ 4595,12 4823,48 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f"
[[package]]
+name = "unicode-bidi"
+version = "0.3.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5"
+
+[[package]]
+name = "unicode-bidi-mirroring"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "23cb788ffebc92c5948d0e997106233eeb1d8b9512f93f41651f52b6c5f5af86"
+
+[[package]]
+name = "unicode-ccc"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1df77b101bcc4ea3d78dafc5ad7e4f58ceffe0b2b16bf446aeb50b6cb4157656"
+
+[[package]]
name = "unicode-ident"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
[[package]]
+name = "unicode-linebreak"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f"
+
+[[package]]
+name = "unicode-properties"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0"
+
+[[package]]
+name = "unicode-script"
+version = "0.5.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9fb421b350c9aff471779e262955939f565ec18b86c15364e6bdf0d662ca7c1f"
+
+[[package]]
name = "unicode-segmentation"
version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 5528,6 5792,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a62ce76d9b56901b19a74f19431b0d8b3bc7ca4ad685a746dfd78ca8f4fc6bda"
[[package]]
+name = "yazi"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e01738255b5a16e78bbb83e7fbba0a1e7dd506905cfc53f4622d89015a03fbb5"
+
+[[package]]
+name = "zeno"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6df3dc4292935e51816d896edcd52aa30bc297907c26167fec31e2b0c6a32524"
+
+[[package]]
name = "zerocopy"
version = "0.8.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 5,8 5,18 @@ edition.workspace = true
[features]
default = ["debug", "wayland"]
-debug = ["bevy_dice/debug", "avian3d/debug-plugin", "dep:bevy-inspector-egui"]
-wasm = ["bevy/webgl2", "bevy_dice/wasm", "dep:console_error_panic_hook"]
+debug = [
+ "bevy_dice/debug",
+ "bevy/bevy_ui_debug",
+ "avian3d/debug-plugin",
+ "dep:bevy-inspector-egui",
+]
+wasm = [
+ "bevy/webgl2",
+ "bevy_dice/wasm",
+ "dep:console_error_panic_hook",
+ "dep:web-time",
+]
wayland = ["bevy/wayland"]
[dependencies]
@@ 19,8 29,10 @@ bevy = { version = "0.16", default-features = false, features = [
"bevy_pbr",
"bevy_render",
"bevy_state",
+ "bevy_ui",
"bevy_window",
"bevy_winit",
+ "default_font",
"multi_threaded",
"png",
"tonemapping_luts",
@@ 32,3 44,4 @@ bevy_egui = { version = "0.34", default-features = false, features = [
] }
bevy-inspector-egui = { version = "0.31", optional = true }
console_error_panic_hook = { version = "0.1", optional = true }
+web-time = { version = "1", optional = true }
@@ 0,0 1,114 @@
+/*
+ * Copyright (C) 2025 Jonni Liljamo <jonni@liljamo.com>
+ *
+ * This file is licensed under MIT, see LICENSE for more information.
+ */
+
+use std::time::Duration;
+#[cfg(not(feature = "wasm"))]
+use std::time::Instant;
+#[cfg(feature = "wasm")]
+use web_time::Instant;
+
+use bevy::{color::palettes::tailwind::*, prelude::*};
+
+pub struct ToastPlugin;
+
+impl Plugin for ToastPlugin {
+ fn build(&self, app: &mut App) {
+ app.add_systems(Startup, setup)
+ .add_systems(Update, cleanup_toasts);
+
+ app.add_event::<ShowResultToast>()
+ .add_observer(show_result_toast);
+ }
+}
+
+#[derive(Component)]
+struct ToastUI;
+
+#[derive(Component)]
+struct Toast {
+ spawned: Instant,
+}
+
+fn setup(mut commands: Commands) {
+ commands.spawn((
+ Node {
+ width: Val::Percent(100.0),
+ height: Val::Percent(100.0),
+ flex_direction: FlexDirection::Column,
+ align_items: AlignItems::FlexEnd,
+ padding: UiRect::all(Val::Px(8.0)),
+ overflow: Overflow::scroll_y(),
+ ..Default::default()
+ },
+ ToastUI,
+ ));
+}
+
+#[derive(Event)]
+pub struct ShowResultToast(pub u32, pub u8);
+
+fn show_result_toast(
+ trigger: Trigger<ShowResultToast>,
+ mut commands: Commands,
+ q_toast_ui: Query<Entity, With<ToastUI>>,
+) {
+ if let Ok(toast_ui) = q_toast_ui.single() {
+ let toast = commands
+ .spawn((
+ Toast {
+ spawned: Instant::now(),
+ },
+ Node {
+ width: Val::Px(180.0),
+ height: Val::Px(60.0),
+ border: UiRect::all(Val::Px(2.0)),
+ flex_direction: FlexDirection::Column,
+ justify_content: JustifyContent::Center,
+ align_items: AlignItems::Center,
+ ..Default::default()
+ },
+ BackgroundColor(Color::from(EMERALD_400)),
+ BorderColor(Color::from(EMERALD_700)),
+ BorderRadius::all(Val::Px(10.0)),
+ BoxShadow::new(
+ Color::BLACK.with_alpha(0.8),
+ Val::Px(4.0),
+ Val::Px(4.0),
+ Val::DEFAULT,
+ Val::DEFAULT,
+ ),
+ children![
+ (
+ Text::new(format!("Die {}", trigger.0)),
+ TextFont {
+ font_size: 18.0,
+ ..Default::default()
+ },
+ TextColor(Color::BLACK),
+ ),
+ (
+ Text::new(format!("Result: {}", trigger.1)),
+ TextFont {
+ font_size: 20.0,
+ ..Default::default()
+ },
+ TextColor(Color::WHITE),
+ )
+ ],
+ ))
+ .id();
+
+ commands.entity(toast_ui).add_child(toast);
+ }
+}
+
+fn cleanup_toasts(mut commands: Commands, q_toast: Query<(Entity, &Toast)>) {
+ for (entity, toast) in q_toast.iter() {
+ if toast.spawned.elapsed() > Duration::from_secs(2) {
+ commands.entity(entity).despawn();
+ }
+ }
+}