← All guides

Guide · Character design

How to draw a character with SVG and AI

How Arttie the otter is drawn: hand-written SVG paths, a Python builder, a written "character bible" and a QA checklist that Claude follows for every post.

Last updated

Arttie, a cartoon sea otter in a navy tee, waving
Arttie, drawn as SVG paths and rendered to an image.
Why SVG, not an image generator? A character has to look the same in every post. Image generators redraw it each time, and the ears, tail or shirt drift. SVG is code: the same path data gives the same otter, every time, and Claude can edit it precisely.

1Start from one model sheet

The model sheet is a turnaround (front, side, back), the expressions and the colours, all drawn in SVG inside one HTML file. It's the source of truth. The rule in the workspace's CLAUDE.md is short:

1. reference/arttie-model-sheet.png / source/Main.dc.html: the official turnaround.
   If anything disagrees with it, the model sheet wins.
2. ARTTIE.md: written spec derived from the model sheet.
3. Posts.

2Write the look down as numbers

"Cute otter" means something different to every model, every time. The character bible (ARTTIE.md) pins each part down as exact path data in a 400×440 box:

Head: M88 172 Q86 96 200 76 Q314 96 312 172 Q310 246 200 254 Q90 246 88 172 Z
Ears: circle (102,120) r14 and (298,120) r14, drawn before the head
Tail: M262 350 Q312 358 342 384 Q358 400 344 410 Q330 416 310 404 Q286 392 262 386 Z

It also has the palette as hex values (fur #A97850, tee #41527A, shorts #DCCAA0), the line weights (6px outlines, 3–4px inner lines) and the draw order.

3Build the figure from code, never from an old post

Old posts can be on an older version of the design (Arttie is on v6), so copying from one brings old mistakes back. So a Python builder, arttie.py, produces the full front view, and each post only adds arms, a face and props:

arttie(uid, arms=[HANG_L, WAVE_R], face='happy')
# emits the defs (hand-drawn "wobble" filter, sleeve masks) and the full figure in draw order

Running python source/arttie.py on its own checks the output against the model sheet.

4Turn every repeated mistake into a written rule

Shoulders were the hardest part. The profile photo took five rounds because one sleeve kept starting lower than the other. After that, the fix went into the bible as numbered rules, for example:

1. Both sleeves start from the same shoulder point.
   Left pivot=(126,254), right pivot=(274,254) (±2px), shift=5.
   If the two sleeve tops aren't level, the torso reads lopsided.

The same goes for small things: a single raised finger on a mitten paw reads as a rude gesture, so the rule is "point sideways".

5Render and check every post

A post is an HTML file at 1080×1350 (Instagram's 4:5). Headless Chrome turns it into a PNG, and a checker lints the post before it's saved:

python source/render.py posts/<folder>    # post.html -> post.png, waits for the fonts
python source/check_posts.py               # must show 0 errors

Then Claude zooms into the PNG and runs the bible's QA checklist: proportions, arm gaps, sleeves with cuffs, nothing covering the face.

6Keep the context lean

The bible says it in its first line: it's a "quick reference so future sessions don't need to re-read the HTML/PNG files". Re-reading the 106 KB model-sheet HTML every session would burn tokens. A short text spec gives Claude the same facts for a fraction of the cost (more on saving tokens).

Be open that AI helps. Arttie's Instagram bio says "drawn by a human dev + AI sidekick". People don't mind AI help; they mind being misled.