<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Rudy Orre</title><description>Notes on backend engineering, distributed systems, and software.</description><link>https://rudyorre.com/</link><item><title>Deterministic SVG glyphs at build time</title><link>https://rudyorre.com/writing/procedural-glyphs/</link><guid isPermaLink="true">https://rudyorre.com/writing/procedural-glyphs/</guid><description>How this site generates zero-runtime geometric thumbnails from post slugs using FNV-1a, Murmur3 avalanche mixing, and SplitMix32.</description><pubDate>Sun, 08 Nov 2026 00:00:00 GMT</pubDate><content:encoded>import ProceduralGlyph from &apos;../../components/ProceduralGlyph.astro&apos;;
import GlyphWorkbench from &apos;../../components/GlyphWorkbench.astro&apos;;
import { familyLabel } from &apos;../../lib/glyph-engine&apos;;

Technical blogs have an awkward thumbnail problem: most posts don&apos;t have a
natural hero photo, and slapping stock art onto a post about a CLI tool or SQL
query planning feels wrong. On the other hand, a list of twenty titles and dates
with no visual anchor quickly turns into a wall of text.

To fix this, every post and project on this site gets a deterministic `64×64`
geometric badge (and a `640×140` header banner) compiled into static inline
`&lt;svg&gt;` markup during build time.

## Interactive seed tester

Type any seed string below (or hit **randomize**) to synthesize both the `64×64`
icon badge and the `640×140` header banner in real time:

&lt;GlyphWorkbench mode=&quot;inline&quot; initialSeed=&quot;post:procedural-glyphs&quot; /&gt;

## How a seed becomes a glyph

Given a seed string like `&quot;post:rebuilding-this-site&quot;`, the generator runs two
tiny, zero-dependency stages:

1. **32-bit FNV-1a + MurmurHash3 finalizer (`hashSeed(seed)`):** Computes an
   FNV-1a hash over the UTF-16 code units and finishes with a 32-bit Murmur3
   avalanche mixer so even a single-character edit cascades across all 32 bits.
   Independent bit slices select:
   - **Motif family (`h0 % 10`):** Picks one of **10 geometric motif families** (`orbits`, `ridges`, `mesh`, `iso-stack`, `polar`, `lissajous`, `bus-routing`, `interference`, `hilbert`, or `automata`).
   - **Dual accent palette (`(h0 &gt;&gt;&gt; 4) % 8`):** Picks primary and secondary
     technical accents from an 8-color HSL-balanced palette.
   - **Registration grid (`(h0 &gt;&gt;&gt; 11) % 4`):** Selects between crosshair rings,
     octagonal target frames, axis ruler ticks, or corner brackets.
2. **SplitMix32 PRNG stream (`makeRng(h0)`):** Produces a repeatable stream of
   floats in `[0, 1)` from that 32-bit state to drive sub-topologies, orbital
   eccentricity, Fourier carrier frequencies, Lissajous ratios, and Hamiltonian
   lattice walks.

```ts
export function hashSeed(str: string): number {
  let h = 2166136261;
  for (let i = 0; i &lt; str.length; i++) {
    h ^= str.charCodeAt(i);
    h = Math.imul(h, 16777619);
  }
  // MurmurHash3 32-bit finalizer for full bit avalanche
  h ^= h &gt;&gt;&gt; 16;
  h = Math.imul(h, 0x85ebca6b);
  h ^= h &gt;&gt;&gt; 13;
  h = Math.imul(h, 0xc2b2ae35);
  h ^= h &gt;&gt;&gt; 16;
  return h &gt;&gt;&gt; 0;
}
```

## Specimen gallery

Expanding from a handful of rigid templates to parameterized motif families—each
with internal sub-modes (e.g., coaxial vs. binary barycenter orbits, Gaussian vs.
bimodal Fourier envelopes, annular vs. phyllotaxis spiral meshes)—keeps
thumbnails visually distinct across long lists of posts.

Here&apos;s an assortment of build-time glyphs generated from different post seeds:

