# Ikar script plugin — example

A minimal script plugin: it attacks the nearest living mob, over and over.

Use it as the starting point for your own script — replace the body of `run` and
you are done.

## Requirements

- Any JDK to run Gradle with. The plugin itself is always compiled for **Java 21** —
  that is the runtime shipped with the script host, and a jar built for anything
  newer will not load. Gradle downloads JDK 21 on its own if you do not have it.
- Nothing else: the Gradle wrapper (`gradlew`) downloads Gradle itself on the
  first run.

## Layout

```
build.gradle.kts     build script
settings.gradle.kts  Kotlin plugin version and repositories
libs/                the API jars the plugin compiles against
src/main/kotlin/     the script itself — MyFarm.kt
src/main/resources/META-INF/services/com.ikar.script.api.IkaScript
                     the plugin registration: one line, the class name
```

## Build

```
gradlew jar          # Windows
./gradlew jar        # Linux / macOS
```

The result is `build/libs/ikar-script-example.jar`. To rename it, change
`rootProject.name` in `settings.gradle.kts`.

## Install

Copy the jar into the `data/scripts` folder next to the application, then start
the application — the plugin appears in the scripts list.

## Writing your own script

1. Rename the class and the file, and put your own values in `ScriptMeta`:

   ```kotlin
   override val meta = ScriptMeta(id = "my-script", name = "My Script")
   ```

2. Put the new fully qualified class name into
   `src/main/resources/META-INF/services/com.ikar.script.api.IkaScript` — one
   line, no package wildcards. A plugin missing from that file is not loaded.

3. Write your logic in `run(bot)`. `bot` is the entire API: properties such as
   `bot.user` and `bot.npcs` read the world, methods such as `bot.attack(...)`
   are commands, `bot.log(...)` writes to the script log.

4. `onStop()` is optional — use it if something has to be cleaned up when the
   script is stopped.

Two things worth knowing before you start:

- **Entities are a snapshot.** `bot.npcs` and friends return the current picture
  of the world, but the objects you get never update themselves. Re-read them on
  every iteration instead of holding a reference across a `delay`.
- **Compare entities by `oid`**, not with `==` — the objects are rebuilt on every
  world update.

## Dependencies

Everything the host provides at runtime is declared `compileOnly`, so the plugin
jar contains only your own classes. Do not switch these to `implementation`: the
API, kotlin-stdlib and coroutines already live in the host, and bundling them
would load the same classes twice in two different class loaders.

`ScriptMeta.apiVersion` is filled in automatically from the API you compile
against. If it does not match the version the application expects, the plugin is
skipped at load time — rebuild it against the jars shipped with your version of
the application.

## Documentation

The full API reference — every command, every model field, every event — ships
with the application documentation.
