Jump to content
Sign in to follow this  
knowjack

MBR MOD Coding Best Practices Recommended for All Contributors!

Recommended Posts

So you want to write a MOD that is wonderful and it deserves to be included in the released code?

Please read this:

Our 300,000+ user community expects the official released bot to be bullet proof and operate without errors, or at least self correcting for any minor errors that occur and keep farming 24/7.  The development team will usually test all hotfix code on least 5 PC, and major code releases on least 30 different PC's including all supported OS, VMware emulator, and on several VPS.  We do this to ensure the minimum number of problems.  :):

Sorry to inform, but most user MOD's are not written well or are not written to be used by others in a shared development environment.  It requires many hours/days/weeks for the development team to clean up/test user contributions in order to add before they can combined into an official released version.  We know most users do not have access to a room full of hardware & software to test new code and makes it harder to produce code with minimal errors.  But community contributors can use some best coding best practices to make the integration process faster & easier for everyone.  These best practices also will make tracking down bugs easier as well. If you are writing MOD's we suggest you follow this list of Best Practices below that we try to follow.

Note - If you find code not following these guidelines, we already know about it.  The Bot code has been mangled with different philosophies by 12+ developers for over a year now.  There are many legacy examples of what NOT to do inside the older code functions.  As these functions are changed, the development staff tries to update them to the current standards.

MBR Best Practices: (List in random order with all practices having equal importance)

1: Download and use the full SciTE editor:

The normal AutoIt install package has a reduce feature version of the SciTE editor included.  The full editor has vastly improved capabilities including: code tracing, break points, Tidy capability, and automatic UDF creation.

https://www.autoitscript.com/site/autoit-script-editor/downloads/

2: Protect the copyright:

There are a lot of AutoIt based Clash of Clans bots.  MBR is the original.  Often copied, cloned, stolen, or imitated, but there is only one MyBotRun!  To keep it this way and help you receive credit for the code you write and contribute to the community, you must include a comment header with appropriate legal information.  The full SciTE editor has the ability to automatically add a User Developed Function (UDF) header and give you a place to describe your code functions.  The basic UDF with the MBR copyright added is below.  Please use this for all functions, including the custom Remarks Copyright as shown.

; #FUNCTION# ====================================================================================================================
; Name ..........:
; Description ...:
; Syntax ........:
; Parameters ....:
; Return values .:
; Author ........: Your Name
; Modified ......:
; Remarks .......: This file is part of MyBotRun. Copyright 2016
;                  MyBotRun is distributed under the terms of the GNU GPL
; Related .......:
; Link ..........:
; Example .......:  =====================================================================================================================

If you are a prolific AutoIt coder, you are welcome to add whatever copyright message your lawyer suggests. But if do use a special copyright, MBR cannot and will not use the code function without written permission.  If you like more information on the AutoIt UDF specification, check out this page in the Wiki: https://www.autoitscript.com/wiki/UDF-spec

3: Use the AutoIt Tidy function on all new files:

The tidy program is available as a separate AutoIt download or built inside of the SciTE full editor.  It will automatically reset all indents, adjust code spacing, and comments to make the code more readable by others.

When editing a code file in SciTE, press CTRL + T to run the tidy process.

Note - MBR does not use Tidy on the GUI Design files as they need some special formatting or it is too easy to get lost.

4: Please include comments in your code:

Many of the older bot files have zero comments.  A couple of "retired" developers did this to make it harder for others to change "THEIR" code.  Please do not do this.  Besides the use of the UDF header to outline function descriptions, and variables used and returned, please add a few comments inside your code to let others know what you are trying to do.  You do not need a comment on every line or command. But the longer the function is, the more it would help others if you tell us what is supposed to happen, especially with complicated code sections.

5: Do not use GUICtrlRead() command inside functions:

Since the entire GUI is disabled when the bot is running (except the pause and stop buttons), there is absolutely no reason to repeatedly use the GUICtrlRead function.  The faster best practice is to use a global variable to store the state of the GUI button/checkbox/combobox/etc.

 

These assignments should be done in the MBR GUI Control XXX.au3 files for the tab where the control is located.  Some older GUI variable assignments are located in the save/read/apply Config files, and for variables that do not change very often, this is also acceptable as the config is saved/applied with every start.

6: Error Proofing:

Because you are writing code to interact with a dynamic window controlled by the CoC APP and BS, you never really know what is on the screen. :sad:  So error proofing is required to ensure the code works as intended not matter what the User, PC, or any other outside force has done.

 

