Introduction
Welcome to the Gremlin Scripts Collection documentation!
You can learn how to use all of the Gremlin Scripts by using the table of contents to the left.
Gremlin (Core)
Welcome to the Gremlin documentation! We're still building most of this out, so there will be some rough edges, but hopefully you'll be up and running in no time with whichever Gremlin Scripts you end up using in your own missions!
Gremlin is a framework for building these scripts around, so it doesn't do much on its own. Still, in case it proves useful for your own scripts, we've documented it anyway. Enjoy!
Setup
First, you need to add MiST to your mission. Follow its instructions to do this.
Next, copy the contents of Gremlin Scripts' src/
directory to your missions folder. Include gremlin.lua
as a DoScriptFile action, immediately followed by the specific Gremlin Scripts you wish to use in your mission.
Finally, run a single line of code to set everything up. Note that the Gremlin Scripts will set up Gremlin automatically, so unless you're building your own scripts on this framework, you don't need to do this step in your own missions.
Gremlin:setup()
Yep. That's it. One line of code to ensure everything is working.
Of course, there are a couple of things that you can configure:
Gremlin:setup({
trace = false,
debug = true,
optionalFeatures = {
logEvents = false,
},
})
-
trace
: boolean Turn on trace level logs iftrue
-
debug
: boolean Turn on debug level logs iftrue
-
optionalFeatures
: table Enable or disable optional features
If you aren't building your own script, you can still configure these by passing them to any Gremlin Script's :setup()
method, instead.
That's it for now. Check out the rest of these docs for more info!
Usage
Gremlin is an abstraction framework that makes working with DCS in scripts much simpler. It doesn't do much on its own, yet, but we're working on adding more! Here's how to use some of what's already working:
Gremlin:setup()
Gremlin.log.info('My Cool DCS Script', 'Starting up!')
Gremlin.comms.displayMessageTo('test', 'Hullabaloo!', timer.getTime() + 1)
local myArgs = Gremlin.utils.parseFuncArgs({ '{unit}:test', '{group}:test', timer.getTime() }, {
unit = {
test: Unit:getByName('test'),
},
group = {
test: Group:getByName('test'),
},
})
local mergedList = Gremlin.utils.mergeTables(list1, list2, list3)
Clearly, the above script doesn't actually do anything, besides show some of how the framework can be used. The function documentation will be more helpful when building scripts that actually do things.
Functions
Gremlin:setup(config)
Sets up Gremlin. Docs for this are in the setup section.
Comms
Gremlin.comms.displayMessageTo(_name, _text, _time)
Displays a message to a named Unit, Group, Country, or Coalition, or to everyone with the special name all
Gremlin.comms.playClipTo(_name, _path)
Plays a clip to a named Unit, Group, Country, or Coalition, or to everyone with the special name all
Events
Gremlin.events.on(_eventId, _fn)
Calls _fn(_event)
when an event's ID (that is, its type) matches _eventId
; returns an _index
value that will let you unregister the event handler using Gremlin.events.off()
when you no longer need it.
This is an improved interface that avoids calling functions that don't handle certain event types anyway; said another way, it's more efficient than what DCS or MiST currently support with their event handler systems.
Gremlin.events.off(_eventId, _index)
Stops calling the _eventId
handler whose _index
is given; the only safe way to stop listening for events.
Gremlin.events.fire(_event)
Another improvement on the DCS event system, this lets you fire off your own events. In fact, the official Gremlin scripts use this to provide support for events in their own code.
Note: you can only receive these custom-fired events if you register an event handler using
Gremlin.events.on()
!
Log
Gremlin.log.error(toolId, message)
Logs an error message, the highest level DCS supports
Gremlin.log.warn(toolId, message)
Logs a warning message
Gremlin.log.info(toolId, message)
Logs an info message
Gremlin.log.debug(toolId, message)
Logs a debug message, if they're enabled
Gremlin.log.trace(toolId, message)
Logs a trace message, if they're enabled
Menu
Only one function in here for the moment! But it's pretty powerful, so the configuration can be a bit complex.
Gremlin.menu.updateF10({ toolId, commands, getForUnits })
WARNING - DO NOT CALL THIS FUNCTION MORE THAN ONCE PER SCRIPT! This is a great way to confuse the poor thing and break your missions.
Registers a set of menu commands to be updated automatically (every 10 seconds) by Gremlin itself. These commands will be grouped under a parent menu named after the tool itself - Gremlin Evac
for evac.lua
, Gremlin Waves
for waves.lua
, etc. Here's an example:
Gremlin.menu.updateF10({ MyScript.Id, {
{
text = 'My Cool Unit Command',
func = MyScript.commands.myCoolUnitFunc,
args = { '{unit}:name' },
when = true,
},
{
text = 'My Cool Group Command',
func = MyScript.commands.myCoolGroupFunc,
args = { '{group}:name' },
when = {
func = MyScript.unit.inTheZone,
args = { '{unit}:name' },
comp = 'equal',
value = true,
},
},
}, function()
return MyScript._state.pilotedUnits
end })
-
toolId
- should be a string identifying your script by name for the menu. Should be the same value used for Gremlin's logging methods. -
commands
- an array of commands to registertext
- a string or a function that returns a string; used for the menu textfunc
- the function to call when this menu command is selectedargs
- any arguments to pass tofunc
(andtext
, if it's a function){unit}:name
- placeholder value for the name of the unit whose menu is being updated{group}:name
- placeholder value for the name of the group whose menu is being updated
when
- indicates when a command should be visible in the menu; can either be a boolean or a tablefunc
- the function to call when deciding whether to add a command to the menuargs
- the arguments to pass tofunc
; uses the same placeholders asargs
a level upcomp
- one ofequal
orinequal
(at the moment); denotes what kind of comparison to make betweenfunc
's return value andvalue
value
- the value to compare againstfunc
's result
-
getForUnits
- a function that returns a table of units to add menus to; this is a function so that your list can change over time
Utils
Gremlin.utils.checkTrigger(_trigger, _type, _extra)
Checks a trigger definition against a type and optional extra data - returns true when any conditions are met
Gremlin.utils.countTableEntries(_tbl)
Counts the number of entries in a table, regardless of type
Gremlin.utils.getUnitZones(_unit)
Looks up a list of all the zones a unit is currently in
Gremlin.utils.innerSquash(_tbl, _idx)
Flatten a table by one level, by removing the second level:
Gremlin.utils.innerSquash({
walnut = { 'redWalnut', 'blueWalnut', [0] = 'noWalnut' },
pecan = { 'redPecan', 'bluePecan', [0] = 'noPecan' },
almond = { 'redAlmond', 'blueAlmond', [0] = 'noAlmond' },
}, coalition.side.BLUE)
would become
{
walnut = 'blueWalnut',
pecan = 'bluePecan',
almond = 'blueAlmond',
}
Gremlin.utils.inspect(_value, _depth)
Converts a Lua value to a string for display or logging. It tries to make the string valid Lua, but there are a few types we can't reconstruct. Leave the second argument off if calling this directly!
Gremlin.utils.isInTable(_tbl, _needle)
Checks whether _needle
is in the haystack _tbl
Gremlin.utils.parseFuncArgs(_args, _objs)
Preps arguments for things like scheduled functions, with some limited autocompletion of Units and Groups. Use a string placeholder for these autocompletions that meets one of the following criteria:
'{unit}:name'
will be replaced by the corresponding Unit'{group}:name'
will be replaced by the corresponding Group
For _objs
, simply pass a table with the appropriate structure:
{
unit = Unit.getByName(unitName),
group = Group.getByName(groupName),
}
Gremlin.utils.mergeTables(...)
Combines two or more tables into a single one, for easier indexing and iteration across multiple tables.
Gremlin Evac
The Gremlin Evac script sets up your missions to include evacuation scenarios. Simply call Evac:setup()
to get sane defualts, or customize everything by filling out the available options you wish to override.
Features
- Automatic spawn of evacuees
- Loading and unloading via in-game menus
- Manual overrides via config and function calls
- Automatic loss for any side that loses too many evacuees
- Automatic win for any side that rescues enough evacuees
- More coming soon!
Setup
Configuration
Evac:setup({
adminPilotNames = { 'Walter White' },
beaconBatteryLife = 30,
beaconSound = 'beacon.ogg',
carryLimits = {
['C-130'] = 90,
['CH-43E'] = 55,
['CH-47D'] = 44,
['Hercules'] = 90,
['Mi-8MT'] = 24,
['Mi-24P'] = 5,
['Mi-24V'] = 5,
['Mi-26'] = 70,
['SH-60B'] = 5,
['SH60B'] = 5,
['UH-1H'] = 8,
['UH-60L'] = 11,
},
idStart = 50000,
loadUnloadPerIndividual = 30,
lossFlags = { 'GremlinEvacRedLoss', 'GremlinEvacBlueLoss' },
lossThresholds = { 25, 25 },
maxExtractable = {
_global = {
Generic = { 0, 0, [0] = 0 },
Infantry = { 0, 0, [0] = 0 },
M249 = { 0, 0, [0] = 0 },
RPG = { 0, 0, [0] = 0 },
StingerIgla = { 0, 0, [0] = 0 },
['2B11'] = { 0, 0, [0] = 0 },
JTAC = { 0, 0, [0] = 0 },
},
},
spawnRates = {
_global = {
{
side = coalition.side.NEUTRAL,
units = 0,
startTrigger = { type = 'time', value = 0 },
spawnTrigger = { type = 'time', value = 0 },
endTrigger = { type = 'limits', value = 100 },
},
{
side = coalition.side.RED,
units = 0,
startTrigger = { type = 'time', value = 0 },
spawnTrigger = { type = 'time', value = 0 },
endTrigger = { type = 'limits', value = 100 },
},
{
side = coalition.side.BLUE,
units = 0,
startTrigger = { type = 'time', value = 0 },
spawnTrigger = { type = 'time', value = 0 },
endTrigger = { type = 'limits', value = 100 },
},
},
},
spawnWeight = 100,
startingUnits = { 'helicargo1', 'helicargo2', 'MedEvac1', 'MedEvac2', 'MedEvac3' },
startingZones = {
{ mode = Evac.modes.EVAC, name = "Test 1", smoke = trigger.smokeColor.Green, side = coalition.side.BLUE, active = true },
{ mode = Evac.modes.RELAY, name = "Test 2", smoke = trigger.smokeColor.Orange, side = coalition.side.BLUE, active = true },
{ mode = Evac.modes.SAFE, name = "Test 3", smoke = trigger.smokeColor.White, side = coalition.side.BLUE },
},
winFlags = { 'GremlinEvacRedWin', 'GremlinEvacBlueWin' },
winThresholds = { 75, 75 },
})
-
adminPilotNames
: Pilots to consider admins, with bonus menu items available.- Default:
{}
- Default:
-
beaconBatteryLife
: How long beacons should broadcast once spawned, in minutes- Default:
30
- Default:
-
beaconSound
: The audio file name to play for radio beacons- Default:
beacon.ogg
- Default:
-
carryLimits
: Specifies the maximum capacity loadout per aircraft designator- Default:
{ ["C-130"] = 90, ["CH-47D"] = 44, ["CH-43E"] = 55, ["Mi-8MT"] = 24, ["Mi-24P"] = 5, ["Mi-24V"] = 5, ["Mi-26"] = 70, ["SH60B"] = 5, ["UH-1H"] = 8, ["UH-60L"] = 11 }
- Default:
-
idStart
: The lowest ID number that Gremlin Evac will use to create units and groups- Default:
50000
- Default:
-
loadUnloadPerIndividual
: The amount of time it takes to load/unload a single evacuee onto/from an aircraft, in seconds- Default:
30
- Default:
-
lossFlags
: Flags to tell the Mission Editor that one side or the other (or both!) has lost- Default:
{ 'GremlinEvacRedLoss', 'GremlinEvacBlueLoss' }
- Default:
-
lossThresholds
: The maximum percentage of evacuees that can be lost from any side- Default:
{ 25, 25 }
- Default:
-
maxExtractable
: Provides a cap for automatically generated evacuees, by zone/type/side; the script won't create more than allowed here- Default:
0
for everything
- Default:
-
spawnRates
: Describes how and when to spawn evacuee units/groups- Default:
{ _global = { units = 0, per = 0, period = Gremlin.Periods.Second } }
(everything at mission start) - Spec
- key: Zone name
- value: table
- key: index
- value: table
side
: The side ID for spawningunits
: Number or composition of units to spawnstartTrigger
: Trigger to start spawningspawnTrigger
: Trigger to actually spawn unitsendTrigger
: Trigger to stop spawning
- Notes:
- Triggers:
{ type = 'time', value = 900 }
: seconds since mission start{ type = 'time', value = { after = 15, period = Gremlin.Periods.Minute } }
: another way to say time since mission start{ type = 'repeat', value = { per = 5, period = Gremlin.Periods.Minute } }
: everyper
period
s{ type = 'flag', value = 7 }
: flag goes truthy{ type = 'event', value = { id = 'Evac:Spawn', filter = function(event) return true end } }
: event triggered{ type = 'menu', value = 'Spawn Bonus Evacuees' }
: menu item selected{ type = 'limits', value = 50 }
:value
% of allowed evacuees spawned
- Triggers:
- Default:
-
spawnWeight
: The average weight of an evacuee - the exact weight used will vary between 90% and 120% of this value- Default:
100
- Default:
-
startingUnits
: Registers units for evacuation purposes during setup- Default:
{}
- Default:
-
startingZones
: Registers zones for evacuation purposes during setup- Default:
{}
- Spec
- key: ignored
- value: table
mode
: One of theEvac.modes
constants, indicating what evacuation mode the zone should be registered usingname
: Zone name - MUST MATCH THE MISSION EDITOR'S NAME FOR THE ZONE EXACTLY!smoke
: Smoke color, taken fromtrigger.smokeColor
side
: Coalition, taken fromcoalition.side
- Default:
-
winFlags
: Flags to tell the Mission Editor that one side or the other (or both!) has won- Default:
{ 'GremlinEvacRedWin', 'GremlinEvacBlueWin' }
- Default:
-
winThresholds
: The minimum percentage of evacuees that must be saved to win, per side- Default:
{ 75, 75 }
- Default:
Usage
For many use cases, you simply configure Gremlin Evac, and the script does the rest. When you want more power, you can use the various available functions to control the map. Below are some simple examples that might help you in this endeavor.
Basic Setup
Evac:setup({
startingZones = {
{ mode = Evac.modes.EVAC, name = "Blue Evac", smoke = trigger.smokeColor.Green, side = coalition.side.BLUE },
{ mode = Evac.modes.RELAY, name = "Blue Relay", smoke = trigger.smokeColor.Orange, side = coalition.side.BLUE, active = true },
{ mode = Evac.modes.SAFE, name = "Blue Safe", smoke = trigger.smokeColor.White, side = coalition.side.BLUE, active = true },
{ mode = Evac.modes.EVAC, name = "Red Evac", smoke = trigger.smokeColor.Green, side = coalition.side.RED },
{ mode = Evac.modes.RELAY, name = "Red Relay", smoke = trigger.smokeColor.Orange, side = coalition.side.RED, active = true },
{ mode = Evac.modes.SAFE, name = "Red Safe", smoke = trigger.smokeColor.White, side = coalition.side.RED, active = true },
},
})
Initializes Gremlin Evac with 6 zones, 4 of which are active at start. Three are RedFor, the other three are BlueFor. Two each are evacuation zones, two each are relay/staging zones, and the last two each are safe zones. All other settings are kept at the defaults.
Full Setup
This example is also available on the Setup page.
Evac:setup({
beaconBatteryLife = 2,
beaconSound = "test.ogg",
carryLimits = {
["SH60B"] = 15,
},
idStart = 5,
loadUnloadPerIndividual = 2,
lossFlags = { 1, 2 },
lossThresholds = { 0, 25 },
maxExtractable = {
_global = {
{
Generic = { 12, 12, [0] = 0 },
Infantry = { 12, 12, [0] = 0 },
M249 = { 12, 12, [0] = 0 },
RPG = { 12, 12, [0] = 0 },
StingerIgla = { 12, 12, [0] = 0 },
["2B11"] = { 12, 12, [0] = 0 },
JTAC = { 3, 3, [0] = 0 },
},
},
},
spawnWeight = 50,
spawnRates = {
["Test 1"] = {
{
side = coalition.side.BLUE,
units = 12,
startTrigger = { type = 'time', value = 0 },
spawnTrigger = { type = 'repeat', value = { per = 5, period = Gremlin.Periods.Minute } },
endTrigger = { type = 'limits', value = 100 },
},
},
},
startingUnits = { 'helicargo1', 'helicargo2', 'MedEvac1', 'MedEvac2', 'MedEvac3' },
startingZones = {
{ mode = Evac.modes.EVAC, name = "Test 1", smoke = trigger.smokeColor.Green, side = coalition.side.BLUE, active = true },
{ mode = Evac.modes.RELAY, name = "Test 2", smoke = trigger.smokeColor.Orange, side = coalition.side.BLUE, active = true },
{ mode = Evac.modes.SAFE, name = "Test 3", smoke = trigger.smokeColor.White, side = coalition.side.BLUE },
},
winFlags = { 3, 4 },
winThresholds = { 0, 75 },
})
Initializes Gremlin Evac, overriding all the defaults:
- any beacons are killed after 2 minutes (default is 30)
- the beacon sound file is changed to something mission specific
- the list of craft that can perform evac ops is reset to just the
SH60B
Unit type at a max loadout of 15 evacuees - the starting ID is dropped from 50000 to 5
- the time it takes to load or unload evacuees is set to 2 seconds per evacuee (down from 30 seconds)
- the flags used to indicate evacuation mission failure are set to 1 and 2, respectively (default is
GremlinEvacRedLoss
andGremlinEvacBlueLoss
) - the percentage of evacuees that can be lost is set to 0 for red, and 25 for blue (default is 25 for both)
- the maximums for generated evacuees are set to 12 on both sides, for all roles except JTAC, which is set to 3 (default is 0)
- the average spawn weight is dropped from 100kg to 50kg
- the spawn rates are configured to spawn 12 Blue generic evacuees every 5 minutes in the
Test 1
Zone (default is spawn all across all Zones at mission start) - the starting Zones are set to three Blue Zones, two of which (evacuation and relay/staging) are active from mission start (default is no registered Zones)
- the flags used to indicate evacuation mission success are set to 3 and 4, respectively (default is
GremlinEvacRedWin
andGremlinEvacBlueWin
) - the percentage of evacuees that need to be evacuated to win is set to 0 for red, and 75 for blue (default is 75 for both)
Manual Setup
Sometimes the built-in logic isn't enough for your mission. This example pulls in several functions to integrate with other parts of the game.
Evac:setup()
Evac.zones.evac.register('Blue Evac 1', trigger.smokeColor.Blue, coalition.side.BLUE)
Evac.zones.evac.register('Blue Evac 2', trigger.smokeColor.Blue, coalition.side.BLUE)
Evac.zones.relay.register('Blue Relay 1', trigger.smokeColor.Orange, coalition.side.BLUE)
Evac.zones.relay.register('Blue Relay 2', trigger.smokeColor.Orange, coalition.side.BLUE)
Evac.zones.safe.register('Blue Safe', trigger.smokeColor.Green, coalition.side.BLUE)
Evac.zones.evac.register('Red Evac 1', trigger.smokeColor.Red, coalition.side.RED)
Evac.zones.evac.register('Red Evac 2', trigger.smokeColor.Red, coalition.side.RED)
Evac.zones.relay.register('Red Relay 1', trigger.smokeColor.Orange, coalition.side.RED)
Evac.zones.relay.register('Red Relay 2', trigger.smokeColor.Orange, coalition.side.RED)
Evac.zones.safe.register('Red Safe', trigger.smokeColor.Green, coalition.side.RED)
Evac.zones.evac.activate('Blue Evac 1')
Evac.zones.evac.activate('Blue Evac 2')
Evac.zones.relay.activate('Blue Relay 1')
Evac.zones.relay.activate('Blue Relay 2')
Evac.zones.evac.activate('Red Evac 1')
Evac.zones.evac.activate('Red Evac 2')
Evac.zones.relay.activate('Red Relay 1')
Evac.zones.relay.activate('Red Relay 2')
Evac.zones.evac.setRemaining('Blue Evac 1', coalition.side.BLUE, country.USA, {
{ type = 'Infantry' },
{ type = 'Infantry' },
{ type = 'Infantry' },
{ type = 'Infantry' },
{ type = 'Infantry' },
{ type = 'RPG' },
{ type = '2B11' },
})
Evac.zones.evac.setRemaining('Blue Evac 2', coalition.side.BLUE, country.USA, {
{ type = 'Infantry' },
{ type = 'Infantry' },
{ type = 'Infantry' },
{ type = 'Infantry' },
{ type = 'Infantry' },
{ type = 'RPG' },
{ type = 'M249' },
{ type = 'StingerIgla' },
{ type = '2B11' },
{ type = 'JTAC' },
})
Evac.zones.evac.setRemaining('Red Evac 1', coalition.side.RED, country.RUSSIA, 4)
Evac.zones.evac.setRemaining('Red Evac 2', coalition.side.RED, country.RUSSIA, 3)
Evac.units.loadEvacuees('MEDEVAC_BLUE_1')
Evac.units.loadEvacuees('MEDEVAC_BLUE_2')
Evac.units.loadEvacuees('MEDEVAC_RED_1')
Evac.units.loadEvacuees('MEDEVAC_RED_2')
This setup does a few things, in order:
- sets up Gremlin Evac using all the defaults
- registers 5 zones for blue evacuations, and 5 for red
- activates the evac and relay Zones
- manually spawns 17 blue evacuees, using composition tables
- manually spawns 7 red evacuees, using numbers (makes all evacuees into generic ones)
- manually loads up evacuees onto various standby Units
Everything from there is either automatic from Gremlin Evac, or manual via additional triggers in the mission.
Events
-
Evac:BeaconDead
details
- the beacon details table used internally- Fired when a beacon dies and gets removed from the map
-
Evac:BeaconSpawn
details
- the beacon details table used internallyzone
- The zone the beacon was spawned into- Fired when a beacon spawns and gets added to the map
-
Evac:Loss
side
- The numeric ID of the coalition that lost- Fired when any side loses too many evacuees
-
Evac:Spawned
units
- The number of evacuees spawnedzone
- The zone in which evacuees were spawned- Fired when evacuees spawn into the map
-
Evac:UnitLoaded
number
- The number of evacuees loadedunit
- The unit that did the loadingzone
- The zone the evacuees were picked up from- Fired when evacuees are finished loading onto an evacuation unit
-
Evac:UnitUnloaded
number
- The number of evacuees unloadedunit
- The unit that did the unloadingzone
- The zone the evacuees were dropped off- Fired when evacuees are finished unloading from an evacuation unit
-
Evac:Win
side
- The numeric ID of the coalition that won- Fired when any side rescues enough evacuees
-
Evac:ZoneActive
mode
- The Evac.modes integer dictating how evacuees should be handled in the zonezone
- The affected zone- Fired when a zone goes active
-
Evac:ZoneAdd
mode
- The Evac.modes integer dictating how evacuees should be handled in the zonezone
- The affected zone- Fired when a zone is added to Evac
-
Evac:ZoneInactive
mode
- The Evac.modes integer dictating how evacuees should be handled in the zonezone
- The affected zone- Fired when a zone goes inactive
-
Evac:ZoneRemove
mode
- The Evac.modes integer dictating how evacuees should be handled in the zonezone
- The affected zone- Fired when a zone is removed from Evac
Functions
Gremlin Evac has its functions nested into various tables, rather than living directly under Evac (or worse, the global namespace). These tables include zones
, units
, and groups
. Keep reading to learn more!
Functions » Groups
Evac.groups.spawn(_side, _numberOrComposition, _country, _zone, _scatterRadius)
Spawns evacuees manually. _side
is the Group's coalition.side
, _numberOrComposition
follows the same rules as Evac.zones.evac.setRemaining()
, _country
is the country
for the Group, _zone
is the Zone name to spawn the evacuees into, and _scatterRadius
is the distance between spawned Units on the map.
Evac.groups.list(_zone)
Returns a list of all Groups in a Zone. _zone
is the name of the Zone to search.
Evac.groups.count(_zone)
Returns a count of all Groups in a Zone. _zone
is the name of the Zone to search.
Functions » Units
Evac.units.register(_unit)
Registers a Unit, either by name or object, as capable of picking up evacuees. Note that the Unit MUST be one of your supported craft in your carryLimits
config, or loading and unloading will not be available.
Evac.units.findEvacuees(_unit)
Lists the currently-active beacons broadcasting for the Unit's side. _unit
is the name of the Unit doing the search.
Evac.units.loadEvacuees(_unit)
Starts the evacuee loading process for a Unit. _unit
is the name of the Unit to load evacuees onto.
Evac.units.unloadEvacuees(_unit)
Starts the evacuee unloading process for a Unit. _unit
is the name of the Unit to unload evacuees from.
Evac.units.countEvacuees(_unit)
Count the number of evacuees aboard a given Unit. _unit
is the name of the Unit to count evacuees aboard.
Evac.units.count(_zone)
Count the number of Units in a given Zone. _zone
is the name of the Zone to check.
Evac.units.unregister(_unit)
Removes a Unit from Gremlin Evac's internal state, making it no longer eligible for evacuation ops.
Functions » Zones
Evac.zones.evac.register(_zone, _smoke, _side)
Registers an evacuation zone with Gremlin Evac so that it can spawn and track evacuees there.
Evac.zones.relay.register(_zone, _smoke, _side)
Registers a relay/staging zone with Gremlin Evac so that it can track evacuees there.
Evac.zones.safe.register(_zone, _smoke, _side)
Registers a safe zone with Gremlin Evac so that it can track evacuees there.
For all three of the above, _zone
is the name of the zone to register, _smoke
is the smoke color from trigger.smokeColor
, and _side
is taken from coalition.side
.
Evac.zones.evac.activate(_zone)
Turns on evacuation automations for a given zone.
Evac.zones.relay.activate(_zone)
Turns on relay/staging automations for a given zone.
Evac.zones.safe.activate(_zone)
Turns on safe zone automations for a given zone.
For all three of the above, _zone
is the zone name to activate.
Evac.zones.evac.setRemaining(_zone, _side, _country, _numberOrComposition)
Sets the number of waiting evacuees in the zone.
Evac.zones.relay.setRemaining(_zone, _side, _country, _numberOrComposition)
Sets the number of waiting evacuees in the zone.
For both of the above, _zone
is the zone name to activate, _side
is taken from coalition.side
, _country
is taken from the country
table, and _numberOrComposition
is (as its name suggests) either a number of evacuees to generate (these will all be of type "Generic"
), or a table listing off the composition of the units to spawn (as its name also suggests).
Sample Composition
Evac.zones.evac.setRemaining('test', coalition.side.BLUE, country.USA, {
{ type = 'Carrier Seaman', unitName = 'Karl Marx', unitId = 42, weight = 75 },
{ type = 'Infantry' },
{ type = 'JTAC' },
{},
})
This will add a generic evacuee named Karl Marx, with associated ID and weight values, an infantry unit, a JTAC unit, and a second generic evacuee whose name is automatically generated. Note how none of the parameters are required if you just want a generic evacuee, though a unit composed entirely of generics is simpler to build with a number instead of a composition table.
Evac.zones.evac.count(_zone)
Gets an evacuee count for a given evacuation zone.
Evac.zones.relay.count(_zone)
Gets an evacuee count for a given relay/staging zone.
Evac.zones.safe.count(_zone)
Gets an evacuee count for a given safe zone.
For all three of the above, _zone
is the zone name to count evacuees within.
Evac.zones.evac.isIn(_unit)
Gets a value indicating whether an evacuee is in a given evacuation zone.
Evac.zones.relay.isIn(_unit)
Gets a value indicating whether an evacuee is in a given relay/staging zone.
Evac.zones.safe.isIn(_unit)
Gets a value indicating whether an evacuee is in a given safe zone.
For all three of the above, _unit
is the unit name to search for.
Evac.zones.evac.deactivate(_zone)
Turns off evacuation automations for a given zone.
Evac.zones.relay.deactivate(_zone)
Turns off relay/staging automations for a given zone.
Evac.zones.safe.deactivate(_zone)
Turns off safe zone automations for a given zone.
For all three of the above, _zone
is the zone name to deactivate.
Evac.zones.evac.unregister(_zone)
Removes an evacuation zone from Evac's control.
Evac.zones.relay.unregister(_zone)
Removes a relay/staging zone from Evac's control.
Evac.zones.safe.unregister(_zone)
Removes a safe zone from Evac's control.
For all three of the above, _zone
is the zone name to remove.
About
Gremlin Urgency is a great way to add ... well, urgency to your missions. Timed events made easy - whether that be mission duration or anything else.
Setup
Configuration
Urgency:setup({
adminPilotNames = {
'Steve Jobs',
'Linus Torvalds',
'Bill Gates',
},
countdowns = {
missionDuration = {
reuse = false,
startTrigger = {
type = 'time',
value = 0, -- mission start (or, well, as close as we can manage)
},
startFlag = 'MissionRunning',
endTrigger = {
type = 'time',
value = 25200, -- 7 hours
},
endFlag = 'MissionTimeout',
messages = {
[0] = { to = 'blue', text = 'Mission is a go! We only get seven hours to complete our objectives!', duration = 15 },
[-1800] = { to = 'blue', text = '30 minutes left in mission! Are we gonna make it?', duration = 15 },
[-900] = { to = 'blue', text = '15 minutes left in mission! Are we gonna make it?', duration = 15 },
[-600] = { to = 'blue', text = '10 minutes left in mission! Are we gonna make it?', duration = 15 },
[-300] = { to = 'blue', text = '5 minutes left in mission! Are we gonna make it?', duration = 15 },
[-60] = { to = 'blue', text = '1 minute left in mission! Are we gonna make it?', duration = 15 },
[-30] = { to = 'blue', text = '30 seconds left in mission...', duration = 5 },
[-15] = { to = 'blue', text = '15 seconds left in mission...', duration = 5 },
[-10] = { to = 'blue', text = '10 seconds left in mission...', duration = 1 },
[-9] = { to = 'blue', text = '9 seconds left in mission...', duration = 1 },
[-8] = { to = 'blue', text = '8 seconds left in mission...', duration = 1 },
[-7] = { to = 'blue', text = '7 seconds left in mission...', duration = 1 },
[-6] = { to = 'blue', text = '6 seconds left in mission...', duration = 1 },
[-5] = { to = 'blue', text = '5 seconds left in mission...', duration = 1 },
[-4] = { to = 'blue', text = '4 seconds left in mission...', duration = 1 },
[-3] = { to = 'blue', text = '3 seconds left in mission...', duration = 1 },
[-2] = { to = 'blue', text = '2 seconds left in mission...', duration = 1 },
[-1] = { to = 'blue', text = '1 seconds left in mission...', duration = 1 },
[25200] = { to = 'all', text = "Time's up! Ending mission...", duration = 15 },
},
},
easterEgg1 = {
reuse = true,
startTrigger = {
type = 'flag',
value = 'Egg1Triggered',
},
startFlag = 'Egg1Found',
endTrigger = {
type = 'time',
value = 3600, -- 1 hour
},
endFlag = 'Egg1Expired',
messages = {
[0] = { to = 'all', text = 'An Easter Egg Was Discovered!', duration = 15 },
[3600] = { to = 'all', text = 'An Easter Egg Has Vanished!', duration = 15 },
},
clips = {
[0] = { to = 'all', path = 'exclaim.ogg' },
[3600] = { to = 'all', path = 'snake.ogg' },
},
},
},
})
-
adminPilotNames
table- A list of pilots who should get the admin menu
-
countdowns
table- A list of countdowns to register at mission start
- countdown
reuse
whether to put this countdown back in the queue to be triggered againstartTrigger
tabletype
one oftime
,flag
,event
, ormenu
value
the time, event id and handler, or menu text to trigger on
startFlag
the flag to set true when the countdown startsendTrigger
tabletype
one oftime
,flag
,event
, ormenu
value
the time, event id and handler, or menu text to trigger on
endFlag
the flag to set true when the countdown endsmessages
a list of messages to display, keyed by the countdown's seconds since start (or seconds until end, if negative)to
the units that should receive the message (unit, group, country, coalition), or the special valueall
for everyonetext
the message to displayduration
how long the message should be visible (in seconds)
clips
a list of clips to play, keyed by the countdown's seconds since start (or seconds until end, if negative)to
the units that should receive the message (unit, group, country, coalition), or the special valueall
for everyonepath
the path to the clip to play
Usage
Gremlin Urgency is really simple to use. Configure it once (see the Setup page), and it handles the rest!
Events
-
Urgency:CountdownEnd
name
- The name of the countdown that just ended- Fired when a countdown ends
-
Urgency:CountdownStart
name
- The name of the countdown that just started- Fired when a countdown begins
-
Urgency:CountdownsReset
- Fired when an admin pilot resets all active countdowns to pending
-
Urgency:CountdownsRestored
- Fired when an admin pilot restores all countdowns so they will start over
About
Gremlin Waves is a reinforcements script for your missions. Running low on RedFor, but not ready for the fun to end? Call in reinforcements with Gremlin Waves!
Setup
Configuration
Waves:setup({
adminPilotNames = {
'Steve Jobs',
'Linus Torvalds',
'Bill Gates',
},
waves = {
['Wave 2'] = {
trigger = {
type = 'time',
value = 12600, -- 3.5 hours
},
groups = {
['F-14B'] = {
category = Group.Category.AIRPLANE,
country = country.USA,
zone = 'Reinforcement Staging',
scatter = 15,
orders = {},
units = {
['F-14B'] = 3,
},
},
['Ground A'] = {
category = Group.Category.GROUND,
country = country.USA,
zone = 'Reinforcement Staging',
scatter = 5,
orders = {},
units = {
['Infantry'] = 4,
}
},
['Ground B'] = {
category = Group.Category.GROUND,
country = country.USA,
zone = 'Reinforcement Staging',
scatter = 5,
orders = {},
units = {
['RPG'] = 1,
['Infantry'] = 3,
['JTAC'] = 1,
}
},
},
},
},
})
adminPilotNames
table- list of pilots who should see the menu
waves
table- collection of reinforcement waves for this mission
- wave
trigger
tabletype
one oftime
,flag
,event
, ormenu
value
a time, flag name / number, event id / filter, or menu item text
groups
table- list of groups to spawn
- group
category
a member ofGroups.Category
indicating the group's categorycountry
acountry
idzone
where to spawn the groupscatter
how far apart, in meters, to scatter units at spawnorders
table- a list of DCS AI tasks for the group to perform
units
table- key: the unit type to spawn
- value: how many to spawn in the group
Usage
Gremlin Waves is really simple to use. Configure it once (see the Setup page), and it handles the rest!
Events
-
Waves:GroupSpawn
wave
- The name of the wave that is spawning groupsgroup
- The name of the group that spawned in this wave- Fired when a group is spawned as part of a wave
-
Waves:Paused
- Fired when an admin pilot pauses all pending waves
-
Waves:Resumed
- Fired when an admin pilot resumes all pending waves
-
Waves:WaveSpawn
wave
- The name of the wave that spawned- Fired when a wave is fully spawned
Contributors
Gremlin Aviation
Modules
- Gremlin
Module Gremlin
Gremlin.
DO NOT EDIT THIS SCRIPT DIRECTLY! Things WILL break that way.
Instead, pass a table to Gremlin:setup()
with any options you wish to configure.
Enums
Name | Summary |
---|---|
Periods | Time period "constants", in seconds. |
SideToText | Coalition name from ID. |
Comms
Name | Summary |
---|---|
Gremlin.comms.displayMessageTo(_name, _text, _time) | Display message to target. |
Gremlin.comms.playClipTo(_name, _path) | Play sound file for target. |
Events
Name | Summary |
---|---|
Gremlin.events.fire(_event) | Fire an event. |
Gremlin.events.idToName | Event name lookup. |
Gremlin.events.off(_eventId, _index) | Unregister an event handler. |
Gremlin.events.on(_eventId, _fn) | Register an event handler. |
Logging
Name | Summary |
---|---|
Gremlin.log.debug(toolId, message) | Log a message at the debug level. |
Gremlin.log.error(toolId, message) | Log a message at the error level. |
Gremlin.log.info(toolId, message) | Log a message at the info level. |
Gremlin.log.trace(toolId, message) | Log a message at the trace level. |
Gremlin.log.warn(toolId, message) | Log a message at the warn level. |
Menu
Name | Summary |
---|---|
Gremlin.menu.updateF10(toolId, commands, forUnits) | Update the F10 menu. |
Utils
Name | Summary |
---|---|
Gremlin.utils.countTableEntries(_tbl) | Count items in a table, numeric or otherwise. |
Gremlin.utils.getUnitZones(_unit) | Get a list of zones a unit is in. |
Gremlin.utils.inspect(_value, _depth) | Get a mostly-Lua representation of a value. |
Gremlin.utils.isInTable(_tbl, _needle) | Searches a table for a value. |
Gremlin.utils.mergeTables(...) | Combine two tables together. |
Gremlin.utils.parseFuncArgs(_args, _objs) | Parse arguments for things like menus. |
checkTrigger(_trigger, _type, _extra) | Check whether a trigger condition has been met. |
innerSquash(_tbl, _idx) | Flattens a table by removing the second level, rather than the first |
Top Level methods
Name | Summary |
---|---|
setup(config) | Setup Gremlin. |
Enums
Periods
Time period "constants", in seconds.
Fields:
- Second 1 second
- Minute 1 minute
- Hour 1 hour
- Day 1 day
SideToText
Coalition name from ID.
Fields:
- [0] Neutral
- [1] Red
- [2] Blue
Comms
Methods for handling communications with players.
Gremlin.comms.displayMessageTo(_name, _text, _time)
Display message to target. Finds a target by name, and then sends a text message.
Parameters:
- _name string, Unit or Group The name of the target to send a message to
- _text string The text to send
- _time number How long before the message should be dismissed
Gremlin.comms.playClipTo(_name, _path)
Play sound file for target. Finds a target by name, then plays a sound file.
Parameters:
- _name string, Unit or Group The name of the target to play sound to
- _path string The filename of the audio clip to play
Events
Methods for handling and firing events.
Gremlin.events.fire(_event)
Fire an event. NOTE: Only works between scripts that register handlers. It cannot send events back to DCS proper.
Parameters:
- _event table The event object to send to all relevant Gremlin handlers
Gremlin.events.idToName
Event name lookup. Not populated until setup is complete!
Gremlin.events.off(_eventId, _index)
Unregister an event handler.
Parameters:
- _eventId integer The DCS event ID to stop listening for
- _index integer The handler index to remove
Gremlin.events.on(_eventId, _fn)
Register an event handler.
Parameters:
- _eventId integer The DCS event ID to listen for
- _fn function The event handler to register
Returns:
- integer The handler index for later removal
Logging
Methods for logging things.
Gremlin.log.debug(toolId, message)
Log a message at the debug level.
Parameters:
Gremlin.log.error(toolId, message)
Log a message at the error level.
Parameters:
Gremlin.log.info(toolId, message)
Log a message at the info level.
Parameters:
Gremlin.log.trace(toolId, message)
Log a message at the trace level.
Parameters:
Gremlin.log.warn(toolId, message)
Log a message at the warn level.
Parameters:
Menu
Methods for setting up menus and keeping them up to date.
Gremlin.menu.updateF10(toolId, commands, forUnits)
Update the F10 menu.
Parameters:
- toolId string A string indicating the top level menu to create
- commands table A table of menu items to sync
- forUnits table A list of units who should be given menu access
Utils
Methods for miscellaneous script activities.
Gremlin.utils.countTableEntries(_tbl)
Count items in a table, numeric or otherwise.
Parameters:
- _tbl table The table to count entries within
Returns:
- integer The number of items in the table
Gremlin.utils.getUnitZones(_unit)
Get a list of zones a unit is in.
Parameters:
- _unit string The unit whose zones should be retrieved
Returns:
- table The list of unit zones
Gremlin.utils.inspect(_value, _depth)
Get a mostly-Lua representation of a value.
Parameters:
- _value any The value to inspect
- _depth integer How deep we've already inspected; should be 0 or nil
Returns:
- string A string representation of the value
Gremlin.utils.isInTable(_tbl, _needle)
Searches a table for a value.
Parameters:
- _tbl table The table to search
- _needle any The value to find
Returns:
- boolean Whether the needle was in the haystack
Gremlin.utils.mergeTables(...)
Combine two tables together. Doesn't care about integer versus string keys.
Parameters:
- ... table One or more tables to combine together
Returns:
- table The final combined result
Gremlin.utils.parseFuncArgs(_args, _objs)
Parse arguments for things like menus.
Parameters:
Returns:
- table The final (usable) arguments
checkTrigger(_trigger, _type, _extra)
Check whether a trigger condition has been met.
Parameters:
- _trigger table The trigger definition table to check against
- _type string The trigger type to check for
- _extra any Any extra data needed to perform the check, or nil
Returns:
- boolean Whether the trigger condition has been met
innerSquash(_tbl, _idx)
Flattens a table by removing the second level, rather than the first
Parameters:
Returns:
- table The flattened table
Top Level methods
setup(config)
Setup Gremlin.
Parameters:
- config table The settings table to configure Gremlin using
Last updated 2024-04-28 12:12:18
Evac
Modules
- Urgency
Module Urgency
Gremlin Urgency
DO NOT EDIT THIS SCRIPT DIRECTLY! Things WILL break that way.
Instead!
When calling Urgency:setup()
, you can pass in a configuration table instead
of nil
. Make your changes in the table you pass - defaults are already in
place if you want to leave those out.
An example, providing all the defaults, is available in the docs, or near the end of this script.
Top level methods
Name | Summary |
---|---|
setup(config) | Setup Gremlin Urgency |
The argument should contain a configuration table as shown below. |
Top level methods
Methods for interacting with Urgency itself.
setup(config)
Setup Gremlin Urgency
The argument should contain a configuration table as shown below.
Example providing all the defaults:
Urgency:setup({
adminPilotNames = {},
countdowns = {},
})
Parameters:
- config table
Last updated 2024-04-28 12:12:18
Modules
- Waves
Module Waves
Gremlin Waves
DO NOT EDIT THIS SCRIPT DIRECTLY! Things WILL break that way.
Instead!
When calling Waves:setup()
, you can pass in a configuration table instead
of nil
. Make your changes in the table you pass - defaults are already in
place if you want to leave those out.
An example, providing all the defaults, is available in the docs, or near the end of this script.
Top level methods
Name | Summary |
---|---|
setup(config) | Setup Gremlin Waves |
The argument should contain a configuration table as shown below. |
Top level methods
Methods for interacting with Waves itself.
setup(config)
Setup Gremlin Waves
The argument should contain a configuration table as shown below.
Example providing all the defaults:
Waves:setup({
adminPilotNames = {},
waves = {},
})
Parameters:
- config table
Last updated 2024-04-28 12:12:18