How to create Clean Code - CodeAlpaca

Code. When you make code you want to have 3 qualities.

  1. Working code (Does what you want)
  2. Efficient code (Doesn’t lag / is flexible)
  3. Clean code (organized nicely + flexible)

I want to give you examples of clean code and how to implement fundamentals into how you code to make it better.

For Working and Efficient code I can explain a long list of things that you’re able to do, but truthfully talking about it can only get you so far. Most of it is best learned through experimentation and willingness to learn.
Also, these aren’t complete rules, but guidelines that once you get good enough, will learn when it’s ok to break them.

Clean code is also something that just takes practice with good habits, but it is something that can be somewhat taught (and will usually result in more efficient code).

There will be a summary of all this at the bottom with quick bullet points, so if you’re not going to read all of this, please read the bullet point version.

(Stick around to the end as I judge your code)


Step 1

Step 1: Wires

Backwards Wires

Wires are the connection between Blocks/Behaviors in Flowlab. They can often jumble up and start to make things very confusing. There are 2 main points about wires that you need to pay attention to.
Here are 2 pictures of code, which one do you think is cleaner?


So, what’s the difference between these 2 examples? The answer is the behavior placement, which in turn, affects the wires.
Backward wires often make things confusing because the order of the behaviors is often messy. So here’s another example.

Screenshot 2023-04-19 2.30.01 PM

See how much better the 2nd one is? Sometimes backward wires cannot be avoided like the blue wire in the example above, but you want to limit the number of times your wires bend backward.

Intersecting Wires

I’m going to show 2 pictures, and once again, tell me which is cleaner.


Just like backward wires, there are some cases that can’t be avoided. But typically, these cases aren’t that bad.

The placement of your behaviors determines how your wires are, and this is the perfect segway into Step 2, Behavior Placement


Step 2

Step 2

Behavior Placement

Ok so this was shown a little bit above, now I’ll go more in-depth about it.
Placement has 3 steps to it,

  1. The amount of space between behaviors.

  2. Placement relative to connecting behaviors.

  3. Grid placement

Before I show example images I want to say this. Almost always, behaviors should move forwards. So if a behavior moves up, it should also move forward. There isn’t often a good reason to move it back.

Here are 3 images to demonstrate the space between behaviors

So with this first image, we can all agree there is just way too much space taken up here. It’s ridiculous. However, there is some debate between the next 2 images about which one is actually better.


Personally, I think that the one that takes up less space is better because I don’t think the readability of the code is any worse, though others may disagree on this.
But, as a rule of thumb, there should never be enough space between behaviors to fit another behavior.

Placement (in relation to connected behaviors)

You will not believe how often I see this. Behaviors are literally covering each other. This is a horrible thing to do, just please never do it.

It’s really not hard to properly space them out. This rule is basically just to make sure behaviors never touch, I cannot think of a situation where it would be better to have them touch.

Grid Placement

So this isn’t as important as the other “rules”, but it’s still important.

This is equivalent to Mixels. Why would you not organize things to be in a neat grid???
Here’s another example, people often do this with bundles.


Screenshot 2023-04-19 3.13.26 PM

Give me a single good reason to place behaviors like the first image.
Keeping things in organized rows make things easier for our brains to process and is just faster because you know exactly where to look, and don’t need to search the entire screen.

Once again a perfect transition into Step 3, Bundles


Step 3

Step 3

Bundles

Bundles. I’ve heard so many people say “well, my code was small, then it just expanded”. That’s an excuse. Do you not plan ahead or know what you’re making?

If you have some code for running, bundle it. If you make attacking code, make a new bundle for it.

Bundles should be used when they

  1. Makes the code easier to read. Let’s say something took 5 steps to complete, maybe some of the steps could be bundled and connected via inputs/outputs. Having a ton of behaviors on screen at once makes things more difficult, I don’t care if it “works for you”.

  2. To separate different features. [Movement] [Attacking] [Health] [Coins]

