Writing Better Code

This is the place for discussion and support for LunaLua and related modifications and libraries.

Moderator: Userbase Moderators

Forum rules
Before you make a topic/post, consider the following:
-Is there a topic for this already?
-Is your post on topic/appropriate?
-Are you posting in the right forum/following the forum rules?
aero
Palom
Palom
Posts: 4787
Joined: Fri Mar 28, 2014 2:51 pm

Writing Better Code

Postby aero » Fri Sep 30, 2016 10:28 pm

If you've clicked into this thread you want to write better code. What is good code? Good code is easily maintained, easy to update, and easy to read and understand. This will be as general as possible to cover as many scripting situations as possible, and will be updated as I see things come up in this forum that need to be covered.

Starting with questions you should ask yourself to consider code quality:
  • Can I easily explain what is going on with this part of my code?
  • If a fellow programmer was reading this code, how long would it take for them to understand what it does?
  • Are any parts of my code repetitive, or recurring with only slight changes?
  • Does my code work under specific circumstances, or universally?
  • Is there a more efficient way of doing this?
  • Am I using good practices?
Let's take these one by one.

Can I easily explain what is going on with this part of my code?

If you can't easily explain what is going on, it will be hard for people to understand your scripts. Also, it will be harder for you to debug your own scripts if you are unable to identify where in your code you went wrong. It will be much harder to continue working on your script after taking a break from it, so it is best to make lines shorter and straight forward. Ask yourself this frequently. Lastly, if you can explain it then do it. You can insert comments into your code by adding a double dash (--) before a line to describe what is going on. You don't have to go into detail for every single line, but comment as much as possible. Descriptive variable names are always a benefit too.

If a fellow programmer was reading this code, how long would it take for them to understand what it does?

It would be much to ask to make your code understandable by a novice, however you should make your code be able to be interpreted by those at your same skill level. To answer this, share your code as you write it with others and see how well they're able to interpret it. If people start getting confused, try going back and seeing if you can make any edits to make your code clear. Helpful insight can come from this so don't be afraid to share unfinished work, or even broken code. You'll be able to write better code in the future this way and learn to solve problems on your own the more you ask early on.

Are any parts of my code repetitive, or recurring with only slight changes?

If yes, this is a sign of inefficiency. Try identifying where the slight change is, and reducing your code to a single chunk with that bit as a variable. Here's an example in pseudo code:

Bad

Code: Select all

if frame = 0 then
	drawimage(x, 0, 32, 32)
elseif frame = 1
	drawimage(x, 32, 32, 32)
elseif frame = 2
	drawimage(x, 64, 32, 32)
elseif frame = 3
	drawimage(x, 96, 32, 32)
elseif frame = 4
	drawimage(x, 128, 32, 32)
...
end
Good

Code: Select all

drawimage(x, frame * 32, 32, 32)
As you can see, the only thing changing in the first code was the second number, so instead of making a long if chain that checks the frame constantly, it can be reduced to one line of code that will always be accurate without checking. Look for patterns, like the number increasing by 32 for each frame in this example, to see where you can fit a variable like this. One line of code is easier to update if need be rather than x amount of lines. Less is more.

Does my code work under specific circumstances, or universally?

The more you can reuse code the better. Code that can only be used in specific circumstances can be easy to lose track of and leaves you with bloated blocks that quickly turn into spaghetti code. Always assume an error will be thrown so make the code robust to handle anything that's thrown at it. If a negative number will break everything, just slap a math.abs() on the variable to knock that out as an example. If you have to be careful with what you send to your functions like that and make different blocks of code for different situations then try going back and revising instead of adding new code.

Is there a more efficient way of doing this?

This is similar to the repetitive code question and the example used. The math library can help knock out a lot of unneeded guess work when it comes to numbers. Most of the time you will be working with numbers so learn what you can do and take advantage of it. Doing the math can make your code more accurate than it is, and more universal as well. Take this code as an example:

Code: Select all

