Develop a Simple App

This section provides an introduction to Application development and presents important foundational knowledge:

  • How Applications and Extensions are defined in .kit and .toml files.

  • How to explore existing Extensions and adding them to your Application.

  • How user settings can override Application configurations.

  • Controlling Application window layout.

Kit and Toml Files

If you have developed solutions before you are likely to have used configuration files. Configuration files present developers with a “low-code” approach to changing behaviors. With Kit SDK you will use configuration files to declare:

  • Package metadata

  • Dependencies

  • Settings

Kit allows Applications and Services to be configured via .kit files and Extensions via .toml files. Both files present the same ease of readability and purpose of defining a configuration - they simply have different file Extensions.

Let’s create a .kit file and register it with the build system:

  1. Create a Kit file:

    1. Create a file named my_company.my_app.kit in .\source\apps.

    2. Add this content to the file:

    [package]
    title = "My App"
    description = "An Application created from a tutorial."
    version = "2023.0.0"
    
    [dependencies]
    "omni.kit.uiapp" = {}
    
    [settings]
    app.window.title = "My App"
    
    [[test]]
    args = [
        "--/app/window/title=My Test App",
    ]
    
  2. Configure the build tool to recognize the new Application:

    1. Open .\premake5.lua.

    2. Find the section -- Apps:.

    3. Add an entry for the new app: define_app("my_company.my_app").

  3. Run the build command.

  4. Start the app:

    • Windows: .\_build\windows-x86_64\release\my_company.my_app.bat

    • Linux: ./_build/linux-x86_64/release/my_company.my_app.sh

My Company App Starting Point

Congratulations, you have created an Application!

Let’s review the sections of .kit and .toml files:

Package

[package]
title = "My App"
description = "An Application created from a tutorial."
version = "2023.0.0"

This section provides information used for publishing and displaying information about the Application/Extension. For example, version = "2023.0.0" is used both in publishing and UI: a publishing process can alert a developer that the given version has already been published and the version can be shown in an “About Window” and the Extension Manager.

Dependencies

[dependencies]
"omni.kit.uiapp" = {}

Dependencies section is a list of Extensions used by the Application/Extension. The above reference "omni.kit.uiapp" = {} points to the most recent version available but can be configured to use specific versions. Example of an Extension referenced by a specific version:

"omni.kit.converter.cad" = {version = "200.1", exact = true}

The dependencies can be hosted in Extension Registries for on-demand download or in various locations on the local workstation - including inside a project like kit-app-template.

Settings

[settings]
app.window.title = "My App"

Settings provide a low-code mechanism to customize Application/Extension behavior. Some settings modify UI and others modify functionality - it all depends on how an Application/Extension makes use of the setting. An Omniverse developer should consider exposing settings to developers - and end users - to make Extensions as modular as possible.

Experiment

Change the title to My Company App - app.window.title = "My Company App" - and run the app again - still, no build required.

Note the Application title bar shows the new name.

Test

The test section can be thought of as a combined dependencies and settings section. It allows adding dependencies and settings for when running an Application and Extension in test mode.

[[test]]
args = [
	"--/app/window/title=My Test App",
]

We will cover this in greater detail later.

Explore NVIDIA Extensions

