@jarrodmedrano/claude-skills 1.0.2 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/.claude/skills/bevy/SKILL.md +406 -0
  2. package/.claude/skills/bevy/references/bevy_specific_tips.md +385 -0
  3. package/.claude/skills/bevy/references/common_pitfalls.md +217 -0
  4. package/.claude/skills/bevy/references/ecs_patterns.md +277 -0
  5. package/.claude/skills/bevy/references/project_structure.md +116 -0
  6. package/.claude/skills/bevy/references/ui_development.md +147 -0
  7. package/.claude/skills/domain-driven-design/SKILL.md +459 -0
  8. package/.claude/skills/domain-driven-design/references/ddd_foundations_and_patterns.md +664 -0
  9. package/.claude/skills/domain-driven-design/references/rich_hickey_principles.md +406 -0
  10. package/.claude/skills/domain-driven-design/references/visualization_examples.md +790 -0
  11. package/.claude/skills/domain-driven-design/references/wlaschin_patterns.md +639 -0
  12. package/.claude/skills/game-design-theory/SKILL.md +102 -0
  13. package/.claude/skills/game-design-theory/design-principles.md +308 -0
  14. package/.claude/skills/game-design-theory/gameplay-elements.md +213 -0
  15. package/.claude/skills/game-design-theory/player-psychology.md +175 -0
  16. package/.claude/skills/game-design-theory/playtesting.md +321 -0
  17. package/.claude/skills/game-design-theory/storytelling.md +219 -0
  18. package/.claude/skills/game-feel/SKILL.md +305 -0
  19. package/.claude/skills/game-feel/references/adsr-tuning.md +271 -0
  20. package/.claude/skills/game-feel/references/classic-profiles.md +279 -0
  21. package/.claude/skills/game-feel/references/perception-thresholds.md +160 -0
  22. package/.claude/skills/game-feel/references/polish-effects.md +246 -0
  23. package/.claude/skills/game-feel/references/simulation-recipes.md +306 -0
  24. package/.claude/skills/game-feel/references/six-metrics.md +239 -0
  25. package/.claude/skills/godot/SKILL.md +728 -0
  26. package/.claude/skills/godot/assets/templates/attribute_template.gd +109 -0
  27. package/.claude/skills/godot/assets/templates/component_template.gd +76 -0
  28. package/.claude/skills/godot/assets/templates/interaction_template.gd +108 -0
  29. package/.claude/skills/godot/assets/templates/item_resource.tres +11 -0
  30. package/.claude/skills/godot/assets/templates/spell_resource.tres +20 -0
  31. package/.claude/skills/godot/references/architecture-patterns.md +608 -0
  32. package/.claude/skills/godot/references/common-pitfalls.md +518 -0
  33. package/.claude/skills/godot/references/file-formats.md +491 -0
  34. package/.claude/skills/godot/references/godot4-physics-api.md +302 -0
  35. package/.claude/skills/godot/scripts/validate_tres.py +145 -0
  36. package/.claude/skills/godot/scripts/validate_tscn.py +170 -0
  37. package/.claude/skills/level-design/SKILL.md +249 -0
  38. package/.claude/skills/level-design/anticipatory-play.md +223 -0
  39. package/.claude/skills/level-design/hiding-linearity.md +181 -0
  40. package/.claude/skills/level-design/indie-practices.md +286 -0
  41. package/.claude/skills/level-design/open-world-planning.md +294 -0
  42. package/.claude/skills/level-design/play-personas.md +240 -0
  43. package/.claude/skills/level-design/procedural-handmade.md +271 -0
  44. package/.claude/skills/level-design/themed-environments.md +264 -0
  45. package/.claude/skills/react-three-fiber/SKILL.md +2055 -0
  46. package/.claude/skills/react-three-fiber/scripts/build-scene.ts +171 -0
  47. package/package.json +3 -1
  48. package/scripts/install.js +16 -1
  49. package/templates/github-actions/README.md +36 -0
  50. /package/.claude/{commands/design-review → agents}/design-review-agent.md +0 -0
  51. /package/.claude/{commands/code-review → agents}/pragmatic-code-review-subagent.md +0 -0
  52. /package/{.claude/commands/code-review → templates/github-actions}/claude-code-review-custom.yml +0 -0
  53. /package/{.claude/commands/code-review → templates/github-actions}/claude-code-review.yml +0 -0
  54. /package/{.claude/commands/security-review → templates/github-actions}/security.yml +0 -0
