Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .cursor-plugin/plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"skills/bake-high-to-low/SKILL.md",
"skills/engine-export-presets/SKILL.md",
"skills/extension-runtime-and-packaging/SKILL.md",
"skills/timers-modal-and-threading/SKILL.md",
"skills/operators/SKILL.md",
"skills/ui-panels/SKILL.md",
"skills/custom-properties/SKILL.md",
Expand Down
4 changes: 2 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ a `.cursor-plugin/plugin.json` manifest so the ecosystem drift checker
classifies it as a `cursor-plugin`. This is content the AI loads when the user
asks Blender questions or works on Blender add-ons in Cursor or Claude Code.

The content base is 17 skills, 9 rules, 3 templates, 28 snippets, 65
The content base is 18 skills, 9 rules, 3 templates, 29 snippets, 66
examples, and 76 showcase pieces (counts are CI-enforced against README.md)
and the manifest). The full inventory tables and per-item purposes live in
`CLAUDE.md`. Example anatomy and authoring rules: copy `examples/bmesh-gear/`;
Expand All @@ -32,7 +32,7 @@ in `docs/VISUAL-STYLE.md`; the canonical run prompt is

```
Blender-Developer-Tools/
skills/<skill-name>/SKILL.md # 17 skill files
skills/<skill-name>/SKILL.md # 18 skill files
rules/<rule-name>.mdc # 9 rule files
templates/<template-name>/ # 3 starter templates
snippets/<snippet-name>.py # 27 standalone Python snippets
Expand Down
19 changes: 10 additions & 9 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ The **Blender Developer Tools** repository is at **v0.145.0**. It packages skill
## Repository Architecture

```
skills/<skill-name>/SKILL.md - AI workflow definitions, 17 total
skills/<skill-name>/SKILL.md - AI workflow definitions, 18 total
rules/<rule-name>.mdc - Anti-pattern rules, 9 total
templates/<template-name>/ - Starter projects, 3 total
snippets/<snippet-name>.py - Standalone code patterns, 28 total
examples/<name>/ - Runnable smoke-gated examples, 65 total (+ gallery.json)
snippets/<snippet-name>.py - Standalone code patterns, 29 total
examples/<name>/ - Runnable smoke-gated examples, 66 total (+ gallery.json)
showcase/<name>/ - Budget-conformance props, 76 pieces, each with a gallery `category` (sibling of examples/; see showcase/README.md § Categories)
scripts/build_gallery.py - Regenerates docs/gallery/ from examples/gallery.json + showcase/gallery.json
scripts/site/ - Vendored landing-page build (Jinja2); tokens.css is the shared palette
Expand All @@ -30,7 +30,7 @@ docs/gallery/ - Committed generated gallery pages + hero render
VERSION - Source of truth for the repo version
```

## Skills (17)
## Skills (18)

| Skill | Purpose |
| --- | --- |
Expand All @@ -51,6 +51,7 @@ VERSION - Source of truth for the repo version
| bl-info-migration | Three-step migration from legacy `bl_info` to Extensions Platform, dual-format pattern |
| vse-python | VSE timeline from Python: `.strips` vs `.sequences`, `new_effect` kwargs, 5.2 COLOR `width`/`height` bake |
| extension-runtime-and-packaging | Bundled wheels, `extension_path_user` data that survives upgrades, `online_access`, `bl_ext` names, `--command extension` build in CI |
| timers-modal-and-threading | `bpy.app.timers` return values and `persistent`, modal operators on `event_timer_add`, worker thread + queue + main-thread drain, no timers in `--background` |

## Rules (9)

Expand Down Expand Up @@ -96,7 +97,7 @@ matching its `globs` does. Changing a glob changes when the rule fires.
- Unity / Godot / Unreal glTF export via the engine-export-presets contract
- Explicit exit codes matching `headless-batch-script-template` (0, then 2+)

## Snippets (28)
## Snippets (29)

Small standalone `.py` files at `snippets/<name>.py`, each 5 to 75 lines.

Expand All @@ -106,15 +107,15 @@ v0.2.0: Principled BSDF material, driver-with-custom-function via `driver_namesp

