Capri's chip

Capri mods

Get mods for her, or make your own.

Kinds of mod

Mods need Capri 0.8.3 or newer, and skills need 0.8.4. Everything works on Windows, Mac and Linux, except code mods and intros.

Settings mod .capri-mod

Changes
names she answers to, how she hears her name, a hearing log
Can't change
any other setting. Her voice, brain and personality stay as they are

Colour set .capri-mod

Changes
her hair, accents, eyes, edges and body, on her own art and on skins
Can't change
any shapes in her art. One set is on at a time

Skin .capri-skin

Changes
her art, strip by strip. Any strip you leave out stays hers
Can't change
strip sizes, her sounds or what she does. One skin is on at a time

Skill .capri-skill

Changes
what she knows while she plays a game you listed
Can't change
anything outside game jobs. It's text, so it runs no code

Code mod .capri-code, Windows only

Changes
anything C# can do. It runs inside Capri with full access to your PC
Can't change
nothing's off limits. She asks before it runs. Read Safety first

Startup intro .capri-code, Windows only

Changes
what plays when she starts: full screen, up to 15 seconds
Can't change
nothing's off limits here either, since it's a code mod

No kind of mod replaces her sounds or her voice.

Install, turn off, remove

  1. Right-click her > Open Capri Mainframe
  2. Mods in the title bar, beside Settings. Mac and Linux: Mods on the CAPRI heading
  3. Browse mods, then Install. Mac and Linux: Download
Browse mods
search by name, author or description. Filter with All, Settings, Code, Skins or Skills. Mac and Linux have no Skills button, so skills show under All
Import mod
pick a mod file you already have. It turns on, and replaces any mod with the same id
On, Off
works straight away and lasts after a restart
Remove
deletes it at once, with no second ask. The file you imported from stays where it was
Reinstall
fetches the latest copy from the directory. She never updates a mod by herself
Rate
installed mods only, 1 to 5 stars. Rating again replaces your old rating
Her colours
Hair, Accents, Eyes, Edges and Body on the Mods page. Mac and Linux: hex boxes, then Save colors. They save as a mod called My Colors. Reset colors brings hers back

How many at once

Skins
one. Turning one on turns the last one off
Colour sets
one, on top of any skin
The rest
as many as you like

New in 0.8.5

Colour sets
they show under Skins, marked COLOURS. In 0.8.4 they show under Settings

The list comes from GitHub, and download counts and stars come from Capri's counter. Installing or rating sends it the mod's folder name. It stores a salted hash of your IP, never the IP itself.

Where mods live

Mods folder on the Mods page opens this folder on any system.

Windows
%LOCALAPPDATA%\Capri\mods
Linux
~/.config/Capri/mods
Mac
~/Library/Application Support/Capri/mods

What's in it

<id>.capri-…
each mod you installed
<id>-skin
a skin, unpacked
<id>-data
a code mod's own folder. Remove leaves it there, so delete it yourself
off.txt
the ids you turned off
approved.txt
the code mods you approved, with each file's SHA-256
my-colors.capri-mod
the colours you picked
hearing-log.txt
only while a hearing log mod is on

Adding files by hand

Import mod is the easy way. A file you drop in yourself works like this:

When it shows
at her next restart, import or remove
File name
has to match the mod's id, or she skips it
Skins
always import them, since they need unpacking
Code mods
show as CHANGED and stay off until you press On and approve

What every mod needs

Settings mods and skin.json use these as JSON keys. Skills and code mods use them as header lines.

format
required, always 1. Skills write it capri-skill: 1, code mods // capri-mod: 1
id
required. Lowercase letters, numbers and dashes, up to 48 characters. It starts with a letter or number
name
required, up to 40 characters
version
optional, up to 20 characters
author
optional, up to 40 characters
description
optional, up to 200 characters

Give every mod its own id, even across kinds. On, Off and approval all go by id, so two mods with the same id switch together.

Size limits

