# MPP - Action Button V1.7.1 - Documentation

## Overview

Click or collision button that sends chat text or posts a Script Event command.
Unified command model: the button has 1 to 4 commands. One command = single action (flash), multiple commands = cycling sequence.
Includes optional interaction sound, visual tint and emissive feedback, remote control via Script Events, a private cooldown notice and access control.

This script is **standalone** - it does not require any other MPP script to function.
When combined with other MPP scripts (Light Switch, Commands Help On Chat, TransformByClickOrChat, etc.), it acts as a universal trigger.

In the Build panel the settings are grouped by category: `Activation/`, `Access/`, `Command/`, `Remote/`, `Sound/`, `Visual/` and `Debug/`.

**New in V1.7.1:** the settings are grouped by category in the Build panel, and the access control uses the same scheme as the other MPP scripts: `Access/Permission Mode (1-3)` with a `Whitelist` and a `Blacklist`. **The three access settings of V1.7.0 are not carried over**: read "Updating from V1.7.0" before you update buttons already placed in a scene.

---

## Changelog

### V1.7.1 (from V1.7.0) - Settings by category and unified access

| Change | Description |
|---|---|
| **Permission Mode (1-3)** | Replaces `Owner Only`, `Access List` and `List Is Blacklist`: 1 = Owner only, 2 = Owner + Whitelist, 3 = Everyone except the Blacklist (default; empty list = everyone). Same scheme as MPP - Light Switch and the other MPP scripts. |
| **Whitelist and Blacklist** | Two separate lists of avatar handles or UUIDs, instead of one list whose meaning depended on a switch. |
| **Settings by category** | `Activation/`, `Access/`, `Command/`, `Remote/`, `Sound/`, `Visual/`, `Debug/`. |
| **Renamed labels** | `Collision Mode` is now `Activation/Use Collision`, `Visual` is `Visual/Visual Feedback`, `Emissive` is `Visual/Affect Emissive`, `Debug` is `Debug/Debug Logging`. Same settings, same values. |
| **Module name** | The script is listed as "MPP - Action Button" in the Build panel, without a version number in its name. |

**36 properties, as in V1.7.0.** Every setting keeps its value when the script is swapped, **except the three access settings**, replaced by new ones (see "Updating from V1.7.0").

### V1.7.0 (from V1.6) - Cooldown Notice and Access Control

| Change | Description |
|---|---|
| **Cooldown Notice** | An avatar who uses the button during its cooldown receives a private chat message: "Please wait 3 seconds before using this button again." Text is configurable (`{time}`, `{seconds}`). At most one message every 3 seconds per avatar. |
| **Access control** | Owner only, whitelist or blacklist of avatar handles or UUIDs; the owner is never blocked. (In V1.7.1 the three settings `Owner Only`, `Access List` and `List Is Blacklist` became `Permission Mode`, `Whitelist` and `Blacklist`.) |
| **Denied Text** | Private message for avatars who are not allowed. At most one every 5 seconds per avatar. Empty = silent. |
| **Hide From Denied** | Click mode only: denied avatars do not see the button as clickable. |
| **Anti double-click safety** | A silent 0.1 s safety per avatar always remains, even with `Cooldown Seconds` = 0 (double-click protection). |
| **More robust** | Lighter on busy scenes; an avatar who leaves during a click no longer causes a script error. |
| **Config warnings** | Initial Command above Command Count, a list the current mode does not use, list entries with spaces, unknown owner identity. |
| **Sound Volume 0** | Now means no sound (V1.6 still played it at -48 dB). |
| **Debug** | Logs the handle and UUID of every avatar who activates or is denied, to fill the lists easily. |

**29 -> 36 properties.** All V1.6 property names are unchanged, so existing values carry over when the script is swapped.

---

## How It Works

The button has **1 to 4 commands**. Each click sends the next command and advances.

