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
38 changes: 38 additions & 0 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
[profile.dev]
split-debuginfo = "unpacked"
opt-level = 1
debug = 1
incremental = true

# Optimize dependencies for faster builds
[profile.dev.package."*"]
opt-level = 3
debug = false

# Bevy-specific optimizations
[profile.dev.package.bevy]
opt-level = 3
debug = false

# Fast dev profile for quick iteration
[profile.dev-fast]
inherits = "dev"
opt-level = 0
debug = false
incremental = true

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

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

[target.x86_64-pc-windows-msvc]
linker = "rust-lld.exe"
rustflags = ["-Ctarget-feature=+crt-static"]

# Build optimizations
[build]
jobs = 8
80 changes: 40 additions & 40 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,74 +6,74 @@ on:
pull_request:
branches: [main]

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

env:
CARGO_TERM_COLOR: always

jobs:
# Run cargo test
test:
name: Test Suite
runs-on: ubuntu-latest
timeout-minutes: 30
timeout-minutes: 25
steps:
- name: Free disk space
run: sudo rm -rf /usr/share/dotnet /opt/ghc /usr/local/lib/android /usr/local/share/boost

- name: Checkout sources
uses: actions/checkout@v4
- name: Cache
uses: actions/cache@v4
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
key: ${{ runner.os }}-cargo-test-${{ hashFiles('**/Cargo.toml') }}
- name: Install stable toolchain

- name: Cache dependencies
uses: Swatinem/rust-cache@v2

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Install Dependencies
run: sudo apt-get update; sudo apt-get install --no-install-recommends libasound2-dev libudev-dev libwayland-dev libxkbcommon-dev
- name: Run cargo test
run: cargo test

- 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: Run tests
run: cargo test --workspace

# Run cargo clippy -- -D warnings
clippy_check:
clippy:
name: Clippy
runs-on: ubuntu-latest
timeout-minutes: 30
timeout-minutes: 25
steps:
- name: Free disk space
run: sudo rm -rf /usr/share/dotnet /opt/ghc /usr/local/lib/android /usr/local/share/boost

- name: Checkout sources
uses: actions/checkout@v4
- name: Cache
uses: actions/cache@v4
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
key: ${{ runner.os }}-cargo-clippy-${{ hashFiles('**/Cargo.toml') }}
- name: Install stable toolchain

- name: Cache dependencies
uses: Swatinem/rust-cache@v2

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
components: clippy
- name: Install Dependencies
run: sudo apt-get update; sudo apt-get install --no-install-recommends libasound2-dev libudev-dev libwayland-dev libxkbcommon-dev

- 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: Run clippy
run: cargo clippy -- -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::new-without-default -A clippy::manual-flatten -A clippy::excessive-precision -A clippy::too-many-arguments

# Run cargo fmt with check flag but allow failures
format:
name: Format
runs-on: ubuntu-latest
timeout-minutes: 30
continue-on-error: true
timeout-minutes: 10
steps:
- name: Checkout sources
uses: actions/checkout@v4
- name: Install stable toolchain

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt
- name: Run cargo fmt
run: cargo fmt --all -- --check || true

- name: Check formatting
run: cargo fmt --all -- --check
37 changes: 34 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,37 @@
# Ignore build artifacts
/target
# Rust build artifacts
/target/
**/target/
Cargo.lock

# Ignore save files
# IDE and editor settings
.vscode/
.idea/
*.swp
*.swo
*~

# OS generated files
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db

