Summary

Skijoring is a co-op skiing game for 2 players made in Unreal Engine 5.6. Inspired by classic arcade racers and the real sport of skijoring, players show off - or wipe out - while outrunning a deadly avalanche.

The project started as my team’s game for Amazing Seasun’s SEED Lab internship in July 2025.
We continued to work on it through December 2025, securing
festival showings and a publisher.

Overview

Timeline

June 2025 - December 2025
(6 months)

Role

Project Lead

Tools

Unreal Engine 5.6

Figma & Notion

Team

9 team members

Project Goals

  • Bring out teamwork and the bond between players

  • Capture the stylish moves and wild wipeouts of skijoring

  • Create carefree, pick-up-and-play fun

My Contributions

    • Designed 2 characters with unique roles.

    • Implemented 3Cs, state machines, VFX, and tricks.

    • Carefully refined the feel of steering, boosts, turns, and airtime.

  • Delivered 5 levels, making reference boards, briefs, top-downs, rough layouts, PCG tools, and set-dressing and lighting spaces.

    • Led weekly standups, design reviews, and playtests for a team of 9.

    • Documented level design process and tools for designers and artists.

    • Scripted both characters and all interactables in Blueprint.

    • Created level set-pieces and transitions in Sequencer.

    • Implemented online multiplayer with Online Subsystem Steam.

Gameplay Reel

Gameplay Design Breakdown

Why should players work together?

We knew we wanted to make a co-op racer, but didn’t know of any games that had pulled it off.

We knew what we didn’t like: hot-seat or combined-input approaches that robbed players of control, as in Mario Kart: Double Dash!! (hot seat) or the Mario Kart: Bowser’s Challenge ride at Universal (combined-input). Co-op always felt like an afterthought.

From the outset, giving players ways to
affect each other and a motive to work together without sacrificing individual control were the goals of our loop.

In the short and long-term, Skier and Snowmobiler had to
matter to each other and retain their agency.

Core Loop

From moment to moment, Snowmobiler drags Skier. Skier reacts to the obstacles approaching them + Snowmo’s path.

Track Loop

As players progress on a track, Skier does tricks and hits slaloms to earn boosts for Snowmo.

Iterations - Snowmobiler

Snowmobiler took up a lot of my focus early on. Since his movement directly affected Skier, he needed solid handling and feedback, as well as motives to create interesting gameplay moments for Skier.

  • Basic controls for Snowmobiler to test pulling Skier. Skier uses a character controller, Snowmo is physics-based.

    On controller, Snowmobiler only used left analog for steering and throttle. Snowmobiler could not turn from a standstill.

    Playtesters found this version slippery and unintuitive. Hill climbs and turning were difficult, and Snowmobiler felt unresponsive.

  • To keep turning consistent and intentional, I moved throttle to a separate button and scaled the strength of Snowmo’s turn over time. This allowed quick, precise turns without Snowmo feeling slippery.

    I changed Snowmo’s physics material, taking a low blend of Snowmo’s friction to expedite turning and climbing steep hills.

    Turning was refactored to use angular velocity instead of torque. Braking and reverse were added here.

  • Players liked the improved turning, but Snowmo still felt stilted relative to the environment.

    Camera lag removed camera jitter on rough surfaces. Changing the snowmobile’s roll to match surfaces made movement more stable and the camera more dynamic.

  • Jumps felt a bit anticlimactic for Snowmo, especially since Skier tricks were in. As a hero feature of skiing games, jumps needed some work.

    Inspired by SSX and Crash Team Racing, I gave Snowmobiler boosts after airtime to reward setting up tricks for Skier. Giving boosts their own trick animation made the effect clear.

  • Initially, our split-screen was horizontal to show more space around each player, with the camera pulled in to highlight characters.

    We switched to vertical split-screen to highlight verticality and speed. Camera shifts during airtime and boosts let us focus on tricks, but show more of the environment when appropriate.

  • Snowmobiler worked well, but had one problem:

    You couldn’t see the Skier! It felt like you were playing the game alone. This was especially bad in online, where screen-peeking wasn’t possible.

    I added a render target widget to show a view of Skier, but left it as an option.

