#bevy_new_2d

1 messages ยท Page 2 of 1

finite depot
#

Hehehe

#

This is supremely cheeky

tacit verge
#

it'll still require a post-generate hook

#

in Rhai i guess

#

i can try to add that

finite depot
#

Thanks ๐Ÿ™‚

tacit verge
#

there doesn't seem to be an easy way to run cargo update from a rhai script

finite depot
#

At least that can be fixed with bevy new

tacit verge
#

i didn't find anything by searching the rhai book for related keywords

#

it seems to be intentionally unsupported for sandboxing purposes, but i don't have a source for that

#

it may be possible to go through a rhai -> rust interface to get around the limitation. that would be a not-easy way to do it :p

finite depot
#

Welp, telling people to run the magic command is not that bad

tacit verge
#

that's also true

#

probably worth adding that to the README until a better solution exists at least

finite depot
#

Or remove the locked modifier from CI and donโ€™t generate a lockfile

finite depot
tacit verge
#

yeah --locked is good for stability

finite depot
tacit verge
#

oh just realized also

#

the two commands we have there

#

it's missing a cd <directory> in between

#

though that's not what it's called in powershell :p

finite depot
#

(It will just lint against it in scripts)

tacit verge
#

ah

finite depot
#

"How dare you not use Set-Location???"

#

But it will also lint against your own functions not starting with a blessed verb like Set, Move, Get, Run, etc.

#

No "CalculateFoo" allowed

tacit verge
#

๐Ÿ˜”

finite depot
#

Powershell's linter really has some opinions

tacit verge
#

reminds me of go's formatter

#

i worded it to avoid cd anyways

finite depot
#

Which means they get a different lockfile

tacit verge
#

it does cargo update

#

which is a superset

finite depot
#

Yeah, for all dependencies

tacit verge
#

we could suggest cargo update -p your_project but that's a longer command and the user would have to substitute their project name there, so they can't copy/paste

#

and cargo update accomplishes the same goal of fixing the Cargo.lock file. it just also updates dependencies

finite depot
#

Hmm, alright. I'm just worries because I have seen stuff break post cargo update before

tacit verge
#

like semver-incompatible update?

finite depot
#

Using our lockfile at least guarantees that the template works

finite depot
#

I mean, as in someone didnโ€™t follow semver

tacit verge
#

right

#

well.. we only depend on bevy, log, and tracing

finite depot
#

And cargo update ended up breaking my build or runtime

tacit verge
#

but in principle you're right

finite depot
#

Which is nasty to fix

finite depot
#

I assume those should be safe, otherwise itโ€™s a Bevy-wide problem

#

Then cargo update is fine, youโ€™ve convinced me

#

That means we can remove our lockfile from the generated files

tacit verge
#

that's true

#

should we?

#

i think keeping it for the main branch makes sense (well, it's necessary for CI actually)

finite depot
#

But thatโ€™s alright

finite depot
tacit verge
#

yeah

#

and/or remove it from the branch

#

at some point i believe we want to merge the cargo-generate branch into main

#

at which point we'd want to keep it in the template but exclude it from being copied on generate so yeah

finite depot
tacit verge
#

i just don't understand how all the other cargo-generate template maintainers write code without rust-analyzer

finite depot
finite depot
#

Approved

tacit verge
#

thanks

hasty furnace
#

Since we're on the topic -- with a fresh Cargo.lock, my CI no longer fails here; but later doctest fails in src/audio.rs because there is a
/// use bevy_quickstart::audio::Music
which probably needs to become
/// use your_project::audio::Music
(or maybe use self::Music is a thing?)

tacit verge
#

yep ๐Ÿ˜„

#

doctests are compiled as though they're in a separate crate i believe, so self or crate wouldn't work

#

i haven't tried self though, only crate

finite depot
#

I'm currently doing a complete rework of Foxtrot based on bevy_quickstart (#1124043933886976171 message) and thought we could maybe have a section in the template for derivatives

#

We could list foxtrot and pyri_template there

#

What do you think?

tacit verge
#

yeah that sounds good to me. pyri_template isn't ready yet but it can go there when it is

tacit verge
#

(this is a PR to bevy_new as a proof-of-concept)

#

this means that every templated file will have 2 copies that should be kept in sync, instead of the entire repo having 2 branches that should be kept in sync

#

it also means that "normal" CI / CD workflows should continue to work, but a ci-generate.yaml workflow would still be good to have to make sure that generated repos have passing CI as well

#

and that the cargo-generate command works at all

tacit verge
#

as for running cargo update -p {{project-name}} and other commands in a post-generate hook, that is actually possible. @stable cloud found that Rhai can do this:

system::command("cargo", ["update", "--project", variable::get("project-name")]);
finite depot
tacit verge
#

i ran cargo generate -ap path/to/local/bevy_quickstart to test and it spent like 20 seconds loading up ~9.5GB of RAM before asking me for project name

#

weird

#

oh.. so cargo-generate seems to load the entire template into RAM before doing any templating or committing it to disk

#

and my local bevy_quickstart has a 9GB target dir ๐Ÿคช

#

which we're not explicitly ignoring because the github source doesn't have that

#

maybe we want to add an ignore = ["target"] for local cargo-generate testing purposes

tacit verge
#

i mean that's still nice but it only solves half the problem

#

if my target dir is 32 GB that's gg to my system ๐Ÿ˜”

tacit verge
#

but like idk. what if hypothetically there is a template with 20 GB of assets? cargo-generate will load it all into RAM and force you to restart your pc?

#

i would have expected it to clone to disk and work there

tacit verge
#

cargo-generate clones hard links as separate files ferris_spooky

#

so they end up taking more space in the generated repo than the template

#

target directory has a bunch of hard links in it, which makes the problem worse

tacit verge
finite depot
tacit verge
fierce jewel
#

Ooo nice! I'm definitely excited about that.

tacit verge
tacit verge
#

this thread should probably be renamed to bevy_new_2d as well

foggy relic
#

bevy_new_2d

tacit verge
#

thanks :)

#

the itch.io release succeeded as well so the rename is done now

stable cloud
#

nice!

muted vortex
#

Ah this is where quickstart went! ๐Ÿ˜†

#

There is an issue with trunk serve on windows and IPv6. I think the Trunk.toml file needs to be updated but not sure what impact this will have on other platforms

# Use IPv4 first - prevents errors on Windows
addresses = ["127.0.0.1", "::1"]
#

The error is

#

ERROR error opening browser error=Custom { kind: Other, error: "Launcher "cmd" "/c" "start" "" "http://::1:8080/" failed with ExitStatus(ExitStatus(1))" }

muted vortex
#

I'm sure y'all know this but I think the widgets approach in this template will need a reboot for 0.15 #general message

lunar valve
#

I was leading the issue for extracting those traits and I've seen no progress since

#

ah, the template defines one..

muted vortex
#

yep its a template thing not a bevy thing

finite depot
tacit verge
#

trying to update bevy_new_2d to 0.15.0-rc.1, there's a fun breaking change

#

fn spawn on the struct ChildBuilder was moved to the trait ChildBuild

#

so now in method resolution, child_builder.spawn doesn't know if we mean ChildBuild::spawn or Spawn::spawn

#

because they're both trait methods

#

whereas before, it was unambiguously ChildBuilder::spawn because that was an inherent method

tacit verge
stable cloud
#

oh, uh I'll stop working on that then ๐Ÿ˜†

round nymph
#

hello, trying to publish WASM on Itch with CD release.yaml, always getting this browser error message after deploy:
Encountered HTTP status 403 when loading asset

#

when I build wasm target in my local machine is working well

mortal breach
#

(on itch's CDN, missing files are served with HTTP 403 Forbidden instead of HTTP 404 Not Found, so the underlying problem should be "assets are missing")

round nymph
round nymph
#

add some screenshots that may help

mortal breach
#

You could download the zip from itch and inspect it / verify it works with a local web server

tacit verge
round nymph
#

ok, I'll try it

round nymph
mortal breach
#

if you don't have AssetMetaCheck::Never, you definitely need that for itch

round nymph
#

ok, doing right now

tacit verge
#

otherwise, not necessarily

round nymph
#

last question, if my window game size is 800x860px and I've defined in web/index.html this canvas dimensions:
<canvas id="bevy" width="800" height="860">

#

I must set something else in Itch config page?

tacit verge
#

an example where it's set to 1280x720

round nymph
#

what a pain ๐Ÿคฆโ€โ™‚๏ธ why is this error message arising?

#

ping @small moth

tacit verge
#

never seen that before ๐Ÿ‘€

#

i think that's github private repo ci quota?

small moth
#

Oh so we need to make the repo public and then we'd be able to rebuild?

tacit verge
#

public repos get infinite free ci

#

for private repos i'm not 100% how it works personally

small moth
#

Thanks

#

Time to go public then haha

tacit verge
#

it seems the free github plan includes 2000 (private repo) ci minutes per month

round nymph
#

thanks for your help, again @tacit verge ๐Ÿ™

tacit verge
stable cloud
#

oh, I keep forgetting I'm not on the "approval means mergeable" list for that repo lol

tacit verge
#

yeah, you could probably be added but i think i shouldn't do that unilaterally

#

hm i don't get this CI failure:

/tmp/rustdoctestv64gum/rust_out: error while loading shared libraries: libstd-ca74a2d9c5166d9f.so: cannot open shared object file: No such file or directory
stable cloud
#

oh hey, I just hit that in an unrelated crate, doing cargo test --doc --all-features


failures:

---- src/lib.rs - (line 200) stdout ----
Test executable failed (exit status: 127).

stderr:
/tmp/rustdoctesthdW3dm/rust_out: error while loading shared libraries: libstd-bd6705db1e77d5f2.so: cannot open shared object file: No such file or directory
#

wonder if rust nightly is doing something interesting

fierce jewel
#

BTW I just realized that the template is still titled "Bevy Quickstart" on the assets page for Bevy.

tacit verge
#

right, that should be changed

#

the description will probably become outdated-ish too

#

since it's not worked on by the bevy jam working group anymore, and it's meant to be the official 2d template at some point, not specific to bevy jams

fierce jewel
#

I figured, which is mostly why I brought it up here as a heads up because I just happened to notice it while looking over some other things on the asset page.

tacit verge
tacit verge
tacit verge
tacit verge
#

thanks for the reviews @finite depot :)

finite depot
tacit verge
#

yep, i know you've been busy

finite depot
#

It's funny, I just updated my own "instance" of bevy_new_2d to the 0.16 RC yesterday for my MSc. stuff and here you go updating the template itself the following day

tacit verge
#

nice

#

the audio doc test is kinda outplaying me here though

finite depot
#

Great timing, now I can change my guesswork to your better update ๐Ÿ‘

tacit verge
#

i moved some issues to the Bevy Jam 7 milestone (the non-critical / controversial / hard ones)

#

there are 11 unblocked open issues remaining in the Bevy Jam 6 milestone, with a PR ready for 1 of them

tacit verge
#

just noticed we're still using a custom OnPress component + observers for button interaction instead of the new bevy_picking stuff, i'll make a PR for that :)

