Conversation
Encapsulates the is_plugin_added / add_plugins default pattern that every implementation plugin must use to auto-satisfy its runtime dependencies. This is the foundational convention required before any crate extraction. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replaces the flat 'all crates depend on dd40_core' rule with Foundation / Implementation / Binary tiers. Documents the ensure_plugins! pattern, adds planned crates to the crate-roles table, and expands INCONSISTENCIES.md with items 5-7 (physics in core, character types in core, player-gated systems) that are tracked in SPEC.md. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Extracts all physics vocabulary from dd40_core into a dedicated foundation crate: Aabb, Velocity, GravityScale, Grounded, CharacterPosition, TentativePosition, Impulse, PhysicsBody, CharacterCollider, PhysicsConfig, PhysicsSet. PhysicsCorePlugin auto-adds CorePlugin via ensure_plugins!. Physics systems remain in dd40_core::character::physics for now (Task 1.2). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copies integration, block_collision, character_collision, and spatial_cache systems from dd40_core into the new dd40_physics implementation crate with updated imports (dd40_physics_core::prelude::* and dd40_core::*). PhysicsPlugin auto-adds CorePlugin and PhysicsCorePlugin via ensure_plugins!. All 49 tests pass. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Phase 1 of the three-tier architecture refactor (SPEC.md Tasks 1.1–1.3): - dd40_physics_core: vocabulary crate (Aabb, Velocity, Grounded, CharacterPosition, Impulse, PhysicsBody, PhysicsConfig, PhysicsSet, etc.) - dd40_physics: implementation crate (integration, block collision, character collision, spatial cache) with PhysicsPlugin that auto-adds its deps via ensure_plugins! - dd40_core::character::physics now re-exports from dd40_physics_core (backward compat shim until Phase 2 removes it entirely) - Removed circular dev-dep dd40_core → dd40_physics: controller integration tests moved to crates/physics/tests/character_controller.rs where dd40_core is a plain dep and TypeIds are consistent - Added Logging and Circular Dev-Dependency rules to CLAUDE.md All 237 workspace tests pass green. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
New foundation crate holding all character vocabulary: Player, Character, MovementSpeed, JumpImpulse, SpawnPosition, CharacterInput, CharacterController, CharacterRenderSet, CharacterBundle, CharacterBuilder, and the controller system. CharacterCorePlugin auto-adds PhysicsCorePlugin via ensure_plugins!. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Deletes crates/core/src/character/ entirely. All character vocabulary (Player, Character, MovementSpeed, JumpImpulse, SpawnPosition, CharacterInput, CharacterController, CharacterRenderSet, CharacterBundle, CharacterBuilder) now comes exclusively from dd40_character_core. Updated consumers: dd40_player, dd40_network (client + server), dd40_renderer. Physics tests updated to add CharacterCorePlugin alongside PhysicsPlugin since the controller system is no longer bundled into CorePlugin. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace hand-rolled panics and missing plugin checks with ensure_plugins!: - WorldPlugin: panic → ensure_plugins!(app, CorePlugin) - DiskStoragePlugin: add ensure_plugins!(app, CorePlugin) - RendererPlugin: add ensure_plugins!(app, CorePlugin) - VanillaPalettePlugin: add ensure_plugins!(app, CorePlugin) - DebugUiPlugin: add ensure_plugins!(app, CorePlugin) - ServerNetworkPlugin: panic → ensure_plugins!(app, CorePlugin) - ClientNetworkPlugin: add ensure_plugins!(app, CorePlugin) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…0_player - Task 3.1: dd40_player_movement crate with camera, input, PlayerMode state, mouse sensitivity, FreeCam movement, and chunk loading systems - Task 3.2: dd40_character_interaction crate with DDA raycast targeting, mining, and placement systems generalised to With<Character> (not With<Player>) - Task 3.3: dd40_player slimmed to a thin wrapper that composes PlayerMovementPlugin + CharacterInteractionPlugin; retains update_debug_info (needs both physics and interaction types) and spawn_player Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…er_core - Task 5.1: renderer LOD anchor now uses CharacterPosition (dd40_physics_core) instead of With<Player>; removes dd40_character_core dep from renderer - Task 5.2: add PlayerId(u64) to dd40_character_core — stable network identity for correlating ECS entities with peer connections - Task 5.3: move MiningState to dd40_character_core (pure vocabulary); renderer can now read mining progress without depending on dd40_character_interaction; dd40_character_interaction re-exports MiningState from character_core Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…troller After the refactor, CorePlugin no longer auto-adds CharacterPlugin/controller. ServerNetworkPlugin was only ensuring CorePlugin, so apply_character_controller was never registered on the server. Characters fell under gravity but never moved horizontally — lightyear confirmed the stationary server position each tick, causing the client to be yanked back to spawn on every move. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
PlayerRotation was registered with add_prediction(), so lightyear would checkpoint and restore it during rollbacks. Since rotation always lags the mouse by one RTT, every correction snapped the rotation backward. Fix: - PlayerRotation now has add_linear_interpolation() only (no prediction). The controlling client never experiences a rollback on rotation. - sync_local_rotation (PostUpdate) writes CharacterInput.pitch/yaw directly to PlayerRotation each frame, after lightyear's replication receive and after player_input has refreshed CharacterInput. Render always sees the current-frame camera orientation with zero lag. - apply_interpolated_rotation (Update) applies PlayerRotation → Transform rotation for remote (Interpolated) entities so other clients see smooth, server-replicated head direction via linear interpolation. Pitch/yaw remain in PlayerInput so the server continues to receive them and can replicate PlayerRotation to non-controlling clients. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…urrent state CLAUDE.md: - Remove *(planned)* from all five crates that now exist - Note MiningState and PlayerId in dd40_character_core role description - Note renderer's CharacterPosition LOD anchor - Note dd40_player's known exception to Tier 1 isolation INCONSISTENCIES.md: - Archive resolved items 1, 3, 5, 6, 7 into a resolved table - Keep item 4 (block crack animation) as open but note it's unblocked - Rewrite dd40_renderer dep as a suggestion (D: key PlayerLocations by PlayerId) - Add dd40_player tier exception as the new open inconsistency SKILL.md: - Add dd40_player exception note to Tier 1 section Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR performs a large architectural split of character and physics responsibilities out of dd40_core into new foundation/implementation crates, while also adopting the new auto-plugin dependency pattern across the workspace. It reshapes how gameplay, rendering, networking, and binaries compose shared systems and vocabulary.
Changes:
- Extracts new foundation crates (
dd40_physics_core,dd40_character_core) and implementation crates (dd40_physics,dd40_player_movement,dd40_character_interaction), then rewires existing crates to use them. - Replaces several manual plugin dependency checks with
dd40_core::ensure_plugins!and updates client/server binaries to include the new physics layer explicitly. - Updates architecture/spec documentation (
SPEC.md,INCONSISTENCIES.md,CLAUDE.md, skill docs) to describe the new three-tier crate model and plugin auto-satisfaction pattern.
Reviewed changes
Copilot reviewed 77 out of 78 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| crates/world/src/plugin.rs | Swaps manual CorePlugin precondition for ensure_plugins!. |
| crates/vanilla_palette/src/lib.rs | Auto-adds CorePlugin before palette plugins. |
| crates/server/src/main.rs | Adds PhysicsPlugin to server composition. |
| crates/server/Cargo.toml | Adds dd40_physics dependency. |
| crates/renderer/src/systems.rs | Switches LOD anchor from player transform to CharacterPosition. |
| crates/renderer/src/lib.rs | Auto-adds core/physics foundation plugins. |
| crates/renderer/Cargo.toml | Replaces dd40_player dependency with dd40_physics_core. |
| crates/player_movement/src/systems.rs | New camera/input/freecam/chunk-loading systems crate. |
| crates/player_movement/src/state.rs | Introduces PlayerMode state. |
| crates/player_movement/src/plugin.rs | Wires player movement systems and tests plugin auto-deps. |
| crates/player_movement/src/lib.rs | Exposes movement plugin/components/state. |
| crates/player_movement/src/components.rs | Adds camera rotation and mouse sensitivity components. |
| crates/player_movement/Cargo.toml | Declares new movement crate dependencies. |
| crates/player/src/lib.rs | Slims player crate into spawn/debug/wrapper responsibilities. |
| crates/player/src/block_interaction/mod.rs | Removes old in-crate block interaction module. |
| crates/player/src/block_interaction/mining.rs | Removes old in-crate mining implementation. |
| crates/player/Cargo.toml | Replaces monolithic deps with split character/physics/player crates. |
| crates/physics_core/src/system_sets.rs | Introduces PhysicsSet in foundation crate. |
| crates/physics_core/src/prelude.rs | Re-exports physics-core vocabulary. |
| crates/physics_core/src/plugin.rs | Registers physics-core types/resources/system ordering. |
| crates/physics_core/src/lib.rs | Exposes physics-core modules. |
| crates/physics_core/src/components.rs | Moves core physics components/config into new crate. |
| crates/physics_core/Cargo.toml | Declares new physics-core crate. |
| crates/physics/tests/physics_behavior.rs | Adds integration tests for physics plugin behavior. |
| crates/physics/tests/character_controller.rs | Adds controller/physics integration tests. |
| crates/physics/src/spatial_cache.rs | Updates spatial cache imports and visibility after split. |
| crates/physics/src/plugin.rs | New implementation physics plugin composing simulation systems. |
| crates/physics/src/lib.rs | Exposes physics modules/plugin/cache. |
| crates/physics/src/integration.rs | Moves integration stage onto physics-core vocabulary. |
| crates/physics/src/character_collision.rs | Moves character-collision stage onto split crates. |
| crates/physics/Cargo.toml | Declares new physics implementation crate. |
| crates/network/src/shared/character.rs | Repoints shared character bundle/controller imports. |
| crates/network/src/server/mod.rs | Uses ensure_plugins! for server networking deps. |
| crates/network/src/server/character.rs | Repoints server character replication to split crates. |
| crates/network/src/server/block_placement.rs | Uses moved physics/cache types for placement validation. |
| crates/network/src/protocol.rs | Repoints replicated types and changes PlayerRotation replication mode. |
| crates/network/src/client/spawn.rs | Repoints player marker import. |
| crates/network/src/client/plugin.rs | Uses ensure_plugins! for client networking deps. |
| crates/network/src/client/character.rs | Repoints client character code and adds rotation sync/interpolation. |
| crates/network/Cargo.toml | Adds split character/physics dependencies. |
| crates/debug_ui/src/lib.rs | Auto-adds CorePlugin. |
| crates/core/src/plugin.rs | Removes old character plugin wiring and keeps core-only responsibilities. |
| crates/core/src/macros.rs | Adds ensure_plugins! macro and tests. |
| crates/core/src/lib.rs | Removes character exports and exposes macros/collision shape. |
| crates/core/src/character/plugin.rs | Deletes old character plugin from core. |
| crates/core/src/character/physics/mod.rs | Deletes old in-core physics module. |
| crates/core/src/character/mod.rs | Deletes old in-core character module. |
| crates/core/src/character/controller.rs | Deletes old in-core character controller. |
| crates/core/src/character/builder.rs | Deletes old in-core character builder. |
| crates/core/src/block/registry.rs | Updates collision-shape import path. |
| crates/core/src/block/mod.rs | Moves CollisionShape into block module. |
| crates/client/src/main.rs | Adds PhysicsPlugin and comments out inspector plugins. |
| crates/client/Cargo.toml | Adds dd40_physics dependency. |
| crates/chunk_storage/src/plugin.rs | Auto-adds CorePlugin. |
| crates/character_interaction/src/targeting.rs | New generic targeting/highlight/debug module. |
| crates/character_interaction/src/plugin.rs | New interaction plugin/resources/messages/scheduling. |
| crates/character_interaction/src/placement.rs | New generic placement module. |
| crates/character_interaction/src/mining.rs | New generic mining module. |
| crates/character_interaction/src/lib.rs | Exposes interaction crate API. |
| crates/character_interaction/Cargo.toml | Declares new interaction crate. |
| crates/character_core/src/system_sets.rs | Introduces CharacterRenderSet in foundation crate. |
| crates/character_core/src/prelude.rs | Re-exports character-core vocabulary. |
| crates/character_core/src/plugin.rs | Registers character-core types/render ordering/controller plugin. |
| crates/character_core/src/mining_state.rs | Moves MiningState into character-core. |
| crates/character_core/src/lib.rs | Exposes character-core modules. |
| crates/character_core/src/controller.rs | Moves character controller into character-core. |
| crates/character_core/src/components.rs | Moves character/player/jump/movement/spawn/player-id types. |
| crates/character_core/src/bundles.rs | Moves CharacterBundle into character-core. |
| crates/character_core/src/builder.rs | Moves CharacterBuilder into character-core. |
| crates/character_core/Cargo.toml | Declares new character-core crate. |
| SPEC.md | Adds detailed modular-architecture refactor spec. |
| INCONSISTENCIES.md | Rewrites inconsistency tracking for new architecture. |
| Cargo.toml | Adds new workspace members and workspace dependencies. |
| Cargo.lock | Locks new crate graph/dependencies. |
| CLAUDE.md | Adds contributor/tooling architecture guidance for new model. |
| .agents/skills/dd40-architecture/SKILL.md | Updates project skill doc for three-tier architecture. |
Comment on lines
+197
to
+225
| /// Casts a ray from the camera and writes the result into [`TargetedBlock`]. | ||
| pub(crate) fn update_targeted_block( | ||
| mut targeted: ResMut<TargetedBlock>, | ||
| config: Res<BlockInteractionConfig>, | ||
| camera_query: Query<&Transform, With<Camera3d>>, | ||
| cache: Res<ChunkCache>, | ||
| registry: Res<BlockRegistry>, | ||
| ) { | ||
| let Ok(camera_transform) = camera_query.single() else { | ||
| targeted.pos = None; | ||
| targeted.face = None; | ||
| targeted.block_id = None; | ||
| return; | ||
| }; | ||
|
|
||
| let origin = camera_transform.translation; | ||
| let direction = *camera_transform.forward(); | ||
|
|
||
| match dda_raycast(origin, direction, config.max_distance, &cache, ®istry) { | ||
| Some((pos, face, block_id)) => { | ||
| targeted.pos = Some(pos); | ||
| targeted.face = Some(face); | ||
| targeted.block_id = Some(block_id); | ||
| } | ||
| None => { | ||
| targeted.pos = None; | ||
| targeted.face = None; | ||
| targeted.block_id = None; | ||
| } |
Comment on lines
+65
to
+68
| app.insert_resource(BlockInteractionConfig::default()) | ||
| .insert_resource(TargetedBlock::default()) | ||
| .insert_resource(HeldBlock::default()) | ||
| .insert_resource(MiningState::default()) |
Comment on lines
+22
to
+32
| equipped_query: Query<&EquippedTool, With<Character>>, | ||
| registry: Res<BlockRegistry>, | ||
| tool_registry: Res<ToolRegistry>, | ||
| time: Res<Time>, | ||
| mut state: ResMut<MiningState>, | ||
| mut start_writer: MessageWriter<StartMiningRequest>, | ||
| mut abort_writer: MessageWriter<AbortMiningRequest>, | ||
| mut mine_writer: MessageWriter<MineBlockRequest>, | ||
| ) { | ||
| let bare_hands = EquippedTool::default(); | ||
| let tool = equipped_query.iter().next().copied().unwrap_or(bare_hands); |
Comment on lines
+15
to
+19
| pub use dd40_character_interaction::{ | ||
| BlockFace, BlockInteractionConfig, CharacterInteractionPlugin as BlockInteractionPlugin, | ||
| HeldBlock, TargetedBlock as TargetBlock, | ||
| }; | ||
| pub use dd40_player_movement::{CameraRotation, MouseSensitivity, PlayerMode as PlayerModeType}; |
| | — | Physics systems lived in `dd40_core` | SPEC.md Phase 1 — extracted to `dd40_physics_core` + `dd40_physics` | | ||
| | — | Character types lived in `dd40_core` | SPEC.md Phase 2 — extracted to `dd40_character_core` | | ||
| | — | Block interaction and movement systems were player-gated | SPEC.md Phase 3 — `dd40_character_interaction` and `dd40_player_movement` created, filters changed to `With<Character>` | | ||
| | — | `PlayerId(u64)` did not exist | SPEC.md Task 5.2 — added to `dd40_character_core::components` | |
Comment on lines
+20
to
+23
| /// Unlike the old `BlockInteractionPlugin`, this plugin does **not** gate | ||
| /// systems on `PlayerMode`. That concern belongs to the caller — wire the | ||
| /// systems under whatever condition suits your control scheme (e.g. only while | ||
| /// `PlayerMode::Controller` for human players). |
Comment on lines
+107
to
+117
| app.add_plugins((PlayerMovementPlugin, CharacterInteractionPlugin)); | ||
|
|
||
| // Clear interaction state when switching to FreeCam so highlights and | ||
| // mining progress don't linger. OnEnter lives here because it needs | ||
| // both PlayerMode (player_movement) and the interaction resources. | ||
| app.add_systems( | ||
| OnEnter(PlayerMode::FreeCam), | ||
| |mut targeted: ResMut<TargetedBlock>, mut mining: ResMut<MiningState>| { | ||
| *targeted = TargetedBlock::default(); | ||
| *mining = MiningState::Idle; | ||
| }, |
The two app.update() calls in the test helper are non-obvious: the first tick lets Bevy accumulate the manual duration into Time<Fixed>; the second actually drains the bucket and runs FixedUpdate where physics systems live. This comment was lost during the crate rename and is worth keeping for anyone unfamiliar with Bevy's fixed-timestep scheduler. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
TentativePosition is a pipeline-internal scratch buffer used only by the dd40_physics systems (integrate, block_collision, character_collision, spatial_cache). It has no meaning outside the physics implementation crate and should not be part of the public vocabulary exposed by dd40_physics_core. Changes: - Remove TentativePosition from dd40_physics_core (components, prelude) - Remove it from PhysicsBody's #[require] (it can't stay there once the type moves to a downstream crate) - Define it as pub(crate) in dd40_physics::integration - Add an On<Add, PhysicsBody> observer in PhysicsPlugin that inserts TentativePosition automatically, preserving the spawn-time guarantee that #[require] previously provided - Update imports in block_collision, character_collision, spatial_cache Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CharacterSpatialCache was living in dd40_physics (implementation tier), making it inaccessible to other crates without pulling in the full physics implementation. Moving it to dd40_physics_core (foundation tier) makes it available as a shared resource. - Add resources module to dd40_physics_core with CharacterSpatialCache and PhysicsConfig (relocated from components) - Initialize CharacterSpatialCache in PhysicsCorePlugin instead of CharacterCollisionPlugin - Inline update_character_spatial_cache into character_collision.rs, removing the now-empty spatial_cache module from dd40_physics - Update prelude and remove dd40_network's direct physics dependency
physics_core, character_core, physics, player_movement, and character_interaction were all missing per-crate READMEs. Add a minimal README to each following the same format as the other crates. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ayout The previous version described the pre-refactor architecture: it listed only 8 crates (now 16), used the old single-dependency rule, and showed module trees for character/ and physics/ sub-modules that were extracted out of dd40_core in the Phase 1-3 work. Rewrite with: - Three-tier dependency model table - All 16 crates in the inventory (Tier 0/1/2 grouped) - Accurate module trees for every crate - dd40_player exception clearly noted Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- README.md: expand layout block to list all 16 crates with tier labels; remove claim that all crates depend only on dd40_core - crates/core/README.md: remove stale character/ and physics/ module trees and the "physics engine exception" rationale (physics is in dd40_physics_core) - crates/player/README.md: replace deleted block_interaction/ module tree with the current three-plugin structure; fix dependency list - crates/renderer/README.md: remove stale note about dd40_player dep inconsistency (fixed in Phase 5); update dep list to include dd40_physics_core Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
character-physics.md: - All import paths updated to dd40_physics_core::prelude and dd40_character_core::prelude (old dd40_core::character::* paths no longer exist) - PhysicsSet: add missing InputSync stage (now 5 stages total) - PhysicsConfig: add ground_friction and air_friction fields - CharacterSpatialCache: note correct location in dd40_physics_core - Builder example updated with correct imports block-system.md: - Remove broken `use dd40_core::character::physics::CollisionShape` import (CollisionShape is already in dd40_core::prelude::*) - Fix "See also" path: vanilla_blocks.rs moved to dd40_vanilla_palette - Update opening paragraph to name dd40_vanilla_palette correctly Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The skill used "core vs non-core" binary terminology from before the Phase 1-3 refactor. Update throughout: - Tier classification: Foundation / Implementation / Binary - Step 2: list all three foundation crates (core, physics_core, character_core) and the Tier 1 isolation rule - Cargo.toml template: note that only foundation deps are permitted - plugin.rs template: add ensure_plugins! call and #[derive(Default)] - Step 7 next-steps sections: rename to Tier 0 / Tier 1 - Architectural rules: restate in tier language; add Default derive and ensure_plugins! as hard rules; note dd40_player exception Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Expand crate list from 6 to 16 with three-tier grouping - Fix broken CollisionShape import (dd40_core::character::physics no longer exists; CollisionShape is in dd40_core::prelude::*) - Replace BlockRenderingPlugin (removed) with RendererPlugin in the plugin-based architecture section Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Remove "Player position/velocity" from the Coming Soon list — it is already rendered via the DebugInfo system in dd40_player. Mention the orientation gizmo and custom DebugInfo elements in the "What You Get" section since they ship with DebugUiPlugin today. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This pull request introduces major architectural updates and documentation improvements to support a modular, three-tier crate structure for the dd40 voxel game project. It adds new foundation and implementation crates, formalizes architectural rules, and improves documentation for both contributors and automated tools. The changes clarify crate dependencies, outline planned architectural work, and update the workspace configuration accordingly.
Architectural and Documentation Updates:
.agents/skills/dd40-architecture/SKILL.md, replacing the previous single-core rule. Added explicit rules for plugin auto-satisfaction with theensure_plugins!macro and clarified code placement guidelines. [1] [2]CLAUDE.mdto provide clear instructions and architectural guidance for Claude Code and new contributors, including commands, crate roles, system ordering, and documentation standards.INCONSISTENCIES.mdto document new and existing architectural violations, referencing planned fixes inSPEC.mdand reflecting the new crate structure (e.g.,dd40_physics_core,dd40_character_core, and implementation crate interactions). [1] [2]Workspace and Crate Additions:
Cargo.toml:dd40_physics_core,dd40_physics,dd40_character_core,dd40_player_movement, anddd40_character_interaction. Updated workspace dependencies accordingly. [1] [2]crates/character_corewith its ownCargo.tomland implemented aCharacterBuilderfluent builder pattern for constructing character bundles, promoting code clarity and modularity. [1] [2]Reference additions: