varg-consistent-characters
Makes multi-scene ad videos on varg in which the same people, outfits and location stay consistent in every shot, built from real actor photos or generated characters: one profile card per actor, an empty location card, scene composites approved as stills first, then image-to-video with native dialo…
Install / Use
npx skills add hashgraph-online/awesome-codex-plugins --skill varg-consistent-charactersInstalls into whichever agent you are using.
SKILL.md
Installable skill definition
Quality Score
Category
Development & EngineeringSupported Platforms
Our assessment of varg-consistent-characters
varg-consistent-characters scores 85/100 on our quality scale, 2734th of 4,651 Development & Engineering skills we index.
Its SKILL.md is 18 KB long, well organised into 30 sections with 16 code examples: a thorough specification that gives an agent plenty to work with.
With 1,075 GitHub stars, it is one of the more widely adopted skills in the catalogue.
Maintenance, license and trust
- The repository was last updated about 2 months ago, so varg-consistent-characters is actively maintained.
- It is released under the Apache-2.0 license, a permissive license that allows use, modification and commercial use with attribution.
- Its trust signals score 100/100, with no cautions. These come from repository metadata, not a code audit — read the skill file before letting an agent act on it.
varg-consistent-characters compared with similar skills
All 4 of these similar skills score higher than varg-consistent-characters; compare them before choosing.
| Skill | Score | Stars | Updated | Format |
|---|---|---|---|---|
| varg-consistent-characters (this skill)by hashgraph-online | 85 | 1.1k | 46d ago | SKILL.md |
| taste-skillby Leonxlnx | 100 | 112.1k | today | CLAUDE.md |
| ai-job-searchby ai-job-search-dev | 100 | 70.6k | today | CLAUDE.md |
| claude-howtoby luongnv89 | 100 | 46.8k | 6d ago | CLAUDE.md |
| lobehubby lobehub | 100 | 84.5k | today | MCP Server |
Frequently asked questions
- How do I install varg-consistent-characters?
- Run
npx skills add hashgraph-online/awesome-codex-plugins --skill varg-consistent-characters. The install tabs above show the steps for each supported agent. - Which AI agents does varg-consistent-characters work with?
- It is written for Universal, as a SKILL.md file. Other agents that read the same format can often use it too.
- Is varg-consistent-characters safe to use?
- It is Apache-2.0-licensed and scores 100/100 on trust signals. Skills are instructions an agent will follow, so read the file before installing it and do not approve commands you do not understand.
- Is varg-consistent-characters still maintained?
- The repository was last updated about 2 months ago, so varg-consistent-characters is actively maintained.
Skill content
View source on GitHubname: varg-consistent-characters description: >- Makes multi-scene ad videos on varg in which the same people, outfits and location stay consistent in every shot, built from real actor photos or generated characters: one profile card per actor, an empty location card, scene composites approved as stills first, then image-to-video with native dialogue audio, trimmed and captioned in one cloud render. Also covers frame and audio QA of the output and turning a reference video into a scene script. Use when a script names actors (A1, A2), a location (L1) and numbered scenes, when someone sends actor or model photos, or asks for a consistent character, the same person in every scene, a recurring mascot or brand character, a UGC or skit ad with two actors, or to remake a reference ad with new people. Not for one speaker on a stage (use varg-character-keynote), seated two-person podcast dialogue (use varg-podcast-video), music videos (use varg-music-video), or one-off images and clips (use varg-ai). license: MIT metadata: author: vargHQ version: "1.0.0" openclaw: requires: anyBins: - curl - bun homepage: https://varg.ai compatibility: >- Needs a VARG_API_KEY (see the varg-ai skill) or the varg MCP connection (https://mcp.varg.ai/mcp). The images-only approval script needs bun; the final render runs in the cloud with curl. QA uses ffmpeg/ffprobe locally. allowed-tools: Bash(bun:) Bash(bunx:) Bash(curl:) Bash(jq:) Bash(ffmpeg:) Bash(ffprobe:) Bash(nohup:*) Read Write Edit
varg consistent characters
Turn a scene script + actor photos into a multi-scene vertical ad where characters, outfits and location stay consistent across every cut. Tested on a 5-scene, 22-second 9:16 fitness ad with two real actors in one gym.
Generation runs on varg: the varg-ai skill (sign-in, models, local and cloud render) or the varg MCP server (https://mcp.varg.ai/mcp). This skill assumes a working VARG_API_KEY or MCP connection.
Core idea: cards, then composites
Never describe characters from scratch in every scene prompt. Build a small set of frozen reference images once, then compose every scene from them.
photo A1 ──edit──> a1Card ─┐
photo A2 ──edit──> a2Card ─┼──edit──> scene1..N ──image-to-video──> vid1..N
prompt ──gen───> gymLoc ─┘
Upload the actor photos first (POST /v2/files, or the MCP upload tools) and use the returned URLs.
No actor photos? Design the cast with varg-character-design (archetypes, a model sheet per character on flat grey) and use each character's full-body crop as the profile card below.
1. Consistency
1.1 Character profile cards
One image-edit call per actor, from their photo:
const a1Card = Image({
prompt: {
text: "Full-body character reference card of the exact same woman from the photo: same face, same grey hair, same body shape. <age/build>. She wears <FIXED OUTFIT, described precisely>. Standing straight facing camera, neutral relaxed pose, arms at her sides. Plain light grey studio background, even soft lighting, head-to-toe framing, photorealistic",
images: [A1_PHOTO_URL],
},
model: varg.imageModel("nano_banana_2_1"), // edits when images are passed
aspectRatio: "9:16",
});
Rules that make cards work:
- "exact same ... from the photo: same face, same hair, same body shape" anchors identity to the reference instead of the text description.
- Fix the outfit in the card. The card's clothes become the outfit for the whole video. Pick it so the script works (e.g. arms or legs visible if scenes point at them). Never re-describe clothes differently later.
- Full body, neutral pose, plain studio background: a clean card composites into any scene; a scene-styled card does not.
The pipeline was first built with Nano Banana Pro edit; nano_banana_2_1 is its successor and varg's default. For the hardest identity cases try gpt_image_2_5.
1.2 Location card
One text-to-image generation, no people:
const gymLoc = Image({
prompt: "Empty modern gym interior with huge floor-to-ceiling windows... No people. ... photorealistic, 9:16 portrait framing",
model: varg.imageModel("nano_banana_2_1"),
aspectRatio: "9:16",
});
An empty location card lets every scene reuse the same walls, light and floor without characters from a previous scene leaking in.
1.3 Scene composites
Every scene is one edit call with all three refs:
const SAME =
"First reference image is Woman A (<short recap of card>). Second reference image is Woman B (<short recap>). Third reference image is the gym location with huge windows. Keep both women's faces, hair, bodies and outfits exactly as in their reference cards, and the gym exactly as in the location reference.";
const scene2 = Image({
prompt: { text: `${SAME} <scene-specific framing, poses, gestures>`, images: [a1Card, a2Card, gymLoc] },
model: varg.imageModel("nano_banana_2_1"),
aspectRatio: "9:16",
});
- The
SAMEpreamble is shared verbatim across all scenes. It names each reference by position ("First reference image is...") and pins identity. - Image edit models take several refs fine. For Video, one image = the first frame; several images switch to reference mode, which only some models support (see
varg-ai). - Scene text only describes what changes: camera framing, poses, gestures, expressions.
1.4 Cache discipline (critical)
Identical prompt + params = free cache hit, both locally and server-side on api.varg.ai. This is what makes the whole pipeline cheap:
- Keep prompts byte-identical between the images-only script, the local template and the cloud template. Copy-paste, never retype.
- The full 5-scene video re-rendered in the cloud for a few credits (the stitching fee) because every image, video and music prompt matched the earlier runs.
- Editing one scene's prompt regenerates only that scene; everything else stays cached.
1.5 Content-moderation gotcha
Body-part wording such as "rear" or "booty" in an image prompt can silently stall generation for ~10 min (provider moderation). Rephrase to neutral anatomy: "hips and thighs". The same words inside spoken dialogue in video prompts passed fine.
Fitness and swimwear scenes trip filters on words, not pictures: "girl" instead of "woman, 28", "tight", "bikini" and short prompts without a garment description get blocked on GPT Image 2.5, FLUX 3 and Grok, while a catalog-style prompt (adult age as a number, each garment named, an activity, "activewear brand catalog photo") passed on all six image models we tried. A block can be random: retry once, then rephrase, then route. Test log, safe-phrasing table and routing: varg-character-design → references/moderation.md.
2. Photos-for-approval pass (images first)
Generate and show all stills before paying for any video. A still costs a few credits; a video clip costs ten times more or more. Approve the cheap layer first.
Standalone script pattern (<project>-images.ts, run with bun):
import { Image } from "vargai/react";
import { createVarg } from "vargai/ai";
const varg = createVarg({ apiKey: process.env.VARG_API_KEY! });
// ... define a1Card, a2Card, gymLoc, scene1..sceneN exactly as in 1.x ...
async function save(name: string, el: ReturnType<typeof Image>) {
const resolved = await el; // await triggers generation (cached)
await Bun.write(`output/<project>/${name}.png`, await resolved.file.data());
}
// cards + location first, then scenes (scenes reference the cards)
await Promise.all([save("a1-card", a1Card), save("a2-card", a2Card), save("location", gymLoc)]);
await Promise.all([save("scene1", scene1), /* ... */]);
Key facts:
Image({...})is a lazy thenable:awaitresolves it,.file.data()gives the bytes. Awaited results are cached, so the later video render reuses them for free.- Run it in the background (
nohup bun run <project>-images.ts > images.log 2>&1 &) and report the PID. - Show the user: the cards + location + every scene. Iterate on individual scene prompts (only the changed one regenerates) until approved.
No bun? Generate the same stills one by one with POST /v2/image (or MCP generate_image), passing the references in files. Keep the prompts identical to the ones you will use in the render.
3. Final render: cloud (POST /v2/render)
After the stills are approved, wrap them in videos + composition and submit the whole TSX to the cloud. No bun or ffmpeg needed on the machine that submits.
3.1 Video layer: image-to-video with native audio
Dialogue is written into the video prompt and the model voices it:
const vid2 = Video({
prompt: {
text: `Same gym with huge windows. <scene action, static camera>.
The trainer says matter-of-factly: "<the scene's line>"
Soft gym ambient sounds.`,
images: [scene2], // exactly ONE image = the first frame
},
model: varg.videoModel("kling_v4"),
audio: "native", // generates and keeps the dialogue audio
duration: 4, // integer seconds (kling_v4: 3-30)
});
- Quote dialogue lines verbatim in the prompt; add a voice direction ("clear encouraging voice", "matter-of-factly").
- Budget ~1 s of dialogue per ~2.5 words, then trim (3.3).
kling_v3is what this pipeline was first tested on and still works the same way (integer 3-15 s);kling_v4is the current Kling.seedance_2_5gives the best faces and lip movement at a higher price.- Native audio needs
audio: "native". A flatproviderOptions: { varg: { generate_audio: true } }is silently dropped and you get a silent clip.
3.2 Cloud TSX rules
POST https://api.varg.ai/v2/render with {"code": "<tsx>"} (MCP: render_video with code):
- No imports, no
createVarg:Render/Clip/Image/Video/Music/Captionsandvargare injected as globals. Local LSP errors on this file are expected and fine. - Must
export default (<Render ...>...); no named exports. - Same
varg.*Model()ids as local.
Price it first (MCP estimate_cost with tool render and the code, or POST /v2/estimate on each clip's request) and get the user's go-ahead. Then submit and poll:
curl -s -X POST https://api.varg.ai/v2/render \
-H "Authorization: Bearer $VARG_API_KEY" -H "Content-Type: application/json" \
-d "{\"code\": $(jq -Rs . < template-cloud.tsx)}"
# -> {"id":"job_xxx",...}; poll every 15s:
curl -s https://api.varg.ai/v2/jobs/JOB_ID -H "Authorization: Bearer $VARG_API_KEY"
# completed -> output.outputs[0].url (s3.varg.ai mp4)
If all prompts match a previous run, the cloud render costs a few credits (server cache) and finishes in ~2 min.
3.3 Dynamic pacing: trim dead air
Generated clips have ~0.2-0.5 s of warm-up and often trailing silence. Detect speech boundaries on the generated clips, then cut tight:
ffmpeg -i scene.mp4 -af "silencedetect=noise=-35dB:d=0.35" -f null -
<Clip cutFrom={0.2} cutTo={5.6} duration={5.4}>{vid1}</Clip> // cut right after the line ends
This took the test video from 27 s to 22.4 s with no content loss.
Keep Music duration an integer: a fractional total like 22.4 failed with a 422 on ElevenLabs music. Round down.
3.4 Centered captions in the cloud (inline SRT)
<Captions> transcribes Speech elements by itself. For dialogue that lives in a video's native audio, the tested route is two passes (newer vargai builds also accept src={vid.audio}; if the render rejects that with "Captions src must be ...", use this route):
- Render once without captions (cloud or local).
- Upload the audio and transcribe it on varg:
POST /v2/files(upload) ->POST /v2/transcriptionwith{"model":"whisper_large_v3","audio_url":...}. The result has word-level timestamps. - Build a word-level SRT; fix Whisper mishears (product names, unusual words). Captions'
Truncated for display — read the full file on GitHub.
Related Skills
taste-skill
112.1kAgent skills that give coding agents taste: art direction, reference images and a browser check instead of generic AI pages
ai-job-search
70.6kThe job search that runs on your machine. AI job application framework built on Claude Code: evaluate postings, tailor CVs, write cover letters, prep interviews. Fork it and own it.
claude-howto
46.8kA visual, example-driven guide to Claude Code — from basic concepts to advanced agents, with copy-paste templates that bring immediate value.
lobehub
84.5k🤯 LobeHub - Super-Agents on Your Team. Add super-agents to the chats your team already uses.They take on work by themselves and get better every week.
Languages
Trust signals
From repository metadata: license, adoption, age and documentation. Not a code audit — see the Safety scan above for what the skill file itself contains.
