5.0 KiB
5.0 KiB
Contributor and Agent Guide
This repository contains Blender extensions and standalone asset-pipeline tools. For Blender work, start with the extension authoring guide, then use the API notes and the testing and release guide as needed.
Repository map
blender/<extension_id>/: one installable Blender extension per directory. Each extension root containsblender_manifest.tomland__init__.py.blender/tests/: headless Blender smoke tests. These run inside Blender's bundled Python, not ordinary system Python.blender/scripts/: focused helpers for the current extension.tools/: standalone tools that do not need to run inside Blender.dist/: generated extension ZIP packages. Do not hand-edit them.build-all.sh: discover and package every manifest underblender/.install-all.sh/install-all.bat: build, install, and enable every extension for the current Blender user.
Rules for Blender extensions
- Use the Blender Extensions format introduced in Blender 4.2. Do not add a
legacy
bl_infodictionary. Metadata belongs inblender_manifest.toml. - Keep each extension self-contained. Use relative imports inside its package.
Bundle third-party dependencies as wheels and list them in the manifest;
never run
pipfrom an enabled extension. - Treat the installed extension directory as read-only. Persistent extension
data belongs under
bpy.utils.extension_path_user(__package__, ...). - Declare
files,network,clipboard,camera, ormicrophonepermissions in the manifest whenever the extension uses them. Network code must also respectbpy.app.online_access. - Register Blender classes in dependency order and unregister them in reverse.
Delete properties added to
bpy.typesduringunregister()and remove every handler, timer, menu callback, preview collection, and keymap item created byregister(). - Operators must have a useful
poll(), use their passedcontext, report actionable failures, and return{'FINISHED'}or{'CANCELLED'}correctly. - Prefer Blender's data API over
bpy.ops. When an operator is necessary, make its context, selection, active object, object mode, and render engine requirements explicit. - Preserve user state. Snapshot and restore temporary selection, active object,
mode, render settings, material assignments, and temporary data in
finally. Do not rely on Undo to reverse file writes or external side effects. - Never mutate shared mesh or material data merely to simplify processing. Copy it, operate on the copy, and clean it up unless a persistent result is an explicit feature.
- Avoid hard-coded repository namespaces such as
bl_ext.user_default. An extension may be installed from another repository; use__package__and relative imports.
Adding an extension
- Create
blender/<extension_id>/blender_manifest.tomland__init__.py. - Use a lowercase snake-case manifest
id; keep operator IDs and registered class names uniquely prefixed. - Set a truthful
blender_version_min, semanticversion, SPDX license, and only the permissions actually required. - Add a deterministic smoke test under
blender/tests/. It must create its own scene data, exercise the public operator or API, assert the result, and check that temporary data and global state are restored. - Add the test to
blender/scripts/test.shor replace that helper with a test dispatcher when a second extension needs its own Blender process. - Document the user workflow in
README.mdor a focused file underdocs/. - Run the completion checks below.
Required completion checks
For any changed Blender extension, run checks proportional to the change. The minimum for code changes is:
./blender/scripts/test.sh
blender --factory-startup --command extension validate blender/<extension_id>
./build-all.sh
blender --factory-startup --command extension validate dist/<id>-<version>.zip
For registration, packaging, dependency, or manifest changes, also test the built package in an isolated Blender user profile and confirm the enabled extension is loaded. See Testing and releasing.
Before declaring success:
- Test both the successful path and at least one important validation/failure path.
- Confirm the original scene state is preserved unless the feature documents a persistent change.
- Confirm no temporary objects, meshes, materials, images, handlers, or files survive unexpectedly.
- Rebuild the ZIP after the final source edit; a previously built package is not evidence for the current source.
- Bump the manifest version for a user-visible release.
Standalone tools
Code under tools/ runs in ordinary Python. Keep its dependencies in
tools/requirements.txt, provide a helpful error when a dependency is absent,
and test with ./tools/test.sh. Standalone tools must not import bpy.