尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證製作者的介紹僅有上面的一句話。 更多詳情請閱讀儲存庫 README。 儲存庫 README ↗
正在載入完整 README。
檢視完整 README ↗Low-poly ski trick game. Plain HTML + Three.js, no build step.
python3 -m http.server 8123
The alpine landscape uses broad snow-covered foothills, layered distant ridges, and deterministic
groves with irregular clearings. landscape.js keeps scenery placement separate from the course RNG,
so the daily race layout stays consistent. Run npm test for terrain continuity and scatter checks.
main redeploys automatically.index.html loads Vercel's /_vercel/insights/script.js (the static-site version of @vercel/analytics).
Turn it on once in Vercel → your project → Analytics → Enable. It only loads on the deployed site, not on localhost or CrazyGames.
supabase/schema.sql → Run. Run it again whenever the file changes.
Then run supabase/points-and-chat.sql for the score-based races, period leaderboards, and global chat.
Then run supabase/surf.sql for the Surf leaderboard.
Then run supabase/coins.sql for the Coins leaderboard (most coins right now, read from the cloud saves; not in the CrazyGames version).
Then run supabase/names.sql: any name allowed (shared names, accents, emoji), renames any time, and scores
from players the database hasn't seen yet are accepted. Finally run supabase/score-cap.sql to upgrade the
score limit and offline submission rules on an existing database. Run supabase/vault.sql for the Vault: Event Horizon, a 10,000,000-coin outfit that only 5 players can ever own (the shop lists the owners). These files are safe to run again. The migration is additive: existing lifetime scores and legacy timed races are kept.config.js. The browser can only call the
validated score and chat functions — it has no direct table access.Endless opens first and has All time and Daily rankings on the main site. CrazyGames also retains Weekly, which resets Monday at 00:00 UTC. Daily resets at 00:00 UTC. Each period uses the best run earned during that period, even when it is below a player's lifetime best. Period tracking starts with this update; old lifetime scores stay on All time. Daily Race awards riding/trick points plus 500 per checkpoint. Highest points wins; faster elapsed time breaks equal scores. Scored race records are stored separately from the old timed records. Completed Endless and Daily Race runs are queued locally before their result screens open and submitted immediately once a name is set. Failed uploads retry automatically with bounded requests, including after reconnecting or restoring a cloud save. The queue retains the best pending run per board and day until the server acknowledges it; older queued runs keep their earned date. Accepted uploads refresh the visible rankings immediately.
Global chat shares the latest 50 messages, however old (run supabase/chat-history.sql once to drop the old 7-day cutoff). Players claim a name before sending,
messages are limited to 240 characters and one per five seconds, and chat identity tokens travel with cloud saves.
Players can mute others on their device and report messages. Reports are stored in public.chat_reports for
owner review; hide a message by setting chat_messages.hidden = true, or mute a sender with
chat_sessions.muted = true in the Supabase dashboard. These tables are not browser-accessible.
Every change to a player's progress (coins, items, missions, name) is backed up to Supabase automatically
(saves table, via save_progress / load_progress in supabase/schema.sql). Players don't have to do anything.
To move to a new domain (e.g. peakflip.io):
canonicalHost: 'peakflip.io' in config.js and push.
Visitors on the old address get their save uploaded and are sent to the new domain with it, so nobody loses progress.The game has three kinds of ad slots, all going through ads.js:
| Slot | When | Where it comes from |
|---|---|---|
| Rewarded | Player clicks a ▶ button: ad-exclusive items (Jetpack, Laser Eyes, Propeller Cap…), +75 coins | CrazyGames SDK or Google H5 Games Ads |
| Between runs | Before "Ride again" (only when ADS_ENABLED = true in game.js) | same |
| Side banners | Desktop screens ≥1280px, your own site only | Google AdSense display ads |
On localhost rewarded ads are faked with a 3-second "test ad" so you can try the flow.
Run npm run build:crazygames and upload peak-flip-crazygames.zip. Their SDK serves the rewarded and midgame ads, and the
build removes every other ad network. See CRAZYGAMES.md for what the build changes, how to submit, and the launch stages.
AdSense is set up with publisher id ca-pub-5606045487621821:
<head> of index.html (Google uses it to verify the site),ads.txt in the project root authorizes Google to sell the ad space,config.js has adsenseClient, h5GamesAds: true and adsTestMode: false, and ADS_ENABLED = true in game.js.Still to do in the AdSense dashboard: add the site (www.peakflip.io) under Sites and request review, apply for H5 Games Ads, and turn on a consent message under Privacy & messaging → GDPR (required for players in Europe). Ads appear only once Google approves; until then players just see no ad and rewarded buttons say none is available.
Alternatives if AdSense says no: GameMonetize, GameDistribution, or AdinPlay (made for web games, easier approval), or simply publish on CrazyGames/Poki and let them handle ads.
npm run zip:crazygames → upload peak-flip-crazygames.zip.
Before uploading, set ADS_ENABLED = true in game.js (it's off for testing). CrazyGames doesn't allow third-party ads, and online leaderboards there should use their SDK instead.
Ski and Surf sit side by side on the home screen (← → to choose, Space to ride). Surf lives in ride.js (physics,
camera, flow) and surf.js (the beach, waves, creatures and rider); game.js hands it the renderer, the synth and the
mountain's own HUD, pause screen and results card, so both modes look and play the same.
You ride downhill on a beach break: sand on the left, open ocean on the right, waves rolling up the slope at you.
Riding into a wave launches you; ← → steers, and in the air ↑ ↓ flips, ← → spins and holding Space grabs. Rocks, sharks,
buoys and paddling surfers wipe you out; jellyfish, turtles, the sand and deep water slow you. Now and then a whale
surfaces in the lane (ride up its back for a bonus) or breaches out at sea.
Whirlpool: every 1,000 to 1,400 m a whirlpool opens in the lane. Ride into it and it pulls you under and out into a
glowing lagoon worth double points for 650 m, like the special worlds on the mountain.
Coins go into the normal wallet. Scores go to their own board, surf, with All time and Daily tabs (run
supabase/surf.sql once to add it; test with supabase/tests/surf.sql). Until then surf scores wait in the local queue.
roblox/ is a Roblox port of Endless mode (same physics, tricks and course), with DataStore saves and
global leaderboards. See roblox/README.md to open it in Roblox Studio and publish it.
game.js — rendering, physics, controls, world generation, sky themes, 3D closet, race modelandscape.js — alpine heightfield and world-space tree grovesmeta.js — save data, cosmetics catalog (incl. themed sets & Fits), daily item shop rotation & prices, daily gift, missionsride.js — the Surf engine: physics, camera, combos, the whirlpool bonus zonesurf.js — Peak Surf: the beach, waves, sea creatures, whirlpool and surferui.js — menus, item shop (daily rotation + 3D try-on), locker (owned items), profile, leaderboards, resultscloud.js — automatic cloud saves, domain hand-off · net.js — Supabase RPC helperchat.js — shared chat, reconnect/polling, mute and report controlsicons.js — the hand-made SVG icon setads.js — rewarded / between-run ads (CrazyGames, Google H5, dev fake)supabase/schema.sql — leaderboard table + functions