KindFileLargest
Settings, coloursJSON64 KB
SkillText64 KB
Code modC# text256 KB
SkinZip of PNGs96 MB

Settings mods

my-names.capri-mod
{
  "format": 1,
  "id": "my-names",
  "name": "My Names",
  "version": "1.0.0",
  "author": "You",
  "description": "She answers to Nova too.",
  "wake_names": ["Nova", "Big Z"],
  "heard_as": ["Capris"],
  "sounds_like": true
}

A settings mod sets at least one of these. She ignores any other key.

wake_names
up to 20 names. She answers to them, and her brain knows them as nicknames. They count as whole words, in any case
heard_as
up to 60 spellings that count as her name, for when her ears get it wrong. Her brain isn't told these
sounds_like
true also counts words that sound like Capri or a wake name. It doesn't cover heard_as
hearing_log
true keeps hearing-log.txt in the mods folder, with each line marked FOR HER or ignored. Turning the mod off deletes the log
colors
her colours. See below
Names
2 to 32 letters or numbers, with single spaces, dashes or apostrophes between them
“Hey Capri”
doesn't use these names. It only listens for those two words
Mac, Linux
there's no voice chat, so only wake_names matter, as nicknames for her brain. A hearing log lists the lines you type

Examples: Custom Names, Sharper Ears, Hearing Log.

Colour sets

colors-ocean.capri-mod
{
  "format": 1,
  "id": "colors-ocean",
  "name": "Colors: Ocean",
  "version": "1.0.0",
  "author": "You",
  "colors": {
    "hair": "#1E90FF",
    "accent": "#00E5C3",
    "eyes": "#FFD54A"
  }
}

Each colour is #RRGGBB. Set at least one. Any you leave out stay hers.

KeyRecoloursHers
hairher reds#FF0046
accenther greens#00E86E
eyesher blues#1870F0
edgesher violets#7854F0
bodyher darks#05030A

Colours go by hue, so a set recolours skins too. Whites and pale greys stay as they are.

Skins

  1. Start from her strips on GitHub, or rename any .capri-skin to .zip and open it
  2. Paint over the PNG strips and keep each size exactly
  3. Add a skin.json
  4. Zip the files with no folder around them, then rename the zip to my-skin.capri-skin
  5. Import mod
skin.json
{
  "format": 1,
  "id": "my-skin",
  "name": "My Skin",
  "version": "1.0.0",
  "author": "You",
  "description": "Capri in blue."
}

That file plus one correctly sized strip, like idle.png, is already a working skin.

In the zip
skin.json and PNG strips, at the top level, and nothing else
Limits
64 files, 96 MB, 256 MB unpacked, 32 MB for one PNG
File names
exactly the names below, with a lowercase .png
Sizes
exact, or she refuses the skin
Frames
side by side in one row. Strip width divided by frames is one frame's width
Missing strips
she uses her own art for those

Her strips

StripSizeFramesfps
idle6960 x 3846024
idle_blink
idle_blink_glitch
928 x 384824
idle_mouth580 x 384512
grin3840 x 384168
blink
blink_glitch
960 x 38448
glitch2400 x 3841015
dangle5760 x 3842410
sleep3840 x 384166
wake3120 x 3841315
walk2880 x 3841212
arrive3360 x 3841415
leave2880 x 3841215
mouth1200 x 384512
perch
perch_talk
perch_music
11760 x 3846030
perch_blink
perch_blink_glitch
1568 x 384830
perch_glitch2880 x 3841015
perch_arrive4032 x 3841415
perch_leave3456 x 3841215
laydown
laydown_talk
laydown_sleep
22320 x 2506030
laydown_blink
laydown_blink_glitch
2976 x 250830
laydown_glitch4400 x 2501015
laydown_leave5280 x 2501215
dance3840 x 3841616
face400 x 4001-
_flipped
every idle, perch and laydown strip except idle_mouth also has one, like perch_flipped, at the same size. It's her facing-left art, stored facing right on the same frames, and she draws it mirrored. Leave one out and she wears her own art when she faces left there
idle_blink
swaps in over idle frames 25 to 32
perch_blink
swaps in over perch frames 29 to 36, and laydown_blink does the same on laydown. Frame 5 of perch_blink is also how she sleeps sitting up
idle_mouth
her talking mouth, drawn over her standing art. Keep her face where it is in every idle frame so it lands on her jaw
Older skins
a 3840 x 384 idle still works. It's 16 frames at 8 fps, mirrored when she faces left, and it goes with blink and blink_glitch over frames 10 to 13 and mouth, at 1200 x 384. Only that size of idle uses those three
dance
Mac and Linux only. Windows dances on idle
face
accepted, but she doesn't use it from a skin
Mac, Linux
don't draw perch_talk, laydown or _flipped strips

