pokemonlive README

The project's README from github.com/xflare-bot/pokemonlive. As one markdown file: README.md.

Pocket Battle Lab

Choose a move. Watch the battle come to life.

Rule-driven Pokémon battles, brought to life with AI-generated 2D animation.

Turn-based singles · Pixel UI + anime video · Chinese / English / Japanese

Preview · Quickstart · Architecture · APIs · Development

[!NOTE] Unofficial, local, non-commercial learning prototype. Read the setup instructions and limitations before running.

Preview

Battle overview with anime-style idle video and pixel-style status panels
Actual desktop gameplay · Chinese UI · Existing local idle video

Players choose moves, the rules engine resolves the battle, and AI turns the results into a continuous animated sequence. Videos play inside the battlefield, without a separate player modal.

Rules first Anime presentation Continuous playback
Code resolves hits, damage, and status. Hand-drawn, cel-shaded video over a retro pixel UI. Prewarm upcoming assets; hold the last frame if the next clip is late.
More screenshots — move selection

The move panel displays type, power, PP, and relevant type-effectiveness hints.

Move selection

Generation endpoints were disabled during screenshot capture. No additional paid assets were generated.

The Experiment

When generating a short video takes about as long as—or less time than—playing it, could a game generate its next cinematic from the player's latest choice instead of relying entirely on prerecorded animations?

This project explores that idea through familiar Pokémon battles: the player gives an order, the trainer calls out a move, the Pokémon responds, attacks, takes a hit, and returns to a standoff. The goal is to generate the next segment while the previous one plays, preserving character identity, move effects, and status conditions across shots.

[!NOTE] This is a working experimental pipeline, not a promise of fixed generation times or zero waiting. Queueing, generation, transfer, and decoding all affect the experience.

Quickstart

Requirements: Node.js, npm, and FFmpeg. The locally verified environment uses Node.js 24 and FFmpeg 8.1. Make ffmpeg available on PATH or set FFMPEG_PATH.

1. Install and configure

npm ci
# First-time setup only; do not overwrite an existing .env.local
cp -n .env.example .env.local

Edit .env.local with your own keys:

DEEPSEEK_API_KEY=replace_with_your_deepseek_key
FAL_KEY=replace_with_your_fal_key
FAL_VIDEO_RESOLUTION=480P
MINIMAX_API_KEY=replace_with_your_minimax_key

2. Start the server

Load the environment file explicitly:

node --env-file=.env.local server.mjs

Open http://localhost:4173/. If the variables are already set in the process environment, you can also use npm start. The --env-file option ensures that the DeepSeek key, resolution, and other variables are loaded together; do not assume the service automatically reads every setting from .env.local.

3. Optional settings

PORT changes the port; DEEPSEEK_MODEL overrides the planner model; FAL_VIDEO_RESOLUTION accepts 480P or 768P for attack generation. Without a planner key, local storyboards are used. Without video or speech keys, the corresponding generation features are unavailable, but the rules engine and local presentation can still run.

Billing and Caching

Architecture

The rules engine owns the outcome. AI owns the presentation.

The stack is vanilla HTML / CSS / JavaScript, a Node.js HTTP server, multiple HTMLVideoElement players, and local FFmpeg. There is no frontend framework or Three.js runtime dependency.

flowchart LR
    A["Battle engine<br/>Resolve actions + snapshot state"] --> B["Shot planner<br/>DeepSeek or local fallback"]
    B --> C["Prompt validation<br/>Rebuild from battle facts"]
    C --> D["Video pipeline<br/>fal generation + buffered playback"]
    D --> E["Closing sequence<br/>State-matched idle"]

    classDef rules fill:#fff0ad,stroke:#b58b00,color:#242f40
    classDef planning fill:#e5efff,stroke:#3562a5,color:#242f40
    classDef media fill:#ffe4df,stroke:#d45850,color:#242f40
    classDef idle fill:#e4f2d6,stroke:#60884b,color:#242f40
    class A rules
    class B,C planning
    class D media
    class E idle
Battle state, storyboards, and status continuity
  1. Battle state: A pure JavaScript rules engine resolves action order, hits, damage, type multipliers, status conditions, and fainting, then emits events and before/after snapshots. AI does not decide who hits, how much HP is lost, or who wins.
  2. Storyboard: DeepSeek returns only compact shot fields: outcome timing, cut points, shot sizes, and camera movement. The application validates these fields and rebuilds full prompts from the actual moves and results. The frontend allows 3 seconds for planning; a timeout or invalid output selects a deterministic local storyboard.
  3. Video: Each recorded action normally gets one 5-second clip, combining close-ups, action shots, and reactions. The sequence is not fixed at six clips. Inability to act due to paralysis, sleep, or freezing, as well as confusion self-damage, receives its own treatment based on the battle record.
  4. State continuity: Prompts carry both existing and newly applied conditions. A sleeping Pokémon must not wake without a corresponding game event, and a camera cut must not remove freezing. Collapse and spiral eyes are requested only for an actual faint. Caches distinguish the active pair, status conditions, language, and asset version; ordinary HP changes do not regenerate idle clips.
Playback, prewarming, switching, and closing sequences
  • Move selection: A local trainer-silhouette clip plays alongside the MiniMax move callout, followed by a state-matched Pokémon response close-up. Planning and first-clip generation proceed in the background. If the response clip is not ready in time, the existing fallback is used rather than waiting indefinitely.
  • Identity and opening frame: A matching response clip, scene frame, or previous turn's tail frame lets Turbo continue the scene. Without a suitable anchor, the Reference model receives anime-style images of both Pokémon. These references preserve identity; they do not require pixel-art output.
  • Frame continuity: Once an attack clip is generated, cloud extraction returns its final frame as an HTTPS image URL for the next clip. This avoids waiting for a full local download, extraction, and upload. Clips that depend on the previous tail frame still generate sequentially; they cannot all run in parallel.
  • Playback and downloads: The first clip starts as soon as it is buffered and decoded, without waiting for the second. Three video slots handle active playback, preloading, and frame holding. If the next clip is late, the current tail frame remains visible until the next real frame is ready. Playback and archiving share one upstream GET; local Range playback requests no longer trigger upstream Range downloads.
  • Switching Pokémon: Trainer raises a Poké Ball → recall → send-out → idle. Recall clips are cached in advance; the transition provides time to prepare the send-out. Once the send-out asset is available, the new pair's idle, response, and recall clips are prewarmed.
  • Status changes and closing sequence: Assets matching the final battle state are prewarmed during combat playback. After the actions finish, the last attack's tail frame starts a closing clip that returns to a shared standoff before the matching idle takes over. Low HP and status conditions affect the performance, not the rules outcome.

New battle and scene clips use seed = 42, but a fixed seed does not guarantee identical results across different prompts or input images. Local FFmpeg still handles idle looping, response-clip loudness processing, scene tail frames, and recovery from archived media; it no longer handles the real-time tail-frame path for new attack clips.

API Integrations

Video goes through fal, shot planning through DeepSeek, and callout speech directly through MiniMax. Model availability, access permissions, and pricing are determined by the providers.

Service Endpoint / Model Purpose
DeepSeek Chat Completions POST https://api.deepseek.com/chat/completions; default: deepseek-v4-flash Compact shot planning; overridable with DEEPSEEK_MODEL
fal H3 Max Turbo minimax/h3-max-turbo/image-to-video Attack, continuation, recall, response, and closing clips with an opening frame
fal H3 Max Reference minimax/h3-max/reference-to-video Opening clips without a usable first frame, send-outs, and state-specific scenes with both character references
fal FFmpeg Extract Frame fal-ai/ffmpeg-api/extract-frame, frame_type: last Attack tail-frame URLs; one request shared by continuation, state prewarming, and archiving
MiniMax Speech WebSocket wss://api.minimax.cn/ws/v1/t2a_v2; speech-2.8-turbo Player move callouts and switch announcements, cached by language and dialogue
fal H3 Max Turbo Text to Video minimax/h3-max-turbo/text-to-video Asset scripts pre-generate trainer silhouettes for reuse as local files

Video is generated through fal, not through MiniMax's direct video API. Only speech connects directly to MiniMax. The Chinese voice is Chinese (Mandarin)_Straightforward_Boy; English and Japanese use their respective language voices. Callout speech plays separately and is not baked into the video.

Only the Node.js server reads API keys. Character images are locally stored PokéAPI assets, so gameplay does not require live PokéAPI lookups. See the third-party notices and character reference provenance.

Scope and Limitations

Development

Location Responsibility
src/battle-engine.js, src/data.js Battle rules and data
src/attack-storyboard.js, src/compact-storyboard.js Action records, shot validation, and prompt reconstruction
src/fal-video-runway.js, src/cloud-tail-frame.js Video generation pipeline and cloud tail-frame extraction
src/scene-video-service.js, src/scene-video-client.js State-specific asset generation, prewarming, caching, and recovery
src/attack-video-player.js, src/app.js Multi-slot playback, UI, and cinematic sequencing
server.mjs Same-origin media serving and external API proxying
assets/, tests/ Local assets and automated regression tests
npm test

Automated tests cover rules, state continuity, generation parameters, shared downloads, cancellation, and failure recovery. Provider calls are mocked. Passing tests does not validate finished-video quality or real generation latency.

License

The original source code and original textual documentation in this repository are licensed under the MIT License, copyright (c) 2026 xflare-bot. This covers the project's own code in src/, scripts/, and tests/, its HTML, CSS, server and configuration files, and its original documentation, only to the extent that the contributors have the rights to license them.

The MIT grant does not cover media assets or third-party material. Files in assets/ and docs/images/, including sprites, reference artwork, fonts, audio, generated videos, and screenshots, are excluded from the project's MIT grant. Third-party code and other third-party material retain their respective licenses and rights; see THIRD_PARTY_NOTICES.md. No Pokémon character, artwork, name, design, or trademark rights are granted by this project's code license.

“Local, non-commercial learning prototype” describes this demo's purpose, not an additional restriction on MIT-licensed code. Commercial use, modification, and closed-source reuse of the covered code are permitted under MIT's terms; rights to excluded assets must be addressed separately.

Assets and Rights

This is an unofficial learning prototype, not a license to use Pokémon intellectual property. Characters, names, and imagery belong to The Pokémon Company, Nintendo, Creatures, GAME FREAK, and their respective rights holders. Non-commercial use does not automatically grant permission. Obtain the necessary permissions or replace restricted assets before distributing or deploying a version that includes them; adding a code license does not resolve those asset rights.

Font and image sources and license records are documented in THIRD_PARTY_NOTICES.md. Screenshots show the actual project interface, not official promotional material.

pokemonlive (xflare-bot/pokemonlive)

Searching Database…

What is this?A local, non-commercial prototype where a pure JavaScript rules engine resolves turn-based Pokemon battles while AI generates a continuous anime-style 2D battle video on the fly.
Is this a finished game or an experiment?It is an experimental pipeline testing whether a game can generate its next cinematic as fast as the previous one plays, not a polished or complete game.
How do I get it running?Install Node.js, npm and FFmpeg, add your API keys to .env.local, then start the server with the --env-file option (or plain npm start if the keys are already in your environment).
Which API keys do I actually need?DeepSeek for shot planning, fal (MiniMax H3 Max Turbo) for video generation, and MiniMax for speech; without a planner key it falls back to local storyboards, and without video/speech keys those features are simply unavailable.
Does generating battle video cost money?Yes, video, cloud frame extraction, DeepSeek planning, and uncached speech are all billed separately by the providers, with no fixed per-battle cost quoted; deleting local caches can also trigger regeneration and extra charges.
What Pokemon can I actually battle with?The default player team is Pikachu, Squirtle, and Bulbasaur against an opposing team of Charmander, Charizard, and Gengar; it only implements core singles rules, not the full move catalog, abilities, held items, weather, or doubles.
Is this playable on mobile or just desktop?Validation and testing focus on the desktop browser experience, with a vanilla HTML/CSS/JS frontend served by a local Node.js server.
Is everything in the repo covered by the MIT license?No, the original source code and documentation are MIT licensed, but sprites, reference artwork, fonts, audio, generated videos, and screenshots in assets/ and docs/images/ are excluded from that grant.
Why did the author build this instead of using prerecorded animations?To test whether a game could generate its next battle cinematic while the previous one plays, instead of relying entirely on prerecorded animations, essentially checking if AI video generation can keep pace with gameplay.
What languages does the UI support?Chinese, English, and Japanese; generation prompts and speech follow the selected language, and existing videos are not re-dubbed if you switch languages.
Does the game need a live connection to the Pokemon API at runtime?No, character images are locally stored PokeAPI assets, so gameplay does not require live PokeAPI lookups.
How is the rules engine separated from the AI presentation?A pure JavaScript rules engine deterministically resolves hits, damage, status, and winners; AI (DeepSeek for shot planning, fal for video) only decides how that outcome is presented, never who wins.
Creator
xflare-bot
Size
54.5 MB
Stars
156
Updated
CommitSep 07
Age
1mo
Commits · 90 Days