D2R Inventory Image
Auto-generated Diablo II item showcase images
What it is
A fun side project for Diablo II: Resurrected. It reads a curated list of items from a Google Sheet and renders a clean, shareable “inventory” image — handy for showing off finds in trade communities.
How it’s built
A small Go service (Gin for routing) composites the image from first
principles using only the standard library — no ImageMagick, no headless
browser. It draws a sprite sheet onto a canvas with image/draw, renders the
item rows with a bitmap font from golang.org/x/image/font, and encodes the
result with image/png.
Engineering highlights
- Spreadsheet as a CMS — the source of truth is a Google Sheet published as CSV, fetched over plain HTTP with no API keys or service accounts. Anyone non-technical can update the item list with zero deploy.
- Dynamic canvas sizing — the image width is computed from the longest row and the height from the row count, so output never clips or hardcodes dimensions.
- Stateless rendering — each regeneration is a full, deterministic redraw cached to disk; no incremental-update bugs, and the service can be restarted or scaled freely.
- Observability from day one — Prometheus counters and latency histograms
(image generation, CSV fetch) are exposed at
/metrics, scraped by Grafana Alloy into Grafana Cloud dashboards for request volume, errors, and timing.
Infrastructure
Served behind nginx with Let’s Encrypt TLS; metrics scraped by a Grafana Alloy agent. The whole thing is a single lightweight Go binary with a tiny footprint.
What I learned
Treating Google Sheets as a lightweight CMS is a surprisingly pragmatic pattern for small projects where the content owner isn’t a developer — and writing the image compositor by hand was a good reminder of how much you can do with Go’s standard library alone.