DEV Community

Orbit Websites
Orbit Websites

Posted on

From Code to Exit: My Journey as a Game Developer and Why I Walked Away

From Code to Exit: My Journey as a Game Developer and Why I Walked Away

I started making games because I loved them. I wanted to build worlds, tell stories, and see players smile. Over three years, I shipped two indie titles, learned Unity inside out, and even made a little money. But last month, I walked away. This is my story — with real code, lessons, and the moment I realized it was time to stop.

Let’s walk through how I built my first game, what I learned, and why I ultimately chose to leave game development behind.


Step 1: Starting with Unity and C

I chose Unity because it’s beginner-friendly, has tons of tutorials, and supports 2D/3D. Here’s how I set up my first project:

  1. Download Unity Hub
  2. Install Unity 2022.3.15f1 (LTS version)
  3. Create a 2D project named PixelRunner

Then, I created a player controller. This script moves a character using arrow keys:

using UnityEngine;

public class PlayerController : MonoBehaviour
{
    public float moveSpeed = 5f;
    private Rigidbody2D rb;
    private Vector2 movement;

    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
    }

    void Update()
    {
        // Input
        movement.x = Input.GetAxisRaw("Horizontal");
        movement.y = Input.GetAxisRaw("Vertical");
    }

    void FixedUpdate()
    {
        // Physics
        rb.MovePosition(rb.position + movement * moveSpeed * Time.fixedDeltaTime);
    }
}
Enter fullscreen mode Exit fullscreen mode

Attach this to a sprite with a Rigidbody2D and Collider2D, and you’ve got movement.


Step 2: Adding Gameplay — Collectibles

Next, I added coins. Each coin disappears when touched and increases the score.

Coin Script:

using UnityEngine;

public class Coin : MonoBehaviour
{
    public int value = 1;
    public AudioClip collectSound;

    private void OnTriggerEnter2D(Collider2D other)
    {
        if (other.CompareTag("Player"))
        {
            ScoreManager.AddScore(value);
            AudioSource.PlayClipAtPoint(collectSound, transform.position);
            Destroy(gameObject);
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Score Manager (Singleton):

using UnityEngine;
using UnityEngine.UI;

public class ScoreManager : MonoBehaviour
{
    public static ScoreManager instance;
    public Text scoreText;
    private int score;

    void Awake()
    {
        if (instance == null)
            instance = this;
        else
            Destroy(gameObject);
    }

    public void AddScore(int amount)
    {
        score += amount;
        scoreText.text = "Score: " + score;
    }
}
Enter fullscreen mode Exit fullscreen mode

Now, when the player touches a coin, the score updates. Simple, but satisfying.


Step 3: Level Design and UI

I used Unity’s Tilemap to build levels. Then added a simple pause menu:

using UnityEngine;

public class PauseMenu : MonoBehaviour
{
    public static bool isPaused = false;
    public GameObject pauseMenuUI;

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Escape))
        {
            if (isPaused)
                Resume();
            else
                Pause();
        }
    }

    public void Resume()
    {
        pauseMenuUI.SetActive(false);
        Time.timeScale = 1f;
        isPaused = false;
    }

    void Pause()
    {
        pauseMenuUI.SetActive(true);
        Time.timeScale = 0f;
        isPaused = true;
    }

    public void QuitGame()
    {
        Application.Quit();
    }
}
Enter fullscreen mode Exit fullscreen mode

This pauses the game by freezing Time.timeScale — a neat Unity trick.


Step 4: Publishing on Itch.io

I built the game for Windows and uploaded it to itch.io:

# In Unity: File > Build Settings > Windows > Build
# Then zip and upload to itch.io
Enter fullscreen mode Exit fullscreen mode

My first game, Pixel Runner, got 800 downloads and $47 in donations. I was thrilled.


Step 5: The Second Game — Bigger, Harder

Encouraged, I started Galaxy Drift, a space shooter. I used object pooling to handle bullets:

using UnityEngine;
using System.Collections.Generic;

public class ObjectPool : MonoBehaviour
{
    public static ObjectPool Instance;
    public GameObject bulletPrefab;
    public int poolSize = 10;

    private Queue<GameObject> bullets;

    void Awake()
    {
        Instance = this;
        bullets = new Queue<GameObject>();

        for (int i = 0; i < poolSize; i++)
        {
            GameObject bullet = Instantiate(bulletPrefab);
            bullet.SetActive(false);
            bullets.Enqueue(bullet);
        }
    }

    public GameObject GetBullet()
    {
        if (bullets.Count > 0)
        {
            GameObject bullet = bullets.Dequeue();
            bullet.SetActive(true);
            return bullet;
        }
        else
        {
            return Instantiate(bulletPrefab);
        }
    }

    public void ReturnBullet(GameObject bullet)
    {
        bullet.SetActive(false);
        bullets.Enqueue(bullet);
    }
}
Enter fullscreen mode Exit fullscreen mode

Used like this in the player script:

void Shoot()
{
    GameObject bullet = ObjectPool.Instance.GetBullet();
    bullet.transform.position = firePoint.position;
}
Enter fullscreen mode Exit fullscreen mode

Pooling improved performance dramatically.


What I Learned

  1. Game loops are hard — balancing fun, difficulty, and progression takes iteration.
  2. Polish wins — animations, sound, and feedback matter more than mechanics.
  3. **Marketing is 50% of the

Community-Focused

Top comments (0)