This is the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

Icon generator

Generate random patterns of colored squares or circles as PNG icons

Icon generator is a Go CLI that creates random grid patterns as PNG images. Choose the canvas dimensions, background, palette, cell size, density, clustering algorithm and strength, and square or circular shapes. Rendering and PNG encoding use only Go’s standard library; no external graphics programs or libraries are required.

From the repository root, create an output directory and generate an icon:

mkdir -p out/icon_generator
bazel_agent bazel run //projects/icon_generator -- \
  --width 256 --height 256 \
  --background '#f5f1e8' \
  --colors '#223843,#d77a61,#e3b23c' \
  --pixel-size 16 --pixel-shape square \
  --density 0.4 --seed 42 \
  --output "$PWD/out/icon_generator/squares.png"

For circles on a transparent background:

bazel_agent bazel run //projects/icon_generator -- \
  --background transparent \
  --colors '#223843,#d77a61,#e3b23c' \
  --pixel-shape circle --seed 42 \
  --output "$PWD/out/icon_generator/circles.png"

Use an absolute output path with bazel run. The output directory must already exist. Existing files and symlinks are never overwritten; choose a new path when repeating a command.

Use --clusterization 0.75 for compact groups. To grow winding, branching strands while keeping the same number of occupied cells, also select --clusterization-algorithm strands. Sparse densities leave more room for open gaps:

bazel_agent bazel run //projects/icon_generator -- \
  --width 512 --height 512 \
  --background '#212121' --colors '#ffffff' \
  --pixel-size 16 --pixel-shape circle \
  --density 0.2 --clusterization 0.75 --clusterization-algorithm strands --seed 42 \
  --output "$PWD/out/icon_generator/clustered.png"

For replication from a sparse initial population of individual white pixels:

bazel_agent bazel run //projects/icon_generator -- \
  --width 1024 --height 1024 \
  --background '#212121' --colors '#ffffff' \
  --pixel-size 1 --pixel-shape square \
  --density 0.03 --clusterization 0.4 --clusterization-algorithm replication \
  --replication-inheritance 0.9 --replication-forward-bias 0.8 \
  --replication-crowding 0.75 --replication-branching 0.15 \
  --replication-field-scale 128 \
  --replication-growth-variation 0.08 --replication-seeding-variation 0.75 \
  --seed 42 --output "$PWD/out/icon_generator/replication.png"

Build the executable with bazel_agent bazel build //projects/icon_generator. It can also run directly, without Bazel or other programs on PATH:

bazel-bin/projects/icon_generator/cmd/icon_generator/icon_generator_/icon_generator --help

For long, gradually curving stems with shorter side branches, select tips and start with a much sparser population. Density 0.00015 gives about 157 starting cells on a 1024-square, one-pixel grid:

bazel_agent bazel run //projects/icon_generator -- \
  --width 1024 --height 1024 \
  --background '#212121' --colors '#ffffff' \
  --pixel-size 1 --pixel-shape square \
  --density 0.00015 --clusterization 0.9 --clusterization-algorithm tips \
  --seed 42 --output "$PWD/out/icon_generator/tips.png"
Option Default Meaning
--width 256 Output width, 1 through 4096 pixels
--height 256 Output height, 1 through 4096 pixels
--background #ffffff Opaque #RRGGBB or transparent
--colors #000000 Nonempty comma-separated #RRGGBB palette
--pixel-size 16 Square side or circle diameter, 1 through 4096 pixels
--pixel-shape square square or circle
--density 0.4 Average initial cell occupancy probability, from 0 through 1
--clusterization 0 Clustering strength, replication probability, or tip growth length, 0 through 1
--clusterization-algorithm compact compact, strands, replication, or tips
--replication-inheritance 0 Probability a child keeps its parent-to-child heading, 0 through 1
--replication-forward-bias 0 Strength of forward and gentle-turn preference, 0 through 1
--replication-crowding 0 Strength of preference for less crowded destinations, 0 through 1
--replication-branching 0 Probability the second child favors a sideways fork, 0 through 1
--replication-field-scale 128 Approximate regional variation scale, 1 through 4096 logical cells
--replication-growth-variation 0 Maximum local offset to reproduction probability, 0 through 1
--replication-seeding-variation 0 Regional starting-population contrast, 0 through 1
--seed Fresh random seed Unsigned 64-bit seed; zero is valid
--output icon.png Destination PNG file
--help Print usage without generating an image