AI asset pipeline track: `decimate_to_budget.py`, `convex_hull_collider.py`, `lod_chain.py` (helper duplicated, not imported), `gltf_draco_export.py`, `export_preset_unity.py`, `export_preset_godot.py`, `export_preset_unreal.py`, `setup_bake_target_image.py`, `bake_normal_high_to_low.py`, `save_baked_image.py`.

Extensions runtime: `extension-user-data.py` (`extension_path_user` settings file and an `online_access` guard).
Extensions runtime: `extension-user-data.py` (`extension_path_user` settings file and an `online_access` guard). Long-running work: `thread-queue-timer.py` (worker thread, `queue.Queue`, main-thread drain timer).

## Examples (65)
## Examples (66)

Runnable scripts at `examples/<name>/`, each asserting a real API contract with
deterministic checks (exit non-zero on failure) and optionally rendering a still via
`--output`. All of them run headless on Blender 5.2 LTS and 4.5 LTS in `blender-smoke.yml` (5.1 on the weekly cron, the `needs-5.1` PR label, or manual dispatch);
**56 of the 65 ship a render in the site gallery** at `docs/gallery/`. The other
nine are **check-only**: they carry no `--output` path, no gallery entry, and no
**56 of the 66 ship a render in the site gallery** at `docs/gallery/`. The other
ten are **check-only**: they carry no `--output` path, no gallery entry, and no
hero asset. The criterion is whether the contract is expressible in pixels. An
example is check-only when its witness is a data or state fact that no scene
redesign can make visible — a datablock name, an RNA attribute's presence, a
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ The drift-check workflow enforces these on every push and PR.

## Aggregate Counts

`README.md` declares aggregate counts (e.g. "17 skills, 9 rules, 3 templates, 28 snippets, 65 examples, and 76 showcase pieces"). The `validate-counts` job in `.github/workflows/validate.yml` enforces these substrings against the filesystem on every push and PR. Showcase pieces are counted separately from examples. When you add or remove content, update the README counts in the same commit.
`README.md` declares aggregate counts (e.g. "18 skills, 9 rules, 3 templates, 29 snippets, 66 examples, and 76 showcase pieces"). The `validate-counts` job in `.github/workflows/validate.yml` enforces these substrings against the filesystem on every push and PR. Showcase pieces are counted separately from examples. When you add or remove content, update the README counts in the same commit.

## Pull Request Process

Expand Down
18 changes: 9 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
</p>

<p align="center">
<strong>17 skills</strong> &nbsp;&bull;&nbsp; <strong>9 rules</strong> &nbsp;&bull;&nbsp; <strong>3 templates</strong> &nbsp;&bull;&nbsp; <strong>28 snippets</strong> &nbsp;&bull;&nbsp; <strong>65 examples</strong> &nbsp;&bull;&nbsp; <strong>76 showcase pieces</strong>
<strong>18 skills</strong> &nbsp;&bull;&nbsp; <strong>9 rules</strong> &nbsp;&bull;&nbsp; <strong>3 templates</strong> &nbsp;&bull;&nbsp; <strong>29 snippets</strong> &nbsp;&bull;&nbsp; <strong>66 examples</strong> &nbsp;&bull;&nbsp; <strong>76 showcase pieces</strong>
</p>

<p align="center">
Expand All @@ -44,7 +44,7 @@

## Overview

This repository ships **17 skills, 9 rules, 3 templates, 28 snippets, 65 examples, and 76 showcase pieces** for Blender Python development targeting Blender 5.2 LTS (current stable) with Blender 4.5 LTS fallback support. Blender 5.1 is prior stable.
This repository ships **18 skills, 9 rules, 3 templates, 29 snippets, 66 examples, and 76 showcase pieces** for Blender Python development targeting Blender 5.2 LTS (current stable) with Blender 4.5 LTS fallback support. Blender 5.1 is prior stable.

