| Crates.io | bevy_pins |
| lib.rs | bevy_pins |
| version | 0.1.1 |
| created_at | 2025-10-14 15:52:33.173987+00 |
| updated_at | 2025-10-17 21:22:04.945848+00 |
| description | A flexible pin/charm system for Bevy games, inspired by Hollow Knight's charm system |
| homepage | https://github.com/tajo48/bevy_pins |
| repository | https://github.com/tajo48/bevy_pins |
| max_upload_size | |
| id | 1882623 |
| size | 220,748 |
A flexible pin/charm system for Bevy games, inspired by Hollow Knight's charm system. This crate provides a complete framework for equippable items that modify entity components and behavior.
Add to your Cargo.toml:
[dependencies]
bevy_pins = "0.1.1"
bevy = "0.17.2"
First, create the components that your pins will add to entities:
use bevy::prelude::*;
#[derive(Component, Default, Debug)]
struct SpeedBoost {
multiplier: f32,
}
#[derive(Component, Default, Debug)]
struct HealthBoost {
extra_health: i32,
}
Use the create_pins! macro to define multiple pins at once:
use bevy_pins::*;
create_pins!(
SwiftPin {
name: "Swift Soul",
description: "Increases movement speed by 50%",
enabled: true,
cost: 2,
image_path: "textures/swift_pin.png",
component: SpeedBoost
},
HealthPin {
name: "Lifeblood Heart",
description: "Grants 2 extra health masks",
enabled: true,
cost: 3,
component: HealthBoost
}
);
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_plugins(PinsPlugin)
.add_systems(Startup, setup)
.run();
}
fn setup(mut commands: Commands) {
// Register all pins (call this after create_pins!)
register_all_pins();
// Spawn an entity with the pin system
commands.spawn((
PinsHolder::new(11), // 11 notch slots
Name::new("Player"),
));
}
fn example_system(
mut inventory_events: MessageWriter<AddPinToInventoryEvent>,
mut equip_events: MessageWriter<EquipPinEvent>,
player_query: Query<Entity, With<PinsHolder>>,
) {
let player = player_query.single();
// Add pin to inventory
inventory_events.write(AddPinToInventoryEvent {
pin_id: PinId::new::<SwiftPin>(),
});
// Equip the pin
equip_events.write(EquipPinEvent {
entity: player,
pin_id: PinId::new::<SwiftPin>(),
});
}
The create_pins! macro supports these fields:
name: Display name of the pindescription: Description text shown in UIenabled: Whether the pin appears in the game (allows hiding pins)cost: Notch cost to equip the pinimage_path: Path to the pin's image asset (optional - defaults to textures/{PinName}.png)component: The Bevy component type this pin adds to entitiesThe system provides several events for managing pins:
AddPinToInventoryEvent / RemovePinFromInventoryEvent: Manage inventoryEquipPinEvent / UnequipPinEvent: Equip/unequip pinsOverpinToggleEvent: Toggle overpin modeWhen the pin UI is open (press Tab):
PinInventory: Tracks owned pinsPinEquipmentState: Tracks equipped pins per entityPinRegistry: Registry of all available pinsPinUIState: UI navigation statePinsHolder: Add to entities that can equip pinsEquippedPin: Information about equipped pinsLike Hollow Knight's overcharm system, entities can equip pins beyond their normal capacity:
Pins can be enabled/disabled and discovered dynamically:
// Pins with enabled: false won't appear in the registry
create_pins!(
SecretPin {
name: "Secret Ability",
description: "A hidden pin",
enabled: false, // Won't appear until enabled
cost: 1,
component: SecretComponent
}
);
Check out examples/demo.rs for a complete working example that demonstrates:
Run with:
cargo run --example demo
This project is licensed under the MIT License - see the LICENSE file for details.
Copyright (c) 2024 Piotr Świercz tajo48@proton.me