Hex colors are case-insensitive. Quote colors so the shell does not interpret # as a comment. Palette colors are opaque and keep their exact RGB values.

Canvas dimensions count output image pixels. Logical pixels occupy a grid starting at the top-left corner. A 256 by 256 canvas with size 16 contains 16 by 16 cells. Squares fill their cell; circles are centered within it and leave the background visible at the corners. Shapes have hard rasterized edges, so very small circles can resemble squares. Partial cells at the right and bottom are clipped without resizing the shape or padding the image.

Initial placement independently samples each cell. Its probability is the requested density, or a local probability when regional seeding is enabled. These local probabilities average to density. Each shape uses a randomly selected palette entry. Density is a probability, not an exact shape count: zero draws only the background and one occupies every cell. Circle corners remain background even at density one.

The algorithm determines how positive clusterization changes placement:

  • compact (default) moves occupied cells to increase neighboring contacts. Higher factors make more attempts and cannot decrease the number of occupied neighbor pairs with the same seed and other settings. Cell count is preserved.
  • strands grows winding strands with occasional branches. Higher factors favor longer strands; placement prefers uncrowded cells to leave open gaps. Cell count is preserved, but the neighbor count can rise or fall. Dense or tiny canvases have less room for open strands.
  • replication uses density for the initial population and clusterization as the base probability that each cell reproduces, optionally varied across regions. Reproduction adds exactly two distinct children chosen randomly from the parent’s empty adjacent cells. A cell with fewer than two vacancies adds none. A cell that dies adds none and remains visible. Children get the same one-time decision, so final coverage can exceed the initial density; high reproduction probabilities can fill most of the image. Initial cells are processed in row order, followed by children in birth order. Each cell is processed once, and growth stops when no decisions remain.
  • tips uses density for the starting population and clusterization to scale growth length. Tips usually extend one adjacent cell along a gradually turning heading. Occasional forks divide the remaining growth budget, giving a smaller share to a side branch. The main tip grows before its deferred branches. Tips stop at exhausted budgets, canvas edges, occupied destinations, or contact with existing paths. The recent trail and a small fork junction are exempt from contact stopping so curves and branches can leave their own stem. Initial cells are processed in seeded shuffled order and remain visible. Final coverage can exceed initial density; higher factors do not guarantee more coverage because collisions can stop growth. Replication controls have no effect on tips. Try density 0.00005 through 0.0008 for individual pixels on a 1024-square canvas; dense initial populations leave little room to grow.

Growth uses all eight neighbors: horizontal, vertical, and diagonal. Opposite canvas edges are not neighbors. Diagonally adjacent circles count as neighbors even though their shapes do not physically touch at the corners. The result can contain several groups and isolated cells; no factor promises one connected group. Zero disables reproduction and preserves the original independent pattern when regional seeding is off. Explicit regional seeding can change that initial pattern. Compact and strands can change positions and colors within the configured palette. Replication and tips retain each initial cell and its color; children use the palette.

The four placement controls default to zero, which reproduces the original uniform-neighbor rule when regional variation is also off. They are validated for every algorithm but affect only replication. They change placement, while --clusterization still controls reproduction probability and --density still sets the initial population.

Inheritance gives a newborn its parent-to-child direction with the configured probability; otherwise it gets a random direction. Roots start with random directions. Forward bias uses those directions to favor continuing forward or turning gently, with weaker preferences for sideways or backward growth. Use inheritance together with forward bias to encourage persistent paths. Inheritance alone has no visible effect when forward bias is zero.

Crowding avoidance lowers the weight of destinations surrounded by more occupied neighbors. It excludes the parent and counts the first child when placing the second. This is a soft preference: crowded vacancies remain eligible.

Branching controls how often the second child favors a direction 90 degrees to either side of the first child’s direction. It controls the fork angle, not the number of children. Every successful reproduction still adds exactly two children; if fewer than two vacancies exist, it adds none. Children can continue reproducing.

Controls do not promise thin or connected strands. High initial density or reproduction probability can still fill gaps. Different placements can change later vacancy availability and final coverage, so comparisons should keep the seed, density, and reproduction probability fixed and report final coverage.

