R3vo/Sandbox – User

From Bohemia Interactive Community
Jump to navigation Jump to search
mNo edit summary
(28 intermediate revisions by the same user not shown)
Line 1: Line 1:
{{TOC|side}}
{{TOC|side}}
If you have ever wondered why you scenario is running so badly, performance profiling is the way to find it out. It allows you to find bottlenecks and slow code by capturing a "slow" frame.
The captured data can then be viewed and analysed.


= Arma 3: Module Configuration
== Getting the correct Version ==
Profiling is enabled in the following {{arma3}} versions
* arma3profiling_x64.exe - '''Part of the Performance Profiling Build'''
* arma3diag_x64.exe - '''Part of the Development Build'''


This page can be considered a hub when it comes to [[Modules]].
Read [[Arma_3: Steam Branches]] for a guide on how to access these branches.
Here you will find everything you need to know when it comes to creating modules, available modules in {{arma3}} and existing module documentation.


{{Feature|informative|It is recommended to use the '''Performance Profiling Build''' (arma3profiling_x64.exe) for performance profiling because:
* Has tools that might not make it into development build
* Has all the profiling related commands that ''arma3diag_x64.exe'' has
* Its performance is closer to the default ''arma3_x64.exe''}}


== General Information ==
== Frame Capturing ==
There are several commands that allow you to capture a frame.
* [[diag_captureFrame]]
* [[diag_captureSlowFrame]]
* [[diag_logSlowFrame]] - not available in Arma 3 :(
* [[diag_captureFrameToFile]]
In most cases you do not want to capture any or all frames, you just want to capture "slow" frames. A slow frame is a frame that takes longer than the average frame and slows down the game.


* Modules are executed before initServer.sqf, initPlayerLocal.sqf and initPlayerServer.sqf (See [[Initialisation Order]])
== How to Use ==
* Modules are very easy to set up, even for unexperienced users
# Run a mission
* They can easily be used to create mission templates
# Execute a scripted command <sqf inline>diag_captureSlowFrame ["total", 0.3];</sqf> using any means ([[Arma 3: Debug Console|Debug Console]], mission radio trigger...)
# Once a slow frame is detected, a window will open
# In the window you will be able to browse a lot of performance-related data, which can be interesting
# To export the gathered information for sharing with others:
## Select Main Thread (if not selected yet)
## Press the Copy button
## Open an external text editor
## Paste the text into a new file
## Save the file


== Create a Module Addon ==
== Capture Frame UI ==
[[File: arma3-capture frame ui overview.png]]


* Make a folder named ''{{Color|purple|TAG}}_addonName'' a create a ''config.cpp'' file in it.
# {{Wiki|TODO}}
* Inside, declare a CfgPatches class with your addon and its modules (in the ''units'' array). Without this, the game would not recognise the addon.
# {{Wiki|TODO}}
* Make sure the addon and all objects start with your tag, e.g. {{Color|purple|TAG_}}.
# {{Wiki|TODO}}
'''Example'''
# {{Wiki|TODO}}
class CfgPatches
# {{Wiki|TODO}}
{
# {{Wiki|TODO}}
class {{Color|purple|TAG}}_addonName
# {{Wiki|TODO}}
{
# {{Wiki|TODO}}
units[] = { "{{Color|purple|TAG}}_{{Color|green|Module}}{{Color|orangered|Nuke}}" };
# {{Wiki|TODO}}
requiredVersion = 1.0;
requiredAddons[] = { "A3_Modules_F" };
};
};


=== Module Category ===
== External Viewer ==
* chrome://tracing
* https://ui.perfetto.dev/


* Modules are placed into basic categories which makes finding a desired module easier.
[[File:Performance_Profiling_04.png|thumb|diag_captureFrame sample output with custom subtree]]
You can use on of the existing categories ''(See table to the right)'' or create your own category (see example below).
== Creating Your Own Subtree ==


{| class="wikitable float-right" style="max-width: 50%"
When Profiling Per-Frame Eventhandlers (PFH), [[diag_captureFrame]] only shows one blob called siFEH that contains all PFH's so you can't see what part of that is caused by your PFH.<br>
! class
You can create your own subtree inside siFEH by wrapping your function call inside a [[isNil]] CODE statement like this:<br>
! displayName
Turn your old call which may look like this:
<sqf>
addMissionEventHandler ["EachFrame", {
call myPFHFunction
}];
</sqf>
 
Into something like this:
<sqf>
addMissionEventHandler ["EachFrame", {
isNil { call myPFHFunction } // isNil creates the subtree
}];
</sqf>
 
Now when you run [[diag_captureFrame]] inside of siPFH you will have a subtree called gsEva and behind that you can see the first line of code inside the isNil statement.<br>
It will only show a part of the first line of that code so you should put something descriptive into the [[isNil]] statement.<br>
You can use the same to create a subtree for any function you like. This will also work inside [[Scheduler#Scheduled_Environment|Scheduled]] ([[spawn]]ed) scripts. <br>
But using this method to "subtree" a function with return values requires a little bit of trickery to get the return value out.
 
 
== Notes ==
 
* 0.3 is a time in second used to determine what duration of a frame you consider abnormal, and first such frame will be captured.
* 0.3 is definitely something you should not see in a normal game.
* If you do not capture any frames with 0.3, try lowering it to 0.2 or 0.1.
* If it triggers too early, before the main slowdown happens, increase it to a higher value, e.g. 1.0.
 
== Scopes ==
{| class="wikitable sortable"
|-
! Technical Name !! Descriptive Name !! Description
|-
| Main
|
|
|-
| total
|
|
|-
| fsPHa
|
|
|-
| winMs
|
|
|-
| dlcSim
|
|
|-
| steamCbk
|
|
|-
| input
|
|
|-
| wSimu
|
|
|-
| docSim
|
|
|-
| wSimDisp
|
|
|-
| MFDManager
|
|
|-
| wDisp
|
|
|-
| EventPrcs
|
|
|-
| gsEva
|
|
|-
| gbFrm
|
|
|-
| memLo
|
|
|-
| siScr
|
|
|-
| scrVM
|
|
|-
| wsSet
|
|
|-
| sLand
|
|
|-
| simSW
|
|
|-
| cLWObj
|
|
|-
| oTemp
|
|
|-
| FPres
|
|
|-
| waitSnd
|
|
|-
| job
|
|
|-
| sound
|
|
|-
| ssAdv
|
|
|-
| snCmt
|
|
|-
| play
|
|
|-
| ARTCpl
|
|
|-
| rendr
|
|
|-
| drwVi
|
|
|-
| txHLi
|
|
|-
| txPMM
|
|
|-
| dsr2t
|
|
|-
| wPrep
|
|
|-
| dPr
|
|
|-
| fmiRun
|
|
|-
| fmiWait
|
|
|-
| fmiMDrw
|
|
|-
| fmiSIns
|
|
|-
| wPrepFtr
|
|
|-
| clPrp
|
|
|-
| oPrep
|
|
|-
| sceAC
|
|
|-
| oSplt
|
|
|-
| sceACTA
|
|
|-
| sceACPrx
|
|
|-
| lodUL
|
|
|-
| PrxObj
|
|
|-
| manAn
|
|
|-
| ppdOT
|
|
|-
| flProx
|
|
|-
| PrxObjTransport
|
|
|-
| oSoSL
|
|
|-
| oSoJE
|
|
|-
| oSoJE1
|
|
|-
| oSoJE2
|
|
|-
| oSo1OFOv
|
|
|-
| oSo1ON
|
|
|-
| sceCLsHSH
|
|
|-
| prpAMCt
|
|
|-
| oSoJEw
|
|
|-
| pDrwFNP
|
|
|-
| oSoSLu
|
|
|-
| lPGCl
|
|
|-
| pdDrw
|
|
|-
| lDGnd
|
|
|-
| lGSMM
|
|
|-
| recCB
|
|
|-
| mtPmj
|
|
|-
| cuDrw
|
|
|-
| prepT
|
|
|-
| drwCB
|
|
|-
| oPasD
|
|
|-
| o1Drw
|
|
|-
| lckDnBf
|
|
|-
| prpTx
|
|
|-
| inst
|
|
|-
| stpSctnTL
|
|
|-
| o1ShV
|
|
|-
| scSVI
|
|
|-
| oPas3
|
|
|-
| sssmC
|
|
|-
| sbDrw
|
|
|-
| aniMt
|
|
|-
| ppSSSM
|
|
|-
| drwROM
|
|
|-
| drwIn
|
|
|-
| wDraw
|
|
|-
| lDPGT
|
|
|-
| oSDrw
|
|
|-
| oPasO
|
|
|-
| lDSky
|
|
|-
| swRdr
|
|
|-
| ppSWDD
|
|
|-
| swRdGeom
|
|
|-
| swRdGeomVB
|
|
|-
| swFillV
|
|
|-
| oPasA
|
|
|-
| ppShrpn
|
|
|-
| lDWat
|
|
|-
| oPas2
|
|
|-
| o2Drw
|
|
|-
| oPas5
|
|
|-
| o5Drw
|
|
|-
| EDraw3D
|
|
|-
| MEventPrcs
|
|
|-
| cLGSY
|
|
|-
| stpAll
|
|
|-
| stpCB
|
|
|-
| stpTxtCS
|
|
|-
| stpUAVsCS
|
|
|-
| ppHDRCL
|
|
|-
| ppGSB
|
|
|-
| ppDOF
|
|
|-
| ppGlwNw
|
|
|-
| ppGLu
|
|
|-
| stpCBUpd
|
|
|-
| ppQWt
|
|
|-
| ppCMAA
|
|
|-
| hudDr
|
|
|-
| 3DEN_UI_OnDraw
|
|
|-
| 3DEN_PrepareDraw
|
|
|-
| clObL
|
|
|-
| 3DEN_Drawing
|
|
|-
| stpTxtGS
|
|
|-
| txt2D
|
|
|-
| mapDr
|
|
|-
| mapSeaAndNormal
|
|
|-
| mapPM
|
|
|-
| lndPM
|
|
|-
| MapObjectsPrepTask
|
|
|-
| mapSeaAndNormalDraw
|
|
|-
| mapCntDraw
|
|
|-
| mapObjectsDraw
|
|
|-
| mapForestShape
|
|
|-
| mapGrid
|
|
|-
|-
| ''Effects''
| drwFn
| Effects
|
|  
|-
|-
| ''Events''
| dtTot
| Events
|
|  
|-
|-
| ''Modes''
| wFram
| Gameplay Modes
|
|  
|-
|-
| ''GroupModifiers''
| 3dSwp
| Group Modifiers
|
|  
|-
|-
| ''Intel''
| preLd
| Intel
|
|  
|-
|-
| ''NO_CATEGORY''
| preLV
| Misc
|
|  
|-
|-
| ''Multiplayer''
| actObjPrld
| Multiplayer
|
|  
|-
|-
| ''ObjectModifiers''
| hashChk
| Object Modifiers
|
|  
|-
|-
| ''Sites''
| sSim
| Sites
|
|  
|-
|-
| ''StrategicMap''
| enfWorkShort
| Strategic
|
|  
|-
|-
| ''Supports''
| updAttPos
| Supports
|  
|}
|  
'''Example'''
|-
class CfgFactionClasses
| oSo1AN
{
|
class NO_CATEGORY;
|
class {{Color|purple|TAG}}_{{Color|teal|explosions}}: NO_CATEGORY
|-
{
| prpAMCf
displayName = "Explosions";
|  
};
|  
};
|-
 
| prpAMCSlt
=== Creating the Module Config ===
|
 
|
* All in-game objects (soldiers, vehicles, buildings, logics, modules, ...) are defined in ''CfgVehicles'' class.
|-
* '''All modules must inherit from Module_F''' parent class, either directly or through some additional sub-parent.
| prpSDM
* Modules functions are by default '''not''' executed when in [[:Category:Eden Editor|Eden Editor]] workspace. It can be enabled using '''is3DEN''' property, but that will also change format of function params.
|
 
|
'''Example:'''
|-
<spoiler>
| locL
<syntaxhighlight lang="cpp">
|
class CfgVehicles
|
{
|-
class Logic;
| mapSeaAndNormalWork
class Module_F : Logic
|
{
|
class AttributesBase
|-
{
| mapObjectsPrepWork
class Default;
|
class Edit; // Default edit box (i.e. text input field)
|
class Combo; // Default combo box (i.e. drop-down menu)
|-
class Checkbox; // Default checkbox (returned value is Boolean)
| drwIdxPrm
class CheckboxNumber; // Default checkbox (returned value is Number)
|
class ModuleDescription; // Module description
|
class Units; // Selection of units on which the module is applied
|-
};
| oSo3
 
|
// Description base classes (for more information see below):
|
class ModuleDescription
|-
{
| lsCVB
class AnyBrain;
|
};
|
};
|-
 
| oSo5
class TAG_Module_Nuke : Module_F
|
{
|
// Standard object definitions:
|-
scope = 2; // Editor visibility; 2 will show it in the menu, 1 will hide it.
| oSo2CL
displayName = "Nuclear Explosion"; // Name displayed in the menu
|
icon = "\TAG_addonName\data\icon_Nuke_ca.paa"; // Map icon. Delete this entry to use the default icon.
|
category = "Effects";
|-
 
| oSo1AF
function = "TAG_fnc_moduleNuke"; // Name of function triggered once conditions are met
|
functionPriority = 1; // Execution priority, modules with lower number are executed first. 0 is used when the attribute is undefined
|
isGlobal = 1; // 0 for server only execution, 1 for global execution, 2 for persistent global execution
|-
isTriggerActivated = 1; // 1 for module waiting until all synced triggers are activated
| Visualize
isDisposable = 1; // 1 if modules is to be disabled once it is activated (i.e. repeated trigger activation will not work)
|
is3DEN = 1; // 1 to run init function in Eden Editor as well
|  
curatorCanAttach = 1; // 1 to allow Zeus to attach the module to an entity
|-
curatorInfoType = "RscDisplayAttributeModuleNuke"; // Menu displayed when the module is placed or double-clicked on by Zeus
| visul
 
|
// 3DEN Attributes Menu Options
|
canSetArea = 1; // Allows for setting the area values in the Attributes menu in 3DEN
canSetAreaShape = 1; // Allows for setting "Rectangle" or "Ellipse" in Attributes menu in 3DEN
class AttributeValues
{
// This section allows you to set the default values for the attributes menu in 3DEN
size3[] = { 100, 100, -1 }; // 3D size (x-axis radius, y-axis radius, z-axis radius)
isRectangle = 0; // Sets if the default shape should be a rectangle or ellipse
};
 
// Module attributes (uses https://community.bistudio.com/wiki/Eden_Editor:_Configuring_Attributes#Entity_Specific):
class Attributes : AttributesBase
{
// Arguments shared by specific module type (have to be mentioned in order to be present):
class Units : Units
{
property = "TAG_Module_Nuke_Units";
};
 
// Module-specific arguments:
class Yield : Combo
{
property = "TAG_Module_Nuke_Yield"; // Unique property (use "<tag>_<moduleClass>_<attributeClass>" format to ensure that the name is unique)
displayName = "Nuclear weapon yield"; // Argument label
tooltip = "How strong will the explosion be"; // Tooltip description
typeName = "NUMBER"; // Value type, can be "NUMBER", "STRING" or "BOOL"
defaultValue = "50"; // Default attribute value. Warning: this is an expression, and its returned value will be used (50 in this case).
 
// Listbox items
class Values
{
class 50Mt { name = "50 megatons"; value = 50; };
class 100Mt { name = "100 megatons"; value = 100; };
};
};
 
class Name : Edit
{
displayName = "Name";
tooltip = "Name of the nuclear device";
property = "TAG_Module_Nuke_Name";
// Default text for the input box:
defaultValue = """Tsar Bomba"""; // Because this is an expression, one must have a string within a string to return a string
};
 
class ModuleDescription : ModuleDescription {}; // Module description should be shown last
};
 
// Module description (must inherit from base class, otherwise pre-defined entities won't be available)
class ModuleDescription : ModuleDescription
{
description = "Short module description"; // Short description, will be formatted as structured text
sync[] = { "LocationArea_F" }; // Array of synced entities (can contain base classes)
 
class LocationArea_F
{
description[] = { // Multi-line descriptions are supported
"First line",
"Second line"
};
position = 1; // Position is taken into effect
direction = 1; // Direction is taken into effect
optional = 1; // Synced entity is optional
duplicate = 1; // Multiple entities of this type can be synced
synced[] = { "BluforUnit", "AnyBrain" }; // Pre-defined entities like "AnyBrain" can be used (see the table below)
};
 
class BluforUnit
{
description = "Short description";
displayName = "Any BLUFOR unit"; // Custom name
icon = "iconMan"; // Custom icon (can be file path or CfgVehicleIcons entry)
side = 1; // Custom side (determines icon color)
};
};
};
};
</syntaxhighlight>
</spoiler>
 
[[File:A3 modules info.jpg|230px|thumb|[[2D Editor]]: The description is available after clicking on "Show Info" button when editing the module]]
[[File:A3 3den ModuleDescription.jpg|thumb|230px|[[:Category:Eden Editor|Eden Editor]]: The description is available after opening the modules' attributes window]]
 
Pre-defined sync preview entities can be:
{| class="wikitable"
! Class
! Descripton
|-
|-
| ''Anything''
| txMLo
| Any object - persons, vehicles, static objects, etc.
|
|  
|-
|-
| ''AnyPerson''
| oSo2Srt
| Any person. Not vehicles or static objects.
|
|  
|-
|-
| ''AnyVehicle''
| oSoSdw
| Any vehicle. No persons or static objects.
|
|  
|-
|-
| ''GroupModifiers''
| prpAMCbsi
| Group Modifiers
|
|  
|-
|-
| ''AnyStaticObject''
| prpAMCp
| Any static object. Not persons or vehicles.
|
|  
|-
|-
| ''AnyBrain''
| Render
| Any AI or player. Not empty objects
|
|  
|-
|-
| ''AnyAI''
| bgD3D
| Any AI unit. Not players or empty objects
|
|  
|-
|-
| ''AnyPlayer''
| stpTxtVS
| Any player. Not AI units or empty objects
|
|  
|-
|-
| ''EmptyDetector''
| ppHBAOPlus
| Any trigger
|
|  
|}
|}


=== Configuring the Module Function ===
<sqf>
private _ctrlTV = ctrlparent (_this select 0) displayCtrl 101;


* Place '' class CfgFunctions'' to ''config.cpp''. See [[Arma 3: Functions Library]] for more info about functions configuration.
private _export = "{| class=""wikitable sortable"""  + endl + "|-" + endl;
'''Example'''<br>
_export = _export + "! Technical Name !! Descriptive Name !! Description";
<spoiler>
class CfgFunctions
{
class {{Color|indigo|TAG}}
{
class {{Color|teal|Effects}}
{
file = "\{{Color|indigo|TAG}}_addonName\functions";
class {{Color|green|module}}{{Color|orangered|Nuke}} {};
};
};
};
</spoiler>


=== Writing the Module Function ===
private _fnc_logChilden =
{
    params ["_path"];


* Create the ''functions'' folder within the addon folder and place *.sqf or *.fsm files there.
    for "_i" from 0 to ((_ctrlTV tvCount _path) - 1) do
* Example: ''\{{Color|indigo|TAG}}_addonName\functions\fn_{{Color|green|module}}{{Color|orangered|Nuke}}.sqf''
    {
* Input parameters differ based on value of ''is3DEN'' property.
        private _text = _ctrlTV tvText (_path + [_i]);
        _text = _text splitString " " select 0;


'''Default Example''' (is3DEN = 0)<br>
        if !(_text in _export) then
<spoiler>
        {
<sqf>
            _export = _export + endl + "|-" + endl + "| " + _text + endl + "| " + endl + "| ";
params [
        };
["_logic", objNull, [objNull]], // Argument 0 is module logic
["_units ", [], [[]]], // Argument 1 is a list of affected units (affected by value selected in the 'class Units' argument))
["_activated", true, [true]] // True when the module was activated, false when it is deactivated (i.e., synced triggers are no longer active)
];


// Module specific behavior. Function can extract arguments from logic and use them.
        if (_ctrlTV tvCount (_path + [_i]) > 0 ) then
if (_activated) then
        {
{
            [_path + [_i]] call _fnc_logChilden;
// Attribute values are saved in module's object space under their class names
        };
private _bombYield = _logic getVariable ["Yield", -1]; // (as per the previous example, but you can define your own)
    };
hint format ["Bomb yield is: %1", _bombYield]; // will display the bomb yield, once the game is started
};
};
// Module function is executed by spawn command, so returned value is not necessary, but it is good practice.
 
true;
[[]] call _fnc_logChilden;
 
copyToClipboard (_export + endl + "|}" + endl);
</sqf>
</sqf>
</spoiler>


'''Example Eden Editor''' (is3DEN = 1)<br>
== See Also ==
<spoiler>
 
When '''is3DEN = 1''' is set in module config, different, more detailed params are passed to the function.
* [[Code Optimisation]]
<sqf>
* [[Mission Optimisation]]
params [
["_mode", "", [""]],
["_input", [], [[]]]
];


switch _mode do
{
// Default object init
case "init":
{
_input params [
["_logic", objNull, [objNull]], // Module logic
["_isActivated", true, [true]], // True when the module was activated, false when it is deactivated
["_isCuratorPlaced", false, [true]] // True if the module was placed by Zeus
];
// ... code here...
};
// When some attributes were changed (including position and rotation)
case "attributesChanged3DEN": {
_input params [
["_logic", objNull, [objNull]]
];
// ... code here...
};
// When added to the world (e.g., after undoing and redoing creation)
case "registeredToWorld3DEN": {
_input params [
["_logic", objNull, [objNull]]
];
// ... code here...
};
// When removed from the world (i.e., by deletion or undoing creation)
case "unregisteredFromWorld3DEN": {
_input params [
["_logic", objNull, [objNull]]
];
// ... code here...
};
// When connection to object changes (i.e., new one is added or existing one removed)
case "connectionChanged3DEN": {
_input params [
["_logic", objNull, [objNull]]
];
// ... code here...
};
// When object is being dragged
case "dragged3DEN": {
_input params [
["_logic", objNull, [objNull]]
];
// ...code here...
};
};
true;
</sqf>
</spoiler>


{{GameCategory|arma2|Editing}}
[[Category:Arma Scripting Tutorials]]
{{GameCategory|arma3|Editing}}
[[Category:Take On Helicopters: Editing]]

Revision as of 18:23, 4 November 2024

If you have ever wondered why you scenario is running so badly, performance profiling is the way to find it out. It allows you to find bottlenecks and slow code by capturing a "slow" frame. The captured data can then be viewed and analysed.

Getting the correct Version

Profiling is enabled in the following Arma 3 versions

  • arma3profiling_x64.exe - Part of the Performance Profiling Build
  • arma3diag_x64.exe - Part of the Development Build

Read Arma_3: Steam Branches for a guide on how to access these branches.

It is recommended to use the Performance Profiling Build (arma3profiling_x64.exe) for performance profiling because:
  • Has tools that might not make it into development build
  • Has all the profiling related commands that arma3diag_x64.exe has
  • Its performance is closer to the default arma3_x64.exe

Frame Capturing

There are several commands that allow you to capture a frame.

In most cases you do not want to capture any or all frames, you just want to capture "slow" frames. A slow frame is a frame that takes longer than the average frame and slows down the game.

How to Use

  1. Run a mission
  2. Execute a scripted command diag_captureSlowFrame ["total", 0.3]; using any means (Debug Console, mission radio trigger...)
  3. Once a slow frame is detected, a window will open
  4. In the window you will be able to browse a lot of performance-related data, which can be interesting
  5. To export the gathered information for sharing with others:
    1. Select Main Thread (if not selected yet)
    2. Press the Copy button
    3. Open an external text editor
    4. Paste the text into a new file
    5. Save the file

Capture Frame UI

arma3-capture frame ui overview.png

  1. 🚧
    TODO: this must be updated.
  2. 🚧
    TODO: this must be updated.
  3. 🚧
    TODO: this must be updated.
  4. 🚧
    TODO: this must be updated.
  5. 🚧
    TODO: this must be updated.
  6. 🚧
    TODO: this must be updated.
  7. 🚧
    TODO: this must be updated.
  8. 🚧
    TODO: this must be updated.
  9. 🚧
    TODO: this must be updated.

External Viewer

diag_captureFrame sample output with custom subtree

Creating Your Own Subtree

When Profiling Per-Frame Eventhandlers (PFH), diag_captureFrame only shows one blob called siFEH that contains all PFH's so you can't see what part of that is caused by your PFH.
You can create your own subtree inside siFEH by wrapping your function call inside a isNil CODE statement like this:
Turn your old call which may look like this:

addMissionEventHandler ["EachFrame", { call myPFHFunction }];

Into something like this:

addMissionEventHandler ["EachFrame", { isNil { call myPFHFunction } // isNil creates the subtree }];

Now when you run diag_captureFrame inside of siPFH you will have a subtree called gsEva and behind that you can see the first line of code inside the isNil statement.
It will only show a part of the first line of that code so you should put something descriptive into the isNil statement.
You can use the same to create a subtree for any function you like. This will also work inside Scheduled (spawned) scripts.
But using this method to "subtree" a function with return values requires a little bit of trickery to get the return value out.


Notes

  • 0.3 is a time in second used to determine what duration of a frame you consider abnormal, and first such frame will be captured.
  • 0.3 is definitely something you should not see in a normal game.
  • If you do not capture any frames with 0.3, try lowering it to 0.2 or 0.1.
  • If it triggers too early, before the main slowdown happens, increase it to a higher value, e.g. 1.0.

Scopes

Technical Name Descriptive Name Description
Main
total
fsPHa
winMs
dlcSim
steamCbk
input
wSimu
docSim
wSimDisp
MFDManager
wDisp
EventPrcs
gsEva
gbFrm
memLo
siScr
scrVM
wsSet
sLand
simSW
cLWObj
oTemp
FPres
waitSnd
job
sound
ssAdv
snCmt
play
ARTCpl
rendr
drwVi
txHLi
txPMM
dsr2t
wPrep
dPr
fmiRun
fmiWait
fmiMDrw
fmiSIns
wPrepFtr
clPrp
oPrep
sceAC
oSplt
sceACTA
sceACPrx
lodUL
PrxObj
manAn
ppdOT
flProx
PrxObjTransport
oSoSL
oSoJE
oSoJE1
oSoJE2
oSo1OFOv
oSo1ON
sceCLsHSH
prpAMCt
oSoJEw
pDrwFNP
oSoSLu
lPGCl
pdDrw
lDGnd
lGSMM
recCB
mtPmj
cuDrw
prepT
drwCB
oPasD
o1Drw
lckDnBf
prpTx
inst
stpSctnTL
o1ShV
scSVI
oPas3
sssmC
sbDrw
aniMt
ppSSSM
drwROM
drwIn
wDraw
lDPGT
oSDrw
oPasO
lDSky
swRdr
ppSWDD
swRdGeom
swRdGeomVB
swFillV
oPasA
ppShrpn
lDWat
oPas2
o2Drw
oPas5
o5Drw
EDraw3D
MEventPrcs
cLGSY
stpAll
stpCB
stpTxtCS
stpUAVsCS
ppHDRCL
ppGSB
ppDOF
ppGlwNw
ppGLu
stpCBUpd
ppQWt
ppCMAA
hudDr
3DEN_UI_OnDraw
3DEN_PrepareDraw
clObL
3DEN_Drawing
stpTxtGS
txt2D
mapDr
mapSeaAndNormal
mapPM
lndPM
MapObjectsPrepTask
mapSeaAndNormalDraw
mapCntDraw
mapObjectsDraw
mapForestShape
mapGrid
drwFn
dtTot
wFram
3dSwp
preLd
preLV
actObjPrld
hashChk
sSim
enfWorkShort
updAttPos
oSo1AN
prpAMCf
prpAMCSlt
prpSDM
locL
mapSeaAndNormalWork
mapObjectsPrepWork
drwIdxPrm
oSo3
lsCVB
oSo5
oSo2CL
oSo1AF
Visualize
visul
txMLo
oSo2Srt
oSoSdw
prpAMCbsi
prpAMCp
Render
bgD3D
stpTxtVS
ppHBAOPlus

private _ctrlTV = ctrlparent (_this select 0) displayCtrl 101; private _export = "{| class=""wikitable sortable""" + endl + "|-" + endl; _export = _export + "! Technical Name !! Descriptive Name !! Description"; private _fnc_logChilden = { params ["_path"]; for "_i" from 0 to ((_ctrlTV tvCount _path) - 1) do { private _text = _ctrlTV tvText (_path + [_i]); _text = _text splitString " " select 0; if !(_text in _export) then { _export = _export + endl + "|-" + endl + "| " + _text + endl + "| " + endl + "| "; }; if (_ctrlTV tvCount (_path + [_i]) > 0 ) then { [_path + [_i]] call _fnc_logChilden; }; }; }; [[]] call _fnc_logChilden; copyToClipboard (_export + endl + "|}" + endl);

See Also