Let's be honest, there are many examples of how NOT to error proof scattered all through legacy code.  The developers are constantly fixing bugs created by "blind" clicking, assuming window never changes, or that error windows never appear. :):

  • One good example is the use of error proofing is the various "click" functions.  Before the bot clicks, you need to make sure that is clicking the intended target.  If you want to click a button, use pixel check (faster) or image search (slow) to make sure the button exists.  If the PC is too slow/fast, then your target may not exist and when you click and you may end up deploying troops instead of hitting a button.  This especially important when clicking on any button that has the potential to use resources.  If you resources are low, then CoC will open a window asking you want to use GEMS to keep going.  There is a special GemClick function written for non-time sensitive clicks to avoid this issue, and there is also a TrainClick function for troop training optimized for speed and safety.  Both of these are good examples of how to use error proofing. :):
  • Another problem area is using pixel checking for shades of green.  Since the entire base is on a green grass, variations in base layout can mean your check for green pixel has a false positive and finds grass and not a button!  :sad:  If you are doing any pixel checks, you must realize that the pixel check tolerance values are simply +/- integer value range of the RGB values for the color.  So before you pick any pixel color check, look at the RGB values of the normal & not normal values to ensure the tolerance is set correctly.  In some cases you may need to check several pixels to ensure you have the intended feature.
  • Another common issue that requires error proofing is waiting for actions like; window closing, window opening, or even built in CoC messages to clear the screen before the code moves to the next task.  The standard method is to add a simple delay using sleep (the bot has a special sleep command, more later).  But if the PC is too slow/fast then the delay time may not be right.  A better practice is use a simple While/WEnd loop that is looking for the action to complete or the next window to be ready.  An example of this from the ProfileReport.au3 file:
$iCount = 0
 While _CheckPixel($aIsMain, $bCapturePixel) = False  ; wait for profile report window very slow close
If _Sleep($iDelayProfileReport3) Then Return
$iCount += 1
If $debugsetlog = 1 Then Setlog("End ProfileReport $iCount= "& $iCount, $Color_PURPLE)
If $iCount > 50 Then
If $debugsetlog = 1 Then Setlog("Excess wait time clearing ProfileReport window: " &$iCount, $COLOR_PURPLE)
ExitLoop
EndIf
WEnd

Also, There are several examples of separate functions created to verify window status: IsTrainPage(), isBarrack(), or IsGemOpen().

7: Delay or Sleep commands:

Background - AutoIt is single threaded language. Only one command can occur at a time.  This means that AutoIt does not have true interrupt driven capability, and the interrupt functionality has to be coded into the program scripts.  There are 2 objects the user touches that makes it look like it interrupts the bot operation, Stop, and Pause.   But these buttons are not true interrupts, but are are merely button states the bot reads occasionally when there is "extra" time.  This extra time is whenever the script is in a "_sleep()" command.   :P:

If your script does not use the _Sleep() function and uses the native AutoIt sleep() function, then our 2 buttons will not behave as expected!  The proper method to add a script delay is:

 If _Sleep(delay time in milliseconds) Then Return 

The If/Then method allows for the sleep time to properly stop the bot with false return value.  

If your code doesn't need really any delays, then the best practice is to add short 50-100ms delay after commands where a small delay has no impact on operation.  Examples of the best place to add these delays for improved stop/pause button response are: after every setlog, after clicking a button, and/or when waiting for windows to open or close.

8: Debug Tools:

Starting with V3.1, the developers added several flag variables specifically for debug purposes.  Examples of these are $debugSearchArea, $debugOcr, $debugRedArea, $debugSetlog, and $debugClick.  Several are for debug of our Proprietary DLL codes ($debugSearchArea, $debugOcr, and $debugRedArea). These enable us to get extra debug information when they are set equal to one.  The  $debugClick variable can be enabled via the expert tab in the GUI to enable users to quickly see what location the bot is clicking when they have issues.  The most useful of the the debug flags for MOD writers is $debugSetlog.  When $debugSetlog is turned on (set equal to one), then these extra log messages can be seen.  Anyone writing a MOD is encouraged to add extra log messages that would help with finding bugs or user errors.  Common places for debug log messages are to check variable values, display pixel colors, or just to say code is "stuck in this loop due an error".  During 1st pass of new feature development there may be a lot of these messages. :):   As the code proves to be working in later revisions, many times the messages will be removed or simplified.   Feel free to add comments on your debug messages that tell others they can be removed when working. :):

 