Seeding and growth variation use the same seed-derived smooth field, so fertile and quiet areas line up. --replication-field-scale sets their approximate size in logical cells: 128 means about 128 output pixels with pixel-size 1, or 1024 output pixels with pixel-size 8. It is not an exact region diameter. Smaller values vary more rapidly; larger values form broader regions.

--replication-growth-variation bounds the local additive change to reproduction probability. For example, base clusterization 0.5 and variation 0.1 keep local probabilities within 0.4..0.6. Values are clamped to 0..1, so their mean can shift near those limits. Base clusterization zero always disables reproduction.

--replication-seeding-variation controls the contrast of the starting population: zero is uniform, while one uses the strongest regional contrast that keeps all initial probabilities within 0..1. Their average remains the requested density, including partially clipped cells, but the sampled cell count is still random. Seeding variation works with clusterization zero, allowing the starting population to be inspected separately. Empty/full density remains empty/full, and a constant field uses uniform probabilities.

Both variation strengths default to zero, preserving earlier seeded images. Regional options affect replication only and add a normalization pass over the logical grid without allocating a full-canvas field buffer. Strong growth variation can fill favorable areas; moderate values preserve more internal gaps.

Successful invocations print seed: NUMBER on stderr. Reuse that seed with the same settings and generator version to reproduce the decoded pixels. PNG compression bytes may change between Go toolchain versions. Different seeds are not guaranteed to yield different images.

Invalid options fail before output creation. Output errors return a nonzero status with a diagnostic, and a failed write removes the incomplete file created by the invocation. The dimension limits bound the main image buffer at 64 MiB. Clustering uses at most another 16 MiB for the cell grid. Replication also uses a queue of up to 64 MiB; tips uses a root-index list of up to 64 MiB and a bounded per-root branch frontier. Encoding and the Go runtime use additional memory.

bazel_agent bazel test //projects/icon_generator:test

The end-to-end suite runs the built command with an empty PATH, decodes its images, checks geometry and color behavior, and exercises failure paths. Its Bazel undeclared outputs contain squares.png, circles.png, transparent.png, clustered.png (strands), compact.png, replication.png, replication-growth.png, replication-regions.png, tips.png, and a manifest.json with replay arguments, seeds, and checksums of decoded dimensions and RGBA pixels. They can be inspected and recreated in a fresh directory.

Project page

1 - OpenSpec

1.1 - Specifications

1.1.1 - Random icon generation

1.1.1.1 - random-icon-generation Specification

Generate PNG icons from random arrangements of configurable colored shapes, with control over the canvas, background, palette, density, and seed.

The icon_generator CLI SHALL accept --width, --height, and --output and write one PNG with exactly the requested dimensions. Width and height SHALL be integers from 1 through 4096, measured in output image pixels. Generation SHALL work without installed image-processing programs or external runtime libraries.

  • WHEN the user requests width 120, height 80, and an available output path with otherwise valid options
  • THEN the command exits successfully and writes a decodable 120 by 80 PNG to that path
  • AND no image-processing executable is required on PATH

The CLI SHALL accept --background as #RRGGBB or transparent, and --colors as a comma-separated nonempty list of #RRGGBB colors. Hex digits SHALL be case-insensitive. An occupied cell SHALL choose uniformly from the supplied palette entries and use that opaque color for its shape. Unoccupied cells and pixels outside shapes SHALL retain the background. Rendering SHALL preserve palette colors without blended edge colors.

  • WHEN the user selects a white background and a palette containing only #123abc
  • THEN every rendered shape pixel has opaque RGB color #123abc
  • AND every remaining pixel is opaque white
  • WHEN the user selects --background transparent
  • THEN pixels not covered by a shape have alpha zero
  • AND shape pixels have alpha 255

