You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix: correct version-accuracy defects across skills and snippets
Re-verified empirically on Blender 4.5.10 LTS and 5.1.1 plus the 4.4/4.5/5.0
release notes. Four confirmed defects corrected:
1. EEVEE engine id was inverted. Correct mapping: 4.2-4.5 use
'BLENDER_EEVEE_NEXT'; 5.0+ reclaimed 'BLENDER_EEVEE' (5.0 release notes,
confirmed by introspection: 5.1.1 rejects _NEXT, 4.5.10 rejects plain).
Fixed version-branch-skeleton.py get_eevee_engine_id(), the
headless-batch-scripting detect snippet/choices/prose, and the
procedural-materials version table.
2. Slotted Actions framing and fabricated 4.5 shim. The slotted data model
shipped in 4.4 (not 5.0); legacy action.fcurves was removed in 5.0;
action_ensure_channelbag_for_slot is new in 5.0 and absent on 4.4/4.5
(no auto-detecting shim). Rewrote slotted-actions-animation: real
version-branching helper (ensure-fn on 5.0+, strip.channelbag(ensure=True)
on 4.4/4.5), removed the hasattr(action,'slots') "5.x sniff", corrected the
compatibility matrix and the snippet header comment.
3. save_pre/save handler signature. Arg0 is the file path string, not a Scene
(4.5 docs + introspection on both versions). Fixed the handler table and
worked examples in drivers-and-app-handlers and app-handler-registration.py
so handlers reach scenes via bpy.data, never treating arg0 as a Scene.
4. Geometry Nodes node version tags. For Each Element (4.3) and Mesh to SDF
Grid (4.3) were mis-tagged "5.0+"; fixed labels and changed
has_for_each_element() to gate on >= (4,3,0). NodeSocketBundle/has_bundles
left at 5.0 (confirmed: interface socket works in 5.1, TypeError in 4.5).
No content added or removed; counts unchanged (12/6/2/17). All snippets and
templates py_compile. Corrected snippets verified to run on 4.5.10 and 5.1.1.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: fOuttaMyPaint <TMhospitalitystrategies@gmail.com>
Copy file name to clipboardExpand all lines: skills/drivers-and-app-handlers/SKILL.md
+27-14Lines changed: 27 additions & 14 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -145,15 +145,17 @@ The handlers live as lists at `bpy.app.handlers.<event>`. To register, append; t
145
145
146
146
| Handler | Signature | Fires when |
147
147
| --- | --- | --- |
148
-
|`save_pre`|`(scene)` (some 4.x), `(scene, filepath)` (5.x) | Before the .blend is written. Use to clean up data you don't want serialized. |
149
-
|`save_post`|Same | After the .blend is written. Use for post-save bookkeeping. |
150
-
|`load_pre`|`(scene)`| Before a .blend is loaded. The current scene is still the old one. |
151
-
|`load_post`|`(scene)`| After a .blend is loaded. Use to validate or migrate add-on data. |
148
+
|`save_pre`|`(filepath: str)`| Before the .blend is written. The argument is the file being saved (empty string for the startup file), **not** a Scene. Use to clean up data you don't want serialized. |
149
+
|`save_post`|`(filepath: str)`| After the .blend is written. Same single filepath argument. |
150
+
|`load_pre`|`(filepath: str)`| Before a .blend is loaded. The argument is the file being loaded. |
151
+
|`load_post`|`(filepath: str)`| After a .blend is loaded. Use to validate or migrate add-on data. |
152
152
|`depsgraph_update_pre`|`(scene, depsgraph)`| Before a depsgraph evaluation pass. |
153
153
|`depsgraph_update_post`|`(scene, depsgraph)`| After a depsgraph evaluation pass. Fires very frequently; must be O(1) or near-O(1). |
154
154
|`frame_change_pre`|`(scene, depsgraph)`| Before frame is set. |
155
155
|`frame_change_post`|`(scene, depsgraph)`| After frame is set. |
156
-
|`exit_pre` (new in 5.1) |`(scene)`| Before Blender shuts down. Use for resource cleanup, telemetry flush, etc. |
156
+
|`exit_pre` (new in 5.1) |`(*args)`| Before Blender shuts down. Use for resource cleanup, telemetry flush, etc. The argument is not a Scene; accept `*args`. |
157
+
158
+
The save/load handlers (`save_pre`, `save_post`, `load_pre`, `load_post`) all receive the **file path as a string** as their single argument, **not** a Scene. (Verified empirically on 4.5.10 LTS and 5.1.1, and against `bpy.app.handlers` docs: "Accepts one argument: the file being saved/loaded.") Only the depsgraph/frame-change handlers receive `(scene, depsgraph)`.
157
159
158
160
The `exit_pre` handler in 5.1 is particularly useful for add-ons that need to release external resources (sockets, log files, child processes) deterministically before the process terminates.
159
161
@@ -165,10 +167,15 @@ from bpy.app.handlers import persistent
165
167
166
168
167
169
@persistent
168
-
defon_save_pre(scene, filepath):
169
-
"""Clear temporary cache data before save so it doesn't bloat the .blend."""
170
-
if'my_addon_cache'in scene:
171
-
del scene['my_addon_cache']
170
+
defon_save_pre(filepath):
171
+
"""Clear temporary cache data before save so it doesn't bloat the .blend.
172
+
173
+
The handler argument is the path being saved (a string), not a Scene, so
174
+
reach the scene(s) through bpy.data.
175
+
"""
176
+
for scene in bpy.data.scenes:
177
+
if'my_addon_cache'in scene:
178
+
del scene['my_addon_cache']
172
179
173
180
174
181
defregister():
@@ -201,7 +208,10 @@ from bpy.app.handlers import persistent
201
208
202
209
203
210
@persistent
204
-
defincrement_save_count(scene, filepath):
211
+
defincrement_save_count(filepath):
212
+
# save_post passes the saved file path (a string) as its only argument.
213
+
# Store the running count on the current scene.
214
+
scene = bpy.context.scene
205
215
counts = scene.get('save_counts', {})
206
216
counts[filepath] = counts.get(filepath, 0) +1
207
217
scene['save_counts'] = counts
@@ -224,8 +234,11 @@ from bpy.app.handlers import persistent
224
234
225
235
226
236
@persistent
227
-
defcleanup_on_exit(scene):
228
-
"""Release the external log file handle before the process terminates."""
237
+
defcleanup_on_exit(*args):
238
+
"""Release the external log file handle before the process terminates.
239
+
240
+
exit_pre's argument is unused here; accept *args to stay signature-proof.
241
+
"""
229
242
global _log_handle
230
243
if _log_handle isnotNone:
231
244
_log_handle.close()
@@ -250,14 +263,14 @@ The `exit_pre` handler list is new in Blender 5.1. On 4.5 LTS, fall back to OS-l
250
263
-**Doing real work inside `depsgraph_update_post`.** This handler fires on every depsgraph evaluation, which is many times per second during playback or interaction. Anything more than O(1) bookkeeping causes user-visible slowdown.
251
264
-**Recursively modifying the scene from a depsgraph handler.** The modification triggers another depsgraph evaluation, which calls the handler, which modifies the scene. Infinite loop, often manifesting as a hang.
252
265
-**Asymmetric register/unregister.** The handler is appended on register but not removed on unregister. Disabling the add-on leaves the callback in place. After enable/disable cycles, the callback runs N times per event.
253
-
-**Assuming the `save_pre`signature.**It changed across the 4.x to 5.x window. Use `(scene, filepath=None)` defensively, or `*args` if you don't need the values.
266
+
-**Treating the `save_pre`argument as a Scene.**The save/load handlers receive the **file path string** (empty for the startup file), not a Scene. Name the parameter `filepath` (or take `*args`), and reach scenes via `bpy.context.scene` / `bpy.data.scenes`. A membership test like `'key' in arg0` against the path string is silently wrong, and `del arg0['key']` raises `TypeError`.
254
267
255
268
## Version correctness
256
269
257
270
| Topic | 4.5 LTS | 5.1 stable |
258
271
| --- | --- | --- |
259
272
|`exit_pre` handler | Not available | New in 5.1; use `atexit` fallback for 4.x |
-`bpy.ops.render.render(write_still=True)` is one of the few `bpy.ops` calls that work in `--background`.
188
-
-`BLENDER_EEVEE_NEXT` is the 5.x EEVEE engine identifier. On 4.5 LTS, use `BLENDER_EEVEE`. Detect via `bpy.app.version`.
192
+
-EEVEE's engine identifier is `BLENDER_EEVEE` on Blender 5.0+ and `BLENDER_EEVEE_NEXT` on 4.2-4.5 LTS (the id was reclaimed in 5.0 after legacy EEVEE was removed in 4.2). Detect via `bpy.app.version`.
189
193
190
194
## Detecting Blender version in scripts
191
195
@@ -195,9 +199,9 @@ import bpy
195
199
major, minor, _patch = bpy.app.version
196
200
197
201
if (major, minor) >= (5, 0):
198
-
eevee_engine ='BLENDER_EEVEE_NEXT'
199
-
else:
200
202
eevee_engine ='BLENDER_EEVEE'
203
+
else:
204
+
eevee_engine ='BLENDER_EEVEE_NEXT'
201
205
```
202
206
203
207
`bpy.app.version` is a `(major, minor, patch)` tuple, always reliable.
Copy file name to clipboardExpand all lines: skills/procedural-materials-and-shaders/SKILL.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -162,7 +162,7 @@ When the same subgraph appears across multiple materials, factor it into a `Shad
162
162
| --- | --- | --- | --- |
163
163
| Principled BSDF |`ShaderNodeBsdfPrincipled`| Same | Some inputs renamed in 5.0; `Specular` -> `Specular IOR Level`. Use string lookup with the 5.x name. |
164
164
| Node group socket interface |`group.inputs.new` / `group.outputs.new`|`group.interface.new_socket`| Different APIs, see snippet `shader-node-group.py`. |
165
-
| EEVEE engine string |`'BLENDER_EEVEE'`|`'BLENDER_EEVEE_NEXT'`| EEVEE Next is the default in 5.x; legacy EEVEE was retired. |
165
+
| EEVEE engine string |`'BLENDER_EEVEE_NEXT'`|`'BLENDER_EEVEE'`|Legacy EEVEE was removed in 4.2. EEVEE Next used the id `'BLENDER_EEVEE_NEXT'` on 4.2-4.5, then reclaimed the plain `'BLENDER_EEVEE'` id in 5.0. |
166
166
| Layered Textures | Not present | Not present in 5.1 | Roadmap pushed to 2027. Do not generate code referencing it. |
167
167
168
168
EEVEE Next stabilized in Blender 5.1 with material caching and feature parity improvements; most Principled BSDF graphs render identically across EEVEE Next and Cycles.
0 commit comments