[22/02/2107 update] 

MBR team has been releasing new versions for over 2 years now, and the debug capabilities inside the code have become much more complex. There are now MANY new debug flags.  Some are created to help with debug of new features like CSV scripts. Other new flags were made to reduce the amount of log data saved by separating portions of the code that are logged; such as training has a separate flag now. 

Here is the list of flags as released in v7:

Spoiler

; <><><><> debugging <><><><>
Global $g_aiSearchEnableDebugDeadBaseImage = 200 ; If $g_iDebugDeadBaseImage is 0 and more than searches reached, set $g_iDebugDeadBaseImage = 1, 0 = disabled
; Enabled saving of enemy villages when deadbase is active
Global $g_aZombie = ["" _ ; 0=Filename
    , 0 _  ; 1=Raided Elixir
    , 0 _  ; 2=Available Elixir
    , 0 _  ; 3=# of matched collectod
    , 0 _  ; 4=Search #
    , "" _ ; 5=timestamp
    , "" _ ; 6=redline
    , 30 _ ; 7=Delete screenshot when Elixir capture percentage was >= value (-1 for disable)
    , 300 _; 8=Save screenshot when skipped DeadBase and available Exlixir in k is >= value and no filled Elixir Storage found (-1 for disable)
    , 600 _; 9=Save screenshot when skipped DeadBase and available Exlixir in k is >= value (-1 for disable)
    , 150 _; 10=Save screenshot when DeadBase and available Exlixir in k is < value (-1 for disable)
]

Global $g_iDebugSearchArea = 0, $g_iDebugRedArea = 0, $g_iDebugWalls = 0, $g_iDebugVillageSearchImages = 0
Global $g_iDebugMultilanguage = 0
Global $g_iDebugGetLocation = 0 ;make a image of each structure detected with getlocation
Global $g_iDebugAndroidEmbedded = 0
Global $g_iDebugWindowMessages = 0 ; 0=off, 1=most Window Messages, 2=all Window Messages
Global $g_iDebugGDICount = 0 ; monitor bot GDI Handle count, 0 = Disabled, <> 0 = Enabled
Global $g_iDebugGDICountMax = 0 ; max value of GDI Handle count
Global $g_oDebugGDIHandles = ObjCreate("Scripting.Dictionary") ; stores GDI handles when $g_iDebugGDICount <> 0

; Milking
Global $g_iDebugResourcesOffset = 0 ;make images with offset to check correct adjust values
Global $g_iDebugMilkingIMGmake = 0
Global $g_iDebugContinueSearchElixir = 0 ; SLOW... if =1 search elixir check all images even if capacity < mincapacity and make debug image in temp folder if no match all images

; From Bot/Debug window
Global $g_iDebugClick = 0 ; Debug Bot Clicks and when docked, display current mouse position and RGB color
Global $g_iDebugSetlog = 0, $g_iDebugOcr = 0, $g_iDebugImageSave = 0, $g_iDebugBuildingPos = 0, $g_iDebugSetlogTrain = 0, $g_iDebugDisableZoomout = 0, $g_iDebugDisableVillageCentering = 0
Global $g_iDebugOCRdonate = 0 ; when 1 make OCR and simulate but do not donate
Global $g_iDebugAttackCSV = 0, $g_iDebugMakeIMGCSV = 0 ;attackcsv debug
Global $g_iDebugDeadBaseImage = 0 ; Enable collection of zombies (capture screenshot of detect DeadBase routine)

; <><><><> debugging <><><><>

 

Starting ~v5, MBR team also added "developer mode". :D   If you add a blank file named "EnabledMBRDebug.txt" in the main bot folder, it will unlock many hidden GUI settings on the debug tab.  Using developer mode, can even enable/disable some flags while the bot is running without need to edit files. ;)   Developer mode also enables an ever changing list of test buttons.  These test buttons are used to run very specific code segments, and then report the results without needing to run the bot to catch an error.  These buttons may or may not be well labeled, but one example is IMGLOC ATTACKBAR: With it you can open the goblin map or any attack, and test detection of your troops in attack bar.  There are also buttons for TH/donation/training image detection.  Note: these test buttons require you to visit the proper window before use, and there is NO support provided for these constantly changing developer mode debug features.

 

9: Variables:

