Skip to content

Usage

This page covers how to add dota-lua-types and dota-panorama-types to your project and use them effectively.

Requirements

  • JDK 17 or later
  • Gradle 8.x (Kotlin DSL recommended)

Adding the Dependencies

Maven Central

Both packages are published to Maven Central. Add them to your build.gradle.kts:

repositories {
    mavenCentral()
}

dependencies {
    // Dota 2 VScript (server-side Lua) types
    implementation("io.github.isycat:dota-lua-types:<version>")

    // Dota 2 Panorama UI types  (add only if you need Panorama)
    implementation("io.github.isycat:dota-panorama-types:<version>")
}

Check the GitHub releases for the latest version.


Project Structure

When using ktox-dota for Dota 2 development, your project typically uses a multi-module structure to separate server-side (Lua) and client-side (Panorama) code:

my-dota-project/
├── build.gradle.kts       # Root build script
├── settings.gradle.kts    # Project and module definitions
├── lua/                   # Server-side module (VScripts)
│   ├── build.gradle.kts
│   └── src/main/kotlin/   # Your Kotlin VScript sources
└── panorama/              # Client-side module (UI)
    ├── build.gradle.kts
    ├── content/           # Assets like images, sounds, etc.
    ├── src/main/kotlin/   # Your Kotlin UI sources
    ├── src/main/layout/   # XML and .dota.xml.kts layouts
    └── src/main/styles/   # CSS, SASS, and SCSS styles
  • Root Project: Contains shared build logic and orchestrates the subprojects.
  • :lua module: Specifically for server-side code. This is where you use dota-lua-types. It is compiled to Lua files that go into your game's vscripts folder.
  • :panorama module: Specifically for client-side UI. This is where you use dota-panorama-types and dota-panorama-layout-dsl. It is compiled to Javascript and XML files for your game's panorama folder. The Panorama module is split into:
    • content/: Static assets.
    • src/main/kotlin/: Kotlin UI logic.
    • src/main/layout/: UI layout files (.xml and .dota.xml.kts).
    • src/main/styles/: Stylesheets (.css, .sass, .scss).

This structure allows you to share common data models or utility classes between both modules if they are placed in a shared module.


dota-lua-types

Package structure

Kotlin package Contents
com.isycat.dota.lua Interfaces for all VScript game entities (CBaseEntity, BaseNPC, BaseNPCHero, …)
com.isycat.dota.lua Enums for all Dota 2 flags and constants
com.isycat.dota.lua Strongly-typed game events (EventKey<T> + data classes)
com.isycat.dota.lua Value classes for opaque IDs (EntityIndex, PlayerID, …)

Accessing global singletons

Common singletons are exposed as top-level val properties:

import com.isycat.dota.lua.*

// Game rules access
val gameMode = GameRules.getGameMode()

// Particle manager
val particle = ParticleManager.createParticle("particles/units/heroes/hero_axe/axe_culling_blade_hit.vpcf", ParticleAttachment.ABSORIGIN_FOLLOW, null)

// Custom events
CustomGameEventManager.registerListener("my_event") { _, eventData ->
    // handle event
}

Listening to game events

import com.isycat.dota.lua.*

onGameEvent(DOTA_GAME_STATE_CHANGE) { event ->
    if (event.newState == DOTA_GameState.GAME_STATE_GAME_IN_PROGRESS) {
        // game started
    }
}

Working with entities

import com.isycat.dota.lua.*

val hero: BaseNPCHero = /* obtained from game */
val health = hero.health          // val Int  — native: GetHealth
hero.health = 500                  // var — native: SetHealth
val isAlive = hero.isAlive         // val Boolean — native: IsAlive

Enums

All Dota 2 flag and constant enums are available as Kotlin enum class with integer values and @NativeName annotations:

import com.isycat.dota.lua.*

val damage = DamageTypes.MAGICAL    // native: DAMAGE_TYPE_MAGICAL
val unitState = UnitState.STUNNED   // native: UNIT_STATE_STUNNED

dota-panorama-types

Package structure

Kotlin package Contents
com.isycat.dota.panorama Panorama panel interfaces (Panel, Button, Label, …)
com.isycat.dota.panorama Panorama API interfaces (GameEvents, Players, …)
com.isycat.dota.panorama Panorama enums
com.isycat.dota.panorama Panorama events and engine events
com.isycat.dota.panorama CSS property constants (CssProperties)

Working with panels

import com.isycat.dota.panorama.*

fun setupPanel(panel: Panel) {
    panel.setPanelEvent("onactivate") {
        // handle click
    }
    panel.addClass("highlighted")
    panel.visible = true
}

CSS properties

Use CssProperties constants to avoid typos in CSS property names:

import com.isycat.dota.panorama.*

panel.style.setProperty(CssProperties.BACKGROUND_COLOR, "#FF000080")
panel.style.setProperty(CssProperties.OPACITY, "0.5")

Listening to Panorama events

import com.isycat.dota.panorama.*

GameEvents.subscribe("DOTAHeroPickCompleted") { event ->
    // handle hero pick completed
}

NativeName annotations

Every property and function carries a @NativeName annotation that maps the idiomatic Kotlin name back to the native Dota 2 engine name. This is used by the runtime (e.g. a Kotlin-to-Lua transpiler) to call the correct engine function.

@get:NativeName("GetHealth")
@set:NativeName("SetHealth")
var health: Int

When you access entity.health the transpiler calls entity:GetHealth() / entity:SetHealth(value) in Lua.


Annotations module

Both packages depend on dota-annotations which provides the @NativeName annotation. It is transitively included, so you do not need to add it explicitly.

If you need to reference the annotation type directly:

import io.github.dota.annotations.NativeName