export const seeds = [
  &apos;post:rebuilding-this-site&apos;,
  &apos;post:procedural-glyphs&apos;,
  &apos;post:consensus-notes&apos;,
  &apos;post:wal-compaction&apos;,
  &apos;post:zero-copy-io&apos;,
  &apos;post:raft-leases&apos;,
  &apos;post:bloom-filters&apos;,
  &apos;post:lsm-trees&apos;,
  &apos;post:grpc-backpressure&apos;,
  &apos;post:query-planner&apos;,
  &apos;post:clock-drift&apos;,
  &apos;post:ebpf-tracing&apos;,
  &apos;post:tail-latency&apos;,
  &apos;post:simd-parsing&apos;,
  &apos;post:ring-buffers&apos;,
  &apos;post:consistent-hashing&apos;,
  &apos;post:merkle-trees&apos;,
  &apos;post:b-plus-trees&apos;,
  &apos;post:vector-clocks&apos;,
  &apos;post:roaring-bitmaps&apos;,
];

&lt;div class=&quot;glyph-grid-showcase&quot;&gt;
  {seeds.map((s) =&gt; (
    &lt;div class=&quot;glyph-specimen&quot;&gt;
      &lt;ProceduralGlyph seed={s} size=&quot;md&quot; /&gt;
      &lt;div class=&quot;glyph-specimen-meta&quot;&gt;
        &lt;span class=&quot;glyph-specimen-seed&quot; title={s}&gt;{s.replace(&apos;post:&apos;, &apos;&apos;)}&lt;/span&gt;
        &lt;span class=&quot;glyph-specimen-family&quot;&gt;{familyLabel(s)}&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  ))}
&lt;/div&gt;

## Banner variants (`640×140`)

The same engine also synthesizes wide header banners (`size=&quot;banner&quot;`) by
adapting node counts, wave steps, and aspect ratios across a `640×140` viewBox:

&lt;div style=&quot;display: flex; flex-direction: column; gap: 0.75rem; margin: 1.25rem 0;&quot;&gt;
  &lt;ProceduralGlyph seed=&quot;post:wal-compaction&quot; size=&quot;banner&quot; /&gt;
  &lt;ProceduralGlyph seed=&quot;post:bloom-filters&quot; size=&quot;banner&quot; /&gt;
  &lt;ProceduralGlyph seed=&quot;post:merkle-trees&quot; size=&quot;banner&quot; /&gt;
  &lt;ProceduralGlyph seed=&quot;post:rebuilding-this-site&quot; size=&quot;banner&quot; /&gt;
  &lt;ProceduralGlyph seed=&quot;post:clock-drift&quot; size=&quot;banner&quot; /&gt;
&lt;/div&gt;

To inspect the extracted PRNG stream, pin specific motif families or palettes,
and export raw SVGs, open the [**Procedural SVG Glyph Workbench (`/lab/glyphs`)**](/lab/glyphs).</content:encoded></item><item><title>Notes on rebuilding this site</title><link>https://rudyorre.com/writing/rebuilding-this-site/</link><guid isPermaLink="true">https://rudyorre.com/writing/rebuilding-this-site/</guid><description>Why I stripped out the client-side React runtime, six themes, and animation libraries in favor of plain HTML, CSS, and markdown.</description><pubDate>Sun, 08 Nov 2026 00:00:00 GMT</pubDate><content:encoded>Every once in a while I look at my personal site and realize it has accumulated
far too many dependencies for a simple, static site.

The previous iteration shipped a full React runtime, two component libraries, an
animation engine, and six color themes just to render a single page of text. We
really don&apos;t need all that.

## What matters for a site like this

As an engineer, the qualities I care about in software are pretty simple:

1. **Predictable latency.** Static text over the wire should arrive and paint in
   a single round-trip.
2. **Few moving parts.** Every dependency is a future build failure when you
   come back six months later just to publish a blog post.
3. **Clear failure modes.** Plain `&lt;a href&gt;` links, semantic HTML, and zero
   required client JavaScript mean the page works everywhere.

```go
// Keep the critical path boring.
func serve(w http.ResponseWriter, r *http.Request) {
    w.Header().Set(&quot;Cache-Control&quot;, &quot;public, max-age=3600&quot;)
    http.ServeFile(w, r, &quot;index.html&quot;)
}
```

## The new setup

This version is built with [Astro](https://astro.build), authored in Markdown,
and styled with a single CSS file using custom properties. Search runs against a
small precomputed JSON index that only loads when you press `⌘K` or `/`.

Now there is nothing left to configure—just a folder of `.md` files to write in.</content:encoded></item></channel></rss>