Release EDDI Scripts and EDDI enabled VA Commands Thread

Excellent find! Was reading through these posts waiting for someone to catch that ;) Don't feel bad, I've been working with VA for five years, and have a public profile with over a thousand downloads, yet still I make simple mistakes with tokens now and then... just the other day, I was adding tons of debug 'write to event log' actions to sus out an error for a nested token variable - darn thing worked in the 'multi-command' above it, couldn't see why it wouldn't work for the 'single-command' version of the same even as I reviewed spelling for typos, didn't catch the actual issue:
{TXT:AVCS_QCC_DATA_MACROS_{{TXT:~avcs_choice_command}}}
was supposed to be:
{TXT:AVCS_QCC_DATA_MACROS_{TXT:{TXT:~avcs_choice_command}}}
😣

FYI: You can also do without the "Save value to profile" (unless you are loading this variable to retrieve info when this profile first loads) -- and if you are using QuantityBefore in this command alone, and not passing it around or needing to refer to it later, you can change the scope of that variable from Global to something that will be destroyed once this command is completed: ~QuantityBefore is command scoped, will be read/used by this command, then will no longer exist until this command runs again. See VoiceAttack Manual for more details on Advanced Variable Control (Scope and Events)
Thanks for your valuable info. I'm still new at this, but I can already see what a well-thought-out program VA is. I've got a lot of reading to do :)
 
Hi @SemlerPDX ,
I just read you are very knowledgeable about VA. Maybe you can help me. I use a little the macro possibilities of VA.
The voice control is secondary for me. I would like to simplify the menu navigation via the keyboard.
The automatic obtaining of the landing permission is known. But the calling of the menus gets confused,
if one has called e.g. the TAB "Contacts", which is not always available. How to work around this problem.
And secondly, if the landing permission is forbidden, the next request could be made again after approx. 5 seconds.
I have not yet managed to do this without errors.

Thanks in advance for some tips

and greetings from nepomuk

Translated with www.DeepL.com/Translator (free version)
 
Hi @SemlerPDX ,
But the calling of the menus gets confused,
if one has called e.g. the TAB "Contacts", which is not always available. How to work around this problem.
Hello sir. This is my "Contacts", it uses [Status vehicle] to check whether you're in a fighter (where Navigation is unavailable), and [Status gui focus] to see if you are already looking at that panel to move tabs instead of opening and closing again. Then custom var to track which tab you're in. Also had to check whether you have a target locked, which would make the number of tabs different.
Code:
Begin Small Integer Compare : [calibration] Equals 1
    Set small int (condition) [calibration] value to 0
    Set small int (condition) [left-panel-tab] value to 3
    Set small int (condition) [5-timer] value to 0
End Condition - Exit when condition met
Begin Text Compare : [Status vehicle] Equals 'Fighter'
    Begin Boolean Compare : [EDDI ship targeted targetlocked] Equals True
        Begin Text Compare : [Status gui focus] Does Not Equal 'external panel'
            Execute command, 'Left Panel' (and wait until it completes)
            Pause 1.2 seconds
        End Condition
        Begin Small Integer Compare : [left-panel-tab] Equals 2
            Execute command, 'Tab Next' (and wait until it completes)
        End Condition
        Begin Small Integer Compare : [left-panel-tab] Equals 4
            Execute command, 'Tab Previous' (and wait until it completes)
        End Condition
        Begin Small Integer Compare : [vocal-response] Equals 1
            Say, '{CMD}'
        End Condition - Exit when condition met
    Else
        Begin Text Compare : [Status gui focus] Does Not Equal 'external panel'
            Execute command, 'Left Panel' (and wait until it completes)
            Pause 1.2 seconds
        End Condition
        Begin Small Integer Compare : [left-panel-tab] Equals 2
            Execute command, 'Tab Next' (and wait until it completes)
        End Condition
        Begin Small Integer Compare : [vocal-response] Equals 1
            Say, '{CMD}'
        End Condition - Exit when condition met
    End Condition - Exit when condition met