The Extension Manager window is a tool for developers to explore Extensions created on the Omniverse platform. It lists Extensions created by NVIDIA, the Omniverse community, and can be configured to list Extensions that exist on a local workstation. Let’s add the Extension Manager to the app so we can look for dependencies to add.

  1. Add Extension Manager.

    1. Open .\source\apps\my_company.my_app.kit.

    2. Add dependency omni.kit.window.extensions. Dependencies section should read:

    [dependencies]
    "omni.kit.uiapp" = {}
    "omni.kit.window.extensions" = {}
    
    1. In order to point the Extension Manager to the right Extension Registry we need to add the following settings:

    # Extension Registries
    [settings.exts."omni.kit.registry.nucleus"]
    registries = [
        { name = "kit/default", url = "https://ovextensionsprod.blob.core.windows.net/exts/kit/prod/shared" },
        { name = "kit/sdk", url = "https://ovextensionsprod.blob.core.windows.net/exts/kit/prod/sdk/${kit_version_short}/${kit_git_hash}" },
    ]
    
    1. Observe that - once you save the source kit file - the corresponding kit file in the build directory was updated as well. This is due to the use of symlinks. A build is not necessary when editing .kit files. See:

      • Windows: .\_build\windows-x86_64\release\apps\my_company.my_app.kit

      • Linux: ./_build/linux-x86_64/release/apps/my_company.my_app.kit

  2. Explore Extensions in Extension Manager.

    1. Start the app:

      • Windows: .\_build\windows-x86_64\release\my_company.my_app.bat

      • Linux: ./_build/linux-x86_64/release/my_company.my_app.sh

    2. Open Extension Manager: Window > Extensions.

    3. Please allow Extension Manager to sync with the Extension Registry. The listing might not load instantly.

    4. Search for graph editor example. The Extension Manager should list omni.kit.graph.editor.example in the NVIDIA tab.

    Extension Manager

    1. Click INSTALL.

    2. Click the toggle DISABLED to enable Extension.

    Extension Manager

    1. Check AUTOLOAD.

    Extension Manager

    1. Close the app and start again.

    2. Observe that the Graph Editor Example Extension is enabled. Look at the [dependencies] section in .\source\apps\my_company.my_app.kit. The omni.kit.graph.editor.example Extension is not listed. The point here is to make it clear that when an Extension is enabled by a user in the Extension Manager, the dependency is NOT added to the Application .kit file. The reason the Extension is still enabled in the app is due to user settings. Let’s explore that topic in more detail…

User Settings

Kit Applications allow a user’s choices and settings to persist between sessions. Configurations like these are stored in a user.config.json file. The default location for this file is the Omniverse Launcher DATA PATH: [data path]\Kit\[application name]\[application version]\user.config.json. If you are not using Omniverse Launcher - or you cannot find the location of the user.config.json file for whatever reason - look at the first lines of the Application log. Look for the line that starts with Loading user config located at:.

Launcher data path

Inspecting the file for this tutorial you should see this section:

"exts": {
    "enabled": {
        "0": "omni.kit.graph.editor.example-1.0.22"
    }
}

When you uncheck AUTOLOAD for omni.kit.graph.editor.example in the Extension Manager you’ll notice the user.config.json file is no longer listing the Extension as enabled.

Note

Because the config file can store both custom enabled Extensions and custom settings, as a developer you may want to at times delete your user.config.json file for the app you are developing to make sure you are viewing the Application like an end user will when they use it in its default state.

Note

As a developer, we recommend that you refrain from using the AUTOLOAD functionality unless you truly want to enable an Extension without making it permanently available in the Application.

Dependency Hierarchy

While the selected Extension is ENABLED, select the DEPENDENCIES tab and click the Toggle View button. It might take a few seconds for the UI to refresh.

Extension Manager

The Extension Manager presents up and downstream dependencies. This is useful for discovering how one Extension is composed of many. It’s also a convenient way to find where an Extension is being referenced from.

Explore Community Extensions

Extensions developed by the community are not really any different from NVIDIA Extensions, they are just stored in a different location and have not been vetted by NVIDIA the same way NVIDIA Extensions have. That’s not to say they have not been through rigorous tests - they have simply not been through the NVIDIA release pipeline.

There are two settings that need to be added to the Application to make use of community Extensions.

  1. Add app.extensions.installUntrustedExtensions = true to enable the app to install and load community Extensions.

[settings]
app.window.title = "My Company App"
app.extensions.installUntrustedExtensions = true
  1. Add the URL to the Community Extension Registry by modifying the registries setting.

# Extension Registries
[settings.exts."omni.kit.registry.nucleus"]
registries = [
    { name = "kit/default", url = "https://ovextensionsprod.blob.core.windows.net/exts/kit/prod/shared" },
    { name = "kit/sdk", url = "https://ovextensionsprod.blob.core.windows.net/exts/kit/prod/sdk/${kit_version_short}/${kit_git_hash}" },
    { name = "kit/community", url = "https://dw290v42wisod.cloudfront.net/exts/kit/community" },
]
  1. Restart the app and allow Extension Manager to sync with the Extension Registry. The listing might not load instantly. You can now experiment by adding community Extensions such as "heavyai.ui.component" = {} to the [dependencies] section.

Community Extension Registry