Iterations - Skier

Skier went through several revisions to reach a level of agency and involvement on par with Snowmobiler.

While Snowmo focused more on the path in macro, Skier centered on style, reaction, and moment-to-moment flow.

  • First draft with Skier turning, jumping, and matching terrain tilt.

    Skier could hit slaloms, but there wasn’t a motive to jump.

    Skier’s camera didn’t show the space ahead, and the implementation for the rope restricted movement.

    Worst of all, Skier would often clip through terrain and walls.

  • To prevent clipping or holding up Snowmo, I added crash detection for Skier and made him ragdoll on crash. This alone made the game twice as fun - there was more interplay between players.

    Tricks and combos made tall jumps more rewarding, but boiled down to button-mashing at first.

    Skier still had little impact on Snowmobiler beyond slaloms.

  • Inspired by Burnout and SSX Tricky, I added the RAD system to motivate tricking. Once RAD is full, both players get a significant boost.

    I added stale tricks, requiring more intentional tricking for RAD. Skier now had a definite, intuitive impact on speed.

    To give Skier more freedom while steering, I increased his maximum step angle and added some “tension“ to the rope - Skier has some leeway beyond the rope’s set bounds, but gets heavier resistance the further out he is from Snowmo.

  • Players were having trouble understanding slaloms, especially who could gain slaloms and whether points were from tricks or slaloms.

    I added a widget callout for slalom pickup, showing the slalom icon to differentiate it from the trick callout.

    Showing the same icon on slaloms, gates, and the UI created a clear language for the feature.

  • Players felt Skier was still a little inconsequential. Snowmo had a way to directly move Skier, but Skier couldn’t affect Snowmo.

    Yoink resolved this: every few seconds, players can pull each other along the rope. Skier could now save Snowmo from cliffs, troll the other player, or do elaborate shortcuts and tricks.

  • Skier was now on par with Snowmo, but something felt off.


    A few testers noticed they couldn’t consistently see Snowmo over Skier. Dithering felt like a shoddy fix - seeing Skier pull off tricks was a core feature.

    I pulled out the camera and made Skier snap to the terrain’s roll rotation to show Snowmo more often.

    Pulling the camera out during long jumps improved visibility and the feel of boosts. Bobbing the camera from a pull-in during a boost to a faraway shot when jumping really sold the central push and pull.

What I Learned

  • Games need to include and‍ motivate fun actions. SSX encourages tricking, Burnout wants you to risk crashing, and Mario Kart rewards every way you can move your kart.

    From the beginning, we knew everything Snowmobiler did would affect Skier and vice versa. Both characters needed motives to act/react in interesting ways and make regular split-second decisions.

    Knowing a reaction would be fun in itself, or affect the other player in a meaningful way, was often enough to motivate a fun action. Tying actions into clearly set goals was an even stronger motivator.

  • A lot of the fun of Skijoring is in “losing“ - crashing into things, miscommunicating, getting into weird situations. We set out to make a game that wasn’t laser-focused on optimal play.

    Making “failure“ an entertaining outcome brought out more teamwork in players. It took the pressure off and let them laugh together instead of getting frustrated.

    In general, I find fail states tend not to be thought through as much as optimal play, despite being a huge element of games. How does it feel to fail? How does it feel to learn? What can a player do after a mistake?

  • The fun of a multiplayer game is in affecting other players. Multiplayer games are least fun when you’re not playing: when your actions are limited or another player removes your agency.

    Finding a balance between players’ agency and effect on each other was the main challenge of making Skijoring. Even once a player had enough control, it still had to tangibly affect the game and other players to motivate action.

  • Most of the Skijoring team were new to Unreal and juggling other commitments. Being proactive with communication, seeking the team’s ideas and feedback, and creating a shared understanding of our design needs not only kept us motivated, but led to better work from everyone.

Level Design Breakdown

Goals

Process

Rules