6.3 KiB
6.3 KiB
Turtle Graphics Library - AI Agent Instructions
Project Overview
Rust workspace with turtle graphics implementations. Primary focus: turtle-lib-macroquad - lightweight library using Macroquad + Lyon for GPU-accelerated rendering.
Workspace Structure
turtle/
├── turtle-lib-macroquad/ # MAIN LIBRARY - Macroquad + Lyon (focus here)
├── turtle-lib-macroquad-macros/ # Proc macro for turtle_main
├── turtle-lib/ # Legacy Bevy 0.17.1 implementation (maintenance only)
├── turtle-example/ # Legacy examples
└── turtle-ui/ # UI components
Architecture (turtle-lib-macroquad)
Core Design Pattern: Command Queue + Tweening
- Builder API (
TurtlePlan) accumulates commands - Command Queue stores execution plan
- Tween Controller interpolates between states for animation
- Lyon Tessellation converts all primitives to GPU meshes
Key Files
src/
├── lib.rs - Public API, TurtleApp (main loop), re-exports
├── builders.rs - Fluent API traits (forward/right/etc chain)
├── commands.rs - TurtleCommand enum (Move/Turn/Circle/etc)
├── execution.rs - Execute commands, update state
├── tweening.rs - Animation interpolation, speed control
├── drawing.rs - Render Lyon meshes with Macroquad
├── tessellation.rs - Lyon integration (polygons/strokes/fills/arcs)
├── state.rs - TurtleState, TurtleWorld, FillState
└── circle_geometry.rs - Arc/circle math
Critical Concepts
1. Consolidated Commands (reduces duplication):
Move(distance)- negative = backwardTurn(angle)- positive = right, negative = left (degrees)Circle{radius, angle, steps, direction}- unified left/right
2. Fill System (multi-contour with holes):
FillStatetracksVec<Vec<Vec2>>(multiple contours)pen_up()closes current contour,pen_down()opens new- Lyon's EvenOdd fill rule auto-detects holes
- Example: Donut = outer circle + inner circle (2 contours)
3. Speed Modes:
< 999: Animated with tweening>= 999: Instant execution- Controlled via
SetSpeedcommands (dynamic switching)
4. Lyon Tessellation Pipeline: All drawing → Lyon → GPU mesh → Macroquad rendering
- ~410 lines eliminated vs manual triangulation
- Functions:
tessellate_polygon/stroke/circle/arc/multi_contour
Developer Workflows
Building & Testing
# Main library
cargo build --package turtle-lib-macroquad
cargo test --package turtle-lib-macroquad
cargo clippy --package turtle-lib-macroquad -- -Wclippy::pedantic \
-Aclippy::cast_precision_loss -Aclippy::cast_sign_loss -Aclippy::cast_possible_truncation
# Run examples (15+ examples available)
cargo run --package turtle-lib-macroquad --example hello_turtle
cargo run --package turtle-lib-macroquad --example yinyang
cargo run --package turtle-lib-macroquad --example cheese_macro
Macro Crate
cargo build --package turtle-lib-macroquad-macros
Code Quality Standards
- Clippy pedantic mode enabled
- Cast warnings allowed for graphics math
- All examples must build warning-free
- Use
#[must_use]on builder methods
Project-Specific Patterns
1. The turtle_main Macro (PREFERRED for examples)
Simplest way to create turtle programs:
use turtle_lib_macroquad::*;
#[turtle_main("Window Title")]
fn draw(turtle: &mut TurtlePlan) {
turtle.forward(100.0).right(90.0);
}
Generates: window setup + render loop + quit handling (ESC/Q)
2. Import Convention
Only need: use turtle_lib_macroquad::*;
- Re-exports:
vec2,RED/BLUE/GREEN/etc, all turtle types - No
use macroquad::prelude::*needed (causes unused warnings)
3. Builder Chain Pattern
let mut t = create_turtle();
t.forward(100).right(90)
.set_pen_color(BLUE)
.circle_left(50.0, 360.0, 36)
.begin_fill()
.end_fill();
let app = TurtleApp::new().with_commands(t.build());
4. Multi-Contour Fill Example
turtle.begin_fill();
turtle.circle_left(100.0, 360.0, 72); // Outer circle
turtle.pen_up(); // Closes contour
turtle.goto(vec2(0.0, -30.0));
turtle.pen_down(); // Opens new contour
turtle.circle_left(30.0, 360.0, 36); // Inner (becomes hole)
turtle.end_fill(); // EvenOdd rule creates donut
5. Manual Setup (advanced control)
#[macroquad::main("Custom")]
async fn main() {
let mut turtle = create_turtle();
// ... drawing code ...
let mut app = TurtleApp::new().with_commands(turtle.build());
loop {
clear_background(WHITE);
app.update();
app.render();
next_frame().await;
}
}
Common Tasks
Adding New Turtle Command
- Add variant to
TurtleCommandenum incommands.rs - Implement builder method in
builders.rs(chain withself) - Add execution logic in
execution.rs - Update tessellation/rendering if needed
Adding Example
- Prefer
turtle_mainmacro for simplicity - Use only
use turtle_lib_macroquad::*; - Keep examples focused (one concept each)
- See
examples/hello_turtle.rsfor minimal template
Debugging Lyon Issues
- Enable tracing:
RUST_LOG=turtle_lib_macroquad=debug cargo run - Check
tessellation.rsfor Lyon API usage - EvenOdd fill rule: holes must have opposite winding
Dependencies & Integration
Main Dependencies
macroquad = "0.4"- Window/rendering frameworklyon = "1.0"- Tessellation (fills, strokes, circles)tween = "2.1.0"- Animation easingtracing = "0.1"- Optional logging (zero overhead when unused)
Proc Macro Crate
- Separate crate required by Rust (proc-macro = true)
- Uses
syn,quote,proc-macro2 - Generates full macroquad app boilerplate
What NOT to Do
- Don't add
use macroquad::prelude::*in examples when not required - Don't manually triangulate - use Lyon functions
- Don't add commands for Forward/Backward separately (use Move)
- Don't modify
turtle-lib(Bevy) unless specifically needed - Don't create summary/comparison docs unless requested
Key Documentation Files
README.md- Main API docsturtle-lib-macroquad/README.md- Library-specific docsturtle-lib-macroquad-macros/README.md- Macro docs
Response Style
- Be concise, no extensive summaries
- No emojis in technical responses
- Focus on code solutions over explanations
- Use bullet points for lists
- Reference specific files when helpful