#

nice to be able to simplify the template a little bit

#

hopefully we can remove the Widgets and Spawn Commands patterns for bevy jam 7 ๐Ÿ˜„

finite depot
tacit verge
#

i'm hoping we get some good ui/bsn features by bevy 0.18

finite depot
#

Aah gotcha

tacit verge
#

the video was a useful resource at the time, and could still be useful now

#

but it may also cause confusion as many things have changed since then (including the name of the template)

#

should the video be removed, or should a disclaimer be added?

finite depot
#

I'm tending towards remove, as stuff changed quite a lot. What do you think, @trim zealot ?

trim zealot
#

The linked issue re: install not working is fixable by mirroring main to that branch in the repo; GitHub already redirects from the old repo to the new rename. I understand not wanting to maintain backwards compatibility like that but breaking the install instructions was definitely a preventable situation too.

finite depot
trim zealot
tacit verge
#

btw i noticed the bevy_new_2d CI has started clean-compiling and taking 14 minutes instead of 1 minute

#

i'm not sure what the cause is. i have noticed that clean compiles are always followed by an "empty" cargo cache sweep, and iterative compiles are always followed by pretty big cache sweeps

#

which could be a red herring

tacit verge
#

@tranquil breach thoughts on this theory? cargo-sweep checks if a cache-restored file was accessed during a workflow job by comparing its atime to an earlier timestamp, so it's possible that many files are incorrectly deleted because their atime doesn't get updated (see https://unix.stackexchange.com/a/8842 )

tacit verge
#

btw the change to the release workflow is still not working. i'm gonna iterate on it in a separate repo and come back with a pr that actually fixes it

finite depot
#

Damn @foggy relic that was quick, I didn't even ping you ๐Ÿ˜„

foggy relic
tranquil breach
tacit verge
tacit verge
#

i noticed that generating a new project with bevy_new_2d brings in the three license files (MIT, Apache, CC0)

#

whereas bevy_new_minimal ignores those files

#

wondering which behavior should be preferred

#

on the one hand, we don't want to add license files to the user's new project that they don't actually want to release their project under

#

on the other hand, it's easier for the user to delete files than to add them

finite depot
tacit verge
#

i'm leaning we shouldn't include the license files by default, unless we add cargo-generate prompts for the user to choose which common license(s) they want

#

we probably shouldn't include docs/ or README.md either

finite depot
#

Fully agreed. Although for users who have just heard about bevy new 2d and may not even know about the repo, a link in a README could be useful. So they know where they can go to learn more about e.g. the workflows.

tacit verge
#

hm i see what you mean, if you know about the command but not the repo where the documentation is

#

i can add a README.md.template

finite depot
finite depot
#

(any clue why the markdown syntax highlighting made the green? ๐Ÿ˜„)

tacit verge
#

html tag probably

finite depot
tacit verge
finite depot
#

I know this was rejected before, but I'd like to revisit the idea of using pub(crate) instead of pub. When we have a lib.rs, clippy cannot detect dead code as easily. I just ran into this while adapting the template for a project. In level.rs...

pub fn spawn_level(world: &mut World) {
    // The only thing we have in our level is a player,
    // but add things like walls etc. here.
    SpawnPlayer { max_speed: 400.0 }.apply(world);
}

... I removed the SpawnPlayer because I replaced it with loading some map data from disk. To my surprise, cargo clippy doesn't have anything to say about this. I then changed:

// player.rs
/// A command to spawn the player character.
#[derive(Debug)]
pub struct SpawnPlayer {
    /// See [`MovementController::max_speed`].
    pub max_speed: f32,
}

to pub(crate) and I get 3 warnings about never used types and methods.

tacit verge
#

i'd still consider this a clippy issue, but i see your point that it would provide value to users of the template now

finite depot
#

@tacit verge do you think you could find some time for a code review? I want to rework Foxtrot into something resembling a 3D version of bevy_new_2d with external libraries on this branch in time for the jam. It's still WIP, but the first person controls are implemented. Still need to add an NPC, dialog, pathfinding, and particles. And docs, of course.
Most code that differs from bevy_new_2d is in the demo dir. In particular, I'd like some input on the player subdirectory. I especially dislike the render layers floating around, but I'm not sure where to nicely tuck them away.

normal shale
tacit verge
#

i'm going to go ahead and assume that unsafe is a no-go for bevy_new_2d ๐Ÿ˜ญ

#

you need an unsafe impl Bundle for MyType to create your own BundleEffect, e.g. for adding an observer to your entity

#

so we can't use fn() -> impl Bundle for entities that are buttons or have buttons as descendants

#

and it would probably be confusing to mix and match entity spawning design patterns

#

so no fn() -> impl Bundle in bevy_new_2d ๐Ÿฅฒ

finite depot
fierce jewel
#

BTW I went ahead and commented some stuff in #333 -- the Support JetBrains IDEs better issue. I also opened a draft PR to kinda show how this would work.

TL;DR it should be possible to add in some default build configurations like how vscode does.

finite depot
fierce jewel
#

Yeah, there are several questions that should probably be answered regarding how it's implemented, but at least it's possible ๐Ÿ˜›

tacit verge
#

i'd be happy to get the support in first and work out the rest later fwiw

#

either way

#

what are the contents of the default .idea/.gitignore?

#

also, what's the issue with shell commands? is the output format affected?

fierce jewel
#
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
tacit verge
#

well that's pretty brief so it would be reasonable enough to include, ofc that means if they change it upstream we'd want to change it in the template too which is awkward

fierce jewel
#

Yeah. The issue is some of these files (like workspace.xml) is literally just configuration of your current environment. So tabs opened and stuff.

tacit verge
#

right, it would probably be pretty annoying for a user to accidentally check that in to the repo

#

i imagine this .gitignore file doesn't change very often

fierce jewel
#

This is autogenerated whenever you first open a project in RustRover, and doesn't seem to ever be regenerated AFAIK. So it probably shouldn't change much.

tacit verge
#

seems the maintenance cost would be low and the UX benefit would be high then, so i'm in favor of including the .gitignore

fierce jewel
#

As for the issue with Shell Commands over the default cargo runners and stuff, has to do with some integration. (Such as easily switching what toolchain you're using via editing the configuration. Or being able to quickly change the build profile (dev, release, test, bench)).

Cargo will use the build tab for showing information regarding the build, which provides a slightly nicer UI with regards to build errors. If we use shell commands we can either have it execute in the IDE's Terminal, or not. If we do the former, you can easily click on where errors are, but it opens up a terminal whenever you run a command, which probably isn't a big issue. If you don't put it in the terminal then you don't really get any of that.

#

FWIW since the goal is to provide decent defaults, I think going with the shell commands is fine enough, and if someone really wants to use the cargo commands, they probably have some ideas of how to use it.

tacit verge
#

ic

fierce jewel
#

It might be possible to get that working with the shell commands, but I'm not quiet certain.

tacit verge
#

bevy CLI also supports a --verbose tag to see which commands it runs, so a user could use that to find the proper cargo commands

#

in VS Code, both "shell" and "cargo" commands have the same structured formatting because it's parsed from the output, so the decision to use bevy run for VS Code tasks was made in that context

fierce jewel
#

Yeah. Looking into it, part of that niciety is because the cargo Configuration by default has a "Before Launch - Build" which runs a build of the project generally before running it. This isn't possible with the Shell scripts though.

tacit verge
#

i'd probably lean towards cargo commands for jetbrains ides if the UX is better that way

#

fully unifying under bevy CLI is a nice ideal but it's not that important

fierce jewel
#

The UX is a bit better, but if we go with the options running in the terminal then it should be fine. That would preserve the ability to click on where an error is and the IDE will jump to it.

#

The only thing that's lost through not using the cargo commands is that build option, which while nice is also manually trigerable. (Build will also automagically take you to where an error is, but again that's also manually triggerable)

#

The only downside to running it in the terminal, is that to cancel it you have to cancel it in the terminal.

#

All right so we'd probably need to use some shell stuff anyways, so it might just be better to use the shell commands for now, at least for the web stuff since we'd also need to run wasm bind-gen and the like.

#

if we wanted to we could have the best of both worlds by making a plugin for RustRover /jk

#

At the very least, what I have in the PR now will work, and going with it might be the best idea in the short term to get something in there for the Jam.

fierce jewel
#

I'm also not 100% on grouping the build stuff in a folder/group, but if someone doesn't like it they can always change it pretty easily.

#

There is actually a slight issue with the terminal commands. I can't seem to use the RustRover debugger. So we might want to provide at least one cargo run configuration to allow debugging.I'm not sure how debugging web builds would work though tbqh.

#

So how does the plugin snippet work?

#

All right so bad news regardings the snippets:

It is possible to have it in RustRover, the only downside is they are global, so can't be shared per-project.

#

There's a plugin that, theoretically, would allow this to work but it hasn't been updated to the latest version of the IDEs, and I'm not sure when it will be.

The Plugin is Open Source, I just don't have the knowledge to maintain it, but I could potentially update it.

#

Without the Plugin the best way to share it is for me to port them to RustRover, then export my settings and only export those Templates. Which can then be downloaded and imported to work.

fierce jewel
#

BTW I've gone ahead and created the live templates for Rust Rover even though it's not the easist thing to share for the time being (that is, it's a zip file)

tacit verge
fierce jewel
#

Fair enough. If you want we can provide information on how to (briefly) setup the snippets (mostly linking to the documentation) and the like or provide my zip file if they want to try and use them. However fwiw I didn't even know RustRover had that feature, and it has several useful templates/snippets built in.

tacit verge
#

we could put that in the docs/tooling.md ๐Ÿ˜„

fierce jewel
#

Cool. It's actually fairly simple to setup, and it's mostly 1:1 with the VSCode Snippets

tacit verge
#

nice

fierce jewel
#

The main difference is Live Templates require you to set the context they work in.

#

The plugin live template in RustRover is:

use bevy::prelude::*;

pub(super) fn plugin(app: &mut App) {
   $END$
}

and is set to only work in rust modules.

The component live template in RustRover is:

#[derive(Component, Reflect, Debug)]
#[reflect(Component)]
struct $NAME$;

And is set to work in modules, statements, and expressions.

tacit verge
#

i'm merging your PR now

fierce jewel
#

All right. Do you want me to add in a cargo build really quick so we could at least have a native way to debug in RustRover or should I do that seperately?

tacit verge
#

probably a separate PR

#

will be easier to see the diff

fierce jewel
#

That's absolutely fair.

#

So how do you want me to do the section in tooling on the Live Templates?

tacit verge
#

So it could go in that section

fierce jewel
#

Well I imagine it would be it's own section for Rustrover, no?

tacit verge
#

Right but same general area since it's about editor tooling whereas the first part is about crates

fierce jewel
#

Ah all right.

tacit verge
finite depot
#

I won't push anything onto main until it's done so you don't get any merge conflict

#

I can do some level design until then

tacit verge
#

ok, i'll try and update to main real quick to unblock the pr

#

done, the merge conflict was a deleted comment

#

good to merge this pr and i can make more later, which most likely won't touch as many files

finite depot
#

merged ๐ŸŽ‰

finite depot
fierce jewel
#

So I've gotten a way to fix debugging with dynamic linking on RustRover, downside is that it's not generalizable. IE: I don't think we can, necessarily, do anything about it or set it up.

fierce jewel
#

I'm currently doing some testing on Windows to try and figure out the magic incantation for Windows on RustRover to get the same results, this way we can at least include it in documentation.

finite depot
fierce jewel
finite depot
#

@fervent locust you may be interested in this

fierce jewel
#

I imagine on OSX/MacOS it would be the same as linux, using LD_LIBRARY_PATH, or you could also probably use DYLD_LIBRARY_PATH or DYLD_FALLBACK_LIBRARY_PATH

#

If Jetbrains fixed things so you could actually use Path Variables when setting Environment Variables for Cargo Run Configurations it would definitely help

finite depot
#

@tacit verge I think your latest PR made the Widgets section of the design docs outdated FYI

#

@fierce jewel dunno if you knew this, but the CI uses LD_LIBRARY_PATH="$(rustc --print target-libdir)"

#

might be useful for what you're doing ๐Ÿ™‚

fierce jewel
#

That...might be very useful

finite depot
#

๐Ÿ˜„

tacit verge
tacit verge
#

this is likely related

fierce jewel
#

It is related, unfortunately (at least on windows) that does not work.

#

$(rustc --print target-libdir) does not actually get evaulated.

#

Also do you just want me to turn the Live Templates section into a more generic RustRover section with subsections for Live Templates and Environment Variables, or just have a separate section on debugging in RustRover with Dynamic Linking?

tacit verge
fierce jewel
#

AFAIK windows by default uses powershell and cmd.exe. But in RR I do not know what it's using to run the executable and set environment variables, although it might be cmd.exe

tranquil breach
#

Keep in mind RR might be directly executing the program using a system call, like what std::process::Command does, so it might sidestep both cmd.exe and Powershell

#

It's tricky, and something you can really only figure out through testing ^^

fierce jewel
#

Yeah

#

But yeah. RustRover (and all JetBrains IDEs in general) have built-in functionality to deal with things that will change from computer to computer but might be needed in things like RunCommands. The issue is, is that the functionality is partially broken it seems. >w>

tacit verge
#

good news: we can add observers with fn() -> impl Bundle thanks to #ui message

#

it requires a very small amount of "code that's patching something that should be provided by bevy", and no unsafe

#

i'll get a PR up in a sec

tacit verge
#

i don't love that mod audio is public only so that its doc tests compile

#

doc tests having the visibility of a consumer of the library makes no sense for internal documentation

#

there is no good solution and it's not being worked on or even discussed, though ๐Ÿ™ƒ

finite depot
finite depot
tacit verge
#

i might make a tiny 3rd-party crate with this that should hopefully become obsolete in 0.17

tacit verge
#

it's like a verbose version of the old bevy_mod_picking API:

// bevy 0.16 + bevy_spawn_observer + bevy_picking
Children::spawn(SpawnObserver::new(|_: Trigger<Pointer<Click>>| { ... }))
// bevy_mod_picking
On::<Pointer<Click>>::run(|| { ... })
finite depot
#

@tacit verge what are your thoughts on implementing pausing and a settings menu the bevy_new_2d way?

#

Just implementing the settings is easy, organizationally speaking: add a new screen called Settings, treat it like the credits screen, done

#

Just implementing pausing is also fairly simple: create two substates of Screen::Gameplay called GameplayScreen::Playing and GameplayScreen::Pause, then run most logic only in the former

#

Draw the pause UI when in the Pause substate, done

#

Cool, but I'd like to have a settings menu in both the title screen and the pause screen

#

So sending me from GameplayScreen::Pause directly to Screen::Settings wouldn't be good, as that would reset the game

#

I could just create a GameplayPauseScreen substate for GameplayScreen::Pause with a variant called GameplayPauseScreen::Settings that duplicates the content of Screen::Settings with the exception of proceeding back into the pause screen or gameplay instead of the main menu

#

but that feels a bit roundabout and boilerplatey, doesn't it?

#

Hope I'm illustrating my throughts clearly, otherwise I could make some diagrams of what I mean

#

That was design question A, now design question B

#

We currently preload all assets at the start, but shouldn't they be conditional on the level?

#

The sand level might need totally different assets than the forest level, and we don't really want to load them all at the start of the game

#

wouldn't it make more sense to preload stuff once we want to start the actual level?

#

This ofc opens the design problem of "Level A requires loading prop B, which itself loads textures C and D, and sounds D, E, and F"

#

My first approach prototyping something like that looked like

#[derive(Resource, Asset, Reflect)]
struct Level {
  #[dependency]
  prop_a: PropAAssets,
  #[dependency]
  prop_b: PropBAssets,
  #[dependency]
  prop_c: PropCAssets,
  #[dependency]
  prop_d: PropDAssets,
}

// This is located in another file
#[derive(Resource, Asset, Reflect)]
struct PropAAssets {
  #[dependency]
  model: Handle<Scene>,
}

// impl FromWorld for PropAAssets boilerplate goes here

// Repeat for all props

but that quickly started feeling a bit silly once I got a dozen props

#

Then I switched to

#[derive(Resource, Asset, TypePath)]
struct LevelAssets {
    #[dependency]
    pub(crate) level: Handle<Scene>,
    #[dependency]
    pub(crate) props: Vec<UntypedHandle>,
}
#

This is wayyyy more concise, but does not deal well with nested dependencies -> prop C cannot easily depend of things on its own

#

So I did this silly implementation:

#

impl FromWorld for LevelAssets {
    fn from_world(world: &mut World) -> Self {
        let assets = world.resource::<AssetServer>();
        Self {
            props: [
                Chair::scene_path(),
                Table::scene_path(),
                Grate::scene_path(),
                Bookshelf::scene_path(),
                LampSitting::scene_path(),
                Crate::scene_path(),
            ]
            .into_iter()
            .map(|path| assets.load::<Scene>(path).untyped())
            // BurningLogs has subdependencies
            .chain(BurningLogs::preload(assets))
            .collect(),
        }
    }
}
#

Here, BurningLogs brings in a preload function that returns the assets it needs:

impl BurningLogs {
    pub(crate) fn preload(asset_server: &AssetServer) -> Vec<UntypedHandle> {
        vec![
            asset_server
                .load::<Scene>(BurningLogs::scene_path())
                .untyped(),
            asset_server.load::<Image>(TEXTURE_PATH).untyped(),
            asset_server.load::<AudioSource>(SOUND_PATH).untyped(),
        ]
    }
}
#

This works, but looks very out of place when compared with the rest of the template, and frankly feels a bit ugly as well

finite depot
finite depot
#

If so: how do I actually access the prop's assets? I need to somehow access the handle in the hand. I cannot really get it from Res<LevelAssets> as I'd like to have multiple levels, so I don't want to query a specific one in the logic for e.g. fn animate_flower(). That flower shouldn't need to care what level she's in IMO

#

Right now, I just solve this with a constant called TEXTURE_PATH etc, as you can see above, which I can then load at runtime with the asset server. That again works, but it is entirely contrary to how we're doing asset loading so far, as our current approach calls the asset server a single time when setting up the resource and then always just fetches the Handle that is already present in the asset resource.

#

I could of course just insert PropAAssets, PropBAssets, etc. into the world after the level loads, but then they stick around until I close the program. However, they should be dropped when the level that uses them is dropped, imo.
So I could make a shallow copy of them and insert those. But then we have "zombie resources" laying around after exiting the level, all holding invalid handles.

#

Or, the level removes them all when it is dropped, but that sounds like even more boilerplate and cannot be handled by like a simple for. When you add a prop_z to your level, you better remember to manually add it to the cleanup step as well when dropping the level!

#

This file here is a good example of my struggles. No clue how to cleanly preload that. Again, the current approach I use works, it's just very different from the rest of the preloading code.

finite depot
#

Oh, and I'd like to hear @lunar valve's opinion as well

tacit verge
# finite depot but that feels a bit roundabout and boilerplatey, doesn't it?

state stack would be the clean way to do this. lacking that, this can instead be modeled as orthogonal state types. enum Screen for the major screens, Paused(bool) as a substate of Screen::Gameplay to pause and display a popup pause menu, and an orthogonal enum SettingsMenu { None, Main, Audio, Graphics } for navigating a settings menu that covers the whole screen

tacit verge
#

a state type

finite depot
#

A what

#

You mean like Screen?

tacit verge
#

same as Screen

#

yes

finite depot
#

Aaah okay ๐Ÿ™‚

tacit verge
#

i say "state type" to be unambiguous

#

because SettingsMenu::Main is the state, SettingsMenu is the state type

finite depot
#

Makes sense

#

So when we start the level, we are in Screen::Gameplay and the substate Paused(false)?

tacit verge
#

yep, and SettingsMenu::None as well

finite depot
#

Got it

#

and then when we hit escape, we can enter Paused(true) and SettingsMenu::Main?

tacit verge
#

we enter Paused(true) and still SettingsMenu::None

#

and there will be a "Settings" button in the popup pause menu

finite depot
tacit verge
#

yep

finite depot
#

And e.g. have some logic that checks whether we are in the main menu or the pause menu and style the settings menu differently

tacit verge
#

oh i figured it would be styled the same for simplicity

finite depot
#

Because in-game we might want to keep the background a bit transparent

#

Although I guess in the main menu, the background could be transparent as well ๐Ÿคทโ€โ™‚๏ธ

#

Alright, thanks, that answers my first question quite clearly ๐Ÿ™‚

tacit verge
#

ok time to read some more

tacit verge
tacit verge
#

honestly i don't know the best practice for asset management, i feel like it's in a weird place right now

finite depot
#

At least, that's the only way I could figure out in the BurningLogs example

#

And then let all asset requiring types have a preload function that returns a Vec<UntypedHandle>

#

Maybe not for bevy_new_2d specifically, but generally for me as a user of the template that want to split assets by level

finite depot
#

Maybe not even for most games, period. 200 MiB of RAM or so is not much to pay

#

Although asset preloading can take a sweet time on Wasm IME

tacit verge
#

and then when you click "Play", if the assets are still not done loading, it'll show you a loading screen. otherwise, it'll skip the loading screen

#

this gives the assets just a little longer to load in the background

#

whereas bevy_new_2d does the same thing but goes splash -> loading -> title, with unconditional loading screen even if it's only for 1 frame

#

3d games tend to load a lot more assets than 2d games, but either way i'd be more concerned with reducing user-facing loading time than RAM usage (at least as a first improvement)

#

also a loading bar, which bevy_new_2d does not have yet, would improve the UX of waiting :p

finite depot
#

@trim zealot I think those are valid points you raise on the SpawnObserver PR. The version with SpawnWith doesn't look too bad until we can upstream something

tacit verge
#

Also personally I'm not concerned about the ergonomics of fn button() itself, but moreso about the viral loss of ergonomics for any entity that has a button as a descendant. So SpawnWith is totally fine because you still return a bundle that includes an observer

lunar valve
finite depot
#

Or just remove the loading state?

lunar valve
#

You can store strong handles in one resource

#

And use raw path in systems that need those resources

#

Since they're already loaded you'll just create new strong handles

#

Without additional loading

finite depot
#

Ah yeah I see

#

and just have a const per path so that we have no duplication

lunar valve
#

Yup

#

Also preloading is now additive over no preloading

fierce jewel
#

BTW just as a note I intend to try and get the docs together for RustRover by this weekend.

finite depot
#

@tacit verge I just realized that we removed the design docs for spawner commands, but the level and player very much still do use that pattern hmm

#

I think it would be best to either replace it with a bundle or add the pattern back into the docs

#

Then of course we'd need to say "use the bundle pattern when A, and use the spawn command pattern when B"

#

I'm not sure which path is best

fierce jewel
finite depot
#

Ah, also ping @fervent locust when you're done. RustRover is his main Rust IDE, so he's also a good Guinea Pig for this

fierce jewel
#

Will do!

fierce jewel
#

I'm also going to be checking some of this against Intellij IDEA Ultimate and CLion to see if there's any meaningful differences or things to know when using the Rust Plugin with those IDEs.

finite depot
tacit verge
fierce jewel
#

Also should my RustRover documentation on debugging be in 362 (The one adding the Cargo Run Config), or should it be a separate PR?

finite depot
#

ping me if you need a review in 362

fierce jewel
#

Will do!

tacit verge
#

i think this is the simplest solution for now

#

it's not that bad imo (it works, it's just "annoying")

tacit verge
#

i'll pick at the code a bit before approving though

finite depot
tacit verge
#

ah ok, i would disagree with them then, every game should have a settings menu unless it's more of an artistic experience than a game, in which case they can delete settings.rs

#

it's (at least) as fundamental as a title screen

#

i'd consider something to be example territory if it would be useful for some but not all games, or showcases a specific bevy feature

austere shale
#

as a potential user of the template for jams I'd def welcome a settings with volume control. It's very nice QoL in a jam entry

finite depot
#

As said in my PR, I think a settings menu is non-negotiable if we want to be accessible by default

tacit verge
#

@finite depot suppose gameplay screen had a HUD with some UI

#

we'd want a fn spawn_gameplay_screen() { ... } system in gameplay.rs

#

we'd probably want that system to call commands.spawn(level(...)) in addition to spawning the HUD

#

so it would have to pass dependencies down

#

either that or we have two systems gameplay::spawn_gameplay_screen and level::spawn_level both added to OnEnter(Screen::Gameplay)

#

can i add like a tiny HUD to justify the design? ๐Ÿ˜ญ

#

like it could say Level 1 at the top of the window for example

finite depot
#

Why wouldnโ€™t you want two systems?

tacit verge
#

just seems like spawn_gameplay_screen should be the one to control what gets spawned

#

if it wants to spawn a HUD or a level or whatever

finite depot
#

Ooooh I see the justification now

#

Hmm

#

Hmmm

tacit verge
#

lol

finite depot
#

Let me brood on this for a while

tacit verge
#

there's no correct design TM ofc

finite depot
#

I may just be biased against boilerplate

fierce jewel
finite depot
#

@tacit verge after rolling it around my head a while, I think the cleanest design is to actually run two systems in that case, spawn_level and spawn_hud.

#

Though I'm ready to give in if someone else jumps in and says otherwise

finite depot
fervent locust
fierce jewel
finite depot
#

@tacit verge updated my PRs

tacit verge
finite depot
#

I'm using the default debugger settings:

#

BTW @fierce jewel I can tell you why the automatic resolution for the LD_LIBRARY_PATH didn't work

#

it escaped the special symbols:

fierce jewel
#

It doesn't do that on WIndows.

finite depot
#

huh

tacit verge
fierce jewel
finite depot
fierce jewel
#

You also need to add ./target/debug/deps to that as well.

finite depot
#

oh whoops

#

it says right there in your documentation ๐Ÿ˜„

fierce jewel
#

I'm honestly surprised it ran without that.

finite depot
#

still same though

finite depot
#

Because I don't want to bother with it ๐Ÿ˜„

fierce jewel
#

You also need to use the cargo run configuration as well

#

You can't use the shell scripts

finite depot
#

Oooh I see

#

where did I do that again?

#

(been a few years since I user RustRover)

fierce jewel
#

You can add in a new run configuration or use the one from the PR Pyrious merged

finite depot
#

oh I see

finite depot
#

./target/debug/deps:/home/hhh/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib

fierce jewel
finite depot
#

compiling debug now ๐Ÿ™‚

#

@fierce jewel break points work now!

#

๐Ÿ˜„

fierce jewel
#

Woo. I also found out you can attach the debugger manually in the shell scripts, but it's not great. So there's that.

#

You run the game, then attach the debugger by going to Run > Attach To Process and then finding the right process. It can then attach.

#

I feel this should be documented as well, but I'm not quiet sure where.

finite depot
fierce jewel
#

Just do that and then rerun it.

finite depot
#

Nopes, now getting /home/hhh/git/bevy_new_2d/target/debug/bevy_new_2d: error while loading shared libraries: libstd-bd3f4c5fdfb888bb.so: cannot open shared object file: No such file or directory

#

I have LD_LIBRARY_PATH set to ./target/debug/deps:/home/hhh/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib

#

where rustc --print target-libdir prints /home/hhh/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib

fierce jewel
#

Change your channel in the run configuration to nightly

finite depot
#

oooh right

fierce jewel
#

Because otherwise it uses the default for the project, which is stable.

finite depot
fierce jewel
#

can you copy/paste the LD_LIBRARY_PATH values?

fierce jewel
#

And you're on Linux?

finite depot
fierce jewel
#

All right I'm waiting on it to compile on my end

#

I'm mildly surprised JetBrains doesn't seem to make this automagic considering they have to know IMHO. It's not like they haven't put out several materials regarding RustRover and Bevy

#

Also thank you for sitting here with me and working through this Jan.

#

I'm not sure why it's not working...it's working for me when I made those changes...

#

Can you copy/paste the entire bit that's in Environment Variables? (Not the menu, just the text box next to it)

finite depot
finite depot
#

LD_LIBRARY_PATH=./target/debug/deps:/home/hhh/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib

#

maybe needs "

#

nope, that wasn't it

#

If we can't find it out, I'm sure my local code / linux / Rust / overall wizard @hearty cosmos can help tomorrow, if we find the right incantation to motivate them โœจ

fierce jewel
#

I did notice there was an extra space, maybe remove that? Aside from that, maybe try switching to stable and see if it works that way?

#

Because otherwise ours match 1:1, minus the user

#

all right so I just checked and @finite depot remove the space and try again. when I added in the space it failed.

finite depot
#

@tacit verge I addressed your comments

finite depot
#

Thanks, it works now (on nightly)!

fierce jewel
#

Woo!

#

I feel I should include a note somewhere in the documentation on that because that is really not intutitive and is super easy to miss.

#

BTW I think the Web Dev build is broken atm

#

All right So web dev/release is broken.

It breaks because of line 18-19 in title.rs

#[cfg(not(target_family = "wasm"))]           widget::button("Exit", exit_app),
finite depot
#

Could we add bevy build web to the CI?

fierce jewel
finite depot
#

wait what is the error even telling me ๐Ÿ‘€

#

@fierce jewel how did you fix it?

fierce jewel
#

I believe what's happening is that the children! macro does not play nicely with the conditional compilation (I think it's trying to use it as part of the macro?)