function updateOxygen(timer)
	if((timer < 1956) and (timer > 1755)) then
		oxygen = 10;
	end
	
	if((timer <= 1755) and (timer > 1560)) then
		oxygen = 9;
	end
	
	if((timer <= 1560) and (timer > 1365)) then
		oxygen = 8;
	end
	
	if((timer <= 1365) and (timer > 1170)) then
		oxygen = 7;
	end

	if((timer <= 1170) and (timer > 975)) then
		oxygen = 6;
	end
	
	if((timer <= 975) and (timer > 780)) then
		oxygen = 5;
	end
	
	if((timer <= 780) and (timer > 585)) then
		oxygen = 4;
	end
	
	if((timer <= 585) and (timer > 390)) then
		oxygen = 3;
	end
	
	if((timer <= 390) and (timer > 195)) then
		oxygen = 2;
	end
	
	if((timer <= 195) and (timer > 0)) then
		oxygen = 1;
	end
	
	if(timer <= 0 ) then
		oxygen = 0;
	end	
end	
Doing the math leaves you with this:

Code: Select all

function updateOxygen(timer)
   oxygen = math.abs(math.ceil((timer / 65) / 3))
end
This example comes from Prado's water timer. There isn't an exact pattern with the code here, other than repetitive if blocks, so you'll have to pay attention to what you're looking for and see if you can make a math function that gives you the right value every time.

Am I using good practices? -credit to Hoeloe
Optimization is one thing, but there's actually another element to this too: standards and good practice.

There's actually a lot to this, but effectively there are certain standard ways things are done when programming. By no means are they the only way to achieve an effect, but they are standard because they have some benefit over other methods.

Code repetition is a good example. Doing something like this:

Code: Select all

local x = 5;
local y = x*4+3;
local z = y*4+3;
local w = z*4+3;
isn't inefficient, but it does have a problem. Here, you're repeating the same pattern of code 3 times. Now, what happens if you want to change that to this?

Code: Select all

local x = 5;
local y = x*5+7;
local z = y*5+7;
local w = z*5+7;
You COULD go around replacing every instance, but what if it's not all together like this, and instead dotted around a 2000 line file? It's quite likely you'll miss one, and then, at best things will not work as intended, at worst there will be some subtle bug that you won't notice right away.

To solve this, it's good practice to minimize repetition where possible. This isn't the same as optimizing the code - it doesn't make it run faster - it just allows less room for error when modifying the code later. Ideally, you'd do something like this:

Code: Select all

local function myfunc(val)
    return (val*4)+3;
end
local x = 5;
local y = myfunc(x);
local z = myfunc(y);
local w = myfunc(z);
Now, notice that if I want to change what the function does, I only have to edit one location in the code, rather than several at once.

Also note that I've put brackets around the equation. Again, this does not make it run faster, but it removes potential ambiguity in expressions, and makes it clearer what the code is doing.

Basically, optimization is a huge and important step, but good code practice is just as important. I've rewritten programs a lot of times, not because they ran slowly, but because they were difficult to read and understand, so I wrote them with better coding practice.

Also, where the function of some code isn't immediately obvious, comments are your friend.

Any more advice is welcome.
Last edited by aero on Sat Oct 01, 2016 1:49 pm, edited 1 time in total.

Danny
Wart
Wart
Posts: 4001
Joined: Fri Dec 20, 2013 1:12 pm
Flair: aka LMNtals
Pronouns: he/they

Re: Writing Better Code

Postby Danny » Fri Sep 30, 2016 11:30 pm

Fun fact, people also have their own ways of coding/organizing code, and most developers adapt to what they're comfortable with instead of conforming to making carbon-copy, non-unique method. There isn't really a way to "write better code", since everyone's ways on writing code vary. This is a good thing though, because it could make it harder for your code to get manipulated, stolen, or just reworked without your consent, since you would be the one that knows how it works, and others wouldn't.
A good example of this is when everyone tried to modify the Terraria code, but nobody understood it because of the way Redigit codes, and that's kind of a good thing because he didn't want anyone to rip apart and modify the game in the first place.

