top of page

"Don’t Tell Me to Chill": A Thorough Assessment of Proper Game Development Ethics

Writer: Aneesh Saraswat
Aneesh Saraswat
Sep 26
5 min read

Chapter 1: The Game Works — Is That All?



When I first set out to develop my most complete project to date—Don’t Tell Me to Chill, a first-person, retro-style homage to the popular game Baldi’s Basics—my primary objective was simply to get a playable base game off the ground. My initial visual goals included implementing an old-school, pixelated VHS filter to capture the aesthetic of a classic PlayStation 1 title, fully modeling the environment, and establishing a clear development timeline.

Original Development Timeline:

  1. First-Person Player Controller: Fully functional, smooth movement scaled to the game world.

  2. External Character Models: Created models for each non-player character (NPC).

  3. Main Antagonist Setup: Model scaled and basic animations assigned (without active logic).

  4. Player Fine-Tuning: Refined speed, interaction systems, and core variables to integrate with scene objects.

  5. Antagonist Programming: Implemented AI pathfinding, player detection, chase sequences, and trigger zones.

  6. Secondary Antagonists: Modeled, scaled, and programmed unique AI behaviors, detection rules, and mechanics for supporting characters.

  7. Playable Draft & Initial Debugging: Verified that the core gameplay loop was functional and free of console errors or broken interactions.

  8. Aesthetic Enhancements: Added static meshes, particle effects, chromatic aberration, and interactive objects to make the world feel alive.

  9. User Interface (UI): Integrated a HUD, main menu, settings menu, and dynamic object interaction prompts.

  10. UI Polish: Added menu animations, visual enhancements, and clean layout design.

  11. Secondary Debugging Round: Conducted extensive playtesting to eliminate newly introduced bugs.

  12. Final Design & Logic Polish: Evaluated the overall project flow to make key adjustments for quality and player satisfaction.

  13. Pre-Release Testing: Gathered external play testers to gain unbiased user experience feedback and implement worthwhile suggestions.

  14. Release: Published and marketed the game on widely accessible platforms like itch.io and Steam.

While this timeline provided a reliable roadmap, development was far from seamless. Resolving console bugs and handling hardware bottlenecks taught me a crucial lesson: building a successful game requires far more than basic functionality—it demands deliberate software organization, optimization, and scalable design.


Chapter 2: The Hidden Problem — Games Need Proper Architecture Too


As project complexity grew, the distinction between making code work and designing code well became glaringly obvious. Adopting a modular mindset forced me to rethink my approach to game architecture. Maintainability relies on a clean separation of responsibilities; a feature might function properly in isolation while silently making the overall codebase harder to read, debug, or extend.

Researching game programming patterns introduced me to foundational concepts like finite state machines, modularity, separation of concerns, and structured game loops. This shifted my core perspective from hastily implementing features to systematically orchestrating an entire software architecture.

Applying the principle of separation of concerns fundamentally changed how I built systems. Initially, I intended to write a single, monolithic script for all player behaviors—movement, environmental interaction, and secondary mechanics. Recognizing that future features would require constant, messy edits to this giant script, I broke the system down into dedicated modules:

  • Movement System: Handles locomotion inputs and mechanics (sprinting, crouching, walking, jumping).

  • Interaction System: Manages environmental inputs (e.g., pressing E to open doors, inspect objects, or hide).

  • Contextual Mechanics System: Controls conditional status effects (e.g., speed debuffs from specific items or safe-zone stealth behavior).

Decoupling these mechanics created isolated, maintainable systems. Instead of wading through hundreds of lines of cluttered code to tweak a single mechanic, I could instantly locate and modify the specific module responsible.


Chapter 3: Becoming One with the Game Loop


Deepening my understanding of the fundamental game loop further refined my approach to system design.

At its core, a game engine operates on a continuous, three-step cycle: processing input, updating game state, and rendering the output.

Consider how this applies to collecting inventory parts in Don’t Tell Me to Chill:

  1. Input: The player presses E while looking at a part.

  2. State Update: The engine registers the item as collected and updates the inventory count.

  3. Render: The UI updates on screen to reflect the new total.

Understanding this cycle highlighted the importance of structuring code around continuous execution updates. Rather than packing input handling, state updates, and rendering logic into a single, overloaded Unreal Engine Blueprint, I separated these concerns into dedicated managers built specifically for their step in the loop.


