SA-MP Forums Archive
[Tutorial] How to NOT code a bad script? - Printable Version

+- SA-MP Forums Archive (https://sampforum.blast.hk)
+-- Forum: SA-MP Scripting and Plugins (https://sampforum.blast.hk/forumdisplay.php?fid=8)
+--- Forum: Scripting Help (https://sampforum.blast.hk/forumdisplay.php?fid=12)
+---- Forum: Tutorials (https://sampforum.blast.hk/forumdisplay.php?fid=70)
+---- Thread: [Tutorial] How to NOT code a bad script? (/showthread.php?tid=273775)



How to NOT code a bad script? - Godhimself - 03.08.2011

How to NOT code a bad script?

Introduction:

Ok im going to make this simple and short, infact in steps to make it clearer.
Im making this tutorial to try show scripters out there at my stage or less or/and even people who dont know how to optimize yet how to script in proper efficency, i learnt the hard way, i created a massive script clearing 15k lines basically on all the knowledge i had from the past, the bad thing i did was use individual strings, default functions in mass amounts creating 1000s of practically useless lines, besides that my individual strings ranged from 64 cells to 128 cells and was averageing 40-60% CPU usage< lmao. What i should of been doing was using global variable, player variables. I basically coded 2000+ lines of a system in my script to 887 lines, using 16 variables rather then 100s to 1000s and stocks for typically used functions to break down lines. You want your script to run at the best efficency, 1 to keep your players happy with less lag and crashes and 2 to keep your host happy so you dont use massive amounts of CPU to run your bad script so they crash/restart your server.

Step 1 - What to code with?


The best thing to do is start from scratch and rebuild your script so it will determine global efficency.
Im not going to tell you what to use but the best command processors/functions are:

- zcmd (Fast command proccessor by ZeeX here)

- ycmd (Fast command proccessor by ****** here)

- sscanf (Epic plugin/function to make commands with fields on one line(ie. /command [field1] [field2] by ****** here)

And the best file saving plugins/includes are:

- my_sql (There is more then one release/creator ****** "samp mysql plugin")

- y_ini (By ****** here)

If you dont know pvars yet, learn it now, player variables are so handy and determains less lines and efficency. You can use them for everything from file values to new variables.

Step 2 - How to code a command efficently?

I could simply brag on how to code efficently but im going to just show you and im sure you will get it:

Exibit A: Bad command

pawn Код:
CMD:command(playerid, params[])//This is zcmd, use a fast proccessor = maximium efficency
{
    new string[64], pName[24];//We dont need to make strings under every command, Imagine your script with 200 commands. 100s of useless cells = more CPU usage
    GetPlayerName(playerid, pName, sizeof(pName));//This is a typical function, its used all the time, Why make another line for it? When we can make a stock and use the function in the strings = less lines/cells/less CPU usage.
    format(string, sizeof(string), "Your name is %s with id %d", pName, playerid);//This is also a typical fucntion, imagine how many times this is used? Why make individual strings for each fucntion? When we can make 1 for the future use of the function.
    SendClientMessage(playerid, 0x0, string);
    return true;
}
(Scroll right)

Exibit B: Efficency rebuild

pawn Код:
//top
new GlobalMessageString[100];//This is going to be our global message string for every "format" function(Can also be used again for every other use of the "format" function.

//Anywhere in script
stock GetName(playerid)//We can now use GetName(playerid) in our fomat function etc to get the players name
{
    new pName[24];//This way its typed once(BTW 24 cells is not too small type a 24 charactor name and tell me thats a name)
    GetPlayerName(playerid, pName, sizeof(pName));//This way this function is typed once.
    return pName;//return the players name.
}

//Rebuilt command
CMD:command(playerid, params[])
{
    format(GlobalMessageString, sizeof(GlobalMessageString), "Your name is %s with id %d", GetName(playerid), playerid);//We can use this same function with the strings again without redefining strings and adding more cell usage.
    SendClientMessage(playerid, 0x0, GlobalMessageString);
    return true;
}
(Scroll right)

Step 3 - How to code a saving system efficently?

Basically instead of using an enum for file values, use pvars(SetPVarInt/GetPVarInt), just call the variable the enum value and set it on login/register after you get your saved values, and then simply get the values when needed.
(If this dont make sense reply here and ill try make it clearer)

---[End of Tutorial]---

Feel free to post any comments/questions/step add-ons, i know i have not covered all areas but enough to optimize your script.

Tutorial by Godhimself




Re: How to NOT code a bad script? - Calgon - 03.08.2011

Quote:

How to NOT code a bad script?

You should be more specific, using this as your title is very vague and isn't pointing out what your aim of this tutorial is.

Quote:

The best thing to do is start from scratch and rebuild your script so it will determine global efficencyIm not going to tell you what to use

but the best command processors/functions are:

"Global efficiency" as you say cannot single-handedly be defined by the plugins and includes you use, it's the coding practices you use throughout.

Quote:

- zcmd (Fast command proccessor by ZeeX here)

- ycmd (Fast command proccessor by ****** here)

You should point out the advantages of using zcmd or ycmd, and you should provide a direct link to the y_commands release topic.

Quote:

- sscanf (Epic plugin/function to make commands with fields on one line(ie. /command [field1] [field2] by ****** here)

sscanf is a splitting routine, it isn't limited only to commands - you should explain this a little more in-depth.

Quote:

And the best file saving plugins/includes are:

You should explain why you believe these are the best "plugins/includes," instead of providing just a list without much information.

Quote:

- my_sql (There is more then one release/creator ****** "samp mysql plugin")

MySQL isn't directly a 'file saving include', it's a database engine - and you haven't provided a sufficient explanation of the alternatives available to MySQL, such as SQLite - which is generally more efficient to use in SA-MP as opposed to MySQL.

Quote:

If you dont know pvars yet, learn it now, player variables are so handy and determains less lines and efficency. You can use them for everything from file values to new variables.

PVars are a set of functions that store/get player data, and if you did your research - you'd generally understand that PVars are less efficient than normal arrays/variables, because of the function overhead and the memory usage (you need to store the variable name & the value).

Quote:

GetPlayerName(playerid, pName, sizeof(pName));//This is a typical function, its used all the time, Why make another line for it? When we can make a stock and use the function in the strings = less lines/cells/less CPU usage.

Simply using the function more than once is pretty pointless - the value won't change unless you force it to with SetPlayerName, you should merely create an array storing the player's name when a player connects.

Quote:

new GlobalMessageString[100];//This is going to be our global message string for every "format" function(Can also be used again for every other use of the "format" function.

You should declare a higher string size, such as 128. You'll be surprised how commonly you collide with the 100 cell limit.

Also, you should consider naming your variables by their scope - so 'gGlobalMessage' would be a more appropriate name as it's a globally defined variable, also you might want to look in to Hungarian Notation, since Pawn is a typeless language.

Quote:

GetPlayerName(playerid, pName, sizeof(pName));//This way this function is typed once.

Just because a function is typed once, that does not mean it is only used once. Simply using the function more than once is pretty pointless - the value won't change unless you force it to with SetPlayerName, you should merely create an array storing the player's name when a player connects.

Quote:

Basically instead of using an enum for file values, use pvars(SetPVarInt/GetPVarInt), just call the variable the enum value and set it on login/register after you get your saved values, and then simply get the values when needed.
(If this dont make sense reply here and ill try make it clearer)

You should explain this more clearer, one of the advantages for PVars is that you can dynamically update, destroy and create these values - which I think is what you're trying to get at - use PVars for values you're not entirely sure will exist for the player's entire connection.

Quote:

but enough to optimize your script.

To what extent? You've only covered a few 'basics' with commands and strings.


Re: How to NOT code a bad script? - Godhimself - 03.08.2011

@Calg00ne

Thankyou very much for your comment, i am amazed by the extent of your knowledge.

Although i tried to hint i was not as knowledgable in my introduction, i basically rage posted it to prevent anyone doing what i did and take forever to fix it(I do beleive some people will benifit from my tutorial). I will be sure to put your advise to practice to help develop my knowledge and when im confident, redo this tutorial.

Thanks again


Re: How to NOT code a bad script? - System64 - 03.08.2011

why use PVar, they are slow, and one big + for optimizing your script is using YSI, everything you can/know from YSI put that in your script, anyway nice


Re: How to NOT code a bad script? - Chrillzen - 05.08.2011

Thank you very much!


Re: How to NOT code a bad script? - Deskoft - 05.08.2011

Nice post, needs some improvement, but it's a great start.
Learning to script is not an easy thing, and mantaining a project is not easy either.
Don't abandon projects just because you don't recieve support, as ****** said on a topic (not this one),
support is the last thing you will recieve.

You can be questioned, criticized and insulted, but don't loose 'your lines'. If you know what you are doing, have confidence, and don't hear to people, unless they have a valid statement.

Instead of being a lone-wolf, your community is the most important part of your staff, as I said previously, treat your community (support) as gold.

Discuss features with them, and evaluate every single line they suggest, try to please them, it's not "your" script, it's "our" (the community's) script.

And please, when you are hiring people, don't hire him on popularity, base him on maturity, productivity and activity.

Again, nice topic.


Re: How to NOT code a bad script? - Godhimself - 05.08.2011

Thanks for you comments guys.

@Deskoft

Very well said sir.


On Topic: I made this topic to try prevent anyone making the same mistake as me and code a massive CPU eating script. I completed the tutorial on my current knowledge and tried to explain what i know to the word.
Great to see people appreciating my work! I appreciate your feedback! Thanks again.

EDIT: I will be sure to update it upon my future knowledge growth.


Re: How to NOT code a bad script? - Chrillzen - 05.08.2011

It's great, but can you make some more examples? (If possible).


Re: How to NOT code a bad script? - dr.pepper - 05.08.2011

I really like this tutorial but needs a lot more stuff. And yes, scripting can be hard. Good job and I hope you add more things. Good job once again.


Re: How to NOT code a bad script? - Godhimself - 05.08.2011

@ Chrillzen

I will, im actually still learning better optimizing techniques, and when im confident i know what im doing completely i will be sure to add alot more examples. BTW the example in the command can be used anywhere in the script.

Basically:

- Use global strings and try use the least amount of strings, also watching the cell usage. (Use 1 string for say all of your fomat strings, and one for all of the times you get a player name etc)

- Use fast proccessors/functions and code things in clean indentation and structure your codes as efficent as possible, also try keep the least amount of lines in a script(Naturally will be easier to proccess)

Feel free to post any/better ways to code efficently as im still learning.