Else
    Begin Boolean Compare : [EDDI ship targeted targetlocked] Equals True
        Begin Text Compare : [Status gui focus] Does Not Equal 'external panel'
            Execute command, 'Left Panel' (and wait until it completes)
            Pause 1.2 seconds
        End Condition
        Begin Small Integer Compare : [left-panel-tab] Equals 1
            Execute command, 'Tab Next 2' (and wait until it completes)
        End Condition
        Begin Small Integer Compare : [left-panel-tab] Equals 2
            Execute command, 'Tab Next' (and wait until it completes)
        End Condition
        Begin Small Integer Compare : [left-panel-tab] Equals 4
            Execute command, 'Tab Previous' (and wait until it completes)
        End Condition
        Begin Small Integer Compare : [vocal-response] Equals 1
            Say, '{CMD}'
        End Condition - Exit when condition met
    Else
        Begin Text Compare : [Status gui focus] Does Not Equal 'external panel'
            Execute command, 'Left Panel' (and wait until it completes)
            Pause 1.2 seconds
        End Condition
        Begin Small Integer Compare : [left-panel-tab] Equals 1
            Execute command, 'Tab Next 2' (and wait until it completes)
        End Condition
        Begin Small Integer Compare : [left-panel-tab] Equals 2
            Execute command, 'Tab Next' (and wait until it completes)
        End Condition
        Begin Small Integer Compare : [vocal-response] Equals 1
            Say, '{CMD}'
        End Condition - Exit when condition met
    End Condition - Exit when condition met
End Condition - Exit when condition met

Docking request is bugged if your first request is denied. To solve it, go right left right to "refresh" the cursor.
Code:
Execute command, 'UI Panel RIGHT - bindED' (and wait until it completes)
Pause 0.1 seconds
Execute command, 'UI Panel LEFT - bindED' (and wait until it completes)
Pause 0.1 seconds
Execute command, 'UI Panel RIGHT - bindED' (and wait until it completes)
Pause 0.1 seconds
Execute command, 'UI Panel SELECT - bindED' (and wait until it completes)
Pause 0.05 seconds
 
Last edited:
Hi @SemlerPDX ,
...
The automatic obtaining of the landing permission is known. But the calling of the menus gets confused,
if one has called e.g. the TAB "Contacts", which is not always available. How to work around this problem.
And secondly, if the landing permission is forbidden, the next request could be made again after approx. 5 seconds.
I have not yet managed to do this without errors.

One pro tip for using VA and macros to control your UI Panels is to turn off 'look at panel' to display it - this way you can look anywhere without accidentally pulling up a UI panel, and this is essential to ensuring macros do not get out of sorts, and start pushing all sorts of buttons incorrectly because they started off on the wrong page/tab/etc. This can be very troublesome especially if you are in a hurry to avoid getting scanned with a cargo hold full of contraband.

Second, when it comes to these UI panels, since there is no "reset" and the UI will remain on a tab/page it was last set to, I force all my UI macros to start from (and return to) the first panel. So, if the action is to open the left panel, move over a couple tabs, and press a button on the panel, the next steps are to move back the same number of tabs and close the panel.

I put most everything I can into "config" commands or files, these are where my global variables are set, and get read each time the profile is loaded. I use a variable pause for the time between keypresses and the time a key is held down, so they can be fine tuned in one location for all commands with keypresses, so this may look odd - also is old, probably needs some tweaking as I begin to recreate my systems in my new AVCS CORE Framework profile family for VoiceAttack.

The idea is to always return menus to where they started, so the next Macro can do it's thing properly. When I must manually navigate menus, I always return them to the first/leftmost panel and close them, so they are ready for any voice macro menu actions. I also set a boolean called "AVCS_Macros_ON", and in other sensitive commands, check if this is true before attempting to fire another macro so that two can never operate at the same time (the script below is a separate command 'called' by my voice command for Request Docking, where that check occurs):