Chapter 4: Benefits and Limitations of Complex State Architecture


Managing state transitions quickly became another critical focus. Games are inherently dynamic; rules, interaction prompts, and engine behaviors shift continuously based on current context.

[Main Menu] ---> [Gameplay Loop] ---> [Game Over / Win]

To maintain control over these transitions without relying on massive conditional statements, I replaced single-blueprint game loops with dedicated state handlers. Managing state through modular architecture prevents central scripts from becoming unmaintainable as new conditions are added—a common anti-pattern highlighted throughout official development documentation.

However, advanced architecture comes with trade-offs. Complex design patterns are not a one-size-fits-all solution; over-engineering a simple system introduces unnecessary abstraction, overhead, and organizational clutter. The real engineering goal is choosing the simplest, most effective architecture for the project's specific scope.


Chapter 5: Separating Responsibilities Across Systems


Reflecting on Don’t Tell Me to Chill, I realize how many interconnected responsibilities exist beneath the surface of a seemingly straightforward game:

  • Player Character: Manages movement mechanics, camera controls, and environmental interactions.

  • Main Antagonist: Handles pathfinding navigation, detection systems, and chase behavior.

  • Secondary NPCs: Executes unique visual events, AI routines, and utility triggers.

  • User Interface: Displays real-time game data smoothly without holding or managing core game logic.

  • Environment: Renders world visuals and interactive objects without interfering with core gameplay loops.

Isolating these domains allowed me to design individual systems independently while maintaining clear communication channels between them. The core development question shifted from "Where can I insert this code to make the feature work?" to "Which system is logically responsible for this feature?"

This structural shift transformed my debugging process. When an issue arose, I no longer needed to scour the entire project—I could isolate the bug directly within its dedicated domain.


Chapter 6: From Prototype to Product


The journey of Don’t Tell Me to Chill highlighted the stark difference between a rough prototype and a finished product.

A prototype simply proves a concept. My initial goal was basic execution: placing a functional player model into an environment alongside dynamic antagonists to verify that the core concept worked.

A product, by contrast, must endure long-term development and user variability. Delivering a game for public distribution requires planning beyond local performance. It demands stability, intuitive UX, optimized execution, polish, and an architecture built to withstand iterative updates.

Transitioning from a prototype to a product relies heavily on playtesting. Developer bias makes it easy to overlook design flaws due to familiarity with your own systems. External play testers bring fresh perspectives, exposing unintuitive mechanics, edge-case bugs, and usability flaws that internal testing rarely reveals. Transforming a prototype into a product is a gradual process that requires patience, iteration, and attention to detail.


Chapter 7: Engineering Lessons Learned


Building Don’t Tell Me to Chill proved that game development is far more than bundling functional features together—it is an exercise in software engineering.

I initially focused entirely on the player's immediate experience. As the project grew, my focus expanded to include the structure, stability, and scalability of the underlying code. Good architecture isn't about making a game complex for the sake of it; it is about deliberately managing complexity.

The defining shift in my journey was moving from asking "Does this work?" to "Will this remain stable and maintainable as the project evolves?"

That fundamental shift transformed Don’t Tell Me to Chill from a collection of scripts into a fully engineered software product.


Conclusion


Although development spanned nearly three months, establishing these architectural strategies earlier would have significantly streamlined the process. Effective organization and thoughtful planning are just as essential as writing code. Taking the necessary time to design clean systems, test thoroughly, and refine mechanics ultimately leads to a far more stable, professional, and satisfying game.

 
 
 

13 Comments


Arsh Talan
Arsh Talan
7 days ago

This is amazing aneesh

Like

DR. GIRIDHAR GOPAL SARASWAT
DR. GIRIDHAR GOPAL SARASWAT
Oct 07

Excellent article. Good job. Keep it up the Good work. God bless you Aneesh.

Like

Digesh Sahu
Digesh Sahu
Oct 07

Good article. Keep it up!

Like

Shikha Dixit
Oct 07

Outstanding work Aneesh!!👍

Crushing goals like a pro! Keep shining! ✨

Like

Saneel Reeshan
Saneel Reeshan
Oct 07

Nice work there Aneesh!!!

Like
bottom of page