### Command Count = 1 (Single Action)
- Every click sends Command 1 (always the same command).
- Visual: flashes `Command 1 Tint`, holds briefly, fades back to the initial material tint.
- Use case: a button that always does the same thing (toggle lights, show help, etc.)

### Command Count = 2-4 (Cycling Sequence)
- Each click advances: Command 1 -> Command 2 -> ... -> Command Count -> Command 1.
- Visual: applies the corresponding `Command N Tint` and stays.
- Use case: a button that cycles between states (speed on/off, light modes, etc.)

### Activation order
1. The avatar is validated (still in the scene).
2. **Access check** - denied avatars receive `Denied Text` (throttled) and nothing else happens.
3. **Cooldown check** - blocked avatars receive the cooldown notice (throttled) and nothing else happens.
4. Sound, visual feedback, then the command (chat text or Script Event).

---

## Activation Modes

### Click Mode (default)
- `Activation/Use Collision` = Off
- The button shows a hover text (`Activation/Hover Text`) and activates on click.

### Collision Mode
- `Activation/Use Collision` = On
- Activates when an avatar enters the trigger volume or makes character contact.
- Requires a RigidBodyComponent on the object.
- VR hand contacts are ignored (unchanged from V1.6).

---

## Cooldown

| Mode | Behavior |
|---|---|
| `Activation/Global Cooldown` = Off (default) | Each avatar has its own cooldown timer. |
| `Activation/Global Cooldown` = On | The button has a single cooldown timer for all avatars. |

- `Activation/Cooldown Seconds` = 0 disables the configured cooldown. A silent 0.1 s per-avatar safety remains (double-click protection).
- Maximum accepted value: 86400 s (24 h).

### Cooldown Notice

When an avatar tries to use the button during the cooldown, they receive a **private** chat message (only them, in their Nearby Chat).

| Placeholder | Replaced by | Example |
|---|---|---|
| `{time}` | Remaining time with its unit | `1 second`, `12 seconds`, `2 minutes 30 seconds`, `1 hour 5 minutes` |
| `{seconds}` | Remaining whole seconds | `150` |

- Default text: `Please wait {time} before using this button again.`
- The remaining time is rounded up (never "0 seconds").
- Anti-spam: at most one notice every 3 seconds per avatar.
- No notice when `Cooldown Seconds` is 0.1 or less (the safety floor stays silent).
- In global mode, avatars who never clicked also get the notice if the button is busy.
- Tip: with very short cooldowns (under 1 second), you may prefer `Activation/Cooldown Notice` = Off.

---

## Access Control

Who can use the button is set by one number and two lists, in the `Access/` group. This is the scheme shared by every MPP script:

| Access/Permission Mode | Who can use the button |
|---|---|
| **1** - Owner only | The scene owner only |
| **2** - Owner + Whitelist | The scene owner and the avatars of `Access/Whitelist` (empty list = owner only) |
| **3** - Everyone except Blacklist (default) | Everyone, minus the avatars of `Access/Blacklist` (empty list = everyone) |

- The **scene owner is always allowed**, in every mode, even if listed in the Blacklist.
- The owner is recognized by the avatar that owns the scene (with its handle as a fallback). Another persona of the owner counts as a different avatar.
- A list that the current mode does not use is ignored, with a warning in the script console: a Whitelist in mode 1 or 3, a Blacklist in mode 1 or 2.
- The access check applies to click and collision activation. Remote Control events (from other scripts) are not affected.

### List format (Whitelist and Blacklist)
- Avatar **handles** or avatar **UUIDs**, separated by commas, semicolons or new lines.
- Handles are not case sensitive; a leading `@` is ignored.
- Display names are not supported (not unique). Entries containing a space are ignored with a warning.
- Example: `@morgane, friend-handle; 3f2c1a9e-0000-4c1e-9a55-1234567890ab`
- Tip: turn `Debug/Debug Logging` On and click the button with the avatar to add: the script console shows its handle and UUID, ready to paste.

### Denied Text
- Private message sent to a denied avatar. Default: `You are not allowed to use this button.`
- At most one message every 5 seconds per avatar (useful in collision mode). Empty = silent.