Emral
Cute Yoshi Egg
Cute Yoshi Egg
Posts: 9891
Joined: Mon Jan 20, 2014 12:58 pm
Flair: Phoenix

Re: Writing Better Code

Postby Emral » Fri Sep 30, 2016 11:38 pm

Syndrilevosse wrote:There isn't really a way to "write better code",
Except there is. It's called code optimisation. If you choose to create a new goomba every frame rather than moving your existing goomba around, there's clearly room for improvement in your code.

Another aspect is readability and how easy debugging your code is. You want your variable names to be something they relate to. "stateTimer" is a much more readable variable than "butt". The latter will not just leave other people, but also yourself confused when you decide to revisit your code after two weeks. Code that could be a few lines long also shouldn't take up the entire screen just because you want other people to get nightmares from reading your code.
On the aspect of debugging, having variables for reoccuring patterns makes your code better by reducing the time spent running around searching for the same formula or number over and over. If you gotta run around your code to find 5 instances of the number 64 to replace it with 96, the only one you're tricking is yourself.

Why would you wanna be secretive as a programmer anyway? Programming thrives on the concept of improving and building off things other people have done. If you write bad code just so other people can't read it, not only are you a dick but you're also gonna run into a lot of issues and fights once you run into a problem you can't solve by youself.

aero
Palom
Palom
Posts: 4787
Joined: Fri Mar 28, 2014 2:51 pm

Re: Writing Better Code

Postby aero » Sat Oct 01, 2016 12:20 am

Syndrilevosse wrote:A good example of this is when everyone tried to modify the Terraria code, but nobody understood it because of the way Redigit codes, and that's kind of a good thing because he didn't want anyone to rip apart and modify the game in the first place.
This is wrong because what people are modifying is decompiled code, not Redigit's code. If Redigit were a competent programmer, and I have no reason to assume he isn't, he would be trying to optimize his code as much as possible so its possible to build his game. If he didn't do that and what I'm saying here, updates would be a nightmare and performance would be shit. In programming circles, optimization and FOSS are widely discussed. What I mentioned above are the simplest and wide reaching points usually talked about in these discussions. Any disciplined programmer can affirm this, and I myself have been programming for five years and I've learned these things through trial and many errors.

Hoeloe
Phanto
Phanto
Posts: 1465
Joined: Sat Oct 03, 2015 6:18 pm
Flair: The Codehaus Girl
Pronouns: she/her

Re: Writing Better Code

Postby Hoeloe » Sat Oct 01, 2016 5:36 am

Aero wrote:If Redigit were a competent programmer, and I have no reason to assume he isn't
Lol.
There is a reason the unofficial development motto of SMBX2 was "gdiredigit"

Anyway, optimisation is one thing, but there's actually another element to this too: standards and good practice.

There's actually a lot to this, but effectively there are certain standard ways things are done when programming. By no means are they the only way to achieve an effect, but they are standard because they have some benefit over other methods.

Code repetition is a good example. Doing something like this:

Code: Select all

local x = 5;
local y = x*4+3;
local z = y*4+3;
local w = z*4+3;
isn't inefficient, but it does have a problem. Here, you're repeating the same pattern of code 3 times. Now, what happens if you want to change that to this?

Code: Select all

local x = 5;
local y = x*5+7;
local z = y*5+7;
local w = z*5+7;
You COULD go around replacing every instance, but what if it's not all together like this, and instead dotted around a 2000 line file? It's quite likely you'll miss one, and then, at best things will not work as intended, at worst there will be some subtle bug that you won't notice right away.

To solve this, it's good practice to minimise repetition where possible. This isn't the same as optimising the code - it doesn't make it run faster - it just allows less room for error when modifying the code later. Ideally, you'd do something like this:

Code: Select all

local function myfunc(val)
    return (val*4)+3;
