# Blender Developer Tools > Skills, rules, snippets and templates that keep AI coding agents (Claude Code, Cursor) writing correct Blender Python for 5.2 LTS and 4.5 LTS, backed by runnable examples that are smoke-tested on both versions. Targets Blender 5.2 LTS with a 4.5 LTS fallback. Install as a Claude Code plugin with `/plugin marketplace add TMHSDigital/Blender-Developer-Tools@plugin-dist`, or as a Cursor local plugin from the `plugin-dist` branch. Every skill below is plain Markdown you can read directly. Full text of all skills and rules: https://tmhsdigital.github.io/Blender-Developer-Tools/llms-full.txt ## Skills - [addon-scaffolding](https://raw.githubusercontent.com/TMHSDigital/Blender-Developer-Tools/main/skills/addon-scaffolding/SKILL.md): Scaffold a Blender add-on as an Extensions Platform package: blender_manifest.toml, modular file layout, register_classes_factory, symmetric register/unregister. Use when the user starts a new add-on or extension, writes or fixes blender_manifest.toml, asks which layout or registration pattern to use on Blender 4.5 LTS or 5.x, or has classes that fail to register or unregister cleanly. Targets 5.2 LTS with 4.5 LTS fallback. - [ai-mesh-cleanup](https://raw.githubusercontent.com/TMHSDigital/Blender-Developer-Tools/main/skills/ai-mesh-cleanup/SKILL.md): Ordered cleanup for an imported generated or scanned mesh before it goes to an engine: scene units, apply rotation and scale, origin to base, recalculate normals, evaluated triangle count, decimate to a budget, convex collider. Use when the user has a GLB, glTF or FBX that is not engine-ready, mentions unit scale, unapplied transforms, triangle budget, LODs or a collision hull, or is about to run mesh operations on an import without checking its scale. Targets 5.2 LTS with 4.5 LTS fallback. - [bake-high-to-low](https://raw.githubusercontent.com/TMHSDigital/Blender-Developer-Tools/main/skills/bake-high-to-low/SKILL.md): Cage-bake high-poly surface detail onto a low-poly target as a tangent-space normal map with bpy.ops.object.bake (Cycles, selected-to-active, active Image Texture node, UV layer, save_render). Use when the user wants a normal map from a dense mesh onto a game-resolution or decimated LOD, mentions cage_extrusion or use_selected_to_active, or gets a bake that returns CANCELLED, comes out black or flat, or fails with 'No active UV layer found'. Targets 5.2 LTS with 4.5 LTS fallback. - [bl-info-migration](https://raw.githubusercontent.com/TMHSDigital/Blender-Developer-Tools/main/skills/bl-info-migration/SKILL.md): Migrate a legacy bl_info add-on to the Extensions Platform in three steps, with a before/after diff and the dual-format pattern. Use when the user has a bl_info dictionary in __init__.py, asks whether bl_info is deprecated or still supported, wants to publish to extensions.blender.org or ship an extension .zip, or sees warnings about legacy add-ons at install time. Targets 5.2 LTS; manifests work from 4.2. - [custom-properties](https://raw.githubusercontent.com/TMHSDigital/Blender-Developer-Tools/main/skills/custom-properties/SKILL.md): Define and bind custom properties with bpy.props annotations, PropertyGroup and PointerProperty, and choose where to store them (Scene, Object, WindowManager, AddonPreferences). Use when the user attaches settings or data to datablocks so it survives save and load, is unsure where add-on settings belong, or writes a property as an assignment instead of an annotation and gets a deprecation warning or a _PropertyDeferred value. Targets 5.2 LTS. - [depsgraph-and-evaluated-data](https://raw.githubusercontent.com/TMHSDigital/Blender-Developer-Tools/main/skills/depsgraph-and-evaluated-data/SKILL.md): Read the evaluated geometry the user actually sees through the dependency graph instead of raw obj.data: evaluated_depsgraph_get, evaluated_get, to_mesh and to_mesh_clear lifetimes. Use when the user writes an exporter, measurement or inspection script, reports that modifiers, shape keys, armatures or geometry nodes are missing from exported or measured geometry, or reads obj.data.vertices and gets the undeformed base mesh. Targets 5.2 LTS. - [drivers-and-app-handlers](https://raw.githubusercontent.com/TMHSDigital/Blender-Developer-Tools/main/skills/drivers-and-app-handlers/SKILL.md): Drive properties from expressions with the Driver API (driver_add, driver_namespace for custom Python functions) and react to events with bpy.app.handlers (load_post, save_pre, frame_change_post, depsgraph_update_post, exit_pre in 5.1+). Use when the user wants one property to follow another, runs code on load, save, frame change or exit, or has a driver failing with NameError or the Python security block, including drivers that die after reopening a file. - [engine-export-presets](https://raw.githubusercontent.com/TMHSDigital/Blender-Developer-Tools/main/skills/engine-export-presets/SKILL.md): Export presets for Unity, Godot and Unreal. glTF is +Y up and meters by spec, so every engine gets export_yup=True with no scale bake (Unreal converts to centimeters on import); FBX takes axis_forward/axis_up plus global_scale. Use when the user exports for a game engine, mentions export_yup, axis_forward, axis_up, global_scale, Y-up or centimeters, passes FBX axis kwargs to export_scene.gltf, or gets a model that imports lying on its back or 100x too large. Targets 5.2 LTS with 4.5 LTS fallback. - [extension-runtime-and-packaging](https://raw.githubusercontent.com/TMHSDigital/Blender-Developer-Tools/main/skills/extension-runtime-and-packaging/SKILL.md): Ship and run a Blender extension after its first install: bundled wheels, user data that survives upgrades via bpy.utils.extension_path_user, the network permission and bpy.app.online_access, bl_ext package names, and blender --command extension validate/build/server-generate in CI. Use when the user bundles third-party Python packages, pip-installs into Blender's Python, writes files next to __file__, needs a settings or cache directory, makes network calls from an add-on, or builds and publishes extension zips. Targets 5.2 LTS with 4.5 LTS fallback. - [geometry-nodes-python](https://raw.githubusercontent.com/TMHSDigital/Blender-Developer-Tools/main/skills/geometry-nodes-python/SKILL.md): Build Geometry Nodes trees from Python: node_groups.new, tree.interface sockets, nodes by RNA identifier, links, Repeat and for-each zones, Bundles, and applying the tree as a NODES modifier including the 5.1 vs 5.2 modifier input API. Use when the user generates a GeometryNodeTree in a script, sets modifier inputs from Python, or hits 'Node type ... undefined' or socket identifier errors. Targets 5.2 LTS with 4.5 LTS fallback. - [headless-batch-scripting](https://raw.githubusercontent.com/TMHSDigital/Blender-Developer-Tools/main/skills/headless-batch-scripting/SKILL.md): Run Blender unattended with blender --background --python, arguments after the -- separator, --factory-startup and --python-exit-code, and temp_override for operators that need context. Use when the user renders, exports or processes .blend files from a CLI, CI job or batch script, passes arguments to a Blender script, or hits 'poll() failed, context is incorrect' or a job that exits 0 despite a Python traceback. Targets 5.2 LTS with 4.5 LTS fallback. - [mesh-editing-and-bmesh](https://raw.githubusercontent.com/TMHSDigital/Blender-Developer-Tools/main/skills/mesh-editing-and-bmesh/SKILL.md): Create, edit and read meshes efficiently: when to use bpy.data, bpy.ops or bmesh, the bmesh.new / try / finally / free pattern, foreach_get and foreach_set for bulk data, and evaluated meshes for modifier results. Use when the user writes mesh-generating or mesh-editing Python, mentions bmesh, from_pydata, foreach_set or mesh.vertices, has a slow script looping over bpy.ops.mesh or per-vertex assignments, or a bmesh script that misbehaves on its second run. Targets 5.2 LTS. - [operators](https://raw.githubusercontent.com/TMHSDigital/Blender-Developer-Tools/main/skills/operators/SKILL.md): Author bpy.types.Operator classes: bl_idname naming, poll / invoke / execute / modal lifecycle, bl_options (REGISTER, UNDO, INTERNAL, BLOCKING), operator properties and defensive context handling. Use when the user creates an operator for a button, menu, keymap or script, asks why its properties are missing from the Adjust Last Operation (redo) panel or why Ctrl-Z ignores it, or gets poll failures or None context objects. Targets 5.2 LTS with 4.5 LTS compatibility. - [procedural-materials-and-shaders](https://raw.githubusercontent.com/TMHSDigital/Blender-Developer-Tools/main/skills/procedural-materials-and-shaders/SKILL.md): Build materials and shader node graphs from Python: bpy.data.materials, node_tree, Principled BSDF and its 4.0+ socket names, default values, links and shader node groups, for EEVEE and Cycles. Use when the user creates or edits materials in a script, generates many material variations, hits a KeyError on a Principled BSDF input such as Specular or Emission, or asks about EEVEE vs Cycles differences or the deferred Layered Textures system. Targets 5.2 LTS. - [slotted-actions-animation](https://raw.githubusercontent.com/TMHSDigital/Blender-Developer-Tools/main/skills/slotted-actions-animation/SKILL.md): Create and edit animation from Python under Slotted Actions (Blender 4.4+): Action, slots, layers, strips, channelbags. Bind the action slot, then reach F-curves through a channelbag; action_ensure_channelbag_for_slot exists only on 5.0+, so use strip.channelbag(slot, ensure=True) on 4.5 LTS. Use when the user inserts keyframes or builds F-curves in a script, hits AttributeError on action.fcurves in 5.x, or has keys that exist but never play back. Targets 5.2 LTS with 4.5 LTS fallback. - [timers-modal-and-threading](https://raw.githubusercontent.com/TMHSDigital/Blender-Developer-Tools/main/skills/timers-modal-and-threading/SKILL.md): Run long or repeated work in a Blender add-on without freezing or crashing it: bpy.app.timers return values and persistent=True, modal operators driven by event_timer_add, and worker threads that hand results to the main thread through a queue. Use when the user polls, animates or downloads from an add-on, calls bpy from a thread, writes a modal operator, sees a timer never fire in --background, or loses a timer after opening a file. Targets 5.2 LTS with 4.5 LTS fallback. - [ui-panels](https://raw.githubusercontent.com/TMHSDigital/Blender-Developer-Tools/main/skills/ui-panels/SKILL.md): Author bpy.types.Panel UI: bl_space_type, bl_region_type, bl_category sidebar tabs, declarative draw(), layout row, column and split, sub-panels, and conditional UI with enabled and active. Use when the user adds an N-panel tab or properties-editor panel, exposes add-on properties or operator buttons, or has a panel that does not appear, shows the wrong labels or warns about a missing _PT_ in its bl_idname. Targets 5.2 LTS. - [vse-python](https://raw.githubusercontent.com/TMHSDigital/Blender-Developer-Tools/main/skills/vse-python/SKILL.md): Build and inspect Video Sequence Editor timelines from Python: SequenceEditor.strips vs the removed .sequences, new_effect length vs frame_end, strip transforms, and the 5.2 COLOR strip width/height bake from scene resolution. Use when the user scripts the sequencer, hits AttributeError on sequence_editor.sequences in 5.x or a TypeError on new_effect keyword arguments, or renders COLOR strips that ignore transform scale after a resolution change. Targets 5.2 LTS with 4.5 LTS fallback. ## Rules - [always-free-bmesh](https://raw.githubusercontent.com/TMHSDigital/Blender-Developer-Tools/main/rules/always-free-bmesh.mdc): Flag bmesh.new() calls without a paired bm.free() in a try/finally block. Blender frees an unreferenced BMesh only when its Python wrapper dies, which a traceback, global, closure or modal operator can delay for the whole session; an explicit free() in finally releases it deterministically. - [no-unapplied-modifiers-on-export](https://raw.githubusercontent.com/TMHSDigital/Blender-Developer-Tools/main/rules/no-unapplied-modifiers-on-export.mdc): Flag an export call on objects that still carry unapplied modifiers when the export arguments do not request evaluated geometry. The engine then receives the authored cage, not the modifier result. - [prefer-data-over-ops-in-loops](https://raw.githubusercontent.com/TMHSDigital/Blender-Developer-Tools/main/rules/prefer-data-over-ops-in-loops.mdc): Flag bpy.ops.* calls inside iteration over many objects, meshes, or frames. Each bpy.ops call triggers a full depsgraph evaluation and UI redraw; loops slow down by orders of magnitude. Use bpy.data.* and bmesh instead. - [prefer-temp-override-over-context-copy](https://raw.githubusercontent.com/TMHSDigital/Blender-Developer-Tools/main/rules/prefer-temp-override-over-context-copy.mdc): Flag uses of `bpy.context.copy()` to override context for an operator call. Passing a context dict to an operator was deprecated in Blender 3.2 and removed in 4.0, so it already fails on the 4.5 LTS fallback. Use `bpy.context.temp_override(**overrides)` as a context manager instead. - [target-extensions-platform-format](https://raw.githubusercontent.com/TMHSDigital/Blender-Developer-Tools/main/rules/target-extensions-platform-format.mdc): Flag new Blender add-ons that ship only a legacy bl_info dict without a blender_manifest.toml. New add-ons must use the Extensions Platform format. bl_info may appear alongside as a fallback for backward compatibility, but the manifest is the source of truth. - [type-annotate-props-and-defend-context](https://raw.githubusercontent.com/TMHSDigital/Blender-Developer-Tools/main/rules/type-annotate-props-and-defend-context.mdc): Flag two related anti-patterns. (1) bpy.props defined as class-level assignments instead of type annotations (deprecated since 2.8). (2) Code that touches bpy.context.active_object without guarding for None, or that assumes the active object is selected. - [use-correct-axis-rna-per-exporter](https://raw.githubusercontent.com/TMHSDigital/Blender-Developer-Tools/main/rules/use-correct-axis-rna-per-exporter.mdc): Flag export_scene.gltf calls that pass FBX axis_forward or axis_up, and export_scene.fbx calls that pass glTF export_yup. The two exporters do not share axis RNA. - [use-foreach-set-for-bulk-data](https://raw.githubusercontent.com/TMHSDigital/Blender-Developer-Tools/main/rules/use-foreach-set-for-bulk-data.mdc): Flag Python loops that set vertex coordinates, normals, UVs, or other bulk per-element data one element at a time. For meshes of more than a few thousand elements, this is 100x to 1000x slower than `mesh.vertices.foreach_set("co", flat_array)`, which writes through to C-level storage in one pass. - [validate-imported-mesh-scale](https://raw.githubusercontent.com/TMHSDigital/Blender-Developer-Tools/main/rules/validate-imported-mesh-scale.mdc): Flag a glTF or FBX import followed by mesh operations with no transform_apply and no unit-scale check. Generated files often arrive with non-identity object scale or a non-meter scene scale; mesh edits then bake the wrong size. ## Examples - [Examples gallery](https://tmhsdigital.github.io/Blender-Developer-Tools/gallery/): runnable headless scripts, each asserting one API contract and exiting non-zero when it breaks, smoke-tested on 5.2 LTS and 4.5 LTS - [examples/](https://github.com/TMHSDigital/Blender-Developer-Tools/tree/main/examples): source of every example ## Optional - [snippets/](https://github.com/TMHSDigital/Blender-Developer-Tools/tree/main/snippets): small standalone patterns - [templates/](https://github.com/TMHSDigital/Blender-Developer-Tools/tree/main/templates): add-on, headless batch and asset-pipeline starters - [Rules summary for Claude Code](https://raw.githubusercontent.com/TMHSDigital/Blender-Developer-Tools/main/claude/blender-rules.md)