API Reference#
flowerevolver#
Every class and free function here is bound directly from the C++ core
(src/bindings/python/*.cpp) via nanobind - the same code path the
JS/WASM API’s FEService and the native C++ library’s
include/fe/FlowerEvolver.hpp both go through, so behavior (and, for
Flower/DNA’s JSON, wire format) matches across all three.
FlowerEvolver - generates 2D/3D flowers from CPPN genomes evolved via EvoAI.
Native Python bindings (nanobind) around the same C++ core that powers the JS/WASM API and the native desktop app – genomes and rendered images round-trip with both (see Flower.to_json()/from_json()).
Quick start:
from flowerevolver import make_flower
flower = make_flower(radius=64, num_layers=3, P=6.0, bias=1.0) flower.petals.image.to_png_bytes() # -> bytes, ready to write to disk flower.to_json() # -> str, the genome
- class flowerevolver.DNA(*args, **kwargs)#
Bases:
objectThe genome underlying a Flower - a small collection of CPPN genomes (a stats genome plus another for petals), evolved via EvoAI. Most code creates these indirectly, through make_flower()/reproduce()/mutate() rather than by hand. Individual genomes aren’t exposed to Python (EvoAI::Genome has no binding of its own) – treat DNA as an opaque, sized container.
- clear(self) None#
Removes every genome, leaving size() == 0.
- distance = <nanobind.nb_func object>#
- from_json = <nanobind.nb_func object>#
- get_fitness(self) float#
Reads back the fitness set via set_fitness() (from genome[0]); 0.0 if this DNA is empty.
- mutate(self, rates: flowerevolver._core.MutationRates) None#
Mutates every existing genome in place (topology and weights), according to rates. This never adds or removes genomes – size() before and after is always identical; what changes is each genome’s internal structure, not how many there are.
- reproduce = <nanobind.nb_func object>#
- set_fitness(self, fitness: float) None#
Applies the same fitness value to every genome this DNA holds.
- size(self) int#
Number of genomes this DNA holds.
- to_json(self) str#
Serializes to a compact JSON string – this DNA’s own genomes array, not wrapped in the outer {“Flower”: …} shape Flower.to_json() produces (a bare DNA isn’t a complete, renderable Flower on its own). Round-trips with DNA.from_json().
- class flowerevolver.Effects(*args, **kwargs)#
Bases:
objectPer-stat effect strengths derived from the genome, roughly -100..100 each.
- property agility#
(self) -> float
- property intelligence#
(self) -> float
- property luck#
(self) -> float
- property strength#
(self) -> float
- property vitality#
(self) -> float
- class flowerevolver.Flower(*args, **kwargs)#
Bases:
objectA complete flower: its genome (dna) and rendered image (petals). Usually created via make_flower()/reproduce()/mutate() rather than constructed directly.
- property dna#
(self) -> flowerevolver._core.DNA
- from_json = <nanobind.nb_func object>#
- property petals#
(self) -> flowerevolver._core.Petals
- to_json(self) str#
Serializes to the same {“Flower”: {“dna”: …, “petals”: …}} JSON shape used throughout this project’s ecosystem (the JS/WASM API, the native desktop app, Generation.json/Session.json’s own per-flower entries) – round-trips with Flower.from_json(), and interoperates with genomes saved by any of those.
- class flowerevolver.Image(*args, **kwargs)#
Bases:
objectA simple RGBA pixel buffer - what Flower.petals.image and every draw_*()/make_*() call’s rendered output is. Pixel colors are plain (r, g, b, a) tuples of 0-255 ints, not a separate bound Color type.
- create(self, width: int, height: int, color: tuple[int, int, int, int]) None#
Allocates a width x height buffer, filled with color (r, g, b, a).
- get_pixel(self, x: int, y: int) tuple[int, int, int, int]#
Returns the (r, g, b, a) color at (x, y); (0, 0, 0, 0) if out of range.
- property height#
(self) -> int
- set_pixel(self, x: int, y: int, color: tuple[int, int, int, int]) None#
Sets the pixel at (x, y) to color (r, g, b, a). Out-of-range x/y are silently ignored (matches the C++ API – see setPixel’s own bounds-check comment in src/fe/Image.cpp).
- to_png_bytes(self) bytes#
Encodes to an in-memory PNG and returns it as bytes – e.g. pathlib.Path(‘flower.png’).write_bytes(image.to_png_bytes()).
- property width#
(self) -> int
- class flowerevolver.MutationRates(*args, **kwargs)#
Bases:
objectRates controlling how DNA.mutate()/mutate() perturbs a genome. Every parameter is independent – a given mutation call can add a node, add a connection, and perturb weights all at once, each gated by its own rate below.
- property act_type_rate#
Rate to change a neuron’s activation function.
- property add_conn_rate#
Rate to add a new connection.
- property add_node_rate#
Rate to add a new node.
- property disable_rate#
Rate to disable a currently-enabled gene.
- property enable_rate#
Rate to enable a currently-disabled gene.
- property perturb_weights_rate#
Rate to change the weight of a connection.
- property remove_conn_rate#
Rate to remove an existing connection.
- class flowerevolver.Petals(*args, **kwargs)#
Bases:
objectThe rendered-image half of a Flower (Flower.petals) - the generation parameters that produced it, plus the resulting image.
- property P#
(self) -> float
- property bias#
(self) -> float
- property has_bloom#
(self) -> bool
- property image#
(self) -> flowerevolver._core.Image
- property num_layers#
(self) -> int
- property radius#
(self) -> int
- class flowerevolver.PetalsType(*values)#
Bases:
EnumWhich part of a flower to render - passed to some of the lower-level make_*()/draw_*() calls.
- TRUNK = 0#
- PETALS = 1#
- TRUNK_AND_PETALS = 2#
- class flowerevolver.Stats(*args, **kwargs)#
Bases:
objectEnvironment-dependent stats derived from a flower’s genome - see get_flower_stats().
- property effects#
(self) -> flowerevolver._core.Effects
- property health#
(self) -> int
- property maturation_period#
(self) -> int
- property max_temperature#
(self) -> int
- property min_temperature#
(self) -> int
- property sex#
(self) -> flowerevolver._core.Sex
- property stamina#
(self) -> int
- property toxicity_rate#
(self) -> float
Free functions#
- flowerevolver.make_flower(radius: int, num_layers: int, P: float, bias: float) flowerevolver._core.Flower#
Generates a brand new, random flower.
- Parameters:
radius – pixel radius, clamped to [4, 256].
num_layers – clamped to [1, floor(log2(radius))].
P – controls roughly how many petals the flower can have.
bias – bias fed into the CPPN alongside radius/angle/layer.
- Returns:
a Flower – .to_json() for the genome, .petals.image for the render.
- flowerevolver.make_petals(radius: int, num_layers: int, P: float, bias: float) flowerevolver._core.Flower#
Same as make_flower(), but renders just the petals (no stem).
- flowerevolver.make_petal_layer(radius: int, num_layers: int, P: float, bias: float, layer: int) flowerevolver._core.Flower#
Same as make_flower(), but renders just one petal layer (no stem).
- Parameters:
layer – which layer to render, 0-indexed from the outermost.
- flowerevolver.make_stem(radius: int, num_layers: int, P: float, bias: float) flowerevolver._core.Flower#
Same as make_flower(), but renders just a stem (no petals).
- flowerevolver.draw_flower(dna: flowerevolver._core.DNA, radius: int, num_layers: int, P: float, bias: float) flowerevolver._core.Image#
Renders an existing DNA (e.g. from Flower.dna, or DNA.from_json()) instead of generating a new one.
- Parameters:
dna – the genome to render; needs at least 2 genomes.
radius – pixel radius, clamped to [4, 256].
num_layers – clamped to [1, floor(log2(radius))].
P – controls roughly how many petals the flower can have.
bias – bias fed into the CPPN alongside radius/angle/layer.
- Returns:
the rendered Image.
- Raises:
ValueError – if dna has fewer than 2 genomes.
- flowerevolver.draw_petals(dna: flowerevolver._core.DNA, radius: int, num_layers: int, P: float, bias: float) flowerevolver._core.Image#
Same as draw_flower(), but renders just the petals (no stem).
- flowerevolver.draw_petal_layer(dna: flowerevolver._core.DNA, radius: int, num_layers: int, P: float, bias: float, layer: int) flowerevolver._core.Image#
Same as draw_flower(), but renders just one petal layer (no stem).
- Parameters:
layer – which layer to render, 0-indexed from the outermost.
- flowerevolver.reproduce(dna1: flowerevolver._core.DNA, dna2: flowerevolver._core.DNA, radius: int, num_layers: int, P: float, bias: float) flowerevolver._core.Flower#
Breeds two genomes into a rendered child Flower. For crossover only, with no rendering, see DNA.reproduce() instead.
- Parameters:
dna1 – the father’s genome.
dna2 – the mother’s genome; must have the same number of genomes as dna1.
radius – pixel radius, clamped to [4, 256].
num_layers – clamped to [1, floor(log2(radius))].
P – controls roughly how many petals the flower can have.
bias – bias fed into the CPPN alongside radius/angle/layer.
- Raises:
RuntimeError – if dna1 and dna2 don’t have the same number of genomes.
- flowerevolver.mutate(dna: flowerevolver._core.DNA, radius: int, num_layers: int, P: float, bias: float, add_node_rate: float = 0.20000000298023224, add_conn_rate: float = 0.30000001192092896, remove_conn_rate: float = 0.20000000298023224, perturb_weights_rate: float = 0.6000000238418579, enable_rate: float = 0.3499999940395355, disable_rate: float = 0.30000001192092896, act_type_rate: float = 0.4000000059604645) flowerevolver._core.Flower#
Mutates a copy of dna and renders the result – dna itself is left untouched.
- Parameters:
dna – genome to mutate; needs at least 2 genomes.
radius – pixel radius, clamped to [4, 256].
num_layers – clamped to [1, floor(log2(radius))].
P – controls roughly how many petals the flower can have.
bias – bias fed into the CPPN alongside radius/angle/layer.
add_node_rate – rate to add a new node.
add_conn_rate – rate to add a new connection.
remove_conn_rate – rate to remove an existing connection.
perturb_weights_rate – rate to change a connection’s weight.
enable_rate – rate to enable a currently-disabled gene.
disable_rate – rate to disable a currently-enabled gene.
act_type_rate – rate to change a neuron’s activation function.
- Raises:
ValueError – if dna has fewer than 2 genomes.
- flowerevolver.make_3d_flower(dna: flowerevolver._core.DNA, radius: int, num_layers: int, P: float, bias: float, flower_id: str, flower_params: str = '') str#
Generates a 3D flower model.
- Parameters:
dna – the genome to render; needs at least 2 genomes.
radius – pixel radius, clamped to [4, 256].
num_layers – clamped to [1, floor(log2(radius))].
P – controls roughly how many petals the flower can have.
bias – bias fed into the CPPN alongside radius/angle/layer.
flower_id – a unique string identifying this flower (used in the model’s own group names).
flower_params – JSON string, e.g. ‘{“sex”: 2, “useNormals”: true, “useEmissive”: false}’; “” for defaults.
- Returns:
the 3D model as a glTF 2.0 JSON string.
- Raises:
ValueError – if dna has fewer than 2 genomes, or radius/num_layers/flower_id are invalid.
- flowerevolver.get_flower_stats(genome: str, humidity: float, temperature: int, altitude: int, terrain_type: int) flowerevolver._core.Stats#
Derives environment-dependent Stats from a flower’s genome.
- Parameters:
genome – a Flower.to_json()-shaped JSON string.
humidity – 0.0 to 1.0.
temperature – degrees, same scale as the resulting Stats’ min_temperature/max_temperature.
altitude – meters above sea level.
terrain_type – terrain type id.
- Raises:
ValueError – if genome doesn’t contain a DNA with at least 2 genomes.
RuntimeError – if genome is malformed JSON entirely.
- flowerevolver.get_version() str#
The semver this extension was built from, e.g. “4.0.0”.
- flowerevolver.get_commit_hash() str#
The short git commit hash this extension was built from, or “unknown” for a build outside a git checkout.
- flowerevolver.get_version_string() str#
get_version() + “+” + get_commit_hash(), e.g. “4.0.0+a1b2c3d” – the one to put in a bug report.
flowerevolver.cli#
The flower-evolver console script installed alongside the package -
matches the native desktop app’s own single-flower flags. See
the module docstring below for the exact invocations; flower-evolver
--help covers the same ground interactively.
FlowerEvolver CLI - matches the native desktop app’s own single-flower flags: -lf, -sf, -si, -s3d, -m, -repr, and the shared -l/-r/-p/-b generation parameters.
Three entry points (each self-sufficient - -lf/-repr just replace “start from a fresh flower” with “start from an existing one/two”). -m <n> mutates n times and saves only the final result, matching the native app - run this repeatedly (feeding each -sf output back in via -lf) if you want every intermediate step saved instead:
flower-evolver -l <numLayers> -r <radius> -p <P> -b <bias> -m <n> flower-evolver -lf <flower.json> -l <numLayers> -r <radius> -p <P> -b <bias> -m <n> -sf <out.json> -si <out.png> flower-evolver -repr <flower1.json> <flower2.json> -l <numLayers> -r <radius> -p <P> -b <bias> -m <n> -sf <out.json> -si <out.png>
Add -s3d <filename> to any of the above to also generate and save a 3D model (glTF) for the resulting flower, e.g.:
flower-evolver -sf flower.json -si flower.png -s3d flower.gltf
Use -se3d <filename> instead of (or alongside) -s3d for an emissive 3D model - same glTF export, but with useEmissive turned on, matching FEService.makeEmissive3DFlower()/drawEmissive3DFlower() on the JS/WASM side. Both can be passed together to save a regular and an emissive model from the same flower:
flower-evolver -sf flower.json -si flower.png -s3d flower.gltf -se3d flower_emissive.gltf
- flowerevolver.cli.build_parser() ArgumentParser#
- flowerevolver.cli.main(argv: list[str] | None = None) int#