bevy inspired ergonomics for ark #445
Replies: 11 comments
-
|
Hi @schphe, I need to take the time for a deeper look later, but it is definitely cool to see that it was possible for you to build this kind of convenience wrapper around Ark. Just a few questions/comments:
I would also be interested in which limitations or difficulties you hit when building this, regarding Ark's API. Or was everything you needed there and convenient? As a final, small point: it would be nice for readers as well as for Ark if you could make it's name a link in you README intro. |
Beta Was this translation helpful? Give feedback.
-
|
Hi @mlange-42 ^^ 1.yeah it's independent, as the current event system doesn't support emitting events with structs (for extra event data) and there wasn't any mechanism to send optional cancels for some events which i needed as seen in the example //bevi:system Update
func DenyBlockBreak(
r bevi.EventReader[dragonfly.PlayerBlockBreak],
) {
for ev := range r.Iter() {
ev.Player.Message("You can't break blocks here.")
r.Cancel()
}
}i've been planning to pass observer events into the current event system optionally with some generator magic if requested by the system function signatures, but i'll see what can i do 2.yup you can absolutely do that type A struct{ ... }
type B struct{ ... }
type C struct{ ... }
//bevi:system Update
//bevi:filter q1 !exclusive
//bevi:filter q2 !exclusive
func Test(
q1 *ecs.Query2[A, B], // write intent via a pointer
q2 ecs.Query2[B, C],
) {
for q1.Next() {
// some r+w operation
}
for q2.Next() {
// some r operation
}
}3.could you explain this a bit further? currently the read/write access is specified like this in the generated system glue by the info collected from system definitions acc := bevi.NewAccess()
bevi.AccessEventWrite[BonusEvent](&acc)
bevi.AccessEventWrite[CancelEvent](&acc)
bevi.AccessWrite[Test](&acc)
meta := bevi.SystemMeta{Access: acc, Set: "", Before: nil, After: []string{"Tick"}, Every: 1000000000 * time.Nanosecond}
app.AddSystem(bevi.Update, "IncreaseMoney", meta, func(ctx context.Context, w *ecs.World) {
_q0 := _flt_4.Query()
IncreaseMoney(ctx, _ew_2, _ew_3, &_q0)
_q0.Close()
})as seen, with the event and component types (+ resource, not shown here) for the difficulties/limitations part i guess limitations for me was mostly the event system but i think i like ark's being a non-opinionated library providing core ecs functionality which you can use with the "tools/extensions" arbitrarily to have more stuff if needed (other than that everything i needed was there and convenient, great library!) difficulties, it was definitely planning and figuring out the codegen i may say i've updated the readme for the link! |
Beta Was this translation helpful? Give feedback.
-
|
Regarding access and parallelization, in the docs it looked like you specify write access per query (by using a pointer). So you may have queries/systems that need write access, but to different components, like:
So it would be possible to run these queries in parallel. With how I understand from the docs, this would not be detected. In the generated code you shared above however, it seems te be granular on components. Just not sure how the user could specify this. |
Beta Was this translation helpful? Give feedback.
-
|
maybe i should improve readme a bit and add more examples : package main
import "github.com/mlange-42/ark/ecs"
type A struct { /* ... */ }
type B struct { /* ... */ }
type C struct { /* ... */ }
type D struct { /* ... */ }
//bevi:system Update Reads={A,B}
//bevi:filter q1 !exclusive
//bevi:filter q2 !exclusive
func Test(
q1 *ecs.Query3[A, B, C],
q2 *ecs.Query3[A, B, D],
) {
// Query 1: Read A and B, write C
for q1.Next() {
a, b, c := q1.Get()
_ = a
_ = b // reads
// write to C
// c.Field = ...
_ = c
}
// Query 2: Read A and B, write D
for q2.Next() {
a, b, d := q2.Get()
_ = a
_ = b // reads
// write to D
// d.Field = ...
_ = d
}
}which will generate // Code generated by bevi gen; DO NOT EDIT.
// Generated at 2025-11-03T05:38:20-06:00
package main
import (
"context"
"github.com/mlange-42/ark/ecs"
"github.com/oriumgames/bevi"
)
func Systems(app *bevi.App) {
_flt_0 := ecs.NewFilter3[A, B, C](app.World())
_flt_0 = _flt_0.Exclusive()
_flt_1 := ecs.NewFilter3[A, B, D](app.World())
_flt_1 = _flt_1.Exclusive()
// System: Test (from main.go)
{
acc := bevi.NewAccess()
bevi.AccessRead[A](&acc)
bevi.AccessRead[B](&acc)
bevi.AccessWrite[C](&acc)
bevi.AccessWrite[D](&acc)
meta := bevi.SystemMeta{Access: acc, Set: "", Before: nil, After: nil}
app.AddSystem(bevi.Update, "Test", meta, func(ctx context.Context, w *ecs.World) {
_q0 := _flt_0.Query()
_q1 := _flt_1.Query()
Test(&_q0, &_q1)
_q0.Close()
_q1.Close()
})
}
} |
Beta Was this translation helpful? Give feedback.
-
|
Are you sure it is correct to close the queries manually? If they are fully iterated, this should panic I think. The parallelism/write access stuff only makes sense for separate systems I guess? I understood it the way that systems are executed in parallel if possible. |
Beta Was this translation helpful? Give feedback.
-
|
i've been closing queries just in case if systems are not iterating them fully and yeah that's right, scheduler only runs the systems in parallel if possible |
Beta Was this translation helpful? Give feedback.
-
|
🤔 This should actuall panic with "unbalanced unlock. Did you close a query that was already iterated?". Are you sure you have a proper test for it in place? |
Beta Was this translation helpful? Give feedback.
-
|
ah... my bad, i forgot i was doing this and diagnostics were not on when i was testing it does panic : |
Beta Was this translation helpful? Give feedback.
-
|
You should be aware that Ark is not designed to recover from panics. A panic is a sign of wrong usage, and recovering may leave the world in an unhealthy state. Probably not for this one, but I would recommend to not close the query and to leave that for users if they break out of the iteration. If they forget it, it will show up after a while as the world runs out of lock bits. |
Beta Was this translation helpful? Give feedback.
-
|
i've made changes to properly panic after reporting diagnostics and removed auto close placement from generator also added a section called query lifetime to the readme |
Beta Was this translation helpful? Give feedback.
-
|
hi @mlange-42, right now as there's no way to determine if a query is closed without panicking, would you consider adding a method like this? ( #456 ) |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
i've just released bevi,
an extension library for ark that adds some bevy-inspired ergonomics
https://github.com/oriumgames/bevi
i originally wrote this for my minecraft server project,
but decided to separate it into its own library in case others might find it useful
i'd really appreciate any feedback or suggestions for improvement
Beta Was this translation helpful? Give feedback.
All reactions