The CLI SHALL accept --pixel-size as an integer from 1 through 4096 and --pixel-shape as square or circle. The grid SHALL start at the top-left canvas corner with cells of the requested size. A square SHALL fill its cell; a circle SHALL be centered in its cell with a diameter equal to that size. A circle SHALL include an output pixel when that pixel’s center is on or inside the circle. Shapes SHALL have hard rasterized boundaries. The rightmost and bottommost cells SHALL be clipped at the canvas bounds without changing their original shape size or center.

  • WHEN the user requests a 32 by 16 canvas, size 16, square shapes, and density 1
  • THEN two adjacent 16 by 16 squares cover the canvas
  • WHEN the user requests a 16 by 16 canvas, size 16, circle shapes, and density 1
  • THEN the cell contains a centered circle of diameter 16
  • AND the canvas corners retain the background
  • WHEN the user requests a 25 by 18 canvas with size 16
  • THEN the grid contains two columns and two rows
  • AND shapes in the last column and row are clipped to the 25 by 18 output bounds without padding or shrinking the shapes
  • WHEN size is 1, density is 1, and the shape is either supported value
  • THEN every output pixel receives a palette color

The CLI SHALL accept a finite --density from 0 through 1 inclusive. Initial placement SHALL independently sample each cell. The per-cell probability SHALL equal density unless regional replication seeding is enabled, in which case density SHALL equal the mean of the local probabilities. Compact and strand clustering SHALL rearrange that sample without changing its occupied-cell count. Replication and tips SHALL use the sample as their initial population and MAY increase the count through growth. Density SHALL represent an average initial occupancy probability, not an exact occupied-cell count or the percentage of output pixels covered by circles.

  • WHEN density is 0, with any valid clusterization and algorithm
  • THEN every output pixel retains the configured background
  • AND growth does not introduce a population spontaneously
  • WHEN density is 1, with any valid clusterization and algorithm
  • THEN every cell contains the selected shape
  • AND circle boundaries still leave background visible outside circles

The CLI SHALL accept an optional unsigned 64-bit integer --seed, including zero. For the same tool version, seed, and rendering settings, the decoded output dimensions and pixel values SHALL be identical. If omitted, the command SHALL obtain a fresh seed and report the effective seed on stderr so the user can reproduce the result. Reproducibility SHALL concern image content, without requiring byte-identical PNG encodings across toolchains.

  • WHEN two invocations use the same explicit seed and rendering options but different available output paths
  • THEN decoding both PNGs produces identical dimensions and pixels
  • WHEN an invocation omits the seed and the user repeats its rendering options with the reported seed
  • THEN the repeated image has identical decoded dimensions and pixels

The CLI SHALL default to width 256, height 256, background #ffffff, palette #000000, pixel size 16, square shapes, density 0.4, a fresh seed, and output icon.png. The CLI SHALL provide --help describing options, defaults, accepted values, seed replay, and the distinction between output pixels and logical grid cells. Help SHALL exit successfully without writing an image.

  • WHEN the command is invoked without options and icon.png does not already exist
  • THEN it writes a 256 by 256 PNG using black 16 by 16 square cells, a white background, and occupancy probability 0.4
  • WHEN the user invokes --help
  • THEN the command describes all supported options and exits successfully without creating or changing an image file

The CLI SHALL reject invalid dimensions, size, density, palette, background, shape, seed, unknown flags, and unexpected positional arguments with a nonzero exit status and a diagnostic on stderr. Input validation SHALL complete before creating the output file. The command SHALL refuse to overwrite an existing output file. File creation, encoding, and close failures SHALL produce a nonzero exit status and a diagnostic; a failed write SHALL remove only the incomplete output created by that invocation.

  • WHEN a rendering option is invalid, such as a zero width, size 4097, density NaN, an empty palette, a malformed hex color, or shape triangle
  • THEN the command reports the invalid option and exits unsuccessfully
  • AND it does not create an output image
  • WHEN the requested output path already exists
  • THEN the command exits unsuccessfully and reports the conflict
  • AND the existing file remains unchanged
  • WHEN the output parent directory does not exist or cannot be written
  • THEN the command exits unsuccessfully and identifies the output error

The CLI SHALL accept a finite --clusterization factor from 0 through 1, defaulting to 0, and --clusterization-algorithm as compact, strands, replication, or tips, defaulting to compact. Zero factor SHALL prevent reproduction. With regional seeding disabled, it SHALL preserve independent placement and existing seeded image content for every algorithm. Explicit strand selection SHALL preserve the current seeded strand behavior.