Code:
//Dynamic Keypress Macro - Request Docking
//   ***This Script expects the Left Panel to be resting on the leftmost Navigation Panel and closed***
// by SemlerPDX Jan2019
// VETERANS-GAMING.COM
//
Set Boolean [AVCS_Macros_ON] to True
Press down variable key(s) [edFocusLeftPanel]
Pause a variable number of seconds [AVCS_QCC_TimeHeldDown]
Release variable key(s) [edFocusLeftPanel]
Pause a variable number of seconds [AVCS_QCC_TimeBetween]
//
Press down variable key(s) [edCycleNextPanel]
Pause a variable number of seconds [AVCS_QCC_TimeHeldDown]
Release variable key(s) [edCycleNextPanel]
Pause a variable number of seconds [AVCS_QCC_TimeBetween]
Press down variable key(s) [edCycleNextPanel]
Pause a variable number of seconds [AVCS_QCC_TimeHeldDown]
Release variable key(s) [edCycleNextPanel]
Pause a variable number of seconds [AVCS_QCC_TimeBetween]
//
Press down variable key(s) [edUI_Right]
Pause a variable number of seconds [AVCS_QCC_TimeHeldDown]
Release variable key(s) [edUI_Right]
Pause a variable number of seconds [AVCS_QCC_TimeBetween]
Press down variable key(s) [edUI_Select]
Pause a variable number of seconds [AVCS_QCC_TimeHeldDown]
Release variable key(s) [edUI_Select]
Pause a variable number of seconds [AVCS_QCC_TimeBetween]
//
Press down variable key(s) [edCyclePreviousPanel]
Pause a variable number of seconds [AVCS_QCC_TimeHeldDown]
Release variable key(s) [edCyclePreviousPanel]
Pause a variable number of seconds [AVCS_QCC_TimeBetween]
Press down variable key(s) [edCyclePreviousPanel]
Pause a variable number of seconds [AVCS_QCC_TimeHeldDown]
Release variable key(s) [edCyclePreviousPanel]
Pause a variable number of seconds [AVCS_QCC_TimeBetween]
//
Press down variable key(s) [edUI_Back]
Pause a variable number of seconds [AVCS_QCC_TimeHeldDown]
Release variable key(s) [edUI_Back]
Pause a variable number of seconds [AVCS_QCC_TimeBetween]
Set Boolean [AVCS_Macros_ON] to False

Best wishes and good luck!
Personally, when I use my macro to request docking and it is denied, I manually wait for 5 seconds and issue the voice command again - since my first macro returns to leftmost panel anyway, it is already reset and ready to fire again as needed - this is something I would not prefer to have on an automated system for detecting that it was denied and auto-refire at 5 second mark cuz computers are stupid and need supervision; can't account for every scenario so easily ;)

As far as the appearance of a panel that is not always there (contacts), then it is most important for you as the user to know when this macro is safe to call. It will always be there when you are within range of a docking station IIRC, so is a non-issue there.

