Do you plan out systems or designs?

Something I found myself doing much more frequently than in past months, is spending an hour or two planning out the design of a system (typically larger ones) in docs or writing out huge comment blocks. I’ve been looking into flowcharts as well, which might make it easier, but I’d like to know if you plan out your systems, and how do you go about doing it?

I’ve found documenting these systems help for longer-term projects where you might have more programmers join the team and use these systems has been really great. I’d like to continue this, but I’d also like to “optimize” or “standardize” how I do these things. Do you plan out your systems? If so, what methods do you use to do this?

3 Likes

If I find myself writing a diagram, I switch gears and try to simplify it down enough to not need a diagram.

It usually means reframing my problem, and reframing a problem correctly can be much harder than writing the more complex system.

2 Likes

There are two ways I can interpret your post, so I will try to touch on both by describing how I structure my code base and how I attempt to cleanly document its behavior.

Project structure

The way I structure my project is by splitting pieces of logic into their own isolated (Local)Scripts and attaching BindableEvents and BindableFunctions to them which will be used to interact with those systems. I try to keep the responsibilities of each piece of logic to a minimum and to the point, so it becomes easier to learn what each piece does.

My first step when starting a project is always to ask myself which technical pieces of logic do I need? I then write those down and draw connections between them. For example, an ‘achievement system’ will need to access the player’s data, stored in the ‘player data system’. So, for example, when writing a team-based racing games with randomly generated maps, I would instantly write down the following pieces I need:

  • Game state system
  • Player data system
  • Map generator system
  • Achievement system
  • Team system

I know that the game state system will need to tell the map generator system to generate a map, so for that I attach a new BindableEvent or BindableFunction to the map generator system. It will then act as a ‘method’ of the map generator system. I repeat this for all other interactions. I also add BindableEvents that act as ‘events’ that will broadcast important changes (such as: a map has been loaded, a game has ended, etc.)

Documentation

The project structure I just described actually helps make documentation very straight forward for me.

When you expand a (Local)Script in the explorer you will see all of its BindableFunctions and BindableEvents. Their names tell you what they do, and their implementation can of course be found inside the script. This way the game explorer is essentially turned into a ‘global overview’ for documentation, assuming that logic is not spread across many different places. It helps give unfamiliar developers a vague idea of what everything does.

As for the documentation within scripts, I make sure to add a couple comments for each BindableFunction and BindableEvent explaining the details of what exactly is happening. The game hierarchy already tells a summarized story due to the different BindableFunctions and BindableEvents and their names, so the contents of each script turns into a ‘chapter’ of sorts, listing only the details.

If there are any systems that are very complex and/or hard to comprehend, I do end up writing external documentation for them. I usually do this in the form of a Google document or a Confluence page. I can then add a comment at the top of the script with a link to the document where I add diagrams and/or images as well.

2 Likes

Surprisingly not, despite my number of large scale works.

More often than not, rather than planning systems, I just fragment the idea of what that system is into its constituent parts; a large system can often be represented by a chorus of smaller systems. Using this knowledge, a lot of my system design is very discrete, but never really planned out and done to a blueprint. It’s kind of built on an as-needed basis. When the need for a new component comes up, I do a little planning to try to scale it as best as possible so that the component in its own unique context can scale, but I don’t do it with other components in mind very often.

Now that said, I do make very large comment blocks describing something’s purpose and its semantics if need be, but at that point, I’m doing it because I expect to drop the code and come back to it in 5 years or something insane like that. I write my code for future me to comfortably read.

An unintended pro of this methodology is that my systems are very portable. It’s quite easy for me to just pick out bits and pieces from one project and seamlessly transplant them into another. I have a whole suite of personal libraries that I can just drag n drop into projects that are incredibly powerful. I may actually release them to this forum rather than the pub forum.

2 Likes