Skip to content

cuppachino/bevy_logic

Repository files navigation

bevy_logic

Crates.io docs license Crates.io

A logic gate simulation plugin for bevy.

Features

  • A LogicGraph resource for sorting (potentially cyclic) logic gate circuits.
  • A fixed timestep LogicUpdate schedule that works just like bevy's FixedUpdate.
  • A ternary approach to Signal, enabling non-boolean circuits and analog machines.
  • LogicGate trait queries.
  • Builder traits for World and Commands that ease gate hierarchy construction.
  • Commands for synchronizing a graph with the game world.
  • Modular plugin design. Pick and choose which features you need.

Running examples

cargo run --release --example cycles

Quickstart

Add the LogicSimulationPlugin to your app, and configure the Time<LogicStep> resource to tick at the desired speed.

const STEPS_PER_SECOND: f64 = 30.0;
app.add_plugins(LogicSimulationPlugin)
    .insert_resource(Time::<LogicStep>::from_hz(STEPS_PER_SECOND));

Custom logic gates

You can create your own logic gates by implementing the LogicGate trait...

use bevy_logic::prelude::*;

/// The XOR gate emits a signal if the number of "truthy" inputs is odd.
#[derive(Component, Clone, Copy, Debug, Default, Reflect)]
pub struct XorGate;

impl LogicGate for XorGate {
    fn evaluate(&mut self, inputs: &[Signal], outputs: &mut [Signal]) {
        let signal: Signal = inputs
            .iter()
            .filter(|s| s.is_truthy())
            .count()
            .is_odd()
            .into();

        outputs.set_all(signal);
    }
}

And then registering the component with bevy_trait_query...

struct CustomLogicPlugin;

impl Plugin for CustomLogicPlugin {
    fn build(&self, app: &mut App) {
        app.register_logic_gate::<XorGate>();
    }
}

You can use the logic::commands module to spawn gates and fans, and then connect fans with wires. Make sure to compile() the logic graph.

fn spawn_custom_gate(mut commands: Commands, mut sim: ResMut<LogicGraph>) {
    let xor_gate = commands
        .spawn_gate((Name::new("XOR"), XorGate))
        .with_inputs(2)
        .with_outputs(1)
        .build();

    let not_gate = commands
        .spawn_gate((Name::new("NOT"), NotGate))
        .with_inputs(1)
        .with_outputs(1)
        .build();

    let wire = commands.spawn_wire(&not_gate, 0, &xor_gate, 0).downgrade();

    sim.add_data(vec![xor_gate, not_gate]).add_data(wire).compile();
}

Bevy Compatibility

bevy bevy_logic
0.14 0.7.x
0.13.2 0.6.x