# Configuration Painting-Paper uses `config.yml`. Painting-Velocity uses `plugins/painting/resourcepack.yml`. Both share the same shape with a few platform-specific keys called out below. Apply changes by running `/painting reload`. --- ## General Settings | Field | Type | Default | Description | |---|---|---|---| | `enabled` | Boolean | `true` | Master switch. When `false`, Painting does nothing. | | `mode` *(Paper only)* | String | `AUTO` | `AUTO`, `STANDALONE`, or `PROXIED`. `AUTO` flips to `PROXIED` after the first plugin-message receipt from Velocity. | | `server_name` *(Paper only)* | String | `default` | Used to match the `servers:` regex when running standalone. | | `append-hash-to-url` | Boolean | `false` | Append `?hash=<sha1>` to the pack URL. Useful for cache-busting CDN responses. | | `prompt-timeout` | Integer | `15` *(Velocity)* / `15` *(Paper)* | Seconds to wait for the player to accept the prompt before kicking. Only applies to required packs. `0` disables the timeout. | | `kickdelay` | Integer | `0` | Seconds to wait before kicking after `DECLINED` or `FAILED_DOWNLOAD`. `0` kicks immediately. | | `failed-retries` | Integer | `2` | How many times to retry a `FAILED_DOWNLOAD` before kicking. Each retry re-issues the offer with `?_painting_retry=N` so a stale CDN edge doesn't kick a player while others on the same server are unaffected. `0` disables retry. | | `hash-refresh-throttle` *(Velocity only)* | Integer | `60` | Seconds between hash freshness checks. Player joins and a periodic timer share the same throttled refresh. `0` disables auto-refresh. | --- ## Messages | Field | Type | Description | |---|---|---| | `messages.prompt` | String | Prompt text shown above the resource pack offer. MiniMessage. | | `messages.declined` | String | Kick message when a required pack is declined. MiniMessage. | | `messages.failed` | String | Kick message when a required pack fails to download (after retries). MiniMessage. | ```yaml messages: prompt: "<green>Welcome! Please install the resourcepack." declined: "<red>You need to accept the resourcepack in order to play." failed: "<red>Failed to download the resourcepack. Please try reconnecting." ``` --- ## Pack Definitions Each pack name maps to a list of variants. The first variant whose `protocols` or `versions` matches the player is sent. | Field | Type | Description | |---|---|---| | `resourcepacks.<name>[].url` | String | Public URL of the `.zip` resource pack. | | `resourcepacks.<name>[].hash` | String | SHA-1 hash of the pack. Populated by `/painting generatehashes` or auto-refresh. | | `resourcepacks.<name>[].protocols` | Integer List | Raw protocol numbers this variant matches. Optional. | | `resourcepacks.<name>[].versions` | String List | Version expressions this variant matches. Optional if `protocols` is set. | A variant must define at least one of `protocols` or `versions`, otherwise it is skipped. ```yaml resourcepacks: base: - url: "https://cdn.example.com/packs/base-1.21.zip" hash: "" versions: ["1.21+"] legacy: - url: "https://cdn.example.com/packs/legacy-old.zip" hash: "" protocols: [763, 764] - url: "https://cdn.example.com/packs/legacy-new.zip" hash: "" versions: [">=1.21,<26.1"] ``` ### Version Expressions | Form | Meaning | |---|---| | `1.21` | Exact match. | | `1.21+` | Greater than or equal to 1.21. | | `>=1.21.4` | Greater than or equal. | | `>1.21.4` | Strictly greater than. | | `<=1.21.7` | Less than or equal. | | `<26.1` | Strictly less than. | | `>=1.21.4,<26.1` | AND — comma chains conditions. | | `["1.21+", "26.1+"]` | OR — list entries are evaluated as alternatives. | The version table is loaded from the bundled `version_protocols.yml` and can be extended in config: ```yaml version_protocols: "26.1.3": 776 ``` --- ## Server Entries Server entries match against the current server name (Paper: `server_name` config; Velocity: registered server name). Packs from every matching entry are sent in declaration order. `required: true` kicks players who decline or fail. | Field | Type | Description | |---|---|---| | `servers.<name>.regex` | String | Regex matched against the server name. | | `servers.<name>.required` | Boolean | When `true`, declining or failing kicks the player. | | `servers.<name>.packs` | String List | Pack names to send, in order. Top of the list is the bottom layer; later entries override earlier ones. | ```yaml servers: global: regex: ".*" required: false packs: - base survival: regex: "^survival-\\d+quot; required: true packs: - base - survival-overlay ``` Server entries that reference an unknown pack name log a warning at reload. --- ## Redis (CI/CD Push) Painting can subscribe to a Redis Pub/Sub channel and react to JSON envelopes. Useful for re-deploying a pack from CI without restarting the server. | Field | Type | Default | Description | |---|---|---|---| | `redis.enabled` | Boolean | `false` | Subscribe to the channel. | | `redis.host` | String | `127.0.0.1` | Redis host. | | `redis.port` | Integer | `6379` | Redis port. | | `redis.password` | String | `""` | Optional AUTH password. | | `redis.channel` | String | `painting:redis` | Pub/Sub channel name. | In hybrid setups, Velocity owns Redis. Disable `redis.enabled` on Paper backends to avoid double handling. ### Envelope Format | Action | Payload | Effect | |---|---|---| | `reload` | `{"action":"reload"}` | Reload pack and server registries from disk. | | `update_pack` | `{"action":"update_pack","force_resend_online":true}` | Reload, then optionally resend to all online players. | | `resend` | `{"action":"resend","force_resend_online":true}` | Resend pack offers without reloading config. | --- ## Example Configuration (Paper) ```yaml enabled: true mode: AUTO append-hash-to-url: false prompt-timeout: 15 kickdelay: 0 failed-retries: 2 server_name: "default" redis: enabled: false host: "127.0.0.1" port: 6379 password: "" channel: "painting:redis" messages: prompt: "<green>Welcome! Please install the resourcepack." declined: "<red>You need to accept the resourcepack in order to play." failed: "<red>Failed to download the resourcepack. Please try reconnecting." resourcepacks: base: - url: "https://cdn.example.com/base.zip" hash: "" versions: ["1.21+"] servers: global: regex: ".*" required: false packs: - base ``` --- ## Example Configuration (Velocity) ```yaml enabled: true append-hash-to-url: false prompt-timeout: 15 kickdelay: 0 failed-retries: 2 hash-refresh-throttle: 60 redis: enabled: false host: "127.0.0.1" port: 6379 password: "" channel: "painting:redis" messages: prompt: "<green>Welcome! Please install the resourcepack." declined: "<red>You need to accept the resourcepack in order to play." failed: "<red>Failed to download the resourcepack. Please try reconnecting." resourcepacks: base: - url: "https://cdn.example.com/base.zip" hash: "" versions: ["1.21+"] servers: global: regex: ".*" required: false packs: - base ``` --- ## Related Pages - [[Painting/Server Owners/Overview]] — plugin features and modes - [[Painting/Server Owners/Commands]] — command reference - [[Painting/Developers/Overview]] — developer API documentation