Search Unity

When to make a separate object or class/script? Help me think like a programmer! (Example in text.)

Discussion in 'Scripting' started by SlimeProphet, Jan 30, 2021.

  1. SlimeProphet

    SlimeProphet

    Joined:
    Sep 30, 2019
    Posts:
    50
    I don't know how to decide when to break things up.

    I'm making a color-sorting game that has the following things (simplified):
    • Colored boxes (can be moved around)
    • A box dispenser (boxes exit from here at regular intervals and fall to the ground)
    • Slots for the boxes (you move the colored boxes into these slots in the correct order to "win")
    • Layout (where the slots go on the screen)
    • Solution (the logic that figures out what colors you get and what order they should be to "win")
    • Demon (an enemy that knocks down the boxes you've placed)
    • Score
    • Timer
    • Settings
    Right now I have a separate object and script for each of these. The boxes also have a "draggable" script that allows them to be moved and either dropped in the air or placed into a slot. Game flow (start, reset) is currently inside the "Solution" script.

    I'm trying to do this right by "separating my concerns." But it feels wrong and needlessly complicated for such a simple game. I wonder if I should basically just lump almost all the game logic into one script, with only minimal communication between the boxes and that script. The boxes would have a movement script, and then every time the player lifts up the mouse button, the box would tell Game its new position---and that would be about it.

    What's the right thing to do? Keep all this separate, and even make a new GameFlow object? Or combine the base logic into one Game object until there's some reason not to?
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,689
    This is a reasonable initial approach. The problem is you have listed the parts, but you haven't really listed how they interact, and even if you did, it's still sorta up to you how to organize it.

    Only YOU will know how to organize it, and the only way you can tell is to do the work.

    I recommend this: first, develop ALWAYS with source control (such as git), and every time you get even the slightest thing working, commit those changes with good commit messages.

    Then move to the next thing, commit, etc. And I mean even trivial stuff, and give yourself good commit messages. Good commit messages are not for anyone else but you. Be kind to your future self.

    That way as you move forward you will have fine-grained history of how things evolve. For instance if you start with it all in one script, you can then decide "okay, this works great, but this script is getting hairy. How about I pull out this part into its own file," and you work on that.

    As you do that "pull apart work," you might realize "oh crap, this isn't so good after all because of X,Y and Z not liking being separated..." One push of the git button and you are instantly back to the way it was just before you tried, nothing broken, ready to try again.

    This lets you trivially try breaking it up a different way, or else creating another system to aid in breaking it up.
     
  3. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    1,997
    Putting things in the same or different scripts doesn't really matter. I usually put box-creation, layout, problem info...in one script since it seems related. Enemy scripts and box-changing scripts go on those objects since Unity likes it that way.

    The real idea is not mixing "concerns" anywhere. The part that picks box colors can just choose color# 0-6. It has enough to worry about without setting the real colors. (including if it's hidden, or the color-scheme for level 11-20 being different... .) But being strict about that is often impossible (or just really, really, awkward). After experience you get a feel for it.
     
    Kurt-Dekker and Bunny83 like this.
  4. makeshiftwings

    makeshiftwings

    Joined:
    May 28, 2011
    Posts:
    3,350
    I think the way you're going now sounds pretty good. It's always better to err on the side of over-separating things than under-separating, in my opinion. It's much easier to shove two things together than it is to separate something monolithic into its correct parts if you change your mind down the road. I will say that the idea "This would look neater if I had just one giant script instead of separate ones" will vanish really quickly the first time you work in a team and have to read someone else's one giant script. ;)
     
  5. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    1,997
    Suppose the Monster script has lines like
    Board.center.x+Baord.halfTile*9
    ,
    if(Levels.level%2==0)
    , and
    Player.BoxCollider.layer
    . Likewise the Player script has stuff like
    Monster.M.getChild("eye").material.color=
    and
    Score.S.scoreText.text=(deaths*10+boxes*2)+"0"
    . Everyone is sharing their variables and using everyone else's specific details. You've basically got one big program, even though it's split into several files.

    Having the program in parts in a useful way means things like
    Board.tilePos(x,y)
    , where it does the math, or
    Score.addBoxesDestroyed(1)
    , which displays the score however it wants. That's old-fashion Object use -- each part keeps its details to itself, providing general functions: "tell me to do X" or "ask me about Y".

    Sure, having a program in several files makes it a tiny bit harder to grab other people's details -- you need Board.center instead of just boardCenter -- but not much. Multiple files can be great for fancy testing, or re-using only parts in a new program. But by then you'll want to completely rewrite you old code using everything else you've since learned.
     
    Kurt-Dekker and SlimeProphet like this.