@@ -0,0 +1,385 @@
1
+ # Bevy-Specific Development Tips
2
+
3
+ ## Bevy 0.17 Specific Changes
4
+
5
+ **Important:** Bevy 0.17 introduced several breaking API changes. If you encounter compilation errors related to materials, events, or colors, refer to this section.
6
+
7
+ ### Material Component Wrapper
8
+
9
+ In Bevy 0.17, material handles are wrapped in `MeshMaterial3d<T>`:
10
+
11
+ ```rust
12
+ // ❌ Bevy 0.15/0.16 - This will fail in 0.17
13
+ Query<&Handle<StandardMaterial>>
14
+
15
+ // ✅ Bevy 0.17 - Use the wrapper component
16
+ Query<&MeshMaterial3d<StandardMaterial>>
17
+
18
+ // Access the inner handle with .0
19
+ fn update_materials(
20
+ query: Query<&MeshMaterial3d<StandardMaterial>>,
21
+ mut materials: ResMut<Assets<StandardMaterial>>,
22
+ ) {
23
+ for material_3d in query.iter() {
24
+ if let Some(material) = materials.get_mut(&material_3d.0) {
25
+ material.emissive = LinearRgba::RED;
26
+ }
27
+ }
28
+ }
29
+ ```
30
+
31
+ **Error symptoms:**
32
+ - `Handle<StandardMaterial> is not a Component`
33
+ - Query trait bounds not satisfied
34
+
35
+ **Solution:** Always use `MeshMaterial3d<T>` wrapper when querying material components.
36
+
37
+ ### Observer Pattern (Replaces Events)
38
+
39
+ Bevy 0.17 introduces observers as a replacement for the event system:
40
+
41
+ ```rust
42
+ // ❌ Old event pattern (Bevy 0.15/0.16)
43
+ #[derive(Event)]
44
+ struct SpellCastEvent { spell_name: String }
45
+
46
+ app.add_event::<SpellCastEvent>()
47
+ .add_systems(Update, handle_spell_cast);
48
+
49
+ fn handle_spell_cast(mut events: EventReader<SpellCastEvent>) {
50
+ for event in events.read() {
51
+ info!("Cast: {}", event.spell_name);
52
+ }
53
+ }
54
+
55
+ fn cast_spell(mut events: EventWriter<SpellCastEvent>) {
56
+ events.send(SpellCastEvent { spell_name: "Fireball".into() });
57
+ }
58
+
59
+ // ✅ Bevy 0.17 observer pattern
60
+ #[derive(Event, Clone)] // Must derive Clone!
61
+ struct SpellCastEvent { spell_name: String }
62
+
63
+ app.add_observer(handle_spell_cast); // Observer, not system
64
+
65
+ fn handle_spell_cast(
66
+ trigger: Trigger<SpellCastEvent>, // Trigger parameter
67
+ // ... other system params
68
+ ) {
69
+ let event = trigger.event();
70
+ info!("Cast: {}", event.spell_name);
71
+ }
72
+
73
+ fn cast_spell(mut commands: Commands) {
74
+ commands.trigger(SpellCastEvent { spell_name: "Fireball".into() });
75
+ }
76
+ ```
77
+
78
+ **Key differences:**
79
+ - Events **must derive `Clone`** in addition to `Event`
80
+ - Use `add_observer(handler)` instead of `add_event()` + `add_systems()`
81
+ - Handler takes `Trigger<T>` as first parameter, use `.event()` to access data
82
+ - Trigger with `commands.trigger()` instead of `EventWriter::send()`
83
+ - Observers are not systems - they're called directly when triggered
84
+
85
+ **Error symptoms:**
86
+ - `MyEvent is not a Message`
87
+ - `method 'send' not found for MessageWriter`
88
+ - `method 'read' not found`
89
+
90
+ **Solution:** Migrate to the observer pattern as shown above.
91
+
92
+ ### Color Operations
93
+
94
+ Direct color arithmetic operations aren't supported in Bevy 0.17:
95
+
96
+ ```rust
97
+ // ❌ Doesn't compile
98
+ let emissive = color * 0.5;
99
+ let darker = color - 0.2;
100
+
101
+ // ✅ Extract components manually
102
+ let emissive = Color::srgb(
103
+ color.to_srgba().red * 0.5,
104
+ color.to_srgba().green * 0.5,
105
+ color.to_srgba().blue * 0.5,
106
+ );
107
+
108
+ // Or use LinearRgba for math operations
109
+ let linear = color.to_linear();
110
+ let dimmed = LinearRgba::rgb(
111
+ linear.red * 0.5,
112
+ linear.green * 0.5,
113
+ linear.blue * 0.5,
114
+ );
115
+ ```
116
+
117
+ **Error symptoms:**
118
+ - `cannot multiply Color by {float}`
119
+ - `no implementation for Color * f32`
120
+
121
+ **Solution:** Convert to component form or use `LinearRgba` for mathematical operations.
122
+
123
+ ---
124
+
125
+ ## Using Bevy Registry Examples
126
+
127
+ **The registry examples are your bible.** Bevy ships with extensive examples that demonstrate best practices and patterns.
128
+
129
+ **Location:**
130
+ ```bash
131
+ ~/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bevy-0.17.1/examples
132
+ ```
133
+
134
+ **When to consult registry examples:**
135
+ - Before implementing a new feature type
136
+ - When unsure about API usage
137
+ - To see working patterns for complex systems
138
+ - To understand how plugins should be structured
139
+ - For reference implementations of common game mechanics
140
+
141
+ **How to use them:**
142
+ 1. Browse the examples directory for relevant use cases
143
+ 2. Study the complete implementation (not just snippets)
144
+ 3. Note how they structure components, systems, and plugins
145
+ 4. Adapt patterns to your specific needs
146
+
147
+ There are MANY examples covering:
148
+ - 2D/3D rendering
149
+ - Animation
150
+ - Audio
151
+ - Input handling
152
+ - UI systems
153
+ - Physics
154
+ - Scenes and assets
155
+ - And much more
156
+
157
+ **Always refer to examples before diving into implementation.**
158
+
159
+ ## Plugin Structure
160
+
161
+ Break your app into discrete modules using plugins whenever possible.
162
+
163
+ **Why use plugins:**
164
+ - Organizes code by feature/domain
165
+ - Makes systems reusable
166
+ - Improves code discoverability
167
+ - Enables modular development
168
+ - Follows Bevy best practices
169
+
170
+ **Plugin pattern:**
171
+ ```rust
172
+ use bevy::prelude::*;
173
+
174
+ pub struct CombatPlugin;
175
+
176
+ impl Plugin for CombatPlugin {
177
+ fn build(&self, app: &mut App) {
178
+ app
179
+ .add_event::<DamageEvent>()
180
+ .add_systems(Startup, setup_combat)
181
+ .add_systems(Update, (
182
+ process_damage,
183
+ check_death,
184
+ update_health_bars,
185
+ ));
186
+ }
187
+ }
188
+
189
+ // In main.rs
190
+ fn main() {
191
+ App::new()
192
+ .add_plugins(DefaultPlugins)
193
+ .add_plugins(CombatPlugin)
194
+ .add_plugins(MovementPlugin)
195
+ .add_plugins(UIPlugin)
196
+ .run();
197
+ }
198
+ ```
199
+
200
+ **References:**
201
+ - Plugin guide: https://bevy.org/learn/quick-start/getting-started/plugins/
202
+ - System sets: https://bevy-cheatbook.github.io/programming/system-sets.html
203
+
204
+ ## Build Performance and Optimization
205
+
206
+ ### Dynamic Linking
207
+
208
+ **Always use dynamic linking during development:**
209
+ ```bash
210
+ cargo build --features bevy/dynamic_linking
211
+ ```
212
+
213
+ **Why:**
214
+ - 2-3x faster compile times
215
+ - Critical for iteration speed
216
+ - Only affects development builds
217
+
218
+ **Setup in `.cargo/config.toml`:**
219
+ ```toml
220
+ [target.x86_64-unknown-linux-gnu]
221
+ linker = "clang"
222
+ rustflags = ["-C", "link-arg=-fuse-ld=lld"]
223
+
224
+ [target.x86_64-apple-darwin]
225
+ rustflags = ["-C", "link-arg=-fuse-ld=/usr/local/opt/llvm/bin/ld64.lld"]
226
+ ```
227
+
228
+ **Optimization levels** - See: https://bevy.org/learn/quick-start/getting-started/setup/
229
+
230
+ For faster dev builds, add to `Cargo.toml`:
231
+ ```toml
232
+ [profile.dev]
233
+ opt-level = 1
234
+
235
+ [profile.dev.package."*"]
236
+ opt-level = 3
237
+ ```
238
+
239
+ ### Build Management
240
+
241
+ **CRITICAL: Do not delete target binaries freely!**
242
+
243
+ Bevy takes **minutes** to rebuild from scratch. Be mindful of:
244
+
245
+ 1. **Target directory management:**
246
+ - Avoid `cargo clean` unless absolutely necessary
247
+ - Incremental builds are your friend
248
+ - Each clean rebuild costs valuable development time
249
+
250
+ 2. **Version and dependency management:**
251
+ - Bevy is under active development
252
+ - Be mindful of the version you are using
253
+ - Dependencies can get tangled easily
254
+ - Version mismatches can force complete rebuilds
255
+ - Stick to one Bevy version per project when possible
256
+
257
+ 3. **Crate dependencies:**
258
+ - Adding/removing dependencies triggers rebuilds
259
+ - Changing feature flags triggers rebuilds
260
+ - Plan dependency changes carefully
261
+ - Batch dependency updates when possible
262
+
263
+ **Best practices:**
264
+ - Use `cargo check` for quick validation (no binary)
265
+ - Use `cargo build --features bevy/dynamic_linking` for testing
266
+ - Only use `cargo clean` when dealing with corrupted build artifacts
267
+ - Keep a stable `Cargo.lock` for consistent builds
268
+
269
+ ## Domain-Driven Design for ECS
270
+
271
+ **Pure ECS structure demands careful data modeling.**
272
+
273
+ ### Think Before You Code
274
+
275
+ Because it's hard to search a massive list of systems in one file, you must:
276
+
277
+ 1. **Design the data model first:**
278
+ - What entities exist in your domain?
279
+ - What components do they need?
280
+ - What behaviors (systems) operate on them?
281
+ - How do components relate?
282
+
283
+ 2. **Refer to docs and existing code:**
284
+ - Check Bevy examples for similar patterns
285
+ - Review the official docs for component design
286
+ - Look at existing project code for consistency
287
+ - Understand the domain before implementing
288
+
289
+ 3. **Use bounded contexts:**
290
+ - Group related components together
291
+ - Create plugins per domain area
292
+ - Keep systems focused on single responsibilities
293
+ - Avoid cross-domain coupling
294
+
295
+ ### Example Domain Modeling Process
296
+
297
+ **Bad approach:**
298
+ ```
299
+ ❌ Start coding immediately
300
+ ❌ Add systems to one giant file
301
+ ❌ Discover missing components mid-implementation
302
+ ❌ Hard to navigate, hard to maintain
303
+ ```
304
+
305
+ **Good approach:**
306
+ ```
307
+ ✅ Define the domain (e.g., "Combat System")
308
+ ✅ List entities (Player, Enemy, Projectile)
309
+ ✅ List components (Health, Damage, Armor)
310
+ ✅ List events (DamageEvent, DeathEvent)
311
+ ✅ List systems (process_damage, check_death, spawn_projectile)
312
+ ✅ Check examples for similar implementations
313
+ ✅ Create CombatPlugin
314
+ ✅ Implement incrementally
315
+ ✅ Test at each step
316
+ ```
317
+
318
+ ### File Organization for Discoverability
319
+
320
+ ```
321
+ src/
322
+ ├── main.rs # App setup only
323
+ ├── plugins/
324
+ │ ├── mod.rs
325
+ │ ├── combat.rs # CombatPlugin
326
+ │ ├── movement.rs # MovementPlugin
327
+ │ └── inventory.rs # InventoryPlugin
328
+ ├── components/
329
+ │ ├── mod.rs
330
+ │ ├── combat.rs # Health, Armor, Damage
331
+ │ ├── movement.rs # Velocity, Speed
332
+ │ └── inventory.rs # Inventory, Item
333
+ └── events.rs # All game events
334
+ ```
335
+
336
+ **Benefits:**
337
+ - Easy to find related code
338
+ - Clear domain boundaries
339
+ - Plugin-based modularity
340
+ - Searchable by feature/domain
341
+
342
+ ## Version Management
343
+
344
+ **Bevy is under active development.**
345
+
346
+ 1. **Check your Bevy version:**
347
+ ```bash
348
+ cargo tree | grep bevy
349
+ ```
350
+
351
+ 2. **Stay on one version per project:**
352
+ - Avoid mixing Bevy versions
353
+ - Update all Bevy crates together
354
+ - Test thoroughly after version updates
355
+
356
+ 3. **API changes between versions:**
357
+ - Read the migration guide when updating
358
+ - Bevy's API evolves rapidly
359
+ - Code from older versions may not work
360
+ - Examples are version-specific
361
+
362
+ 4. **When seeking help:**
363
+ - Always mention your Bevy version
364
+ - Check if examples match your version
365
+ - Look for version-specific documentation
366
+
367
+ ## Summary Checklist
368
+
369
+ **Before implementing:**
370
+ - [ ] Check registry examples for similar features
371
+ - [ ] Design the data model (entities, components, events, systems)
372
+ - [ ] Create a plugin for the feature domain
373
+ - [ ] Review existing code for patterns
374
+
375
+ **During development:**
376
+ - [ ] Use `cargo build --features bevy/dynamic_linking`
377
+ - [ ] Avoid `cargo clean` unless necessary
378
+ - [ ] Test incrementally
379
+ - [ ] Keep systems focused and organized
380
+
381
+ **After implementation:**
382
+ - [ ] Verify the feature works
383
+ - [ ] Check for code organization issues
384
+ - [ ] Document domain-specific patterns
385
+ - [ ] Update plugin structure if needed
@@ -0,0 +1,217 @@
1
+ # Common Bevy Pitfalls Reference
2
+
3
+ ## 1. Using Old Event System in Bevy 0.17
4
+
5
+ **❌ Problem:**
6
+ ```rust
7
+ // Bevy 0.15/0.16 event system doesn't work in 0.17
8
+ #[derive(Event)]
9
+ struct MyEvent { data: String }
10
+
11
+ app.add_event::<MyEvent>()
12
+ .add_systems(Update, handle_event);
13
+
14
+ fn handle_event(mut events: EventReader<MyEvent>) { /* ... */ }
15
+ fn trigger(mut events: EventWriter<MyEvent>) { /* ... */ }
16
+ ```
17
+
18
+ **Symptoms:**
19
+ - Compilation error: `MyEvent is not a Message`
20
+ - `method 'send' not found for MessageWriter`
21
+ - `method 'read' not found for MessageReader`
22
+
23
+ **✅ Solution:**
24
+ Migrate to the observer pattern:
25
+ ```rust
26
+ // Bevy 0.17 observer pattern
27
+ #[derive(Event, Clone)] // Must derive Clone!
28
+ struct MyEvent { data: String }
29
+
30
+ app.add_observer(handle_event); // Use observer, not system
31
+
32
+ fn handle_event(
33
+ trigger: Trigger<MyEvent>, // Trigger parameter
34
+ // ... other params
35
+ ) {
36
+ let event = trigger.event();
37
+ }
38
+
39
+ fn trigger_event(mut commands: Commands) {
40
+ commands.trigger(MyEvent { data: "test".into() });
41
+ }
42
+ ```
43
+
44
+ See `references/bevy_specific_tips.md` for complete migration guide.
45
+
46
+ ## 2. Querying Material Handles in Bevy 0.17
47
+
48
+ **❌ Problem:**
49
+ ```rust
50
+ // Bevy 0.15/0.16 pattern doesn't work in 0.17
51
+ Query<&Handle<StandardMaterial>>
52
+ ```
53
+
54
+ **Symptoms:**
55
+ - `Handle<StandardMaterial> is not a Component`
56
+ - Query trait bounds not satisfied
57
+
58
+ **✅ Solution:**
59
+ Use the `MeshMaterial3d` wrapper:
60
+ ```rust
61
+ Query<&MeshMaterial3d<StandardMaterial>>
62
+
63
+ // Access handle with .0
64
+ for material_3d in query.iter() {
65
+ if let Some(material) = materials.get_mut(&material_3d.0) {
66
+ material.emissive = color;
67
+ }
68
+ }
69
+ ```
70
+
71
+ ## 3. Forgetting to Register Systems
72
+
73
+ **❌ Problem:**
74
+ ```rust
75
+ // Created system but forgot to add to app
76
+ pub fn my_new_system() { /* ... */ }
77
+ ```
78
+
79
+ **✅ Solution:**
80
+ Always add to `main.rs`:
81
+ ```rust
82
+ .add_systems(Update, my_new_system)
83
+ ```
84
+
85
+ ## 2. Borrowing Conflicts
86
+
87
+ **❌ Problem:**
88
+ ```rust
89
+ // Can't have multiple mutable borrows
90
+ mut query1: Query<&mut Transform>,
91
+ mut query2: Query<&mut Transform>, // Error!
92
+ ```
93
+
94
+ **✅ Solution:**
95
+ ```rust
96
+ // Use get_many_mut for specific entities
97
+ mut query: Query<&mut Transform>,
98
+
99
+ if let Ok([mut a, mut b]) = query.get_many_mut([entity_a, entity_b]) {
100
+ // Can mutate both
101
+ }
102
+ ```
103
+
104
+ ## 3. Infinite Loops with Events
105
+
106
+ **❌ Problem:**
107
+ ```rust
108
+ // System reads and writes same event type
109
+ fn system(
110
+ mut events: EventWriter<MyEvent>,
111
+ reader: EventReader<MyEvent>,
112
+ ) {
113
+ for event in reader.read() {
114
+ events.send(MyEvent); // Infinite loop!
115
+ }
116
+ }
117
+ ```
118
+
119
+ **✅ Solution:**
120
+ Use different event types or add termination condition.
121
+
122
+ ## 4. Not Using Changed<T>
123
+
124
+ **❌ Problem:**
125
+ ```rust
126
+ // Runs every frame for every entity
127
+ fn system(query: Query<&BigFive>) {
128
+ for traits in query.iter() {
129
+ // Expensive calculation every frame
130
+ }
131
+ }
132
+ ```
133
+
134
+ **✅ Solution:**
135
+ ```rust
136
+ // Only runs when BigFive changes
137
+ fn system(query: Query<&BigFive, Changed<BigFive>>) {
138
+ for traits in query.iter() {
139
+ // Only when needed
140
+ }
141
+ }
142
+ ```
143
+
144
+ ## 5. Entity Queries After Despawn
145
+
146
+ **❌ Problem:**
147
+ ```rust
148
+ commands.entity(entity).despawn();
149
+ // Later in same system
150
+ let component = query.get(entity).unwrap(); // Crash!
151
+ ```
152
+
153
+ **✅ Solution:**
154
+ Commands apply at end of stage. Use `Ok()` pattern:
155
+ ```rust
156
+ if let Ok(component) = query.get(entity) {
157
+ // Safe
158
+ }
159
+ ```
160
+
161
+ ## 6. Material/Asset Handle Confusion
162
+
163
+ **❌ Problem:**
164
+ ```rust
165
+ // Created material but didn't store handle
166
+ materials.add(StandardMaterial { .. }); // Handle dropped!
167
+ ```
168
+
169
+ **✅ Solution:**
170
+ ```rust
171
+ let material_handle = materials.add(StandardMaterial { .. });
172
+ commands.spawn((
173
+ MeshMaterial3d(material_handle),
174
+ // ...
175
+ ));
176
+ ```
177
+
178
+ ## 7. System Ordering Issues
179
+
180
+ **❌ Problem:**
181
+ ```rust
182
+ // UI updates before state changes
183
+ .add_systems(Update, (
184
+ update_ui,
185
+ process_input, // Wrong order!
186
+ ))
187
+ ```
188
+
189
+ **✅ Solution:**
190
+ Order systems by dependencies:
191
+ ```rust
192
+ .add_systems(Update, (
193
+ // Input processing
194
+ process_input,
195
+
196
+ // State changes
197
+ update_state,
198
+
199
+ // UI updates (reads state)
200
+ update_ui,
201
+ ))
202
+ ```
203
+
204
+ ## 8. Not Filtering Queries Early
205
+
206
+ **❌ Problem:**
207
+ ```rust
208
+ // Filter in loop (inefficient)
209
+ Query<(&A, Option<&B>, Option<&C>)>
210
+ // Then check in loop
211
+ ```
212
+
213
+ **✅ Solution:**
214
+ ```rust
215
+ // Filter in query (efficient)
216
+ Query<&A, (With<B>, Without<C>)>
217
+ ```