I made this game How should i improve it?

Summary

A beginner submitted a Python timing game with a score of -2, asking for improvements. The postmortem analyzes the user experience, input handling, and code structure. The primary issue is the harsh penalty system and lack of user feedback, which leads to frustration. The core takeaway is that beginner code often prioritizes logic over user experience, and improving robustness requires separating game state management from input/output logic.

Root Cause

The negative score and request for help stem from three specific code behaviors:

  • Ruthless Reset Logic: The score = 0 clause on every wrong guess destroys progress immediately. If the user guesses correctly 10 times and fails once, they are back to zero. This is an exponential difficulty curve that discourages play.
  • Implicit Data Types: The user uses int(input(...)). If the user types “2.5” or “two”, the program crashes with a traceback. In production, uncaught exceptions are fatal errors.
  • Blind Timing: random.randint(1, 5) generates the number, but the user is not informed of the range. Users cannot make an educated guess without knowing the constraints.

Why This Happens in Real Systems

This specific pattern—harsh penalties and brittle inputs—appears frequently in professional software development, not just beginner scripts.

  • The “Fail Fast” Misunderstanding: Developers often implement “fail fast” strategies (resetting state on error) to ensure data integrity. However, applied to a game or UI, this becomes user hostile.
  • Developer Bias: The coder knows the constraints (1 to 5 seconds). They forget the user is flying blind. This is the “curse of knowledge,” where the creator assumes the user has the same context they do.
  • Lack of Defensive Programming: Beginners (and sometimes seniors under deadline) forget that users will intentionally or unintentionally break input flows. Without validation, the flow is linear and fragile.

Real-World Impact

If this were a deployed application rather than a hobby script, the impact would be severe:

  • High Churn Rate: Users who lose all progress due to a single mistake will quit the app immediately. The retention metric would plummet.
  • UI Lockups: Users entering non-integer text causes the program to hang or crash. In a web context, this is equivalent to a 500 Error.
  • Zero Learnability: The user is told “Nope” without understanding why they were wrong (e.g., were they too high or too low?). The user gains no skill from the interaction.

Example or Code

Below is the specific block from the submission.

import time
import random

score = 0
while True:
    print(f"Guess how long you wait from this message to the next one. Your score is {score}")
    random_number = random.randint(1, 5)
    time.sleep(random_number)
    guess = int(input("Okay, Guess now in seconds: "))
    if guess == random_number:
        print("Good job")
        score = score + 1
    else:
        print(f"Nope, it was {random_number} seconds")
        score = 0

How Senior Engineers Fix It

Senior engineers improve code by focusing on resilience and incentive structures.

  1. Input Validation (Defensive Coding):
    Wrap input conversion in a try/except block. If the input is invalid, ask again rather than crashing. This creates a forgiving user experience.
  2. Smoothing the Difficulty Curve:
    Replace score = 0 with score = score - 1 (or a small penalty). Alternatively, implement a “lives” system. This maintains player engagement despite failure.
  3. State Isolation:
    Move the game logic into functions (e.g., get_user_guess(), run_game_loop()). This reduces cognitive load when reading the code.
  4. User Information:
    Tell the user the range (e.g., “The number is between 1 and 5”).

Why Juniors Miss It

Juniors focus on the happy path—the scenario where the code works exactly as intended.

  • Algorithmic Focus: They obsess over the if guess == random_number logic and forget the ecosystem around it (inputs, edge cases).
  • Lack of Empathy for the User: They don’t anticipate that a user might not want to lose 10 points because of a typo.
  • Fear of Complexity: Adding try/except blocks or input loops feels like “advanced” code, so they stick to linear execution, not realizing that robustness requires explicit error handling.