Please Select the game mode your feature request is about.
All Game Modes
Is your feature request related to a problem?
I would like programmatically get live information out of OutFox. Some of my current usecases (currently limited to karaoke in UltraStar Deluxe, but they easily apply to all game modes):
being able to log stuff (like played songs) in a format I like
enabling/disabling an external overlay depending on what screen the game is on
externally controlling light fixtures.
sending (and updating) the data the UI shows in json form. Essentially broadcasting/streaming, expect there's no video encoding involved so there's no delay.
The first three are must-have's for me. See "Additional context" for more background on how exactly the third one is currently set up and why I'm not interested in having OutFox control my fixtures directly.
The last one can be ignored for the time being, since it needs much more data compared to the other ones, and isn't really a priority the immediate future anyway.
Describe the solution you'd like
I'd like some kind of plugin/API system.
Note: I use "plugin" not in the sense as "it adds functionality to OutFox itself" but more "this is the way of getting live data out of OutFox so I can use it as input to MyCustomAwesomeScriptOrProgram". Feel free to use a different term if that covers this better.
plugin loading/registering/hooks
some scripting language or .so/.dll (I don't mind either, but others might)
probably some kind of way for OutFox to get a plugin's name (or just use filename if you have it) so that if a plugin throws errors the log can at least point in the right direction
probably some kind of called-at-game-start init function?
some way to 'subscribe' to things. Probably either
being able to (un)subscribe manually (usually from within the init function, but can be at other places)
if the plugin defines a certain function, it'll get called if that thing happens
Personally, my usecase is this: is whatever fifo/file that this plugin is going to output to present? If yes, then 'subscribe' to something that just gets called for every drawn frame. I can do my own frame limiting. The fifo/file gets created by the receiving script/program, and if it isn't present, it makes no sense for the plugin to do anything either.
API functions available to plugins
If you're going for the "every single frame" approach, plugins should at least be able to get the following things:
The current screen (returns: string -- the one that DebugLights=1 shows should work)
The current game mode (returns: string)
Some way of keeping track of elapsed time so that plugins can implement their own frame limiting. Needs (at least) millisecond precision. Considering this will be used/compared A LOT, probably best as an int. Elapsed time since game start basically. Can be omitted if plugins can easily get it from elsewhere (Lua in USDX cannot).
Some info about the current song. Probably best to just have dedicated functions per element? For a first implementation, stick to the static things like Artist and Title.
Some way of getting the song progress. In USDX, this is a float value of the current "beat", and takes into account things like #GAP and the length of the audio file etc. I'm not sure if this will work for every game mode in OutFox though.
You'll have to figure out what you want to do if someone calls an API function that doesn't make any sense at that particular moment, like "give me the artist" while in the game settings. They shouldn't really be called at such a moment anyway, but null or empty string is a thing. Personally I'm fine with either as long as it's consistent.
nice to have's
Although not strictly OutFox-related, if the scripting environment is really limited (IIRC in USDX you can't import anything, and it's not the full Lua either), please provide some convenience functions for object-to-single-line-string for the most used things, like json and XML. Anything that can be easily piped into something else, basically.
future thoughts
It's possible that in the future you also want to update player names or even start entire songs from a plugin. I don't need any of this right now (if ever), but don't tailor the API for reads only if maybe you want to eventually do writes.
Describe alternatives you've considered
Subscribing to individual data things
Some inbetween, eg "the screen has opened" "the highscores are now being shown"
OutFox dumping everything the whole time
The convencience (to a plugin author) that the first two add is near insignificant, while (massively) increasing OutFox maintenance. And the third is just nope in terms of performance.
Additional context
Attached are two plugins I wrote and use in UltraStar Deluxe. Both append single-line json's to a file, which in turn gets tailed by some external script. USDX's Display.Draw hook runs on every single frame, hence there's also some logic to not actually do stuff every single frame. A lot of my inspiration for this feature request came from there.
As requested on Discord, here is a brief overview of how I currently control my light fixtures.
Preparation
QLC+ controls my light fixtures. For some songs (matched based on artist/title/position coming from USDX), I've created a bunch of directives that basically translate to "if song x - y is playing, at beat z press this button in QLC+".
The Plugin
Literally all the plugin does is sending the artist+title when the song starts, continually outputs the current beat while playing, and sends when it has ended (or forfeited, or whatever). It outputs this information to a file that 'happens' to be created by The Script.
The Script
The Script is a fugly bash script, which (highly simplified):
starts a bunch of processes to try and detect beats at different BPM's (The Script knows which of these is currently selected in QLC+ and sends only the beats detected for the correct one to QLC+). Same for stuff like volume level.
creates the file that The Plugin writes to and pipes it to a python script, because it's less painful to work with arrays and json there. It's this python script that also connects to the QLC+ "webinterface" (ie, a websocket) and does the automatic button pressing.
The Real World
The big advantage is that I'm always able to manually override what the lights are doing. Temporarily disabling entire effects is also very easy (not every convention likes stroboscopes). And of course, it's not USDX-specific. With manual control I can also use it with any music, or YouTube video, or even Discord calls.
Although my primary interest is karaoke, the API functionality itself can be tested on probably any game mode. I don't mind helping to test this, in fact it's in my own interest to do so, because there's little incentive for me to switch to OutFox if I can't do this. I am in the Discord.
EDIT: added some horizontal lines to make the sections clearer
Please Select the game mode your feature request is about.
All Game Modes
Is your feature request related to a problem?
I would like programmatically get live information out of OutFox. Some of my current usecases (currently limited to karaoke in UltraStar Deluxe, but they easily apply to all game modes):
The first three are must-have's for me. See "Additional context" for more background on how exactly the third one is currently set up and why I'm not interested in having OutFox control my fixtures directly. The last one can be ignored for the time being, since it needs much more data compared to the other ones, and isn't really a priority the immediate future anyway.
Describe the solution you'd like
I'd like some kind of plugin/API system. Note: I use "plugin" not in the sense as "it adds functionality to OutFox itself" but more "this is the way of getting live data out of OutFox so I can use it as input to MyCustomAwesomeScriptOrProgram". Feel free to use a different term if that covers this better.
plugin loading/registering/hooks
Personally, my usecase is this: is whatever fifo/file that this plugin is going to output to present? If yes, then 'subscribe' to something that just gets called for every drawn frame. I can do my own frame limiting. The fifo/file gets created by the receiving script/program, and if it isn't present, it makes no sense for the plugin to do anything either.
API functions available to plugins
If you're going for the "every single frame" approach, plugins should at least be able to get the following things:
DebugLights=1
shows should work)#GAP
and the length of the audio file etc. I'm not sure if this will work for every game mode in OutFox though.You'll have to figure out what you want to do if someone calls an API function that doesn't make any sense at that particular moment, like "give me the artist" while in the game settings. They shouldn't really be called at such a moment anyway, but null or empty string is a thing. Personally I'm fine with either as long as it's consistent.
nice to have's
Although not strictly OutFox-related, if the scripting environment is really limited (IIRC in USDX you can't import anything, and it's not the full Lua either), please provide some convenience functions for object-to-single-line-string for the most used things, like json and XML. Anything that can be easily piped into something else, basically.
future thoughts
It's possible that in the future you also want to update player names or even start entire songs from a plugin. I don't need any of this right now (if ever), but don't tailor the API for reads only if maybe you want to eventually do writes.
Describe alternatives you've considered
The convencience (to a plugin author) that the first two add is near insignificant, while (massively) increasing OutFox maintenance. And the third is just nope in terms of performance.
Additional context
Attached are two plugins I wrote and use in UltraStar Deluxe. Both append single-line json's to a file, which in turn gets
tail
ed by some external script. USDX'sDisplay.Draw
hook runs on every single frame, hence there's also some logic to not actually do stuff every single frame. A lot of my inspiration for this feature request came from there.ultrastardx-plugins.zip
Usecase: controlling light fixtures
As requested on Discord, here is a brief overview of how I currently control my light fixtures.
Preparation QLC+ controls my light fixtures. For some songs (matched based on artist/title/position coming from USDX), I've created a bunch of directives that basically translate to "if song x - y is playing, at beat z press this button in QLC+".
The Plugin Literally all the plugin does is sending the artist+title when the song starts, continually outputs the current beat while playing, and sends when it has ended (or forfeited, or whatever). It outputs this information to a file that 'happens' to be created by The Script.
The Script The Script is a fugly bash script, which (highly simplified):
The Real World The big advantage is that I'm always able to manually override what the lights are doing. Temporarily disabling entire effects is also very easy (not every convention likes stroboscopes). And of course, it's not USDX-specific. With manual control I can also use it with any music, or YouTube video, or even Discord calls.
Although my primary interest is karaoke, the API functionality itself can be tested on probably any game mode. I don't mind helping to test this, in fact it's in my own interest to do so, because there's little incentive for me to switch to OutFox if I can't do this. I am in the Discord.
EDIT: added some horizontal lines to make the sections clearer