From 9837d7d52e8c7056361af5290c74f24cde2aac91 Mon Sep 17 00:00:00 2001 From: core Date: Sun, 5 Apr 2026 11:11:19 -0400 Subject: [PATCH] chore: document the attachment system somewhat --- crates/unified/src/attachment.rs | 36 +++++++++++++++++++++++++++-- crates/unified/src/server/player.rs | 2 -- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/crates/unified/src/attachment.rs b/crates/unified/src/attachment.rs index dcf479249aa1b90f4a3617807d12f80280588531..7d14a6be442164c1a9d6abd535219b95be1ec93b 100644 --- a/crates/unified/src/attachment.rs +++ b/crates/unified/src/attachment.rs @@ -1,3 +1,19 @@ +//! attachment system overview +//! +//! hearty has a `Ship` marker component, and a `Parts` auto component containing all parts of the +//! ship +//! +//! parts of the ship have a `PartInShip` pointing back to hearty +//! +//! parts have many `Joint`s, which are separate children entities representing an attachment point +//! get pointers to joints with the `Joints` auto component +//! +//! joints have `JointOf` pointing to the part they belong to +//! if a part is connected to another point at a joint, that joint will have a `Peer`, pointing to +//! the Joint entity on the other part, and containing a pointer to the physics world joint +//! +//! snaps are also a thing and can be generally disregarded + use bevy::ecs::entity::MapEntities; use crate::prelude::*; use serde::{Deserialize, Serialize}; @@ -5,32 +21,41 @@ use std::ops::Deref; #[derive(Component, Serialize, Deserialize)] #[require(Replicated)] -/// The primary component for a ship structure +/// The primary component for a ship structure. Will be present on Hearty pub struct Ship; #[derive(Component, Serialize, Deserialize, MapEntities, Deref)] #[relationship_target(relationship = PartInShip, linked_spawn)] #[require(Replicated)] +/// List of all parts in this Ship. Will be present on Hearty. +/// Managed automatically by attachment system (do not modify)y, + pub struct Parts(#[entities] Vec); #[derive(Component, Serialize, Deserialize, MapEntities, Debug)] #[relationship(relationship_target = Parts)] #[require(Replicated)] +/// A Pointer to the `Ship` that this part belongs to. Managed automatically by attachment system +/// (do not add/remove manually) pub struct PartInShip(#[entities] pub Entity); #[derive(Component, Serialize, Deserialize)] #[require(Transform)] #[require(Replicated)] +/// A `Joint` is a separate entity (child of a part) that represents a single possible attachment +/// point for that part. pub struct Joint { pub id: JointId, pub transform: Transform, } #[derive(Component, Serialize, Deserialize, MapEntities)] #[require(Replicated)] +/// A `Peer` is a pointer component of a `Joint` that references the Joint entity it is connected to. +/// Two joints are said to be 'peered' when they are attached to each other. +/// Two Parts are connected when they have a set of peered `Joint`s pub struct Peer { #[entities] pub peer_joint_entity_id: Entity, - pub processed: bool, #[entities] pub physics_joint: Entity } @@ -38,10 +63,12 @@ pub struct Peer { #[derive(Component, Serialize, Deserialize, MapEntities)] #[relationship(relationship_target = Joints)] #[require(Replicated)] +/// A pointer to the `Part` that this `Joint` belongs to. Managed automatically, do not add/remove pub struct JointOf(#[entities] pub Entity); #[derive(Component, Serialize, Deserialize, MapEntities, Debug, Clone)] #[relationship_target(relationship = JointOf)] #[require(Replicated)] +/// All the `Joint`s that belong to this `Part`. Managed automatically, do not modify pub struct Joints(#[entities] Vec); impl Deref for Joints { type Target = Vec; @@ -49,13 +76,17 @@ impl Deref for Joints { &self.0 } } + #[derive(Component, Serialize, Deserialize, MapEntities)] #[relationship(relationship_target = Snaps)] #[require(Replicated)] +/// The `Part` that this Snap belongs to. A Snap is an internal entity used for snapping during +/// the attachment routine. Managed automatically. pub struct SnapOf(#[entities] pub Entity); #[derive(Component, Serialize, Deserialize, MapEntities)] #[relationship_target(relationship = SnapOf)] #[require(Replicated)] +/// All the `Snap`s of this `Joint`. Managed automatically. pub struct Snaps(#[entities] Vec); impl Deref for Snaps { type Target = Vec; @@ -76,4 +107,5 @@ impl JointId { #[derive(Serialize, Deserialize, Component, MapEntities)] #[require(Replicated)] +/// The `Joint` that this `Snap` belongs to pub struct SnapOfJoint(#[entities] pub Entity); diff --git a/crates/unified/src/server/player.rs b/crates/unified/src/server/player.rs index ef596fbdad16ff436ffb1f4a2a897e6dba16c65d..9e67222dbe76ce06a6ae14be483f8ab0ab796d09 100644 --- a/crates/unified/src/server/player.rs +++ b/crates/unified/src/server/player.rs @@ -368,12 +368,10 @@ fn dragging( // create the peering component... commands.entity(source_joint.4).insert(Peer { peer_joint_entity_id: target_joint.4, - processed: true, physics_joint: joint_id }); commands.entity(target_joint.4).insert(Peer { peer_joint_entity_id: source_joint.4, - processed: true, physics_joint: joint_id });