The content is consumed by AI coding agents reading these files directly from a checkout — **there is no MCP server in this repository, and none is required**. Both agents install it as a plugin (see [Quick start](#quick-start)): Cursor loads the skills and applies `rules/*.mdc` wherever their scope globs match; Claude Code loads the skills and gets the rules through a generated `blender-rules` skill, since it does not read Cursor `.mdc` files. An agent picks a skill up when its description matches the task. Any agent that can read files in a workspace can use it the same way. There is no build step for the content — edit the Markdown and Python files directly.

Expand All @@ -63,14 +63,14 @@ The content is consumed by AI coding agents reading these files directly from a
git clone https://github.com/TMHSDigital/Blender-Developer-Tools.git
```

- **Cursor** — install it as a local plugin from the slim `plugin-dist` branch, then run **Developer: Reload Window**. **Customize** lists the 17 skills and 9 rules; the rules apply by glob scope and the agent loads a skill when its description matches the task.
- **Cursor** — install it as a local plugin from the slim `plugin-dist` branch, then run **Developer: Reload Window**. **Customize** lists the 18 skills and 9 rules; the rules apply by glob scope and the agent loads a skill when its description matches the task.

```bash
git clone --branch plugin-dist --single-branch https://github.com/TMHSDigital/Blender-Developer-Tools.git ~/.cursor/plugins/local/blender-developer-tools
```

(On Windows the folder is `%USERPROFILE%\.cursor\plugins\local\`. Cursor skips symlinks that point outside that folder, so clone or copy rather than link.) Teams can import the repository as a team marketplace instead; it carries `.cursor-plugin/marketplace.json`. For one project only, copy `skills/*` into the project's `.cursor/skills/` and `rules/*.mdc` into `.cursor/rules/` from a checkout. Copying only the rules gives you no skills.
- **Claude Code** — install as a plugin, then run `/skills` to see all 17 skills plus `blender-rules`:
- **Claude Code** — install as a plugin, then run `/skills` to see all 18 skills plus `blender-rules`:

```text
/plugin marketplace add TMHSDigital/Blender-Developer-Tools@plugin-dist
Expand Down Expand Up @@ -105,7 +105,7 @@ Releases ship often; [CHANGELOG.md](CHANGELOG.md) lists what each one changed.

## Falsifiers

Every one of the 65 examples carries a **falsifier**: a flag that changes the
Every one of the 66 examples carries a **falsifier**: a flag that changes the
input so a real assertion fails. It never disables the assertion, skips the
check, or short-circuits to an error — it feeds the script something the
contract says must not pass, and the same check that guards the happy path
Expand Down Expand Up @@ -133,7 +133,7 @@ per-script exit-code model, are in

## Examples and showcase

**65 examples** in [`examples/`](examples/) are runnable, self-checking scripts: each asserts one API contract, carries a falsifier, and runs headless on Blender 5.2 LTS and 4.5 LTS in the `blender-smoke` workflow (5.1 on the weekly cron or by manual dispatch). Those whose contract is visible also render a still. **76 showcase pieces** in [`showcase/`](showcase/) exist to show the skills working together at production scale: each is a single headless script that models a game prop, then runs it through the same cleanup, bake, LOD, collider and export steps the skills teach, and fails if a measured budget (triangle counts, colliders, materials, real-world size) is missed. They are not API examples. Conventions: [`showcase/README.md`](showcase/README.md).
**66 examples** in [`examples/`](examples/) are runnable, self-checking scripts: each asserts one API contract, carries a falsifier, and runs headless on Blender 5.2 LTS and 4.5 LTS in the `blender-smoke` workflow (5.1 on the weekly cron or by manual dispatch). Those whose contract is visible also render a still. **76 showcase pieces** in [`showcase/`](showcase/) exist to show the skills working together at production scale: each is a single headless script that models a game prop, then runs it through the same cleanup, bake, LOD, collider and export steps the skills teach, and fails if a measured budget (triangle counts, colliders, materials, real-world size) is missed. They are not API examples. Conventions: [`showcase/README.md`](showcase/README.md).

Browse both, with filters, full-size renders and each script's README, in the **[gallery](https://tmhsdigital.github.io/Blender-Developer-Tools/gallery/)**.

Expand All @@ -151,11 +151,11 @@ Browse both, with filters, full-size renders and each script's README, in the **
## How content is organized

```
skills/<name>/SKILL.md - 17 skill files, YAML frontmatter, one canonical pattern each
skills/<name>/SKILL.md - 18 skill files, YAML frontmatter, one canonical pattern each
rules/<name>.mdc - 9 rule files, anti-pattern + correction
templates/<name>/ - 3 template directories (extension-addon-template, headless-batch-script-template, ai-asset-pipeline-template)
snippets/<name>.py - 28 standalone Python snippets, 5 to 75 lines each
examples/<name>/ - 65 example directories: script, README with exit codes and falsifier
snippets/<name>.py - 29 standalone Python snippets, 5 to 75 lines each
examples/<name>/ - 66 example directories: script, README with exit codes and falsifier
showcase/<name>/ - 76 showcase pieces: budget-gated game props, script and README
claude/ - generated Claude Code copies of the rules (blender-rules skill + import file)
```
Expand Down
2 changes: 1 addition & 1 deletion docs/new-example-prompt.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ metadata — so the render would be identical whether the API held or broke. The
"redesign the scene until failure would be visible" instruction above is the test:
attempt it first, and only when it cannot succeed in principle does the example
become check-only. The exception is for contracts that are invisible, not for
renders that are hard. Nine of the 65 examples currently qualify, and `CLAUDE.md`
renders that are hard. Ten of the 66 examples currently qualify, and `CLAUDE.md`
carries the same rule. A check-only example is otherwise a full example: it still
asserts a real contract, still exits non-zero on failure, still carries a falsifier,
and still takes a `tests/smoke/catalog.json` row so it runs on every PR.
Expand Down
38 changes: 38 additions & 0 deletions examples/index.json
Original file line number Diff line number Diff line change
Expand Up @@ -1901,6 +1901,44 @@
"13": "`--output`: bundled `datafiles/fonts/Inter.woff2` not found"
}
},
{
"name": "timers-modal-threading",
"path": "examples/timers-modal-threading/",
"script": "examples/timers-modal-threading/timers_modal_threading.py",
"skills": [
"operators",
"timers-modal-and-threading"
],
"render": false,
"min_version": "4.5",
"run": "blender --background --python examples/timers-modal-threading/timers_modal_threading.py",
"summary": "Proves the event-loop contracts behind long-running add-on work.",
"falsifiers": [
{
"args": [
"--return-zero-once"
],
"expect_exit": 5
},
{
"args": [
"--non-persistent"
],
"expect_exit": 8
}
],
"exit_codes": {
"0": "Success",
"1": "Uncaught exception (FATAL wrapper)",
"2": "argparse / usage",
"3": "`--background` child failed, or its timer ran",
"4": "Windowed child wrote no result",
"5": "Timer return values not honoured (`--return-zero-once` lands here)",
"6": "Worker result not applied once on the main thread",
"7": "Modal operator did not finish and remove its timer",
"8": "File load did not keep only the persistent timer (`--non-persistent` lands here)"
}
},
{
"name": "triangulate-tangents",
"path": "examples/triangulate-tangents/",
Expand Down
1 change: 1 addition & 0 deletions examples/skills.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
"solidify-even-thickness": ["depsgraph-and-evaluated-data", "mesh-editing-and-bmesh"],
"swatch-grid": ["procedural-materials-and-shaders"],
"temp-override-join": ["headless-batch-scripting", "operators"],
"timers-modal-threading": ["operators", "timers-modal-and-threading"],
"text-version-stamp": [],
"triangulate-tangents": ["mesh-editing-and-bmesh"],
"turntable": ["slotted-actions-animation"],
Expand Down
Loading
Loading