Create Profile Atlas
Core Rule
Generate the artwork. Do not manually draw expression overlays onto portraits. If an expression is wrong, regenerate that cell or a small replacement atlas, then replace the cell during post-processing.
Workflow
Collect inputs
- Subject reference image(s) or existing profile emoji.
- Desired shortcode prefix, such as
pixel-paul or pixel-alex.
- Whether this is a first-run full set or an extend set.
- Destination directory for final assets.
Read pose guidance
- Read
references/pose-guide.md before prompting generation.
- Use its built-in poses unless the user gives a custom list.
Prepare references
- Load local reference images with
view_image before calling image_gen.
- For extensions, load several existing successful sprites so identity, crop, palette, and pixel style stay anchored.
- If matching Slack names/order, use
agent-slack emoji search/get only when the user asks for Slack context; run it outside the sandbox.
Generate an atlas
- Use built-in
image_gen by default.
- Prompt for a row/column atlas on a flat solid
#00ff00 chroma-key background.
- Demand large, emoji-readable expression details. Tiny props fail at 48px.
- Ask for green gutters between cells and no labels, borders, numbers, watermark, or grid lines.
- If the generated file path is not locally discoverable, ask the user to pass the generated image back.
Inspect the generated atlas
- Use
view_image on the full generated atlas.
- Regenerate any weak cell before slicing when details are too small, identity drifts, or an expression is ambiguous.
- For one bad expression, generate a one-cell or small replacement atlas and use the postprocess script’s replacement option.
Post-process deterministically
- Use
scripts/profile_atlas_postprocess.py to split the atlas, remove green, create individual transparent PNGs, a transparent atlas, manifest, 48px preview, and optional zip.
- The script needs Pillow. If
python cannot import PIL, call load_workspace_dependencies and run the script with the bundled Python path.
- Do not assume equal cell widths. Generated atlases often have uneven gutters; the script detects green separator bands per row.
- Prefer tight square individual PNGs for Slack emoji. Do not resize before upload unless the user explicitly asks.
Validate
- Inspect the transparent atlas, individual problem cells, and 48px preview with
view_image.
- Check for trapped green regions between disconnected details, especially around symbols like
Zzz, motion marks, hearts, hands, explosions, and hair.
- If a cell has no intended green content, rerun postprocess with
--aggressive-green <name> for that cell.
- If a cell has intended green content, avoid aggressive removal and regenerate with a different key color or cleaner separation if needed.
Optional Slack upload
- If asked to upload, use
agent-slack emoji add <name> --image <path> --yes outside the sandbox.
- Check existing names first with
agent-slack emoji get ....
- To replace one Slack emoji, remove then add the same shortcode. Confirm with
agent-slack emoji get <name>.
First-Run Pattern
Create a complete atlas from a subject reference:
Use the provided subject image as the strict identity/style reference.
Create a <cols>x<rows> generated pixel-art Slack emoji atlas for shortcode prefix <prefix>.
Each cell is a close-cropped bust/face portrait on flat #00ff00, with green gutters.
Keep identity, hair, clothing cues, and crop consistent. Make expression-specific details oversized and readable at 48px.
No text, no labels, no grid lines, no borders, no watermark.
Atlas order: <pose list from pose-guide.md or user list>.
Then split:
python <skill>/scripts/profile_atlas_postprocess.py \
--atlas <generated-atlas.png> \
--out <output-dir> \
--names <comma-separated-shortcodes> \
--cols <cols> \
--rows <rows> \
--zip <output-dir>/<prefix>-images.zip
Extend Pattern
Create only new poses while matching an existing set:
Use the visible existing <prefix> emoji sprites as strict identity, crop, palette, and pixel-art style references.
Create a <n>-column by 1-row mini atlas for these new shortcodes: <names>.
Keep the same scale and close crop as the existing set. Put every cell on flat #00ff00 with green gutters.
Make each new prop/symbol oversized enough to survive at 48px.
For a weak cell, regenerate only that cell and pass it as a replacement:
python <skill>/scripts/profile_atlas_postprocess.py \
--atlas <extension-atlas.png> \
--out <output-dir> \
--names <name1,name2,name3> \
--cols 3 \
--rows 1 \
--replace name2=<replacement.png> \
--aggressive-green name2
Practical Lessons
- Big symbols matter: sweat beads, heart eyes, anger marks,
Zzz, tears, fists, explosions, and clown/skull details should be large enough to read at 48px.
- The best atlas is generated cleanly; post-processing should only cut, key, crop, and compose.
- Uneven generated gutters are normal. Detect separators from green bands per row.
- Transparent previews on black can reveal green halos; white 48px previews reveal readability.
- Keep generated originals. Copy them into outputs or manifest paths, but do not delete the generator’s original file.
- If Slack upload fails because a name exists, ask whether to replace. Replacement is destructive:
emoji remove <name> --yes, then emoji add.
Bundled Resources
references/pose-guide.md: reusable pose list and prompt notes.
scripts/profile_atlas_postprocess.py: split atlas, remove chroma key, apply replacements, create preview/manifest/zip.
1---2name: create-profile-atlas3description: Generate profile/portrait emoji atlases for Slack-style custom emoji. Use when making or extending a pixel/person/mascot emoji set, chroma-keying and splitting an atlas into transparent PNGs, fixing green-screen artifacts, checking emoji-size readability, or building manifests, previews, and zips.4---56# Create Profile Atlas78## Core Rule910Generate the artwork. Do not manually draw expression overlays onto portraits. If an expression is wrong, regenerate that cell or a small replacement atlas, then replace the cell during post-processing.1112## Workflow13141. **Collect inputs**15 - Subject reference image(s) or existing profile emoji.16 - Desired shortcode prefix, such as `pixel-paul` or `pixel-alex`.17 - Whether this is a **first-run** full set or an **extend** set.18 - Destination directory for final assets.19202. **Read pose guidance**21 - Read `references/pose-guide.md` before prompting generation.22 - Use its built-in poses unless the user gives a custom list.23243. **Prepare references**25 - Load local reference images with `view_image` before calling `image_gen`.26 - For extensions, load several existing successful sprites so identity, crop, palette, and pixel style stay anchored.27 - If matching Slack names/order, use `agent-slack emoji search/get` only when the user asks for Slack context; run it outside the sandbox.28294. **Generate an atlas**30 - Use built-in `image_gen` by default.31 - Prompt for a row/column atlas on a flat solid `#00ff00` chroma-key background.32 - Demand large, emoji-readable expression details. Tiny props fail at 48px.33 - Ask for green gutters between cells and no labels, borders, numbers, watermark, or grid lines.34 - If the generated file path is not locally discoverable, ask the user to pass the generated image back.35365. **Inspect the generated atlas**37 - Use `view_image` on the full generated atlas.38 - Regenerate any weak cell before slicing when details are too small, identity drifts, or an expression is ambiguous.39 - For one bad expression, generate a one-cell or small replacement atlas and use the postprocess script’s replacement option.40416. **Post-process deterministically**42 - Use `scripts/profile_atlas_postprocess.py` to split the atlas, remove green, create individual transparent PNGs, a transparent atlas, manifest, 48px preview, and optional zip.43 - The script needs Pillow. If `python` cannot import `PIL`, call `load_workspace_dependencies` and run the script with the bundled Python path.44 - Do not assume equal cell widths. Generated atlases often have uneven gutters; the script detects green separator bands per row.45 - Prefer tight square individual PNGs for Slack emoji. Do not resize before upload unless the user explicitly asks.46477. **Validate**48 - Inspect the transparent atlas, individual problem cells, and 48px preview with `view_image`.49 - Check for trapped green regions between disconnected details, especially around symbols like `Zzz`, motion marks, hearts, hands, explosions, and hair.50 - If a cell has no intended green content, rerun postprocess with `--aggressive-green <name>` for that cell.51 - If a cell has intended green content, avoid aggressive removal and regenerate with a different key color or cleaner separation if needed.52538. **Optional Slack upload**54 - If asked to upload, use `agent-slack emoji add <name> --image <path> --yes` outside the sandbox.55 - Check existing names first with `agent-slack emoji get ...`.56 - To replace one Slack emoji, remove then add the same shortcode. Confirm with `agent-slack emoji get <name>`.5758## First-Run Pattern5960Create a complete atlas from a subject reference:6162```text63Use the provided subject image as the strict identity/style reference.64Create a <cols>x<rows> generated pixel-art Slack emoji atlas for shortcode prefix <prefix>.65Each cell is a close-cropped bust/face portrait on flat #00ff00, with green gutters.66Keep identity, hair, clothing cues, and crop consistent. Make expression-specific details oversized and readable at 48px.67No text, no labels, no grid lines, no borders, no watermark.68Atlas order: <pose list from pose-guide.md or user list>.69```7071Then split:7273```bash74python <skill>/scripts/profile_atlas_postprocess.py \75 --atlas <generated-atlas.png> \76 --out <output-dir> \77 --names <comma-separated-shortcodes> \78 --cols <cols> \79 --rows <rows> \80 --zip <output-dir>/<prefix>-images.zip81```8283## Extend Pattern8485Create only new poses while matching an existing set:8687```text88Use the visible existing <prefix> emoji sprites as strict identity, crop, palette, and pixel-art style references.89Create a <n>-column by 1-row mini atlas for these new shortcodes: <names>.90Keep the same scale and close crop as the existing set. Put every cell on flat #00ff00 with green gutters.91Make each new prop/symbol oversized enough to survive at 48px.92```9394For a weak cell, regenerate only that cell and pass it as a replacement:9596```bash97python <skill>/scripts/profile_atlas_postprocess.py \98 --atlas <extension-atlas.png> \99 --out <output-dir> \100 --names <name1,name2,name3> \101 --cols 3 \102 --rows 1 \103 --replace name2=<replacement.png> \104 --aggressive-green name2105```106107## Practical Lessons108109- Big symbols matter: sweat beads, heart eyes, anger marks, `Zzz`, tears, fists, explosions, and clown/skull details should be large enough to read at 48px.110- The best atlas is generated cleanly; post-processing should only cut, key, crop, and compose.111- Uneven generated gutters are normal. Detect separators from green bands per row.112- Transparent previews on black can reveal green halos; white 48px previews reveal readability.113- Keep generated originals. Copy them into outputs or manifest paths, but do not delete the generator’s original file.114- If Slack upload fails because a name exists, ask whether to replace. Replacement is destructive: `emoji remove <name> --yes`, then `emoji add`.115116## Bundled Resources117118- `references/pose-guide.md`: reusable pose list and prompt notes.119- `scripts/profile_atlas_postprocess.py`: split atlas, remove chroma key, apply replacements, create preview/manifest/zip.