Skip to content

Spec: Avatar Species and Human-drawn Custom Parts for the pixel Avatar #1209

Closed
12 of 12 issues completed
Closed

Description

@DoodleBears

Problem Statement

The pixel Avatar is now a PersonaBot's mascot as well as its portrait: Window Companions (#1135) show it moving and speaking across Harness pages. Humans can only make human characters, though. Animals, elves, goblins and other fantasy species can only be faked with a single accessory such as cat ears. Hair is one color in three fixed pieces, and the one accessory slot cannot combine a headpiece with anything else. A Human who wants a decoration the catalog lacks cannot make it. Japanese character makers such as Picrew show that variety and personal expression are what make a maker appealing.

Solution

Extend the pixel Avatar Family with Avatar Species and Custom Parts, following ADR-0148:

  • Avatar Species. A Human picks a species for a PersonaBot: human, elf, goblin, dwarf, orc, cat, dog, fox, rabbit, bear or flower.
    • Each species is a base on the existing pixel bust rig. It sets the head silhouette, ears, nose or muzzle and suggested body colors.
    • Every species keeps gaze, blink, head turns, the speech mouth and the transparent Window Companion silhouette.
    • Switching species keeps hair, outfit and decorations. A choice the species cannot show is saved and hidden, then comes back when it fits again.
  • Hair and headpieces. Hair splits into separately colored pieces: bangs, left side, right side, back and a single strand. A new headpiece slot holds ears, horns, halos and small head wings, which pass through the hair with one layer in front and one behind.
  • Custom Parts. A Human draws their own pixel parts in the app, with pencil, eraser, fill, gradient, noise, mirror, line, rectangle, eyedropper and undo, and sees a live 1× preview on the real Avatar.
    • Parts recolor with the Avatar.
    • Parts are saved in a Part Library in the Profile and can be reused on other Bots.
    • Parts travel with exported Bots, and a single part moves as a PNG file that imports back without loss.
    • Imported parts animate like built-in ones.
  • Random. The editor's random action covers every species and part. New Bots get a full-domain face from their name. Existing Bots keep their face.

This spec records the accepted target. The documentation commit that accompanies it does not deliver runtime behavior.

