Lou Montana/Sandbox – User

From Bohemia Interactive Community
Jump to navigation Jump to search
m (Add format example)
m (Future Template:Header/Tutorial template)
(29 intermediate revisions by the same user not shown)
Line 1: Line 1:
[[Category: Sandbox]]
[[Category: Sandbox]]
 
<noinclude>
{{Informative | Future [[Code Best Practices]] page}}
-----
{{wip}}
Future [[Template:Header/Tutorial|Header/Tutorial]] template
 
</noinclude><includeonly>{{Feature|informative
----
 
{{SideTOC}}
{{Stub}}
 
[[:Category: Scripting Topics]]
 
== Getting started ==
 
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.
 
With that being said, let's go!
 
=== Prerequisites ===
 
* An advanced text editor such as Visual Studio Code or Notepad++ (see [[Debugging Techniques#Code Edition|Debugging Techniques' Code Edition chapter]] for useful plugins)
* Some English knowledge, helped if needed by
* Access to this wiki is a plus (the Swiss flag is, too)
* Tutorial/examples (YouTube tutorials, community tutorials, [[:Category:Example_Code|Example Code]])
* Google-Fu (a.k.a search engine skills)
* Help with a translator tool, like [https://www.google.com/translate Google Translate] or [https://www.deepl.com/ DeepL]
 
 
== Best practices ==
 
=== Code format ===
 
* Whatever you do about your code's format, '''be consistent'''.
* Choose an indentation format '''and stick to it'''. There is not especially one indent better than another (''but there sure are terrible ones''), again the important point here being ''consistency''.
** Common indentation styles are:
*** [https://en.wikipedia.org/wiki/Indentation_style#K&R_style K&R style] indenting
*** [https://en.wikipedia.org/wiki/Indentation_style#Allman_style Allman style] indenting
** Use empty space. Line return, spaces before and after brackets, if this improves readability, use it: space is free.
** indent with two/four spaces '''or''' one tab. Do not mix these.
** ''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.
* {{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.<br><!--
--> You do '''not''' need it in script files.
 
=== Variable format ===
 
* Name your variables and functions properly:<!--
--> 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.
** Your variable names must have a meaning: variables like '''_u''' instead of '''_uniform''' should not exist. '''_i''' is an accepted iteration variable name (e.g in [[for]] loops).
** It is recommended to use [https://en.wikipedia.org/wiki/Camel_case camel-case] your variables;<!--
--> camel-casing (namingLikeThis) your variables and functions make the code naturally more readable, especially for long names.
* Prefix your public variables and [[setVariable]] with your tag in order to avoid any conflict about other mods, scripts or mission variables.
* Make your variables '''private''' thanks to the [[private]] or [[params]] keyword in order to avoid accidental upper-scope overwriting of variables of the same name.
* Defined constants must be UPPERCASE_WITH_UNDERSCORES (e.g {{Inline code|#define SOME_CONST}}).
 
 
=== Code structuration ===
 
* '''DRY:''' '''D'''on't '''R'''epeat '''Y'''ourself. If you write the same code block or the same logic many times, export this code as a function and use parameters with it.
** If your code has too many levels, it is time to split and rethink it<!--
--> (e.g {{Inline code|[[if]] (something) [[then]] { [[if]] (somethingElse) [[then]] { [[if]] (anotherSomething) [[then]] { {{codecomment|/* etc */ }} }; }; };}}...)
** Do NOT use [[PreProcessor_Commands#Macros|macros]] as functions - these hinder readability. Use functions instead.
* Using {{codecomment|comments}} in your code must not explain ''what'' the code does, but ''why'' it is done this way (if needed).<!--
--> Your code organisation combined to your variable names must be enough to be read by a human.
 
=== Code/Files organisation ===
 
* Use [[Arma 3 Functions Library#Adding a Function|CfgFunctions]] to declare the functions that will be called frequently.
** One Functions directory, with sub-directories if needed.
* Use [[Event Scripts]] as needed.
* Don't put '''any code''' in a unit's init box ''but eventually'' [[local]] commands for this specific unit - '''all''' unit's init boxes are run client-side on client connection.
 
 
== Examples ==
 
<!--
 
EDITOR'S NOTE: Formatting Code examples are not linking commands on purpose! This allows for a fair comparison of both syntaxes' readability.
-->
{| class="bikitable"
! <big>Bad Example</big>
! <big>Good Example</big>
|-
! colspan="2" |
<small>
=== Good Practice examples ===
</small>
|-
| <code>_unit = player;</code>
| <code>'''private''' _unit = player;</code>
|-
| <code>private _uB = allUnits select { side _x == blufor };</code>
| <code>private '''_bluforUnits''' = allUnits select { side _x == blufor };</code>
|-
| <code>finalAssault = true; publicVariable "finalAssault";</code>
| <code>'''PREFIX_'''finalAssault = true; publicVariable "'''PREFIX_'''finalAssault";</code>
|-
| <code>player setVariable ["MoneyInPocket", true];</code>
| <code>player setVariable ["'''PREFIX_'''MoneyInPocket", true];</code>
|-
! colspan="2" |
<small>
=== Flow Logic examples ===
</small>
|- style="vertical-align: top"
|
|
<code>if (alive player && damage player >= 0.9) then {
* {{#if:{{{target|}}}
hint "very damaged";
| Target: {{#switch:{{{target}}}
};
  |0= newcomer
if (alive player && damage player >= 0.5 && damage player < 0.9) then {
  |1= beginner
hint "quite damaged";
  |2= moderate
};
  |3= advanced
if (alive player && damage player > 0 && damage player < 0.5) then {
  |4= expert
hint "slightly damaged";
  |#default= -wrong target defined-
};
}}
if (alive player && damage player == 0) then {
| -no target defined-}}
hint "pristine state";
* {{#if:{{{difficulty|}}}
};
| Difficulty: {{#switch:{{{difficulty}}}
if (not alive player) then {
  |0= easy {{Colorball|green}}
hint "dead";
  |1= normal {{Colorball|orange}}
};</code>
  |2= hard {{Colorball|red}}
  |#default= -wrong difficulty defined-
}}
| -no difficulty defined-}}
{{#if:{{{prerequisites|}}}
|
|
<code>if (not alive player) exitWith { hint "dead"; };<br>
* Prerequisites:<br>
private _playerDamage = damage player;
{{{prerequisites}}}
switch (true) do {
}}
case (_playerDamage >= 0.9): { hint "very damaged"; };
}}</includeonly><noinclude>{{Doc/Template
case (_playerDamage >= 0.5): { hint "quite damaged"; };
|descr= Tutorial header.
case (_playerDamage > 0)  : { hint "slightly damaged"; };
|param1= target
default { hint "pristine"; };
|descr1= number in range 0..4: newcomer - beginner - moderate - advanced - expert
};</code>
|param2= difficulty
|-
|descr2= number in range 0..2: easy - normal - hard
! colspan="2" |
|param3= prerequisites
<small>
|descr3= (Optional) free text for prerequisite tutorials/knowledge. make a (sub-)list with <nowiki>**</nowiki> and new lines
=== Format examples ===
|example1= <nowiki>{{Header/Tutorial}}</nowiki>
</small>
|result1= {{User:Lou_Montana/Sandbox}}
|- style="vertical-align: top"
|example2= <nowiki>{{Header/Tutorial|target=0}}</nowiki>
|
|result2= {{User:Lou_Montana/Sandbox|target=0}}
<code>if (not alive player) exitWith
|example3= <nowiki>{{Header/Tutorial|target=0|difficulty=0}}</nowiki>
{ hint "dead"; };<br>
|result3= {{User:Lou_Montana/Sandbox|target=0|difficulty=0}}
private _playerDamage = damage player;
|example4= <nowiki>{{Header/Tutorial|target=0|difficulty=1|prerequisites=a prerequisite}}</nowiki>
switch (true) do {
|result4= {{User:Lou_Montana/Sandbox|target=0|difficulty=1|prerequisites=a prerequisite}}
case (_playerDamage >= 0.9): {hint "very damaged";};
|example5= <span style="white-space: pre"><nowiki>{{Header/Tutorial|target=0|difficulty=2|prerequisites=** prerequisite 1
case (_playerDamage >= 0.5): {
** prerequisite 2}}</nowiki></span>
hint  "quite damaged";};<br>
|result5= {{User:Lou_Montana/Sandbox|target=0|difficulty=2|prerequisites=** prerequisite 1
case (_playerDamage > 0): { hint "slightly damaged"; };
** prerequisite 2}}
<nowiki> </nowiki>default
}}</noinclude>
{<br>
<nowiki>   </nowiki>hint "pristine";
<nowiki> </nowiki>};
};</code>
|
<code>if (not alive player) exitWith { hint "dead"; };<br>
private _playerDamage = damage player;
switch (true) do {
case (_playerDamage >= 0.9): { hint "very damaged"; };
case (_playerDamage >= 0.5): { hint "quite damaged"; };
case (_playerDamage > 0)  : { hint "slightly damaged"; };
default { hint "pristine"; };
};</code>
|}
 
 
== Final words ==
 
* Learn from others' scripts but don't steal code and pretend it's yours — be a decent human being. Stealing code and its consequences:
** It soils your reputation and devaluates your actions once it is found out — and it ''always'' get found out. DMCA's are filled on Steam every day.
** It makes people in the community get less helpful and more reluctant in giving advices. It can also prevent them to ''release'' an interesting feature!
* Don't try to obfuscate your code: it is considered rude, especially since you learnt from others.
** Obfuscated code only makes it ''harder'' to get, but does not make it ''protected''.
** Obfuscated code is also slower on compilation (and, depending on the quality of code and obfuscation, on execution too).
* 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