EDIT: Also wanted to note that, as opposed to doing checks each time during a macro command, you can use all sorts of Event Triggers to set some booleans/variables as to the state of things, and just check those variables as needed to ensure your commands "can" fire, or everything is in the correct state to fire (as bronney's example shows, where he checks for deployed fighter, target lock, etc.)

These are the triggers I currently use (well, used, as noted haven't worked on this profile since 2019):
qqvwwnX.png



Hello sir. This is my "Contacts", it uses [Status vehicle] to check whether you're in a fighter (where Navigation is unavailable), and [Status gui focus] to see if you are already looking at that panel to move tabs instead of opening and closing again. Then custom var to track which tab you're in. Also had to check whether you have a target locked, which would make the number of tabs different.

That's some excellent problem solving there, accounting for the curve balls that can get thrown around. If I might offer some constructive criticism, the actions to execute another command in order to push buttons such as 'Tab Previous' or such has a timing hit to be considered compared to simply pressing the correct key at that stage, and since this is a macro, and there are many of them, they all add up and complicate any optimization and fine control of the speed. You can set variables to hold the key to press, and they can be called whatever you want (even 'Tab Previous'), or if this is for public distribution, you might consider using some version of the plugin 'bindED' which presents you with callbacks which correlate to whatever the user has saved in their Controls in Elite Dangerous.

One of the coolest things about macros is that they can input keystrokes like Commander Data from Star Trek, so long as we know the 'fastest' that our computer can accept those inputs (usually no faster than 0.05 seconds button push, and time between button pushes), and by taking full control over these things, you can ensure your macros are firing (and delaying) only at your set intervals, and as fast as physically possible on your PC.
 
Last edited:
such has a considerable timing hit compared to simply pressing the correct key at that stage
Thank you. I might change them out later as I am already using bindED so it should be safe. When we first started there were no bindED that's why it got carried over :) The timing hit is very annoying that's why I launch fighters manually even though there're voice commands for it. Good advice!
 
Thank you. I might change them out later as I am already using bindED so it should be safe. When we first started there were no bindED that's why it got carried over :) The timing hit is very annoying that's why I launch fighters manually even though there're voice commands for it. Good advice!
haha! yeah! Same thing with the small integers -- those are depreciated but remain for backwards compatibility with very old profiles. Also figured your script may be part of something larger, since there is no place shown where the small integer 'calibration' becomes set to '1', triggering the setting of the global variables 'left-panel-tab' and '5-timer'.

Typically, when I have sets like that which need to be set (if not already set), I use a boolean compare condition, where "Not set" is evaluated as 'false', or integers where "Not set" is evaluated as '0', or text where "Not set" is evaluated as 'blank' to allow for one-time run of the actions inside the compare, such as setting up global variables for use later. Your compare seems to check if a value is '1' and then set it to zero, which is sortof the opposite, and holding a value for both states rather than existing with a value, or not existing at all -- but again, assuming this is part of a larger system that dictates when/if 'calibration' is set to '1' this may be the best/most desirable way for your systems to function.

The beauty of VoiceAttack, and programming in general, is that there are so many ways to accomplish a goal, and achieve the same outcome with little margin of difference between methods.

Here's how I do a first run init set of actions based on the existence of a boolean, where if it is "Not set" (or 'false') text variable, where if it is "Not set" (or 'blank'), then it will run this section setting necessary variables, and then the overall boolean to 'true' text variable to "complete" so it knows it doesn't need to run this again:

Code:
Begin Condition : ([AVCS_ACTIVE_PROFILE] Equals 'CORE' AND [AVCS_SFS_CORE_LOADED] Does Not Contain 'complete')
    Set text [AVCS_CORE_SaveFilePath] to '{TXT:AVCS_SFS_SaveFileFolderPath}\save.txt'
    Begin Text Compare : [{STATE_FILEEXISTS:AVCS_SFS_SaveFilePath}] Equals '1'
        Set text [~saved_data] to [{TXT:AVCS_SFS_SaveFilePath}]
        Begin Text Compare : [~saved_data] Does Not Equal ''
            //
            Execute command, 'F_SFS_LOAD_ALL' (by name) (and wait until it completes)
            Set text [AVCS_SFS_CORE_LOADED] to 'complete'
            //
        End Condition
    End Condition
End Condition
*(I stopped using "Save to profile" for my variables and created a save file system, so nothing gets lost even between new profile version updates, etc. Worth all the time spent!)

**Pro Tip 2: if you make all your 'Execute command' actions (by name), you will have better control over importing/deleting/copying/updating commands since they are not 'hard-linked' to a profile command, but rely on you (and the name you set) for the existence of a command. You can work on this command in some other "dev" profile version, then delete the one in your "public" profile version, and copy over the new edited one without issue this way.

(edit: not enough coffee - thought I grabbed one of my examples with a boolean - lol)
 
Last edited:
**Pro Tip 2: if you make all your 'Execute command' actions (by name), you will have better control over importing/deleting/copying/updating commands since they are not 'hard-linked' to a profile command, but rely on you (and the name you set) for the existence of a command. You can work on this command in some other "dev" profile version, then delete the one in your "public" profile version, and copy over the new edited one without issue this way.

(edit: not enough coffee - thought I grabbed one of my examples with a boolean - lol)
I was a self-taught flash actionscript dev way back in year 2000 before I became a graphic designer for 10 years and now a photographer for another 10 lol. If not for Elite I wouldn't touch those pesky if thens at all bro, "ima artist™" lol. But Ishmair made his profile (those calibration and timers are his gems), that I don't wanna touch if it's not broken. I got his approval to "steal" his public profile to improve upon in ED 2.4 and recently came back after 3 years of not playing to 3.7. I agree with your timing cut with variable key press but on the other hand, his way of doing "tab next" was what enabled a noob like me to study his stuff and make new stuff. Anyway, I've since updated the profile so that even if you manually tab with your joystick, the tab are tracked so I no longer say Modules unless my thumb is actually full :)

Guess it doesn't matter as long as the edPresses are variable keys but.. perhaps later. And yeah, it's nice running into everyone here that has an interest in making Elite more boring by automation hehehe.
 
...
Anyway, I've since updated the profile so that even if you manually tab with your joystick, the tab are tracked so I no longer say Modules unless my thumb is actually full :)

Guess it doesn't matter as long as the edPresses are variable keys but.. perhaps later. And yeah, it's nice running into everyone here that has an interest in making Elite more boring by automation hehehe.

nice!! I had never used key & tab tracking for the menus because there were plenty of times when I would press that key and not be able to differentiate which panel set was on which tab, since these same controls are multi-function and part of other game and menu interactions - but again, I have not revisited any of this either for some time. EDDI has improved a lot since then, too, so I'm looking forward to getting more efficient systems surrounding certain actions. If it's reliable enough to get info from EDDI and the Frontier API for knowing which panel is open or when they are closed, I'm sure I'll have fun making use of those for better control. At present, it left off with simple "put it back the way you found it" rules for the macros and my own manual use of panels with my X52.

Also, if it hasn't been mentioned already, it's important to turn off panel visual effects in the game options, as these can delay or cause inconsistent timing when opening a panel.
 
Hello sir. This is my "Contacts", it uses [Status vehicle] to check whether you're in a fighter (where Navigation is unavailable), and [Status gui focus] to see if you are already looking at that panel to move tabs instead of opening and closing again. Then custom var to track which tab you're in. Also had to check whether you have a target locked, which would make the number of tabs different.
[snip]
You have a great deal of repeated code there and that means that you can simplify the script by moving the repeated sections to another script. My docking request script had 22 separate scripts. However, all but one of those are used in many other places. This has the advantage of making the scripts much easier to maintain and understand. Also, my docking script does not bug if docking is denied.

Mind you, I'm also a computer programmer by trade so my scripts take advantage of the advanced features of VA such as parameter passing, expression evaluation and in a couple of places, inline c# functions.

But, whatever works for you.

I think you may also have a problem with the section of the script that starts with "Begin Boolean Compare : [EDDI ship targeted targetlocked] Equals True". As far as I can see, the only way that you get 4 active tabs on the external panel is when you have a target locked, the scan stage is 3 and you have selected the contacts tab. This has the unfortunate consequence of making the number of tabs in the panel change as you tab through the panel.

I have yet to find a reliable solution to this.
 
Last edited:
[snip]

**Pro Tip 2: if you make all your 'Execute command' actions (by name), you will have better control over importing/deleting/copying/updating commands since they are not 'hard-linked' to a profile command, but rely on you (and the name you set) for the existence of a command. You can work on this command in some other "dev" profile version, then delete the one in your "public" profile version, and copy over the new edited one without issue this way.

Pro Tip 3: Be very very careful if you do use Pro Tip 2 since you can really screw up your profile if you get it wrong. As a rule of thumb, Pro Tip 2 should be use sparingly. Using "Execute command' actions (by name)" also has the distinct disadvantage that it makes understanding the script harder since you cannot see from the script what command is being executed until you open the command edit form.
 
Pro Tip 3: Be very very careful if you do use Pro Tip 2 since you can really screw up your profile if you get it wrong. As a rule of thumb, Pro Tip 2 should be use sparingly. Using "Execute command' actions (by name)" also has the distinct disadvantage that it makes understanding the script harder since you cannot see from the script what command is being executed until you open the command edit form.

Care should definitely be taken when using any advanced methods and creating complex command systems in VoiceAttack - organization is key, but it's far more easy to break things by having tons of actions in commands that call other commands not by name, but by profile commands list - doing things right the first time can save headaches later.

When using commands in this manner as 'functions' that you call by name from many other commands, rather than repeating code in each command for a common function, the only time you can get screwed up is if you change the name of the command without changing it everywhere. It doesn't break anything to have some actions of executing another command (by name) if that command no longer exists, it just won't fire and will toss an error to the VA event log.

The solution to this is to simply export the profile expanded as .xml and do a block-replace of the command name (and thereby all references to it), and re-import the profile. As mentioned, if you're building profiles for the public, it lets you maintain and edit your commands in your DEV build, and copy/transfer them over to a Public build without the deal-breaking issues had all your 'Execute another command' actions not been set up to call (by name)

(example: https://veterans-gaming.com/index.php?/blogs/entry/41-avcs-core-profile-framework-for-voiceattack/ )
0aAF2T7.png
 
Last edited:
Care should definitely be taken when using any advanced methods and creating complex command systems in VoiceAttack - organization is key, but it's far more easy to break things by having tons of actions in commands that call other commands not by name, but by profile commands list - doing things right the first time can save headaches later.

When using commands in this manner as 'functions' that you call by name from many other commands, rather than repeating code in each command for a common function, the only time you can get screwed up is if you change the name of the command without changing it everywhere. It doesn't break anything to have some actions of executing another command (by name) if that command no longer exists, it just won't fire and will toss an error to the VA event log.

The solution to this is to simply export the profile expanded as .xml and do a block-replace of the command name (and thereby all references to it), and re-import the profile. As mentioned, if you're building profiles for the public, it lets you maintain and edit your commands in your DEV build, and copy/transfer them over to a Public build without the deal-breaking issues had all your 'Execute another command' actions not been set up to call (by name)

(example: https://veterans-gaming.com/index.php?/blogs/entry/41-avcs-core-profile-framework-for-voiceattack/ )
0aAF2T7.png
Not the way I create and develop new commands, but it obviously works for you. There's probably other ways to work as well. Still, indirection should always be used with caution.
 
Not the way I create and develop new commands, but it obviously works for you. There's probably other ways to work as well. Still, indirection should always be used with caution.
This is merely the programming equivalent of public functions outside main that may be used by multiple parts of a script, an organizational method for centralizing your work, and using the best method to call it and (in future) support it through updates/modifications. This concept is entirely for larger systems which rely upon common functions as shown in the picture.

You yourself had noted the redundancy of a 'great deal of repeated code'.

I wanted a save file system so user settings could more easily persist between physical profile updates or even reinstallation (of the profile, VA, or even Windows) since early public profiles I shared using EDDI ran into occasional inconsistencies with variables "Saved to Profile" - I would use EDDI to try to get around anything, but if there was lag or delay from the Frontier API such as requiring a jump for a state to change, I needed my own sets to fall back on (and robust enough to handle VA crashing mid-game and recover seamlessly). Rather than have a "save to file" function inside any command which needs to save a variable for later retrieval, I used the well known and supported method of non-voice commands to hold these methods so they could merely be called by any other voice command as needed by name, and especially so that if I edit/change a function of the save file system, I can do so in just ONE place. I can delete an old version from a public build, and copy over the new version of the same command from the dev build with such ease that it makes this a highly useful method worth recommending.

This is significantly saving me time right now, as I am about to release an update with a fix for the "LOAD_ALL" function -- international users which express Pi as '3,14' as opposed to my regions '3.14' were getting decimal variables loaded with the separator removed (so, 0.05 second pauses between macro keystrokes became 5 second pauses!). If I had this "load all" in several places, I would have to make sure that it was changed/edited in all places adding time and work, not to mention the great deal of repeated code. AVCS CORE (only 68 commands, expanded as XML) is already half a million lines long and takes several seconds to open in NP++ for editing AT tokens, etc.

For these reasons and others, advanced methods like this exist and while definitely should be used with caution, again with a keen attention to detail and organization, they can be the perfect solution to having a common method to use throughout many, many other voice commands in a profile with a singular place to edit and support that function.
 
Last edited:
This is merely the programming equivalent of public functions outside main that may be used by multiple parts of a script, an organizational method for centralizing your work, and using the best method to call it and (in future) support it through updates/modifications. This concept is entirely for larger systems which rely upon common functions as shown in the picture.

You yourself had noted the redundancy of a 'great deal of repeated code'.

I wanted a save file system so user settings could more easily persist between physical profile updates or even reinstallation (of the profile, VA, or even Windows) since early public profiles I shared using EDDI ran into occasional inconsistencies with variables "Saved to Profile" - I would use EDDI to try to get around anything, but if there was lag or delay from the Frontier API such as requiring a jump for a state to change, I needed my own sets to fall back on (and robust enough to handle VA crashing mid-game and recover seamlessly). Rather than have a "save to file" function inside any command which needs to save a variable for later retrieval, I used the well known and supported method of non-voice commands to hold these methods so they could merely be called by any other voice command as needed by name, and especially so that if I edit/change a function of the save file system, I can do so in just ONE place. I can delete an old version from a public build, and copy over the new version of the same command from the dev build with such ease that it makes this a highly useful method worth recommending.

This is significantly saving me time right now, as I am about to release an update with a fix for the "LOAD_ALL" function -- international users which express Pi as '3,14' as opposed to my regions '3.14' were getting decimal variables loaded with the separator removed (so, 0.05 second pauses between macro keystrokes became 5 second pauses!). If I had this "load all" in several places, I would have to make sure that it was changed/edited in all places adding time and work, not to mention the great deal of repeated code. AVCS CORE (only 68 commands, expanded as XML) is already half a million lines long and takes several seconds to open in NP++ for editing AT tokens, etc.

For these reasons and others, advanced methods like this exist and while definitely should be used with caution, again with a keen attention to detail and organization, they can be the perfect solution to having a common method to use throughout many, many other voice commands in a profile with a singular place to edit and support that function.
Quite.
I have to say that all my scripts are non-voice as I interface with VA via the keyboard and an Keys-16 button bar only.

I also use the tried and tested "make it work then refactor the heck out of it" method of development, so although I noted "a great deal of repeated code' earlier, you should have seen my first draft scripts, whilst I'm prototyping. Admittedly, as you yourself have probably already found, that as the library of useful VA script grows, so the repeated code reduces, even for new or prototype scripts.

Still, I tend to use IDEs with intellesense built in during my professional code development and the lack of that in VA is irksome. It also means that it is difficult to see what parameters are being passed to another script necessitating the organisational method you employ to keep track.

But as I said, in effect, each has their own way of working and your way would drive me up the wall. I dare say that mine would do that to you as well. Having said that, I also use NP++ extensively.

In the end, as long as there is a robust and resilient set of scripts, then who really cares under which methodology they were developed.

I said "robust and resilient" there with some tongue in cheek, since the VA/ED combination relies in many places on a lot of guess work, there been little feedback from ED to VA, and as a result achieving the two 'R's is not easy. Hopefully we will get some more journal and status updates along the lines of extending "Status gui focus" in future. But I'm not holding my breath.

I should also note that I'm only developing VA scripts for my own use, including my carrier navigator, so I don't really have to worry too much about distribution.
 
...
Still, I tend to use IDEs with intellesense built in during my professional code development and the lack of that in VA is irksome. It also means that it is difficult to see what parameters are being passed to another script necessitating the organisational method you employ to keep track.

But as I said, in effect, each has their own way of working and your way would drive me up the wall. I dare say that mine would do that to you as well. Having said that, I also use NP++ extensively.
...
Oh, I totally agree. I spend a fair bit of time writing my commands in NP++ and then bringing them into VA, but then I tend to lean heavily upon Inline Functions for the majority of my systems operations, with the almost 'code blocks' style VA Actions merely doing some minor lifting for pre-checks or whatnot before diving into the meat and potatoes in the Inline's.

My latest module, a standalone system, uses none of these 'common function' commands, basically wrote the entire thing in VB.net and the VA action for the same includes a compiler that handles funky VA proxy functions as well as standard C#/VB.net 'intellisense' - and can even do a test run directly from the panel. I often use this to do live testing during writing, so I can use the "Test Run" button as well as Voice Command, where the script can tell how it was 'called' and operate accordingly.

Really helps to run through many test in short time to have that specific sort of exception handling for debug/testing - looks like this:
5Rek3Aq.png


And here's the code if anyone is interested -- will be a public profile for download real soon, including commands not listed here - this is just the main. If anyone wanted to play with this, you'd just copy the 'When I say' phrase from the comments at top to a new voice command, and set the text variable noted in the next comment line.

Very fast, up to 3 operands and 2 operations at a time, and conversions for some units of length, velocity, and temperature:
https://pastebin.com/spEypfF2
 
Oh, I totally agree. I spend a fair bit of time writing my commands in NP++ and then bringing them into VA, but then I tend to lean heavily upon Inline Functions for the majority of my systems operations, with the almost 'code blocks' style VA Actions merely doing some minor lifting for pre-checks or whatnot before diving into the meat and potatoes in the Inline's.

My latest module, a standalone system, uses none of these 'common function' commands, basically wrote the entire thing in VB.net and the VA action for the same includes a compiler that handles funky VA proxy functions as well as standard C#/VB.net 'intellisense' - and can even do a test run directly from the panel. I often use this to do live testing during writing, so I can use the "Test Run" button as well as Voice Command, where the script can tell how it was 'called' and operate accordingly.

Really helps to run through many test in short time to have that specific sort of exception handling for debug/testing - looks like this:
5Rek3Aq.png


And here's the code if anyone is interested -- will be a public profile for download real soon, including commands not listed here - this is just the main. If anyone wanted to play with this, you'd just copy the 'When I say' phrase from the comments at top to a new voice command, and set the text variable noted in the next comment line.

Very fast, up to 3 operands and 2 operations at a time, and conversions for some units of length, velocity, and temperature:
https://pastebin.com/spEypfF2
The inline function is such a handy way to do things sometimes. Some VA scripts can get just a wee bit too convoluted and impenetrable with the lack of higher maths functions (such as ABS). Then I resort to c# that takes just a few lines to do the same thing. I have, for example, a random number generator that not only provides linear distributions but normal, gaussian and chi-squared a well. Try scripting those in VA. Not possible. Well it might be but I don't want to try and probably wouldn't run in any useful time.

What use is such a number greater I hear you ask? Well, humans are not linear and sometimes adding a few random pauses in speech can make it less mechanical.
 
Very fast, up to 3 operands and 2 operations at a time, and conversions for some units of length, velocity, and temperature:
https://pastebin.com/spEypfF2
Just taken a look at this and that's very, very nice work. Not much use to me as it's a voice command thing but neat all the same. I once wrote a recursive descent parser in C for a calculator app, must be 30 years ago now, and that was a right pain.

I would be sorely tempted to write a VA mock app to test this sort of thing out. Nothing fancy, just the methods required to get and set the variables and such like. Then things like this could be tested outside of the VA application.

Hm. Interesting.

Something to think about.
 
Back
Top Bottom