Gameplay Pillars
- >Momentum as the main skill expression
- >Clear visual language for puzzle affordances
- >Fast restart loops for level mastery
Gameplay Programmer & Level Designer
I designed and implemented the core movement systems and level scripting tools. The objective was to create expressive player control with high skill ceiling while preserving approachability for first-time players.
Duration
5 months
Team
3 developers
Engine
Unity
Platforms
PC, Web Build
Horizontal speed and airborne control are tuned from a shared movement curve profile.
Impact: Improved consistency between early and late levels while keeping advanced tech routes viable.
Puzzle logic assembled by data assets instead of one-off MonoBehaviours.
Impact: Cut level scripting iteration time and reduced duplicated puzzle logic bugs.
Snapshot-based respawn system resets dynamic puzzle objects in under one frame.
Impact: Maintained flow state during difficult segments and improved completion rates.
Screenshots and clips from gameplay, debug tools, and iteration passes.

Late-game route featuring chained wall jumps and gravity switch timing.

Internal level-authoring tools for puzzle nodes and checkpoint links.
Movement tech demo: coyote + buffered jump + wall redirect combo.
Focused clips showing implementation outcomes, tuning passes, and polished gameplay moments.
One-take run used to validate route readability and checkpoint placement.
Practical samples from gameplay systems and runtime tools used in production.
PlayerMovementController.cs | csharp
Combines coyote time and jump buffering for responsive platforming inputs.
private float coyoteTimer;
private float jumpBufferTimer;
private void UpdateJumpTimers(float deltaTime)
{
coyoteTimer = IsGrounded ? coyoteTime : Mathf.Max(0f, coyoteTimer - deltaTime);
jumpBufferTimer = jumpPressedThisFrame
? jumpBufferDuration
: Mathf.Max(0f, jumpBufferTimer - deltaTime);
}
private void TryConsumeJump()
{
if (jumpBufferTimer <= 0f || coyoteTimer <= 0f)
{
return;
}
velocity.y = jumpVelocity;
coyoteTimer = 0f;
jumpBufferTimer = 0f;
}PuzzleNodeController.cs | csharp
Data-driven puzzle actions triggered by node activation rules.
public void ActivateNode(string triggerId)
{
foreach (PuzzleAction action in nodeData.actions)
{
if (!action.triggerIds.Contains(triggerId))
{
continue;
}
actionExecutor.Execute(action);
}
}