### Hide From Denied
- Click mode only (ignored with a warning when `Use Collision` is On).
- Denied avatars do not see the button as clickable: no highlight, no hover text.
- Applied to avatars present when the script starts, and to each joining avatar about 2 seconds after arrival.
- This is a comfort feature: the access check on click always stays active.

---

## Commands

### Send as Command
- **Off** (default): the command value is sent as chat text.
- **On**: the command value is posted as a Script Event that other scripts can listen to.

The event payload contains the activating avatar's UUID (`IActionButtonEventData`).

### Private Text
Only used when `Command/Send as Command` = Off. If On, text is sent only to the activating avatar.

### Command Values
- `Command 1` through `Command 4`: the text or Script Event name to send.
- Example with `Send as Command` = On: `Command 1` = `mpp_lamp_toggle` will toggle all Light Switch instances.
- Example with `Send as Command` = Off: `Command 1` = `Hello!` will send "Hello!" to chat.

---

## Initial Command

Controls the button's starting state when the scene loads.

| Value | Count=1 | Count=2-4 |
|---|---|---|
| **0** (default) | Button at rest. First click sends Command 1. | Displays Command 1 tint. First click sends Command 1. |
| **1** | Flashes Command 1 tint at startup. | Displays Command 1 tint. First click sends Command 2. |
| **2** | Ignored (warning) | Displays Command 2 tint. First click sends next command. |
| **3-4** | Ignored (warning) | Same logic for commands 3-4. Above Command Count: ignored (warning). |

**Use case:** Your button controls AvatarSpeed which starts in "normal" mode (= Command 2). Set `Initial Command = 2` so the button shows Command 2 tint at startup and the first click sends Command 1 (speed boost).

---

## Remote Control

When `Remote/Remote Control` = On, the button listens for incoming Script Events from other scripts to control its state externally.

### Events Listened To

| Event Name | Effect |
|---|---|
| `<prefix>_reset` | Resets to command 1 (Count=1: flash+fade, Count>1: apply tint) |
| `<prefix>_set_1` | Jump to command 1 |
| `<prefix>_set_2` | Jump to command 2 (if Count >= 2) |
| `<prefix>_set_3` | Jump to command 3 (if Count >= 3) |
| `<prefix>_set_4` | Jump to command 4 (if Count = 4) |

- `<prefix>` = `Remote/Remote Prefix` (default: `mpp_actionbutton`)
- If `Remote/Remote Token` is set: `<prefix>_<token>_reset`, `<prefix>_<token>_set_1`, etc.

### Remote Token - Targeting specific buttons

Without a token, **all** Action Buttons sharing the same prefix react. The token differentiates instances.

| Button | Controls | Token | Listens to |
|---|---|---|---|
| Lobby Lights | Lobby lamps | `lobby` | `mpp_actionbutton_lobby_reset`, `_set_1`, `_set_2` |
| Stage Lights | Stage lamps | `stage` | `mpp_actionbutton_stage_reset`, `_set_1`, `_set_2` |
| Avatar Speed | Speed boost | `speed` | `mpp_actionbutton_speed_reset`, `_set_1`, `_set_2` |

### Practical Examples

**Master Reset button:** Resets all buttons to command 1.
- Create an Action Button with `Send as Command` = On, `Command 1` = `mpp_actionbutton_reset`
- Click it -> all buttons listening with that prefix reset.
- Tip: set `Access/Permission Mode` = 1 on this master button so visitors cannot reset the scene.

**Reset one button only:**
- `Command 1` = `mpp_actionbutton_lobby_reset`

**External script sync:** A timer script calls `PostScriptEvent("mpp_actionbutton_speed_set_2", ...)` to force the Speed button to display command 2 when a boost expires automatically.

**Remote flash for Count=1:** A script calls `PostScriptEvent("mpp_actionbutton_lobby_set_1", ...)` -> the button flashes Command 1 Tint and returns to normal, as if someone clicked it.

