Integrating Seed App with ECS

I’m planning to use Seed for the first time in making a simple turn-based card game. I am anticipating a structure something like:

-client (Seed)
  \-model
        \-ECS (Shipyard)
-server (Warp)

Does anyone have experience with integrating an ECS framework within a Seed app? Does this make any sense or am I tragically misguided?

I’ve ported Shipyard’s demo to Seed example bunnies (PR).

If you want to try it, just clone the current Seed master branch and from the root run cargo make start bunnies and open http://localhost:8000/.

I didn’t encounter any problems during porting. I was able to remove a lot of low-level code thanks to using Seed’s animation loop and declarative HTML + event handlers.


I assume you will need WebSockets for communication with Warp - it’s already possible through web_sys (there is an example in the Seed repo) and I’m also writing a wrapper with better API.


Let me know when you have some questions or something doesn’t work.
Cheers, M.

1 Like

Wow. That is a much more extensive answer than I was expecting. Thank you so much for putting in that effort. It will probably take me a while due to life in the next couple of weeks, but I think I can manage it based on the examples you’ve provided. So kind of you to donate your time like that. Cheers.

When I run the bunnies example I just gut a blank screen with a blue box in the upper left with

bunnies: 0
fps:0

The terminal output is:

MicroServer running on port 8000!
Serving .
Spa support: true. Root: index.html
A((File { resp: Response { status: 304, version: HTTP/1.1, headers: {}, body: Body(Empty) } },))
A((File { resp: Response { status: 304, version: HTTP/1.1, headers: {}, body: Body(Empty) } },))
A((File { resp: Response { status: 304, version: HTTP/1.1, headers: {}, body: Body(Empty) } },))
A((File { resp: Response { status: 200, version: HTTP/1.1, headers: {"content-length": "77180", "content-type": "application/javascript", "accept-ranges": "bytes", "last-modified": "Wed, 29 Apr 2020 14:02:29 GMT"}, body: Body(Streaming) } },))
A((File { resp: Response { status: 200, version: HTTP/1.1, headers: {"content-length": "4855009", "content-type": "application/wasm", "accept-ranges": "bytes", "last-modified": "Wed, 29 Apr 2020 14:02:29 GMT"}, body: Body(Streaming) } },))
A((File { resp: Response { status: 200, version: HTTP/1.1, headers: {"content-length": "309", "content-type": "image/png", "accept-ranges": "bytes", "last-modified": "Wed, 29 Apr 2020 02:03:56 GMT"}, body: Body(Streaming) } },))
A((File { resp: Response { status: 200, version: HTTP/1.1, headers: {"content-length": "456", "content-type": "application/octet-stream", "accept-ranges": "bytes", "last-modified": "Wed, 29 Apr 2020 02:03:56 GMT"}, body: Body(Streaming) } },))
A((File { resp: Response { status: 200, version: HTTP/1.1, headers: {"content-length": "139", "content-type": "application/octet-stream", "accept-ranges": "bytes", "last-modified": "Wed, 29 Apr 2020 02:03:56 GMT"}, body: Body(Streaming) } },))
A((File { resp: Response { status: 304, version: HTTP/1.1, headers: {}, body: Body(Empty) } },))
A((File { resp: Response { status: 304, version: HTTP/1.1, headers: {}, body: Body(Empty) } },))
B((File { resp: Response { status: 200, version: HTTP/1.1, headers: {"content-length": "835", "content-type": "text/html", "accept-ranges": "bytes", "last-modified": "Wed, 29 Apr 2020 02:03:56 GMT"}, body: Body(Streaming) } },))

I had assumed the bunny sprite would show up somewhere. What have I done wrong?

  • If you see blank screen and a blue box, it means that Seed and resources (e.g. sprite) have been loaded.
  • fps: 0 is the default value so it looks like the game loop hasn’t been started.

  • Look at the browser dev console if there aren’t any errors - you should see only:
