# Asking questions

These answer yes or no. They are what [conditions](/docs/conditions) are made of.

## Inventory

```js
$.hasItem('rope')       // do they have any?
$.hasItem('rope', 3)    // do they have at least three?
```

The second argument is a minimum, not an exact count.

## Presence and life

```js
$.alive('Ironjaw')                  // is this named NPC still alive?
$.at('Ironjaw', 'the mill')         // is this NPC in this location?
```

Both take names as they appear in your game. A name that does not exist answers `false`
rather than erroring — so a typo reads as "no", not as a broken rule.

## Abilities

```js
$.hasAbility('secondwind')
```

## Asking about other plugins

This is the pair that makes plugins cooperate without depending on each other:

```js
$.hasPlugin('hunger')                  // is that plugin even installed?
$.hasField('infection', 'target')      // does this entity have that field?
```

The field bag is flat, so one plugin *can* read another's field directly. These let it ask
first rather than assuming. Without them, a rule reading `$.field('satiety')` in a game
with no hunger plugin gets `null` and quietly behaves as though everyone is starving — or
never starving, depending on which way your comparison points.

### Worked example: a plugin that plays nicely

A disease that hits harder when the victim is also hungry, in a game that might not have
hunger installed at all:

```js
$.hasPlugin('hunger') && $.field('satiety') < 20 ? 2 : 1
```

## Comparing with a chosen operator

```js
$.compare(actual, op, target)
```

Where the operator itself comes from data — a quest that stores `'>='` alongside its
threshold — rather than being fixed when you write the rule.

## Time windows

```js
$.timeBetween('20:00', '04:00')
```

True when the game clock currently reads inside that window. Wraps midnight correctly.

### Worked example: something that only happens at night

```js
$.timeBetween('20:00', '04:00') && $.at('the lighthouse', $.player.location)
```

## Every question

<!-- api:generated:questions -->
| Call | Answers |
|---|---|
| `$.hasItem('rope', 2)` | Whether the subject carries at least that many. |
| `$.carried('weight')` | The total of a field across everything carried. |
| `$.stat('might')` | A stat on the subject, read by ROLE — never by the display name, which an author can rename. |
| `$.field('satiety', 'player')` | One declared field, on the subject or whoever `who` names. |
| `$.compare(actual, op, target)` | Compare two values with an operator chosen at runtime. |
| `$.alive('Ironjaw')` | Whether a named entity is alive. |
| `$.at('Ironjaw', 'the mill')` | Whether a named entity is at a location. |
| `$.timeBetween(from, to)` | Whether the clock now reads between two times. |
| `$.hasAbility('secondwind')` | Whether the subject has an ability. |
| `$.hasPlugin('hunger')` | Whether another plugin is installed — ask before reading its fields. |
| `$.hasField('infection', 'target')` | Whether a field exists, so a missing one is not read as a real zero. |
| `$.dial('foodDrainPerHour')` | One of your own plugin's dials. Never freeze a dial's value as a literal. |
<!-- /api:generated:questions -->

## Next

[Conditions](/docs/conditions) — where these get used.
