Two little guys. One keyboard. Zero room for mistakes.
A brain-bending coordination platformer where one character walks on the ground while the other traverses the ceiling, requiring synchronized spatial planning to guide both through hazard-filled rooms.

Traditional platformers operate under a single downward gravity vector. In Tiny Together, the player simultaneously commands a ground-based and a ceiling-based character using one set of controls. The primary design hurdle was preventing players from becoming disoriented by ceiling physics, while creating level geometry where floor and ceiling obstacles interact harmoniously.
Built a modular gravity-agnostic character controller in Unity C# paired with zero-allocation scene reset architecture.
Refactored CharacterMovement to accept an orientation vector (Vector2.up vs Vector2.down). Raycast checks, sprite flipping, and jump velocity vectors automatically derive from this orientation scalar.
Implemented an event-driven door system where either character can arrive first and stand on the pressure switch, but the level door only unlocks when both switches register continuous pressure.
Instead of calling SceneManager.LoadScene() (which causes WebGL stutters and garbage collection freezes), pressing 'R' triggers a soft checkpoint reset that resets entity transforms and switches in under 5 milliseconds.
using UnityEngine;
[RequireComponent(typeof(Rigidbody2D))]
public class InvertedGravityController : MonoBehaviour
{
[SerializeField] private bool isCeilingWalker = false;
[SerializeField] private float moveSpeed = 7f;
[SerializeField] private float jumpForce = 12f;
[SerializeField] private LayerMask groundLayer;
[SerializeField] private Transform groundCheck;
private Rigidbody2D rb;
private bool isGrounded;
private float gravitySign => isCeilingWalker ? -1f : 1f;
private void Awake()
{
rb = GetComponent<Rigidbody2D>();
// Adjust gravity scale based on orientation
rb.gravityScale = 3f * gravitySign;
if (isCeilingWalker)
{
transform.localScale = new Vector3(1, -1, 1);
}
}
public void Move(float direction)
{
rb.velocity = new Vector2(direction * moveSpeed, rb.velocity.y);
}
public void Jump()
{
CheckGrounded();
if (isGrounded)
{
rb.velocity = new Vector2(rb.velocity.x, jumpForce * gravitySign);
}
}
private void CheckGrounded()
{
Vector2 direction = isCeilingWalker ? Vector2.up : Vector2.down;
RaycastHit2D hit = Physics2D.Raycast(groundCheck.position, direction, 0.2f, groundLayer);
isGrounded = hit.collider != null;
}
}ℹ By parametrizing gravity direction with `gravitySign`, identical platforming logic seamlessly operates right-side up and upside-down with zero duplicate code.
Tiny Together became a standout jam title, finishing in the Top 10 Most Rated submissions out of 550+ games in The Brainless Game Jam.
Ranked among the Top 10 most rated projects out of 550+ international entries.
Instant soft reset eliminated scene reload latency during rapid puzzle attempts.
Praised by playtesters and content creators for frictionless trial-and-error pacing.
Playable right now in your browser with full WebGL performance.