Extend Eden in Three Clicks

Extending the Eden editor is a bit fiddly, especially if you aren't accustomed to writing Arma 3 config.cpp files or creating addon .pbo's. Fortunately the Debug Console—which was carried over from the 2D editor where it previously wasn't much use—runs scripts in the Eden context, exactly the same way that a full Eden addon would. Scripts that manipulate Eden objects and settings can be pasted into the Debug Console and executed immediately.

To try it out:

  1. Open the Eden editor on any map.
  2. Select Tools and then Debug Console... from the menu.
  3. Paste the following script into the Execute field:
    for "_i" from 0 to 30 do
    {
        create3DENEntity ["Object", "Land_FieldToilet_F", 
            screenToWorld [0.5, 0.5] vectorAdd [random 50 - 25, random 50 - 25, 0]];
    };
    
  4. Click the LOCAL EXEC button.

The created objects will immediately show up as Eden editor objects:

An example image of scripting in the Eden editor.

Although you could randomly place toilets in the mission with an init.sqf script, placing them in the editor gives you instant feedback, and also lets you tweak the results.

You can't add user interface elements to Eden—such as menu options or object attributes—without making a full add-on, but you can use the console to automate such things as:

After a few more examples, we'll cover what you need to know to make your own script snippets.

Random Rotations

Placing down "background" litter to enhance the ambience of missions is as easy as dragging objects from the object list in Eden, but by default everything will be pointing north. Rather than tediously rotating a large number of placed objects, you can select them and run this script:

collect3DENHistory {
    {
        _x set3DENAttribute ["rotation", [0, 0, random 360]];
    }
    forEach get3DENSelected "object";

    do3DENAction "LevelWithSurface";
};

It's ideal for fields of wrecks or other littered objects:

Random rotation of objects in Arma 3's Eden editor.

One part of the script above that may not be self explanatory is the call to collect3DENHistory. Without it, each change a script makes—like setting the rotation of a single object—is added to the undo stack as one item. Undoing the entire script would require many presses of the undo key.

Any changes made within a collect3DENHistory block—however—are grouped into a single undo item.

Batch Class Name Changes

If you need to swap out a large number of objects of one type for another—for example, changing all your UCP camouflage soldiers to OCP camouflage as the United States Army currently is—you can do so with a console script.

The following script takes every Land_Wreck_Ural_F on the map and turns them into a Land_Wreck_Slammer_F, and every Land_Wreck_Hunter_F into a Land_Wreck_T72_hull_F. If you edit the _map and put the same "from" class on multiple lines, the script will randomly choose a "to" class name to swap it to.

private _map = [
    ["Land_Wreck_Ural_F", "Land_Wreck_Slammer_F"],
    ["Land_Wreck_Hunter_F", "Land_Wreck_T72_hull_F"]
];

collect3DENHistory {
    {
        private _entity = _x;
        private _mapEntries =
            _map select { _x select 0 == typeOf _entity };

        if (count _mapEntries > 0) then
        {
            [_entity] set3DENObjectType
                (selectRandom _mapEntries select 1);
        };
    }
    forEach (all3DENEntities select 0);
};

Organising Objects

This script puts the selected objects into a perfect circle:

private _centre = screenToWorld [0.5, 0.5];
private _radius = screenToWorld [0.5, 0.5] distance2D screenToWorld [1, 0.5];
private _selected = get3DENSelected "object";

if (count _selected == 0) exitWith { };

private _angleIncrement = 360 / count _selected;
private _angle = 0;

collect3DENHistory {
    {
        _x set3DENAttribute ["position", 
            _centre vectorAdd [_radius * sin _angle, _radius * cos _angle, 0]];

        _x set3DENAttribute ["rotation", [0, 0, _angle]];

        _angle = _angle + _angleIncrement;
    }
    forEach _selected;

    do3DENAction "LevelWithSurface";
};

Scripts that place or position objects seem to be the most fun to play with:

Automatic placement of objects in Eden.

Changing Gear

Ballstic headgear is nice and all, but random caps for the selected units look cooler:

{
    if (_x isKindOf "CAManBase") then
    {
        removeHeadgear _x;
        _x addHeadgear selectRandom 
            ["H_Cap_red", "H_Cap_surfer", "H_Cap_blu", "H_Cap_grn_BI"];

        save3DENInventory [_x];
    };
}
forEach get3DENSelected "object";

Unit gear is a little unusual in Eden; firstly, you modify the gear directly in your script and then tell Eden you've changed it with the—currently undocumented—save3DENInventory command. This isn't typical of Eden scripts; normally you modify the Eden properties of an object and let Eden make the changes to the real object.

Secondly, it isn't part of the undo system. Changes made by both scripts and the arsenal menu item can't be undone.

That the save3DENInventory command isn't covered at all in the extensive Eden documentation could be a hint that inventory handling may change—or, perhaps—that it was just a late addition.

Automating Mission Settings

If you make missions frequently it can be useful to have a script that sets some baseline mission attributes. This example sets just a few of the scenario attributes, which are all documented in the scenario attributes reference:

set3DENMissionAttributes [
    ["Scenario", "OverviewPicture", "picture.paa"],
    ["Multiplayer", "RespawnDelay", 10],
    ["Multiplayer", "MinPlayers", 1],
    ["Multiplayer", "MaxPlayers", 70],
    ["Multiplayer", "DisabledAI", true]];

One omission from the scenario attributes reference—and also the BIS_fnc_3DENExportAttributes function that generates the reference—is what the section should be for each attribute group:

Displayed Section for Scripts
General "Scenario"
Environment "Intel"
Multiplayer "Multiplayer"
Garbage Collection "GarbageCollection"

To set the "Author" attribute shown in the General category in the reference for example, you use "Scenario" as the section:

set3DENMissionAttributes [
    ["Scenario", "Author", "Sun Tzu"]
];

Writing your Own

The Eden script environment is identical to the in-mission script environment, with the exception of a new layer of "Eden Entities":

Diagram of Arma 3's Eden Scripting Environment.

The position of a unit, for example, is updated in two steps:

  1. A script first sets the position into an Eden Attribute by using set3DENAttribute; or, the user drags the unit which also internally updates the Eden Attribute.
  2. The Eden system, detecting a change to the attribute, updates The World. It does the equivalent of setPos on the unit.

The key thing to remember is the transfer of data from Eden Attributes to The World is unidirectional; although you can actually move entities with commands such as setPos—and even see those changes occur on the screen—the changes won't end up in the mission.sqm and will instead be overwritten when the Eden Attributes change, or when the mission is previewed or reloaded.

The one exception to this is with unit gear. Unit gear must be updated on the unit itself, and then copied back to the Eden Attributes via the save3DENInventory command.

Everything else that is available in a mission is also available in Eden. You can, for example, query for map objects, roads, and any other properties of the world or game.

Script Commands

All of the Eden specific script commands are listed in the Eden Command Group page. Many of the Eden commands are only suitable for use in addons—the following is a list of only those commands that are useful in the debug console:

Finding Entities all3DENEntities
get3DENSelected
Changing Entities create3DENComposition
create3DENEntity
delete3DENEntities
get3DENAttribute
set3DENAttributes
set3DENObjectType

(Entity Attributes)
Entity Connections add3DENConnection
get3DENConnections
remove3DENConnection
Layers add3DENLayer
remove3DENLayer
set3DENLayer
get3DENLayerEntities
Miscellaneous collect3DENHistory
do3DENAction
get3DENMissionAttribute
set3DENMissionAttributes

(Mission Attributes)

Using .sqf Files

Once scripts get larger and more complicated, it becomes tedious to paste them into the debug console. Scripts can be saved into a text file and replaced in the debug console with a call to execVM.

While a mission is running, there are three places that are searched for scripts accessed by execVM, loadFile and preprocessFileLineNumbers:

It turns out that all three directories also work within Eden—even though your mission isn't actually running. The script files aren't cached, so each call to execVM or any of the other functions will load a fresh copy each time you execute them.

Hinting

Hint doesn't work in Eden, presumably due to different UI/HUD resources being active. To print values out, use systemChat:

systemChat str [1 + 2, 4 / 2];