Underground 2 Revived
Chrome과 Firefox에서 Need for Speed Underground 2를 WebGPU로 두고 팬 프로젝트입니다
itch.io 모든 게임잼·예정·진행 상황과 팀·솔로 개발자 찾기
Game jam search and team finder: every game jam on itch.io, live and upcoming, plus the game dev teams and solo devs looking for someone like you.
게임TypeScript · CSSGitHub @BrackeysCommunity온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기GitHub mirror for https://git.brackeys.dev/web/brackeys.community
저장소 README에서 가져옴
README 전체를 불러오는 중입니다.
README 전문 보기 ↗jams.team is the Brackeys Discord community's jam hub. This repo is a single TanStack Start application that powers:
This README is the repo-level source of truth for local setup and day-to-day development. The old starter README is intentionally replaced because it no longer matched the codebase.
/ home / jam landing page/command-center command and macro docs/profile sign-in gate and profile entry/profile/:userId public profile view and owner edit flow/collab collab browse flow/collab/new collab post creation/collab/:postId collab post detail/oauth/github/callback GitHub account-link callback/oauth/itchio/callback itch.io link callback/api/auth/* Better Auth endpoints/api/rpc/* ORPC endpointssrc/
components/
collab/
home/
layout/
profile/
ui/
db/
lib/
orpc/
routes/
drizzle/
.storybook/
Important files:
src/routes/__root.tsx: shell, background, command palette, layoutsrc/db/schema.ts: app schemasrc/lib/auth.ts: Better Auth provider configsrc/orpc/router/*: typed server proceduresdrizzle.config.ts: Drizzle configOptional but relevant depending on what you are working on:
bun install
Copy-Item .env.example .env.local
.env.local.Minimum required for most local work:
DATABASE_URLBETTER_AUTH_URLBETTER_AUTH_SECRETDISCORD_CLIENT_IDDISCORD_CLIENT_SECRETDISCORD_GUILD_IDOnly the user should ever run bun run db:generate, bun run db:migrate, or
bun run db:push. Agents should update schema and migration files, but the
user remains the only operator for those commands.
For an existing migration flow:
bun run db:migrate
For fast local iteration against an empty local database:
bun run db:push
bun run dev
The app runs on http://localhost:3000.
README only documents variables that are actually referenced in the repo today.
DATABASE_URL: Postgres connection stringBETTER_AUTH_URL: local app URL, usually http://localhost:3000BETTER_AUTH_SECRET: Better Auth secretDISCORD_CLIENT_ID: Discord OAuth client IDDISCORD_CLIENT_SECRET: Discord OAuth client secretDISCORD_GUILD_ID: guild used for member role/profile enrichmentGITHUB_CLIENT_ID: GitHub account linkingGITHUB_CLIENT_SECRET: GitHub account linkingGITLAB_CLIENT_ID: gitlab.com account linkingGITLAB_BOOTH_CLIENT_ID: git.booth.dev linkingGITLAB_BRACKEYS_CLIENT_ID: git.brackeys.dev linking
(register each application non-confidential — a public PKCE client needs no
secret; GITLAB_*_CLIENT_SECRET exists for instances that require one)DISCORD_BOT_TOKEN: guild membership and ban probes, and the collab feed mirror belowDISCORD_COLLAB_CHANNEL_ID: the channel an author's SHARE TO DISCORD posts their collab
post into. Unset means the feature does not exist — the button never renders. The bot
needs View Channel / Send Messages / Embed Links there and nothing more; it only ever
edits or deletes the messages it wrote itself.DISCORD_DEVLOGS_CHANNEL_ID: the #devlogs channel a forum devlog is mirrored into when its
author ticks "Share to #devlogs". Unset means no checkbox and no button. Same permissions
as the collab channel.VITE_ITCHIO_CLIENT_ID: itch.io linking flowVITE_STRAPI_URL: Strapi-backed uploads / demo contentMINIO_ENDPOINT: MinIO server URL, for example https://your-minio-host.up.railway.appMINIO_PUBLIC_BASE_URL: public base URL used to render stored objectsMINIO_BUCKET: bucket name for uploaded profile project imagesMINIO_ACCESS_KEY: MinIO access keyMINIO_SECRET_KEY: MinIO secret keyVITE_APP_TITLE: client title overrideVITE_DEPLOY_ENV: production | staging | development — overrides the staging marker
(badge beside the logo, top-edge stripe, [STAGING] tab-title prefix). Derived from
VITE_SITE_ORIGIN when unset, which is right for every deploy we have; set it only where
the origin can't tell the truth.DISCORD_COLLAB_SHARE_COOLDOWN_SECONDS: how long a member waits between announcing posts
in the collab feed channel (default 21600, six hours). Updating a message they already
posted is limited separately, at ten an hour.SERVER_URL: server-side absolute URL overrideVITE_POSTHOG_KEY: PostHog project API key — analytics, feature flags, error tracking (all off when unset)VITE_POSTHOG_HOST: PostHog ingestion host, for example https://eu.i.posthog.com. Staging and
prod point it at PostHog's managed reverse proxy on a jams.team subdomain. Inlined into the
browser bundle at build time — changing it needs a rebuild, not just a restart.POSTHOG_PERSONAL_API_KEY: build-time, server-only — enables source-map upload so error
stacks are un-minified. Never give this a VITE_ prefix: it is a write credential and the
prefix would inline it into the browser bundle. Absent means maps are simply not uploaded.POSTHOG_PROJECT_ID: build-time, pairs with the personal API key — the numeric project id
(269454 prod, 269446 staging). Both must be set or the build skips maps entirely.POSTHOG_API_HOST: build-time, optional — the PostHog API/UI host for source-map
upload (https://eu.posthog.com). Distinct from the ingestion host below; do not
set both to the same value.POSTHOG_KEY / POSTHOG_HOST: read by the services/* workers for error reporting; they
fall back to the VITE_-prefixed names so one Railway shared variable can cover everythingIf you have access to the Railway project, you can pull environment variables directly from Railway instead of maintaining .env.local manually.
https://docs.railway.com/cli#installing-the-cli
npm i -g @railway/cli
# or MacOS
brew install railway
# or Linux/WSL
bash <(curl -fsSL cli.new)
railway login
railway link
The interactive prompt will ask you to select the workspace, project, environment, and service.
railway environment # list available environments
railway environment dev # switch to dev
Use the railway:* scripts to run any command with Railway-injected environment variables:
vp run railway:dev # dev server with Railway env vars
vp run railway:build # production build
vp run railway:db:migrate # run migrations against Railway database
vp run railway:db:studio # open Drizzle Studio against Railway database
You can also pass -s <service> and -e <environment> flags inline:
railway run -e staging -- vp dev --port 3000
The standard bun run dev / vp run dev workflow with .env.local continues to work for developers who do not need Railway CLI.
bun run dev
bun run build
bun run preview
bun run start
bun run db:generate
bun run db:migrate
bun run db:push
bun run db:pull
bun run db:studio
bun run lint
bun run format
bun run check
bun run test
bun run storybook
bun run build-storybook
bun run db:generate, bun run db:migrate, and bun run db:push are
user-only commands. Do not have agents execute them.
__APP_VERSION__ (footer, PostHog app_version, source-map release) is a Vite
define assembled at build time in vite.config.ts:
<package.json version>+<UTC build stamp>.<short sha> # staging, previews, local
0.1.0+20260906.0441.8ab5478
<tag without v>+<short sha> # tagged prod release
0.1.0+8ab5478
The stamp orders builds and the sha pins one. On a tagged release the tag does
the ordering, so the stamp is dropped: the release pipeline sets APP_RELEASE
as a Railway service variable and vite.config.ts takes that branch. The
standalone services have no Vite build and read APP_RELEASE at runtime
(src/lib/service-telemetry.ts), falling back to RAILWAY_GIT_COMMIT_SHA.
For the sha: Railway exposes RAILWAY_GIT_COMMIT_SHA on repo-connected
deploys, the release pipeline sets APP_COMMIT_SHA, GitLab exposes
CI_COMMIT_SHA, and a local build falls back to git rev-parse.
Nothing bumps package.json automatically; you change its version by hand
when the release line moves:
npm version minor --no-git-tag-version # → 0.2.0
Landing that on main releases to prod — the bump is the trigger, not a
bookkeeping step. See "Releasing" below before you merge one.
A production release is a git tag. Pushing vX.Y.Z to GitLab runs one
pipeline that gates the commit, migrates the prod database, and deploys all
five application services — Web, itch-crawler, media-scan,
notifications-worker, discord-bot — from that one tree. Nothing in prod
moves because a branch moved; the Railway auto-deploy triggers on the prod
instances are off.
Staging is unchanged: it still tracks main through the GitHub mirror.
Ordinary work never touches a tag. Branch off main, open an MR, and get the
usual MR pipeline (lint, test, sonar, a Railway preview). Merging to
main deploys staging through the GitHub mirror, and applies staging
migrations if the MR touched drizzle/. Soak it there.
Because staging is where you decide, soak first, then bump — the bump MR is the release decision, not a step after it.
Open an MR that bumps package.json's version and nothing else:
npm version minor --no-git-tag-version # → 0.2.0
Merge it. That is the whole release. The auto-tag job on main sees the
version field change, pushes v0.2.0, and the tag runs the release pipeline.
Two things it deliberately will not do:
auto-tag diffs the version field
itself, not the file, so Renovate MRs pass through untouched.0.3.0-rc.1 and it lands on main
and deploys to staging with no tag and no prod deploy. Only X.Y.Z ships.Pushing a tag by hand does the same thing, and is the fallback if auto-tag is
ever wedged:
git tag -a v0.2.0 -m "v0.2.0" && git push origin v0.2.0
From the tag on: release-gate checks the tag matches package.json, that the
commit is reachable from main, and type-checks every services/* package —
the only place CI does, since root vp check does not cover them. Then
db-migrate-prod runs (always, not only when drizzle/ changed — that filter
is what let schema and code race), five parallel deploy-prod jobs
railway up each service and poll it to SUCCESS, smoke-prod asserts
/api/health reports the new version, and publish-release writes the GitLab
Release from git log.
auto-tag needs RELEASE_TOKEN: a project access token, Maintainer (the
v* protected-tag rule requires it), write_repository, masked and protected.
It expires. A previous incarnation of CI-side versioning died exactly that
way and went unnoticed for three months, so this job fails loudly on a missing
token and verifies the tag actually landed rather than trusting git push —
but a red auto-tag on main is the only thing between an expired token and a
release that silently never happens. Put its expiry in a calendar.
/api/health returns { ok, version }; the footer shows v0.1.0+<sha>;
PostHog app_version reads 0.1.0 for web and services alike; Railway shows
five deployments messaged v0.1.0 @ <sha>.
SUCCESS deployment (railway deployment list --service X --environment prod --json) and call deploymentRollback(id) over GraphQL (the CLI has no
rollback verb). Image and variables come back together, so APP_RELEASE
reverts with it. Only deployments with canRollback: true qualify.deploy-prod.
Same code path as a release, so it is the one to trust.Migrations do not roll back; drizzle has no down. A release whose migration is
not backwards-compatible with the previous code needs a forward fix (v0.1.1),
not a rollback. A deploy that fails mid-release leaves that service on its
previous deployment — the failure mode is "one service stale", not "prod down".
auto-tag — no tag, so no release happened at all; main and staging
are fine. Usually the token: expired, unmasked, or its user is not a
Maintainer so the v* rule refused the push (the job says which). Fix the
token and re-run the job, or push the tag by hand.release-gate — nothing has moved. Fix and re-tag: delete the tag
locally and remotely (git push origin :v0.1.0), then tag again.db-migrate-prod — nothing has deployed, and drizzle applies pending
migrations in one transaction, so prod's schema is untouched. Fix the
migration on main and cut the next patch tag.deploy-prod job — that service is still on its previous
deployment; the other four are on the new one. Retry the job from the
pipeline. If the build itself is broken, fix forward with v0.1.1 rather
than leaving the split in place.smoke-prod — all five deployed but the origin is not serving the new
version. Check /api/health by hand before assuming the job is wrong; if
prod really is bad, roll back Web first, since it is the only user-facing
one.src/routes/demo/* still contains scaffold/demo routes and should not be treated as product truth.The schema currently spans:
authuserhammercollabtodosProfile data still uses separate profile_projects and jam_participations tables. The unified typed-projects migration has not landed yet.
bun run check runs Biome across the repo.bun run test uses Vitest.src/routes/profile.$userId.tsx), so isolated validation is sometimes more useful than full repo typechecking.