<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Zalogin Aleksei</title>
    <description>The latest articles on DEV Community by Zalogin Aleksei (@sicksect).</description>
    <link>https://dev.to/sicksect</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4093597%2F155e80f1-9f61-4b6a-bfc3-7de2124a9e1a.jpg</url>
      <title>DEV Community: Zalogin Aleksei</title>
      <link>https://dev.to/sicksect</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sicksect"/>
    <language>en</language>
    <item>
      <title>My 3D tool turned a scanned face into a mess. The tool wasn't the problem.</title>
      <dc:creator>Zalogin Aleksei</dc:creator>
      <pubDate>Mon, 02 Nov 2026 20:19:06 +0000</pubDate>
      <link>https://dev.to/sicksect/my-3d-tool-turned-a-scanned-face-into-a-mess-the-tool-wasnt-the-problem-562i</link>
      <guid>https://dev.to/sicksect/my-3d-tool-turned-a-scanned-face-into-a-mess-the-tool-wasnt-the-problem-562i</guid>
      <description>&lt;h1&gt;
  
  
  My 3D tool turned a scanned face into a mess. The tool wasn't the problem.
&lt;/h1&gt;

&lt;p&gt;I wrote a button that rebuilds a 3D model with fewer polygons — a normal step&lt;br&gt;
before a model goes into a game. Then I pointed it at a scanned head and got&lt;br&gt;
something I wouldn't show anyone.&lt;/p&gt;

&lt;p&gt;Three things were wrong, and none of them was the button itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. The head wasn't one model
&lt;/h2&gt;

&lt;p&gt;It was 93 separate pieces, and many of them were open at the edges. The button&lt;br&gt;
treated all of them as one surface, pulled the new mesh onto that surface, and&lt;br&gt;
the result came out smeared.&lt;/p&gt;

&lt;p&gt;Now there is a &lt;strong&gt;Repair&lt;/strong&gt; button: it merges duplicate points, removes empty&lt;br&gt;
faces, and tells you how many pieces the model is actually in. The rebuild also&lt;br&gt;
warns about a broken model &lt;em&gt;before&lt;/em&gt; producing the result.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. The "how many polygons" setting did nothing
&lt;/h2&gt;

&lt;p&gt;5,000 and 10,000 gave me the exact same model. The method I used can only&lt;br&gt;
double the detail, so the number you type in mostly doesn't matter.&lt;/p&gt;

&lt;p&gt;Now the tool searches for the right cell size instead, and the budget lands&lt;br&gt;
where you set it: 5,000 → 4,748.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. The model was tiny and far away
&lt;/h2&gt;

&lt;p&gt;It came in scaled 26 times and sitting 300 metres from the centre of the scene.&lt;br&gt;
The tool tried to fit the new surface to the origin — the wrong place — and&lt;br&gt;
every point collapsed into one spot.&lt;/p&gt;

&lt;p&gt;Two fixes: the tool now keeps the model's position and scale, and it snaps&lt;br&gt;
points to the nearest part of the surface instead of pushing them through it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's in 0.6.8
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Repair&lt;/strong&gt; — merges duplicate points, removes empty faces, reports pieces and
open edges.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Exact budget&lt;/strong&gt; — the polygon count you type in is the count you get.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Safer fitting&lt;/strong&gt; — keeps the model's position and scale, and refuses to
guess when the model is open.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Delete the unused&lt;/strong&gt; — shows the materials and images it will remove, then
asks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The AI sees the buttons&lt;/strong&gt; — a button's report now reaches the chat model.&lt;/li&gt;
&lt;li&gt;Fixed: a missing import made the repair silently do nothing.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://github.com/SickSect/BlenderAgent" rel="noopener noreferrer"&gt;Source and releases&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  blender #gamedev #3d #indiedev #python #blenderaddon
&lt;/h1&gt;

</description>
      <category>gamedev</category>
      <category>software</category>
      <category>tools</category>
    </item>
    <item>
      <title>Asset Assistant 0.6.6 — what I ran into while working on real assets</title>
      <dc:creator>Zalogin Aleksei</dc:creator>
      <pubDate>Mon, 26 Oct 2026 17:16:28 +0000</pubDate>
      <link>https://dev.to/sicksect/asset-assistant-066-what-i-ran-into-while-working-on-real-assets-511j</link>
      <guid>https://dev.to/sicksect/asset-assistant-066-what-i-ran-into-while-working-on-real-assets-511j</guid>
      <description>&lt;p&gt;I wrote about Asset Assistant before — it's my Blender add-on for game assets:&lt;br&gt;
it audits what is broken and turns the repetitive parts of the pipeline&lt;br&gt;
(unwrap, atlas, bake, pack, retopology, export) into one click each.&lt;/p&gt;