Skins published so far use the older idle and hold 41 strips: everything except dance, face, mouth and the new idle_ strips. Example: Maid Suit.

Skills

mc-basics.capri-skill
---
capri-skill: 1
id: mc-basics
name: Minecraft basics
version: 1.0.0
author: You
description: Getting through the first night.
games: Minecraft
---
Punch trees first, then make a crafting table.
Build a small shelter before dark.
Carry torches into caves.
Header
the file opens with a --- line. Each header line is key: value with a lowercase key, and a second --- closes it
games
required. Up to 20 names split by commas, each up to 60 characters
Know-how
everything under the second ---. It can't be empty

When she uses it

Game jobs
while she plays a listed game for you. Normal chat never sees it
Matching
only letters and numbers count, in any case. BloonsTD6 matches Bloons TD 6
Window titles
she trims them, so Minecraft 26.3 - Singleplayer counts as Minecraft
Many names
list them all, like Bloons TD 6, BloonsTD6, BTD6
Her brief
she's told to follow it over her general advice. Your saved controls for that game come after it
Every turn
it goes to her brain each turn of the job, so keep it tight on a paid key

Example: BTD6 strategy.

Code mods Windows only

C# that Capri compiles and runs inside herself. Import this one, press Yes, then type mod check to her.

hello-capri.capri-code
// capri-mod: 1
// id: hello-capri
// name: Hello Capri
// version: 1.0.0
// author: You
// description: Answers "mod check".

using CapriDesktop;

public class HelloCapri : ICapriMod
{
    private ICapriHost capri;

    public void Start(ICapriHost host)
    {
        capri = host;
        capri.Log("Started.");
    }

    public bool Heard(string words)
    {
        string line = words.ToLowerInvariant();
        if (!line.Contains("mod check"))
            return false;
        capri.Say("Code mod online.");
        capri.Sound("hop");
        return true;
    }

    public void Stop()
    {
        capri.Log("Stopped.");
    }
}

The file

Header
// key: value lines at the very top. The first line that doesn't fit ends it, so plain comments go below it
intro
an extra header line, // intro: yes. Startup intros
C#
C# 5 on .NET Framework. No $"...", ?., nameof or => members
References
System, System.Core, System.Drawing, System.Windows.Forms and Capri. Anything else won't compile, including System.Xml and System.Net.Http
One class
exactly one non-abstract class implements ICapriMod, with a constructor that takes nothing

The API

namespace CapriDesktop
public interface ICapriMod
{
    void Start(ICapriHost capri);
    bool Heard(string words);
    void Stop();
}

public interface ICapriHost
{
    string Folder { get; }
    void Say(string line);
    void Log(string line);
    Bitmap Art(string name);
    void PlayIntro();
    void Sound(string name);
}

public interface ICapriIntro
{
    double Seconds { get; }
    void Begin(Bitmap desktop,
        Rectangle screen, Rectangle her);
    void Draw(Graphics graphics,
        Rectangle screen, Rectangle her,
        double at);
}

