func Generate
crossing ActionGenerate renders a pattern, adds it to the on-chain gallery, and returns the rendered art.
Package asciiart is a small on-chain ASCII art generator. Instead of a hand-authored font table, each pattern is prod...
⚠️ Experimental — generated with no human supervision by the daily MCP pipeline to exercise gno tooling. Not audited. See r/moul/x/daily.
An on-chain ASCII art generator that draws patterns (diamond, pyramid, Sierpinski triangle, checkerboard) from short deterministic formulas instead of a hand-authored font table -- the Sierpinski gasket is just row & col == 0. Call Generate(pattern, size) to render a piece and add it to a public gallery; browse the gallery or a specific piece via Render. It's a neat, self-contained example of generative art as pure on-chain logic.
Built for sapphire (gno 0.9). Live demo (agent address): https://sapphire.testnets.gno.land/r/g12cs4cehujpffpjpywmkqj43m6u5ya53nj69sjz/asciiart
Two ports against v0, which stays live and untouched.
Identical behaviour to v0 apart from rendering, which now goes
through p/moul/kit/ui instead of the local escapeInline helper.
Real escaping. The local helper replaced a handful of markdown metacharacters. ui.Inline and ui.Cell delegate to p/nt/markdown/sanitize, which also strips bidi and zero-width characters and folds newlines, so user text cannot reorder or escape the line it sits on.
State moved from a hand-rolled avl.Tree + nextID + zero-padding helper to
p/moul/kit/store, which keys entries by
seqid instead of a fixed-width decimal string.
v0 padded ids to width 6. Past that width the padding stops and the tree
orders "1000000000000" before "999999999999", so every list this realm
renders would be wrong from that entry on. store keys are 8 big-endian bytes
whose order is numeric for every uint64, so there is no width left to outgrow.
piece loses its ID field, which the store now owns. The gallery page also
gets simpler: v0 reverse-iterated the whole tree with a shown counter to
stop at eight, where PageReverse(1, 8) asks the store for exactly that window.
A non-numeric or zero path is now rejected by ParseID rather than by
strconv.Atoi plus a range check.
Ids stay plain integers and the rendered output of the storage port is
unchanged. Each port changes something v0 promised, one the rendered output
and one the storage layout, so under this repo's versioning rule each is a
compatibility change and neither could be an edit to v0 in place.
They land in the same new version because v1 was never published. A
version number is a tag on something that exists on a chain, and until it does
there is nothing for a second number to avoid disturbing, so the right move is
to keep editing the version you have. gnopm unbump is what folded the second
port back down into this one.
Part of moul/gno-contracts — moul's versioned gno.land contracts. See the repository for the full catalog, build/test tooling, and usage.
Dependency graph:

🧪 Highly experimental — potentially vibe-coded. Not audited; may break, change, or be removed at any time. Do not use with anything of value. Full disclaimer: DISCLAIMER.
Package asciiart is a small on-chain ASCII art generator. Instead of a hand-authored font table, each pattern is produced by a short, pure, deterministic algorithm -- e.g. the Sierpinski triangle falls out of a single bitwise AND over row/column indices. Callers pick a pattern and a size; the realm renders it and keeps a gallery of everyone's generations.
Generate renders a pattern, adds it to the on-chain gallery, and returns the rendered art.
Render shows the pattern guide + gallery at "", or one piece by numeric ID.
RenderChecker draws an n x n checkerboard of # and . cells.
RenderDiamond draws a filled diamond of half-width n (2n-1 rows total), each row's stars centered and padded with spaces.
RenderPyramid draws a solid triangle n rows tall, widening by two stars per row and centered with leading spaces.
RenderSierpinski draws a Sierpinski triangle in an n x n grid (n must be a power of two): cell (row, col) is filled exactly when row&col == 0, the classic bitwise identity for Pascal's-triangle-mod-2.