> For the complete documentation index, see [llms.txt](https://docs.nursultan.fun/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.nursultan.fun/settings/entries-with-their-own-logic.md).

# Entries with their own logic

The options of a `selectable` or a `combo` are not strings but **entry** objects. Strings work too, but an entry lets you attach behaviour to an option instead of comparing text.

## Strings — when there is no logic

If the options just mark a mode, strings are fine:

```kotlin
val mode by selectable("Mode", "Fast", "Smooth", selected = "Fast")

if (mode == "Fast") { ... }
```

The entries are built for you.

## Entries — when there is logic

`entry("Name")` creates an option you can hang handlers on:

```kotlin
val fast = entry("Fast", true) {
    onSelect { chat.print("fast mode") }
    onDeselect { chat.print("not fast any more") }
    onTick { control.jump() }
}

val smooth = entry("Smooth") {
    onTick {
        if (player.onGround()) {
            control.jump()
        }
    }
}

val mode = selectable("Mode", fast, smooth)
```

| Handler      | When it fires                                                                    |
| ------------ | -------------------------------------------------------------------------------- |
| `onSelect`   | the option was picked                                                            |
| `onDeselect` | another one was picked (for a `combo`, it was unchecked)                         |
| `onTick`     | every game tick, but **only while this option is selected and the script is on** |

The second argument of `entry("Fast", true)` is whether it starts selected. A `selectable` needs exactly one selected option; mark none and the first one wins. A `combo` takes any number, including none.

This way a mode with its own behaviour lives in one place, and your event handler does not turn into a ladder of `if`s.

## Working with the selection

```kotlin
mode.value()              // the selected Entry
mode.value() == fast      // identity, no strings
mode.selected(smooth)     // same thing, shorter
mode.select(fast)         // pick it
mode.entries()            // every option
mode.options()            // their names as strings
```

A combo is the same, only about a set:

```kotlin
val items = combo("Items", trident, crossbow)

items.value()             // list of selected entries
items.has(trident)
items.set(crossbow, false)
items.value(listOf(trident))
```

## Finding an entry by name

When you do not have the object — say you are driving a [client module](/more/client-modules.md) — you can look one up:

```kotlin
val targets = client.modules().get("AttackAura").combo("targets")

targets.set(targets.entry("entry.players"), true)
targets.set("players", true)          // same thing, shorter
```

Lookup accepts the full key (`entry.players`), the name, or the last segment; case, dots, dashes and underscores do not matter.

## What you cannot do

You cannot attach `onSelect`/`onTick` to an entry of a built-in client module — it is someone else's setting, and a script may only read and switch it.
