Underground 2 Revived
Chrome과 Firefox에서 Need for Speed Underground 2를 WebGPU로 두고 팬 프로젝트입니다
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기Freeski game in the browser with real ski physics: sidecut carving, rigid-body spins and corks, no landing assist.
README 전체를 불러오는 중입니다.
README 전문 보기 ↗A freeski game in the browser built from Stomped's mountains, parks, gear and loading screen, riding on Cork7's simulation: rebuilt from how Cork7's current version behaves and checked against it frame by frame (tools/c7sim.mjs runs Cork7's own sim headless, tools/ourtrick2.mjs rides ours the same way; TRICK and HOLD pick the keys and how long they're held).
Play: https://reidwcoleman.github.io/fall-line/
Skier.groundC7): one speed along the line. acc = 9.81 sin(slope) x 1.7 - 0.13 - k v^2 - 0.38 |edge| - (17 braking), k 0.0028 (0.0024 tucked, x1.38 in deep snow), 0-43 m/s. The edge eases toward the stick at (11 + 11 x cross-over) x clamp(13/v, .45, 1) per second; the line turns at edge x (0.8 + min(v/85, .44)). Braking skids the skis sideways (lateral speed 0.1 x skid x v). W poles every 0.95 s, then tucks (held 1.25 s or past 18 m/s).Skier.stepAirC7, src/c7assist.js): 17.5 m/s^2, almost no drag. Spins and flips build toward 6.3 rad/s (6.8 held, 9.5 with a grab) at 10/s, reverse at 28/s and wind down at 6.5/s; a spin and a flip held together inside 0.25 s of takeoff make a cork, the up arrow a rodeo or a misty. Let go (turning under 2.8 rad/s) and the landing assist locks the nearest clean landing and eases the body to it, square to the landing's slope over the last 1.5 s (up to 4.8 rad/s); a flat spin is held level.Skier.landC7): crash only upside down, flat on your back with a hard or long air, or a 33 m/s hit; sideways or on the tails is SAVED IT and costs a few % of speed; a stomp onto a downslope adds 2.6 m/s; the spin you land with swings straight on the snow.src/course.js): Cork7-size, with the runs at 0.75x the map grades and each kicker's sweet spot on its sign.blender/rider.py, src/toyrider.js): built from scratch to Cork7's, measured off its locker turntable (shots/c7/locker*.png): a long straight shell to 0.40 of the height with a funnel collar and the hood on the back, dropped shoulders, slim sleeves to black cuffs and gloves, shorter legs (its own skeleton: the rig poses it from its limb lengths) in straight baggy pants, a big head with a long face. node tools/locker.mjs <out.png> renders it standing the way Cork7's locker shows its (front, side, back, side, three-quarter); node tools/posecheck.mjs <out.png> freezes it in Trick School's grab and flip poses.Built like the front page of a live-service indie game: tabs for Ride, Events, Leaderboard, Locker, Shop, Pass, Replays, Trick School and Updates over a painted background, with your rider as a sticker standing on a lift pass (type your name on it).
The game shares Stomped's Firebase project (alpenglow-ski-reid, config in src/cloud.js) under its own names (cloud.NS = 'fl-' on servers and boards, cloud saves in fl_users):
fl_users/{uid}): wallet, XP, items, kit, medals, lessons, quick tricks, trick book and best runs, written a moment after anything changes. The browser keeps a copy, so it plays offline too.boards/{board}/scores/{uid}, all time and -w<week>) with the run itself in replays/{board}_{uid}: 15 frames a second, positions as floats and the rest as 16-bit steps, gzipped (~100-200 KB).rooms/{server} and lobby): two or three public servers per park plus private room codes. The menu shows who's on each. Anyone on a Yard server can race everyone on it: the start time goes through the server, all riders count down together and the results come in live.firebase/ (firebase deploy --only firestore:rules,database). If Firebase can't be reached, multiplayer falls back to public MQTT relays and progress stays on the device.Pick SKIS or SNOWBOARD on the Ride tab. Snowboarders stand sideways on a twin-tip board (left foot forward) with a tighter 7.5 m sidecut, float better in powder, can't tuck as small, and ride switch after landing a half turn. Spins are called by side (FS 360, BS 540, Half Cab, Cab 720, Switch BS), rolls are wildcats and tamedogs, and the grabs are indy, melon, method, stalefish, nose and tail. About a third of the riders on the mountain are snowboarders.
Pick one on the illustrated map (Ride > the park card), by day or by night. Each is its own line down the mountain.
Every part of every run has its name and difficulty sprayed on the snow where it starts and on the trail signs at its edges; the HUD's corner shows its name as you ride in (Cork7 style, no difficulty dot; the conditions line under it fades after six seconds).
Every rider leaves tracks, lit like the snow round them: carved turns leave two sharp grooves with a lip of pushed-up snow (one wide one for a board), skids a scraped glossy smear with a berm thrown to the outside, powder a deep trench, landings a slapped dent and falls a crater and a trench down the hill. Your own line keeps a ring of its own so it stays behind you; old track fades as it's reused. The pistes already carry the lines of earlier riders (fewer under fresh snow). Spray is two kinds of snow: grains that fly on their own arcs, glint and land, and a fine mist that hangs and drifts down. (node tools/behind.mjs out.jpg [z] [wait] looks back up the hill at your tracks.)
The spruces carry their own share of the snowfall each, fuller crowns up close, darker far off (where the shade under the boughs wins over the snow on them), and a tree well in the snow round each trunk. On fair days cloud shadows drift across the mountain, and on cold clear ones diamond dust glitters in the air, brightest looking toward the sun. (node tools/treecam.mjs out.jpg [z] [tod] frames the nearest tree from a few distances; node tools/gputime.mjs [port] [z] [tod] times one view's render.)
Each sky has its own grade after tone mapping: shade takes the sky's colour and lit snow the sun's, with a soft film S-curve (clamped before SMAA, which turns anything outside 0..1 into bright fringes on dark edges). At Alpenglow Dusk the sun has already set on the runs: it only lights terrain above about 1150 m, full above 1750 m, so the peaks glow pink over blue-shaded slopes under a sky that deepens to blue overhead. (TODS=night,arctic node tools/tods.mjs <dir> [z] shoots the same spot under each sky.)
Carving, a skier stands like one: long outside leg, the inside one folded and leading, hips over the boots and the upper body angulated back toward level (the visual tilt eases off past about 40 degrees). The upper body has weight, lagging into each turn and rocking with the speed, and the arms follow it. The skis bend into their arc under load, slap on landings and chatter at speed on hard snow. Clothes are a freeride cut: a long, roomy shell over the hips, loose sleeves with wide cuffs, and baggy pants stacked over the boots, creased per pixel and rippling in the wind with speed. Carve tracks are clean edge cuts (a wall on the inside of the turn, a ramp to the outside, filtered by their size on screen); skid smears blend their width from segment to segment. Spray is drawn as velocity-stretched streaks (crystals) and ragged puffs (mist): a fan peeled off the ski tails in a carve, a curtain along the edges in a skid, a plume in powder. (node tools/carvecam.mjs out.jpg [z] [turnMs] [key] tucks, holds a turn, freezes and shoots the rider from VIEWS.)
Cork7 physics (the player in the run and the park; races and the computer riders keep the full model): one speed along the line, the slope at 1.7 g, 0.13 rolling, v^2 drag 0.0028 (0.0024 tucked, x1.38 in deep snow), 0.38 m/s^2 per unit of edge, a 17 m/s^2 brake, a 43 m/s cap; the edge rolls toward the stick at (11 + 11 x cross-over) x clamp(13/v, .45, 1) per second and turns the line at edge x (0.8 + min(v/85, .44)) rad/s; W poles every 0.95 s until it tucks (held 1.25 s or past 18 m/s). Air: 17.5 m/s^2, almost no drag; pop 3.6 + 2.6 x charge off the snow; kickers launch along the lip with 1.2 + 2.2 x charge. Spins and flips build toward 6.3 rad/s (6.8 held, 9.5 with a grab) at 10/s and wind down at 6.5/s; off-axis only when set inside 0.25 s of takeoff; nothing pulls the rotation in while you're holding it. Landings: only tipped past ~75 degrees (or a 33 m/s hit) crashes; sideways is SAVED IT (points down to half, a few % of speed); a stomp onto a downslope adds 2.6 m/s. Scoring: 1,500 x turns^2, +15% per inversion, x1.25 switch, 135/s air + 36/m height, grabs 840/s + 300 each (+25% of the spin for a held tail/japan), line +0.25 per feature, stomp +450 and 15%, repeats over the last three airs. The chase camera is Cork7's rig (4.3 m back, 1.3 up, 58 deg + 8 toward 38 m/s, tipped down the slope, rider kept in frame). J.pspeed is each kicker's sweet spot under these numbers (on its numbered marker boards). (node tools/hold.mjs <keys> <ms> [jump] holds keys through a kicker's air; tools/tuckrun.mjs logs a straight tuck's speed; tools/ridesnap.mjs rides a key plan and screenshots.)
Realism pass (ten parallel areas): the rider's shell and pants drape over the body (seams, zips, pockets, a knit neck gaiter); gear is modelled down to boot buckles, binding brakes, steel ski edges and a mirrored goggle lens that reflects the sky. On the snow he plants his poles at each edge change, keeps a quiet upper body and soaks up bumps; in the air spins and flips ease in and out with the shoulders leading, grabs reach the ski and tweak when held, landings absorb. Ground physics: the turn radius follows edge angle and sidecut, and the skis slip into a skid when the turn asks more grip than the snow has (ice least, groomed most); rollers unweight and compress. Snow: wind crust, sastrugi and ripples on exposed crests, sharp sun glints, powder trenches with crumbled walls, spray lit and self-shadowed by its own density grid, GPU falling snow in depth layers, spindrift off ridges. The forest mixes spruce, fir, larch, snags, snow ghosts and saplings with dithered LOD fades and wind sway; the sky adds aerial perspective, valley mist, a sun/moon disc, the earth's shadow at dusk and a sharper rider shadow; rocks are stratified granite/limestone with cliff bands, chalets are timber with snowy roofs and lit windows, and groomers park by the lifts. (node tools/ridecam.mjs films the rider at a fixed step; node tools/groundbench.mjs benches the ground physics; tools take PORT, gputime takes Q=&q=low.)
?park=forest&room=abc).Speed comes easily: in free riding and the parks you ride on fast wax (snow friction 0.032), a slippery tuck, and holding ↑ on the flats skates you up to about 35 km/h; carving never costs speed (only braking, ↓, does). The computer riders and races use the plain snow. Starts and run-outs are steeper than they were.
Weather: a new sky every time you drop in (restarting keeps it; Menu > Weather > Fixed turns it off). Bluebird Morning, Golden Hour, Alpenglow Dusk, Night Session (moonlit, floodlight towers), Powder Day, Spring Sun, Arctic Blue, Snow Showers, Whiteout and Night Snow. Each comes with its snow, which changes the physics and the look: Fresh corduroy, Packed powder, Fresh powder (slow, deep, floaty), Hardpack and ice (fast, little grip, glints) and Spring slush (grabby, wet). Storms bring wind that pushes you in the air.
Two schemes (Menu > Controls). Arrows is the default and needs only the arrows and the keypad:
| Arrows (default) | On the snow | In the air |
|---|---|---|
| ← → | carve | spin |
| ↑ | tuck | front flip |
| ↓ | brake | backflip |
| arrow taps | combos (below) | |
| Space / keypad 0 | hold and let go to pop with no trick | |
| Keypad . / G | hop round: ride backwards (switch), or forwards again |
Combos: in the air, quick taps of the arrows (each under a fifth of a second) throw a trick, sized to the air that's left; hold an arrow instead and you spin or flip by hand. A combo that a longer one starts with waits a beat for more taps.
| Combo | Trick | Combo | Trick | |
|---|---|---|---|---|
| ↓↓ | Mute grab (board: Indy) | ←← / →→ | 360 (one more tap for each half turn: 540, 720; 900 and 1080 are secret) | |
| ↑↑ | Japan (Melon) | ↓↓↓ / ↑↑↑ | Backflip / frontflip (↓↓↓↓ double back: secret) | |
| ←→ / →← | Safety (Method) / Tail | ←↓→ / →↓← | Cork 720 | |
| ↓← / ↑→ | Critical (Stalefish) / Nose | ←↑→ | Bio 540 (Misty) | |
| ↑↓ / ↓↑ | Shifty / Daffy (Boned) | ↓←↓ | Rodeo 540 | |
| ←→← | Sideflip (Wildcat) | ↑←→ | Flatspin 360 | |
| ←↓←↓ | Double Cork 1080 (secret) |
The number keys no longer do tricks. In the park, L picks the next line.
Classic keeps every move by hand:
| Keyboard | Gamepad | |
|---|---|---|
| Carve / spin in the air | A D | Left stick |
| Tuck / front flip in the air | W | RT / RB |
| Brake / backflip in the air | S | LT |
| Air roll: sideflip, flatspin with a spin | ← → | Right stick |
| Rodeo (with S) / misty (with W) | ↑ + spin + flip | B |
| Pop (hold, release) | Space | A |
| Grabs (skis: mute, tail, japan, safety, critical, nose · board: indy, tail, melon, method, stalefish, nose) | Shift / Q / E / F / X / Z | LB / X / Y / D-pad left, right, down |
| Shifty / daffy (board: boned), in the air on their own | ↑ / ↓ | Right stick up / down |
| Butter (nose, or tail with S); hold A/D to pivot 180, 360, 540 | B | LS |
| Nose / tail press on a rail | W / S | |
| Camera (chase, action, helmet, TV) | C | D-pad up |
| Restart (hold) | R | View |
| Replay | V | |
| Room list / chat (multiplayer) | Tab / T | |
| Pause / mute | Esc / M | Menu |
Riding backwards on skis the rider turns his shoulders and looks over one of them; land any half turn and you ride away switch too.
The letter keys work in both schemes. On a rail, A/D swap the slide a quarter turn and Space pops off. Touch controls appear on phones and tablets.
A spin or flip turns while you hold it and carries on with its momentum when you let go, slowing (about a sixth of a turn more from full speed). A combo starts on the tap that makes it (another tap upgrades it in the air: LL is a 360, a third L makes it a 540) and turns faster when it has to, up to a limit, to come round before touchdown. In the last half second a trick that's nearly round (the skis within about 85 degrees of straight, a flip within about 155 of upright) is pulled in to land; further off than that and you crash (a bit off is a sketchy landing, and a crooked one skids round to the line, throwing snow). The computer riders still get a landing assist. The Tricks tab is a trick book that ticks off each family the first time you land it; new tricks call out "NEW TRICK" and count on the results card.
Land a trick clean and it boosts you out of it, more for bigger tricks (stomped: a bit more).
Piste poles, race gates (breakaway), kicker marker poles and signs knock over when you ride into them and cost a little speed; they stand back up next run. Faster than about 30 km/h a pole or sign takes you down with it (gates don't). A tree trunk takes you down at anything over about 12 km/h into it; its branches (out to a couple of metres round it) catch you, drag you back and let you go, dropping their snow on you. The side nets stretch up to about a metre, catch you and push you back in (hit them at over ~45 km/h and you go down in them). The finish straight has solid boards. Trees, rocks, snow guns and lift towers are solid. A wipeout is a short tumble, a beat on the snow and back up within about two seconds, keeping about 40% of the speed you fell at.
It takes a lot: about 60 km/h into a tree, rock or tower, 80 into a pole or sign, or landing on your head from a big jump, and you don't get up. How bad it is depends on how much harder than that you hit. With Injuries: Realistic (the default; Settings) blood sprays off the impact and every time the body slams the snow, the helmet cracks off and the back of the skull is split open, one to three limbs come off at the elbow or knee and tumble away bleeding, the stumps pump blood in spurts with the heartbeat, a shin or forearm that stayed on is snapped with the bone out through the clothes, the clothes soak through, a red smear follows the body and a pool spreads where it stops, and blood runs down the screen; Off keeps all that out. Either way the run stops and the rescue helicopter comes in, lowers its orange stretcher, winches you up and flies you to the Shredline Mountain Clinic (stone and timber, a glass porch, an ambulance bay, a lit helipad with a windsock) beside the bottom of the lift. You walk out patched up, pick any part of the run, and ride a real chair on the lift line (it moves with the others) there for 15 seconds while the terrain at the other end is built, then drop in. node tools/rescue.mjs shots/rescue yard runs it start to finish with a shot of each stage.
The Shop opens on the week's spotlight set (your rider wears it, drag to turn him), then today's deals, outfit sets and every category. Tap anything to see your rider wearing it before you buy. Trails are new: coloured light your skis leave behind you (glow, fire, sparkle or rainbow). The Season Pass has two tracks: the free one, and the Gold Pass (950 flakes) with 25 gold exclusives and flakes in between; buying it unlocks everything up to your level at once.
Turn it sideways. The on-screen buttons are the arrow keys: ◀ ▶ carve (and spin in the air), ▲ tuck / front flip, ▼ brake / backflip, POP, GRAB and TURN (ride switch), so quick taps in the air make combos. Phones start on the Fast graphics setting.
There's an iPhone app in ios/ (xcodegen, bundle id com.reidcoleman.Shredline): it plays the live site, and the copy bundled in the app when offline. ios/sync-web.sh builds that copy, then cd ios && xcodegen generate and build/install as usual.
A soundtrack made as it plays (drums, bass, pads and an arpeggio over four chord progressions): calm in the menu and on the chairlift, the full groove while you ride, pads only after a bad crash. Settings > Music turns it off; M mutes everything.
src/maps.js: the parks (sections, curve, features, zones, tree rules). course.js builds the active one, picked by ?park= or the last one ridden. Picking another reloads the page, and the terrain worker gets the park through its name.src/course.js: one deterministic height function for the whole mountain (piste profile by section, valley walls, domain-warped ridges, moguls, kickers, every park feature down the run, bucketed by z), plus the named zones, race gates and a Catmull-Rom racing line.src/skier.js: ski physics shared by player and AI. The run and the park use an arcade flavour (lower drag, bigger pops, forgiving landings that snap straight, rails that carry your speed); the race keeps the full simulation: progressive edge roll with sidecut carving (R = Rsc / tan(edge)), flat skis drift, grip in g that turns into a speed-scrubbing skid past its limit, snow surfaces (groomed / deep powder / scraped ice from surfaceAt), altitude air drag with tuck and drafting, leg compression from g-load, ballistic airtime with tricks (the flip or roll axis is set when it starts, tilted off-axis when you're spinning: cork, bio, rodeo, misty, flatspin), course nets that bounce you back in, butters, and crashes that tumble and slide (yard sale in src/debris.js) before you get up where you stopped.src/atmos.js: GPU heightfield pass for mountain-cast sun shadows (soft penumbra) and horizon AO, plus an altitude fog with a sun lobe, patched into every material.src/ai.js: AI skiers drive the same physics through the same controls. Racers track the racing line (Stanley controller) with curvature-based speed checks, and everyone else follows pursuit lines with speed control, avoidance and park tricks.src/terrain.js: chunked LOD terrain + mid/far rings, snow shader (wind ripples, corduroy, rock on steep faces, sun glints).src/park.js (+ the park section of course.js): table jumps, rollers, halfpipe and rail ramps are part of the shared height function; a fine surface mesh draws them over the coarser terrain, which meshHeightAt sinks underneath. Grinds (Skier.stepGrind) follow the rail with gravity and friction (and in the race physics, a balance you steer to keep); the pipe turns the skis to follow the speed on the walls and sends lip airs straight up and back in.src/avatar.js: Rocketbox avatars driven from the skier's procedural pose: spine and head from its frames, arms and legs re-solved with the avatar's own bone lengths. The clothes are re-dyed and re-made in the shader: prints, a zip, chest pocket, hem and cuffs, quilting, cargo pockets and roomy pants that flare over the boots; hair is tucked inside the helmet or beanie and the feet inside the boots. The player is always one of the lads (Rider in the Locker).art/prompts.md.tools/fetch_assets.py downloads them, and tools/build_assets.py bakes the sky domes and game textures.npm install
npm run dev # http://127.0.0.1:5270
node tools/sim.mjs race # headless race: finish times, missed gates, crashes
node tools/parksim.mjs # park riders on each line: airs, grinds, crashes
node tools/parkjump.mjs # table jumps: approach speed -> landing spot
node tools/tour.mjs shots/tour free golden # screenshots around the mountain
node tools/trick.mjs shots/cork KeyD,KeyS Large # ride a table with real keys and film the trick
node tools/rail.mjs shots/rail "Long Tube" 2 # ride a rail, swap twice
node tools/ui2.mjs shots/ui2 # park picker, two browsers in one multiplayer room, replay
node tools/cloudtest.mjs bigair # guest run -> global board -> watch it off the server -> cloud save
node tools/srvrace.mjs # two browsers on one server race each other
node tools/eventtest.mjs sprint 1 yard # an event on autopilot to its results
node tools/quick.mjs LDR XL # pop off a park kicker and tap a combo in the air
node tools/injury.mjs shots/inj 25 # a severe crash up close
node tools/hits.mjs shots/hits yard # a pole, the nets, a crash at speed, a hop turn to ride switch
node tools/wx.mjs shots/wx timber 6 # drop in 6 times: a new sky and snow each time (or name them: grand whiteout,nightsnow)
node tools/heli.mjs shots/heli # the helicopter on its pad and the clinic
node tools/shopshots.mjs shots/shop # the shop: deals, an item opened, a trail
node tools/phone.mjs shots/phone # an iPhone in landscape: the front page and a run with touch controls
node tools/portrait.mjs out.jpg 4 1.6 1.66 20 # rider portraits (OUTFITS='[{"head":"hx-racer"}]')
PARK=forest node tools/sim.mjs free 150 # any park headless
Cork7 sky and trick HUD: clear presets (proc: 1, cover) draw the sky in sky.js (gradient in the HDRI's horizon radiance, sun glow, a value-noise cloud plane that drifts with uTime); the image-based light is still captured from the photo (uProc off for the PMREM). In the air main shows the trick so far live (Skier.airTrick(), trickName, trickPoints chips: INVERTED, SWITCH, GRABS, REPEAT via peekRepeat); landings call STOMPED / SAVED IT / CLEAN LANDING with the trick name under it; #charge is the pop bar; the air readout shows speed and distance from the takeoff. tools/hold.mjs takes SHOTS=prefix.
Cork7 HUD and look, round two: no controls banner (How to play has them; the only bottom line is a jump's speed window, as plain text); a music player bottom left like Cork7's (music.js TRACKS: each chord progression is a named track with its own tempo, skip back and forward, pause = Music off); a paler minimap with features as blue beads. ACES is the default tone mapping again (?tm=agx|neutral), LOOK.exp 1.2, so lit snow sits near Cork7's (~190 sRGB) under a bluer drawn sky with more, bigger, whiter cloud. The floodlight masts stand by day too (grey steel, orange padded feet); at night the spray takes the floodlights' light instead of going dark.
Park look (Cork7's): rails and boxes in black painted steel on black legs; every feature's surface carries aFace (how steeply it rises out of the run, from parkAt) and the snow shader shades those faces a little bluer so the shapes read in flat light; dye lines on the snow: across each lip and down both sides of its run-in, faint lines along the landing's edges, and across and beside each rail's entry; a tall marker pole each side of a kicker's run-in with its number and sweet-spot speed on an orange board (one atlas, one instanced mesh).
URL flags: ?park=yard|slope|forest|bigair|timber|grand|mega|canyon&room=name&event=cup|sprint|trial|jam|slopestyle|freeride|bigair&tier=0|1|2&cwatch=<replay id>&menu=0&mode=race|run|park&line=jumps|rails|pipe&auto=1&tod=bluebird|golden|alpenglow|night|storm|spring|arctic|flurries|whiteout|nightsnow&tm=aces|agx|neutral&z=1200&cam=chase|action|helmet|tv&q=low|high|ultra.
Pushing main deploys to GitHub Pages.
src/gear.js: the kit built in code: helmet shells fitted to the avatars' heads (stripe and vents drawn in the shader), knitted beanies with cuffs and poms, goggles with a mirrored bulging lens and a strap, lofted ski and snowboard boots, skis and boards with sidecut, rocker and printed top sheets (17 designs painted on a canvas), bindings and poles.src/cloud.js, src/events.js, src/school.js: the server (accounts, saves, boards, replays, servers), the events and their fields, the Trick School lessons and quick-trick specs.src/sky.js: HDRI sky dome, image-based light from it, and a sun placed where the photo's sun is.src/spruce.js, src/trees.js: snow-laden spruces from a painted needle bough with snow settling on the upper faces, three instanced LODs.src/props.js: chairlift with moving chairs, gates, start house, finish arena + crowd, village, blue course nets, rocks.src/night.js: floodlight towers, glows, beams and the pool of spot lights that follows the camera.src/snap.js, src/replay.js, src/net.js: one skier's look as 52 numbers. Replays record them, multiplayer sends them (with a tiny MQTT client), and both pose stand-in skiers from them.src/post.js: bloom, sun shafts (the sky dome writes alpha 0 as a mask), grade, lens.src/main.js: modes, the scoring (lines, multipliers, repeats), the HUD (zone, score, speed or air time, run minimap) and the menu.