#

I fixed it with:

        #[cfg(not(target_family = "wasm"))]
        children![
            widget::button("Play", enter_gameplay_screen),
            widget::button("Credits", enter_credits_screen),
            widget::button("Exit", exit_app),
        ],

        #[cfg(target_family = "wasm")]
        children![
            widget::button("Play", enter_gameplay_screen),
            widget::button("Credits", enter_credits_screen),
        ],
finite depot
#

oh right

#

thx

tacit verge
fierce jewel
#

Oh btw Jan, mind checking out the changes to the docs I just made?

#

I believe I addressed some of your comments already

finite depot
#

surely there must be a better way, but this at least compiles again

finite depot
fierce jewel
#

Ah all right, will do.

finite depot
#

@tacit verge re: your answer, yeah, I really really want a pause menu with a transparent background

fierce jewel
#

Oh I see what happened. I actually...didn't commit my changes..

tacit verge
finite depot
fierce jewel
#

All right my changes should be pushed now Jan

finite depot
#

you'll never guess the error message

#

sec

tacit verge
#

๐Ÿ˜… maybe we can have it return an empty bundle in wasm

tacit verge
#

yeah if you know how the macro works internally this error message is what you would expect

#

that's a big IF though

#

the cfg ends up inside the Spawn(...) so it has no arguments

