< Back 

Rod and Reef

2026-10-02

Story-driven Roblox fishing game with 530 quests across four islands. I'm its lead developer: I own the backend (player data, luck, quests, dialogues, seasons) and build UI. This page links to the technical article for each system.

LuauRobloxBackendUIPython
Go to quick view

A fishing game whose backend has to last.

Warning

Rod and Reef hasn’t been released yet, and footage of the game and its systems can’t be shown until it launches. The articles below describe the systems without videos or GIFs.

Abstract. Rod and Reef is a story-driven fishing game for Roblox with four islands, 530 quests, 117 dialogue files and 74 recorded voice lines. It’s closed source and still in development. I’m its lead developer: I started on the client, building UI, and I now also own the heavy backend, meaning player data, the luck behind every cast, quests, dialogues and seasons. What ties it together is that the game has to stay maintainable once it’s live. The server decides, the client works from read-only copies, and most content is data that tools generate from the design documents. This page is an index. Each section summarizes a system in a few lines and links to the article where I go through the decisions and the math.

1. My role

I’m the lead developer. I was originally in charge of the whole client side, every piece of UI the player sees and touches, and I still build it, with a preference for interfaces that react to everything you do: the particle burst on each hit of the fishing minigame, dialogue text that types in time with the voice, subtitles that follow the actor word by word. Since the promotion I also own the backend that can’t afford to be wrong, which is everything the server has to decide or save: data, the luck system that decides what a cast catches, quest progress and seasons.

As lead I’m responsible for all of it staying maintainable and technically clean. That depends less on any single system than on a few rules that repeat across them (section 2).

2. How it’s built

The code is vanilla Luau with a service and controller structure made for this game. We dropped frameworks like Knit because at our scale they add more overhead than they solve, and the module layout keeps the server and client boundary explicit. Storage uses ProfileStore and the network uses ByteNet. Four decisions come up repeatedly in the articles below.

  • The server decides and the client keeps a copy. The quest profile is one class that writes to the player’s data on the server and is read-only on the client, and events travel as binary packets with a schema per packet.
  • Content is data. Quests, dialogues and their layers are tables, and tools generate most of them from per-NPC transcriptions of the design documents. Generated and hand-written content live in separate folders and are combined on load, so regenerating never erases what someone wrote by hand.
  • Whatever can run twice has to be safe to run twice. Data migrations run on every join, and any server can close a season because two servers racing to do it write the same thing.
  • Derive instead of maintain. When something depends on the current state, I recompute it from that state instead of trusting that every event arrived once and in order. The effective player state, the menu lock during cutscenes and cutting a bark when a cutscene opens all work this way.

3. Backend

  • Player data. A ProfileStore session acts as a lock, so only one server writes a profile. Every write changes the profile and notifies the client in the same call, which lets the client’s copy, built from a snapshot plus per-path changes, converge to the server’s. Migrations are idempotent, and gifts reach players who are on another server or offline.
  • Seasons. 45-day seasons with four leaderboards and no coordination between servers. The season is a function of the clock, counters reset lazily, and reads go through caches that deduplicate in-flight requests, so a thousand players opening a board cost one request every 30 seconds.
  • Luck system. Five rolls per cast, with the rod, bait, nearby friends, the boat and multipliers on top. Odds come from two piecewise-linear ladders, pity thresholds are derived from the natural probability, and a renewal-process analysis matches a 400,000-cast simulation to the decimal. Bait prices are derived so each bait is the best choice on exactly its own rod.
  • Quests. 530 quests as data, a prerequisite graph that survives disabling a quest, active slots classified from the objectives instead of written by hand, and a journal sorted by an estimate of how many casts each quest takes.
  • Dialogues. 117 files (80 base conversations and 37 layers) that a two-pass deserializer turns into graphs. The client walks the graph to show the conversation and the server walks it in parallel, so it only accepts moves the player was actually offered.

4. Client and UI

  • Fishing minigame. A dial where a needle and a target spin in opposite directions. Difficulty is a pure function of the rod and the fish, and the scoring is a tug of war that, analyzed as a Markov chain, is more sensitive to skill than a simple race.
  • Ambient barks. The protagonist comments on what you do, which required a PlayerStateMachine (parallel state machines, one per owning system) to answer “what is the player doing right now”. A director picks the lines from a shuffled deck so they don’t repeat, and the same state decides when menus and prompts have to wait.

5. Tooling and libraries

  • Subtitles. A Python pipeline that transcribes each clip with faster-whisper large-v3 and keeps the timing of every word, matches each improvised take to its script line, writes one Luau module per clip and uploads the audio. In game, a clock-driven player reveals the words so it doesn’t drift.
  • Spray. My Luau library for playing ParticleEmitters inside the GUI. Every particle is a function of a clock, and with the same effect it uses 1.3 to 1.8 times less CPU per frame than Emitter2D. The game vendors it for the minigame’s effects.
  • PrettyUI. My attribute-driven menu library: hover effects, animations, sound and GUI stacking configured in Studio with no per-button scripting. The game’s menus use it, and the menu lock described in the barks article is built on top of it.

This text by Mastedore. All rights reserved.