"resources loaded"
"canvas ready"
"world created"
"starting game loop..."
  • Also try to click on the screen - if you see jumping bunnies, than only fps meter is broken.
  • And try more browsers - maybe a combination of OS / browser / WebGL drivers causes problems.
  • If nothing works, write me on the Seed chat, please.
1 Like

Seems to be a firefox issue. Works on vivaldi/chromium.
Error from console in firefox:

Failed to create WebGL context: WebGL creation failed: * tryNativeGL * Exhausted GL driver options. package.js:859:43

panicked at ‘get_webgl_context_1: couldn’t create webgl context’, examples/bunnies/src/lib.rs:173:14 Stack: init/imports.wbg.__wbg_new_59cb74e423758ede@http://127.0.0.1:8000/pkg/package.js:388:23 console_error_panic_hook::Error::new::h17005c5aa27070db@http://127.0.0.1:8000/pkg/package_bg.wasm:wasm-function[13007]:0x325916 console_error_panic_hook::hook_impl::hc6cea91100e26cfe@http://127.0.0.1:8000/pkg/package_bg.wasm:wasm-function[1785]:0x1ac651 console_error_panic_hook::hook::h39a61d1714d397a4@http://127.0.0.1:8000/pkg/package_bg.wasm:wasm-function[14553]:0x33aba8 core::ops::function::Fn::call::hb473dc9f1e22c7f2@http://127.0.0.1:8000/pkg/package_bg.wasm:wasm-function[11635]:0x3106bf std::panicking::rust_panic_with_hook::h8b4e827c0775e148@http://127.0.0.1:8000/pkg/package_bg.wasm:wasm-function[3792]:0x239087 rust_begin_unwind@http://127.0.0.1:8000/pkg/package_bg.wasm:wasm-function[13145]:0x327a30 core::panicking::panic_fmt::h8f7175d910f1c839@http://127.0.0.1:8000/pkg/package_bg.wasm:wasm-function[15205]:0x342d66 core::option::expect_none_failed::h7c6b313bb926df39@http://127.0.0.1:8000/pkg/package_bg.wasm:wasm-function[6251]:0x29abcb core::result::Result<T,E>::expect::he3b4c6013c706299@http://127.0.0.1:8000/pkg/package_bg.wasm:wasm-function[3240]:0x219a6a bunnies::create_world::h193cd0a0d8737e6a@http://127.0.0.1:8000/pkg/package_bg.wasm:wasm-function[524]:0xea75f bunnies::update::hec6988197b9aa5ec@http://127.0.0.1:8000/pkg/package_bg.wasm:wasm-function[246]:0x4a55d seed::app::App<Ms,Mdl,INodes,GMs>::process_queue_message::h9171d962a3a86b4f@http://127.0.0.1:8000/pkg/package_bg.wasm:wasm-function[626]:0x106f9d seed::app::App<Ms,Mdl,INodes,GMs>::process_effect_queue::h791f0c6dace58c67@http://127.0.0.1:8000/pkg/package_bg.wasm:wasm-function[552]:0xf2e81 seed::app::App<Ms,Mdl,INodes,GMs>::rerender_vdom::h58795b6d6c693bc2@http://127.0.0.1:8000/pkg/package_bg.wasm:wasm-function[290]:0x7b7df seed::app::App<Ms,Mdl,INodes,GMs>::schedule_render::{{closure}}::hac07eeccc48e0d44@http://127.0.0.1:8000/pkg/package_bg.wasm:wasm-function[3041]:0x20d697 <dyn core::ops::function::FnMut<(A,)>+Output = R as wasm_bindgen::closure::WasmClosure>::describe::invoke::h819fac2363ad6a64@http://127.0.0.1:8000/pkg/package_bg.wasm:wasm-function[3755]:0x2370cc __wbg_adapter_29@http://127.0.0.1:8000/pkg/package.js:243:10 real@http://127.0.0.1:8000/pkg/package.js:213:20

And this one:

panicked at ‘already borrowed: BorrowMutError’, /rustc/4fb7144ed159f94491249e86d5bbd033b5d60550/src/libcore/cell.rs:878:9

Stack:

init/imports.wbg.__wbg_new_59cb74e423758ede@http://127.0.0.1:8000/pkg/package.js:388:23
console_error_panic_hook::Error::new::h17005c5aa27070db@http://127.0.0.1:8000/pkg/package_bg.wasm:wasm-function[13007]:0x325916
console_error_panic_hook::hook_impl::hc6cea91100e26cfe@http://127.0.0.1:8000/pkg/package_bg.wasm:wasm-function[1785]:0x1ac651
console_error_panic_hook::hook::h39a61d1714d397a4@http://127.0.0.1:8000/pkg/package_bg.wasm:wasm-function[14553]:0x33aba8
core::ops::function::Fn::call::hb473dc9f1e22c7f2@http://127.0.0.1:8000/pkg/package_bg.wasm:wasm-function[11635]:0x3106bf
std::panicking::rust_panic_with_hook::h8b4e827c0775e148@http://127.0.0.1:8000/pkg/package_bg.wasm:wasm-function[3792]:0x239087
rust_begin_unwind@http://127.0.0.1:8000/pkg/package_bg.wasm:wasm-function[13145]:0x327a30
core::panicking::panic_fmt::h8f7175d910f1c839@http://127.0.0.1:8000/pkg/package_bg.wasm:wasm-function[15205]:0x342d66
core::option::expect_none_failed::h7c6b313bb926df39@http://127.0.0.1:8000/pkg/package_bg.wasm:wasm-function[6251]:0x29abcb
core::result::Result<T,E>::expect::hbe7106cfd017446b@http://127.0.0.1:8000/pkg/package_bg.wasm:wasm-function[4734]:0x265533
core::cell::RefCell::borrow_mut::h27508931a279e3df@http://127.0.0.1:8000/pkg/package_bg.wasm:wasm-function[5221]:0x278798
seed::app::App<Ms,Mdl,INodes,GMs>::process_queue_message::h9171d962a3a86b4f@http://127.0.0.1:8000/pkg/package_bg.wasm:wasm-function[626]:0x106f12
seed::app::App<Ms,Mdl,INodes,GMs>::process_effect_queue::h791f0c6dace58c67@http://127.0.0.1:8000/pkg/package_bg.wasm:wasm-function[552]:0xf2e81
seed::app::App<Ms,Mdl,INodes,GMs>::update::h1d645ee4098df030@http://127.0.0.1:8000/pkg/package_bg.wasm:wasm-function[2074]:0x1c6e7c
seed::app::App<Ms,Mdl,INodes,GMs>::mailbox::{{closure}}::hbd06e485ff82989c@http://127.0.0.1:8000/pkg/package_bg.wasm:wasm-function[910]:0x13e63a
seed::virtual_dom::mailbox::Mailbox::send::hf98a6bc8a4e85c13@http://127.0.0.1:8000/pkg/package_bg.wasm:wasm-function[1381]:0x18154b
seed::virtual_dom::event_handler_manager::listener::Listener::new::{{closure}}::h28e07b00c5f62f88@http://127.0.0.1:8000/pkg/package_bg.wasm:wasm-function[655]:0x10de21
<dyn core::ops::function::FnMut<(A,)>+Output = R as wasm_bindgen::closure::WasmClosure>::describe::invoke::h76267b04bc6cad21@http://127.0.0.1:8000/pkg/package_bg.wasm:wasm-function[3754]:0x236fe2
__wbg_adapter_35@http://127.0.0.1:8000/pkg/package.js:255:10
real@http://127.0.0.1:8000/pkg/package.js:213:20

I found many Linux & Firefox related issues with WebGL, so it’s very possible.

It’s just a side-effect of dying Seed. It often follows panic with the real error. I didn’t have a reason to make it more expressive (if possible).