# Rust-specific
**/*.rs.bk
*.pdb

# Temporary files
*.tmp
*.temp
*.log

# Environment files
.env
.env.local
.env.*.local

# Application save files
save.json
3 changes: 3 additions & 0 deletions crates/energy/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Energy

Energy conservation, thermodynamics, electromagnetism, and wave mechanics for LP physics simulations.
29 changes: 9 additions & 20 deletions crates/energy/src/conservation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,8 @@ pub struct EnergyQuantity {
impl EnergyQuantity {
/// Create a new energy quantity
pub fn new(value: f32, energy_type: EnergyType, max_capacity: Option<f32>) -> Self {
let clamped_value = max_capacity
.map(|max| value.min(max))
.unwrap_or(value);

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

Self {
value: clamped_value.max(0.0),
energy_type,
Expand All @@ -55,8 +53,8 @@ impl EnergyQuantity {
/// Energy transaction types for conservation accounting
#[derive(Debug, Clone, Copy, PartialEq, Eq, Reflect)]
pub enum TransactionType {
Input, // Energy entering the system
Output, // Energy leaving the system
Input, // Energy entering the system
Output, // Energy leaving the system
}

/// Event for energy transfers between entities
Expand Down Expand Up @@ -118,13 +116,13 @@ impl EnergyAccountingLedger {
TransactionType::Input => self.total_input += transaction.amount,
TransactionType::Output => self.total_output += transaction.amount,
}

self.transactions.insert(0, transaction);
if self.transactions.len() > self.max_history {
self.transactions.pop();
}
}

/// Get the net energy change
pub fn net_energy_change(&self) -> f32 {
self.total_input - self.total_output
Expand All @@ -150,20 +148,13 @@ impl Default for EnergyConservationTracker {
}

/// Utility function to verify energy conservation
pub fn verify_conservation(
initial_energy: f32,
final_energy: f32,
tolerance: f32,
) -> bool {
pub fn verify_conservation(initial_energy: f32, final_energy: f32, tolerance: f32) -> bool {
// First law: Energy cannot be created or destroyed
(final_energy - initial_energy).abs() <= tolerance
}

/// Utility function to calculate conversion efficiency
pub fn conversion_efficiency(
energy_input: f32,
energy_output: f32,
) -> f32 {
pub fn conversion_efficiency(energy_input: f32, energy_output: f32) -> f32 {
if energy_input > 0.0 {
(energy_output / energy_input).clamp(0.0, 1.0)
} else {
Expand All @@ -183,11 +174,9 @@ impl Plugin for EnergyConservationPlugin {
.register_type::<TransactionType>()
.register_type::<EnergyTransaction>()
.register_type::<EnergyAccountingLedger>()

// Add resources
.init_resource::<EnergyConservationTracker>()

// Add event channel
.add_event::<EnergyTransferEvent>();
}
}
}
20 changes: 11 additions & 9 deletions crates/energy/src/electromagnetism/fields.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,10 +124,12 @@ pub fn calculate_field_interactions(
// Electric field interactions
for (source_entity, source_field) in electric_fields.iter() {
for (target_entity, target_field) in electric_fields.iter() {
if source_entity == target_entity { continue; }

if source_entity == target_entity {
continue;
}

let interaction_strength = source_field.strength() * target_field.strength();

if interaction_strength > f32::EPSILON {
field_interaction_events.write(ElectromagneticFieldInteractionEvent {
source: source_entity,
Expand All @@ -141,10 +143,12 @@ pub fn calculate_field_interactions(
// Magnetic field interactions (similar logic)
for (source_entity, source_field) in magnetic_fields.iter() {
for (target_entity, target_field) in magnetic_fields.iter() {
if source_entity == target_entity { continue; }

if source_entity == target_entity {
continue;
}

let interaction_strength = source_field.strength() * target_field.strength();

if interaction_strength > f32::EPSILON {
field_interaction_events.write(ElectromagneticFieldInteractionEvent {
source: source_entity,
Expand All @@ -165,11 +169,9 @@ impl Plugin for ElectromagneticFieldPlugin {
// Register types for reflection
.register_type::<ElectricField>()
.register_type::<MagneticField>()

// Add electromagnetic field interaction event
.add_event::<ElectromagneticFieldInteractionEvent>()

// Add system for field interactions
.add_systems(Update, calculate_field_interactions);
}
}
}
6 changes: 3 additions & 3 deletions crates/energy/src/electromagnetism/interactions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use bevy::prelude::*;
const C: f32 = 299_792_458.0;

/// Represents an electromagnetic wave component
#[derive(Debug, Component)]
#[derive(Debug, Component, Reflect)]
pub struct ElectromagneticWave {
/// Wave frequency in Hertz
pub frequency: f32,
Expand Down Expand Up @@ -74,7 +74,7 @@ impl ElectromagneticWave {
}

/// Material electromagnetic properties component
#[derive(Debug, Clone, Copy, Component)]
#[derive(Debug, Clone, Copy, Component, Reflect)]
pub struct MaterialProperties {
/// Electric permittivity
pub permittivity: f32,
Expand Down Expand Up @@ -118,4 +118,4 @@ impl MaterialProperties {
// v = c/n
C / self.refractive_index()
}
}
}
21 changes: 17 additions & 4 deletions crates/energy/src/electromagnetism/mod.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,25 @@
pub mod fields;
pub mod interactions;

use bevy::prelude::*;

pub struct ElectromagnetismPlugin;

impl Plugin for ElectromagnetismPlugin {
fn build(&self, app: &mut App) {
app.register_type::<fields::ElectricField>()
.register_type::<fields::MagneticField>()
.register_type::<interactions::ElectromagneticWave>()
.register_type::<interactions::MaterialProperties>()
.add_event::<fields::ElectromagneticFieldInteractionEvent>()
.add_systems(Update, fields::calculate_field_interactions);
}
}

/// The electromagnetism prelude.
///
/// This includes the most common types for electromagnetic systems.
pub mod prelude {
pub use crate::electromagnetism::fields::{ElectricField, MagneticField};
pub use crate::electromagnetism::interactions::{
ElectromagneticWave, MaterialProperties
};
}
pub use crate::electromagnetism::interactions::{ElectromagneticWave, MaterialProperties};
}
Loading
Loading