️ Custom Images+ Place real images in your Minecraft world — from Discord, Imgur, or any direct URL Enhanced fork of Custom Images by Andavin — improved with AI-assisted development (Claude Code) ⚡ All improvements developed, tested and deployed in ~1 hour using AI ⚡ ✦━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━✦
⚡ Why Custom Images+?
The original
Custom Images plugin is great, but it hasn't kept up with modern needs. Discord changed their CDN in 2024 and now serves images as WebP —
breaking every image plugin that tries to load Discord URLs. On top of that, the original has no multilanguage support, no region protection, no per-rank limits, and no reload command.
Custom Images+ fixes all of that.
✦━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━✦
The Killer Feature: Discord URL Support
Your players already use Discord. Now they can use it as their image host:
Upload any image to any Discord channel or chat
Right-click the image → "Copy image link"
Paste the URL in /images create <URL>
Click on a wall → done. The image is placed.
No extra steps. No external hosting. No format errors.
The plugin automatically detects Discord URLs, converts
media.discordapp.net to
cdn.discordapp.com, strips the WebP conversion parameters, and keeps the authentication tokens. Your players don't need to know any of this — they just paste and it works.
Also supports direct URLs from Imgur, websites, or any link ending in .png / .jpg
Local files too! You can also place image files (.png, .jpg) directly in the
plugins/Images/ folder. Then in-game, type
/images create and press
TAB — the plugin auto-suggests all available images from the folder. No URL needed.
✦━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━✦
v1.4 — Visual management GUI (/image gui)
Chest-based management menu, one command away
Tired of walking to every image to click-delete? Tired of grepping
images.log to figure out who placed what? Run
/image gui (alias
/imagen menu) and get a unified visual inventory for admins AND users:
"Your Images" — everyone lands on their own personal scope first: stats, a browser filtered to images they placed, and a one-click delete for each of their own entries
Create + Delete buttons for users — regular players never have to learn chat commands. The top row shows a green Create image button (prompts for a URL + scale in chat, then click a wall) and a red Delete image button (puts you in right-click-to-delete mode, sneak to cancel). Works identically on Java, Bedrock PC, and Bedrock mobile
Admin shortcuts — holders of images.gui.admin get an extra bottom row with Browse-all, Filter (world/date/status), Hidden, Banned, Orphan scan, Leaderboard, Export CSV. Regular players see decorative crystals instead
Smart titles — "Your Images" / "My Images" for personal scope, "Manage" for admin server-wide, so staff always know what they're acting on
Brand-new moderation primitives
Hide / Unhide — un-render an image for everyone without destroying its data. Reversible. Useful when you want to temporarily take down content without losing the placement
Ban / Unban — hard moderation flag with admin + reason + timestamp. Only staff with images.gui.ban can lift. Survives restarts
Move (true relocate) — keep the same database id, creator, placedAt and history. Click Move → confirm → right-click the new block. No orphan audit trail from delete+recreate
Bulk actions — toggle multi-select, pick N images, then Bulk Delete / Ban / Hide with one confirmation
Context-aware buttons — ban/hide/move never appear on your own images. Admins see the full toolbox only on others' content
Discovery & housekeeping
Image finder — type a keyword in chat to filter by name or URL. Admin search covers the server; users search their own
Orphan scan — finds images whose item-frames were destroyed but metadata is still in the DB. Bulk-delete the leftovers with one click
Owner leaderboard — top players by image count and storage used
CSV export — dumps the full registry to plugins/ImagesPlus/exports/images-<timestamp>.csv (17 columns)
️ Personalization & audit
Image alias — set a personal label on your own images ("Living Room", "Shop Banner") so the GUI is readable. The original filename stays untouched in the lore
Safe teleport — the TP button stands you 2–3 blocks in front, looking at the image, on safe ground. No falling into lava
Confirmation dialog on every destructive action — short title, full prompt wrapped on a paper item inside the menu
New audit tags in images.log: HIDE, UNHIDE, BAN, UNBAN, MOVE, BULK_DELETE, GUI_TP. GUI-driven removals add via=GUI / via=BULK. A "History" button in the detail menu surfaces the last 5 log entries for that image
Fully translatable Every GUI string (titles, buttons, lores, click hints, messages, stats) is a lang key. Drop a
pt.yml /
fr.yml in
plugins/ImagesPlus/lang/ and reload. Unified color palette across all buttons: green = positive, red = destructive, gold = highlight, aqua = tool, yellow = navigation.
Plugin rename The plugin now shows as
ImagesPlus in
/pl and logs — no more confusion with the original Custom Images. On first boot the data folder
plugins/Images/ is
automatically migrated to
plugins/ImagesPlus/. No manual step, no data loss. All existing images, config and lang files come along.
✦━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━✦
v1.2 — Audit log & click-to-inspect
Detailed audit log (plugins/Images/images.log)
Every image placement and removal is written to a plain-text, grep-friendly log file. Perfect for anti-grief investigations and activity audits.
Use tail -f to watch live, grep "player=Xxx" to audit a specific user
Covers both placements and removals, with confidence level (EXACT vs PROBABLE for area deletes)
Click-to-inspect (/imagen quien / /images who)
Run the command, then click any image in the world to see a detailed info panel:
Code (Text):
--- Image Info ---
Name: foo.png
Placed by: Steve
UUID: 1b4bb76f-1bd9-45f1-9d08-f017a1c14b08
Date: 2026-04-14 16:25:03
World: world
Coordinates: 100, 64, 200
Direction: NORTH
Source: URL
URL: https://cdn.discordapp.com/...
Scale: 1.00x
----------------------
DB-backed storage — every v1.2+ image stores its own metadata (placedAt, source, URL, scale) in the plugin database
Instant lookup — no log parsing needed for new images
Log fallback — older images without DB metadata are resolved by parsing images.log
Perfect for staff — answer "who put that up?" in one click
Other v1.2 fixes
Lang auto-merge — new message keys in future updates are merged into your existing lang/*.yml files automatically, so you never get <placeholder.key> on screen after an update
"Just works" defaults — the config now ships with place-mode: OP and safe default permissions, so the plugin works immediately after drop-in without LP setup
Separated images.command.placed permission — was sharing images.command.list in v1.1, now cleanly separated (staff can have audit tools without granting list)
✦━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━✦
Multilanguage — Not Just Bilingual
The plugin ships with
English and Spanish fully translated (47 configurable message keys each). But you can add
any language:
Copy lang/en.yml to lang/pt.yml (or any language code)
Translate the values
Run /images reload — loaded instantly, no restart needed
Smart language detection: The plugin detects the language from the command the player uses:
/imagen crear → Spanish messages and tab suggestions
/images create → English messages and tab suggestions
Mix freely: /images crear works (English messages), /imagen create works (Spanish messages)
✦━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━✦
Commands
Spanish
Code (Text):
/imagen crear <name | URL> [scale] — Create and place an image
/imagen eliminar — Delete by right-clicking
/imagen eliminar cerca <range> — Delete all images within range
/imagen lista — List available images
/imagen colocadas [radio] — Show placed images with coords (click to TP)
/imagen quien — Click an image to see who placed it (v1.2)
/imagen menu — Open the visual management menu (v1.4)
/imagen importar — Import legacy data (5 min cooldown)
/imagen transferir <MySQL|SQLite|File> — Transfer database (auto-shutdown)
/imagen recargar — Reload config & languages
English
Code (Text):
/images create <name | URL> [scale] — Create and place an image
/images delete — Delete by right-clicking
/images delete near <range> — Delete all images within range
/images list — List available images
/images placed [radius] — Show placed images with coords (click to TP)
/images who — Click an image to see who placed it (v1.2)
/images gui — Open the visual management menu (v1.4)
/images import — Import legacy data (5 min cooldown)
/images transfer <MySQL|SQLite|File> — Transfer database (auto-shutdown)
/images reload — Reload config & languages
Each subcommand also has aliases:
crear/new/add/load,
eliminar/del/remove/borrar/quitar,
lista/options/opciones,
recargar/rl, etc.
✦━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━✦
Scale
Control the image size with any number after the URL:
Code (Text):
/images create <URL> 50
10-20 — Fits in 1 block (icons, small logos, details)
50 — Half size
100 — Original size (default if omitted)
150 — 50% larger
200 — Double size
Use any number you want: 25, 70, 80, 120... experiment until it looks right. Don't like it? Delete and recreate with a different scale.
Each Minecraft block = 128x128 pixels. A 1280x720 image at scale 100 occupies ~10x6 blocks.
✦━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━✦
️ Supported Image Formats
PNG — Recommended. Supports full transparency (transparent areas are invisible on Java Edition)
JPG/JPEG — Great for photos, no transparency
BMP — Uncompressed, large files
GIF — First frame only (not animated)
Discord URLs — Auto-converted from WebP. Just paste the link
Transparency: PNG images with transparent backgrounds are supported. Transparent areas show as the default map color (light beige). Combine with
invisible-frames: true (default on 1.16+) for best results.
Placement: Images must be placed on a
solid block (wall, floor, or ceiling). Horizontal placement (floor/ceiling) supported on 1.13+.
Protocols:http://,
https://,
ftp://,
ftps://
Security: The plugin automatically rejects local, loopback, and internal network URLs to prevent SSRF attacks.
✦━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━✦
CLICK HERE TO SEE ALL SCREENSHOTS / HAZ CLIC PARA VER CAPTURAS
--------
---------
✦━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━✦
Permissions
Code (Text):
images.command.manage — Access the /image command [true]
images.command.list — List available image files [true]
images.command.create — Run /image create (placement gated by place-mode) [true]
images.command.create.url — Allow /image create with a URL [true]
images.command.delete — Run /image delete [true]
images.command.delete.near — Area-delete images within a range [op]
images.command.placed — Show placed images with coordinates (v1.2) [op]
images.command.who — Click to inspect any image (v1.2) [op]
images.command.import — Import legacy data [op]
images.command.transfer — Transfer database [op]
images.command.reload — Reload configuration [op]
images.place — Place images (when place-mode is PERMISSION) [op]
images.restricted.bypass — Bypass creator-restricted protection [op]
images.region.bypass — Place/delete in any region [op]
# v1.4 — Visual management GUI
images.command.gui — Open the /image gui menu [true]
images.gui.admin — Admin rows + server-wide scope [op]
images.gui.teleport — Teleport to any image [op]
images.gui.move — Move an image to a new block [op]
images.gui.hide — Hide / unhide [op]
images.gui.ban — Ban / unban with reason [op]
images.gui.delete.any — Delete any image [op]
images.gui.delete.own — Delete your own images [true]
images.gui.delete.distance — Delete own from any distance [true]
images.gui.bulk — Bulk-select mode [op]
images.gui.search — Text search [op]
images.gui.export — CSV export [op]
images.gui.leaderboard — Owner leaderboard [op]
images.gui.orphan-scan — Orphan detection [op]
Why the true defaults? So the plugin
just works after drop-in. Anyone can run the commands, but actual placement is gated by
place-mode in config.yml (default
OP — only the server owner actually places on a fresh install). Non-ops get a clean "can't place here" message instead of "unknown command", so they don't think the plugin is broken.
Want to restrict further? Override with LuckPerms:
Code (Text):
lp group default permission set images.command.create false
lp group vip permission set images.command.create true
Staff groups (audit tools + destructive commands):
Code (Text):
lp group <staff> permission set images.command.delete.near true
lp group <staff> permission set images.command.placed true
lp group <staff> permission set images.command.who true
lp group <staff> permission set images.command.reload true
✦━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━✦
Permission Modes (place-mode)
Control who can create images beyond basic permissions:
Code (Text):
permissions:
place-mode: GROUP
allowed-groups:
- vip
- premium
- builder
- moderator
- admin
ALL — Anyone with the create permission
OP — Server operators only
PERMISSION — Only players with images.place
GROUP — Only players in allowed-groups (requires Vault + a permissions plugin like LuckPerms)
✦━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━✦
Per-Group Image Limits
Set different limits for each rank. The player gets the
highest limit from all their groups. OP is always unlimited.
Uses
group.<name> permissions from LuckPerms for automatic group detection.
✦━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━✦
️ WorldGuard & ProtectionStones Integration
Control
where players can place images:
Code (Text):
permissions:
region-restricted: true
region-bypass-groups:
- moderator
- admin
No region (wilderness) → ✅ Allowed
Own ProtectionStones protection → ✅ Allowed
Member of someone's region → ✅ Allowed
Someone else's region, not a member → ❌ Blocked
Staff groups (in region-bypass-groups) → ✅ Always allowed
OP or images.region.bypass → ✅ Always allowed
The
__global__ WorldGuard region is automatically ignored. If WorldGuard isn't installed or encounters an error, the plugin fails-open (allows the action). Uses reflection — no compile-time dependency on WorldGuard.
✦━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━✦
Creator Protection
Code (Text):
permissions:
creator-restricted: false
When
true, only the player who created an image can delete it. Other players cannot delete images they didn't create, even if they have the delete permission. Players with
images.restricted.bypass can delete any image (useful for staff cleaning up inappropriate content).
✦━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━✦
Installation
Drop the JAR in your plugins/ folder
Start the server. Done.
The plugin auto-generates everything on first run:
config.yml — Full configuration with comments
lang/en.yml — English (200+ translatable keys including full GUI)
lang/es.yml — Spanish (200+ translatable keys including full GUI)
images.db — SQLite database
WIKI.md — Complete 1000+ line documentation
Data folder: the plugin installs itself to
plugins/ImagesPlus/. If you were on v1.3 or earlier (which used
plugins/Images/) the folder is renamed automatically on first boot — zero manual steps, zero data loss.
Built-in Documentation This plugin includes a complete
780-line WIKI inside the JAR. On first run, it automatically extracts to
plugins/Images/WIKI.md. No need to visit this page again — everything is in your server. Open it with any text editor, or feed it to an AI assistant to configure the plugin for you in seconds.
⬆️ Coming from the original Custom Images? Just replace the old JAR with this one. That's it. Your
existing images, database, and config are fully compatible — nothing breaks, nothing is lost. The plugin reads the same SQLite/MySQL database and the same image files. On first load it will auto-add the new config keys without touching your existing settings. All your placed images will appear exactly as before, plus you now have all the new features.
Upgrading between versions of Custom Images+? Same thing — replace the JAR. New config keys are auto-added without losing your existing settings.
Optional dependencies:
Vault + permissions plugin — Required for place-mode: GROUP
WorldGuard — Required for region-restricted: true
ProtocolLib — Improves stability on versions below 1.21. On 1.21+ the plugin deliberately disables ProtocolLib and uses its own packet implementation for better reliability
Database options: SQLite (default), MySQL, or flat file. Transfer between them with
/images transfer.
✦━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━✦
⚙️ Full Configuration
Code (Text):
# Language for console messages and fallback.
# Players receive messages in the language of the command they use:
# /imagen, /imagenes → Spanish (es)
# /images, /image, /img → English (en)
# Options included: en, es. Create more in plugins/Images/lang/
language: en
# Permissions
permissions:
place-mode: GROUP # ALL, OP, PERMISSION, GROUP
allowed-groups:
- vip
- premium
- builder
- moderator
- admin
max-images-per-player: -1
max-images-per-group:
vip: 10
premium: 25
builder: 20
moderator: -1
admin: -1
creator-restricted: false
region-restricted: true
region-bypass-groups:
- moderator
- admin
✦━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━✦
Troubleshooting
Image not visible after placing Images load asynchronously. Walk away (>128 blocks) and come back. After a server restart, images load gradually.
"Invalid or unreadable image file"
The URL is not a direct image link
The format is not supported (WebP from non-Discord sources)
Discord URL tokens expired
Solution: Download the image, upload to Discord, copy image link.
Discord URLs not working Make sure you use "Copy image link" (not "Copy message link"). The plugin auto-converts Discord URLs, but the link must point to the image itself.
Can't place in my ProtectionStones region
Verify your rank is in allowed-groups
Verify you are owner or member of the protection at that location
If staff, verify your group is in region-bypass-groups
Performance Tested with 130+ active images (~41 MB database) with no TPS impact. Each image section is only sent to players within
show-distance (default 64 blocks). Very large images (>2000px at high scale) may cause momentary lag when creating.
✦━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━✦
What's New vs Original Custom Images
Discord URLs — Original: ❌ broken. This fork: ✅ auto-converts
Language — Original: English only, hardcoded. Fork: Multilang with editable YAML files
Commands — Original: English only. Fork: Bilingual ES/EN with smart detection
Tab completion — Original: English only. Fork: Adapts to command language
AI-assisted development:Claude Code by Anthropic (Opus 4.6)
License: MIT
This entire fork was developed with AI assistance in
approximately 1 hour — from source analysis to multilanguage system, WorldGuard integration, Discord URL support, per-group limits, full documentation (780-line WIKI), and production deployment with 130+ active images. All coded, tested, and shipped using
Claude Code by Anthropic, demonstrating that with the right AI tools you can significantly improve existing plugins in under an hour, not weeks.