Lou Montana/Sandbox – User

From Bohemia Interactive Community
Jump to navigation Jump to search
m (Some page presentation / copy-paste introduction from Code Optimisation)
m (Future Template:Header/Tutorial template)
(31 intermediate revisions by the same user not shown)
Line 1: Line 1:
__NOTOC__
[[Category: Sandbox]]
[[Category: Sandbox]]
{{Informative | Future [[Code Best Practices]] page}}
<noinclude>
{{Important | This is at the moment '''only a list of topics''' and absolutely not the final render. Many single entries will result in a chapter.}}
-----
 
Future [[Template:Header/Tutorial|Header/Tutorial]] template
 
</noinclude><includeonly>{{Feature|informative
----
|
 
* {{#if:{{{target|}}}
 
| Target: {{#switch:{{{target}}}
[[:Category: Scripting Topics]]
  |0= newcomer
 
  |1= beginner
== Getting started ==
  |2= moderate
 
  |3= advanced
=== Prerequisites ===
  |4= expert
 
  |#default= -wrong target defined-
* An Arma game
}}
* Passion
| -no target defined-}}
* Some English knowledge, helped if needed by a translator tool like [https://www.google.com/translate Google Translate] or [https://www.deepl.com/ DeepL]
* {{#if:{{{difficulty|}}}
* Access to this wiki is a plus (the Swiss flag is, too)
| Difficulty: {{#switch:{{{difficulty}}}
* Tutorial/example article (YouTube tutorials, )
  |0= easy {{Colorball|green}}
* Google-Fu (a.k.a search engine skills)
  |1= normal {{Colorball|orange}}
* Advanced text editor (Such as Notepad++ or Visual Studio Code)
  |2= hard {{Colorball|red}}
 
  |#default= -wrong difficulty defined-
 
}}
== Rules ==
| -no difficulty defined-}}
 
{{#if:{{{prerequisites|}}}
In the domain of development, any rule is a rule of thumb. If a rule states for example that it is ''better'' that a line of code doesn't go over 80 characters, it doesn't mean that any line '''''must not''''' go over 80 characters; sometimes, the situation needs it. If you have a good structure, '''do not''' change your code to enforce a single arbitrary rule. If you break many of them, you may have to change something. Again, this is according to your judgement.
|
 
* Prerequisites:<br>
With that being said, here are the three basic rules to get yourself in the clear:
{{{prerequisites}}}
 
}}
# [[#Make it work|Make it work]]
}}</includeonly><noinclude>{{Doc/Template
# [[#Make it readable|Make it readable]]
|descr= Tutorial header.
# [[#Optimise then|Optimise then]]
|param1= target
 
|descr1= number in range 0..4: newcomer - beginner - moderate - advanced - expert
=== Make it work ===
|param2= difficulty
 
|descr2= number in range 0..2: easy - normal - hard
{{quote|Premature optimization is the root of all evil.|[https://en.wikipedia.org/wiki/Donald_Knuth Donald Knuth]}}
|param3= prerequisites
Your first goal when coding is to make your code do what you want it does. A good way to reach this objective is to read and getting inspired by other people's code. If you understand it by reading it once, it is probably a good source of inspiration.
|descr3= (Optional) free text for prerequisite tutorials/knowledge. make a (sub-)list with <nowiki>**</nowiki> and new lines
 
|example1= <nowiki>{{Header/Tutorial}}</nowiki>
* When starting from scratch if you know what you want but miss the specific steps to get to your point, it is a good practice to write down in your native language what you want to do. E.g ''Get [[allUnits|all the units]] [[distance|near]] [[locationPosition|the city]], and [[forEach|for each]] [[side|west]] soldier in them, [[setDamage|add 30% damage]]''.
|result1= {{User:Lou_Montana/Sandbox}}
* Use [[Arma_3_Startup_Parameters#Developer_Options|-showScriptErrors]] startup parameter and '''make sure your code doesn't throw errors.''' Not only will your code run slower but it may also ''not work at all''. Be sure to read the error, isolate the issue and sort it out [[:Category:Scripting Commands|thanks to this Wiki]].
|example2= <nowiki>{{Header/Tutorial|target=0}}</nowiki>
* Read your [[Crash_Files|Arma RPT]] (report) to read more details about the error that happened in your code.
|result2= {{User:Lou_Montana/Sandbox|target=0}}
 
|example3= <nowiki>{{Header/Tutorial|target=0|difficulty=0}}</nowiki>
=== Make it readable ===
|result3= {{User:Lou_Montana/Sandbox|target=0|difficulty=0}}
 
|example4= <nowiki>{{Header/Tutorial|target=0|difficulty=1|prerequisites=a prerequisite}}</nowiki>
Whether you are cleaning your code or a different person's, you must understand the code without twisting your brain:
|result4= {{User:Lou_Montana/Sandbox|target=0|difficulty=1|prerequisites=a prerequisite}}
 
|example5= <span style="white-space: pre"><nowiki>{{Header/Tutorial|target=0|difficulty=2|prerequisites=** prerequisite 1
* While [[SQF syntax|SQF]] ''is'' (non-noticeably) impacted by variable name length, this should not take precedence on the fact that code must be readable by a human being. Variables like '''_u''' instead of '''_uniform''' should not be present.
** prerequisite 2}}</nowiki></span>
* ''One-lining'' (putting everything in one statement) memory improvement is most of the time not worth the headache it gives when trying to read it. Don't overuse it.
|result5= {{User:Lou_Montana/Sandbox|target=0|difficulty=2|prerequisites=** prerequisite 1
* Indentation is important for the human mind, and space is too. Space is free, use it.
** prerequisite 2}}
* Same goes for line return; it helps to see a code block wrapping multiple common instructions instead of having to guess where it starts and stops.
}}</noinclude>
* Do you see the same code multiple times, only with different parameters? Now is the time to write a function!
* If you have a lot of [[if]]..[[else]], you may want to look at a [[switch]] condition, or again break your code in smaller functions.
* Is your function code far too long? Break it in understandable-sized bites for your own sanity.
* Finally, camel-casing (namingLikeThis) your variables and commands will naturally make the code more readable, especially for long names.
 
{{Informative| '''_i''' is an accepted variable standard for a [[for]]..[[do]] iteration}}
 
See the following code:
_w=[]; {_w pushbackunique primaryweapon _x} foreach((allunits+alldeadmen) select{_x call bis_fnc_objectside==east});
 
The same example is far more readable with proper spacing, good variable names and intermediate results:
_weaponNames = [];
_allUnitsAliveAndDead = allUnits + allDeadMen;
_allEastAliveAndDead = _allUnitsAliveAndDead select { _x call BIS_fnc_objectSide == east };
{ _weaponNames pushBackUnique primaryWeapon _x } forEach _allEastAliveAndDead;
<!--
EDITOR'S NOTE: ^ code examples are not linking commands on purpose! This allows for a fair comparison of both syntaxes' readability.
-->
 
==== Constants ====
Using a hard-coded constant more than once? Use preprocessor directives rather than storing it in memory or cluttering your code with numbers. Such as:
a = _x + 1.053;
b = _y + 1.053;
And
_buffer = 1.053;
a = _x + _buffer;
b = _y + _buffer;
Becomes
<span style="color: purple; font-weight: bold;">#define BUFFER 1.053</span> {{codecomment|// note: no semicolon}}
_a = _x + BUFFER;
_b = _y + BUFFER;
{{Informative | Using the '''#define''' macro only works within the current [[SQF]] ''file''. Such definition will not propagate anywhere else.}}
'''Global''' "constants" can be defined ''via'' a [[Description.ext]] declaration, though, and accessed using [[getMissionConfigValue]] command:
 
Declaration in [[Description.ext]]:
<syntaxhighlight lang="cpp">
var1 = 123;
var2 = "123";
var3[] = {1,2,3};
rand = __EVAL(random 999);
</syntaxhighlight>
 
Usage in code:
[[hint]] [[str]] [[getMissionConfigValue]] "var1"; // 123 {{codecomment|// 0.0007 ms}}
[[hint]] [[str]] [[getMissionConfigValue]] "var2"; // "123" {{codecomment|// 0.0008 ms}}
[[hint]] [[str]] [[getMissionConfigValue]] "var3"; // [1,2,3] {{codecomment|// 0.0017 ms}}
[[hint]] [[str]] [[getMissionConfigValue]] "rand"; // constant random, for example 935.038 {{codecomment|// 0.0007 ms}}
 
The [[getMissionConfigValue]] command searching [[Description.ext]] from top to bottom,
it is better for a matter of performance to put all your definitions at the top of the file.
 
=== Optimise then ===
 
Once you know what is what, you can understand your code better.
* Use private variables instead of global variables (preceded with an underscore) as much as possible
* You were iterating multiple times on the same array?
** You should be able to spot your issue now.
* Are you using [[execVM]] on the same file, many times?
** Store your function in memory to avoid file reading every call with {{Inline code|_myFunction {{=}} [[compile]] [[preprocessFileLineNumbers]] "myFile.sqf";}}
* Is your variable name far too long?
** Find a smaller name, according to the variable scope:
e.g
{ _opforUnitUniform {{=}} [[uniform]] [[_x]]; [[systemChat]] _opforUnitUniform; } [[forEach]] _allOpforUnits;
becomes
{ _uniform {{=}} [[uniform]] [[_x]]; [[systemChat]] _uniform; } [[forEach]] _allOpforUnits;
 
{{Informative | See [[Code Optimisation]] for more information.}}
 
 
== Best practices ==
 
=== Code format === // move that in Make it Readable maybe - it's too late, brb later (:
 
* Some general coding tips from [https://www.topcoder.com/blog/coding-best-practices/ here]: standards, line lengths, etc
** Variable names should indicate what they store / are used for.
 
* Format, indentation, no one-line, spacing, line returns
* Be consistent (space/tab indentation, (camel)casing, [https://en.wikipedia.org/wiki/Indentation_style#K&R_style K&R style] / [https://en.wikipedia.org/wiki/Indentation_style#Allman_style Allman style] indenting)
* Use comments frequently to explain ''not'' what the code does, but ''why'' it is done this way.
 
=== Make reusable functions ===
 
* Don't copy and paste the same code, make functions
* Don't make macros to replace SQF code
 
=== Variables ===
 
* Prefix your public variables and [[setVariable]] with your tag
* PRIVATE (or params) your variables
* Use {{Inline code|#define SOME_CONST}} for constant values instead of variables
 
=== Code location ===
 
* '''Nothing''' in init box ''but'' [[local]] commands for this specific unit - '''all''' the init boxes are run client-side on client connection
* {{Inline code|<span style{{=}}"background-color: #FCC">'''0 {{=}}''' </span>''myCommand''}} is "useful" only for editor fields that for no apparent reason refuse commands returning a value.
 
 
== Final words ==
 
* Learn from others' scripts but don't steal code and pretend it's yours — be a decent human being.
* Don't try to obfuscate your code: it is considered rude, especially since you learnt from others.
* Have fun!

Revision as of 16:05, 16 April 2021



Future Header/Tutorial template Tutorial header.

This template is used on these pages.

Usage

{{Lou Montana/Sandbox|target|difficulty|prerequisites}}

  • target: number in range 0..4: newcomer - beginner - moderate - advanced - expert
  • difficulty: number in range 0..2: easy - normal - hard
  • prerequisites: (Optional) free text for prerequisite tutorials/knowledge. make a (sub-)list with ** and new lines
Examples
Code Result
{{Header/Tutorial}}
  • -no target defined-
  • -no difficulty defined-
{{Header/Tutorial|target=0}}
  • Target: newcomer
  • -no difficulty defined-
{{Header/Tutorial|target=0|difficulty=0}}
  • Target: newcomer
  • Difficulty: easy
{{Header/Tutorial|target=0|difficulty=1|prerequisites=a prerequisite}}
  • Target: newcomer
  • Difficulty: normal
  • Prerequisites:
a prerequisite
{{Header/Tutorial|target=0|difficulty=2|prerequisites=** prerequisite 1 ** prerequisite 2}}
  • Target: newcomer
  • Difficulty: hard
  • Prerequisites:
    • prerequisite 1
    • prerequisite 2