Compact clustering SHALL preserve the sampled occupied-cell count and favor dense groups. Increasing the factor with the same seed and other options SHALL NOT reduce the total eight-neighbor occupied pair count. Strand clustering SHALL preserve the sampled count and favor winding strands with occasional branches and open gaps at sparse densities; higher factors SHALL favor longer strands without a monotonic neighbor-count guarantee. Replication SHALL use the factor as the probability of reproduction as specified by its lifecycle. Tips SHALL use the factor to scale growth length as specified by its lifecycle.

All algorithms SHALL use the eight surrounding positions: horizontal, vertical, and diagonal. Adjacency SHALL NOT wrap across opposite canvas edges. Diagonal circle cells SHALL count as neighbors even though their shapes do not touch at corners. The CLI SHALL reject invalid factors and unknown or empty algorithm names before creating an output file and SHALL describe selection in help.

  • WHEN the user increases compact or strand clusterization with the seed and other options fixed
  • THEN the number of occupied cells remains unchanged
  • AND compact mode does not reduce the occupied neighbor-pair count
  • WHEN two occupied cells meet only diagonally on the grid
  • THEN they count as one neighboring pair for clustering
  • AND square and circle shapes use the same grid adjacency definition
  • WHEN the user selects strands, sparse density, and strong clusterization
  • THEN the pattern favors narrow winding strands, occasional branches, and open gaps
  • AND identical settings and seed reproduce the pattern
  • WHEN the user omits clusterization or explicitly sets it to 0, with regional seeding disabled
  • THEN the decoded image matches the independent-placement behavior
  • AND omitted algorithm selection remains equivalent to explicit compact for positive factors
  • WHEN clusterization is negative, greater than 1, nonnumeric, NaN, or infinite
  • THEN the command exits unsuccessfully with a diagnostic and creates no image
  • WHEN the algorithm name is empty or unsupported, even with zero factor
  • THEN the command reports the invalid selector and creates no image

In replication mode, each initial and newborn occupied cell SHALL receive one reproduction decision with probability equal to the clusterization factor, locally modified when regional growth variation is enabled. Zero base clusterization SHALL disable reproduction even with regional growth variation. Reproduction SHALL add exactly two distinct children chosen from the parent’s currently empty eight-neighbor positions, uniformly when placement controls are zero and with configured preferences otherwise. If fewer than two positions are available, the cell SHALL add none. A death decision SHALL add no children and SHALL NOT erase or recolor the parent. Newborn cells SHALL receive their own decision. Cells SHALL never be processed more than once or overwrite occupied positions, and processing SHALL terminate when no decisions remain.

  • WHEN a cell reproduces and at least two adjacent empty positions exist
  • THEN exactly two distinct adjacent positions become occupied
  • AND the parent remains occupied and its children may subsequently reproduce
  • WHEN a cell dies or has fewer than two empty adjacent positions
  • THEN it adds no children and remains visible
  • WHEN replication completes
  • THEN every initial occupied cell remains unchanged
  • AND the final population equals the initial population plus an even number of newborn cells

The CLI SHALL accept --replication-inheritance, --replication-forward-bias, --replication-crowding, and --replication-branching as finite numbers from 0 through 1 inclusive, defaulting to zero. Help SHALL describe each option. These controls SHALL affect only replication. Their zero defaults SHALL preserve existing seeded image content when regional controls are also disabled, and valid values SHALL NOT alter compact or strand output. Invalid values SHALL fail before creating an output file, even when the selected algorithm does not use them.

Inheritance SHALL set the probability that a newborn keeps its parent-to-child direction as its heading instead of taking a random heading. Roots SHALL start with random headings. Forward bias SHALL favor forward and gentle turns over sideways and backward choices relative to the heading. Inheritance alone SHALL NOT change image content when forward bias and branching are zero.

Crowding SHALL softly favor destinations with fewer occupied eight-neighbors, excluding the parent and including the first child when selecting the second. Branching SHALL set the probability that the second child favors a heading 90 degrees to either side of the first child’s direction. All valid vacancies SHALL retain positive selection weights; these controls SHALL NOT add a new reproduction rejection or permit partial births.

  • WHEN the four controls are omitted or explicitly zero and regional controls are disabled
  • THEN replication produces the existing seeded image
  • AND using the same controls and seed replays the same decoded pixels
  • WHEN inheritance and forward bias are enabled
  • THEN children can continue outward using their inherited heading
  • AND larger forward bias strengthens the forward preference
  • WHEN crowding avoidance is enabled
  • THEN more crowded destinations have lower relative weights than equally directed less crowded destinations
  • AND a crowded destination remains eligible if it is vacant
  • WHEN a reproduction decision selects sideways branching
  • THEN the second child’s placement favors a quarter-turn from the first child’s direction
  • AND two distinct children are still placed whenever two vacancies exist
  • WHEN any replication control is negative, above one, nonnumeric, NaN, or infinite
  • THEN the command fails with a diagnostic and creates no output for any algorithm

The CLI SHALL accept --replication-field-scale as an integer from 1 through 4096 logical cells, default 128, and --replication-growth-variation and --replication-seeding-variation as finite values from 0 through 1, default 0. All values SHALL be validated before output creation for every algorithm. Only replication SHALL use regional controls. Both variation strengths zero SHALL preserve all existing seeded image content regardless of field scale.

A seed-derived smooth field SHALL influence seeding and growth in the same spatial regions. Scale SHALL determine the approximate distance over which values vary, measured in logical cells. Growth variation SHALL bound the additive deviation from the base reproduction probability before clamping to [0,1]. Clamping MAY change the mean reproduction probability. Zero base probability SHALL prevent all reproduction.

Seeding variation SHALL interpolate between uniform sampling and regionally contrasted probabilities. The mean initial occupancy probability over the logical grid SHALL remain density within floating-point precision. This SHALL NOT require an exact occupied-cell count. Density 0 and 1 SHALL retain their existing behavior. Constant fields SHALL fall back to uniform probabilities. Regional seeding SHALL remain active when reproduction is disabled, and its sample SHALL be retained even when all cells happen to be occupied or vacant. Every logical cell, including a clipped edge cell, SHALL have equal weight in the mean. The field SHALL be evaluated without a full-resolution field buffer.

  • WHEN the user enables seeding and growth variation
  • THEN starting populations and reproduction probabilities vary gradually across the same regions
  • AND repeated invocations with the same seed and settings reproduce the image
  • WHEN regional seeding is enabled with reproduction disabled
  • THEN the local initial probabilities average to density
  • AND stronger seeding variation creates greater spatial contrast without promising an exact cell count
  • WHEN clusterization is zero with regional seeding enabled
  • THEN the output contains only the sampled regional initial population
  • AND regional growth variation does not introduce births
  • WHEN the grid has one cell, one row, one column, clipped cells, or a field scale larger than its dimensions
  • THEN generation remains finite and deterministic with probabilities within [0,1]
  • AND density endpoints and paired births remain valid
  • WHEN field scale is noninteger or outside 1..4096, or a variation is nonfinite or outside 0..1
  • THEN the command reports the invalid option and creates no image

The tips algorithm SHALL retain initial occupied cells and their colors and extend eight-connected paths into vacant cells. A tip SHALL ordinarily add one cell along a persistent, gradually turning heading. Occasional forks SHALL create a side tip with a smaller remaining growth budget than the continuing main tip. Tips SHALL stop on exhausted budgets, canvas boundaries, occupied destinations, or contact with existing growth outside their recent trail and local fork junction. Growth SHALL be finite without wraparound or overwrites.

Positive clusterization SHALL scale the available growth length; zero SHALL preserve independent placement. Final coverage SHALL NOT be constrained to the initial density or guaranteed monotonic in clusterization. Sparse starting populations SHALL favor narrow winding paths with open gaps. Replication-specific options SHALL NOT affect tips. The CLI SHALL describe tips and its density and factor semantics. Existing algorithms SHALL retain their seeded behavior.

  • WHEN tips is selected with sparse density and positive clusterization
  • THEN paths grow from the sampled initial cells and can add a single child
  • AND occasional forks allocate less growth to side branches than main tips
  • AND every resulting connected component contains an initial cell
  • WHEN a tips image is generated and then replayed with the same settings and seed
  • THEN both images have identical decoded pixels
  • AND every initial cell retains its palette color
  • WHEN a tip meets existing growth outside its local trail or junction, or a canvas edge
  • THEN it stops without overwriting cells or wrapping across the canvas
  • AND single-cell, narrow, clipped, empty, and full grids terminate correctly
  • WHEN valid replication controls change while tips settings and seed remain fixed
  • THEN the tips image remains unchanged