Coded up some special functions, (sin,cos, and J0 bessel for now) using Chebyshev series. I am hoping to code up a small scientific library to help me replicate some papers in my field of study and wanted to do so from scratch. Figure of the J0 cylindrical Bessel function made in https://github.com/lukewilliamboswell/roc-ray. Forgive my terrible graphics. I am still learning that side. My code (still very much a work in progress): https://codeberg.org/tdanieljr/roc-drg
![]()
One of the goals I had for roc-ray was the wrap raylib with an API where it was impossible to do things that shouldn't be done. I think this was more progressed in the first version... I feel like I should do a pass over the current API and see if I can improve it -- just to try out the ergonomics of different things.
Looking at your example here Timothy made me think of this again. I noticed the Draw.begin_frame and Draw.end_frame - if an app author forgets to do this (because they are unfamiliar with the underlying raylib) then it may be surprising or not work correctly.
For example you might change that example to something like...
Draw.render_frame!(|frame|{
frame.clear!(Color.ray_white)
frame.draw_text!({
pos: { x: 30, y: 10 },
text: "J0 Bessel Function",
size: 30,
spacing: Draw.default_spacing,
color: Color.dark_gray,
font: Draw.default_font,
align: Draw.align_top_left,
})
for y in ys {
var h = screen_height - screen_height * (y?.to_f32_wrap() + 1)/2
frame.draw_circle!({
center: { x:screen_width*xi/nx, y: h},
radius: 7,
style: Draw.filled_and_outlined(Color.blue, Color.black, 2),
})
xi = xi + 1
}
})
Here we've moved the draw commands onto the frame handle so you can't accidentally try to draw without having a valid handle.
Interested to know what people think or if they have any other ideas
I think it is much clearer than the current Draw.draw!(|bg_color, callback| {})
https://github.com/lukewilliamboswell/roc-ray/blob/main/platform/Draw.roc#L693
I would even suggest Draw.frame!(|frame| {}).
Would the functions still be available as standalone Draw.draw_text!() or only as methods on the Frame type ? The later option would truly force the pattern. I am not experience enough with raylib to know if it would block any use case though.
Honestly I landed on doing it the way I did because I just grabbed the Draw.draw! from your hello_world example, fought with the callback signature for a minute, and then just grepped for the definition so I could grab the surrounding context.
I don't know the best way but something that could draw to the frame with the appropriate context and handle operations that might error would make what I tried to do smoother. But that could have been a skill issue.
The one other thing I couldn't immediately figure out was how I could pre-calculate the Bessel function once. My understanding right now is I calculate it every frame and re-render. In C I would do this before the while !WindowShouldClose loop since it is a constant. This has more to do with me not having spent time figuring out what is actually happening in the larger platform code (what is running where, entry points etc.), but was something I tried to do and then just set the FPS to 1 and ignored.
I might mess with animations eventually but, to start, I usually draw a static frame to check my work. Drawing the Bessel function exposed a bug in my sin/cos implementation where I forgot to unwind the argument and it went exponential for x > ~2pi.
As for the API, I like raylib because it is so simple and straight forward to get started. So something that pushes that, I would be in favor of. I really value the "time to first plot" when it comes to just drawing something on the screen, both from a boiler plate code and a runtime perspective.
Last updated: Jul 23 2026 at 13:15 UTC