The dark and light covers move up beside the generator as the shipped assets; the six exploratory variants and the contact sheet go. Trims the generator to match: VARIANTS is now only the two covers, and with the retired variants gone so are the knobs nothing reaches any more — the wordmark caption, the branded palette, the whole-board height fit and the non-brand tile face. Left behind, they would read as supported options that no output exercises. `node build-cover.mjs` now reproduces exactly the two committed PNGs.
VK community cover
The cover art for the VK community (1920×768). The community avatar — the «Э» tile — is
uploaded separately; this is only the backdrop behind it.
| File | What |
|---|---|
cover-night-spot.png |
the dark cover — board in a warm spotlight |
cover-day-spot.png |
the light cover — same camera, same crop, daylight |
build-cover.mjs |
the generator both are rendered by |
build-cover.mjs is a small software renderer that draws an Эрудит board in perspective with
the opening ГРАМОТНОСТЬ / СОПЕРНИК / ЭРУДИЦИЯ / УМ already played, and writes the two PNGs
next to itself.
cd assets/vk/cover
node build-cover.mjs # both covers
node build-cover.mjs night-spot # one of them
FAST=1 node build-cover.mjs # 1x instead of 2x supersampling, for quick iteration
ZONES=1 node build-cover.mjs # overlay the VK keep-outs on the render
LAYOUT=cross node build-cover.mjs # the alternative word arrangement
It needs no install: skia-canvas comes from the render sidecar's node_modules, and the
letters are set in Spectral-Bold.ttf from the icon brand folder.
The position
ГРАМОТНОСТЬ opens through the centre square (its Т on H8) and the other three words hook
onto a shared letter. assertLegal re-reads the finished grid and fails the build if the
centre is uncovered, if a declared word is missing, or if any maximal run of two or more
letters is a word nobody played — so the board on the cover is always a position the engine
would accept. All four words are in the Эрудит dictionary; tile values come from
scrabble-solver rules.Erudit().
The default ladder arrangement puts both long words horizontally. The cross arrangement
hangs ЭРУДИЦИЯ down the left instead, which looks more symmetric but collides with the VK
mobile avatar (below).
VK keep-outs
Measured off VK's own template (../VK_group_cover_template.fig), in cover pixels:
| Zone | Area | Why |
|---|---|---|
| Top crop | y < 130 |
trimmed by some clients — nothing important there |
| Mobile avatar | circle, centre (283, 818), r 283 |
the community picture sits over the bottom-left in the VK app |
ZONES=1 paints both so a composition can be checked against them.
Rendering technique
The camera has pitch only — no roll, no yaw — so a board-space horizontal line always maps to
a screen-space horizontal line. That makes the perspective warp an exact per-scanline remap of
a flat texture rather than a general homography: the board surface and the tile faces are each
drawn once, flat, at high resolution, then replayed band by band (warpPlane). Tile thickness
is filled as real 3D quads between the two planes, so the tiles have visible edges.
Two things that are easy to get wrong here and cost a hundredfold in render time:
ctx.filter = 'blur(...)' applies per drawing call, so many blurred shapes must be collected
into one offscreen layer and blurred once (blurred); and drawImage re-snapshots a live
Canvas source on every call, so a texture sampled hundreds of times must be baked into an
Image first (freeze).