# How to add platform and close ModalDialog in script?

**URL:** <https://qa.fmod.com/t/how-to-add-platform-and-close-modaldialog-in-script/20677>\
**Category:** FMOD Studio\
**Tags:** javascript\
**Created:** [September 20, 2023, 10:54am UTC](https://qa.fmod.com/t/how-to-add-platform-and-close-modaldialog-in-script/20677 "2023-09-20T10:54:33Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![MisakaCirno](https://avatars.discourse-cdn.com/v4/letter/m/e480ec/32.png) [@MisakaCirno](https://qa.fmod.com/u/MisakaCirno)\
**Post date:** [September 20, 2023, 10:54am UTC](https://qa.fmod.com/t/how-to-add-platform-and-close-modaldialog-in-script/20677/1 "2023-09-20T10:54:33Z")

</div>

I’m working on a script, but I’m running into two problems.

* * *

The first problem:  
I can get all the platforms in the current preference via `studio.project.workspace.platforms`, and I can make changes to them, but I can’t add a platform.

I think maybe I need to create a `(ManagedObject:Platform)` object, but I don’t seem to be able to find any information on how to do that from the documentation.

* * *

Second question:  
I have used `studio.ui.showModalDialog()` to create a window that has a number of buttons. I want this dialog to be closed when the function is executed after pressing the buttons. But again there is no information about it.

I tried using `studio.window.triggerAction(studio.window.actions.WindowClose)`, but it directly closes the FMOD Studio window, not the dialog.

---

<div class="post-metadata">

**Author:** ![Leah\_FMOD](https://yyz2.discourse-cdn.com/flex036/user_avatar/qa.fmod.com/leah_fmod/32/3685_2.png) [@Leah\_FMOD](https://qa.fmod.com/u/Leah_FMOD)\
**Post date:** [September 21, 2023, 3:24am UTC](https://qa.fmod.com/t/how-to-add-platform-and-close-modaldialog-in-script/20677/2 "2023-09-21T03:24:13Z")

</div>

For the first problem, the bare minimum you need to do to avoid any project issues is the following:

```auto
var platform = studio.project.create("Platform");
studio.project.workspace.platforms.push(platform);
platform.encodingSettings.platform = platform;

```

This will create a new platform with the associated encoding setting, though you’ll want to populate the `Platform` and associated `EncodingSetting` with the settings you want. Note that you can create any `ManagedObject` you need in Studio using `studio.project.create()`.

For the second problem, can I get you to share a code snippet containing any code you’re using for the modal dialog and buttons?

---

<div class="post-metadata">

**Author:** ![MisakaCirno](https://avatars.discourse-cdn.com/v4/letter/m/e480ec/32.png) [@MisakaCirno](https://qa.fmod.com/u/MisakaCirno)\
**Post date:** [September 21, 2023, 3:53am UTC](https://qa.fmod.com/t/how-to-add-platform-and-close-modaldialog-in-script/20677/3 "2023-09-21T03:53:25Z")

</div>

Thanks for the code, it’s very useful. However, I have encountered other problems.  
(1)  
Actually my intention is to add a platform according to a preset (with defaults for its name and subpaths), as if I had chosen Add Platform in the context menu. So is it possible to add a new preset to this context menu?  
 ![export](https://canada1.discourse-cdn.com/flex036/uploads/fmod/original/2X/e/e687e1aa1a637ffe5bb7fcb64b0db1bde682db47.png)

(2)  
Also, while it is possible to add platforms using `studio.project.workspace.platforms.push(platform);`, it doesn’t seem to be possible to remove platforms from it? According to the console, this seems to require `ManagedRelationship.remove`, but I haven’t found the correct way to use that either.

(3)  
Regarding the dialog, my code looks like this:

```auto
function createButton(buttonContent, execute) {
    return {
        widgetType: studio.ui.widgetType.PushButton,
        text: buttonContent,
        sizePolicy: {
            horizontalPolicy: studio.ui.sizePolicy.Expanding,
            verticalPolicy: studio.ui.sizePolicy.Expanding
        },
        onClicked: execute
    };
}

var window_Export = {
    windowTitle: "My Dialog Tool",
    windowWidth: 200,
    windowHeight: 200,
    widgetType: studio.ui.widgetType.Layout,
    layout: studio.ui.layoutType.HBoxLayout,
    spacing: 10,
    items: [
        createButton("Do Something", function () {
            // I will export some data here.
            exportDatas("MyData.data");
            // And I want to close the dialog after that.
            // Maybe something like this:
            studio.ui.closeDialog();
        }),
    ]
};

studio.menu.addMenuItem({
    name: "My Dialog Tool",
    execute: function () {
        studio.ui.showModalDialog(window_Export);
    }
});

```

---

<div class="post-metadata">

**Author:** ![Leah\_FMOD](https://yyz2.discourse-cdn.com/flex036/user_avatar/qa.fmod.com/leah_fmod/32/3685_2.png) [@Leah\_FMOD](https://qa.fmod.com/u/Leah_FMOD)\
**Post date:** [September 21, 2023, 10:43pm UTC](https://qa.fmod.com/t/how-to-add-platform-and-close-modaldialog-in-script/20677/4 "2023-09-21T22:43:22Z")

</div>

> [@MisakaCirno](#):
>
> Actually my intention is to add a platform according to a preset (with defaults for its name and subpaths), as if I had chosen Add Platform in the context menu. So is it possible to add a new preset to this context menu?

Unfortunately, it isn’t. The options in the “Add Platform” menu are based on a hard-coded list of platform hardware. Creating your own `Platform` in a script that you duplicate as needed as a preset may be an option though.

> [@MisakaCirno](#):
>
> Also, while it is possible to add platforms using `studio.project.workspace.platforms.push(platform);`, it doesn’t seem to be possible to remove platforms from it? According to the console, this seems to require `ManagedRelationship.remove`, but I haven’t found the correct way to use that either.

The simplest way to do this is to delete the `Platform` outright with [`studio.project.deleteObject()`](https://www.fmod.com/docs/2.02/studio/scripting-api-reference-project.html#projectdeleteobject). If you want to remove the `Platform` without deletion, you can use `studio.project.workspace.relationships.platforms.remove()`, but the removed `Platform` will trigger a project validation issue since it’s now a dangling object.

> [@MisakaCirno](#):
>
> (3)  
> Regarding the dialog, my code looks like this:
> 
> ```auto
> //...
> 
> ```

To close the dialog from a widget, in this case the `studio.ui.widgetType.PushButton`, instead of calling `studio.ui.closeDialog();` you’ll want to call `this.closeDialog();`.

---

<div class="post-metadata">

**Author:** ![MisakaCirno](https://avatars.discourse-cdn.com/v4/letter/m/e480ec/32.png) [@MisakaCirno](https://qa.fmod.com/u/MisakaCirno)\
**Post date:** [September 22, 2023, 3:25am UTC](https://qa.fmod.com/t/how-to-add-platform-and-close-modaldialog-in-script/20677/5 "2023-09-22T03:25:57Z")

</div>

> [@Leah\_FMOD](#):
>
> Unfortunately, it isn’t. The options in the “Add Platform” menu are based on a hard-coded list of platform hardware. Creating your own `Platform` in a script that you duplicate as needed as a preset may be an option though.

* * *

We coincided on this point, and I wrote this piece of code to accomplish this.  
First, add all the platforms that are in the context menu to the list.  
Then execute the following code in the console:

```auto
function generateDefaultPlatformCode() {
    var code = [];
    code.push("var platform = studio.project.create(\"Platform\");");
    code.push("platform.encodingSettings.platform = platform;");
    code.push("switch (platform.name) {");

    for (var i = 0; i < studio.project.workspace.platforms.length; i++) {
        var p = studio.project.workspace.platforms[i];
        code.push(" case \"{0}\":".format(p.name));
        if (p.name == "Custom") {
            code.push(" default:");
        }
        code.push(" platform.name = \"{0}\";".format(p.name));
        code.push(" platform.subDirectory = \"{0}\";".format(p.subDirectory));
        code.push(" platform.hardwareType = {0};".format(p.hardwareType));
        code.push(" platform.speakerFormat = {0};".format(p.speakerFormat));
        code.push(" platform.encodingSettings.encodingFormat = {0};".format(p.encodingSettings.encodingFormat));
        code.push(" platform.encodingSettings.quality = {0};".format(p.encodingSettings.quality));
        code.push(" platform.encodingSettings.sampleRateMode = {0};".format(p.encodingSettings.sampleRateMode));
        code.push(" platform.encodingSettings.sampleRate = {0};".format(p.encodingSettings.sampleRate));
        code.push(" platform.encodingSettings.loadingMode = {0};".format(p.encodingSettings.loadingMode));
        code.push(" break;");
    }

    code.push("}");

    console.log(code.join("\n"));
}

```

* * *

Then you can get the output like this:

```auto
var platform = studio.project.create("Platform");
platform.encodingSettings.platform = platform;
switch (platform.name) {
    case "Desktop":
        platform.name = "Desktop";
        platform.subDirectory = "Desktop";
        platform.hardwareType = 0;
        platform.speakerFormat = 5;
        platform.encodingSettings.encodingFormat = 3;
        platform.encodingSettings.quality = 37;
        platform.encodingSettings.sampleRateMode = 0;
        platform.encodingSettings.sampleRate = 48000;
        platform.encodingSettings.loadingMode = 0;
        break;
    case "Mobile":
        platform.name = "Mobile";
        platform.subDirectory = "Mobile";
        platform.hardwareType = 1;
        platform.speakerFormat = 1;
        platform.encodingSettings.encodingFormat = 1;
        platform.encodingSettings.quality = 80;
        platform.encodingSettings.sampleRateMode = 0;
        platform.encodingSettings.sampleRate = 24000;
        platform.encodingSettings.loadingMode = 0;
        break;
    case "Xbox One":
        platform.name = "Xbox One";
        platform.subDirectory = "XboxOne";
        platform.hardwareType = 3;
        platform.speakerFormat = 6;
        platform.encodingSettings.encodingFormat = 2;
        platform.encodingSettings.quality = 60;
        platform.encodingSettings.sampleRateMode = 0;
        platform.encodingSettings.sampleRate = 48000;
        platform.encodingSettings.loadingMode = 0;
        break;
    case "Xbox Series X|S":
        platform.name = "Xbox Series X|S";
        platform.subDirectory = "Scarlett";
        platform.hardwareType = 11;
        platform.speakerFormat = 6;
        platform.encodingSettings.encodingFormat = 5;
        platform.encodingSettings.quality = 63;
        platform.encodingSettings.sampleRateMode = 0;
        platform.encodingSettings.sampleRate = 48000;
        platform.encodingSettings.loadingMode = 0;
        break;
    case "PlayStation 4":
        platform.name = "PlayStation 4";
        platform.subDirectory = "PS4";
        platform.hardwareType = 5;
        platform.speakerFormat = 6;
        platform.encodingSettings.encodingFormat = 4;
        platform.encodingSettings.quality = 50;
        platform.encodingSettings.sampleRateMode = 0;
        platform.encodingSettings.sampleRate = 48000;
        platform.encodingSettings.loadingMode = 0;
        break;
    case "PlayStation 5":
        platform.name = "PlayStation 5";
        platform.subDirectory = "PS5";
        platform.hardwareType = 10;
        platform.speakerFormat = 6;
        platform.encodingSettings.encodingFormat = 5;
        platform.encodingSettings.quality = 63;
        platform.encodingSettings.sampleRateMode = 0;
        platform.encodingSettings.sampleRate = 48000;
        platform.encodingSettings.loadingMode = 0;
        break;
    case "Switch":
        platform.name = "Switch";
        platform.subDirectory = "Switch";
        platform.hardwareType = 8;
        platform.speakerFormat = 5;
        platform.encodingSettings.encodingFormat = 1;
        platform.encodingSettings.quality = 80;
        platform.encodingSettings.sampleRateMode = 0;
        platform.encodingSettings.sampleRate = 48000;
        platform.encodingSettings.loadingMode = 0;
        break;
    case "Custom":
    default:
        platform.name = "Custom";
        platform.subDirectory = "Custom";
        platform.hardwareType = 9;
        platform.speakerFormat = 6;
        platform.encodingSettings.encodingFormat = 3;
        platform.encodingSettings.quality = 37;
        platform.encodingSettings.sampleRateMode = 0;
        platform.encodingSettings.sampleRate = 48000;
        platform.encodingSettings.loadingMode = 0;
        break;
}

```

* * *

In the end, they just need to be wrapped a little bit to get the platform instances created based on the preset parameters:

```auto
function createDefaultPresetPlatform(defaultPresetName) {
    if (defaultPresetName == null || defaultPresetName == "") {
        return;
    }
    var platform = studio.project.create("Platform");
    platform.encodingSettings.platform = platform;
    switch (defaultPresetName) {
        case "Desktop":
            platform.name = "Desktop";
            platform.subDirectory = "Desktop";
            platform.hardwareType = 0;
            platform.speakerFormat = 5;
            platform.encodingSettings.encodingFormat = 3;
            platform.encodingSettings.quality = 37;
            platform.encodingSettings.sampleRateMode = 0;
            platform.encodingSettings.sampleRate = 48000;
            platform.encodingSettings.loadingMode = 0;
            break;
        case "Mobile":
            platform.name = "Mobile";
            platform.subDirectory = "Mobile";
            platform.hardwareType = 1;
            platform.speakerFormat = 1;
            platform.encodingSettings.encodingFormat = 1;
            platform.encodingSettings.quality = 80;
            platform.encodingSettings.sampleRateMode = 0;
            platform.encodingSettings.sampleRate = 24000;
            platform.encodingSettings.loadingMode = 0;
            break;
        case "Xbox One":
            platform.name = "Xbox One";
            platform.subDirectory = "XboxOne";
            platform.hardwareType = 3;
            platform.speakerFormat = 6;
            platform.encodingSettings.encodingFormat = 2;
            platform.encodingSettings.quality = 60;
            platform.encodingSettings.sampleRateMode = 0;
            platform.encodingSettings.sampleRate = 48000;
            platform.encodingSettings.loadingMode = 0;
            break;
        case "Xbox Series X|S":
            platform.name = "Xbox Series X|S";
            platform.subDirectory = "Scarlett";
            platform.hardwareType = 11;
            platform.speakerFormat = 6;
            platform.encodingSettings.encodingFormat = 5;
            platform.encodingSettings.quality = 63;
            platform.encodingSettings.sampleRateMode = 0;
            platform.encodingSettings.sampleRate = 48000;
            platform.encodingSettings.loadingMode = 0;
            break;
        case "PlayStation 4":
            platform.name = "PlayStation 4";
            platform.subDirectory = "PS4";
            platform.hardwareType = 5;
            platform.speakerFormat = 6;
            platform.encodingSettings.encodingFormat = 4;
            platform.encodingSettings.quality = 50;
            platform.encodingSettings.sampleRateMode = 0;
            platform.encodingSettings.sampleRate = 48000;
            platform.encodingSettings.loadingMode = 0;
            break;
        case "PlayStation 5":
            platform.name = "PlayStation 5";
            platform.subDirectory = "PS5";
            platform.hardwareType = 10;
            platform.speakerFormat = 6;
            platform.encodingSettings.encodingFormat = 5;
            platform.encodingSettings.quality = 63;
            platform.encodingSettings.sampleRateMode = 0;
            platform.encodingSettings.sampleRate = 48000;
            platform.encodingSettings.loadingMode = 0;
            break;
        case "Switch":
            platform.name = "Switch";
            platform.subDirectory = "Switch";
            platform.hardwareType = 8;
            platform.speakerFormat = 5;
            platform.encodingSettings.encodingFormat = 1;
            platform.encodingSettings.quality = 80;
            platform.encodingSettings.sampleRateMode = 0;
            platform.encodingSettings.sampleRate = 48000;
            platform.encodingSettings.loadingMode = 0;
            break;
        case "Custom":
        default:
            platform.name = "Custom";
            platform.subDirectory = "Custom";
            platform.hardwareType = 9;
            platform.speakerFormat = 6;
            platform.encodingSettings.encodingFormat = 3;
            platform.encodingSettings.quality = 37;
            platform.encodingSettings.sampleRateMode = 0;
            platform.encodingSettings.sampleRate = 48000;
            platform.encodingSettings.loadingMode = 0;
            break;
    }

    return platform;
}

```

---

<div class="post-metadata">

**Author:** ![MisakaCirno](https://avatars.discourse-cdn.com/v4/letter/m/e480ec/32.png) [@MisakaCirno](https://qa.fmod.com/u/MisakaCirno)\
**Post date:** [September 22, 2023, 3:36am UTC](https://qa.fmod.com/t/how-to-add-platform-and-close-modaldialog-in-script/20677/6 "2023-09-22T03:36:02Z")

</div>

> [@Leah\_FMOD](#):
>
> The simplest way to do this is to delete the `Platform` outright with [`studio.project.deleteObject()`](https://www.fmod.com/docs/2.02/studio/scripting-api-reference-project.html#projectdeleteobject). If you want to remove the `Platform` without deletion, you can use `studio.project.workspace.relationships.platforms.remove()`, but the removed `Platform` will trigger a project validation issue since it’s now a dangling object.

> [@Leah\_FMOD](#):
>
> To close the dialog from a widget, in this case the `studio.ui.widgetType.PushButton`, instead of calling `studio.ui.closeDialog();` you’ll want to call `this.closeDialog();`.

After testing, both functions work well, thanks for your professional answer.

* * *

I would also like to ask what is the meaning of the line of code `platform.encodingSettings.platform = platform;`?

If I don’t execute it, I see a “Validation Required” warning in FMOD Studio. And it doesn’t appear in the Build list. But after executing it everything works fine.

Does this mean that object to object relationships need to be established in both directions?

---

<div class="post-metadata">

**Author:** ![Leah\_FMOD](https://yyz2.discourse-cdn.com/flex036/user_avatar/qa.fmod.com/leah_fmod/32/3685_2.png) [@Leah\_FMOD](https://qa.fmod.com/u/Leah_FMOD)\
**Post date:** [September 22, 2023, 4:03am UTC](https://qa.fmod.com/t/how-to-add-platform-and-close-modaldialog-in-script/20677/7 "2023-09-22T04:03:15Z")

</div>

> [@MisakaCirno](#):
>
> I would also like to ask what is the meaning of the line of code `platform.encodingSettings.platform = platform;`?
> 
> If I don’t execute it, I see a “Validation Required” warning in FMOD Studio. And it doesn’t appear in the Build list. But after executing it everything works fine.
> 
> Does this mean that object to object relationships need to be established in both directions?

It depends on the object(s) in question, but in this case, yes. Creating a `Platform` also creates an associated `EncodingSetting`, but doesn’t connect the `EncodingSetting` to the `Platform` since `EncodingSetting` can also be associated with Assets, Asset Folders, etc. That line of code explicitly establishes the relationship and also automatically adds the `EncodingSetting` to `Platform.associatedSettings`, which resolves the validation issue.

---

<div class="post-metadata">

**Author:** ![MisakaCirno](https://avatars.discourse-cdn.com/v4/letter/m/e480ec/32.png) [@MisakaCirno](https://qa.fmod.com/u/MisakaCirno)\
**Post date:** [September 22, 2023, 6:34am UTC](https://qa.fmod.com/t/how-to-add-platform-and-close-modaldialog-in-script/20677/8 "2023-09-22T06:34:37Z")

</div>

Thank you very much for providing simple and clear answers!