fierce jewel
#

Yeah that seems about right

finite depot
finite depot
#

Added a little suggestion, otherwise the factual content seems good to me ๐Ÿ™‚

#

@tacit verge could you do the style and grammar check?

tacit verge
#

sure

finite depot
#

I left tests and doc tests out for now since IME it's enough to just confirm that it even builds on web

#

@tacit verge bevy test is not a thing, I believe

#

We could just manually set the compilation target

#

But there is also something nice about directly using the bevy CLI in the workflow

finite depot
#

Re: --all-targets, I fully agree! I have already removed that from some workflows in the past, thinking "Oh, I don't want to compile for all targets, that's wasteful". The naming is really really bad in this case!

fierce jewel
#

FWIW I'm just happy I caught that issue with web now, instead of someone mentioning it to us after the jam starts

tacit verge
#

true

#

we should trigger a final release workflow before the jam starts though

tacit verge
finite depot
#

should this say "release"? hmm

tacit verge
#

probably not

#

i noticed in the settings menu when putting the volume very high, we have a second "on hover" sound effect occur on release

finite depot
tacit verge
#

it seems it's because we're using the Interaction component instead of observers

#

it goes back to Interaction::Hovered when it's no longer Interaction::Pressed

#

why is Pointer<Over> triggered a second time for a button when you hover its text?

