diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml new file mode 100644 index 0000000..a52d988 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -0,0 +1,55 @@ +name: Bug report +description: Report a reproducible problem in an experience or its source. +title: "[Bug]: " +labels: + - bug +body: + - type: markdown + attributes: + value: Thanks for helping improve Mint Playground. Please keep security reports private as described in SECURITY.md. + - type: input + id: experience + attributes: + label: Experience slug + description: The directory name or live-demo slug, such as vanguard-protocol. + placeholder: vanguard-protocol + validations: + required: true + - type: textarea + id: problem + attributes: + label: What happened? + description: Describe the behavior and what you expected instead. + validations: + required: true + - type: textarea + id: reproduction + attributes: + label: Reproduction steps + placeholder: | + 1. Open … + 2. Select … + 3. Observe … + validations: + required: true + - type: input + id: environment + attributes: + label: Browser and device + placeholder: Chrome 140 on macOS 16, or Safari on iPhone 18 + validations: + required: true + - type: textarea + id: evidence + attributes: + label: Screenshots, recordings, or console output + description: Remove tokens, personal data, and other sensitive information before posting. + - type: checkboxes + id: checks + attributes: + label: Checks + options: + - label: I searched existing issues for this problem. + required: true + - label: This is not a security vulnerability. + required: true diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..797a1e7 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,8 @@ +blank_issues_enabled: false +contact_links: + - name: Mint MCP documentation + url: https://mcp.mint.gg/docs + about: Get help installing or using Mint MCP. + - name: Play the experiences + url: https://play.mint.gg + about: Confirm whether a problem also appears in the deployed experience. diff --git a/.github/ISSUE_TEMPLATE/experience-request.yml b/.github/ISSUE_TEMPLATE/experience-request.yml new file mode 100644 index 0000000..d4bc532 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/experience-request.yml @@ -0,0 +1,45 @@ +name: Experience request +description: Suggest a 3D experience or reusable pattern for a future Playground drop. +title: "[Experience]: " +labels: + - enhancement +body: + - type: textarea + id: concept + attributes: + label: Concept + description: What should someone be able to do, and why is it valuable as an open-source reference? + validations: + required: true + - type: dropdown + id: category + attributes: + label: Category + options: + - Browser game + - Product or commerce + - Data visualization or education + - Creative or editorial + - World or simulation + - Reusable Three.js pattern + validations: + required: true + - type: textarea + id: learning + attributes: + label: What should developers learn from it? + description: List the interaction, rendering, architecture, or performance patterns it would demonstrate. + validations: + required: true + - type: textarea + id: references + attributes: + label: References + description: Link to relevant open-source projects or original visual references. Do not attach unlicensed media. + - type: checkboxes + id: rights + attributes: + label: Rights check + options: + - label: The proposal does not depend on third-party characters, brands, or media that Mint lacks permission to publish. + required: true diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..21a4bdd --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,21 @@ +## What changed + + + +## Experience + + + +## Verification + +- [ ] `pnpm validate:catalog` +- [ ] The affected experience builds successfully +- [ ] Relevant tests pass +- [ ] I checked keyboard, touch, and reduced-motion behavior where applicable +- [ ] I included before-and-after captures for visual changes + +## Contribution checks + +- [ ] This change is focused and does not reformat unrelated files +- [ ] I have permission to publish all contributed code and media +- [ ] No credentials, production data, or downloaded Mint CDN assets are included diff --git a/.github/assets/experiences/boulder-cove.webp b/.github/assets/experiences/boulder-cove.webp new file mode 100644 index 0000000..cb52d2d Binary files /dev/null and b/.github/assets/experiences/boulder-cove.webp differ diff --git a/.github/assets/experiences/breakline.webp b/.github/assets/experiences/breakline.webp new file mode 100644 index 0000000..825b09a Binary files /dev/null and b/.github/assets/experiences/breakline.webp differ diff --git a/.github/assets/experiences/cdx-2089-music-player.webp b/.github/assets/experiences/cdx-2089-music-player.webp new file mode 100644 index 0000000..083be6b Binary files /dev/null and b/.github/assets/experiences/cdx-2089-music-player.webp differ diff --git a/.github/assets/experiences/clicky.webp b/.github/assets/experiences/clicky.webp new file mode 100644 index 0000000..8ac3e40 Binary files /dev/null and b/.github/assets/experiences/clicky.webp differ diff --git a/.github/assets/experiences/common-form.webp b/.github/assets/experiences/common-form.webp new file mode 100644 index 0000000..e99b50c Binary files /dev/null and b/.github/assets/experiences/common-form.webp differ diff --git a/.github/assets/experiences/complete-shelf.webp b/.github/assets/experiences/complete-shelf.webp new file mode 100644 index 0000000..b8f09d3 Binary files /dev/null and b/.github/assets/experiences/complete-shelf.webp differ diff --git a/.github/assets/experiences/compound-visualization.webp b/.github/assets/experiences/compound-visualization.webp new file mode 100644 index 0000000..f7cd5a2 Binary files /dev/null and b/.github/assets/experiences/compound-visualization.webp differ diff --git a/.github/assets/experiences/dead-reckoning.webp b/.github/assets/experiences/dead-reckoning.webp new file mode 100644 index 0000000..1ef88dd Binary files /dev/null and b/.github/assets/experiences/dead-reckoning.webp differ diff --git a/.github/assets/experiences/dynasty-index.webp b/.github/assets/experiences/dynasty-index.webp new file mode 100644 index 0000000..bbaaf95 Binary files /dev/null and b/.github/assets/experiences/dynasty-index.webp differ diff --git a/.github/assets/experiences/elemental-chess.webp b/.github/assets/experiences/elemental-chess.webp new file mode 100644 index 0000000..da4974d Binary files /dev/null and b/.github/assets/experiences/elemental-chess.webp differ diff --git a/.github/assets/experiences/fieldline-santa-clara.webp b/.github/assets/experiences/fieldline-santa-clara.webp new file mode 100644 index 0000000..0a6ba31 Binary files /dev/null and b/.github/assets/experiences/fieldline-santa-clara.webp differ diff --git a/.github/assets/experiences/final-whistle.webp b/.github/assets/experiences/final-whistle.webp new file mode 100644 index 0000000..07576ad Binary files /dev/null and b/.github/assets/experiences/final-whistle.webp differ diff --git a/.github/assets/experiences/financial-city.webp b/.github/assets/experiences/financial-city.webp new file mode 100644 index 0000000..7ca8cf4 Binary files /dev/null and b/.github/assets/experiences/financial-city.webp differ diff --git a/.github/assets/experiences/flappy-bird-3d.webp b/.github/assets/experiences/flappy-bird-3d.webp new file mode 100644 index 0000000..683346c Binary files /dev/null and b/.github/assets/experiences/flappy-bird-3d.webp differ diff --git a/.github/assets/experiences/forgotten-experiment.webp b/.github/assets/experiences/forgotten-experiment.webp new file mode 100644 index 0000000..97ba7fc Binary files /dev/null and b/.github/assets/experiences/forgotten-experiment.webp differ diff --git a/.github/assets/experiences/four-fields.webp b/.github/assets/experiences/four-fields.webp new file mode 100644 index 0000000..5b5d8b7 Binary files /dev/null and b/.github/assets/experiences/four-fields.webp differ diff --git a/.github/assets/experiences/helios-form.webp b/.github/assets/experiences/helios-form.webp new file mode 100644 index 0000000..9d041eb Binary files /dev/null and b/.github/assets/experiences/helios-form.webp differ diff --git a/.github/assets/experiences/impossible-places.webp b/.github/assets/experiences/impossible-places.webp new file mode 100644 index 0000000..b85e6c3 Binary files /dev/null and b/.github/assets/experiences/impossible-places.webp differ diff --git a/.github/assets/experiences/jimothys-backyard-dash.webp b/.github/assets/experiences/jimothys-backyard-dash.webp new file mode 100644 index 0000000..e5a1774 Binary files /dev/null and b/.github/assets/experiences/jimothys-backyard-dash.webp differ diff --git a/.github/assets/experiences/kirby-smash.webp b/.github/assets/experiences/kirby-smash.webp new file mode 100644 index 0000000..0325c2a Binary files /dev/null and b/.github/assets/experiences/kirby-smash.webp differ diff --git a/.github/assets/experiences/memory-constellation.webp b/.github/assets/experiences/memory-constellation.webp new file mode 100644 index 0000000..8fd3762 Binary files /dev/null and b/.github/assets/experiences/memory-constellation.webp differ diff --git a/.github/assets/experiences/mint-hoops.webp b/.github/assets/experiences/mint-hoops.webp new file mode 100644 index 0000000..c63030d Binary files /dev/null and b/.github/assets/experiences/mint-hoops.webp differ diff --git a/.github/assets/experiences/mint-putt.webp b/.github/assets/experiences/mint-putt.webp new file mode 100644 index 0000000..dfc6246 Binary files /dev/null and b/.github/assets/experiences/mint-putt.webp differ diff --git a/.github/assets/experiences/mossbound.webp b/.github/assets/experiences/mossbound.webp new file mode 100644 index 0000000..b1e4bff Binary files /dev/null and b/.github/assets/experiences/mossbound.webp differ diff --git a/.github/assets/experiences/neon-relic.webp b/.github/assets/experiences/neon-relic.webp new file mode 100644 index 0000000..f60d1b4 Binary files /dev/null and b/.github/assets/experiences/neon-relic.webp differ diff --git a/.github/assets/experiences/orbit-week.webp b/.github/assets/experiences/orbit-week.webp new file mode 100644 index 0000000..9a63dcf Binary files /dev/null and b/.github/assets/experiences/orbit-week.webp differ diff --git a/.github/assets/experiences/periodic-table.webp b/.github/assets/experiences/periodic-table.webp new file mode 100644 index 0000000..5019ed4 Binary files /dev/null and b/.github/assets/experiences/periodic-table.webp differ diff --git a/.github/assets/experiences/pogo-man.webp b/.github/assets/experiences/pogo-man.webp new file mode 100644 index 0000000..f1a1d09 Binary files /dev/null and b/.github/assets/experiences/pogo-man.webp differ diff --git a/.github/assets/experiences/project-forge-5.webp b/.github/assets/experiences/project-forge-5.webp new file mode 100644 index 0000000..b55e062 Binary files /dev/null and b/.github/assets/experiences/project-forge-5.webp differ diff --git a/.github/assets/experiences/quadrotor-sandbox.webp b/.github/assets/experiences/quadrotor-sandbox.webp new file mode 100644 index 0000000..df1c0be Binary files /dev/null and b/.github/assets/experiences/quadrotor-sandbox.webp differ diff --git a/.github/assets/experiences/reef-rivals.webp b/.github/assets/experiences/reef-rivals.webp new file mode 100644 index 0000000..3169dba Binary files /dev/null and b/.github/assets/experiences/reef-rivals.webp differ diff --git a/.github/assets/experiences/robot-store.webp b/.github/assets/experiences/robot-store.webp new file mode 100644 index 0000000..637bb0d Binary files /dev/null and b/.github/assets/experiences/robot-store.webp differ diff --git a/.github/assets/experiences/room-ritual.webp b/.github/assets/experiences/room-ritual.webp new file mode 100644 index 0000000..ddc06e4 Binary files /dev/null and b/.github/assets/experiences/room-ritual.webp differ diff --git a/.github/assets/experiences/seatline-nyc.webp b/.github/assets/experiences/seatline-nyc.webp new file mode 100644 index 0000000..b73bc6a Binary files /dev/null and b/.github/assets/experiences/seatline-nyc.webp differ diff --git a/.github/assets/experiences/sf-tennis-atlas.webp b/.github/assets/experiences/sf-tennis-atlas.webp new file mode 100644 index 0000000..980281a Binary files /dev/null and b/.github/assets/experiences/sf-tennis-atlas.webp differ diff --git a/.github/assets/experiences/side-one.webp b/.github/assets/experiences/side-one.webp new file mode 100644 index 0000000..db1a219 Binary files /dev/null and b/.github/assets/experiences/side-one.webp differ diff --git a/.github/assets/experiences/sleeping-snorlax.webp b/.github/assets/experiences/sleeping-snorlax.webp new file mode 100644 index 0000000..53b9d67 Binary files /dev/null and b/.github/assets/experiences/sleeping-snorlax.webp differ diff --git a/.github/assets/experiences/sole-archive.webp b/.github/assets/experiences/sole-archive.webp new file mode 100644 index 0000000..a77f717 Binary files /dev/null and b/.github/assets/experiences/sole-archive.webp differ diff --git a/.github/assets/experiences/vanguard-protocol.webp b/.github/assets/experiences/vanguard-protocol.webp new file mode 100644 index 0000000..4294477 Binary files /dev/null and b/.github/assets/experiences/vanguard-protocol.webp differ diff --git a/.github/assets/social-preview.jpg b/.github/assets/social-preview.jpg new file mode 100644 index 0000000..9a3ed1d Binary files /dev/null and b/.github/assets/social-preview.jpg differ diff --git a/.github/release.yml b/.github/release.yml new file mode 100644 index 0000000..9e33cdd --- /dev/null +++ b/.github/release.yml @@ -0,0 +1,21 @@ +changelog: + exclude: + labels: + - skip-changelog + categories: + - title: New experiences + labels: + - new-experience + - title: Improvements and fixes + labels: + - enhancement + - bug + - title: Documentation + labels: + - documentation + - title: Dependency updates + labels: + - dependencies + - title: Other changes + labels: + - "*" diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml new file mode 100644 index 0000000..ea53604 --- /dev/null +++ b/.github/workflows/validate.yml @@ -0,0 +1,28 @@ +name: Validate catalog + +on: + pull_request: + push: + branches: + - main + +permissions: + contents: read + +concurrency: + group: validate-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + catalog: + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 20 + - name: Validate experience metadata and links + run: node scripts/validate-catalog.mjs + - name: Verify the experience launcher catalog + run: node scripts/play.mjs --list diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..3ade921 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,44 @@ +# Contributor Covenant Code of Conduct + +## Our pledge + +We pledge to make participation in this project a harassment-free experience +for everyone, regardless of age, body size, visible or invisible disability, +ethnicity, sex characteristics, gender identity and expression, level of +experience, education, socio-economic status, nationality, personal +appearance, race, religion, or sexual identity and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our standards + +Examples of behavior that contributes to a positive environment include: + +- Demonstrating empathy and kindness toward other people. +- Respecting differing opinions, viewpoints, and experiences. +- Giving and gracefully accepting constructive feedback. +- Accepting responsibility and apologizing to those affected by our mistakes. +- Focusing on what is best for the overall community. + +Examples of unacceptable behavior include harassment, trolling, insulting or +derogatory comments, publishing others' private information, and other conduct +which could reasonably be considered inappropriate in a professional setting. + +## Enforcement + +Project maintainers are responsible for clarifying and enforcing these +standards. They may remove, edit, or reject comments, commits, code, issues, and +other contributions that do not align with this Code of Conduct. + +Report abusive, harassing, or otherwise unacceptable behavior privately through +the contact options at [mint.gg](https://mint.gg). All reports will be reviewed +and investigated promptly and fairly. Maintainers will respect the privacy and +security of reporters. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.1. + +[homepage]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..ccb957a --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,69 @@ +# Contributing to Mint Playground + +Thanks for helping make these open-source 3D experiences easier to learn from, +run, and reuse. + +## Good contributions + +The most useful contributions are focused and easy to review: + +- Fix a reproducible bug in one experience. +- Improve keyboard, touch, screen-reader, or reduced-motion support. +- Improve runtime performance or asset-loading behavior with measurements. +- Add tests for an existing system. +- Clarify setup instructions or explain a reusable Three.js pattern. +- Report a broken demo, source link, or catalog entry. + +New experiences are generally published through Mint's release pipeline. Before +building one for this repository, open an experience request so the maintainers +can confirm its scope and publication path. + +## Before you start + +Search existing issues and pull requests first. For a substantial change, open +an issue describing the user problem and proposed approach before investing in +implementation. Issues labeled [`good first issue`](https://github.com/mintdotgg/mint-playground/labels/good%20first%20issue) +are intentionally small and should include enough context to begin. + +Only contribute code and media you have permission to publish. Do not commit +credentials, production data, runtime assets downloaded from Mint CDN, or +third-party media without a compatible license and attribution. The curated +social cards under `.github/assets/experiences` are the intentional exception. + +## Local setup + +This repository uses Node.js 20 or newer and the pnpm version pinned in +`package.json`. + +```bash +corepack enable +pnpm install --filter ./experiences/vanguard-protocol +pnpm play vanguard-protocol +``` + +Replace `vanguard-protocol` with any slug printed by `pnpm play --list`. + +## Validate your change + +Always validate the catalog and build the experience you changed: + +```bash +pnpm validate:catalog +pnpm --filter ./experiences/vanguard-protocol build +``` + +Run experience-specific tests when its `package.json` defines a `test` script. +Use `pnpm build` only when you need to verify the entire workspace. + +## Pull requests + +- Keep a pull request focused on one experience or one repository-wide concern. +- Explain the user-visible result and how you verified it. +- Include before-and-after captures for visual changes. +- Preserve each experience's existing framework and style unless the issue + explicitly calls for a migration. +- Update `experience.json` and the root catalog when metadata or URLs change. +- Do not reformat unrelated files. + +By contributing, you agree that your contribution will be licensed under the +repository's [MIT License](LICENSE). diff --git a/README.md b/README.md index 6df242e..6bcc439 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,92 @@ -# Mint Playground +

