Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Add command to watch for changes #245

Open
TimJentzsch opened this issue Jan 24, 2025 · 1 comment
Open

Add command to watch for changes #245

TimJentzsch opened this issue Jan 24, 2025 · 1 comment
Labels
A-Run Related to the bevy run command A-Web Building or running Bevy apps targeting the browser C-Feature Make something new possible D-Complex Quite challenging from either a design or technical perspective. Ask for help! S-Needs-Design This issue requires design work to think about how it would best be accomplished

Comments

@TimJentzsch
Copy link
Collaborator

TimJentzsch commented Jan 24, 2025

Add a command like bevy watch which runs your Bevy app and will restart it whenever you make changes to the code.
The goal here is to speed up the iterative development.

Note that changes to assets should not cause the app to be restarted, as we can use hot reloading there instead. This is the preferred solution, as it's faster and loses less state.
Hot reloading for code is however not (easily) possible at the moment, so we need to restart the app instead.

For the web, we probably need a separate sub-command like bevy watch web.
We need to ensure that not only the code is recompiled to Wasm, but also bundled again and then the web server restarted.
Finally, the browser should refresh the page, which is the equivalent of restarting the app.
#234 is a per-requisite here.

Implementation

As this is quite the complex topic, we should investigate if we can re-use or wrap a third-party solution here.
A popular tool is bacon, which offers a lot of configuration options and might be tailored to our needs.

Interesting for us:

@TimJentzsch TimJentzsch added A-Run Related to the bevy run command A-Web Building or running Bevy apps targeting the browser C-Feature Make something new possible D-Complex Quite challenging from either a design or technical perspective. Ask for help! S-Needs-Design This issue requires design work to think about how it would best be accomplished labels Jan 24, 2025
@TimJentzsch
Copy link
Collaborator Author

Started a simple test repository to play around with it.

Current observations:

  • The general functionality seems to work already.
  • With bevy run, the app doesn't get killed correctly. You get a new app instance for every change.
  • With bevy run web, the browser tab doesn't get refreshed on changes (see In dev mode, refresh the page when the server starts #234).
  • As expected, the output shown in bacon is incomplete, probably because it can't parse the messages we send.

TimJentzsch added a commit that referenced this issue Feb 3, 2025
# Objective

Closes #234.

If you terminate `cargo run` and then run it again, your old application
will have closed and a new one with the newest state opens.

With `bevy run web`, if you terminate the command, only the dev server
terminates, the application will keep running.
If you re-run the command, the tab in the browser will still contain
your old code.

Instead, we want the page to refresh to ensure that the page is
up-to-date.

# Solution

The solution here is adopted from (an old version of) Trunk's auto
reloading, see <trunk-rs/trunk#231>.

The basic idea is that we inject a script into the `index.html` to open
a websocket to the dev server.
When the websocket connection closes (i.e., the server has been shut
down), we periodically try to reconnect again and trigger a reload when
that happens.

Actually, before trying to connect the websocket, we first send a `PING`
request to the same URL. This prevents us spamming the console with
errors due to the websocket connection failing, I couldn't find a good
way to suppress them.

Note that the autoreload script is currently just injected when not in
bundling mode and if the user didn't specify a custom `index.html`.
This is because we really only want to inject this in the dev version,
not in any deployed version.
I plan to lift this limitation in a future PR, but it will require a bit
of restructuring and I didn't want to blow this up more than necessary.

# Testing

With the Bevy CLI installed from this branch:

1. On any Bevy project, use `bevy run web --open`.
2. Wait for the build to complete and the app to load in the browser.
3. (If you want, perform small changes to the code).
4. Shut down the server by terminating the command.
5. Run `bevy run web`.
6. Once the build has completed, the browser tab with your app should
automatically refresh!

# Future Work

- Expand auto reload support to bundled mode and for custom
`index.html`.
- Having a websocket connection between the client and server means that
we are able to send messages from the server to the client (once I
figure out how exactly to do that). This opens up a vast array of
possibilities. With the `reload` message that's already supported with
the current client implementation, we could implement a `bevy watch`
(#245). We could also add cold and eventually hot reloading on asset
changes (#189). We could also display build errors directly in the
browser window, which I believe the current Trunk version is doing.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Run Related to the bevy run command A-Web Building or running Bevy apps targeting the browser C-Feature Make something new possible D-Complex Quite challenging from either a design or technical perspective. Ask for help! S-Needs-Design This issue requires design work to think about how it would best be accomplished
Projects
None yet
Development

No branches or pull requests

1 participant