• 5 min read

Building a game from scratch to finally understand OOP

Table of Contents

Tidal Island is a survival game where you are stranded on a deserted island and must gather resources, craft items, and build a raft before the rising tide submerges everything.

Why I built it

Tidal Island was initially developed as a final project for CMSC 22 (Fundamentals of Object-Oriented Programming).1

The requirement was to build a Java application that applies object-oriented programming concepts. Even without the requirement, I probably would have still chosen to build a game.

I had never built one before, and games felt like a good way to practice OOP. A game naturally has many interacting objects: players, items, resources, inventories, crafting systems, and world events. These are much easier to understand when you can actually see them working together instead of just reading examples in a textbook.

The idea itself was inspired by survival games like Minecraft. I wanted to make something simple but still have a complete gameplay loop: gather resources, craft tools, and eventually escape.

How it turned out

The game is now available on itch.io for free and is playable on Windows, Mac, and Linux.

Title screenPlaying still

The main gameplay loop revolves around surviving the island long enough to build a raft.

Players collect materials, craft items, and manage their inventory while the tide slowly rises over time. The tide mechanic became one of the more unique parts of the game because it required not only making it functional, but making the flooding feel natural.

How I built it

Technologies I used

Java

(yep, that’s it…)

No game engine was used. Everything was built from scratch using Java.

This meant implementing systems that game engines usually handle for you: rendering, input handling, collision detection, object management, and game state.

Architecture and design

The project started small, but the architecture evolved as more features were added.

The final version is organized into several systems:

  • Game engine
  • Entity system
  • Collision system
  • Inventory and crafting system
  • Tidal mechanics
  • Event system
  • UI system

You can read more about the architecture in the documentation.

---
config:
  layout: elk
  look: handDrawn
---

stateDiagram
    state Title
    state Playing
    state Pause
    state GameOver

    [*] --> Title
    Title --> Playing: Start Game
    Playing --> Pause: ESC
    Pause --> Playing: Resume
    Pause --> Title: Exit
    Playing --> GameOver: Death/Flood
    GameOver --> Playing: New Game
    GameOver --> Title: Exit

Throughout development, I applied design patterns such as Singleton, Builder, Factory/Registry, Observer, State, and Template Method . I also tried following SOLID principles where they made sense.

What made these concepts finally click was seeing them represented as actual game objects.

A piece of wood is not just a variable. It is an item with properties. An inventory is a system that manages those items. Different objects have different behaviors, but they still interact inside the same world.

These ideas were much easier to understand when I had to design them for a working game.

Developer experience

While building the game, I also created tools to make development easier.

The most useful was a debug rendering system that visualizes collision boxes, UI elements, and other internal states while playing.

Debug renderWorld builder

I also built a World Builder for designing maps visually. It allows painting tiles, placing objects, undoing changes, and exporting the world data as JSON that the game loads.

The project also includes a JUnit test suite covering important systems.

Art

For graphics, I chose pixel art and created most of the sprites myself using Aseprite.

I was still learning pixel art during development, so there was a lot of trial and error in getting sprites and animations to look right.

For the player character, I started from a base sprite by Hana Caraka because it already included animation states that made development easier. I modified it with my own colors and adjustments.

Player sheet
Player spriteRaft sprite

What I learned

This project changed how I understood OOP.

Before this, concepts like SOLID principles, inheritance, polymorphism, and design patterns felt abstract. Building a game gave them a concrete purpose.

I also learned that game development is much harder than it looks. Even a simple 2D game requires solving problems across many areas: graphics, physics, input handling, state management, tools, and user experience.

The most rewarding part was building something purely because it was fun. Games are one of those things where engineering and creativity meet.


Footnotes

  1. CMSC 22 is a computer science course I took at UPV. It covers topics such as the pillars of OOP, SOLID principles, and design patterns.