+ + Mint Playground — 39 open-source Three.js experiences + +

-Open-source Three.js Experiences from [Mint Playground](https://play.mint.gg/). +

Mint Playground

-Every app here was made with [Mint MCP](https://mcp.mint.gg/) as the 3D asset -pipeline and -[Mint Three.js Skills](https://github.com/mintdotgg/mint-threejs-skills) as the coding workflow. +

+ 39 production-grade 3D web experiences, with live demos and source.
+ Explore reusable patterns for browser games, product configurators, data visualization,
+ character animation, physics, audio, and Gaussian splats. +

-## Experiences +

+ Play the demos + · + Run one locally + · + Browse by category + · + Contribute +

+ +

+ GitHub stars + Catalog validation + MIT License +

+ +Every app is built with [Mint MCP](https://mcp.mint.gg/) as the 3D asset +pipeline and [Mint Three.js Skills](https://github.com/mintdotgg/mint-threejs-skills) +as the coding workflow. The source is organized as a pnpm workspace, with each +experience isolated in `experiences/` and linked to its deployed version. + +## Start here + + + + + + + + +
+ Vanguard Protocol animated character roster + Character systems
+ Vanguard Protocol — animation, selection, cameras, and reactive staging. +
+ Breakline arcade snowboarding game + Game architecture
+ Breakline — physics, input, camera rigs, tricks, HUD, and audio. +
+ Room Ritual furniture configurator + 3D configurators
+ Room Ritual — placement, materials, lighting, and persistent state. +
+ Impossible Places Gaussian-splat world + Gaussian splats
+ Impossible Places — streamed worlds and cinematic exploration. +
+ +## Browse by category + +| Category | Good places to begin | +| --- | --- | +| **Browser games** | [Breakline](experiences/breakline), [Mossbound](experiences/mossbound), [Reef Rivals](experiences/reef-rivals), [Genesis Grove Putt-Putt](experiences/mint-putt), [Flappy Bird 3D](experiences/flappy-bird-3d) | +| **Product and commerce** | [Common Form](experiences/common-form), [Room Ritual](experiences/room-ritual), [Sole Archive](experiences/sole-archive), [Seatline NYC](experiences/seatline-nyc) | +| **Data and education** | [Compound Visualization](experiences/compound-visualization), [Periodic Table 3D](experiences/periodic-table), [Financial City](experiences/financial-city), [SF Tennis Atlas](experiences/sf-tennis-atlas) | +| **Creative and editorial** | [Neon Relic](experiences/neon-relic), [CDX-2089 Music Player](experiences/cdx-2089-music-player), [Side One](experiences/side-one), [The Complete Shelf](experiences/complete-shelf) | +| **Worlds and simulation** | [Impossible Places](experiences/impossible-places), [Project Forge-5](experiences/project-forge-5), [Quadrotor Sandbox](experiences/quadrotor-sandbox), [Boulder Cove](experiences/boulder-cove) | + +## Patterns you can reuse + +| Pattern | Reference implementation | +| --- | --- | +| Character animation and selection | [`vanguard-protocol/src/showcase.ts`](experiences/vanguard-protocol/src/showcase.ts) | +| Third-person physics and camera systems | [`breakline/src/systems`](experiences/breakline/src/systems) | +| Configurator state and spatial placement | [`room-ritual/src`](experiences/room-ritual/src) | +| Audio-reactive Three.js visuals | [`cdx-2089-music-player/src/audio`](experiences/cdx-2089-music-player/src/audio) | +| Interactive scientific visualization | [`compound-visualization/src`](experiences/compound-visualization/src) | +| Product viewer and persistent cart | [`sole-archive/components/sole-archive`](experiences/sole-archive/components/sole-archive) | + +## All experiences @@ -22,7 +97,7 @@ pipeline and @@ -33,7 +108,7 @@ pipeline and @@ -44,7 +119,7 @@ pipeline and @@ -55,7 +130,7 @@ pipeline and @@ -66,7 +141,7 @@ pipeline and @@ -77,7 +152,7 @@ pipeline and @@ -88,7 +163,7 @@ pipeline and @@ -99,7 +174,7 @@ pipeline and @@ -110,7 +185,7 @@ pipeline and @@ -121,7 +196,7 @@ pipeline and @@ -132,7 +207,7 @@ pipeline and @@ -143,7 +218,7 @@ pipeline and @@ -154,7 +229,7 @@ pipeline and @@ -165,7 +240,7 @@ pipeline and @@ -176,7 +251,7 @@ pipeline and @@ -187,7 +262,7 @@ pipeline and @@ -198,7 +273,7 @@ pipeline and @@ -209,7 +284,7 @@ pipeline and @@ -220,7 +295,7 @@ pipeline and @@ -231,7 +306,7 @@ pipeline and @@ -242,7 +317,7 @@ pipeline and @@ -253,7 +328,7 @@ pipeline and @@ -264,7 +339,7 @@ pipeline and @@ -275,7 +350,7 @@ pipeline and @@ -286,7 +361,7 @@ pipeline and @@ -297,7 +372,7 @@ pipeline and @@ -308,7 +383,7 @@ pipeline and @@ -319,7 +394,7 @@ pipeline and @@ -330,7 +405,7 @@ pipeline and @@ -341,7 +416,7 @@ pipeline and @@ -352,7 +427,7 @@ pipeline and @@ -363,7 +438,7 @@ pipeline and @@ -374,7 +449,7 @@ pipeline and @@ -385,7 +460,7 @@ pipeline and @@ -396,7 +471,7 @@ pipeline and @@ -407,7 +482,7 @@ pipeline and @@ -418,7 +493,7 @@ pipeline and @@ -429,7 +504,7 @@ pipeline and @@ -440,16 +515,46 @@ pipeline and
- Nyx-7 displayed in the Vanguard Protocol combat roster + Nyx-7 displayed in the Vanguard Protocol combat roster

Vanguard Protocol

Code · Live demo

- Asterion interceptor displayed in the Helios Form orbital showroom + Asterion interceptor displayed in the Helios Form orbital showroom

Helios Form

Code · Live demo

- Aether humanoid displayed in the Neon Relic editorial gallery + Aether humanoid displayed in the Neon Relic editorial gallery

Neon Relic

Code · Live demo

- The Observatory issue of the Impossible Places travel magazine + The Observatory issue of the Impossible Places travel magazine

Impossible Places

Code · Live demo

- Mint Hoops fieldhouse with a basketball aimed at a lime-trimmed hoop + Mint Hoops fieldhouse with a basketball aimed at a lime-trimmed hoop

Mint Hoops

Code · Live demo

- A rune sword facing corrupted grove creatures among mossy ruins + A rune sword facing corrupted grove creatures among mossy ruins

Mossbound

Code · Live demo

- Jalen Quill basketball card displayed in the Dynasty Index collector vault + Jalen Quill basketball card displayed in the Dynasty Index collector vault

Dynasty Index

Code · Live demo

- SF Tennis Atlas showing official public tennis facilities across a stylized 3D map of San Francisco + SF Tennis Atlas showing official public tennis facilities across a stylized 3D map of San Francisco

SF Tennis Atlas

Code · Live demo

- Two tube-riding heroes face a three-pirate raft crew in the tropical Reef Rivals arena. + Two tube-riding heroes face a three-pirate raft crew in the tropical Reef Rivals arena.

Reef Rivals: Treasure Tide

Code · Live demo

- The PRISM skin of the CDX-2089 futuristic music player with its illuminated disc and controls. + The PRISM skin of the CDX-2089 futuristic music player with its illuminated disc and controls.

CDX-2089 Music Player

Code · Live demo

- Spain celebrates a 2-1 championship victory in a packed open-top stadium. + Spain celebrates a 2-1 championship victory in a packed open-top stadium.

Final Whistle: Spain vs Argentina

Code · Live demo

- Aerial view of Half Dome Opening, a lime-green putting lane through a rocky Yosemite-inspired landscape + Aerial view of Half Dome Opening, a lime-green putting lane through a rocky Yosemite-inspired landscape

Genesis Grove Putt-Putt

Code · Live demo

- A cave kid explores a pastel prehistoric village with stone huts, a bone bridge, trees, tools, and a life-sim HUD. + A cave kid explores a pastel prehistoric village with stone huts, a bone bridge, trees, tools, and a life-sim HUD.

Boulder Cove

Code · Live demo

- A glowing Sun and dark Mercury frame the Monday mission planner against a deep-space star field. + A glowing Sun and dark Mercury frame the Monday mission planner against a deep-space star field.

Orbit Week

Code · Live demo

- Jimothy’s Backyard Dash menu showing three racers at the start of a three-lane backyard course. + Jimothy’s Backyard Dash menu showing three racers at the start of a three-lane backyard course.

Jimothy’s Backyard Dash

Code · Live demo

- Common Form showroom with the Everyday Tote and five everyday objects staged beneath warm sculptural lighting. + Common Form showroom with the Everyday Tote and five everyday objects staged beneath warm sculptural lighting.

Common Form

Code · Live demo

- Room Ritual apartment configurator with a furniture catalog, measured 3D room plan, and product inspector. + Room Ritual apartment configurator with a furniture catalog, measured 3D room plan, and product inspector.

Room Ritual

Code · Live demo

- Sole Archive showing the Sublevel Zero sneaker in a dark acid-green configurator with product controls. + Sole Archive showing the Sublevel Zero sneaker in a dark acid-green configurator with product controls.

Sole Archive

Code · Live demo

- Seatline NYC showing a selected seat beside the 3D auditorium sightline and booking controls. + Seatline NYC showing a selected seat beside the 3D auditorium sightline and booking controls.

Seatline NYC

Code · Live demo

- Water Tribe and Fire Nation sculptures face each other across an ornate icy chessboard. + Water Tribe and Fire Nation sculptures face each other across an ornate icy chessboard.

Elemental Chess

Code · Live demo

- A dark memory observatory with warm connected stars, orbital trails, and the heading Where, when, and who we remember. + A dark memory observatory with warm connected stars, orbital trails, and the heading Where, when, and who we remember.

Memory Constellation

Code · Live demo

- A stylized rider bounces on a pogo stick over yellow and coral cars on a colorful city street. + A stylized rider bounces on a pogo stick over yellow and coral cars on a colorful city street.

Pogo Man

Code · Live demo

- Editorial robot storefront featuring the orange-and-white Sunday Memo robot surrounded by technical callouts and a carousel of robot models. + Editorial robot storefront featuring the orange-and-white Sunday Memo robot surrounded by technical callouts and a carousel of robot models.

Future Form: Robot Store

Code · Live demo

- A snowboarder carves through a bright alpine course as the HUD tracks closing polar bear and Yeti pursuers. + A snowboarder carves through a bright alpine course as the HUD tracks closing polar bear and Yeti pursuers.

Breakline

Code · Live demo

- A warm storybook miniature farm with a barn, farmhouse, fenced fields, hay bales, and a water trough. + A warm storybook miniature farm with a barn, farmhouse, fenced fields, hay bales, and a water trough.

Four Fields

Code · Live demo

- A daytime miniature financial city with active streets, civic buildings, parks, and dense Metropolitan Ledger architecture. + A daytime miniature financial city with active streets, civic buildings, parks, and dense Metropolitan Ledger architecture.

Financial City

Code · Live demo

- A warm editorial 3D bookshelf with colorful procedural hardcovers arranged above a walnut shelf. + A warm editorial 3D bookshelf with colorful procedural hardcovers arranged above a walnut shelf.

The Complete Shelf

Code · Live demo

- Two colorful fighters battle on a floating three-platform arena above waterfalls and distant sky islands. + Two colorful fighters battle on a floating three-platform arena above waterfalls and distant sky islands.

Kirby Smash

Code · Live demo

- A ball-and-stick caffeine molecule surrounded by composition, measurement, and structural-library controls. + A ball-and-stick caffeine molecule surrounded by composition, measurement, and structural-library controls.

Compound Visualization

Code · Live demo

- A worn containment machine stands in an abandoned laboratory beneath a classified experiment HUD. + A worn containment machine stands in an abandoned laboratory beneath a classified experiment HUD.

The Forgotten Experiment

Code · Live demo

- A glossy wooden periodic table with 118 color-coded raised element tiles and a matching category board. + A glossy wooden periodic table with 118 color-coded raised element tiles and a matching category board.

Periodic Table 3D

Code · Live demo

- A black vinyl record with a red center label emerging from a minimal cream sleeve beside the Side One wordmark. + A black vinyl record with a red center label emerging from a minimal cream sleeve beside the Side One wordmark.

Side One

Code · Live demo

- Polished ivory and black chess pieces emerging from pale fog above a rocky board in an ink-wash mountain valley. + Polished ivory and black chess pieces emerging from pale fog above a rocky board in an ink-wash mountain valley.

Dead Reckoning

Code · Live demo

- AXIOM H1 humanoid robot standing in the Project Forge-5 platform roster interface. + AXIOM H1 humanoid robot standing in the Project Forge-5 platform roster interface.

Project Forge-5

Code · Live demo

- A yellow 3D bird facing a green pipe course over a bright blue ocean beneath the Flappy Bird 3D title. + A yellow 3D bird facing a green pipe course over a bright blue ocean beneath the Flappy Bird 3D title.

Flappy Bird 3D

Code · Live demo

- A large sleeping Snorlax resting in a sunny low-poly meadow beneath a Poke Snorlax prompt. + A large sleeping Snorlax resting in a sunny low-poly meadow beneath a Poke Snorlax prompt.

Sleeping Snorlax

Code · Live demo

- Fieldline’s modeled Levi’s Stadium bowl with the field, red seating, and selected-seat analysis panels. + Fieldline’s modeled Levi’s Stadium bowl with the field, red seating, and selected-seat analysis panels.

Fieldline Santa Clara

Code · Live demo

- A shuttle launch stack climbing above a modern city with glowing engine plumes and live flight telemetry. + A shuttle launch stack climbing above a modern city with glowing engine plumes and live flight telemetry.

Quadrotor Sandbox

Code · Live demo

- The heyclicky landing page surrounded by floating 3D character, tech, and sticker props. + The heyclicky landing page surrounded by floating 3D character, tech, and sticker props.

heyclicky

Code · Live demo

-## Run locally +## Quick start + +Requirements: Node.js 20 or newer and pnpm 10.6.2. Corepack can install the +pinned pnpm version for you. + +```bash +corepack enable +pnpm install --filter ./experiences/vanguard-protocol +pnpm play vanguard-protocol +``` + +Run `pnpm play` without a slug to choose an experience interactively, or use +`pnpm play --list` to print every available slug. Runtime 3D assets are loaded +from Mint CDN, so the experiences require a network connection. -Install the workspace and start any Experience by its directory name: +To verify the repository catalog without installing dependencies: ```bash -pnpm install -pnpm --dir experiences/vanguard-protocol dev +pnpm validate:catalog ``` -Build every Experience with `pnpm build`. +Build all experiences with `pnpm build`, or build one with: + +```bash +pnpm --filter ./experiences/vanguard-protocol build +``` + +## Contributing + +Bug fixes, accessibility improvements, performance work, tests, and clearer +documentation are welcome. Start with the [contribution guide](CONTRIBUTING.md) +and look for [`good first issue`](https://github.com/mintdotgg/mint-playground/labels/good%20first%20issue) +or [`help wanted`](https://github.com/mintdotgg/mint-playground/labels/help%20wanted) +issues. New experience ideas belong in the experience request form so the +maintainers can align them with the publishing pipeline before code is written. + +If this collection saves you time or gives you an idea, star the repository to +follow future Playground drops. Maintainers can use the +[GitHub visibility playbook](docs/maintainer-playbook.md) for repository settings, +release structure, publishing checks, and weekly measurement. ## License diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..7969ab8 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,18 @@ +# Security policy + +## Reporting a vulnerability + +Please do not open a public issue for a suspected vulnerability. + +Use GitHub's private vulnerability reporting for this repository when it is +available. Otherwise, contact the Mint team privately through +[mint.gg](https://mint.gg) and include: + +- The affected experience or repository path. +- Steps to reproduce the issue. +- The potential impact. +- Any suggested mitigation. + +We will acknowledge the report, investigate it, and coordinate disclosure with +the reporter. This policy covers code in this repository; vulnerabilities in a +third-party dependency should also be reported to that dependency's maintainer. diff --git a/docs/maintainer-playbook.md b/docs/maintainer-playbook.md new file mode 100644 index 0000000..a81299d --- /dev/null +++ b/docs/maintainer-playbook.md @@ -0,0 +1,67 @@ +# GitHub visibility playbook + +This checklist keeps Mint Playground discoverable without turning the README or +release feed into marketing noise. + +## Repository settings + +These settings live in GitHub and cannot be applied by a pull request. + +**Description** + +> 39 open-source Three.js and React Three Fiber apps, games, configurators, visualizations, and Gaussian-splat worlds—with live demos and source code. + +**Website** + +`https://play.mint.gg` + +**Topics** + +`threejs`, `webgl`, `react-three-fiber`, `typescript`, `3d`, `creative-coding`, +`browser-games`, `game-development`, `interactive-3d`, `gaussian-splatting`, +`model-context-protocol`, `3d-visualization` + +Upload [`.github/assets/social-preview.jpg`](../.github/assets/social-preview.jpg) +as the repository social preview. GitHub Settings → General → Social preview is +the current location of that control. + +Enable Discussions only when a maintainer can respond consistently. Start with +Announcements, Q&A, Ideas, and Show and tell. + +## Publishing an experience + +1. Confirm the experience has an `experience.json`, package metadata, README, + live demo, source link, and a local social card at + `.github/assets/experiences/.webp`. +2. Confirm all names, models, images, audio, and reference material can be + published. Rename or remove material with unclear rights before promotion. +3. Run `pnpm validate:catalog` and the experience's build and tests. +4. Add it to the category and full catalog sections in the root README, and use + the local social card from both the root and experience READMEs. +5. Use the `new-experience` label so generated release notes classify it. + +## Playground drops + +Publish a GitHub release after a meaningful group of additions rather than for +every commit. A good release includes: + +- One strong visual and a one-sentence theme. +- Direct links to each live demo and source directory. +- The reusable Three.js patterns demonstrated by the new work. +- Credit for external contributors. +- A short prompt to watch releases for future drops. + +## Weekly measurement + +GitHub Insights → Traffic retains a rolling 14-day window. Record these metrics +weekly so results can be compared across equivalent periods: + +- Unique visitors and total views. +- Unique cloners and total clones. +- Referring sites and popular repository pages. +- Net-new stars, watchers, forks, and external contributors. +- Issues and discussions that received a maintainer response. + +Use visitor growth and useful participation as the primary signals. Stars are a +helpful secondary signal, not a substitute for people successfully running and +learning from the projects. diff --git a/experiences/boulder-cove/README.md b/experiences/boulder-cove/README.md index f152328..c8d21b3 100644 --- a/experiences/boulder-cove/README.md +++ b/experiences/boulder-cove/README.md @@ -1,7 +1,7 @@ # Boulder Cove - A cave kid explores a pastel prehistoric village with stone huts, a bone bridge, trees, tools, and a life-sim HUD. + A cave kid explores a pastel prehistoric village with stone huts, a bone bridge, trees, tools, and a life-sim HUD. A cozy prehistoric island life game where you gather, fish, catch bugs, plant trees, and help dinosaur neighbors earn your own boulder hut. diff --git a/experiences/breakline/README.md b/experiences/breakline/README.md index 1ce28a8..43ab9a3 100644 --- a/experiences/breakline/README.md +++ b/experiences/breakline/README.md @@ -1,7 +1,7 @@ # Breakline - A snowboarder carves through a bright alpine course as the HUD tracks closing polar bear and Yeti pursuers. + A snowboarder carves through a bright alpine course as the HUD tracks closing polar bear and Yeti pursuers. Carve a 1.8 km mountain, chain tricks and grinds, and stay ahead of a Yeti and polar bear in a third-person arcade snowboarding chase. diff --git a/experiences/cdx-2089-music-player/README.md b/experiences/cdx-2089-music-player/README.md index 1ce8826..5a32e65 100644 --- a/experiences/cdx-2089-music-player/README.md +++ b/experiences/cdx-2089-music-player/README.md @@ -1,7 +1,7 @@ # CDX-2089 Music Player - The PRISM skin of the CDX-2089 futuristic music player with its illuminated disc and controls. + The PRISM skin of the CDX-2089 futuristic music player with its illuminated disc and controls. A skin-adaptive 3D music player with five futuristic disc decks, audio-reactive visuals, and an unfolding dance floor. diff --git a/experiences/clicky/README.md b/experiences/clicky/README.md index 6d1e1e8..50ccb16 100644 --- a/experiences/clicky/README.md +++ b/experiences/clicky/README.md @@ -1,7 +1,7 @@ # heyclicky - The heyclicky landing page surrounded by floating 3D character, tech, and sticker props. + The heyclicky landing page surrounded by floating 3D character, tech, and sticker props. Explore a playful desktop AI companion through draggable media windows, switchable 2D and 3D stickers, easter eggs, features, social proof, pricing, and FAQs. diff --git a/experiences/common-form/README.md b/experiences/common-form/README.md index bfb5a32..221bc5b 100644 --- a/experiences/common-form/README.md +++ b/experiences/common-form/README.md @@ -1,7 +1,7 @@ # Common Form - Common Form showroom with the Everyday Tote and five everyday objects staged beneath warm sculptural lighting. + Common Form showroom with the Everyday Tote and five everyday objects staged beneath warm sculptural lighting. Explore six considered everyday objects in a warm interactive showroom, inspect them in 3D, and build a persistent demo cart. diff --git a/experiences/complete-shelf/README.md b/experiences/complete-shelf/README.md index ee8b7c6..332d8c6 100644 --- a/experiences/complete-shelf/README.md +++ b/experiences/complete-shelf/README.md @@ -1,7 +1,7 @@ # The Complete Shelf - A warm editorial 3D bookshelf with colorful procedural hardcovers arranged above a walnut shelf. + A warm editorial 3D bookshelf with colorful procedural hardcovers arranged above a walnut shelf. Browse nineteen procedural hardcovers on a continuous 3D shelf, then pull any volume forward to orbit, zoom, and inspect its editorial details. diff --git a/experiences/compound-visualization/README.md b/experiences/compound-visualization/README.md index e9b7a9b..603d161 100644 --- a/experiences/compound-visualization/README.md +++ b/experiences/compound-visualization/README.md @@ -1,7 +1,7 @@ # Compound Visualization - A ball-and-stick caffeine molecule surrounded by composition, measurement, and structural-library controls. + A ball-and-stick caffeine molecule surrounded by composition, measurement, and structural-library controls. Explore more than 40 molecules and crystals, switch rendering styles, inspect atoms and bonds, measure geometry, and search PubChem. diff --git a/experiences/dead-reckoning/README.md b/experiences/dead-reckoning/README.md index 718006d..f1ce6ad 100644 --- a/experiences/dead-reckoning/README.md +++ b/experiences/dead-reckoning/README.md @@ -1,7 +1,7 @@ # Dead Reckoning - Polished ivory and black chess pieces emerging from pale fog above a rocky board in an ink-wash mountain valley. + Polished ivory and black chess pieces emerging from pale fog above a rocky board in an ink-wash mountain valley. Play a complete 3D chess match where fog reveals only squares your pieces attack while a greedy AI moves unseen. diff --git a/experiences/dynasty-index/README.md b/experiences/dynasty-index/README.md index 916037b..aafd56e 100644 --- a/experiences/dynasty-index/README.md +++ b/experiences/dynasty-index/README.md @@ -1,7 +1,7 @@ # Dynasty Index - Jalen Quill basketball card displayed in the Dynasty Index collector vault + Jalen Quill basketball card displayed in the Dynasty Index collector vault An immersive collector vault for selecting and inspecting six fictional premium sports trading cards. diff --git a/experiences/elemental-chess/README.md b/experiences/elemental-chess/README.md index 4afdee1..ca3e30e 100644 --- a/experiences/elemental-chess/README.md +++ b/experiences/elemental-chess/README.md @@ -1,7 +1,7 @@ # Elemental Chess - Water Tribe and Fire Nation sculptures face each other across an ornate icy chessboard. + Water Tribe and Fire Nation sculptures face each other across an ornate icy chessboard. Choose Water, Earth, Fire, or Air, face a rival, and play a complete cinematic 3D chess match in a Mint-authored elemental world. diff --git a/experiences/fieldline-santa-clara/README.md b/experiences/fieldline-santa-clara/README.md index eb82cbd..d1c11be 100644 --- a/experiences/fieldline-santa-clara/README.md +++ b/experiences/fieldline-santa-clara/README.md @@ -1,7 +1,7 @@ # Fieldline Santa Clara - Fieldline’s modeled Levi’s Stadium bowl with the field, red seating, and selected-seat analysis panels. + Fieldline’s modeled Levi’s Stadium bowl with the field, red seating, and selected-seat analysis panels. Explore every section at Levi’s Stadium, enter modeled seated views, compare sightlines, and inspect obstruction, shade, weather, and event context before opening official tickets. diff --git a/experiences/final-whistle/README.md b/experiences/final-whistle/README.md index 073f3a8..a4274bd 100644 --- a/experiences/final-whistle/README.md +++ b/experiences/final-whistle/README.md @@ -1,7 +1,7 @@ # Final Whistle: Spain vs Argentina - Spain celebrates a 2-1 championship victory in a packed open-top stadium. + Spain celebrates a 2-1 championship victory in a packed open-top stadium. Lead Spain through a 150-second 3D arcade football final against Argentina with passing, tackles, charged shots, and golden-goal drama. diff --git a/experiences/financial-city/README.md b/experiences/financial-city/README.md index 447cd3d..fff2327 100644 --- a/experiences/financial-city/README.md +++ b/experiences/financial-city/README.md @@ -1,7 +1,7 @@ # Financial City - A daytime miniature financial city with active streets, civic buildings, parks, and dense Metropolitan Ledger architecture. + A daytime miniature financial city with active streets, civic buildings, parks, and dense Metropolitan Ledger architecture. Shape a private monthly budget and watch traffic, civic services, construction pressure, and forty city blocks respond in a living miniature metropolis. diff --git a/experiences/flappy-bird-3d/README.md b/experiences/flappy-bird-3d/README.md index 05c4629..39d605c 100644 --- a/experiences/flappy-bird-3d/README.md +++ b/experiences/flappy-bird-3d/README.md @@ -1,7 +1,7 @@ # Flappy Bird 3D - A yellow 3D bird facing a green pipe course over a bright blue ocean beneath the Flappy Bird 3D title. + A yellow 3D bird facing a green pipe course over a bright blue ocean beneath the Flappy Bird 3D title. Fly a selectable 3D bird down an endless ocean causeway, flapping through randomized pipe gaps for a high score. diff --git a/experiences/forgotten-experiment/README.md b/experiences/forgotten-experiment/README.md index e7acbc2..44035ef 100644 --- a/experiences/forgotten-experiment/README.md +++ b/experiences/forgotten-experiment/README.md @@ -1,7 +1,7 @@ # The Forgotten Experiment - A worn containment machine stands in an abandoned laboratory beneath a classified experiment HUD. + A worn containment machine stands in an abandoned laboratory beneath a classified experiment HUD. Search two abandoned laboratory rooms, collect and equip tools, solve layered evidence puzzles, and unlock Dr. Elias Vale's experiment. diff --git a/experiences/four-fields/README.md b/experiences/four-fields/README.md index 1fd6b50..990a510 100644 --- a/experiences/four-fields/README.md +++ b/experiences/four-fields/README.md @@ -1,7 +1,7 @@ # Four Fields - A warm storybook miniature farm with a barn, farmhouse, fenced fields, hay bales, and a water trough. + A warm storybook miniature farm with a barn, farmhouse, fenced fields, hay bales, and a water trough. Harvest corn, potatoes, tomatoes, and strawberries across four timed plots in a warm storybook miniature farm. diff --git a/experiences/helios-form/README.md b/experiences/helios-form/README.md index 3d64a5f..55788d3 100644 --- a/experiences/helios-form/README.md +++ b/experiences/helios-form/README.md @@ -1,7 +1,7 @@ # Helios Form - Asterion interceptor displayed in the Helios Form orbital showroom + Asterion interceptor displayed in the Helios Form orbital showroom A luminous orbital-vehicle showroom for inspecting six futuristic craft and their onboard systems. diff --git a/experiences/impossible-places/README.md b/experiences/impossible-places/README.md index 0a28aad..9f35f66 100644 --- a/experiences/impossible-places/README.md +++ b/experiences/impossible-places/README.md @@ -1,7 +1,7 @@ # Impossible Places - The Observatory issue of the Impossible Places travel magazine + The Observatory issue of the Impossible Places travel magazine A cinematic travel magazine spanning five explorable Mint-generated Gaussian-splat worlds. diff --git a/experiences/jimothys-backyard-dash/README.md b/experiences/jimothys-backyard-dash/README.md index 32158f3..ad22193 100644 --- a/experiences/jimothys-backyard-dash/README.md +++ b/experiences/jimothys-backyard-dash/README.md @@ -1,7 +1,7 @@ # Jimothy’s Backyard Dash - Jimothy’s Backyard Dash menu showing three racers at the start of a three-lane backyard course. + Jimothy’s Backyard Dash menu showing three racers at the start of a three-lane backyard course. Guide Jimothy through a fast three-lane backyard race, dodging obstacles, collecting Moon Tokens, and battling two rivals across five streamed worlds. diff --git a/experiences/kirby-smash/README.md b/experiences/kirby-smash/README.md index 48df5e3..fbc844a 100644 --- a/experiences/kirby-smash/README.md +++ b/experiences/kirby-smash/README.md @@ -1,7 +1,7 @@ # Kirby Smash - Two colorful fighters battle on a floating three-platform arena above waterfalls and distant sky islands. + Two colorful fighters battle on a floating three-platform arena above waterfalls and distant sky islands. Battle across three floating arenas in a 2.5D platform fighter with four selectable combatants, local two-player or CPU matches, percent damage, stocks, and Smash-style knockback. diff --git a/experiences/memory-constellation/README.md b/experiences/memory-constellation/README.md index da569f8..f47be0e 100644 --- a/experiences/memory-constellation/README.md +++ b/experiences/memory-constellation/README.md @@ -1,7 +1,7 @@ # Memory Constellation - A dark memory observatory with warm connected stars, orbital trails, and the heading Where, when, and who we remember. + A dark memory observatory with warm connected stars, orbital trails, and the heading Where, when, and who we remember. Capture private memories locally, explore their connections as a 3D constellation, and revisit every moment in an accessible timeline. diff --git a/experiences/mint-hoops/README.md b/experiences/mint-hoops/README.md index eacfffd..acd2ff2 100644 --- a/experiences/mint-hoops/README.md +++ b/experiences/mint-hoops/README.md @@ -1,7 +1,7 @@ # Mint Hoops - Mint Hoops fieldhouse with a basketball aimed at a lime-trimmed hoop + Mint Hoops fieldhouse with a basketball aimed at a lime-trimmed hoop A 60-second arcade basketball score attack with drag-to-shoot controls, combo multipliers, and a three-point finale. diff --git a/experiences/mint-putt/README.md b/experiences/mint-putt/README.md index c3b798e..6d36b0e 100644 --- a/experiences/mint-putt/README.md +++ b/experiences/mint-putt/README.md @@ -1,7 +1,7 @@ # Genesis Grove Putt-Putt - Aerial view of Half Dome Opening, a lime-green putting lane through a rocky Yosemite-inspired landscape + Aerial view of Half Dome Opening, a lime-green putting lane through a rocky Yosemite-inspired landscape An 18-hole putting round through California-inspired Gaussian splat worlds, with drag-to-aim shots, touch controls, and a running scorecard. diff --git a/experiences/mossbound/README.md b/experiences/mossbound/README.md index 2d462bf..049b0f9 100644 --- a/experiences/mossbound/README.md +++ b/experiences/mossbound/README.md @@ -1,7 +1,7 @@ # Mossbound - A rune sword facing corrupted grove creatures among mossy ruins + A rune sword facing corrupted grove creatures among mossy ruins A first-person fantasy melee run through five escalating waves of corrupted grove creatures, ending in a showdown with the Thornheart. diff --git a/experiences/neon-relic/README.md b/experiences/neon-relic/README.md index 4b8be56..3e4aa50 100644 --- a/experiences/neon-relic/README.md +++ b/experiences/neon-relic/README.md @@ -1,7 +1,7 @@ # Neon Relic - Aether humanoid displayed in the Neon Relic editorial gallery + Aether humanoid displayed in the Neon Relic editorial gallery An interactive poster gallery where four sci-fi relics reshape the typography, lighting, materials, and sound. diff --git a/experiences/orbit-week/README.md b/experiences/orbit-week/README.md index 9fe1561..58d7f40 100644 --- a/experiences/orbit-week/README.md +++ b/experiences/orbit-week/README.md @@ -1,7 +1,7 @@ # Orbit Week - A glowing Sun and dark Mercury frame the Monday mission planner against a deep-space star field. + A glowing Sun and dark Mercury frame the Monday mission planner against a deep-space star field. A cinematic 3D weekly planner where each day is a planet and every task becomes a mission you can add, complete, and carry through the week. diff --git a/experiences/periodic-table/README.md b/experiences/periodic-table/README.md index b9f3fb7..c38d9f2 100644 --- a/experiences/periodic-table/README.md +++ b/experiences/periodic-table/README.md @@ -1,7 +1,7 @@ # Periodic Table 3D - A glossy wooden periodic table with 118 color-coded raised element tiles and a matching category board. + A glossy wooden periodic table with 118 color-coded raised element tiles and a matching category board. Browse all 118 elements on a tactile 3D table, open any tile, and orbit an animated atom surrounded by detailed scientific properties. diff --git a/experiences/pogo-man/README.md b/experiences/pogo-man/README.md index 99267b5..9a05351 100644 --- a/experiences/pogo-man/README.md +++ b/experiences/pogo-man/README.md @@ -1,7 +1,7 @@ # Pogo Man - A stylized rider bounces on a pogo stick over yellow and coral cars on a colorful city street. + A stylized rider bounces on a pogo stick over yellow and coral cars on a colorful city street. Charge double jumps to clear city traffic, build combos, and chase a high score in a one-button 3D arcade run. diff --git a/experiences/project-forge-5/README.md b/experiences/project-forge-5/README.md index d1f2b6e..cc6974f 100644 --- a/experiences/project-forge-5/README.md +++ b/experiences/project-forge-5/README.md @@ -1,7 +1,7 @@ # Project Forge-5 - AXIOM H1 humanoid robot standing in the Project Forge-5 platform roster interface. + AXIOM H1 humanoid robot standing in the Project Forge-5 platform roster interface. Command five specialized robots through indoor qualification missions and an outdoor physics sandbox. diff --git a/experiences/quadrotor-sandbox/README.md b/experiences/quadrotor-sandbox/README.md index 23d1e92..187e743 100644 --- a/experiences/quadrotor-sandbox/README.md +++ b/experiences/quadrotor-sandbox/README.md @@ -1,7 +1,7 @@ # Quadrotor Sandbox - A shuttle launch stack climbing above a modern city with glowing engine plumes and live flight telemetry. + A shuttle launch stack climbing above a modern city with glowing engine plumes and live flight telemetry. Pilot seven distinct aircraft through a collider-rich city with real flight models, wind, sensing, tuning, landings, and launch staging. diff --git a/experiences/reef-rivals/README.md b/experiences/reef-rivals/README.md index 605f2c4..bc25fe9 100644 --- a/experiences/reef-rivals/README.md +++ b/experiences/reef-rivals/README.md @@ -1,7 +1,7 @@ # Reef Rivals: Treasure Tide - Two tube-riding heroes face a three-pirate raft crew in the tropical Reef Rivals arena. + Two tube-riding heroes face a three-pirate raft crew in the tropical Reef Rivals arena. A three-round tropical projectile battler where tube-riding heroes aim, charge, and outshoot an escalating pirate raft crew. diff --git a/experiences/robot-store/README.md b/experiences/robot-store/README.md index 59b2c1d..4ed7a36 100644 --- a/experiences/robot-store/README.md +++ b/experiences/robot-store/README.md @@ -1,7 +1,7 @@ # Future Form: Robot Store - Editorial robot storefront featuring the orange-and-white Sunday Memo robot surrounded by technical callouts and a carousel of robot models. + Editorial robot storefront featuring the orange-and-white Sunday Memo robot surrounded by technical callouts and a carousel of robot models. Explore an editorial 3D archive of 15 humanoid robots, orbit each digital twin, and compare their capabilities. diff --git a/experiences/room-ritual/README.md b/experiences/room-ritual/README.md index d936118..fb55d29 100644 --- a/experiences/room-ritual/README.md +++ b/experiences/room-ritual/README.md @@ -1,7 +1,7 @@ # Room Ritual - Room Ritual apartment configurator with a furniture catalog, measured 3D room plan, and product inspector. + Room Ritual apartment configurator with a furniture catalog, measured 3D room plan, and product inspector. Arrange six statement furniture pieces in a soft-brutalist loft, customize finishes and lighting, and save, compare, or cart room plans. diff --git a/experiences/seatline-nyc/README.md b/experiences/seatline-nyc/README.md index 1cc1357..780ff68 100644 --- a/experiences/seatline-nyc/README.md +++ b/experiences/seatline-nyc/README.md @@ -1,7 +1,7 @@ # Seatline NYC - Seatline NYC showing a selected seat beside the 3D auditorium sightline and booking controls. + Seatline NYC showing a selected seat beside the 3D auditorium sightline and booking controls. Choose a New York theater, showtime, and seat, then preview the 3D screen angle and sightline before opening the venue’s live listing. diff --git a/experiences/sf-tennis-atlas/README.md b/experiences/sf-tennis-atlas/README.md index 673b0bb..1d42e05 100644 --- a/experiences/sf-tennis-atlas/README.md +++ b/experiences/sf-tennis-atlas/README.md @@ -1,7 +1,7 @@ # SF Tennis Atlas - SF Tennis Atlas showing official public tennis facilities across a stylized 3D map of San Francisco + SF Tennis Atlas showing official public tennis facilities across a stylized 3D map of San Francisco A source-aware 3D atlas for exploring all 64 official San Francisco public tennis facilities. diff --git a/experiences/side-one/README.md b/experiences/side-one/README.md index af853c5..b59552f 100644 --- a/experiences/side-one/README.md +++ b/experiences/side-one/README.md @@ -1,7 +1,7 @@ # Side One - A black vinyl record with a red center label emerging from a minimal cream sleeve beside the Side One wordmark. + A black vinyl record with a red center label emerging from a minimal cream sleeve beside the Side One wordmark. Browse seven landmark releases across nine pressings, inspect every sleeve and track list, and cue a record on a configurable 3D turntable. diff --git a/experiences/sleeping-snorlax/README.md b/experiences/sleeping-snorlax/README.md index efcde60..384506f 100644 --- a/experiences/sleeping-snorlax/README.md +++ b/experiences/sleeping-snorlax/README.md @@ -1,7 +1,7 @@ # Sleeping Snorlax - A large sleeping Snorlax resting in a sunny low-poly meadow beneath a Poke Snorlax prompt. + A large sleeping Snorlax resting in a sunny low-poly meadow beneath a Poke Snorlax prompt. Poke a peacefully sleeping Snorlax to trigger escalating procedural reactions, combos, wake-ups, and permanent growth. diff --git a/experiences/sole-archive/README.md b/experiences/sole-archive/README.md index 69269f1..0224fbb 100644 --- a/experiences/sole-archive/README.md +++ b/experiences/sole-archive/README.md @@ -1,7 +1,7 @@ # Sole Archive - Sole Archive showing the Sublevel Zero sneaker in a dark acid-green configurator with product controls. + Sole Archive showing the Sublevel Zero sneaker in a dark acid-green configurator with product controls. Inspect and configure six fictional sneakers in an underground boutique with exploded materials, comparison, wishlist, sizing, and a persistent demo cart. diff --git a/experiences/vanguard-protocol/README.md b/experiences/vanguard-protocol/README.md index 92927f8..ed051b6 100644 --- a/experiences/vanguard-protocol/README.md +++ b/experiences/vanguard-protocol/README.md @@ -1,7 +1,7 @@ # Vanguard Protocol - Nyx-7 displayed in the Vanguard Protocol combat roster + Nyx-7 displayed in the Vanguard Protocol combat roster A cinematic five-character combat roster with animated fighters and reactive tactical staging. diff --git a/package.json b/package.json index 7793574..5b308e8 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,8 @@ "license": "MIT", "packageManager": "pnpm@10.6.2", "scripts": { - "build": "pnpm -r --if-present build" + "build": "pnpm -r --if-present build", + "play": "node scripts/play.mjs", + "validate:catalog": "node scripts/validate-catalog.mjs" } } diff --git a/scripts/play.mjs b/scripts/play.mjs new file mode 100644 index 0000000..8189d7b --- /dev/null +++ b/scripts/play.mjs @@ -0,0 +1,99 @@ +import { readdir, readFile } from "node:fs/promises"; +import { spawn } from "node:child_process"; +import { createInterface } from "node:readline/promises"; +import { stdin, stdout } from "node:process"; + +const experiencesDirectory = new URL("../experiences/", import.meta.url); + +async function getExperiences() { + const entries = await readdir(experiencesDirectory, { withFileTypes: true }); + const experiences = []; + + for (const entry of entries) { + if (!entry.isDirectory()) continue; + + try { + const manifest = JSON.parse( + await readFile(new URL(`${entry.name}/experience.json`, experiencesDirectory)), + ); + const packageJson = JSON.parse( + await readFile(new URL(`${entry.name}/package.json`, experiencesDirectory)), + ); + + if (packageJson.scripts?.dev) { + experiences.push({ + order: manifest.order ?? Number.MAX_SAFE_INTEGER, + slug: entry.name, + title: manifest.title ?? entry.name, + }); + } + } catch { + // Catalog validation reports incomplete experience directories in detail. + } + } + + return experiences.sort((left, right) => + left.order - right.order || left.title.localeCompare(right.title), + ); +} + +function printExperiences(experiences) { + const width = Math.max(...experiences.map(({ slug }) => slug.length)); + for (const { slug, title } of experiences) { + console.log(`${slug.padEnd(width)} ${title}`); + } +} + +async function chooseExperience(experiences) { + console.log("Choose an experience:\n"); + experiences.forEach(({ title }, index) => { + console.log(`${String(index + 1).padStart(2)}. ${title}`); + }); + + const prompt = createInterface({ input: stdin, output: stdout }); + const answer = await prompt.question("\nNumber or slug: "); + prompt.close(); + + const number = Number.parseInt(answer, 10); + if (String(number) === answer.trim() && number >= 1 && number <= experiences.length) { + return experiences[number - 1]; + } + + return experiences.find(({ slug }) => slug === answer.trim()); +} + +const experiences = await getExperiences(); +const argument = process.argv[2]; + +if (argument === "--list") { + printExperiences(experiences); + process.exit(0); +} + +const selected = argument + ? experiences.find(({ slug }) => slug === argument) + : await chooseExperience(experiences); + +if (!selected) { + console.error(`Unknown experience: ${argument ?? "selection"}\n`); + console.error("Run `pnpm play --list` to see every available slug."); + process.exit(1); +} + +console.log(`\nStarting ${selected.title}…\n`); + +const child = spawn( + "pnpm", + ["--dir", `experiences/${selected.slug}`, "dev"], + { cwd: new URL("..", import.meta.url), stdio: "inherit" }, +); + +child.on("error", (error) => { + console.error(`Unable to start pnpm: ${error.message}`); + process.exit(1); +}); + +child.on("exit", (code, signal) => { + if (signal) process.kill(process.pid, signal); + process.exit(code ?? 1); +}); diff --git a/scripts/validate-catalog.mjs b/scripts/validate-catalog.mjs new file mode 100644 index 0000000..450b411 --- /dev/null +++ b/scripts/validate-catalog.mjs @@ -0,0 +1,103 @@ +import { readdir, readFile } from "node:fs/promises"; + +const repositoryRoot = new URL("../", import.meta.url); +const experiencesDirectory = new URL("experiences/", repositoryRoot); +const readme = await readFile(new URL("README.md", repositoryRoot), "utf8"); +const entries = await readdir(experiencesDirectory, { withFileTypes: true }); +const directories = entries.filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort(); +const errors = []; +const records = []; + +async function readJson(path, label) { + try { + return JSON.parse(await readFile(new URL(path, repositoryRoot), "utf8")); + } catch (error) { + errors.push(`${label}: ${error.message}`); + return null; + } +} + +for (const directory of directories) { + const prefix = `experiences/${directory}`; + const cardPath = `.github/assets/experiences/${directory}.webp`; + const manifest = await readJson(`${prefix}/experience.json`, `${directory}/experience.json`); + const packageJson = await readJson(`${prefix}/package.json`, `${directory}/package.json`); + let experienceReadme = ""; + + try { + experienceReadme = await readFile(new URL(`${prefix}/README.md`, repositoryRoot), "utf8"); + } catch { + errors.push(`${directory}: missing README.md`); + } + + try { + const card = await readFile(new URL(cardPath, repositoryRoot)); + const isWebp = + card.subarray(0, 4).toString("ascii") === "RIFF" && + card.subarray(8, 12).toString("ascii") === "WEBP"; + if (!isWebp) errors.push(`${directory}: social card is not a valid WebP file`); + } catch { + errors.push(`${directory}: missing local social card`); + } + + if (!manifest || !packageJson) continue; + + if (manifest.slug !== directory) { + errors.push(`${directory}: manifest slug is ${JSON.stringify(manifest.slug)}`); + } + if (!Number.isFinite(manifest.order)) { + errors.push(`${directory}: order must be a number`); + } + if (!manifest.title?.trim()) { + errors.push(`${directory}: title is required`); + } + if (!manifest.description?.trim()) { + errors.push(`${directory}: description is required`); + } + if (!Array.isArray(manifest.tags) || manifest.tags.length === 0) { + errors.push(`${directory}: at least one tag is required`); + } + if (!packageJson.scripts?.dev) { + errors.push(`${directory}: package.json must define a dev script`); + } + if (!packageJson.scripts?.build) { + errors.push(`${directory}: package.json must define a build script`); + } + if (!readme.includes(`experiences/${directory}`)) { + errors.push(`${directory}: root README is missing a source link`); + } + if (!readme.includes(`https://play.mint.gg/${directory}`)) { + errors.push(`${directory}: root README is missing a live demo link`); + } + if (!readme.includes(cardPath)) { + errors.push(`${directory}: root README is missing its local social card`); + } + if (!experienceReadme.includes(`../../${cardPath}`)) { + errors.push(`${directory}: experience README is missing its local social card`); + } + + records.push({ directory, order: manifest.order, title: manifest.title }); +} + +for (const field of ["title"]) { + const grouped = new Map(); + for (const record of records) { + const value = record[field]; + grouped.set(value, [...(grouped.get(value) ?? []), record]); + } + for (const [value, matches] of grouped.entries()) { + if (matches.length > 1) { + errors.push( + `duplicate ${field} ${JSON.stringify(value)}: ${matches.map(({ directory }) => directory).join(", ")}`, + ); + } + } +} + +if (errors.length > 0) { + console.error(`Catalog validation failed with ${errors.length} error${errors.length === 1 ? "" : "s"}:\n`); + errors.forEach((error) => console.error(`- ${error}`)); + process.exit(1); +} + +console.log(`Catalog valid: ${records.length} experiences.`);