Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

208 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Comic Chat Web

Modern TypeScript port of the 1996+ Microsoft Comic Chat IRC client w/ Cloudflare Durable Objects as the network layer.

450 tests passingChecked with Biome

Live demo comics.remsky.art
Create a custom comic strip comics.remsky.art/studio
Create with AI assistance comics.remsky.art/agent-skill

Features

The composition rules follow the SIGGRAPH '96 Comic Chat paper and original works: (credits).

Validated against traces from an instrumented C++ client of the original to accurately reproduce the original engine including:

  • Original character cast and artpacks, automatic panel layout
  • Emotion detection, speech balloon splines
  • Avatar posing, reactive angles and camera
Screenshots
Comic Chat Web interface showing a three-panel conversation, member list, avatar, and emotion wheel Comic Chat Web mobile view showing a three-panel conversation with the mobile toolbar Comic Chat Web connection screen with room, nickname, and character selection controls
Modern tweaks and commands

Slash Commands/Gestures:

Typing / will list gestures the character you are wearing has art for: most carry three or four, some none.

The command text itself is stripped from messages. Gesture commands reach pose art found in the files that did not otherwise seem accessible. The original stores these under codes above the emotion ring which appears skipped by GetBodyFromEmotion.

/wave /shrug 
/point /pointself /doublepoint
/walk /walkup /walkaway

Defaults

These are by default and control some quality-of-life changes not in the 1996 client. Turn it off to get closer to the original behavior.

Tweak On Off
Balloon text Smaller unit, more text per panel 1996 metrics
Cast Two people on one character share a panel Same character always splits into separate panels
Background picker Thumbnail grid Dropdown
@nick Opens a menu of who is here; picking one inserts the plain nick Literal text
/gesture Poses the avatar Literal text

Naming someone points your avatar at them, and being named highlights that line and adds an * to the tab title. Both work off the bare name, with or without the @. Anyone can wear any character, so some composition rules were adjusted to key by nickname and avatar. Optional nametags can be enabled if it feels confusing.

Studio

An integrated editor allowing you to create strips (panel by panel) on your own is available at /studio

The result is exportable as a PNG sheet or square, as an MP4 or GIF that plays the panels in order, or import/export as its JSON definition document. It's pretty fun to tool around with.

  • Available art per character is generated as an asset list in catalog.json.
  • Includes art, combinations, and control not reachable in normal chat (sizing, direction, gestures, etc).
  • The MODERATION variable acts similarly to how it does in chat, putting a pause on rendering. See DEPLOYMENT.md.

For assistance from an AI agent to spin up some strips, a skill is available. It has understanding of the poses, backgrounds, characters, limitations, and can generate a condensed link that will prefill the editor page for review/adjustments/download. See /agent-skill for details or use one of the following methods:

npx skills
npx skills add remsky/comic-chat-web 
zipped .skill file

Download comic-strip.skill from the latest release and drop it into a chat on ChatGPT or claude.ai as a custom skill.

Claude Code Plugin
/plugin marketplace add remsky/comic-chat-web
/plugin install comic-strip@comic-chat-web
OpenAI Codex Plugin
codex plugin marketplace add remsky/comic-chat-web
codex plugin add comic-strip@comic-chat-web

Screenshots
Comic Chat Studio panel list with the Save menu open and the JSON pane below the panel constructor Comic Chat Studio showing a rendered five-panel strip above the panel list and character controls
Sample JSON
{
  "version": 2,
  "columns": 5,
  "panels": [
    {
      "background": "volcano",
      "camera": "close",
      "actors": [
        {
          "avatar": "kevin",
          "text": "It's not the worst studio",
          "emotion": "shout"
        },
        {
          "avatar": "denise",
          "text": "Pretty decent options",
          "facing": "left"
        }
      ]
    },
    {
      "background": "volcano",
      "zoom": 1.3,
      "actors": [
        {
          "avatar": "kevin",
          "text": "Wait. We're also over there?!",
          "emotion": "shout",
          "gesture": "pointself",
          "facing": "left"
        },
        {
          "avatar": "denise",
          "text": "Don't worry about it",
          "emotion": "laugh_1",
          "gesture": "wave",
          "facing": "left"
        }
      ]
    }
  ]
}

Deployment / Self-Hosting

Deploy to Cloudflare

