Bringing Bevy's Design Philosophy to Desktop Apps: Building a Deterministic Logic Engine for Electron/Vue #23493
Ailrid
started this conversation in
Show and tell
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
Hi everyone,
I’m a huge fan of Bevy’s design philosophy and I’ve been deeply involved in the community, currently writing comprehensive documentation/guides for Bevy.
As a web developer building complex desktop applications with Electron, I’ve often felt frustrated by the "spaghetti state" and the mental overhead caused by Vue's reactive system and Electron's IPC management. To solve this, I’ve been developing Virid — a logic engine that introduces Bevy's ECS and deterministic scheduling concepts into the TypeScript/Desktop ecosystem.
🌟 Core Architectural Shifts:
From Reactive to Deterministic (The Tick System):
I’ve moved away from Vue’s ref/watch for core business logic. Instead, Virid employs a Double-Buffered Message Pool and a Logic Tick mechanism. All state changes are dispatched as Messages and processed within the next microtask cycle, ensuring a predictable execution order similar to Bevy's Schedule.
"Deep Shield" - Emulating Rust's Immutability in TS:
In @virid/vue, I implemented a recursive Proxy-based interceptor. This is more than just a "readonly" hint; it’s a Physical Shield that blocks all unauthorized mutations and method calls (e.g., Array.push) for non-owned components, throwing detailed stack traces for illegal writes. This mimics Rust’s ownership and borrowing constraints at runtime.
IPC Location Transparency:
Inspired by distributed systems and Bevy’s messaging, I abstracted Electron’s IPC into a unified message stream. Whether a System is running on the Main process, a Renderer, or a Worker, the Controller remains agnostic. It simply emits a message, and the dispatcher handles the routing.
Zero-Intrusion Undo/Redo:
By treating the entire app state as a collection of versioned Components, I’ve implemented a linear versioning model. This allows for application-wide Undo/Redo functionality without the need to write any business-specific rollback logic.
💬 Why I'm posting this:
My next milestone is to rewrite the entire core in Rust to serve as a truly "Headless" cross-platform logic framework (potentially targeting Tauri).
I’d love to get some "reality checks" from the experts here:
Does the overhead of a Tick-based system in a non-gaming UI environment sound like overkill, or is the predictability worth the trade-off?
Has anyone else attempted to implement a more "Rust-idiomatic" ECS structure within the constraints of the JS event loop?
Repo/Docs: https://github.com/Ailrid/virid
Beta Was this translation helpful? Give feedback.
All reactions