---

## Sound

- `Sound/Click Sound` = optional SoundResource played at the button's position on activation.
- `Sound/Sound Volume` = loudness from 0 to 200 percent (100 = original volume, 0 = no sound).
- No sound is played for denied avatars or during the cooldown.

---

## Visual Feedback

### Tint
- `Visual/Visual Feedback` = On enables material tint changes.
- `Visual/Tint Material Name` = filter to a specific material (empty = all tintable scriptable materials).

| Count | Behavior |
|---|---|
| 1 | Flash `Command 1 Tint`, hold 0.08s, fade back to initial tint over `Return Fade Seconds` (max 60 s). |
| 2-4 | Apply `Command N Tint` instantly, stays until next click. |

### Emissive
- `Visual/Affect Emissive` = On enables EmissiveIntensity changes alongside tint.
- Returns to the material's cached initial emissive value (for Count=1 fade and initial tints).

---

## Editor Properties Reference (36 total)

### Activation (6)
| Property | Type | Default | Description |
|---|---|---|---|
| Activation/Use Collision | bool | Off | Off = click, On = collision or trigger volume |
| Activation/Hover Text | string | "Use Button" | Click mode hover text |
| Activation/Cooldown Seconds | double | 0.75 | Cooldown duration (0 = disabled, 0.1 s safety remains) |
| Activation/Global Cooldown | bool | Off | Button-level vs per-avatar |
| Activation/Cooldown Notice | bool | On | Private "please wait" message during cooldown |
| Activation/Cooldown Notice Text | string | "Please wait {time} before using this button again." | Notice text, `{time}` / `{seconds}`; empty = no message |

### Access (5)
| Property | Type | Default | Description |
|---|---|---|---|
| Access/Permission Mode (1-3) | int (1-3) | 3 | 1 = Owner only, 2 = Owner + Whitelist, 3 = Everyone except Blacklist. The owner is always allowed |
| Access/Whitelist | string | "" | Handles or UUIDs allowed in mode 2, comma or semicolon separated |
| Access/Blacklist | string | "" | Handles or UUIDs blocked in mode 3, comma or semicolon separated |
| Access/Denied Text | string | "You are not allowed to use this button." | Private message for denied avatars (empty = silent) |
| Access/Hide From Denied | bool | Off | Click mode: denied avatars cannot see the button as clickable |

### Command (8)
| Property | Type | Default | Description |
|---|---|---|---|
| Command/Send as Command | bool | Off | Chat text vs Script Event |
| Command/Private Text | bool | Off | Send to activator only (text mode) |
| Command/Command Count | int (1-4) | 1 | Number of commands |
| Command/Initial Command | int (0-4) | 0 | Starting command at scene load |
| Command/Command 1 | string | "command1" | First command value |
| Command/Command 2 | string | "command2" | Second command value |
| Command/Command 3 | string | "command3" | Third command value |
| Command/Command 4 | string | "command4" | Fourth command value |

### Remote (3)
| Property | Type | Default | Description |
|---|---|---|---|
| Remote/Remote Control | bool | Off | Listen for external control events |
| Remote/Remote Prefix | string | "mpp_actionbutton" | Prefix for incoming events |
| Remote/Remote Token | string | "" | Token for targeting a specific button |

### Sound (2)
| Property | Type | Default | Description |
|---|---|---|---|
| Sound/Click Sound | SoundResource | (none) | Optional activation sound |
| Sound/Sound Volume | int | 100 | Loudness 0-200 percent (0 = no sound) |

