← Browse Dives
Full screen
Screenshot of Duck, Duck, Where? — Guess the Duck by its Range
Loading Interactive Dive...

Duck, Duck, Where? Guess the Duck by its Range

A geography guessing game. Identify a mystery duck species from its real worldwide GBIF sighting distribution plotted on a map, then get a photo + fun-fact reveal. Built on a distilled slice of GBIF's 180GB global biodiversity snapshot.

GameMapMotherDuckDuckDB
Author: Nick Saletto  ·  June 10, 2026    Region: us-east-1

AI Prompts Used

1Prompt 1
Build a MotherDuck Dive called "Duck, Duck, Where?" — a geography guessing game: the
player identifies a mystery duck from its real worldwide GBIF sighting distribution
plotted on a world map, with a photo + fun-fact reveal. Do all data prep in MotherDuck
via the MCP tools, validate coverage before materializing, then build the Dive.

== DATA SOURCE (GBIF) ==
- Public S3, no credentials. Latest monthly snapshot lives at
  s3://gbif-open-data-us-east-1/occurrence/<YYYY-MM-01>/occurrence.parquet/.
  Find the newest date with glob(); part files are named 000001, 000002, ... (NOT 000000).
- Records cluster by dataset, so any single part file may contain zero birds. Do NOT scan
  the full ~180GB. Sample part files spread evenly across the snapshot (e.g., every ~100th).
  read_parquet rejects subqueries, so GENERATE the sampled file paths, then INLINE them as a
  literal list.

== SPECIES (30, balanced across continents) ==
Anas platyrhynchos, Spatula clypeata, Aix sponsa, Aix galericulata, Anas acuta,
Bucephala albeola, Lophodytes cucullatus, Aythya fuligula, Bucephala clangula,
Aythya valisineria, Oxyura jamaicensis, Somateria mollissima, Somateria spectabilis,
Histrionicus histrionicus, Merganetta armata, Chenonetta jubata, Tadorna variegata,
Cairina moschata, Mareca strepera, Mareca penelope, Mareca americana, Mergus merganser,
Clangula hyemalis, Spatula cyanoptera, Netta rufina, Aythya ferina, Tadorna tadorna,
Dendrocygna autumnalis, Anas superciliosa, Netta peposaca.

Mark these 10 as the EASY/geo-obvious pool (single-region endemics + household names):
Anas platyrhynchos, Aix sponsa, Aix galericulata, Chenonetta jubata, Anas superciliosa,
Tadorna variegata, Merganetta armata, Cairina moschata, Netta peposaca, Dendrocygna autumnalis.

== TABLES (build in a DEDICATED database named `ducks`, NOT the main warehouse) ==
1. points(scientific_name, lat, lon, countrycode, year): from the sampled files, filter
   species IN (...), occurrencestatus='PRESENT', valid lat/lon (exclude null and 0,0),
   cap ~800 random points/species. Capture each species' specieskey here too.
2. species(scientific_name, common_name, specieskey, difficulty, native_region, fun_fact):
   hand-write common names + a one-line fun fact each; difficulty = 'easy' for the 10 above,
   else 'standard'.
3. photos: the snapshot only FLAGS mediatype, it has no image URL. Pull CC-licensed photos
   from the GBIF API inside MotherDuck via read_json over https:
   https://api.gbif.org/v1/occurrence/search?taxonKey=<key>&mediaType=StillImage
     &license=CC0_1_0&license=CC_BY_4_0&license=CC_BY_NC_4_0&limit=40
   Unnest results, take media[0].identifier/license/creator, keep only CC licenses.
4. photo_thumbs(scientific_name, data_url, creator, license): Dives BLOCK external images
   via CSP, so store image BYTES as base64 data: URLs. Take ~4 photos/species, rewrite to
   small thumbnails (flickr `_b.jpg`->`_n.jpg`, iNaturalist `/original.`->`/small.`), fetch
   with read_blob([...inlined urls...]) (also rejects subqueries), store
   'data:image/jpeg;base64,'||to_base64(content).
5. basemap(geojson): can't fetch at runtime, and MotherDuck CANNOT install the spatial
   extension. Store a world outline as text:
   CREATE TABLE ducks.main.basemap AS SELECT content AS geojson FROM read_text(
   'https://raw.githubusercontent.com/nvkelso/natural-earth-vector/master/geojson/ne_110m_admin_0_countries.geojson');

== SHARING ==
Create an unrestricted share: CREATE SHARE ducks FROM ducks (ACCESS UNRESTRICTED, UPDATE AUTOMATIC).
Get its URL from MD_INFORMATION_SCHEMA.OWNED_SHARES.

== DIVE (React + useSQLQuery; fully-qualified queries; d3 for geo; no external fetch; React state only) ==
- Declare the share so gallery viewers attach it, aliased to avoid colliding with the owned db:
  export const REQUIRED_DATABASES = [{ type:'share', path:'md:_share/ducks/<uuid>', alias:'ducks_share' }];
  Reference every table as "ducks_share"."main".<table>.
- Map: d3.geoNaturalEarth1() + d3.geoPath() (parse basemap geojson; plot the target species'
  points as small dots). No raw-SVG charts.
- Gameplay: one "run" = all 30, no repeats, dealt from a shuffled deck whose FIRST 4 cards
  come from the easy pool, rest random. 4 options (target + 3 random distractors). 3 hints/run;
  a hint removes 2 wrong options (50/50) and decrements. Score = correct-in-a-row streak + a
  best. ANY wrong answer ends the run and resets everything (streak 0, deck + hints refreshed,
  back to the easy on-ramp); its reveal button says "Start over", a correct one says "Next duck".
- Reveal: correct/incorrect, common + scientific name, a random photo from photo_thumbs (data:
  URL, fetched per-round), native_region, fun_fact, and a "More on GBIF" link to
  https://www.gbif.org/species/<specieskey>.
- Win: when the streak reaches 30, show a popup over the dimmed board titled
  "🦆 NEW ACHIEVEMENT UNLOCKED: Ducking Expert" with playful copy (the odds of guessing all 30
  at random are ~1 in 1.15 quintillion = 4^30, "more suspicious than a mallard with a fake
  mustache", etc.) and a "Play again" button that resets the game.
- Styling: clean, minimal, MotherDuck blue (#0777b3). Wrap query numerics in Number().

Comments

Log in to leave a comment.

No comments yet. Be the first!