Add Extensions

  1. Let’s assume we found a few Extensions we want to use. Add the below [dependencies] section to the my_company.my_app.kit Application. The Extension Manager has been removed since that is a developer tool.

[dependencies]
"omni.kit.uiapp" = {}
# Viewport
"omni.kit.viewport.bundle" = {}
# Render Settings
"omni.rtx.window.settings" = {}
# Content Browser
"omni.kit.window.content_browser" = {}
# Stage Inspector
"omni.kit.window.stage" = {}
# Layer Inspector
"omni.kit.widget.layers" = {}
# Toolbar. Setting load order so that it loads last.
"omni.kit.window.toolbar" = { order = 1000 }
# Properties Inspector
"omni.kit.property.bundle" = {}

# DX shader caches (windows only)
[dependencies."filter:platform"."windows-x86_64"]
"omni.rtx.shadercache.d3d12" = {}
  1. Add this setting:

app.content.emptyStageOnStart = true
  1. Run the app again. It’ll look something like this:

App

Application Layout

The Application window layout is fairly organized already but let’s take care of the floating Content Browser by docking it below the viewport window.

Add a Resource Extension

Extensions do not need to provide code. We use so-called “resource Extensions” to provide assets, data, and anything else that can be considered a resource. In this example we create it to provide a layout file.

  1. Create a new Extension using repo template new command (command cheat-sheet).

    1. For What do you want to add choose extension.

    2. For Choose a template choose python-extension-simple.

    3. Enter an all new name: my_company.my_app.resources. Do not use the default name.

    4. Leave version as 0.1.0.

    5. The new Extension is created in .\source\extensions\my_company.my_app.resources.

  2. Add a layouts directory inside my_company.my_app.resources. We’ll be adding a resource file here momentarily.

  3. Configure the build to pick up the layouts directory by adding a { "layouts", ext.target_dir.."/layouts" }, in the Extension’s .\my_company.my_app.resources\premake5.lua file:

-- Use folder name to build Extension name and tag. Version is specified explicitly.
local ext = get_current_extension_info()

-- That will also link whole current "target" folder into as extension target folder:
project_ext (ext)
    repo_build.prebuild_link {
        { "data", ext.target_dir.."/data" },
        { "docs", ext.target_dir.."/docs" },
        { "layouts", ext.target_dir.."/layouts" },
        { "my_company", ext.target_dir.."/my_company" },
    }

Configure App to Recognize Extensions

By default, Extensions that are part of the Kit SDK will be recognized by Applications. When we add Extensions like the one above we need to add paths to the Application’s .kit file. The below adds the paths for these additional Extensions. Note the use of ${app} as a token. This will be replaced with the path to the app at runtime.

Add this to the my_company_my_app.kit:

[settings.app.exts]
# Add additional search paths for dependencies.
folders.'++' = ["${app}/../exts", "${app}/../extscache/"]

Note

Reference: Tokens

Configure App to Provide Layout Capabilities

Add these Extensions to the my_company_my_app.kit [dependencies] section. omni.app.setup provides layout capabilities.

# Layout capabilities
"omni.app.setup" = {}
# App resources
"my_company.my_app.resources" = {}

Create a Layout File

  1. Run a build to propagate the new Extension to the built solution and start the app.

  2. Drag and drop the Content Browser on top of the lower docker manipulator within the Viewport window.

Drag Browser

Dropped Browser

  1. Save the layout:

    1. Use menu Window > Layout > Save Layout... command.

    2. Save the layout as .\source\extensions\my_company.my_app.resources\layouts\layout.json.

Use Layout

  1. Add this to the my_company.my_app.kit files [settings] section. Again, here we are using a token: ${my_company.my_app.resources}. That token is replaced with the path to the Extension at runtime:

app.kit.editor.setup = true
app.layout.default = "${my_company.my_app.resources}/layouts/layout.json"
  1. Run a build so the layouts directory with its layout.json file is created in the _build directory structure.

  2. Run the Application again and see the Content Browser being docked.

A developer can provide end users with different layouts - or workflows. This topic can be further explored in the omni.app.setup reference.

You now have an Application and could skip ahead to the Package App and Publish App sections; however, this tutorial now continues with a more advanced example: Develop a USD Explorer App.