&lt;p&gt;This release is not a feature dump. Every item below is something I hit while&lt;br&gt;
working on an actual asset, and that is the reason it is in this version.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I ran into
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The export lost my texture mapping.&lt;/strong&gt; A &lt;code&gt;Texture Coordinate → Mapping →
Image Texture&lt;/code&gt; chain never reached the file: Blender's FBX exporter
hard-codes &lt;code&gt;uvset = None&lt;/code&gt;, so the engine samples the first UV set whatever
the material says. Now the chain is evaluated per face into one UV layer per
object, and the scene is restored right after the export.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Baked albedo came out washed out.&lt;/strong&gt; It was baked as &lt;code&gt;COMBINED&lt;/code&gt;, so the
light and the shadows went into the base colour map. Now it is baked as the
base colour through an Emission — on a cube with base colour (0.8, 0.2,
0.1): (0.968, 0.627, 0.541) instead of the expected (0.906, 0.485, 0.349).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A sculpt of 211,618 triangles, with no UVs and no budget.&lt;/strong&gt; Hence a mesh
doctor (nine checks) and retopology under a triangle budget you type in —
3,632 quads in 2.4 s, 0.00 mm off the original surface — plus a LOD chain.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The panel had grown into a wall of buttons.&lt;/strong&gt; It is now split by pipeline
stage: Textures, Mesh, UV, Bake, Export.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The smaller ones
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;the export no longer crashes when the target is a &lt;code&gt;.blend&lt;/code&gt; path&lt;/li&gt;
&lt;li&gt;baking an already baked material no longer produces &lt;code&gt;Wood_Dark_Bake_Bake&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;UV overlaps are detected by real geometry, not by bounding boxes&lt;/li&gt;
&lt;li&gt;the tab labels show names instead of i18n keys&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Unchanged
&lt;/h2&gt;

&lt;p&gt;Every button works with no AI at all. The optional chat still runs on a local&lt;br&gt;
model and calls the same 46 tools.&lt;/p&gt;

&lt;p&gt;Blender 4.2+, tested on 5.2 LTS. 19 headless test scripts, 12 doctor checks,&lt;br&gt;
19 presets, 28 chapters of documentation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/SickSect/BlenderAgent/releases" rel="noopener noreferrer"&gt;Releases page&lt;/a&gt; ·&lt;br&gt;
&lt;a href="https://github.com/SickSect/BlenderAgent" rel="noopener noreferrer"&gt;Source&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>blender</category>
      <category>gamedev</category>
    </item>
    <item>
      <title>I built a Blender add-on that tells you which of your game assets are broken</title>
      <dc:creator>Zalogin Aleksei</dc:creator>
      <pubDate>Wed, 21 Oct 2026 19:39:51 +0000</pubDate>
      <link>https://dev.to/sicksect/i-built-a-blender-add-on-that-tells-you-which-of-your-game-assets-are-broken-31d4</link>
      <guid>https://dev.to/sicksect/i-built-a-blender-add-on-that-tells-you-which-of-your-game-assets-are-broken-31d4</guid>
      <description>&lt;p&gt;Blender is wonderful for making game assets and terrible for keeping them correct.&lt;/p&gt;

&lt;p&gt;Nothing warns you that the normal map is in sRGB instead of Non-Color. That the texel density on one island is twice that of its neighbour. That the texture file you linked two weeks ago is no longer on disk. You find out when the engine complains — or, worse, when it doesn't.&lt;/p&gt;

&lt;p&gt;The routine I wanted to kill&lt;br&gt;
Every asset went through the same sequence, and every step was manual:&lt;/p&gt;

&lt;p&gt;unwrap it, and check that the texel density is even;&lt;br&gt;
hand the layout to an external painting program and bring the result back;&lt;br&gt;
bake the procedural material into real textures;&lt;br&gt;
pack the textures so the project survives being moved;&lt;br&gt;
find out it is still not ready to hand over.&lt;br&gt;
And the part that actually hurt: with a hundred objects in the scene, finding the badly configured one is no longer a five-minute job.&lt;/p&gt;

&lt;p&gt;The doctor&lt;br&gt;
That last problem is what the add-on is really about.&lt;/p&gt;

&lt;p&gt;AI → Material Doctor reads the whole scene and reports what is broken: the wrong colour space, a normal map wired straight into Base Color, a missing texture file, a mesh with textures but no UV, absolute paths, unpacked textures, a shader the exporter cannot express. It says which object, which material, how serious it is, and what can be repaired safely.&lt;/p&gt;

&lt;p&gt;Twelve checks, and the safe ones are fixed for you. Nothing is deleted.&lt;/p&gt;

&lt;p&gt;What works today&lt;br&gt;
The buttons — no model needed, they just do the work&lt;/p&gt;

&lt;p&gt;PBR from folder — a folder of maps becomes a material, assigned, with the right colour spaces.&lt;br&gt;
Doctor / Fix — the audit above, and the safe repairs.&lt;br&gt;
UV — unwrap, even texel density, a shared atlas with padding, and a UV kit: the layout as a PNG plus a manifest, to paint in Aseprite or Krita and bring back, without the UVs ever being touched.&lt;br&gt;
Bake — procedural material to textures, written next to the .blend, with a plain material on the object. The file names can follow the game convention (_col, _nrm, _rgh).&lt;br&gt;
Textures — pack into the .blend, relative paths, relink lost files, fix colour spaces.&lt;br&gt;
Export — GLB and FBX with the axes and modifiers the engines expect. The readiness check runs first.&lt;br&gt;
Presets — 16 procedural recipes and 4 hand-written layered materials to start from.&lt;br&gt;
The agent — the same tools, plus a chat that sees your scene&lt;/p&gt;

&lt;p&gt;Every request carries a snapshot of the scene, focused on what you are looking at right now, and a section of problems the model cannot see.&lt;br&gt;
The model can call any of the 40 tools by name, and reads back what actually happened instead of guessing.&lt;br&gt;
8 skills carry the knowledge it should not improvise — the exact socket names of Blender 4.x/5.x, colour spaces, PBR wiring. They attach to your own words, and every code sample in them is executed in Blender by a test, so an instruction cannot quietly drift away from the API.&lt;br&gt;
When no tool fits, it writes the code; the Run code button executes it in the scene, with Undo.&lt;br&gt;
Destructive tools never run on their own: it asks, and the chat shows a Run / Cancel block.&lt;br&gt;
Tools   40 — each one a button, a model call, and a headless test&lt;br&gt;
Doctor checks   12, 4 of them repaired automatically&lt;br&gt;
Skills  8, with runnable code samples&lt;br&gt;
Headless checks 16 scripts that run the real code in the real Blender&lt;br&gt;
Needs   Blender 4.2+ and a model (local via Ollama, or an API key) — only for the agent half&lt;br&gt;
Where it is going&lt;br&gt;
More around the agent, because right now it does not do that much, but it can already help with analysis and information:&lt;/p&gt;

&lt;p&gt;the result of "Run code" back into the model's context, so it can check its own work;&lt;br&gt;
a doctor check for "this is a flat BSDF, not a procedural material" — the piece that lets a small local model learn to build materials;&lt;br&gt;
the preset buttons calling the tool directly;&lt;br&gt;
the presets as node groups, so they live in the .blend like any Blender asset;&lt;br&gt;
the model driving other add-ons.&lt;br&gt;
And around the pipeline: ORM packing, a preview render, and material generation by the model as a separate step once (2) exists.&lt;/p&gt;

&lt;p&gt;Try it&lt;br&gt;
git clone &lt;a href="https://github.com/SickSect/BlenderAgent.git" rel="noopener noreferrer"&gt;https://github.com/SickSect/BlenderAgent.git&lt;/a&gt;&lt;br&gt;
python tools/build_addon.py      # -&amp;gt; dist/asset_assistant-.zip&lt;br&gt;
Edit → Preferences → Get Extensions → ▾ → Install from Disk, pick the zip, enable Asset Assistant.&lt;/p&gt;

&lt;p&gt;The buttons need no model at all. For the agent, run Ollama locally (ollama pull qwen2.5-coder:7b) or point it at any OpenAI-compatible endpoint.&lt;/p&gt;

&lt;p&gt;If the doctor has ever found a broken asset you did not know about, that is the feature I would like to hear about.&lt;/p&gt;

</description>
      <category>gamedev</category>
      <category>productivity</category>
      <category>python</category>
      <category>tools</category>
    </item>
    <item>
      <title>Blender forbids Python threads. So my AI add-on talks to itself through two JSON files</title>
      <dc:creator>Zalogin Aleksei</dc:creator>
      <pubDate>Mon, 19 Oct 2026 09:36:01 +0000</pubDate>
      <link>https://dev.to/sicksect/blender-forbids-python-threads-so-my-ai-add-on-talks-to-itself-through-two-json-files-58hb</link>
      <guid>https://dev.to/sicksect/blender-forbids-python-threads-so-my-ai-add-on-talks-to-itself-through-two-json-files-58hb</guid>
      <description>&lt;p&gt;The pivot&lt;br&gt;
I spent the last months building a local multi-agent CLI code generator - planner → coder → tester → executor → reviewer, running on open models via Ollama. It closed the loop: it wrote code, ran it, tested it, and fixed it.&lt;/p&gt;

&lt;p&gt;It worked. And that's exactly the problem: it solved a problem I don't have. Writing code for files on disk is a solved niche - I was competing with every other code-gen tool for a user who already has one.&lt;/p&gt;

&lt;p&gt;What I actually do all day is 3D. So the project became something else: an AI assistant that lives inside Blender and holds real tools for working with models, not just a text box that emits code.&lt;/p&gt;