Those three interfaces are the whole public API. Everything else in Capri is internal and can change in any update.

Start
runs when the mod turns on and each time she starts. Save capri for later calls
Heard
gets each line you say or type to her, trimmed. Return true and she does nothing else with it
Stop
runs on Off, Remove, re-import and when she quits. Clean up here
Folder
your own folder, mods\<id>-data. It stays after Remove
Say
she says the line word for word, in her bubble and voice, after whatever she's saying now. Cut to 500 characters
Log
adds a line to errors.txt, marked mod <id>
Art
a strip by name, like idle, in her current skin and colours. A new Bitmap each time, so dispose it. null if there's no such strip
Sound
plays arrive, leave, hop, click or bonk. Anything else does nothing
PlayIntro
plays the running intro now

What Heard gets

Typed
every line
Spoken
every line. With Listen for Capri on, only lines with her name or a mod's name in them, and the lines in the chat that name starts
Call mode
only your own words that carry her name, or your answers
Whole line
“Capri, mod check” arrives with her name in it, so search inside the line
All mods
every running mod sees the line, even after one returns true
Never
her system lines, dropped files, screen text or your friends on a call

Threads and errors

UI thread
Start, Heard and Stop run on it. A slow one freezes her, so move long work to your own thread
Constructor
can run on a background thread at startup. Do your setup in Start
Your threads
catch everything. An uncaught error on a background thread ends Capri. Say is safe to call from them
Start throws
on import, the mod saves and turns off. At startup it stays off for that run and tries again next time
Heard throws
counts as not taken. The error goes to errors.txt

Examples: Hello Code keeps a count in its folder, and Dice & Decider is a full one.

Startup intros Windows only

A code mod with // intro: yes whose class also implements ICapriIntro.

red-flash.capri-code
// capri-mod: 1
// id: red-flash
// name: Red Flash
// version: 1.0.0
// author: You
// description: A red flash when she starts.
// intro: yes

using System.Drawing;
using CapriDesktop;

public class RedFlash : ICapriMod, ICapriIntro
{
    public void Start(ICapriHost capri) { }
    public void Stop() { }

    public bool Heard(string words)
    {
        return false;
    }

    public double Seconds { get { return 2; } }

    public void Begin(Bitmap desktop,
        Rectangle screen, Rectangle her) { }

    public void Draw(Graphics g,
        Rectangle screen, Rectangle her,
        double at)
    {
        double left = 1 - at / Seconds;
        int fade = (int)(200 * left);
        using (Brush red = new SolidBrush(
            Color.FromArgb(fade, 255, 0, 70)))
        {
            g.FillRectangle(red, screen);
        }
    }
}
Order
she waits up to 8 seconds for code mods to start, plays the intro, then arrives
Seconds
0 to 15. Longer is cut to 15, and 0 skips it
Begin
runs once. desktop is a screenshot of her screen, or black if that fails. her is where her body sits
Draw
runs about every 15 ms on a clear, click-through window over her screen. at is the seconds so far
Skipped
when Glitch in at startup is off, she's hidden or something's full screen
Two intros
only one plays
Errors
a throw in Begin or Draw ends the intro, and she still arrives
Testing
call capri.PlayIntro() from Heard and skip the restarts

Example: Startup Intros.

Safety and approval

Code mods have full trust

Runs as
part of Capri, with your access to your PC
Can reach
your files, your accounts and the API keys she has saved
Sandbox
none. Her SECURITY settings don't apply to code mods
Her warning
“Nothing limits what it can do, and Capri doesn't check whether it's safe.”

What approval means

Import
she asks every time, even for the same file, and No is the default
The ask
shows the mod's name, version, who it says it's by and the file's SHA-256. Anyone can type any author
No
saves nothing and runs nothing
Yes
saves the file and keeps its SHA-256 in approved.txt
Any edit
one changed byte shows it as CHANGED and turns it off until you approve it again
Each start
she checks the file against its approval before she runs it
Remove
drops the approval. Anything the mod already did stays done