### Visual (11)
| Property | Type | Default | Description |
|---|---|---|---|
| Visual/Visual Feedback | bool | Off | Enable visual tint changes |
| Visual/Tint Material Name | string | "" | Filter to a specific material |
| Visual/Return Fade Seconds | double | 0.75 | Fade back duration (Count=1 only) |
| Visual/Command 1 Tint | Color | (255,89,89,255) | Tint for command 1 |
| Visual/Command 2 Tint | Color | (89,255,89,255) | Tint for command 2 |
| Visual/Command 3 Tint | Color | (89,166,255,255) | Tint for command 3 |
| Visual/Command 4 Tint | Color | (255,217,89,255) | Tint for command 4 |
| Visual/Affect Emissive | bool | Off | Enable emissive changes |
| Visual/Command 1-4 Emissive | float | 1.0 | EmissiveIntensity per command |

### Debug (1)
| Property | Type | Default | Description |
|---|---|---|---|
| Debug/Debug Logging | bool | Off | Writes activations, access decisions (with the avatar handle and UUID), command state and materials to the script console |

---

## Updating from V1.7.0

**Before you update, take a screenshot of the Build panel of each button** whose access you had changed (Owner Only, Access List, List Is Blacklist): these three settings are replaced by new ones and their values are not carried over.

- **Everything else carries over**: the 33 other settings keep their internal names and their values. Only their labels move into categories (`Collision Mode` is now `Activation/Use Collision`, `Visual` is `Visual/Visual Feedback`, `Emissive` is `Visual/Affect Emissive`, `Debug` is `Debug/Debug Logging`).
- **Access**: after the update every button is in `Access/Permission Mode` 3 with empty lists, which means **everyone can use it**, whatever its V1.7.0 access was. Set the access again on the buttons that had one, using your screenshot:

| V1.7.0 settings | V1.7.1 settings |
|---|---|
| `Owner Only` Off, list empty (default) | `Permission Mode` 3, lists empty: nothing to do |
| `Owner Only` Off, `List Is Blacklist` On, list filled | `Permission Mode` 3, paste the list into `Blacklist` |
| `Owner Only` On, list empty | `Permission Mode` 1 |
| `Owner Only` On, `List Is Blacklist` Off, list filled | `Permission Mode` 2, paste the list into `Whitelist` |

- Update the owner-only buttons (master reset, admin panels) first, so they are not open to visitors in the meantime.
- Commands, Script Events, `IActionButtonEventData` and the Remote Control events are unchanged: the scripts that listen to your buttons keep working as they are.

## Updating from V1.6

- Every V1.6 property keeps its name and its value; the labels moved into categories in V1.7.1.
- Default behavior is identical (everyone can click), with one visible difference: **Cooldown Notice is On by default**. Turn it Off to get the exact V1.6 behavior.
- `Sound/Sound Volume` = 0 now mutes the click sound.
- The access control is new since V1.7: `Access/Permission Mode` 3 with empty lists = everyone, as in V1.6.

---

## Compatibility

`IActionButtonEventData` and `PostScriptEvent` are unchanged from V1.4.x. All consumer scripts (Light Switch, Commands Help On Chat, TransformByClickOrChat, StoreListingRouter, RandomObjectSpawner) remain fully compatible.

## Event Payload Interface

```csharp
public interface IActionButtonEventData
{
    string ActivatorAvatarUuid { get; }
}
```

---

## Related MPP Items

| Item | What it adds |
|---|---|
| **Light Switch Script** (V1.5.3) | Lamps and glowing materials switched by this button with `Send as Command` On and `mpp_lamp_all_toggle`, `mpp_lamp_<group>_on`, etc. Store: https://www.sansar.com/store/listings/7379d48c-2b6f-45f6-b6f1-205ce95aec1c/light-switch-script |
| **Commands Help On Chat Script** (V1.5.2) | A help button: `Command 1` = `show_commands_help` shows the scene commands in Nearby Chat, in public or in private to the avatar who clicked. Store: https://www.sansar.com/store/listings/fea2df6b-21ce-48eb-94fc-4b7a7aad2777/commands-help-on-chat-script |

---

*MPP - My Pretty Pixels. Action Button V1.7.1 (script `MPP - Action Button`). Store: https://www.sansar.com/store/listings/3e1a3546-6c79-4527-bc1e-78d02648d19e/action-button-script*
