Today was about making the game prototype feel like an actual game instead of a tech demo.

Gameplay additions

  • RoastingStick — A tool players pick up and use. It mounts to the character’s hand with proper grip positioning via Motor6D attachments
  • Backpack subsystem — Manages tool equipping/unequipping through the framework instead of relying on Roblox’s default backpack
  • BillboardGui on Dispensers — Floating text showing how many items are left to grab
  • Satisfaction HUD — A real-time indicator showing how well you’re doing at the current task
  • Marshmallow color — Visual feedback tied to roasting state (golden brown = good, charcoal = bad)

We wrote our own Backpack subsystem instead of using Roblox’s default one because the default backpack UI is opinionated and hard to customize. It renders a toolbar at the bottom of the screen with numbered slots, and overriding its behavior means fighting with CoreGui. Our subsystem manages the same underlying mechanics (equip, unequip, drop) but gives us full control over the UI and input handling.

The first production bug

We published to Roblox to test with actual players, and immediately hit a deployment order race condition. In Studio, everything loads near-instantly — scripts and models are already in the DataModel when the game starts. In a published game, assets replicate to clients at different speeds depending on network conditions and asset size.

Our System was trying to initialize assets that hadn’t arrived yet. The init() call would run, try to access child instances, and find nothing there. No error, no warning — just silent nil values that cascaded into broken state.

The fix was straightforward — WaitForChild on expected children before initializing — but it highlighted a fundamental difference between Studio and production that catches a lot of Roblox developers:

  • In Studio: Everything exists before scripts run. script.Parent:FindFirstChild("Config") always works.
  • In production: Replication is async. That same FindFirstChild might return nil because the Config hasn’t arrived yet.

If you’re only testing in Studio Play mode, you’ll never see these bugs. They only appear in published games or Team Test with simulated latency. We started publishing to a private test place every time we made structural changes.

Lesson learned early: always test published, not just in Studio.