#

is that event bubbling?

finite depot
tacit verge
#

it's a known issue apparently

#

#ui message

finite depot
#

So I guess we just leave it as-is for the moment?

tacit verge
#

btw we should also only be playing the pressed sfx on click, not on press

#

so effectively on release

finite depot
#

thanks for investigating

finite depot
tacit verge
#

if you hover over a button, press, drag out, and release, it won't activate the button because you canceled your click

finite depot
#

Oooh got it

tacit verge
#

but rn you still get the sfx when you pressed

finite depot
#

Yeah, t hat makes sense

tacit verge
#

that would already work with a Pointer<Click> observer, but i don't want to use an observer for one sfx and a system for the other :p

tacit verge
#

once those comments are resolved i'll do a final pass that'll probably just be a few small things. it's a little awkward to continue with all the suggestions breaking up the flow of the text

fierce jewel
#

Thanks Pyrious, I will note I have a very odd writing style, and tend to be a bit more verbose than necessary.

Also thank-you for noting how to specify the channel, I actually had no idea how to do that.

#

All right I've gone through and updated the documentation based on feedback

tacit verge
tranquil breach
#

If Swatinem/rust-cache ends up just being better, I may talk with the other maintainers of Leafwing-Studios/cargo-cache about deprecating and archiving it

tacit verge
#

i found another bug with our buttons

#

if you hover a button's text, mouse down, move mouse so you're still over the button but not over the text, and mouse up, it won't register as a click

#

same thing if you start on the button and move to the text

#

it's easy to verify this with UI debug overlay toggled on by pressing backtick

finite depot
#

Dunno how well-known this is, but itch now has a Bevy Engine option for metadata. Updated bevy_new_2d accordingly ๐Ÿ™‚

tacit verge
#

great, this has been a thing since december 12th 2024 i think

#

Rust is an option there too

tacit verge
#

this is the command you're running?