User Stories

  1. As a Human, I want to choose a species for my PersonaBot, so that it can be an elf, a goblin, an animal or a flower instead of only a human.
  2. As a Human, I want every species to keep the same blink, gaze, head turns and speech mouth, so that my Window Companion mascot feels equally alive whatever it is.
  3. As a Human, I want every species to show a transparent silhouette in a Window Companion, so that it stands in the window like the existing human bust.
  4. As a Human, I want a goblin with green skin, pointed ears and small tusks, so that I can make a fantasy character.
  5. As a Human, I want elves, dwarves and orcs, so that I can build a medieval fantasy cast.
  6. As a Human, I want a dwarf's beard to leave the mouth visible, so that it still speaks visibly.
  7. As a Human, I want armor, robes, tunics and cloaks, so that my medieval characters are dressed for their world.
  8. As a Human, I want helmets and hoods that hide hair while worn, so that headgear looks right.
  9. As a Human, I want my hair choices back when I remove a helmet or hood, so that trying headgear does not lose my styling.
  10. As a Human, I want cat, dog, fox, rabbit and bear species with muzzles and animal ears, so that my Bot can be an anthropomorphic animal.
  11. As a Human, I want animal patterns such as tabby stripes, spots, cow patches and colorpoint, so that my animal Bot looks individual.
  12. As a Human, I want patterns to follow the body color, so that recoloring keeps the pattern intact.
  13. As a Human, I want a talking flower species with petals and leaves or a pot, so that I can have a gentle, easy-on-the-eyes companion.
  14. As a Human, I want petal colors to work like hair colors, so that I can color each petal piece separately.
  15. As a Human, I want skin color to act as body color for every species, so that fur, bark-green or goblin skin use one control.
  16. As a Human, I want suggested color swatches for each species, so that I start from colors that suit it.
  17. As a Human, I want free color choice for every species, so that suggestions never limit me.
  18. As a Human, I want switching species to keep my hair, outfit and decorations, so that I can compare species quickly.
  19. As a Human, I want choices a species cannot show to be hidden and kept, with a visible note, so that nothing is silently replaced.
  20. As a Human, I want hidden choices to return when I switch back, so that experimenting is safe.
  21. As a Human, I want left and right side hair as separate pieces, so that I can make asymmetric styles.
  22. As a Human, I want each hair piece to have its own color, defaulting to the main hair color, so that I can make streaks and two-tone hair.
  23. As a Human, I want a single-strand piece, so that I can add an ahoge independently of my bangs.
  24. As a Human, I want bunny ears, horns, halos and small head wings in a headpiece slot, so that I can wear them together with other accessories.
  25. As a Human, I want headpieces to sit partly behind and partly in front of my hair, so that they look attached to the head.
  26. As a Human, I want to draw my own part in the app, so that I can make decorations the catalog lacks.
  27. As a Human, I want to draw in headpiece, accessory, hair-piece and pattern slots, so that my parts fit the rig.
  28. As a Human, I want eyes, brows and mouth to stay non-drawable, so that blinking and speaking never break.
  29. As a Human, I want pencil, eraser, flood fill, mirror and a live 1× preview, so that I can draw a symmetric part and judge it at real size.
  30. As a Human, I want a gradient tool that steps through tones with dithering, so that my parts get pixel-art shading.
  31. As a Human, I want a noise tool that jitters tones, so that I can add texture.
  32. As a Human, I want line, rectangle and eyedropper tools and undo/redo, so that drawing is precise and forgiving.
  33. As a Human on a touch device, I want an offset cursor with a separate draw button, so that my finger never hides the pixel I am drawing.
  34. As a Human, I want to pick colors as an appearance color plus a tone, so that my part recolors when I change hair or body color.
  35. As a Human, I want fixed colors as well, so that a part can keep an exact color.
  36. As a Human, I want to draw a headpiece's front and back layers separately, with hair occlusion in the preview, so that I control what hair covers.
  37. As a Human, I want my drawn part to move with my Avatar's head, gaze and turns, so that it behaves like a built-in part.
  38. As a Human, I want my parts saved in a Part Library in my Profile, so that I can reuse them on other Bots.
  39. As a Human, I want applying a part to copy it into the Bot's appearance, so that later library edits never change Bots I already dressed.
  40. As a Human, I want exported Bots to carry their parts, so that whoever imports my Bot sees it as I made it.
  41. As a Human importing a Bot, I want its parts added to my Part Library, so that I can reuse decorations I received.
  42. As a Human, I want the Part Library to show and filter where each part came from, so that drawn and imported parts stay distinguishable.
  43. As a Human, I want identical parts to merge in my library, so that repeated imports do not create duplicates.
  44. As a Human, I want to export one part as a PNG that previews anywhere, so that I can share it in chat.
  45. As a Human, I want to import that PNG back without losing color references or tones, so that shared parts work natively and animate.
  46. As a Human, I want to export my whole Part Library as a zip, so that I can back it up or share a set.
  47. As a Human, I want to import a plain PNG drawn in another tool, so that I can reuse my existing pixel art.
  48. As a Human importing a plain PNG, I want to see the color count before accepting, so that I understand how it was converted.
  49. As a Human, I want to open a built-in part or someone else's part and edit it into my own, so that I can start from something close.
  50. As a Human, I want derived parts to record their parent and keep the original author's name, so that credit is preserved.
  51. As a Human, I want a note that a part derived from a built-in part keeps its current shape, so that I understand it no longer adapts to hair length or face shape.
  52. As a Human, I want a random action covering every species and part, so that I can discover characters.
  53. As a Human creating a Bot, I want its first face to come from its name across every species, so that new Bots are varied.
  54. As a Human with existing Bots, I want their faces unchanged by this feature, so that recognizable identities stay stable.
  55. As a Human, I want my edited appearance fixed when I rename a Bot, so that renaming never changes its face.
  56. As a Human using an older Client, I want a newer appearance to show its saved snapshot with a note, so that it never silently becomes a different character.
  57. As a Human, I want existing appearances to render exactly as before, so that nothing changes until I edit.
  58. As a Human, I want imported parts to remain plain data, so that sharing never runs foreign code in my Client.

Implementation Decisions

Authority. The glossary terms are Avatar Family, Avatar Species, Avatar Appearance, Custom Part and Part Library (CONTEXT.md). ADR-0148 partially supersedes ADR-0118's free-drawing and upload limits. Everything else in ADR-0118 still holds: appearance is independent of activity, the PersonaBot owning module is the canonical write/read path, and the missing-version snapshot fallback applies.

