SpaceGoats / Case study

I led a team to build a game about an escaping goat colony.

I made SpaceGoats for a national Italian game-design competition. I led the team, served as lead programmer, and combined a one-button platformer with a colony-management system about sustainability.

Play my WebGL build

My roleTeam lead / Lead programmer
I usedUnity 6 / C# / URP 2D
I designedOne-button movement
I worked fromSustainable cities
The SpaceGoats colony I helped build on an alien planet

What I had to solve

I needed to make sustainability playable.

I started from UN Sustainable Development Goal 11. My team and I paired a fast platforming loop with a slower colony loop: I send the goat into mines for food and metal, repair geothermal equipment, and spend resources on upgrades that make the colony more independent.

My main design problem: I wanted each run to feel immediate while still making the colony’s long-term progress easy to see.

How my loop works

I connected short runs to long-term upgrades.

  1. I choose the mine, energy facility, or greenhouse from the colony.
  2. I run automatically and use one button for jumps and wall jumps.
  3. I watch oxygen and health while collecting food and materials.
  4. I only keep the resources if I return safely.
  5. I spend them on the goat and the colony.
  6. I finish upgrade stacks to make the colony self-sufficient.

How I handled character upgrades

I store oxygen, health, maximum speed, and jump force in a shared GoatStats ScriptableObject. I made the speed and jump sliders use the player’s unlocked maximum, so upgrades create more choice instead of forcing the hardest setting.

How I handled colony upgrades

I made each upgrade a data asset with its text, resource costs, and UnityEvents. My UpgradeManager builds the progression stacks, loads saved levels, updates the interface, and checks when the required stacks are complete.

How I structured it

I connected small systems with events.

I built the project in Unity 6 with C#, URP 2D, the Input System, Tilemaps, TextMesh Pro, post-processing, and LeanTween. I shipped six scenes: the story, colony, energy facility, two caves, and greenhouse.

How I made one-button movement work

I BoxCast in four directions and classify each physics frame as ground, air, wall, or corner. I keep a short contact history so the goat preserves its direction through transitions. I also added grace frames, input buffering, variable jump time, wall sliding, and acceleration limits so one button still feels responsive.

How I handled a run

I use a persistent GameManager with events for startup, scene loading, run start, victory, game over, reset, and returning to the colony. I connect health, oxygen, resources, UI, and transitions to those events instead of letting every component control the whole run.

How I saved the world

I identify each resource by its type, scene, and position. I save its remaining regrowth or repair time as JSON in PlayerPrefs. I also save food, materials, upgrade levels, and player progress between scenes and sessions.

How I shipped it

I packaged the same Unity project as a WebGL/PWA build and an Android APK.

View my source repository →

How I led the team

I had to manage the project, not just my code.

I coordinated the team in Italian, set internal deadlines, split up feature work, and kept everything moving toward one complete build. I used feature branches for UI, art, resources, upgrades, and levels, then integrated them into main. That let us work in parallel, but I also dealt with reverts, rebases, scene conflicts, and late fixes near the deadline.

What I completed with the team

  • I worked from the first repository setup in December 2024 through the final fixes in April 2025.
  • I integrated movement, regrowth, oxygen, resources, upgrades, minimap UI, audio, story scenes, and accessibility sliders.
  • I merged separate contributor branches into one shared game instead of collecting disconnected demos.
  • I produced the final WebGL and Android builds from the integrated project.

What I learned

I learned as much from integrating the game as I did from programming it.

  • I make difficult controls forgiving internally. My one-button interface still needed contact states, grace frames, buffering, variable jump force, and careful wall behavior.
  • I separate data from behavior. ScriptableObjects let me tune statistics, resources, and upgrades without hard-coding everything into scenes.
  • I design saving early. My scene-and-position IDs work, but I would use stable IDs if I rebuilt the levels.
  • I document event ownership. UnityEvents reduced coupling, but I would make their order and save responsibilities clearer next time.
  • I integrate branches more often. Scene conflicts taught me to use smaller commits, clearer ownership, and regular merges.
  • I treat accessibility as part of the mechanic. One-button input and adjustable movement became part of the game’s identity.