Approval only records that you said yes to that exact file.

Stay safe

  1. Install from the directory, or from people you trust
  2. Read code mods first. Cards mark them RUNS CODE, View opens the mod on GitHub, and a .capri-code file is plain text
  3. Read skills too. They're instructions her brain follows during a game job
  4. Only get Capri from capriai.app or her GitHub
  5. Think a mod took your keys? Remove it, then make new keys on each provider's site
  6. Found a bad mod? Tell us in the Discord

Settings mods, colour sets and skins run no code.

Share a mod

  1. Check your mod imports and works
  2. Fork capri-mods, the directory on GitHub. A free account is enough. On Windows, Publish on your mod's row has the link and Show my mod file
  3. Add a folder, mods/<id>/, with the files below
  4. Open a pull request
Your folder
mods/my-names/
  my-names.capri-mod
  README.md
  preview.png (optional)
README.md
# My Names

She answers to Nova and Big Z.

- Kind: settings mod
Mod file
one per folder, named after its id, so Installed and ratings work
Folder
use the id. Letters, numbers, dots, dashes and underscores, up to 64 characters
README
line 1 is # Name. The first plain line is the description on its card. Your GitHub username shows as the author. Add - Made by: Your name to use a different one
preview.png
optional. Mods without one get a default picture. Around 16:9, up to 2 MB and 4096 px each way. Cards crop it, so keep the subject in the middle
index.json
leave it alone. It's rebuilt after your mod is merged
Updates
open a new pull request with a higher version. People get it with Reinstall
Credit
built on her art or code? Credit the Capri project. Its licence is noncommercial

What gets checked

Every mod
checked for malware before it goes up, without compiling or running it
Skins
skin.json and strips, and nothing else in the zip
Code mods
read line by line for what they do with your files, the web and other programs
Previews
checked before merging
Names
names from other people's shows or games can get flagged

Fixes

Refused files and failed mods also go in errors.txt, beside the mods folder. The Mods page only shows the first problem, so check that file for the rest.

Importing

“That file isn't valid mod JSON.”
A comma or quote is off. Run it through a JSON checker.
“That mod needs format 0, and this Capri reads format 1.”
Add "format": 1.
“That mod doesn't change anything.”
Add wake_names, heard_as, sounds_like, hearing_log or colors. She ignores other keys.
“Skipped …: its file name doesn't match its id, ….”
Rename the file to its id, or use Import mod.

Skins

“… can't be in a skin. Keep every file at the top of the zip.”
Your zip has a folder in it. Select the files themselves and zip those. A Mac's __MACOSX folder counts too.
“… isn't one of her sprite strips.”
Use the names above, with a lowercase .png. Take out anything else, like a README.
She turns back to her own art facing left
That strip's _flipped version is missing.

Skills

“… isn't a header line.”
Only key: value lines with lowercase keys go in the header. Close it with a second ---.
She ignores a skill
Check it's On, then check the game's name in games:. Skills only reach her when she plays the game for you.

Code mods

“A code mod starts with a // capri-mod: 1 line.”
Put it first. A plain comment above it ends the header.
“That code didn't compile, line …”
Hover the message to read it all. Most often it's something newer than C# 5, or a reference she doesn't load.
“That mod failed while starting: … It's saved, and off until you turn it on again.”
Your Start threw an error. The full error is in errors.txt.
“CHANGED, approve it again.”
The file changed since you approved it. Press On to approve the new one.
“Windows only for now”
Mac and Linux can't run code mods.

The directory

“Couldn't reach the mods directory: …”
Check your internet. GitHub also limits how often one address can ask, so try again later.
You don't have a mod's new version
Press Reinstall. She never updates a mod by herself.

Still stuck?

  1. Right-click her > Help > Copy error details
  2. Paste it in the Discord with the mod's name and what you tried

Something out of date? Tell us in the Discord.