Species.

  • An Avatar Species is a base on the pixel bust rig, not a new Avatar Family. It sets the silhouette, ears, nose or muzzle, default eyes, suggested body colors, anchor offsets and the parts it accepts.
  • Only a different skeleton or visual language makes a new family.
  • Every species supports the full rig contract before release: transparent companion surface, anchors, gaze, blink, turns, and closed/half-open/open mouth.
  • Species provide the same anchors the Window Companion consumes. Bubble anchors are being reworked in #1177; new species must satisfy whichever anchor contract is current.

Compatibility rules.

  • Switching species replaces its base parts and keeps every other choice.
  • An incompatible choice is hidden and kept, never substituted. The same rule applies to helmets and hoods hiding hair.
  • Beards are a lower-face part that always leaves the mouth area visible. Mouth-covering parts are out of the first set.

Recipe.

  • Side hair splits into left and right pieces. Bangs, left, right, back and strand each take an optional color that defaults to the main hair color.
  • A headpiece slot has front and back layers around the hair. The existing accessory slot stays, and ear, horn and halo accessories move to the headpiece slot.
  • Skin color is the body color.
  • A recipe that uses any new field raises the asset/schema version. Recipes without them keep byte-identical output, and BotPixel's golden fixture is never regenerated to pass.
  • Older Clients use ADR-0118's snapshot fallback.

Custom Parts.

  • A Custom Part is a bounded grid for one slot, with front and back layers for headpieces. Each cell is empty or holds a color source (an appearance color slot or a fixed color) plus a tone step on the rig's shade ramp.
  • Gradient and noise bake tone steps into cells at draw time; no procedural parameters are stored.
  • Parts may fill headpiece, accessory, hair-piece and pattern slots, not eyes, brows or mouth.
  • A part follows its slot anchor. Turned poses come from the slot's shift and far-side rules.
  • Content is immutable. A part's identity is a content hash of its cells, color references and slot. Name, author, origin and parent are metadata outside the hash. Editing creates a new part.

Ownership.

  • BotPixel owns the part type, validation, rendering and pure drawing algorithms (fill, gradient, dither, noise, mirror, PNG quantization).
  • DeepSeekBot owns the editor UI, the Host-owned Part Library in the DSH Profile, and import/export through existing Host seams.
  • Applying a part embeds a copy in the Avatar Appearance.
  • Bot export and import carry embedded parts. Import adds them to the library, deduplicated by content and marked by origin.

Files.

  • A single part exports as a PNG with its part data embedded and reimports losslessly. The library exports as a zip.
  • A plain PNG of slot size imports with a bounded color count as fixed colors.
  • Imports are size- and color-bounded data, never markup or code.

Seeds. New PersonaBots record a seed version and use a full-domain name seed. A Bot without that record keeps today's human-only seed. An Avatar follows its name until a Human edits it; after that it is fixed across renames.

Editor UX. Follow the pixel-part editor research:

  • A color grid of appearance slots × tones, plus fixed colors.
  • Mirror locked to the Avatar centerline, working with every tool.
  • One stroke per undo step.
  • Integer zoom with a grid, slot bounds and the dimmed Avatar under the canvas, plus a fixed 1× preview on the real Avatar.
  • Write all of it ourselves; never copy Aseprite, LibreSprite or Lospec code or assets.

Testing Decisions

Test observable behavior through the highest existing seams, not private renderer structure:

  • BotPixel rendering. The golden fixture proves existing recipes are byte-identical. New golden entries cover each species and new part at legal extremes, front and turned poses, closed/half-open/open mouths, beards with a visible mouth, and headpiece layering behind and in front of hair. Unit tests cover the pure drawing algorithms (fill boundaries, dither pattern, seeded noise, mirror axis), content-hash stability and identity, and PNG round-trip.
  • Edit and save path. A Human edits in the Client, the PersonaBot owning module saves and re-reads the appearance, and the roster Avatar and Window Companion render it. Reuse existing Avatar appearance save/validate and Client interaction tests as prior art.
  • Compatibility. Species switching with hidden-but-kept choices; an older-version recipe showing its snapshot fallback; unchanged faces for Bots without a seed version.
  • Sharing. Bot export to zip and import as a new Bot carries embedded parts, adds them to the importer's library with origin, and deduplicates repeats. Single-part PNG export and import round-trips. A plain PNG is quantized with a bounded color count. Reuse existing Bot export/import tests as prior art.
  • Runtime acceptance. On an isolated verified DSH Profile, edit a Bot, see it animate and speak in a Window Companion with a real DM reply, then export and import it. Capture before/after screenshots in light and dark themes.

