Long-Form Editions

Overview

A long-form edition series is one algorithm that produces many unique outputs — each driven by a deterministic seed. The same seed always produces the same image. This is the workflow behind Art Blocks, fxhash, and numbered print editions.

Eido provides this pipeline:

  1. Define a parameter spec — what varies across editions
  2. Write a scene function — turns parameters into a scene
  3. Render the range of editions — one deterministic parameter map each
  4. Analyze trait distribution across the series

Parameter Specs

A parameter spec defines what varies across editions using data-driven distributions:

(def spec
  {:hue      {:type :uniform :lo 0.0 :hi 360.0}
   :density  {:type :gaussian :mean 20.0 :sd 5.0}
   :palette  {:type :choice :options [:sunset :ocean :forest]}
   :bold?    {:type :boolean :probability 0.3}
   :weight   {:type :weighted-choice
              :options [:light :medium :heavy]
              :weights [0.5 0.35 0.15]}})

Each edition samples from these distributions using a deterministic seed derived from the master seed + edition number. Distribution types: :uniform, :gaussian, :choice, :weighted-choice, :boolean, :pareto, :triangular, :eased.

Scene Function

The scene function takes sampled parameters and returns a scene map:

(defn make-scene [params]
  {:image/size [800 800]
   :image/background [:color/hsl (:hue params) 0.1 0.95]
   :image/nodes
   [(build-artwork params)]})

This is where your creative algorithm lives. The parameters control variation; the algorithm defines the visual language.

Batch Rendering

series-range expands a spec into one deterministic parameter map per edition. Render each one in a loop:

(require '[eido.gen.series :as series])

(doseq [[edition params]
        (map-indexed vector (series/series-range spec 42 0 50))]
  (eido/render (make-scene params)
               {:output (str "editions/edition-" edition ".png")}))

This writes editions/edition-0.png through edition-49.png. Each edition's parameters come from a seed derived from the master seed (42) and the edition number, so the same pair always reproduces the same image.

Trait Analysis

Traits categorize continuous parameters into named labels. trait-summary counts how many editions fall into each bucket across the series:

(series/trait-summary
  spec 42 100
  {:density [[15 "sparse"] [25 "medium"] [100 "dense"]]})
;=> {:density {"sparse" 22, "medium" 48, "dense" 30}}

Useful for verifying that rare traits are actually rare before releasing a series.

Reproducibility

Reproduction rests on determinism: the same scene map renders to the same bytes, every time. Store the scene as EDN — or the seed and spec that generate it — and you can always re-render it.

When you stumble on a seed worth keeping, bookmark it:

(series/save-seed! "seeds.edn"
  {:seed 42 :params params :note "strong diagonal"})

;; Later, read them all back
(series/load-seeds "seeds.edn")
;=> [{:seed 42 :params {,,,} :note "strong diagonal" :timestamp "..."}]

save-seed! appends one EDN form per line; load-seeds reads them back in append order.