&lt;p&gt;What works right now&lt;br&gt;
The add-on is called Game Asset Assistant, targets Blender 4.2+, and ships as a proper extension zip.&lt;/p&gt;

&lt;p&gt;Chat where you work&lt;/p&gt;

&lt;p&gt;Docked in the 3D Viewport sidebar (N → AI tab)&lt;br&gt;
Also opens as a standalone floating window with Ctrl+Alt+A&lt;br&gt;
Streamed responses, message history, stop/clear buttons&lt;br&gt;
It knows your scene&lt;/p&gt;

&lt;p&gt;Every request carries a compact snapshot injected into the system prompt:&lt;/p&gt;

&lt;p&gt;Blender 4.2.0&lt;br&gt;
Scene: Scene | fps=24 | units=METRIC | render=CYCLES&lt;br&gt;
Objects: 12&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cube [MESH] loc=(0.00, 0.00, 0.00) rot_deg=(0.0, 0.0, 0.0) scale=(1.00, 1.00, 1.00) verts=8 edges=12 faces=6 | uv=UVMap | materials=Steel | modifiers=SUBSURF
Selected: Cube
Active: Cube | mode=OBJECT
So when you ask "how many polygons does the active object have?", the model answers about your object - by name.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One click from answer to action&lt;/p&gt;

&lt;p&gt;When a reply contains a &lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
python block, it appears in a box with two buttons:

Run code - executes it in the current scene on the main thread, captures print() output and tracebacks, and pushes both back into the chat. That closes the loop: the model writes, Blender executes, the model sees the error and fixes it.
To Text Editor - saves it as a text datablock for manual review.
Backends

Local (Ollama, e.g. qwen2.5-coder:7b) or any OpenAI-compatible API - switchable in preferences, no code changes.

The part that broke my brain: Blender forbids threads
Here's the non-obvious bit worth the whole post.

Blender's API docs say it plainly: Python threads that outlive the script cause hard-to-diagnose crashes in Blender's own drawing code. So the obvious approach - "spawn a thread, call the LLM API, update the UI when it returns" - is off the table.

The add-on therefore never blocks and never spawns a thread. Instead:

Blender (main thread)              worker process            network
┌────────────────────────┐         ┌──────────────┐
│ operator appends a     │commands │              │
│ JSON line ─────────────┼────────→│  worker.py   │──HTTP──→ Ollama / API
│                        │         │              │
│ bpy.app.timers,        │events   │              │
│ every 0.1s, reads new  │←────────┤              │
│ lines ─────────────────┤         └──────────────┘
└────────────────────────┘
Commands are just JSON objects appended to commands.jsonl.
Events (chunk, done, error) are appended to events.jsonl.
A bpy.app.timers callback pumps events every 0.1 s - and a timer is not a thread, it's a callback Blender invokes on the main thread between frames. That's the only legal way to do background work.
Side effect: the whole add-on ships without any third-party dependency, and the protocol already has room for tool-call requests in a later phase.

What's not there yet
Being honest about the gaps:

No structured tool-calling - the model emits a code block and we exec() it
No confirmation for destructive operations (the prompt asks the model to warn; that's a request, not a guarantee)
No undo grouping - one Ctrl+Z won't roll back a whole script
UV, rigging and texturing exist only as chat advice, not as one-click tools
Scene snapshot is blind to UV islands, texel density, weights and armature pose
Roadmap
Phase   What    Why first
0   Richer snapshot, undo-push, destructive-op confirmation Cheap, unlocks everything after
1   Tool-calling over the JSONL channel, executed on the main thread with a registry + JSON schemas The reliability jump: from "80 lines of text that may fail" to named calls
2   Texturing: PBR material presets, texture assignment, packing, bake helpers  Stable API, high daily value
3   UV: quick unwrap/pack/texel-density, seam-by-angle, and a UV diagnostics report (overlaps, density) Most repetitive work; the report lets the model read the result and propose fixes
4   Auto-rig: metarig → Rigify, auto-weights, weight validation, export checks    Hardest - errors are silent, so diagnostics matter more than generation
5   One-click pipelines: GBC Prep, Char Prep, PBR Bake, Game Export Combines 2–4 into buttons
6   Teach the model: tool catalog in the prompt, domain recipes, few-shot examples  Ongoing, parallel
Integration with other Blender add-ons (delegating to UV packers, for example) is on the list - but the final roadmap is still open. I'd rather ship phases 0–3 and let real usage decide what phase 4 looks like.

The plan from here
Post progress as it lands. If you're working on AI × 3D pipelines, or you've wrapped a DCC tool for an LLM - I'd love to compare notes.

Repo link in the comments.

#blender #ai #python #gamedev #3d #showdev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>python</category>
      <category>tools</category>
    </item>
  </channel>
</rss>