Note

See DEPLOYMENT.md before deploying to understand the parameters available, and what a fork inherits.

Quick Details

Rooms are anonymous (no accounts); moderation is rudimentary: a content filter with escalating mutes. A deploy is bounded by its fixed room list, and public billed deployments must determine and set Cloudflare rate-limiting rules and usage alerts to avoid any suprising bills. On Free Tier, it will simply stop running until end of day if limits are reached. For reference, the traffic on this repo's demo sits comfortably under 10% of daily Free Tier usage.

Reception

Sampled from the live rooms as rendered; without attributions

Screenshots
Four-panel strip: dude this is cool, this brings back memories, how cool is this, on a scale from 1 to 10? 47!, is teleported back to 1996
Four-panel strip: aliens greeting each other, one testing a very long message across two panels, and a reply that they have not thought about Comic Chat in decades
Four-panel strip: does the world know it exists, how does this work, waouh, this is so based, they have the internet on computers now

Technical

Local Run

Spin up locally to test via:

git clone https://github.com/remsky/comic-chat-web
cd comic-chat-web
npm install
npm run preview:worker
Testing
npm ci
npm run dev          # Vite dev server at localhost:5173
npm test             # both vitest projects: node + worker
npm run test:browser # Playwright desktop + mobile smoke; wants `npm run dev:api` up for the studio's screen call
npm run check        # biome + strict tsc over src, worker, test, and tools

npm test runs two vitest projects, selectable with --project:

Project Runs in Covers
node (test/) node Engine units and golden trace suites
worker (test/worker/) workerd, via @cloudflare/vitest-pool-workers Durable Object behavior against real SQL storage and the live WebSocket protocol

Worker tests get isolated storage per test and read their bindings from wrangler.jsonc. They typecheck under their own test/worker/tsconfig.json, since workers types collide with the node and DOM types the rest of the suite uses.

Trace validation

The engine is validated against JSONL traces from an instrumented C++ client, the Comic Chat trace harness:

Trace Validation focus
smoke-01 Core two-speaker flow, balloon modes, emotions, and panel breaks
balloon-01 Interleaved say, think, whisper, and shout balloon geometry
edge-01 Single-character, punctuation-only, and repeated messages
emotion-01 Shouting, laughter, greetings, smileys, pointing, and waving rules
long-01 Multi-panel overflow, retries, continuation, and three-speaker ordering
speakers-01 Six-speaker avatar selection, placement, flipping, and ordering
wrap-01 Long text, wrap boundaries, URLs, and unbreakable words
Art pipeline

All steps are deterministic and byte-reproducible, sourced from a sibling checkout of the Comic Chat trace harness:

  • npm run assets:avatars: packed per-character avatar atlases and runtime manifest in public/assets/avatars/ from the original .avb files.
  • npm run assets:backgrounds: backdrop PNGs in public/assets/backgrounds/ from the original .bgb files.
  • npm run fixtures:avatars: the test fixture.

Related projects to check out

License and attributions

This unofficial port builds on the original Microsoft Comic Chat client and the efforts of those who preserved it.

  • Jim Woodring: created the original character cast, poses, and backgrounds
  • Vincent Connare: designed Comic Sans, the typography of Comic Chat's speech balloons
  • David Kurlander: original creator and lead developer of the Microsoft Comic Chat engine (1995)
  • Tim Skelly and David Salesin: co-authors, with Kurlander, of the SIGGRAPH '96 Comic Chat paper defining the panel layout, balloon placement, and avatar composition algorithms reproduced in this port
  • Robert Standefer and Scott Hanselman: facilitated the 2026 open-source release of the original Microsoft repository

Except for the third-party material identified below, this project is licensed under the GNU Affero General Public License v3.0 only. If you operate a modified version over a network, the AGPL requires you to offer its corresponding source to the people using it.

Microsoft-derived code and artwork retain Microsoft's MIT license and notice. See Third-Party Notices and the preserved Microsoft MIT license for details.

This is an unofficial community project and is not affiliated with or endorsed by Microsoft; based on the open-source Microsoft Comic Chat repository.

About

Modern port of Microsoft Comic Chat 1996 on Cloudflare Durable Objects || Create custom strips & live demo at comics.remsky.art

Topics

Resources

Contributing

Stars

9 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages