How a flame is made

Every flame is a fractal flame drawn live in your browser by one shared program on Bitcoin. Nobody picks a flame's shape, and nobody knows its colours or rarity until its block is mined. Here's how each piece works.

01

What's actually on chain

A flame inscription is tiny, about 215 bytes. It holds no picture and no seed, just one line that loads the renderer:

<script data-mint src="/content/<renderer inscription>"></script>

The renderer is a separate inscription, about 36 KB of JavaScript, inscribed once and shared by every flame. When anyone opens a flame, the renderer runs in their browser. It asks the ordinals server about the flame itself using recursive endpoints (/r/inscription, /r/blockinfo, /r/tx, /r/block), then draws it. Everything it uses is already on Bitcoin, so the flame needs no outside server to exist.

02

The seed: the flame's own inscription ID

A flame's shape comes from its seed, and the seed is the flame's own inscription ID, such as 6d729aec…17c93i0. That ID is the ID of the reveal transaction that creates the inscription, plus i0. It doesn't exist until the mint transaction is made, so nobody, including the minter, can choose it ahead of time.

Not every ID makes a good flame. About 4 in 5 produce one that's too sparse, too crowded, or collapses into clumps partway through its loop. So when the site builds your reveal, it tries a few versions of that transaction until the ID passes a quality check:

The versions differ only in a field called the sequence number. It's part of the transaction ID, but it doesn't change the fee, the outputs or when the transaction can confirm. The site takes the first one that passes, usually within a handful of tries. You don't pick among them, and neither does anyone else.

The check runs once, when minting, and never again when viewing. Browsers do floating-point maths very slightly differently, and an ID near the borderline could pass in one browser and fail in another. Checking once at mint time means every viewer sees exactly the same flame.

Try it: draw IDs like the site does

Candidate IDs
Press "Draw IDs" to start.

The flame for the passing ID

These IDs are random stand-ins; a real mint's ID comes from its reveal transaction. "Confirm in a random block" places the flame in a made-up mainnet block, so you can see how its block sets the rest.

03

From seed to flame

A fractal flame is the shape you get by moving a point over and over through a few randomly chosen functions and recording everywhere it lands. Scott Draves invented the technique for the flam3 program and the Electric Sheep screensaver.

  1. The genome. The seed feeds a deterministic random-number generator, which picks 3 to 5 transforms. Each is a stretch-rotate-shift of the plane combined with one or two of 24 curved variations, such as swirl, spherical or julia, and each has its own colour and weight. The same seed always gives the same genome.
  2. Symmetry. The seed also decides whether the flame gets extra rotational copies and a mirror, and rare sats can add more (see below).
  3. The chaos game. Your graphics card runs hundreds of thousands of points in parallel, each jumping through the transforms millions of times a second. Where they land is added to a brightness map.
  4. Developing. The map is turned into an image the way flam3 does it: brightness on a log scale so faint wisps and dense cores both show, colour from where the points came from, a soft glow, and smoothing in sparse areas.
  5. Motion. The transforms slowly rotate, so the flame loops forever. Each loop takes 7 to 26 seconds, depending on its tempo.

On phones or browsers without WebGL2, a CPU version draws the same image more slowly. In marketplace grids, each small flame does less work so many can play at once.

Exports. Holders can export a flame or chain they own from its viewer in the gallery: a profile picture, a 4096 px 16-bit still, a GIF or a 60 fps video. Exports use the same drawing at far higher quality: hundreds of samples per pixel instead of a few, supersampling, motion blur between frames, and no screen dither. They render on your own device, so the largest take minutes.

04

Traits and rarity: decided by the block

The seed fixes the shape. Everything else, the colours, motion and rarity, comes from where the mint lands: the block it confirms in and its position there. Until it confirms, a flame plays in silver as Unrevealed.

From the chainWhat it sets
Block hashThe palette. Also half of the flame's luck: how far the hash came in under the block's difficulty target. The luckiest 1 in 32 blocks give a Lucky Hash and the luckiest 1 in 1,024 a Blessed Hash, both with a neon palette.
Position in the blockThe other half of the luck: closeness to the block's sweet spot (below). Landing right on it is a Bullseye. Position also gives a name (Genesis, Vanguard, Early, Mid-block, Late, Rearguard, Last Light) and the tempo: earlier in the block means a slower loop.
Block heightThe background tint, which changes every halving epoch. Special heights are named in the traits: a halving block gets the gold palette and a palindromic height a mirror. They don't change the tier, since anyone can time a mint into a chosen block.
The sat it's inscribed onRare sats add rotational symmetry (an uncommon sat 2-fold up to a mythic sat 6-fold), and palindrome sats a mirror. They don't change the tier, since rare sats can be bought.

The sweet spot

Miners roughly order a block by fee rate, so if rarity came from being first or last in a block, people could pay their way to it. Instead each block has a sweet spot, a position picked from the block's own hash. That hash doesn't exist until the block is mined, so no fee rate can aim for it. Distances wrap around the block's ends, so the first and last transactions are neighbours. That way every position has exactly the same odds.

How luck becomes a tier

Each half of the luck is a fair 0-to-1 chance: the share of the block at least as close to the sweet spot, and the hash's share of its target. A flame's luck is −ln(position share) − ln(hash share). The odds of any luck score are then known exactly, P(luck > x) = (1 + x)·e−x, so the tier cut-offs are set to give this split on mainnet:

TierShare of mintsLook
Common60%Base glow and density
Uncommon25%More glow and denser sampling
Rare10%Brighter still
Epic4%Adds a fisheye "lens" transform
Legendary1%Adds palette cycling

A simulation of a million mints using real mainnet block sizes and difficulty gave 59.8 / 25.1 / 10.1 / 4.1 / 1.0, the same whether a mint landed first in its block, last, or anywhere between. Rare sats and special heights change the look, never these odds. Click a flame, or press i, to see its traits, including the odds of its placement ("1 in 340"). See every trait, its values and how it's granted →

05

The reveal transaction

Most wallets can send bitcoin but can't inscribe. So minting uses two transactions, commit and reveal, and your wallet only has to make an ordinary payment.

Commit and reveal: the wallet pays a one-time address; the page's reveal spends it, carries the inscription, and pays the minter and the creator. Your wallet approves one payment (the commit) One-time Taproot address its key is made in this page and it commits to the inscription script Reveal transaction signed by the page with the one-time key witness carries the inscription its ID becomes the flame's seed Output 0 · 546 sats to you: carries the flame Output 1 · creator fee to the creator
The wallet only sees a normal payment. The page builds, signs and sends the reveal. Whatever the commit pays beyond the two outputs is the miners' fee for the reveal.
  1. Prepare. The page makes a brand-new one-time key and builds the inscription: the content type and the <script data-mint …> line, inside an "ord" envelope. Those two together give a Taproot address that can only be spent by revealing that exact inscription. The key is saved in your browser before any money moves.
  2. Commit. Your wallet pays that address exactly enough to cover the reveal: the miners' fee for the reveal, the 546 sats that will hold the flame, and the creator fee.
  3. Pick the reveal. Once the payment is seen, the page builds the reveal: one input spending the commit, output 0 to your address, and output 1 to the creator. It tries sequence numbers until the transaction's ID passes the quality check (section 2).
  4. Sign and broadcast. The page signs with the one-time key, putting the inscription in the witness, and broadcasts it through mempool.space. Its ID plus i0 is your flame's inscription ID, and its seed.

The flame lives on the first sat of output 0, which lands in your wallet like any other inscription. If the page is closed between the commit and the reveal, the saved one-time key lets you finish from "In progress" on the minting page. Nobody else ever holds your keys or your bitcoin.

06

What makes a flame official

Bitcoin doesn't stop anyone inscribing the same one-line file with another tool. The renderer decides which flames are official, and it checks every flame when drawing it:

A flame that fails either check plays in silver as Unofficial, with no traits. A flame minted through another tool also skips the reveal search from section 2, so it's usually a weak flame too.

Chains have their own, much smaller creator fee (section 7).

07

Chains: your flames in one endless loop

A chain is a separate inscription that plays several flames one after another. Each flame spins through its loop, then morphs smoothly into the next, and the last morphs back into the first. Like a flame, a chain holds no images, only a list:

<script data-chain="<flame ID>,<flame ID>,<flame ID>" data-transition="6" src="/content/<renderer inscription>"></script>

data-chain lists flame inscription IDs in playing order, and data-transition is the length of each morph in seconds. Each extra flame adds about 67 bytes, so even a long loop costs little to inscribe.

Inscribing a chain

  1. Pick and order. On the minting page, press "Add to chain" on flames you hold, reorder them with the arrows, and set the morph length (2 to 15 seconds). The loop preview and its timeline bar show exactly what will play.
  2. Commit and reveal, as for a flame. Your wallet pays a one-time address, and the page signs the reveal. Output 0 (546 sats) carries the chain to you, and output 1 pays the chain creator fee.
  3. No ID search. A chain's ID isn't a seed, so there's no quality check and the first reveal is used as is.

How a chain plays

A three-flame chain: each flame spins for its tempo's length, then morphs into the next; the last morphs back into the first. Flame 1 spins · 18 s Flame 2 · 12 s Flame 3 · 26 s morph morph back to 1 One loop = each flame's spin + one morph per flame (here 18 + 12 + 26 + 3 × 6 = 74 s), then it repeats
Each flame spins for its own tempo's length (Largo 26 s, Andante 18 s, Allegro 12 s, Presto 7 s), fixed by where it was minted. Colours show each flame's tier.

Each time a chain is opened, the renderer:

  1. Checks every link. For each listed ID it loads the inscription and keeps it only if it's a flame minted with this same renderer. Then it reads that flame's block data, which gives the same traits the flame has on its own, and its current owner.
  2. Checks who holds the chain. Only flames owned by the chain's current holder play. The check runs on every load: sell a flame and it drops out of your chain; sell the chain and it plays the buyer's flames from its list instead. If the holder owns none of them, the chain goes dormant and plays them as silver, unrevealed shapes.
  3. Checks the chain fee. A chain that didn't pay its creator fee plays its flames in silver, marked Unofficial.
  4. Builds the morphs. Between two flames, it pairs each transform with the most similar transform in the next flame, so each one travels the shortest path. Then it blends them the way flam3 does: each transform's rotation and stretch move in polar form, turning the short way round and scaling smoothly rather than collapsing through zero. Shifts and variation weights blend directly, and a transform with no partner fades in or out. Palette, background, glow and framing blend at the same time, with an ease in and out.

A flame finishes its spin exactly where it started, so every morph begins from a resting shape and the whole loop has no visible seam. Click a playing chain, or press i, to see which flame is on screen, its traits, and how many of the chain's flames its holder owns. Every official chain is listed in the gallery under Chains.

08

Credits and license

The fractal flame algorithm was invented by Scott Draves, and developed with Erik Reckase in flam3, the program behind Electric Sheep. flame-btc's renderer is a new implementation of that algorithm for the browser. It follows flam3's variation numbering, its "log" interpolation for morphs and its way of developing the image. flame-btc is not affiliated with or endorsed by the flam3 or Electric Sheep projects.

PartLicenseWhat it lets you do
Software: the renderer, this site and its toolsGNU GPL v3.0 or laterUse, study, change and share it, as long as anything you distribute that's built from it stays under the GPL with its source available. flam3 itself is GPL v3 or later.
Artwork: the images and animations drawn for each flame and chainCC BY-NC 4.0Share and adapt it for non-commercial purposes with credit ("flame-btc" and the flame's inscription ID) and a link to the license. Owning a flame lets you hold, display and transfer it; other commercial use needs the creator's permission.

The inscribed renderer is a minified build of onchain/renderer.js; its first line names both licenses and this credit. The signing and inscription code bundled into the site (@scure/btc-signer, micro-ordinals, @scure/base) and the export encoders (gifenc, mp4-muxer, webm-muxer) are MIT-licensed.