cargo binstall --no-confirm --git=https://github.com/TheBevyFlock/bevy_cli --locked bevy_cli
finite depot
#

let me update my binstall, maybe that's the issue

tacit verge
finite depot
#

I also get no error when not running --force

tacit verge
#

i wonder where it's getting =0.1.0-dev from?

#

ah right that's in the Cargo.toml of the bevy_cli github repo

tacit verge
#

it looks like maybe cargo-binstall forgets that you passed a --git argument when it gets to the final "install from source" fallback

#

it looks for the crates.io version of bevy_cli which is a namesquat bevy reserved crate that only has 0.0.1 released, so it fails

finite depot
#

@foggy relic do you want give the template a review before the jam?

#

Would be nice to have a link to it this time around ๐Ÿ™‚

#

Although that is probably already contained within the CLI showcase

foggy relic
#

Still sick today :/

finite depot
tacit verge
#

@finite depot do you know if the windows white flash issue still occurs in bevy 0.16?

finite depot
#

I haven't noticed it on my end

#

But that doesn't have to mean it's gone

tacit verge
#

although we're linking to the bevy 0.14 version of this example

finite depot
#

I have something about the CLI doing an audio hack for us in mind

#

don't know if it's exactly this

tacit verge
#

ah, no, i don't think so

#

the audio hack is something that every bevy game basically already uses, idk exactly what that's for

#

the blog post is saying to disable the background music in your game (for web builds only) and instead load it using web apis directly

finite depot
#

Alright, I see

tacit verge
#

which only really works well if your game uses 1 background track the whole time, but when it works it works

finite depot
#

Maybe another performance hack could be to disable your Bevy code on web and replace it with web APIs as well /s

tacit verge
#

lol

#

also the ending of the blog post is interesting

#

This approach can be extended by communicating between the Rust and JavaScript code in order to control the music. This code will play the same song in a loop, which was good enough for our game, but it might be severely limited for your use-case.

A more rigorous solution would be to implement a new library that uses the Web Audio API as an audio backend on the web, but that would require a lot of work. Also, there doesnโ€™t seem to be enough interest in this topic in the Bevy community.

#

saying in theory you could instrument the web audio API from your rust code so you're not so limited

tacit verge
#

was there a reason we're not using bevy build for native release builds in the release workflow?

#

we're using it for the web release build only right now

tacit verge
tacit verge
#

which is kinda neat as part of the showcase on itch.io but not intended

#

i'll get back to this tomorrow

normal shale
finite depot
#

๐Ÿ‘€

tacit verge
finite depot
#

Didn't check yet (am doing level design stuff today)

tacit verge
#

would we want to add this to .vscode/settings.json?

    // Prepend `mod.rs` files with their parent directory.
    "workbench.editor.customLabels.patterns": {
        "**/mod.rs": "${dirname}/mod.rs"
    },
#

so mod.rs is displayed in the editor tab as util/mod.rs

#

i'm switching my personal template from foo.rs + foo/ to foo/mod.rs... i gave foo.rs a chance and it was ok but having twice as many names in src/ is annoying

#

and i think 99% of rust devs prefer foo/mod.rs even though foo.rs is "recommended"

finite depot
#

But it sounds cool

tacit verge
tacit verge
#

box shadows are pretty

finite depot
tacit verge
#

it makes the "Game paused" text look kinda flat in comparison but whatever :p

finite depot
tacit verge
#

the buttons also move upwards when you hover and leave the shadows in place

finite depot
#

Good job tweaking those knobs

tacit verge
#

that took some hackery

finite depot
#

I love the pixelated font as well

tacit verge
#

thanks i made it myself ๐Ÿ’…

finite depot
#

Oh what

#

You can do thatโ€ฝ

tacit verge
#

i started it during bevy jam simulator and kept working on it for a while

#

yeah i drew it with aseprite

finite depot
#

Fonts for me always feel like magical artifacts bestowed upon us by absent gods

tacit verge
#

they're just vector art + kerning data :)

tacit verge
#

the pixel font converter converts a .png grid of pixel art glyphs into vector graphics and lets you add metadata / kerning info

#

internally i mean. it outputs a ttf

finite depot
#

Thanks for the crash course, haha

tacit verge
#

btw you may or may not know about inline_tweak. i hadn't used it for a while, but reached for it now because bevy_editor_pls isn't updated to 0.16 yet

#

it has a new #[tweak_fn] attribute which lets you edit any constant in the decorated function and the new value is "hot reloaded" automatically

#

as opposed to without the attribute where you have to explicitly wrap all your constants in tweak!(...) before hitting compile

#

i'm putting #[tweak_fn] on all my impl Bundle functions and it's very convenient

#

compiled out of release builds ofc

#

i have to make the entities respawn to see the new values in action, like by closing and re-opening a menu. nbd

tacit verge
#

i'm trying to look into the running out of space caching issue in CI

#
zstd: error 70 : Write error : cannot write block : No space left on device 
/usr/bin/tar: cache.tzst: Wrote only 4096 of 10240 bytes
/usr/bin/tar: Child returned status 70
/usr/bin/tar: Error is not recoverable: exiting now
Warning: Failed to save: "/usr/bin/tar" failed with error: The process '/usr/bin/tar' failed with exit code 2

i hit this in my personal template in the Test job

#

its cache is 4GB, which is already a lot, then more disk usage resulting from actually running the test command, and then yet more disk usage from trying to create a compressed file to save as the new cache

finite depot
tacit verge
#

so i suspect it is using the full 14GB

finite depot
tacit verge
#

my current thought is we're doing too much in the Test job

#

it takes like 12m fresh and generates 4GB cache

#

trying to look at how other big rust crates handle CI caching

#

so far checked serde and rand, they just don't do caching and their commands are smaller

tacit verge
tacit verge
#

example:

      - name: Test rand
        run: |
          cargo test --target ${{ matrix.target }} --lib --tests --no-default-features
          cargo build --target ${{ matrix.target }} --no-default-features --features alloc,os_rng,small_rng,unbiased
          cargo test --target ${{ matrix.target }} --lib --tests --no-default-features --features=alloc,os_rng,small_rng
          cargo test --target ${{ matrix.target }} --examples
#

tokio does use caching, via Swatinem/rust-cache, but again more specific commands

stable sandal
#

you could remove debug info in CI as that's never used and should free a lot of place

normal shale
#

I think @tranquil breach recently investigated a different caching action, I think it includes less files in the cache. maybe that could help as well

finite depot
tacit verge
#

if we're talking about Swatinem/rust-cache then yes

normal shale
#

Ah OK never mind :D

tacit verge
#

i recorded my thoughts in the issue so they won't get lost

finite depot
#

We test exactly one combination: activate all features

#

How can that take up more space than first testing feature A and then feature B?

#

I guess if the last feature permutation results in fewer dependencies being pulled in, that could have an effect ๐Ÿค”

tacit verge
#

think i got all features confused with all feature combinations

#

the other repos have like 100MB caches

#

i guess we have a lot of dependencies through bevy

tranquil breach
#

Yeah, the CLI and linter have Bevy with all default features disabled in order to decrease CI times and cache sizes

#

That's not really feasible with a template, though

viral blaze
#

I've used this example for a bit, but now for a new project I am actually trying to use the CICD integrations with Itch and the Build for Web step is timing out. I haven't even changed anything on the project yet simply generated the initial template.

normal shale
#

Perhaps we should enable --verbose in CI to aid with debugging

viral blaze
#

Well I can see that it's simply taking too long to build with whatever default / free runners Github actions have configured, as it's being killed exactly after 30 minutes while it's still building.
At that stage it's installing wasm-bindgen

...
     Finished `web` profile [optimized + debuginfo] target(s) in 22m 20s
info: bundling JavaScript bindings...
warning: failed to run wasm-bindgen, trying to find automatic fix...
...
finite depot
finite depot
viral blaze
#

Okay so in my case with default build runners from github cicd it takes +-32m to finish the build and +-47 for the release. Since I haven't changed anything at all perhaps we should increase that default timeout on the template?

#

Also one interesting thing that happened to me is that it picked the linux bundle rather than the web bundle on itch.io, so I had to manually change it

finite depot
#

(31 of which are the Windows runner)

tacit verge
#

the release workflow is also a lot slower currently due to compiling bevy_cli, especially on the windows runner

viral blaze
#

Perhaps it has different limits on runners

tacit verge
#

so it seems like private repo + windows runner + compiling bevy_cli now pushes the time very high

#

fwiw we don't need bevy_cli for anything but web builds, but i modified the workflows to use it anyways in anticipation of hopefully being able to cargo-binstall it soon

tacit verge
normal shale
tacit verge
#

experimenting with some workflow improvements in my personal template ๐Ÿ˜„

#

the boxes are all checked by default, but you can modify their defaults by editing release.yaml

tacit verge
#

setting RUSTFLAGS: -C debuginfo=0 -C incremental=no was very effective at reducing cache size

#

i haven't tested the flags separately

#

the first and second cache were about 2.7GB and 3.2GB previously

tacit verge
#

the third cache is the release workflow caching the web build, and it was about the same size before too, because debug info is already disabled for release builds

#

and i guess release builds are just significantly smaller overall

tacit verge
#

ok so i have a proposition that i think is not the right choice for bevy_new_2d but figured i'd mention it

#

because my personal template is jam-focused, i modified the release workflow to run on every commit to main, only doing a web release, and with caching enabled

#

then i realized i can remove the build web job from the CI workflow since it's made redundant by actually releasing for web on every commit instead

#

plus there's the cache size reduction from making that a release build instead of a dev build

#

the main downside afaict is that "release to itch.io on every commit" is a strange default for a non-jam game

tranquil breach
#

If you don't mind, could you test how much space debuginfo=1 and debuginfo=line-tables-only take up? I'm hesitant to remove all debug info, since it may help diagnose issues only apparent in CI for tests

tacit verge
#

will do

tacit verge
tacit verge
#

debuginfo=0 vs debuginfo=1 (still with incremental=no):

JOB       BEFORE AFTER
test      830MB  1GB
build     540MB  540MB
bevy-lint 630MB  670MB
doc       620MB  610MB
clippy    620MB  610MB
tacit verge
#

debuginfo=0 vs debuginfo=line-tables-only (still with incremental=no):

JOB       BEFORE AFTER
test      830MB  1GB
build     540MB  540MB 
bevy-lint 630MB  590MB
doc       620MB  610MB
clippy    620MB  580MB
#

there seems to be some noise, and i think technically we only care about the test job because that one compiles a dev build

#

so order of +200MB in both cases

#

i'm going to go with debuginfo=0 for my personal template, but i can see being cautious and going with debuginfo=1 for bevy_new_2d for now. it should be a big win regardless

tacit verge
finite depot
#

We could have a continuous_release flag or something like that in this template

#

Though I bet this would cause some people to accidentally cheat the deadline for jams by not remembering that their fixes are landing live, haha

tacit verge
#

test and build-web on bevy_new_2d went from 1.7GB and 1.9GB cache to 840MB and 960MB ๐Ÿ˜„

austere shale
finite depot
#

I've also been thinking whether we can disable cache for everything except test and web. Thoughts?

austere shale
# finite depot ah, nice!

they better do that, otherwise it would be really easy to cheat that in every jam ๐Ÿ˜…
edit: sry for the late edit - I wanted to reply to make more sense/add context...

austere shale
finite depot
fierce jewel
#

Yeah. I still remember when this was quickstart ๐Ÿ˜›

#

(FWIW I welcome the morphing into definitely more of a 2nd party template)

finite depot
#

I like the pattern, though ๐Ÿ™‚

fierce jewel
#

It's also been immensely useful in providing a resource to point people towards regarding code layout, styling, and design if that makes any sense.

finite depot
fierce jewel
#

At least for me personally, I've definitely used things that the template does to enhance my own stuff and to get a better understanding of things like custom commands, as it's pretty bare bones. When combined with something like the bevy cheatbook, it becomes really nice.

finite depot
fierce jewel
#

Also with the documentation on RustRover, it's quickly becoming a more useful resource for things like Bevy and RustRover...and probably has the most comprehensive documentation on setting things up to work (like with the Debugging with dynamic linking), as otherwise you have to scour and piece together a few different bug reports, messages in this Discord, and/or reddit posts.

finite depot
fierce jewel
#

Also bevy_new_2d, even as a 2nd party resource, does fill in a nice niche/need for Bevy -- that is a quick 2d project template. Which is something that I know several game engines have, which definitely help with onboarding.

fierce jewel
#

But even their official blog posts don't mention anything regarding debugging with Dynamic Linking and the like .

#

also cargo generate is great

finite depot
#

I think theyโ€™d be happy to link to it

#

Or yoink it

fierce jewel
# finite depot Can you ping them somewhere?

I don't have any contact with JetBrains beyond being a customer, unfortunately and I'm uncertain if there's anyone from JB (although, tbh, I'm sure there are a few people that are here.)

finite depot
fierce jewel
#

(YouTrack is also JetBrain's own Issue Tracking software)

austere shale
tranquil breach
#

You'll be able to use this once we release v0.1.0 of the linter, since that release will include prebuilt binaries

tacit verge
finite depot
#

ah, beautiful cache hits!

tacit verge
#

finally fast CI again

finite depot
#

FYI

#

Still leaves the workspace-related issues

#

@tacit verge are you planning on implementing pausing in bevy_new_2d?

finite depot
#

Sweet ๐Ÿ˜„

tacit verge
#

i have pausing in my personal template already, although that's using pyri_state, but it should be reasonable to translate

#

i just wanted to figure out the title -> settings vs pause -> settings thing in my personal template first before bringing it to bevy_new_2d

finite depot
#

I was just thinking about implementing it on my own, but I trust your ability more in this regard

#

BTW, you don't happen to have any idea what is up with mouse locking on itch.io pages on Firefox, right?

tacit verge
finite depot
#

For me, the mouse goes haywire when not in fullscreen

#

Also firefox / linux

tacit verge
#

10s of testing the mouse it seems to work fine, but choppy audio :)

finite depot
#

Yeah the audio is choppy AF for the first few seconds

#

Really not sure what to do about that except call the web APIs directly

tacit verge
#

wall jumps would be cool with these walls lol, not to add scope creep but i assume bevy_tnua has support

finite depot
#

Thinking of making a crate that just observes OnAdd, AudioPlayer, despawns them instantly and calls web APIs on web

tacit verge
#

also Esc to take back cursor control also putting you back in title screen, and then have to respawn the level which takes like 5s

finite depot
finite depot
#

That, it's needed to be able to easily tweak mouse sensitivity and FOV

#

going back to the title screen for that and then reloading the level makes no sense

tacit verge
#

yeah makes sense

#

i was gonna research what actual games do for this

#

is it the same settings menu from title vs pause or different

#

or mostly same with different bg

finite depot
#

I've seen both

tacit verge
#

either approach can be implemented but just need to know which one

finite depot
finite depot
tacit verge
#

ah ic

#

time to go through my steam library

finite depot
#

Which is fine, but for FOV having a slightly transparent BG is very nice

#

Also for eventual graphics options

tacit verge
#

makes sense

finite depot
#

So that is what I've been seeing in newer releases

tacit verge
#

so most likely we'd want the same menu but a different backing overlay

tacit verge
#

tbh it'd probably still be a different state

#

but reuse the same entity spawning fn

finite depot
#

Yeah makes sense

#

That also means being able to differentiate options that don't really make sense in-game

tacit verge
#

interesting, do you have an example?

finite depot
#

e.g. a button for "Setup my TrenchBroom directory on my computer so that I can create my own levels plz"

tacit verge
#

oh or in minecraft you have world difficulty

#

like per-save settings

finite depot
#

Right!

#

That's a very good example

tacit verge
#

ok so they definitely should be separate

#

i wonder if older games used the same menu to save storage space or w/e

finite depot
#

Some games also have some graphics options only available when in the main menu

#

But I don't know if that is just sloppyness lol

tacit verge
#

they probably don't want to implement hot reloading :p

austere shale
tacit verge
# finite depot

is there an upstream rustc issue for this? i don't see it linked anywhere

finite depot
#

Does it just noop in those cases

finite depot
viral blaze
#

Hello, I am trying to load my levels from toml, and that works, and I am doing it from the AssetServer identically to what is done for the footsteps audio in the example.

#[derive(Resource, Asset, Reflect, Clone)]
pub struct LevelAssets {
    #[dependency]
    pub levels: Vec<Handle<Level>>,
}

impl LevelAssets {
    pub const PATH_LEVEL_1: &'static str = "test.level.toml";
    pub const PATH_LEVEL_2: &'static str = "test2.level.toml";
}

impl FromWorld for LevelAssets {
    fn from_world(world: &mut World) -> Self {
        let assets = world.resource::<AssetServer>();
        Self {
            levels: vec![
                assets.load(LevelAssets::PATH_LEVEL_1),
                assets.load(LevelAssets::PATH_LEVEL_2),
            ],
        }
    }
}

I was trying to access the actual loaded levels but I've been struggling to find out how, since it seems all I can get are handles. I was originally trying to do it in a command from_world but I've even gave up on that to simplify, however I still don't understand how to go from a Vec<Handle<Level>> to the concrete level I want.

I messed around with try_downcast_ref as is level_ref: &dyn PartialReflect but no luck.

fn update_level(current: Res<CurrentLevel>, level_assets: Res<LevelAssets>) {
    // TODO despawn existing level
    if let Some(level_ref) = level_assets.levels.iter().nth(current.level) {
        if let Some(level) = level_ref.try_downcast_ref::<Level>() {
            error!("loaded level positions {}", level.positions.len());
        } else {
            error!("failed downcast");
        }
    } else {
        error!("level {} not found", current.level);
    }
}
austere shale
# finite depot Does it just noop in those cases

IIRC Confined tries to fallback to locked and vice versa

Since Windows and macOS have different CursorGrabMode support, we first try to set the grab mode that was asked for. If it doesnโ€™t work then use the alternate grab mode.

