Z AI Character Card Wiki

The Last Letter in Personalized Artificial Intelligence

User Tools

Site Tools


specifications:characard

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
specifications:characard [2026/03/18 04:23] tysspecifications:characard [2026/03/18 05:23] (current) – [Implementation Sketch] tys
Line 2: Line 2:
 The CharaCard specification covers three formats and describes its interaction with the PNG specification. As with any community-defined specification, the precise meanings and definitions are somewhat fluid and determined only by a specific implementation. The most common implementations being [[:interfaces:SillyTavern]] and [[:archives:Characterhub|Character Hub]]. This page documents the CharaCard specification, as generally implemented by the myriad of [[:archives]] and [[:interfaces]] which interact with these items - not just the most popular. The CharaCard specification covers three formats and describes its interaction with the PNG specification. As with any community-defined specification, the precise meanings and definitions are somewhat fluid and determined only by a specific implementation. The most common implementations being [[:interfaces:SillyTavern]] and [[:archives:Characterhub|Character Hub]]. This page documents the CharaCard specification, as generally implemented by the myriad of [[:archives]] and [[:interfaces]] which interact with these items - not just the most popular.
  
-===== Overall Structure =====+===== CharaCard Structure =====
 Character Cards are usually distributed as PNG images or JSON text documents. The JSON document directly contains the CharaCard JSON structure, while the PNG contains the same JSON CharaCard structure as metadata. Note that the PNG is **not** a polymorphic JSON/PNG hybrid file, but a fully standards-compliant (if unusually constructed) PNG, with metadata which can be decoded back into a JSON CharaCard structure. Character Cards are usually distributed as PNG images or JSON text documents. The JSON document directly contains the CharaCard JSON structure, while the PNG contains the same JSON CharaCard structure as metadata. Note that the PNG is **not** a polymorphic JSON/PNG hybrid file, but a fully standards-compliant (if unusually constructed) PNG, with metadata which can be decoded back into a JSON CharaCard structure.
  
 When parsing these fields, many implementations omit unsupported fields from generated output. It is recommended to handle invalid/missing fields as gracefully as possible, while populating as many as possible when exporting/generating cards. When parsing these fields, many implementations omit unsupported fields from generated output. It is recommended to handle invalid/missing fields as gracefully as possible, while populating as many as possible when exporting/generating cards.
  
-===== CCv1 =====+==== CCv1 ====
 Version 1 was created with [[:interfaces:TavernAI]], and is long obsolete. This standard is not backwards compatible and provided as a matter of historical interest. All fields are required and utilized as part of prompt generation. Version 1 was created with [[:interfaces:TavernAI]], and is long obsolete. This standard is not backwards compatible and provided as a matter of historical interest. All fields are required and utilized as part of prompt generation.
  
Line 19: Line 19:
 | scenario | String | Specific scenario that the Card and user are engaging with. | | scenario | String | Specific scenario that the Card and user are engaging with. |
  
-===== CCv2 ===== +==== CCv2 ==== 
-===== CCv3 =====+==== CCv3 ====
 CharaCard Version 3 is backwards compatible, adding only optional, additional fields. CharaCard Version 3 is backwards compatible, adding only optional, additional fields.
  
Line 101: Line 101:
  
 ===== PNG ===== ===== PNG =====
-PNG metadata description coming soon.+PNG file is far more than an array of bytes forming an image. While some interfaces can retrieve data from disordered chunks or incorrectly typed metadata, the following specifications seem to define the only reliable way to build Character Cards for various interfaces. 
 + 
 +==== Chunk Organization ==== 
 +"A PNG file consists of a PNG signature followed by a series of chunks," (via [[https://www.libpng.org/pub/png/spec/1.2/PNG-Structure.html|libpng]]). While the precise and beautiful design of the format is beyond this page, we can consider a PNG to have the following chunks: 
 +  * Header (IHDR) 
 +  * Image (PLTE, IDAT, etc.) 
 +  * End (IEND) 
 +CharaCard metadata is required to inhabit an tEXt metadata fragment. While metadata is typically placed after the header and before the image (exiftool warns of this). However, CharaCard (and several implementations) require this tEXt metadata chunk to appear at the very end of the PNG, immediately before the End. The resulting structure should be in the following format: 
 +  * Header (IHDR) 
 +  * Image (PLTE, IDAT, etc.) 
 +  * **CharaCard Metadata (tEXt)** 
 +  * End (IEND) 
 + 
 +==== tEXt Chunk Composition ==== 
 +The tEXt Chunk is specified [[https://www.libpng.org/pub/png/spec/1.2/PNG-Chunks.html#C.tEXt|here]]. Essentially, it has a "keyword" and "text" field. While your API may vary, this keyword field must be set to "chara" for CCv2 metadata, and "ccv3" for CCv3 metadata. If building a CCv3 card, it is wise to duplicate the structure to the "chara" key as well. The "text" is a CharaCard JSON structure that has been base64 encoded. 
 + 
 + 
 +==== Implementation Sketch ==== 
 +[[https://www.libpng.org/|libpng]] is one of few libraries capable of precisely constructing a PNG in this way. What follows is a sketch of how [[:interfaces:LocalTavern]] uses libpng to take an input PNG and set the metadata. 
 + 
 +<code c> 
 +//prepare in_png with png_create_read_struct 
 +//prepare out_png with png_create_write_struct 
 +//prepare in_info and out_info with png_create_info_struct(in/out_png) 
 + 
 +//configure in_png to read from file/memory 
 +png_read_png(in_png, in_info, PNG_TRANSFORM_IDENTITY, NULL); 
 + 
 +//At this point, in_png and in_info have the input file successfully prepared 
 +//  out_png and out_info are ready for writing, but are currently blank. 
 + 
 +//Build png_text structures for tEXt as follows: 
 +//key_count could be 1 or 2 depending on chara or ccv3 and chara 
 +png_text *text_chunks = (png_text *)malloc(sizeof(png_text) * key_count); 
 +for (int i = 0; i < key_count; i++) { 
 +  text_chunks[i].compression = -1; 
 +  text_chunks[i].key = key; //pointer to key (chara/ccv3) 
 +  text_chunks[i].text = data; //pointer to data (base64-encoded JSON) 
 +  text_chunks[i].text_length = data_len; 
 +  text_chunks[i].itxt_length = 0; 
 +  text_chunks[i].lang = NULL; 
 +  text_chunks[i].lang_key = NULL; 
 +
 + 
 +//modify read PNG to remove any tEXt fields. 
 +png_free_data(in_png, in_info, PNG_FREE_TEXT, -1); 
 + 
 +//At this point, write fields from read PNG into the write PNG fields 
 +png_write_info(out_png, in_info); 
 + 
 +//Write image chunks 
 +png_bytep *row_pointers = png_get_rows(read_png, read_info); 
 +if (!row_pointers) { 
 +  fprintf(stderr, "No IDAT (image data) found in image\n"); 
 +  exit(1); 
 +
 +png_set_text(out_png, row_pointers); 
 + 
 +//Specify the tEXt metadata 
 +//This has to be performed after image chunks have been written to place the tEXt correctly. 
 +png_set_text(out_png, in_info, text_chunks, key_count); 
 + 
 +//Closeout written PNG 
 +png_write_end(out_png, in_info); 
 + 
 +</code> 
 +Note that this is only a sketch - memory management, file I/O, and further implementation is left as an exercise for the reader.
  
 ===== Other CharaCard "Standards" ===== ===== Other CharaCard "Standards" =====
specifications/characard.1773807788.txt.gz · Last modified: by tys