All those things should be bundled separately because the only thing they have in common is that they are in the same object. And even if things are “related”, if it’s a Global value there’s a decent chance it should just be in a different bundle.


Step 4

Step 4

Other

Evaluating

If you ever use more than 5 of the same behavior, reevaluate what you’re doing, because it’s probably something wrong.

What’s a better way to do this?

Screenshot 2023-04-19 7.17.13 PM

This effectively has the exact same result because the global will update in all of the objects you were sending messages to. However, if you’re only sending 3 messages, creating an entirely new global for that would not be better.


So something seems ineffective here too.

Screenshot 2023-04-19 7.21.25 PM

Router is a behavior that is often forgotten but is quite a useful behavior that should always be in your mind.
(Also what I showed is still wrong, because Router has an option called “Randomize Next Route” which will output randomly, giving the same result of a Random except with the numbers aren’t ranging from 1-5)

Naming

If you ever read Name of The Wind, you know names are important. And if not, you’re excluded from the inside joke.

This one is pretty simple, name things effectively.
This means if you create an Object, name it.
Examples

  • Name Objects. If it’s a parent object (whose entire purpose is to be a parent object) something like “PARENT Enemy”. Just don’t leave it “New Object 123”
  • Name Messages. Leaving it “Hello”, “Hello1”, etc is a sin. It saves you 2 seconds and costs you 10 minutes trying to figure out what it meant 2 weeks later.
    Be careful how you abbreviate things. If you do “IF 1” “IN 1” it’s hard to know what that means. (I did this before, it means “Idle Off 1”, Idle On 1”. Just spell it out properly”
    Also, don’t be weird and name it “BOOM!!!”, “Awesomeness”, or something else random.
  • Name Globals. Similar to Messages, just properly name it.

So to give bullet points about everything discussed (once again, these aren’t hard set rules, just general guidelines. As you improve you’ll learn when you can break them)

  1. Wires
  • Backwards Wires: Smaller isn’t always better. Keeps things moving forward
  • Intersecting Wires: Avoid them, often caused by poorly placed behaviors.
  1. Behavior Placement
  • Space between blocks: Avoid having enough space to fit another behavior in between.
  • Placement: Always try to move forward, and avoid going backward. (basically, straighten things)
  • Grid Placement: Try to keep things in line with each other. (mainly on X axis)
  1. Bundles
  • Readable: Use it if it makes the code more readable (general rule of thumb, if there are over 20 behaviors on screen, it should be bundled).
  • Separation: Using it to separate different things like walking and attacking.
  1. Other
  • Evaluate: If you use 5 of the same behavior, rethink what you’re doing, because it’s probably ineffective. Flowlab is a good software, so if there is something that seems like it should be easier/cleaner, it probably is.
  • Naming: Just name your objects, messages, and globals effectively. Don’t leave it as “Hello”, “New Object 42”, etc.
”Tools’

Advanced Switch

This is how people normally turn things off. It’s rather bulky and if you needed to expand it to turn off during other things like attacking, dashing, etc. it would become very large and hard to read.
I am the biggest (and only) fan of the Advanced Switch. I haven’t seen anyone else use this, but it’s just a normal switch, but concealed inside of a bundle, making it visually easier for you and making it much easier to adjust/add to.


Isn’t that so much better? Is easily adjustable and makes things very clear to work with.


WARNING: I will be a bit harsh for comedic purposes because if it was just a text wall no one would read this, so I will make fun of you. I am sorry.

Judging others code

So I’ll be taking a look at the code from Galactian, Kiwileaf, Puginarug, Sup3r, Recryptech, JR01.
Why them you may ask? Because they probably already did some of it so I won’t need to do as much work as other new users. (if any)

And when I judge these people’s code, I’m not saying I code so much cleaner. Just look at the code in some of my past projects. Everyone makes mistakes, it’s just about minimizing them and actually improving. If you look at the code that I did in Beyond The Glass compared to my most recent project Poetry For Neanderthals, there’s a big difference.

I will look at my old code later, but for rn, I don’t want to cringe at my past self


Galactian

In a galaxy far far far far far far far away, someone made some code. Galactian is a pretty competent coder, but I have noticed at times that the code isn’t the cleanest, so let’s “fix” that.

Let’s take a look at the game BloodLust

This code is inside the player object

Already looking at this there are a few things wrong. He’s trying to hide a death star beneath all that.

  1. Message is labeled “Hello” are other abbreviations
  2. Backwards/Intersecting Wires
  3. Improper Grid Placement.

Screenshot 2023-04-19 7.50.11 PM

Here I just reorganized it a little and named the “Hello” Message. I don’t know what the other Messages are meant to be so I left it alone, but you get the point.

Here I slightly reorganized the grouping of things and bundled things.

Here I removed the backward wires and cleaned up the intersecting wires

What Galactian did wasn’t wrong at all, it was fine and you could argue that I spend a few minutes fixing it up, but the purpose of practicing good habits isn’t to code and fix it afterward, it’s to instinctively code cleaner. The cleaner you code, the faster you’ll code in the long run.

—- - –

Kiwileaf

Kiwi is a decent coder, just make sure not to talk about his past. I have never looked at Kiwi’s code before, but from the little bit I have seen and know about him, I don’t think it will be perfect. (And that’s ok, I can take a lot of my older code and say the exact same thing)

I’ll be looking at his game Factured Worlds, made for the 2023 Flowjam.

I don’t recommend playing this game rn, it’s being remade. And hopefully, that means the code too sick burn, dab. I’m so lame lol, I feel like a 90 yr.

This code here, seems perfectly fine, so that’s a good sign. (maybe the messages could have been going up so the wires weren’t as long. The position of the Once and the things connected feel a little weird, but that’s nitpicking)
Also from this, I can tell that Kiwi likes to build with a little more space.

Here everything is organized very well (Aside from the Full Screen). All the separate functions are in bundles, which is very good.

I was worried that I wouldn’t be able to use this as an example for a moment, but here we are.
(Also once again, notice his use of space. I prefer slightly more compact, but it’s a personal preference from habit, and this way of having slightly more space is very good.

So here are the problems

  1. Backwards/Intersecting Wires
  2. Improper Message use
  3. Fundamental Coding error

(What I mean by this is that besides reorganization is that ineffective methods are probably being used, though I won’t fix this and will just focus on rearranging the code)

Screenshot 2023-04-19 11.11.12 PM

This fixes the issues with 5 messages. The messages are all being sent at once to different objects, so a single global has the exact same effect

Screenshot 2023-04-19 11.26.21 PM

I removed this entirely because it was redundant. The player already has X, Y globals, so there is no need for these messages.

Here I rearranged the behaviors to lessen the intersecting wires and backward wires.
I removed all the connections to the NOR gate and instead had the switch turn itself off and directly connect to the NOR (This works because the Proximity had to output for it, but that means the switch is on outputting).

It’s something I like to call “Bottle Necking”, meaning to have all the wires lead to 1 point (The Switch), and expand off of it, which often lowers the wire count it improves things.
I will say, the original layout was nice and square but looked way more complicated than it needed to be. There is an argument to be made that it was fine if the NOR was fixed.

However, I won’t even talk about this mess. (In this case, Messages or a Staircase formation might be best)
You can try to say the switches are there to redirect the wires (which is a real thing), but at least use a behavior with 1 input and 1 output so it’s smaller.

Puginarug

Best known for getting 2.9 for the Winter Flowjam and using an 8-bit pixel art style.

Well, I’m going to be quite frank here, this is spaghetti. He knows it, I know it, everyone knows it. It’s almost as bad as Agent Y

Ok, here are the problems

  1. Distance between behaviors (meaning wires often intersect and travel incredibly long distances)
  2. Behavior Islands. These are groups of behaviors that are mostly separated but are connected by pretty much a single behavior. This means that you can probably just bundle it and give it an output. (also just random single behaviors not connected to anything)
  3. Backwards/Intersecting wires.
  4. Improperly labeled Messages (just called “Hello”)
  5. There’s more I can list, but I’m going to spend a while fixing this.

Screenshot 2023-04-20 12.05.03 AM

I am legit doing gods work to this code. I bundled all of it neatly, and it works exactly the same. It took me 10 minutes of work with code I don’t understand to clean it, imagine how fast it should have been for him.

This should have been bundled, the only reason it wasn’t is because the Always was connected to code a mile away. Also reorganized it to remove intersecting wires and wasted space.

Completely reorganized it, removing many backward and intersecting wires. Also removed a ton of wasted space and separated this into 2 bundles because there was only 1 connecting link.

Reorganised to remove backward and intersecting wires, as well as remove a ton of wasted space. This is the 2nd bundle connected to the code shown above

Screenshot 2023-04-20 12.18.12 AM

A simple Misc bundle for things that didn’t belong anywhere else.

I should get paid for this.
Jk, but this was a mess of code that I would expect from someone using Flowlab for 3 months, not almost an entire year. (My own code wasn’t great at a year (4 months ago), about it wasn’t nearly this bad)

  • – -

Sup3r87

A user almost as famous as myself inside the Flowlab community, known for his love of space games and more space games + an unhealthy addiction to puzzlers.

While he may be struggling with Shapez.io withdrawal, he does know how to code (excluding lists :sob:) pretty well.

Screenshot 2023-04-20 12.33.27 AM

Excellent sign so far. I have no idea why he didn’t move it down slightly, but hey, it’s not pug’s at least (sorry)

I’m noticing a trend. Have nice neat bundles, then crazy code (no offense). Kind of like the trend of somehow Sup3r making it into Flowlab games.

Problems with this

  1. Way too much space between behaviors
  2. Backwards/Intersecting Lines

Rearranged things making sure to keep the Frame Order of things. I’m not happy with this, but I think it’s because Prime Number coding could simplify this. But, I’m not rebuilding the whole thing so I’ll leave it like this.


Recryptech

A user almost as famous as BitWit until his sudden disappearance. Winner of a single Flowjam and has yet to reclaim the title (ok that was too far, I’m sorry, I love your games uwu).

Anyways, great coder, he has said he made some messy code before, so idk.

Ok so I looked through the code, and I would just feel bad criticizing it. I would just be making things up out of thin air. Honestly props to you for being so clean, Mr. Clean

People say JR01 is the bundle guy, but I think it’s Recryptech, just looking at his code reminds you that you need more lol.

Also, this code was for a Flowjam, so it’s not like he was working on this for a long time.


JR01

The final boss himself is not him. It’s grazer, you really thought it was JR?
A user that as a wee lad I looked up to, and now I’m taller than him, so it’s a weird situation. He’s like 5’3 and I don’t know how to feel about that.

Besides that, he’s an awesome game that does a lot for the community, best known as the anime dragon guy who you can @ for coding help. Wait am I a furry?

Ok, so pretty much perfect, really good use of Bottle Necking (Bringing it all to 1 point, then expanding from it), as can be seen at the Filter and Expression. It’s mostly because it literally has to be coded like the, but it’s still good.

There are some backward wires, but they’re used pretty neatly, but I will try to improve on this

Ok, it’s a bit of an improvement. Rearranged the behaviors to remove a ton of intersecting wires, and kept some of the backward wires because extending them would cause too much space and would actually be messier. The only real way to improve this would be to bundle all the Keyboard into 4 separate bundles. (80% sure Recryptech would have done that)

I was going to end this by looking at my own code, but this took a while to wait and I’m insulted you just scrolled down to the bottom to heart this.

21 Likes

Congratulations, you get one free ticket to the Flowlab Out Of Context topic!

2 Likes

Also I think you’d have a stroke if you ever saw my code

2 Likes

Just a little note with the code in my games. I ALWAYS bundle things. It makes things so much easier to find and I also like to keep my code organized so there are not too many wires stretched out and bunched together so when I have to edit something its not all over the place. If you were to ever see unorganized code in my games, it’s not from me. Example being, somehow in my other game I was making, when I copied a bundle over to another object, the code got jumbled up.

I remember when I first started making games here, my code was all over the place and I found it super hard to find what I was looking for. I look back at those old games wondering what in the world I was thinking while making it.

With that being said, please listen to what @CodeAlpaca is saying. It will really help in the long run, there were so many things I was able to fix just because I kept my code tidy.

No seriously, listen. I go into some of your games and it gives me PTSD.

6 Likes

I did warn you lol

2 Likes

I have a lot more quotable stuff in there…

3 Likes

Ohh, and another thing. If your having trouble with your game and you need someone to look into it. It will be very hard for them as everything is all over the place.

3 Likes

Don’t worry, it’s all going to end up there one way or another

1 Like

Here’s another good one

2 Likes

Glad you didn’t review my coding, lol.

I use older techniques that make everything very messy. I try to be organized, but later in development I start to lose motivation. So I pour whatever I have left in getting the game done, than perfecting the code organization.

3 Likes

The bundles really help when you need to fix a problem or even just tweak some settings. It speeds up the dev time aswell since you know where to look immediately and not having to look at a wall full of code you dont even want to change.

About putting the behaviors in one line…well… im still learning haha
Edit: thank you ofc alpaca. Im sure its going to help future forum visitors

1 Like

I hope it helps, I’m still learning it a bit myself. It’s not something you really think about, so I’ve only really started getting into over the last month or so, and before that I just used general habits like bundles.
(Would also make solving help requests much easier lol)

2 Likes

Everyone just needs to use bundles more, it’s not messy if you can’t see it.

4 Likes

But seriously true, I didn’t start using bundles until after my first game, Drive Nero, but you will see me using them more and more from each game and Flowjam. Now a lot of my code is much smaller from bundling, but more so from expression coding nowadays. Definitely compare my games like Drive Nero, Escape the Rewind, The Witch in the Woods, Pack-It! and Camera+.

Bundle when you can but don’t focus on it too much and just try to keep your code evenly spaced and all in one screen. Even still, there are times that I’m not satisfied with the code (like the area Alpaca found lol) because I make things in a rush in a Flowjam. A lot of my games and examples uses a mix of new and old code (if it works, import it!). I would definitely bundle the keyboard behaviors together, but also find a way to fit more of it into a single expression later on.

5 Likes

This is all amazing advice—thanks for writing it out!

On a side note I will mention that personally I’m starting to move away from bundles (except in specific cases) since they seem to cause frame timing issues and also make it harder to tell what order behaviors will be executed in.

1 Like

@thebrickccentric, there’s frame timing issues because the positions inside the bundle is relative to the position outside the bundle. Bundling is definitely not ideal for frame order stuff, but I do have an input gate bundle that may help remove the timing issues. @CodeAlpaca also has a lot of experience with this bundle too for similar reasons.

{"data":{"behavior":{"v":"2","nodes":[{"inputCount":2,"outputCount":1,"name":"Input Gate","behaviorType":"logic.NodeGroup","x":720,"y":-32,"group":"","id":"a23882078ccc2d42","isMenuItem":false},{"inputCount":3,"outputCount":1,"name":"Switch","behaviorType":"logic.logic.Switch","x":450,"y":0,"group":"a23882078ccc2d42","id":"a23882082739bc48","_startVal":0,"dataType":2},{"inputCount":0,"outputCount":1,"name":"Bundle Input","behaviorType":"logic.NodeGroupInput","x":270,"y":0,"group":"a23882078ccc2d42","id":"a238820879e77248","portId":"a23882078ccc2d42i0","tag":"A","dataType":2},{"inputCount":0,"outputCount":1,"name":"Bundle Input","behaviorType":"logic.NodeGroupInput","x":270,"y":64,"group":"a23882078ccc2d42","id":"a238820861a05e4c","portId":"a23882078ccc2d42i1","tag":"B","dataType":2},{"inputCount":1,"outputCount":0,"name":"Bundle Output","behaviorType":"logic.NodeGroupOutput","x":990,"y":0,"group":"a23882078ccc2d42","id":"a2388208e818664e","portId":"a23882078ccc2d42o0","tag":"out","dataType":2},{"inputCount":3,"outputCount":1,"name":"Switch","behaviorType":"logic.logic.Switch","x":630,"y":0,"group":"a23882078ccc2d42","id":"a238820897fb684b","_startVal":0,"dataType":2},{"inputCount":3,"outputCount":1,"name":"Number","behaviorType":"logic.logic.Value","x":810,"y":0,"group":"a23882078ccc2d42","id":"a238820804e99746","startVal":1,"tag":"","roundMode":1}],"links":[{"input_id":"a238820897fb684bi2","output_id":"a23882082739bc48o0"},{"input_id":"a23882082739bc48i1","output_id":"a238820879e77248o0"},{"input_id":"a23882082739bc48i2","output_id":"a238820879e77248o0"},{"input_id":"a238820897fb684bi1","output_id":"a238820861a05e4co0"},{"input_id":"a23882082739bc48i2","output_id":"a238820861a05e4co0"},{"input_id":"a238820897fb684bi0","output_id":"a238820897fb684bo0"},{"input_id":"a23882082739bc48i0","output_id":"a238820897fb684bo0"},{"input_id":"a238820804e99746i1","output_id":"a238820897fb684bo0"},{"input_id":"a2388208e818664ei0","output_id":"a238820804e99746o0"}]}}}

image

4 Likes

Yeah, exactly, and that’s why I don’t bundle much anymore.
(On another side note doesn’t the code you pasted above essentially function the same as having only one switch which the A input turns on and the B input goes through the switch and then turns the switch off? Though the code in the picture might work differently)

1 Like

No, because the bundle is supposed to output once all the inputs have been seen, no matter the order. So input A turns on Switch A and input B turns on Switch B, while both inputs A and B are trying to go through the layers of switches. The last switch is used as the activation and resets all the other switches. The picture above would be a good example to use this bundle, because you can’t actually know which mailbox will be activated last if they are coming from other objects in the level.

Also why it works in this specific order:

The first switch relies on input A. So if input A is activated, the switch will go in it’s input order (off, on, in) making it turn “on” before “in” is used. For the other switches the “on” input is activated at the same time as the “in” of the first switch, so those other switches are turned on before the first switch outputs.

The order can be modified for more inputs, different input types, change if the switches reset and even able to output a specific input. If you want to reset the inputs, just make sure the last switch is resetting the other switches. I used this bundle more when I try to code a lot of things in the same frame.

2 Likes

Update: I redid this code because I was just not satisfied with it lol,
here’s what it looks now:

And for the keyboard behaviors:

2 Likes

Could you judge my code? I’d like to know how I’m doing.
If you can’t find any games here are a few that have some code:
Flowlab Game Creator - Hovercraft Trainee (old game)
Flowlab Game Creator - Robo-Rumble (new game, in the works)
Flowlab Game Creator - Pixel Noise (somewhat newer project)

Edit: For the love of god I just realized how BAD I made Hovercraft Trainee… There’s literally like 20 objects just for the different skins when I could’ve used animations. I think I knew this, but I used separate objects anyways because I wasn’t that good at coding yet.

2 Likes