viral blaze
#

Okay so this works:

fn update_level(level_assets: Res<LevelAssets>, levels: Res<Assets<Level>>) {
    // let get: Option<Handle<Level>> = level_assets.levels.get(0);
    if let Some(level_handle) = level_assets.levels.get(0) {
        if let Some(level) = level_handle.try_downcast_ref::<Handle<Level>>() {
            if let Some(level) = levels.get(level) {
                trace!("level positions {:?}", level.positions);
            }
        } else {
            panic!("Failed to load level!");
        }
    }
}

However I don't understand why I need to try_downcast_ref to Handle<Level> since the compilers knows that what I have is a vector of Handle<Level> anyway.
I would expect let get: Option<Handle<Level>> = level_assets.levels.get(0); to succeed, however instead

mismatched types
expected enum `std::option::Option<bevy::prelude::Handle<level_assets::Level>>`
   found enum `std::option::Option<&(dyn PartialReflect + 'static)>` [E0308]

Either way, thanks!

finite depot
#

Oh wait I see

#

No, wait, you do have them

#

The heck?

#

FYI you can also skip reading the handles completely and just load the level with an asset server again. Since the preloaded handle is still in memory inside a resource, loading the level a second time uses the already loaded data.

#

That can save you some boilerplate

#

But I'm very confused why you had to go through this song and dance in the first place

finite depot
#

@trim zealot how much in advance of the jam do you think the video should be?

#

Asking so we can make sure our bigger changes are done in time ๐Ÿ™‚

trim zealot
# finite depot <@103513724052082688> how much in advance of the jam do you think the video shou...

Publishing at least a couple days before would be good. Gives a marketing beat for the jam and gives people a day or two to actually take a look at the templates and play with them before deciding to use them for the jam. I think jam plan is still first week of June right?

I think the CLI is going to publish before then too, so planning to cover that as well. Would be great to be able to use the bevy cli with the flock templates for that video.

fierce jewel
#

That monitor stuff is...rather annoying from what I saw while looking into it fwiw.

fierce jewel
#

winit itself has current_monitor() on windows, which returns an Option<MonitorHandle> which is an handle to the Monitor, if the window is on one.

Unfortunately I'm not quite sure how to access that from Bevy, and there may not be a way?

tacit verge
#

it's probably just an API gap

fierce jewel
#

Yeah looks like this has been at least complained about once, back around 0.9

#

This issue was brought up: https://github.com/bevyengine/bevy/issues/6993

In which due to changes in how windowing worked, something broke. However the ability to get the monitor the window is on wasn't really added it seems.

The changes were later reverted or otherwise changed, so the issue was closed.

GitHub

What problem does this solve or what need does it fill? Prior to 0.9, it was possible to have "window persistence" for a multi-monitor setup. By window persistence I mean that the app wil...

#

Which one of us wants to open the issue? ๐Ÿ˜›

tacit verge
tacit verge
#

does MonitorSelection::Current not work?

#

idk if i was missing something previously or if i'm missing something now

fierce jewel
#

As far as I can tell, MonitorSelection::Current tells you absolutely nothing about the monitor it's on

tacit verge
#

for the purposes of a video mode selector, as long as it stays in the same monitor when it becomes fullscreen, that would be fine right?

fierce jewel
#

Sure, but we can't tell what monitor the window is on in the first place. So we can't limit resolutions to what a specific monitor provides.

#

So, for example, if you have two monitors and they both support different resolutions, the game has no way to limit the resolutions we get to only the monitor it's on AFAICT

tacit verge
#

that's what i was missing, thanks

fierce jewel
#

Yeah. Technically there is a way to determine what window we are on, but it's kinda hacky.

#

And I can only test on Linux -- and particularly X11 atm.

#

TL;DR if you get the window position, and then get all the monitors you can calculate whether or not the window is within the physical position of one of the monitors.

#

Although if WindowPosition is ever Automatic we can't tell

tacit verge
fierce jewel
#

Here's a system that should work, at least on Linux under X11:

fn detect_window_monitor(window: Single<&Window, (Changed<Window>, With<PrimaryWindow>)>, monitors: Query<&Monitor>) {
    println!("POS: {:#?}", window.position);

    let position = match window.position {
        WindowPosition::Automatic => return,
        WindowPosition::Centered(_) => return,
        WindowPosition::At(ivec) => ivec,
    };
    
    for monitor in monitors {
        let extents = [
            monitor.physical_position,
            monitor.physical_position + monitor.physical_size().as_ivec2()
        ];
        
        if position.x >= extents[0].x && position.x <= extents[1].x && position.y >= extents[0].y && position.y <= extents[1].y {
            println!("Within {:?}", &monitor.name);
        }
    }
}
#

This is limited to one window, and I use Changed so I don't get spammed with output, but.

tacit verge
#

oh lol i see, yeah that's not nice. definitely not bevy_new_2d material

fierce jewel
#

If window.position is WindowPosition::Automatic then we can't tell.

if window.position is WindowPosition::Current we can't tell.

tacit verge
#

so the other option for bevy 0.16 is to include a monitor selector in our settings menu as well?

fierce jewel
#

Yeah.

tacit verge
#

ok, i think that would be reasonable enough to add to the template for now anyways

fierce jewel
#

Even then if the window is moved, and it's not 'sticky' then it could be incorrect. But.

tacit verge
#

yep

tacit verge
#

i'll link to that in the issue

fierce jewel
#

Cool. also the following code would provide a function that can -- roughly -- determine the monitor a window is on (at least on Linux):

fn determine_monitor<'a>(window: &Window, monitors: Vec<(&'a Monitor, Option<&PrimaryMonitor>, Entity)>) -> Option<&'a Monitor>{
    match window.position {
        WindowPosition::Automatic => None, // we can not determine the monitor it's on at all.
        WindowPosition::At(window_pos) => {
            let mut zero_monitor = None;
            for (monitor, ..) in monitors {
                let extents = [
                    monitor.physical_position,
                    monitor.physical_position + monitor.physical_size().as_ivec2()
                ];
                
                if monitor.physical_position.x == 0 && monitor.physical_position.y == 0 {
                    zero_monitor = Some(monitor);
                }

                if window_pos.x >= extents[0].x && window_pos.x <= extents[1].x && window_pos.y >= extents[0].y && window_pos.y <= extents[1].y {
                    return Some(monitor)
                }
            }
            zero_monitor
        }
        WindowPosition::Centered(selection) => match selection {
            MonitorSelection::Current => None, // We can not actually determine position.
            MonitorSelection::Index(idx) => None,
            MonitorSelection::Primary => monitors.into_iter().find(|(_, p, ..)| p.is_some()).map(|(m, ..)| m),
            MonitorSelection::Entity(entity) => monitors.into_iter().find(|(.., e)| *e == entity).map(|(m, ..)| m),
        }
    }
}
#

That works under a handful of conditions, but there are some conditions where I just don't think we can tell. For example, when Monitor Index is used, we can't tell which monitor is at which index, as Bevy also does not expose that information.

#

If the MonitorSelection is current, then we can't know because we don't have any way to get that information.

#

If Window Position is automatic, there is no way to tell where it's at.

#

We can only determine the window's position with absolute certainty in one case, and we can likely determine the window's position in about half of the potential paths.

#

Apologies for the rambling btw, I just wanted to at least somewhat document what I've found and what could be done as a work around just incase someone is looking through the discord to find how to do this in the meantime.

tacit verge
#

iirc WindowPosition::Centered and Automatic are temporary variants that get converted to At, so maybe you can ignore those cases

fierce jewel
#

Yeah. That could work, although there are some cases where it could be triggered.

#

Namely if you set the window position with Centered and then the system that determines the Monitor the window is on on runs afterwards, then it might still have WindowPosition::Centered

tacit verge
#

maybe you can run after the system that resolves the window position to At?

#

it seems to happen in the changed_windows system which runs in the Last schedule, but not if the window manager has to be the one to set the window position, aka in the WindowPosition::Automatic case. anyways yeah not ideal

finite depot
fierce jewel
#

But I could put it in its own crate too.

#

Not sure what to name it tho...

fierce jewel
tacit verge
#

i refactored my personal template, moving pretty much everything in UI into widget.rs, and it's much nicer this way

#

makes me think the two settings menus (from title vs from pause) should just use widgets as code sharing

#

aka put the entire volume, video mode, etc. widgets in widget.rs

#

there would still be duplication in the actual spawning code for the two menus, but i think that's correct, so it's easy to change one menu without affecting the other

#

and it'd only be like 10 duplicated lines at worst

#

well.. maybe a more involved settings menu would have more duplication

#

but you could split into pages (e.g. audio, graphics, etc.) and have entire pages be widgets

tacit verge
#

there is the risk that a user will add something to one settings menu but forget to add it to the other i guess

tacit verge
#

if you want to make that one page different, then you'd have to replace the widget with inline code yourself. or make it 2 widgets that share a helper function

finite depot
finite depot
#

Could automatically insert a Monitor component into Windows in PreUpdate ๐Ÿ™‚