Blender Python Add-on Rules
Add-on Structure
- Keep add-on entry points in
__init__.pywith clearregister()andunregister()functions. - Group operators, panels, properties, preferences, and utilities into separate modules for non-trivial add-ons.
- Use
bl_infoorblender_manifest.tomlaccording to the Blender version and packaging target. - Keep UI labels concise and user-facing text translatable where appropriate.
API Usage
- Use
bpy.types.Operatorfor actions,bpy.types.Panelfor UI, andbpy.types.PropertyGroupfor grouped settings. - Define
bl_idname,bl_label, andbl_optionsexplicitly. - Validate context in
poll()before enabling operators. - Use
invoke()for interactive setup andexecute()for the actual operation. - Return
{'FINISHED'}or{'CANCELLED'}consistently. - Use dependency graph updates and evaluated objects when reading final scene state.
Data and Properties
- Register custom properties through
PropertyGroupclasses instead of loose global state. - Store add-on preferences in
AddonPreferences. - Use
PointerProperty,CollectionProperty, and typed properties with names and descriptions. - Clean up custom properties and handlers during
unregister().
Safety and Performance
- Do not run destructive scene operations without explicit user action.
- Avoid blocking UI work in modal operators; use timers or modal state machines for long operations.
- Batch mesh changes and use
bmeshwhen editing mesh data programmatically. - Avoid repeatedly scanning large scenes in draw methods.
- Keep file paths configurable and use Blender path utilities.
Testing and Debugging
- Test scripts in a clean Blender profile and a representative production scene.
- Add smoke tests that import the add-on, register it, run core operators, and unregister cleanly.
- Log actionable messages with
self.report()for user-facing operator feedback. - Keep version-specific API differences isolated behind helper functions.
Common Mistakes
- Do not forget to unregister classes, handlers, timers, and keymaps.
- Do not mutate Blender data from panel
draw()methods. - Do not assume an active object, selected object, or mode without checking context.
- Do not hardcode absolute asset paths.