Out of Scope

  • Full-body characters, quadruped pets, face-less plants and other new skeletons (they would be new Avatar Families).
  • Drawable eyes, brows or mouth, and per-frame animation drawing.
  • Layers beyond headpiece front/back, animation frames and selection transforms in the editor.
  • Back wings behind the shoulders, and mouth-covering parts such as masks.
  • SVG or other markup parts, imported renderers and arbitrary-size images.
  • A shared online part marketplace or cross-Profile library sync.
  • Changing the existing name seed for Bots without a seed version.

Further Notes

  • Confirmed through a grilling session on 2026-10-08 (Q1–Q28). Decision log: specification handoff. Glossary terms are in CONTEXT.md and CONTEXT.zh.md. The living architecture §5.4 integrates the target.
  • Pixel artwork follows anime 32×32 bust techniques; all assets are original.
  • Each tracer bullet crosses BotPixel (published @botharness/pixel-avatar) and DeepSeekBot. Release the BotPixel change before the DeepSeekBot consumer, following each repo's release flow.
  • Delivery status lives in this issue's sub-issues.

Activity

  1. added this to the v1.2 milestone on Oct 8, 2026
  2. added
    ready-for-agentFully specified, ready for an AFK agent
    area:ui-uxInteraction and visual experience; may accompany a code-layer area
    feature:avatarPersonaBot avatar media and activity frame
    area:fullstackEnd-to-end Host and Client implementation
    scope:specNormative specification for follow-on slices
    on Oct 8, 2026
  3. DoodleBears commented on Oct 9, 2026

    @DoodleBears
    ContributorAuthor

    交接(agent 额度用完,暂停)

    已完成并 merge 的:#1210 #1211 #1212 #1213 #1214 #1215 #1216 #1238 #1240。BotPixel 发布了 0.8.0、0.9.0、0.10.0。

    还开着的 3 个,代码都已经写完,并且推到了 GitHub。三个分支是叠在一起的,必须按顺序 merge:

    顺序 Issue 分支 Head 状态
    1 #1217 头发分件上色和内置头饰 claude/festive-gauss-gv7xu2 d8cb5c7 PR #1246 已开,CI 绿,等 review 和 merge
    2 #1219 PNG 导入和派生编辑 claude/festive-gauss-gv7xu2-1219 11ff9ab 还没开 PR
    3 #1218 猫、狗、狐、兔、熊和花纹(pixel-avatar 0.10.0) claude/festive-gauss-gv7xu2-1218 040cde1 还没开 PR

    接手步骤:

    1. Review 并 squash merge feat(avatar): color every hair piece and wear built-in headpieces beside an accessory #1246,然后去掉 Avatar Pieces: every hair piece colored and built-in headpieces #1217 上的 agent:active 标签。
    2. 把 Custom Parts 4: plain PNG import and derived editing #1219 rebase 到 main,跑检查(npx -y pnpm@12.4.2 下的 tsc、lint、format、test),然后开 PR。
      git fetch origin
      git checkout -B next-1219 origin/claude/festive-gauss-gv7xu2-1219
      git rebase --onto origin/main d8cb5c7
      
    3. Custom Parts 4: plain PNG import and derived editing #1219 merge 之后,对 Avatar Species 3: cat, dog, fox, rabbit, bear with patterns #1218 做同样的事:
      git checkout -B next-1218 origin/claude/festive-gauss-gv7xu2-1218
      git rebase --onto origin/main 11ff9ab
      
    4. 每个 PR 的证据都在 docs/assets/pr/<n>-*/。PR 里的图片用 raw/<full-sha>/ 链接。

    需要 human QA:三个 PR 的录屏和截图效果。

    已知情况:client-observer.test.ts 在本地会因为 node:sqlite 打包失败,这个问题在这些改动之前就有。


    Generated by Claude Code

  4. DoodleBears commented on Oct 9, 2026

    @DoodleBears
    ContributorAuthor

    全部完成:12 个子 issue 都已 merge 并关闭。最后三个按顺序合并:#1246(#1217)→ #1252(#1219)→ #1253(#1218)。BotPixel 发布了 0.8.0、0.9.0、0.10.0。


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:fullstackEnd-to-end Host and Client implementationarea:ui-uxInteraction and visual experience; may accompany a code-layer areafeature:avatarPersonaBot avatar media and activity frameready-for-agentFully specified, ready for an AFK agentscope:specNormative specification for follow-on slices

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions