Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,10 @@ debug = false
incremental = true

[target.x86_64-unknown-linux-gnu]
linker = "clang"
rustflags = ["-Clink-arg=-fuse-ld=lld", "-Ctarget-cpu=native"]
rustflags = ["-Ctarget-cpu=native"]

[target.aarch64-unknown-linux-gnu]
linker = "clang"
rustflags = ["-Clink-arg=-fuse-ld=lld", "-Ctarget-cpu=native"]
rustflags = ["-Ctarget-cpu=native"]

[target.x86_64-pc-windows-msvc]
linker = "rust-lld.exe"
Expand Down
20 changes: 19 additions & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,27 @@ jobs:

- name: Cache dependencies
uses: Swatinem/rust-cache@v2
with:
shared-key: test-suite

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable

- name: Install system dependencies
run: sudo apt-get update && sudo apt-get install --no-install-recommends libasound2-dev libudev-dev libwayland-dev libxkbcommon-dev clang lld

- name: Quick check
run: cargo check --workspace

- name: Run tests
run: cargo test --workspace

- name: Check documentation
run: cargo doc --workspace --no-deps

- name: Check lockfile consistency
run: cargo update --workspace --locked

clippy:
name: Clippy
runs-on: ubuntu-latest
Expand All @@ -50,6 +61,8 @@ jobs:

- name: Cache dependencies
uses: Swatinem/rust-cache@v2
with:
shared-key: clippy-lint

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
Expand All @@ -60,7 +73,7 @@ jobs:
run: sudo apt-get update && sudo apt-get install --no-install-recommends libasound2-dev libudev-dev libwayland-dev libxkbcommon-dev clang lld

- name: Run clippy
run: cargo clippy --workspace -- -A clippy::upper-case-acronyms -A clippy::new-without-default -A clippy::manual-flatten -A clippy::excessive-precision -A clippy::too-many-arguments
run: cargo clippy --workspace -- -A clippy::upper-case-acronyms -A clippy::manual-flatten -A clippy::excessive-precision -A clippy::too-many-arguments

format:
name: Format
Expand All @@ -70,6 +83,11 @@ jobs:
- name: Checkout sources
uses: actions/checkout@v4

- name: Cache dependencies
uses: Swatinem/rust-cache@v2
with:
shared-key: format-check

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
Expand Down
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "LP"
version = "0.1.0"
edition = "2021"
edition = "2024"
description = "A systemic 2D platformer in a dynamic living ecosystem.."
license = "Apache-2.0"

Expand Down Expand Up @@ -30,7 +30,7 @@ forces = { path = "crates/forces" }
information = { path = "crates/information" }
matter = { path = "crates/matter" }

bevy = "0.16"
bevy = { version = "0.16", features = ["dynamic_linking"] }

glam = "0.29.2"

Expand Down
2 changes: 1 addition & 1 deletion crates/energy/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "energy"
version = "0.1.0"
edition = "2021"
edition = "2024"
description = "Core systems governing how energy manifests, transforms and flows."

[dependencies]
Expand Down
40 changes: 31 additions & 9 deletions crates/energy/src/conservation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,18 @@ pub struct EnergyQuantity {
impl EnergyQuantity {
/// Create a new energy quantity
pub fn new(value: f32, energy_type: EnergyType, max_capacity: Option<f32>) -> Self {
debug_assert!(
value >= 0.0,
"Energy cannot be negative (violates conservation)"
);
debug_assert!(
value < 1e20,
"Energy exceeds realistic bounds (nuclear scale ~1e20 J)"
);
if let Some(max) = max_capacity {
debug_assert!(max > 0.0, "Energy capacity must be positive");
}

let clamped_value = max_capacity.map(|max| value.min(max)).unwrap_or(value);

Self {
Expand Down Expand Up @@ -138,26 +150,36 @@ impl EnergyAccountingLedger {
return 0.0;
}

let current_time = self.transactions.first().map(|t| t.timestamp).unwrap_or(0.0);
let current_time = self
.transactions
.first()
.map(|t| t.timestamp)
.unwrap_or(0.0);
let cutoff_time = current_time - time_window;

let recent_transactions: Vec<&EnergyTransaction> = self.transactions
let mut total_rate = 0.0;
let mut count = 0;

for transaction in self
.transactions
.iter()
.take_while(|t| t.timestamp >= cutoff_time)
.collect();

if recent_transactions.is_empty() {
return 0.0;
{
total_rate += transaction.transfer_rate;
count += 1;
}

let total_rate: f32 = recent_transactions.iter().map(|t| t.transfer_rate).sum();
total_rate / recent_transactions.len() as f32
if count == 0 {
0.0
} else {
total_rate / count as f32
}
}

/// Get current energy flux (sum of all active transfer rates)
pub fn current_flux(&self, current_time: f32, active_duration: f32) -> f32 {
let cutoff_time = current_time - active_duration;

self.transactions
.iter()
.filter(|t| t.timestamp >= cutoff_time && t.duration > 0.0)
Expand Down
8 changes: 4 additions & 4 deletions crates/energy/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ pub trait EnergySystem {
destination,
timestamp: 0.0, // Current time should be passed in a real implementation
transfer_rate: 0.0, // Default to instantaneous transfer
duration: 0.0, // Default to instantaneous transfer
duration: 0.0, // Default to instantaneous transfer
}
}

Expand Down Expand Up @@ -113,9 +113,9 @@ pub mod prelude {
pub use super::{EnergySystem, EnergyTransferError};

pub use crate::conservation::{
conversion_efficiency, verify_conservation, EnergyAccountingLedger,
EnergyConservationPlugin, EnergyConservationTracker, EnergyQuantity, EnergyTransaction,
EnergyTransferEvent, EnergyType, TransactionType,
EnergyAccountingLedger, EnergyConservationPlugin, EnergyConservationTracker,
EnergyQuantity, EnergyTransaction, EnergyTransferEvent, EnergyType, TransactionType,
conversion_efficiency, verify_conservation,
};

pub use crate::electromagnetism::prelude::*;
Expand Down
33 changes: 26 additions & 7 deletions crates/energy/src/thermodynamics/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@ pub mod thermal;

use bevy::prelude::*;

#[derive(SystemSet, Debug, Clone, PartialEq, Eq, Hash)]
pub enum ThermodynamicsSet {
/// Calculate thermal transfers and conduction
ThermalTransfer,
/// Update entropy and equilibrium states
Equilibrium,
}

pub struct ThermodynamicsPlugin;

impl Plugin for ThermodynamicsPlugin {
Expand All @@ -16,21 +24,32 @@ impl Plugin for ThermodynamicsPlugin {
.register_type::<equilibrium::ThermalEquilibrium>()
.register_type::<equilibrium::PhaseState>()
.add_event::<thermal::ThermalTransferEvent>()
.add_systems(Update, thermal::calculate_thermal_transfer);
.configure_sets(
Update,
(
ThermodynamicsSet::ThermalTransfer,
ThermodynamicsSet::Equilibrium,
)
.chain(),
)
.add_systems(
Update,
thermal::calculate_thermal_transfer.in_set(ThermodynamicsSet::ThermalTransfer),
);
}
}

pub mod prelude {
pub use super::entropy::{
entropy_change_heat_transfer, entropy_change_irreversible, is_valid_process,
total_entropy_change, Entropy, Reversibility,
Entropy, Reversibility, entropy_change_heat_transfer, entropy_change_irreversible,
is_valid_process, total_entropy_change,
};
pub use super::equilibrium::{
apply_equilibrium_transitivity, equilibrium_time_estimate, find_equilibrium_group,
is_in_equilibrium, validate_equilibrium_group_consistency, PhaseState, ThermalEquilibrium,
ThermalProperties,
PhaseState, ThermalEquilibrium, ThermalProperties, apply_equilibrium_transitivity,
equilibrium_time_estimate, find_equilibrium_group, is_in_equilibrium,
validate_equilibrium_group_consistency,
};
pub use super::thermal::{
thermal_utils::heat_conduction, Temperature, ThermalConductivity, ThermalDiffusivity,
Temperature, ThermalConductivity, ThermalDiffusivity, thermal_utils::heat_conduction,
};
}
12 changes: 10 additions & 2 deletions crates/energy/src/thermodynamics/thermal.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use bevy::prelude::*;

/// Stefan-Boltzmann constant (W/(m²·K⁴))
pub const STEFAN_BOLTZMANN: f32 = 5.67e-8;
// Physical constants
pub const STEFAN_BOLTZMANN: f32 = 5.67e-8; // W/(m²·K⁴)

/// Temperature component for thermal systems
#[derive(Component, Debug, Clone, Copy, Reflect, Default)]
Expand All @@ -12,6 +12,14 @@ pub struct Temperature {

impl Temperature {
pub fn new(kelvin: f32) -> Self {
debug_assert!(
kelvin >= 0.0,
"Temperature below absolute zero violates thermodynamics"
);
debug_assert!(
kelvin < 1e8,
"Temperature exceeds realistic stellar core bounds (~1e8 K)"
);
Self {
value: kelvin.max(0.0),
}
Expand Down
24 changes: 14 additions & 10 deletions crates/energy/src/waves/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,27 +17,31 @@ impl Plugin for WavesPlugin {
.register_type::<superposition::StandingWaveMarker>()
.register_type::<wave_equation::WaveEquationComponent>()
.add_event::<oscillation::WaveGenerationEvent>()
.add_systems(Update, propagation::update_wave_displacements)
.add_systems(Update, superposition::update_standing_waves)
.add_systems(Update, wave_equation::update_wave_equation);
.add_systems(
Update,
(
propagation::update_wave_displacements,
superposition::update_standing_waves,
wave_equation::update_wave_equation,
),
);
}
}

/// The waves prelude.
///
/// This includes the most common types for wave systems.
pub mod prelude {
pub use crate::waves::oscillation::{
angular_frequency, damping_from_half_life, wave_number, WaveParameters,
WaveParameters, angular_frequency, damping_from_half_life, wave_number,
};
pub use crate::waves::propagation::{
create_linear_wave, solve_radial_wave, solve_wave, update_wave_displacements,
WaveCenterMarker, WavePosition, WaveType,
WaveCenterMarker, WavePosition, WaveType, create_linear_wave, solve_radial_wave,
solve_wave, update_wave_displacements,
};
pub use crate::waves::superposition::{
create_standing_wave_parameters, solve_standing_wave, update_standing_waves, StandingWaveMarker,
StandingWaveMarker, create_standing_wave_parameters, solve_standing_wave,
update_standing_waves,
};
pub use crate::waves::wave_equation::{
update_wave_equation, WaveEquation2D, WaveEquationComponent,
WaveEquation2D, WaveEquationComponent, update_wave_equation,
};
}
2 changes: 1 addition & 1 deletion crates/energy/src/waves/propagation.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::oscillation::{angular_frequency, wave_number, WaveParameters};
use super::oscillation::{WaveParameters, angular_frequency, wave_number};
use bevy::prelude::*;

// Calculate modified angular frequency with dispersion
Expand Down
2 changes: 1 addition & 1 deletion crates/energy/src/waves/superposition.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::oscillation::{angular_frequency, wave_number, WaveParameters};
use super::oscillation::{WaveParameters, angular_frequency, wave_number};
use super::propagation::WavePosition;
use bevy::prelude::*;

Expand Down
2 changes: 1 addition & 1 deletion crates/forces/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "forces"
version = "0.1.0"
edition = "2021"
edition = "2024"
description = "Fundamental interaction mechanisms that create relationships between entities and drive dynamic behaviors across scales."

[dependencies]
Expand Down
22 changes: 13 additions & 9 deletions crates/forces/src/core/gravity.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use super::newton_laws::{AppliedForce, Mass};
use bevy::prelude::*;

/// Modified gravitational constant for simulation scale
// Simulation constants
pub const GRAVITATIONAL_CONSTANT: f32 = 0.1;

/// Resource for gravity simulation parameters
Expand Down Expand Up @@ -47,10 +47,11 @@ pub struct GravitySource;
#[derive(Component, Debug, Clone, Copy, Reflect)]
pub struct MassiveBody;

// Spatial partitioning structures for Barnes-Hut algorithm
// Barnes-Hut spatial partitioning
mod spatial {
use bevy::prelude::*;

// Algorithm parameters
const MAX_DEPTH: usize = 8;
const MAX_BODIES_PER_NODE: usize = 8;

Expand Down Expand Up @@ -95,13 +96,19 @@ mod spatial {
pub center_of_mass: Vec3,
}

impl MassProperties {
pub fn new() -> Self {
impl Default for MassProperties {
fn default() -> Self {
Self {
total_mass: 0.0,
center_of_mass: Vec3::ZERO,
}
}
}

impl MassProperties {
pub fn new() -> Self {
Self::default()
}

pub fn add_body(&mut self, position: Vec3, mass: f32) {
let new_total_mass = self.total_mass + mass;
Expand Down Expand Up @@ -365,11 +372,8 @@ pub fn calculate_barnes_hut_force(
}

let mut total_force = Vec3::ZERO;
for child in &node.children {
if let Some(child_node) = child {
total_force +=
calculate_barnes_hut_force(affected_position, child_node, theta, softening);
}
for child_node in node.children.iter().flatten() {
total_force += calculate_barnes_hut_force(affected_position, child_node, theta, softening);
}

total_force
Expand Down
Loading
Loading