Inspired by Block Puzzle Ancient-style, free placement puzzle games. This project started as an architecture showcase, and grew into a fully shipped mobile game.
- Design a game core (engine) completely independent from UI
- Separate game rules, state and render layers with strict boundaries
- Rather than a simple game, build a design where each layer does its own job and be able to justify its necessity.
- Doesn't know React / React Native
- Doesn't know UI
- Doesn't know State
- Contains only rules and math
Responsibilities:
- Can a piece be placed
canPlace - Placement adjustment
getAdjustedPlacement - Rotation and matrix transformations
- Board boundary and collision checks
- Level validation via backtracking solver Core is completely platform independent. Can run in web, RN, desktop or Node environment.
Note:
- Board doesn't hold occupancy state, it's a dummy space.
- Collision detection is done through
occupiedCellsprovided from outside. - Core doesn't impose a single "absolute truth"; it's parametric. I thought of it like this; board is the land, puzzle pieces are people settling on that land. When a new piece wants to settle, it doesn't ask the board, it asks each person individually "where are you". The reason is that board isn't just for this type of block-puzzle, it can be used for other types of games too.
- Game's memory is kept here
- Single entry point between UI and Core
Purpose and responsibilities of this layer:
- Puzzle piece information and management
- Information like
baseMatrix, rotation, position tryPlacePieceis the only entry to coreoccupiedCellsgeneration and matrix normalization- Prevent UI from accessing Core directly
UI never calls rules like
canPlacedirectly. Instead it uses entry points liketryPlacePiecethrough this state.
- Render
- Gesture (drag & drop via PanResponder)
- Animation (Reanimated 4)
Knows nothing else.
- Doesn't know board logic
- Doesn't calculate collisions
- Doesn't make decisions about rules Only passes data and renders elements according to incoming data.
UI only communicates intent:
- position
- rotation
- interaction Decision is made by State + Core.
- Anchor point is always
matrix[0][0] - Coordinates from UI are normalized before passing to Core
- No gravity, line clear, classic Tetris rules. This isn't a Tetris game anyway, it's a puzzle game using Tetris pieces. This engine is designed for free placement puzzle rules.
- Levels + remote levels via Supabase
- Daily puzzle with streak tracking
- Leaderboard
- Background music playlist + sound effects
- Rewarded & interstitial ads (Google Mobile Ads)
- Analytics (PostHog with session replay)
- i18n: English / Turkish
- OTA updates via Expo
| Layer | Technology |
|---|---|
| Runtime | React Native 0.81 + Expo 54 |
| Language | TypeScript 5.8 |
| State | Zustand + custom hooks |
| Animations | react-native-reanimated 4 |
| Backend | Supabase (levels, settings) |
| Analytics | PostHog |
| Ads | Google Mobile Ads |
| Audio | expo-av |
- Shipped on iOS App Store and Google Play
- Architecture is stable, core has no React dependencies
- Levels delivered remotely via Supabase; new levels can be added without an app update
This repo exists to show:
- How layered architecture is built
- How engine is isolated from UI
- Why state should be a "single gate"
- How a small problem domain can be transformed into clean design Not for playing the game, but for reading the code and examining the architecture. Initially I wanted to mimic a simple game I liked, but then turned it into a layered example and eventually shipped it.