Skip to content

UGC -> single bucket migration script - #317

Draft
bnolan wants to merge 3 commits into
mainfrom
ugc-single-bucket
Draft

UGC -> single bucket migration script#317
bnolan wants to merge 3 commits into
mainfrom
ugc-single-bucket

Conversation

@bnolan

@bnolan bnolan commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

Summary

Island-parameterised migration that consolidates all parcel UGC into the single voxels-ugc bucket (served via ugc.crvox.com) and rewrites parcel scene JSON to point only at that host. Replaces the current sprawl of hosts (compressor, img, herring, media, files, cdn2 + external discord/reddit/dropbox/ipfs).

  • Images -> ETC1S .ktx2 (512, via basisu) + .webp (2k max side), stored side by side; url rewritten to the extensionless base key.
  • Vox / audio / video / lightmap / tileset -> copied as-is, 100MB cap (skip + log over limit).
  • Embedded far-LOD placeholders baked into the JSON for instant zero-fetch distant render: 8x8 jpeg feature.thumb for images, 4x4x4 fixed-palette feature.lod4 for vox (shared palette in common/vox-palette.ts).
  • Discord workaround: refreshes expired signed cdn urls via /attachments/refresh-urls (needs DISCORD_BOT_TOKEN), soft-fails to skip.
  • Idempotent (skips already-migrated urls + existing keys), per-parcel dedup, opensea permalinks skipped, JSONL manifest for audit/rollback, --dry-run mode.

Files: scripts/migrate-island-assets.ts (cli), scripts/lib/ugc-migrate.ts (engine), common/vox-palette.ts (shared palette), plans/ugc-single-bucket.md (what/why notes).

Not in this PR (phase 2, client)

The script writes the new bucket urls + placeholders but the client doesn't consume them yet: ktx2 transcoder registration, distance LOD swap (.ktx2 -> .webp), far-LOD render of thumb/lod4, and making voxel-field treat the migrated absolute content.tileset. See plan notes.

Test plan

  • Offline: palette, 4x4x4 vox LOD, sharp + basisu (.ktx2/.webp/thumb) all produce valid output
  • --dry-run on 5 Poneke parcels: 41 img / 80 vox / 3 copy planned, manifest mappings correct, dedup confirmed, 0 errors, 0 db writes
  • Live run on a small island, then spot-check in world (needs UGC_SECRET + DISCORD_BOT_TOKEN + network) -- holding for review

Made with Cursor

bnolan and others added 3 commits June 20, 2026 13:23
Pulls all parcel UGC (images, vox, audio/video, lightmaps, tilesets) into the
voxels-ugc bucket (ugc.crvox.com), converts images to ETC1S .ktx2 + .webp, and
rewrites parcel scene JSON in place. Bakes far-LOD placeholders into the JSON
(8x8 jpeg feature.thumb for images, 4x4x4 fixed-palette feature.lod4 for vox)
so distant parcels render instantly with zero fetches.

Includes the discord cdn refresh workaround, 100MB cap, opensea skip, per-parcel
dedup, idempotent uploads, and a --dry-run mode. Client-side consumption is
phase 2 (see plans/ugc-single-bucket.md).

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Require UGC_ACCESS_KEY_ID + UGC_SECRET env vars for live runs; harden idempotency and discord refresh handling.

Co-authored-by: Cursor <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant