Creator docs

Beautify Spec

Updated · 2026-07-07Public document

This is the mechanics reference for Foreverse chat beautify: what a single message can contain (HTML / fv-card / stickers), how the full-card beautify rendering pipeline works, and where the regex engine stops. Every entry matches real app behavior, so cards written against this spec render immediately after import.

Quick start

Fastest path: send the prompt below to any AI, ask it to generate beautify code for you, then place the result in a character card greeting or message to test the render.

请生成一段用于聊天气泡的自包含 HTML + 内联 <style>。
需求:紫色渐变主题的状态栏卡片,白色描边,圆角,顶部一行标题。
约束:不要引用外部资源(图片/字体/JS 库都不行);不要用 min-height: 100vh;
所有样式写在一个 <style> 里;宽度自适应容器。

Put the full generated result inside a ```html fence when sending it. Foreverse will render that message with the built-in WebView using your styles. "Don't reference external resources" is not a suggestion; it's a sandbox rule. See below.

Single-message syntax

An AI reply is split into segments in order, and each segment is rendered by the syntax it matches:

SyntaxRendered asNotes
```html … ```Rich WebView renderFull HTML/CSS renders as the author intended; each fence gets an isolated iframe scope and reports its height automatically
Bare HTML blockRich WebView renderWithout a fence, paired <div> / <section> / <style> / <table> / <svg> / <details> / <center> tags also go through WebView
```fv-card … ```Native mini cardThe fence contains JSON. It doesn't use WebView; the app renders it natively. Fields are listed below
[[sticker:name]]Sticker imageName length <= 40 characters; loads the same-name image from this companion's stickers/ folder and falls back to a text badge if missing
Other textPlain bubbleRendered with basic markdown syntax

fv-card fields (v1 · three types)

FieldTypeNotes
typestringnote (small note) / countdown (countdown date) / mood (mood card); unknown values render as note for forward compatibility
titlestringCard title; title or body must have at least one non-empty value, or the card won't render
bodystringBody text, optional
datestringUsed by countdown, yyyy-MM-dd; the app calculates "N days left / today / N days ago" automatically
emojistringUsed by mood cards
accentstringAccent color #RRGGBB; when empty, the current character accent color is used
```fv-card
{ "type": "countdown", "title": "见面纪念日", "date": "2026-08-14", "accent": "#8b5cf6" }
```

Full-card beautify pipeline (status bars / chain of thought / clickable options)

To make the model output themed status bars, collapsible chain-of-thought blocks, or clickable options every turn, use the same three-stage pipeline as desktop Tavern:

模型输出纯文本 marker  →  卡内美化正则替换成主题化 HTML  →  WebView 渲染

Three hard rules. Break any one and it won't render:

  • Markers must be plain text symbols (such as :::think, [状态|…], :::scene, :::note, :::opt). Don't use <tag> as a marker. Import-time cleanup strips raw HTML from card text fields. HTML is only allowed in the regex replaceString.
  • Beautify regex rules should set placement: [2] (AI output) and markdownOnly: true (run only at display time, without polluting the history sent back to the model).
  • When a card includes an HTML beautify regex, import automatically turns on rich rendering for that card. Users don't need to set it manually.
Macros like {{char}} / {{user}} expand only during the prompt phase sent to the model. They do not expand at display time. Don't depend on macros inside display fields such as status bars. Write the character name directly, or have the model include it in output.

Regex rules

FeatureSupport
Capture group references$1$99, $<name>, {{match}}
Variable-length loops / recursive replacementNot supported. Components such as status bars need a fixed number of fields (demo cards use 4 fixed fields)
Scopeplacement controls whether it applies to user input / AI output; markdownOnly controls display-only replacement without rewriting history sent back to the model
Safety fallbackIf a regex replaces content with empty text, the original text is shown instead. No blank screen

WebView features and limits

Rich-render WebView matches desktop Tavern rendering semantics while running inside a mobile sandbox. Capability list:

ItemBehavior
Inline CSS / JSSupported; each html fence gets its own isolated iframe scope
HeightAutomatically reports scrollHeight to expand the bubble; don't use viewport-filling styles such as min-height: 100vh
External resourcesBlocked: file / content access is disabled, remote JS libraries such as jQuery CDN are unavailable; external-link taps are handed to the system browser
TavernHelper host APISupports triggerSlash (/setinput, /send, /trigger, and so on), getChatMessages, getCurrentMessageId, getWorldbook; generate() / generateRaw() can trigger real second-pass generation
Clickable optionsOptions / buttons / links disable text selection while body text can still be selected. Tapping an option won't accidentally select text
Sensitive informationContent shaped like token: value is redacted to *** before entering model context

The goal is for beautified cards tuned on desktop to behave the same on phone. If you hit a rendering difference, send the card and screenshots to [email protected], and we'll treat it as P1.

Beautify Spec — Chat Cards, Stickers, HTML Rendering · Foreverse · Xinmeng