Stream: show and tell

Topic: roc-bevies


view this post on Zulip jan kili (Feb 01 2022 at 08:18):

I don't know if this counts as "the first Roc game", since all Roc is doing is adjusting the speed of the ball+paddle... but it works great!
https://github.com/JanCVanB/roc-bevies

breakout gameplay

view this post on Zulip Folkert de Vries (Feb 01 2022 at 08:21):

oh very cool!

view this post on Zulip Folkert de Vries (Feb 01 2022 at 08:21):

the platform should be able to accept an u16, I can check why that did not work later today

view this post on Zulip jan kili (Feb 01 2022 at 08:23):

Thanks! This is my first original (not entirely copy-pasted) Rust code, so it's likely that I misunderstood roc_std's (and Bevy's) constraints.

view this post on Zulip Folkert de Vries (Feb 01 2022 at 21:48):

so bevy does not work for me currently (linker problems), but looking at the LLVM IR I don't see why having the roc code (ultimately speedForHost) return an I16. What was the problem you ran into?

view this post on Zulip jan kili (Feb 01 2022 at 22:15):

I was simply hacking naively until something worked, so this could all be incorrect: The equation it plugs into seems to expect an f32, and Rust told me that it couldn't autocast an i128 to an f32. Instead, it suggested that it could do so for an i16, so I went with that.

view this post on Zulip Folkert de Vries (Feb 01 2022 at 22:18):

are there downsides to roc just giving you an f32?

view this post on Zulip jan kili (Feb 01 2022 at 22:28):

No, that would be great! I was working under the assumption that the only types I could pass between Roc & Rust were the pub RocFoo things in roc_std/, so basically RocStr, RocDec, and RocResult.

view this post on Zulip Folkert de Vries (Feb 01 2022 at 22:28):

oh, no

view this post on Zulip Folkert de Vries (Feb 01 2022 at 22:28):

all the primitive types also work

view this post on Zulip Folkert de Vries (Feb 01 2022 at 22:28):

so ints and floats

view this post on Zulip jan kili (Feb 01 2022 at 22:28):

🤯

view this post on Zulip Folkert de Vries (Feb 01 2022 at 22:29):

these map 1 to 1 (except Nat becomes usize)

view this post on Zulip jan kili (Feb 01 2022 at 22:29):

Well that's wonderful.

view this post on Zulip Folkert de Vries (Feb 01 2022 at 22:29):

and as I said elsewhere records/structs also work in a predictable but not always intuitive way

view this post on Zulip jan kili (Feb 01 2022 at 22:29):

I think I skimmed the examples and only found RocStr used.

view this post on Zulip Folkert de Vries (Feb 01 2022 at 22:30):

so far sending integers was boring

view this post on Zulip jan kili (Feb 01 2022 at 22:31):

Me: "Passing ints & floats must be hard, somehow. Dec it is!"

view this post on Zulip Folkert de Vries (Feb 01 2022 at 22:33):

we just happen to agree on what the bits mean for number types

view this post on Zulip Folkert de Vries (Feb 01 2022 at 22:33):

for strings for instance that is not true, because we have the small string optimization

view this post on Zulip jan kili (Feb 01 2022 at 22:35):

Therefore, my next steps for roc-bevies is to (a) simplify int passing and (b) expanding breakout to populate most constant values & primitive formulae with Int/Float/Str/function fields of a big Roc configuration record

view this post on Zulip jan kili (Feb 01 2022 at 22:37):

I love the idea of Rust/Bevy handling all the heavy rendering logic, then asking its boss Roc "hey, what sprite should I use here, and how many points does the player get for this?"

view this post on Zulip Folkert de Vries (Feb 01 2022 at 22:43):

yes! I think it gets really interesting if the roc app stores some state

view this post on Zulip jan kili (Feb 01 2022 at 22:45):

How??

view this post on Zulip jan kili (Feb 01 2022 at 22:45):

Monadically?

view this post on Zulip jan kili (Feb 01 2022 at 22:47):

I'd love to hear an example :D

view this post on Zulip Folkert de Vries (Feb 01 2022 at 22:50):

No, I think game logic could live in roc. This may be a bit contrived but

Model : { score : U64 }

Msg : [ ScoredPoint ]

update : Model, Msg -> Model
update = \model, msg ->
    when msg is
        ScoredPoint -> { score: model.score + 1 }


view : Model -> U64
view = .score

view this post on Zulip Folkert de Vries (Feb 01 2022 at 22:50):

you'd also need init = { score: 0 }

view this post on Zulip Folkert de Vries (Feb 01 2022 at 22:51):

then the platform can call init, and then update the model it has every time a game event happens (e.g. score is increased), and "render" the score when needed

view this post on Zulip Folkert de Vries (Feb 01 2022 at 22:52):

does this make sense in practice? I don't really know, but it's possible

view this post on Zulip jan kili (Feb 01 2022 at 23:27):

Yes! This update-state-on-event loop is common in games, and Bevy has a managed hyperscalable version of that pattern in its ECS architecture

view this post on Zulip jan kili (Feb 01 2022 at 23:37):

I suppose that Roc could complement an ECS platform with its own additional state management layer, but I'm not sure why it would

view this post on Zulip jan kili (Feb 01 2022 at 23:39):

If your app doesn't have a fixed timestep, that could be a fun pattern for discrete event simulations :)

view this post on Zulip jan kili (Feb 02 2022 at 03:46):

On second thought, since Bevy claims to be modular, moving state management (data layer, ECS, whatever) into Roc could be quite fun

view this post on Zulip jan kili (Feb 02 2022 at 03:47):

I'm pretty bummed that it looks like Roc can't define Bevy game nouns (entities are defined via Rust struct literals) or verbs (system functions reference entity types), only support them with primitive-passing functions. Is that accurate?

view this post on Zulip Matthias Devlamynck (Feb 02 2022 at 09:11):

I guess you'd need to have your platform code create rust types (macro?) from roc types.

view this post on Zulip Matthias Devlamynck (Feb 02 2022 at 09:13):

Mirroring bevy's systems API to expose it to Roc may prove to be difficult ^^'

view this post on Zulip Folkert de Vries (Feb 02 2022 at 12:12):

actrually @Richard Feldman have you thought about this? I remember we discussed writing database plugins in Roc which would run into the same issues: you'd want the database to understand your specific roc data structure. As far as I know, you can only do that with additional code gen

view this post on Zulip Folkert de Vries (Feb 02 2022 at 12:12):

e.g. for postgress extensions in rust you need to derive a bunch of things

view this post on Zulip Folkert de Vries (Feb 02 2022 at 12:12):

and it generates a ton of C code

view this post on Zulip jan kili (Feb 02 2022 at 12:14):

:nerd::memo:

view this post on Zulip Richard Feldman (Feb 02 2022 at 12:30):

so what we'd talked about awhile ago (a year or so maybe?) was something along these lines:

we hadn't talked about it in the context of Rust macros needing to get involved, but one idea for a particularly fancy way that could potentially work: in your Rust host's build.rs, use :point_up: to generate .rs files from your Roc types, with the (un-annotated) structs and everything, then - still in build.rs - modify those files to add the annotations (e.g. find/replace struct Player { with #[derive(BevyStuff)]\nstruct Player {), and then let the build continue as normal.

view this post on Zulip Richard Feldman (Feb 02 2022 at 12:34):

so assuming all the generator prerequisites were in place (they don't exist yet, of course!) the workflow would be:

of course there's some extra setup work involved to make that generation/substitution happen at the right time, but I don't think that's avoidable in the general case whenever the goal is to sync type definitions between two decoupled programming languages :big_smile:

view this post on Zulip Folkert de Vries (Feb 02 2022 at 12:36):

Right, the challenge is then to make the whole rust/c/zig codegen bit hidden from the Roc user

view this post on Zulip Folkert de Vries (Feb 02 2022 at 12:37):

for https://github.com/zombodb/pgx they do this with a custom cargo command

view this post on Zulip jan kili (Feb 02 2022 at 12:37):

@Richard Feldman That sounds awesome! I had no idea Roc could get that powerful.

view this post on Zulip jan kili (Feb 02 2022 at 13:22):

That codegen feature addition would enable replacing roc-bevies (dozens of subgenre-specific platforms) with roc-bevy (one general-purpose gamedev platform).

view this post on Zulip Lucas Rosa (Feb 02 2022 at 17:52):

cool stuff!

view this post on Zulip jan kili (Feb 09 2022 at 05:09):

@Folkert de Vries :smiley: https://github.com/JanCVanB/roc-bevies/commit/70fc0e


Last updated: Jul 06 2025 at 12:14 UTC