end
local x = 5;
local y = myfunc(x);
local z = myfunc(y);
local w = myfunc(z);
Now, notice that if I want to change what the function does, I only have to edit one location in the code, rather than several at once.

Also note that I've put brackets around the equation. Again, this does not make it run faster, but it removes potential ambiguity in expressions, and makes it clearer what the code is doing.


Basically, optimisation is a huge and important step, but good code practice is just as important. I've rewritten programs a lot of times, not because they ran slowly, but because they were difficult to read and understand, so I wrote them with better coding practice.

Also, where the function of some code isn't immediately obvious, comments are your friend.

Magician
Volcano Lotus
Volcano Lotus
Posts: 567
Joined: Fri Dec 20, 2013 7:36 pm
Pronouns: he/him

Re: Writing Better Code

Postby Magician » Sat Oct 01, 2016 6:06 am

Just speaking personally, when I'm writing code for anything I'm just working within the limits of my own knowledge. Sometimes there's a type of command or function that does what I want to do better, and that doesn't mean I know what that thing is, and often when I look up a function I get an explanation for what it does conceptually without actual practical uses for it that gives any of it any meaning to me as a non-programmer (not that I'm unwilling to learn).

I'm only barely grasping the concept of something like an array because of messing around in excel, for example, but I haven't yet gotten into trying out lunalua. It's possible that it's easier to understand than I expect, but in general I look around for something that already does something similar to what I want and then modify it, watch what happens, and then tweak it until it works. Optimizing can be far and away from anything I'm capable of if I don't always understand WHY it works. It wouldn't surprise me if other people were in the same boat.

Hoeloe
Phanto
Phanto
Posts: 1465
Joined: Sat Oct 03, 2015 6:18 pm
Flair: The Codehaus Girl
Pronouns: she/her

Re: Writing Better Code

Postby Hoeloe » Sat Oct 01, 2016 6:25 am

Magician wrote:Optimizing can be far and away from anything I'm capable of if I don't always understand WHY it works. It wouldn't surprise me if other people were in the same boat.
I would always always ALWAYS strongly recommend not using code until you understand it. There are plenty of tutorials and resources about to help you learn, and if LunaLua is what you're looking towards, there are a lot of very knowledgeable people who can help.

aero
Palom
Palom
Posts: 4787
Joined: Fri Mar 28, 2014 2:51 pm

Re: Writing Better Code

Postby aero » Sat Oct 01, 2016 1:03 pm

Hoeloe wrote:*snip*
This is all very important indeed; I wasn't sure how to put code practices into words like this. I'll edit this into the OP later on. Thank you.
Magician wrote:Just speaking personally, when I'm writing code for anything I'm just working within the limits of my own knowledge. Sometimes there's a type of command or function that does what I want to do better, and that doesn't mean I know what that thing is, and often when I look up a function I get an explanation for what it does conceptually without actual practical uses for it that gives any of it any meaning to me as a non-programmer (not that I'm unwilling to learn).

I'm only barely grasping the concept of something like an array because of messing around in excel, for example, but I haven't yet gotten into trying out lunalua. It's possible that it's easier to understand than I expect, but in general I look around for something that already does something similar to what I want and then modify it, watch what happens, and then tweak it until it works. Optimizing can be far and away from anything I'm capable of if I don't always understand WHY it works. It wouldn't surprise me if other people were in the same boat.
In order for resources you look up to be of any use, you'll need to write your own code instead of copying down functions so you know what to ask for. Googling tutorials and guides can be almost useless if you don't know what to look for. This is a very big thing with programming is that often times people do run into novel problems so they need to understand what they're doing, and what they're trying to do in order to look up the solution to bridge the difference. Iirc this is heavily discussed in this Google presentation:



Return to “LunaLua”

Who is online

Users browsing this forum: No registered users and 1 guest

SMWCentralTalkhausMario Fan Games GalaxyKafukaMarioWikiSMBXEquipoEstelari