We try to follow the AutoIt Best practices ( https://www.autoitscript.com/wiki/Best_coding_practices ) for variables. The only place we are radically different, is we treat all variable scope as local scope, even if it is global bot variable (read the AutoIt wiki on variable scope for more information).

To avoid having functions declare the same variable names please place all global variables in the GlobalVariables.au3 file in the \COCBot folder.  Also, While AutoIt will let you add "Local" or "DIM" statement anywhere, please not make others look for your declared variables.  All local variables should be declared at the top of the function.  The developers have not turned on the AutoIt "Must declare" compile feature as we still have a lot of legacy code to clean up first, but it will be used at a later date.

 

[22/02/2017 update] Later has arrived.  For V7+ MBR team is not enforcing "Must declare" and is also refactoring old code to fully use AutoIt standard format for global variables.

 

10: Code Organization:

There is an attempt to keep the bot code organized.  There is a lot of legacy code and the organization is constantly being improved as we find problems or better ways to structure the code.  Here is an outline of the current code directories and the purposes=

  • Root folder directory list:
    • Files= MyBot.run.au3, MyBot.run.exe, License,txt, MyBot.run.txt
    • Folders=
    • COCBot: (all AutoIt code files for the bot)
    • CSV: Holds both custom TH snipe attacks and regular attacks. Some attacks are included, but you can make your own.
    • Images: Hold all the matching images used by the code when searching including; TH, Dead base, walls, CoC error messages.
    • Languages: Holds all the language files that MBR uses when you select a different language.
    • Lib:  Holds the closed source proprietary DLL written by MBR staff.  The DLL support faster custom image searching, OCR, and several other key functions that make MBR special. Also includes encrypted XML files used for OCR, helper functions for background mode, and image search. In curl folder, curl.exe processes pushbullet commands.
    • Profiles:  user configuration files; profile.ini for profile switching and individual folders for the saved user configuration files.
    • Templates:  Location for saving standard or shared user configurations (future option - not in use yet)
  • COCBot folder directory: (2nd level of Bot code)
    • Files= MBR Functions.au3, MBR Global Variables.au3, MBR GUI Control.au3, MBR GUI Design.au3
    • Folders=
    • Functions: Most of the AutoIt code functions
    • GUI: All of the GUI Code for the individual tabs and windows.  There is one file for the design and one file with active controls or actions when the user interacts with the GUI.
  • Functions folder directory: (3rd level folder of bot code)
    • Attack: All the code for attacking (attack algorithms, troop deployment, End battle)
    • Config: Code for save/read/apply the GUI data, file of standard screen coordinates, and standard delay times
    • CreateArmy: Code used for training troops and spells
    • ImageSearch: All imaged matching/finding code functions.
    • MainScreen: All functions related to managing the normal window or BS when user base is showing. Also includes multi emulator code.
    • Other: Miscellaneous general use functions, many called by other functions internally
    • Pixels: All functions related to find/search/capture/check single pixel color or location
    • Read Text: All functions related to reading text in the various windows
    • Search: Functions related to searching for a base to attack based on user selections
    • Village: Functions that interact with the users base (donations, CC request, upgrades, etc)

 

11. Magic Numbers

Many GUI and WinAPI functions have constants that are used as parameters. These evaluate to numbers. In your functions, do not use the actual value. Instead, use the name of the constants. This makes your code much easier to read and understand.

Can you tell what the below snippets do without looking up the AutoIt help file?

GUICtrlSetState($hControl, 128)
GUICtrlSetState($hControl, $GUI_DISABLE)

As you can see, the bottom one is much better. More information here: https://www.autoitscript.com/wiki/Best_coding_practices#Magic_Numbers

 

12. Syntax Checking

Before you release a mod, be sure to run the SciTE builtin syntax check. Open MyBot.run.au3 and press CTRL+F5. This can find many simple bugs like undeclared variables and functions. Syntax check is also run whenever the bot is run using F5 from the editor, and will stop bot execution if it finds an error. Doing this will also allow us to implement your mod into the official version much more easily.

 

That is all for now.  When We think of more items to add, you will see them here....

 

And thanks for your MOD contributions!

Edited by monkeyhunter
  • Like 1
  • Upvote 2

Share this post


Link to post
Share on other sites

Starting with v7 release, MBR team has started refactoring old code to follow the AutoIt standard format for Global Variable naming. 

v7.0.0 is approximately 60-70% complete with refactoring, and future releases will change ALL global variables to comply with standard.

 

Best Practices section on debugging has also been updated with new information. :O 

 

Edited by monkeyhunter
  • Upvote 2

Share this post


Link to post
Share on other sites
Guest
This topic is now closed to further replies.
Sign in to follow this  

×
×
  • Create New...