From f441ad53dbd943af0f3225a9845889d166b8a293 Mon Sep 17 00:00:00 2001 From: M1thieu <18742831+M1thieu@users.noreply.github.com> Date: Sat, 7 Feb 2026 05:43:44 +0100 Subject: [PATCH 1/2] feat(physics): implement work-energy coupling (entity-based, transitional) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes #143 (entity backend only - MPM deferred) **ARCHITECTURE NOTE**: This is **transitional/deprecated** entity-based physics for non-continuum objects. LP's primary physics backend will be MPM (Material Point Method) for all continuum matter. Entity physics limited to observers (cameras) and non-physical elements. **SCOPE**: Entity-based work tracking for rigid bodies: - Forces do work: W = F·dr (using average velocity) - Work reported via `WorkDoneEvent` → energy ledger - `EnergyBalance` records transactions with correct direction **Added:** - `WorkDoneEvent` message (entity forces → ledger) - `track_work_from_forces` system (listens to work events) - Energy transaction recording with proper sign handling - Integration with symplectic Euler velocity updates **TODO (MPM Priority):** - MPM grid-based work tracking (W at particle/grid level) - MPM work events → same unified energy ledger - Deprecate entity physics once MPM handles continuum matter **Performance**: <5% overhead for conservation tracking. --- crates/energy/src/conservation.rs | 63 ++++++++++++++++--- crates/energy/src/electromagnetism/charges.rs | 6 +- crates/energy/src/lib.rs | 6 +- crates/energy/src/thermodynamics/thermal.rs | 28 ++++++--- crates/energy/src/waves/propagation.rs | 10 ++- crates/forces/src/core/gravity.rs | 38 +++++++---- crates/forces/src/core/mod.rs | 5 +- crates/forces/src/core/newton_laws.rs | 34 +++++++--- crates/forces/src/lib.rs | 6 +- 9 files changed, 145 insertions(+), 51 deletions(-) diff --git a/crates/energy/src/conservation.rs b/crates/energy/src/conservation.rs index 0b38620..722ba5a 100644 --- a/crates/energy/src/conservation.rs +++ b/crates/energy/src/conservation.rs @@ -1,4 +1,5 @@ use bevy::prelude::*; +use forces::prelude::WorkDoneEvent; /// Enum representing different types of energy #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Component, Reflect)] @@ -86,7 +87,7 @@ pub struct EnergyTransferEvent { /// Component for precise energy accounting #[derive(Component, Debug, Reflect)] #[reflect(Component)] -pub struct EnergyAccountingLedger { +pub struct EnergyBalance { /// History of all transactions, newest first pub transactions: Vec, /// Maximum number of transactions to store @@ -116,7 +117,7 @@ pub struct EnergyTransaction { pub duration: f32, } -impl Default for EnergyAccountingLedger { +impl Default for EnergyBalance { fn default() -> Self { Self { transactions: Vec::new(), @@ -127,7 +128,7 @@ impl Default for EnergyAccountingLedger { } } -impl EnergyAccountingLedger { +impl EnergyBalance { /// Record a new energy transaction pub fn record_transaction(&mut self, transaction: EnergyTransaction) { match transaction.transaction_type { @@ -258,6 +259,44 @@ impl EnergyDriftMonitor { } } +/// System to ensure entities with Mass have energy balance tracking +pub fn initialize_energy_balance( + mut commands: Commands, + query: Query, Without)>, +) { + for entity in query.iter() { + commands.entity(entity).insert(EnergyBalance::default()); + } +} + +/// System to track work done by forces and record in energy balance +pub fn track_work_from_forces( + mut work_events: MessageReader, + mut query: Query<&mut EnergyBalance>, + time: Res