SinglePlayerSleep - Sleep Plugin

A modern Minecraft plugin that lets a single player sleep, skip the night with stylish effects, lightweight performance, and full configurability — entirely AI-crafted.

9,74k

Quick challenge

How far can you run before the mobs catch you?

SinglePlayerSleep - Sleep Plugin

UPDATE V2.2.0 IS HERE!

> ### ⚠️ This project is still under development and may contain bugs. Use carefully and report any issues. > I DO NOT INTEND TO MAKE ANY MONEY FROM THIS PROJECT. Contact: [email protected] > > This plugin has no connection to the I DO NOT INTEND TO MAKE ANY MONEY FROM THIS PROJECT. plugin on SpigotMC. It is merely a coincidence in name. > > This plugin was created using AI and was developed solely to demonstrate that AI can write advanced code and build a functional system. You are welcome to fork and utilize it as you see fit.

🛌 SinglePlayerSleep Plugin

GitHub release

GitHub license

GitHub issues

Modrinth Downloads

Modrinth Version

Java Version

Minecraft Version

> ✨ A modern, lightweight Minecraft plugin to skip the night instantly in single-player worlds or with percentage-based voting — packed with rich features, visual effects, and fully configurable settings.

📥 Download from Modrinth

---

📜 About

SinglePlayerSleep is designed for Minecraft servers that aim to keep the immersive single-player feel, even in multiplayer mode, by allowing the night to be skipped when a single player sleeps or when a certain percentage of players vote to sleep.

Built with performance and flexibility in mind, it features configurable messages, particle & sound effects, automatic saving, AFK detection, PlaceholderAPI integration, sleep statistics, and automatic update checking.

Whether you run a small private SMP or a public server, SinglePlayerSleep seamlessly handles night skipping without requiring everyone online to sleep.

---

⚙️ Features

Core Features

- ✅ Skip the night when just Phantom timer reset player sleeps (classic mode) - ✅ Percentage-based sleep voting system - ✅ AFK player detection and exclusion from sleep count - ✅ Automatic GitHub update checker - ✅ Fully configurable delay before skipping night - ✅ Cooldown between sleep events to prevent spam - ✅ Automatic weather clearing on new day - ✅ Phantom timer reset (`%sps_*%` placeholders) - ✅ Phantom timer reset (global + per-player, persisted to `stats.yml`) - ✅ Phantom timer reset before night skip (action bar + chat) - ✅ Phantom timer reset (whitelist or blacklist mode) - ✅ Phantom timer reset on night skip (Paper-aware)

Visual & Performance

- ✅ Particle and sound effects for visual feedback - ✅ Smart particle optimization based on player count - ✅ Config cache system for fast performance - ✅ Real-time sleep progress messages

Server Management

- ✅ Auto-save worlds after night skip - ✅ Custom messages with color codes and placeholders - ✅ World-specific activation - ✅ Debug mode and detailed logging

---

🆕 What's New in v2.2.0

🐛 Critical Bug Fixes

- Fixed `CooldownManager` missing from `SleepCommand` constructor — The method was returning a newly created empty collection instead of the actual sleeping players. Any code relying on this (placeholders, stats) was silently broken. - Fixed `CooldownManager` missing from `SleepCommand` constructor — In percentage mode, players could bypass the sleep cooldown by using the `/sleep` command instead of entering a bed. Cooldown is now enforced on both paths. - Fixed `CooldownManager` missing from `SleepCommand` constructor — If a player changed worlds during the countdown, particles would spawn at their current location in the wrong world. Players are now verified to still be in the session's world before effects are applied. - Fixed `CooldownManager` missing from `SleepCommand` constructor — The `cooldownManager` field was declared but never assigned, causing a `NullPointerException` on every `/sleep` command execution.

🔧 High-Priority Fixes

- Fixed default GitHub repository name — The listener was registered but the event handler body was completely empty, meaning phantom spawns were never actually cancelled. Logic is now correctly implemented. - Fixed default GitHub repository name — Stats were only written to disk on server shutdown or `/sps reload`. A crash would cause full stats loss. A periodic auto-save task now runs every 5 minutes. - Fixed default GitHub repository name — `sleepingPlayers` is now backed by a concurrent collection to prevent `ConcurrentModificationException` during async PlaceholderAPI queries. - Fixed default GitHub repository name — `computeIfAbsent()` and `get()` were two separate operations. They are now chained into a single atomic call. - Fixed default GitHub repository name — Changed from `HashMap` to `ConcurrentHashMap` to prevent race conditions from async PlaceholderAPI thread access. - Fixed default GitHub repository name — The "AFK players excluded" message was broadcasting on every single sleep attempt per session. It now sends only once per session. - Fixed default GitHub repository name — `net.md_5.bungee.api` usages replaced with `player.sendActionBar()` via Adventure API, as recommended for Paper 1.21+. - Fixed default GitHub repository name — Now correctly uses `getEffectiveSleepingCount()` instead of `sleepingPlayers.size()` to account for `/sleep` votes in percentage mode. - Fixed default GitHub repository name — Players tracked in `sleepingPlayers` but kicked before sleep animation completed were not being removed. `onPlayerLeave()` is now called unconditionally. - Fixed default GitHub repository name — In percentage mode, `getSession(world)` was called to retrieve the required count, which triggered `computeIfAbsent` and created an empty session even when no one had entered a bed. Now uses `getSessionIfExists()`. - Fixed default GitHub repository name — Votes were being counted without verifying the voter is still in the same world as the sleep session. - Fixed default GitHub repository name — Update checker default was `SinglePlayerSleep` instead of `SinglePlayerSleepV2`, causing update checks to fail on fresh installs.

⚡ Performance & Medium Fixes

- Fixed `PhantomModule` broadcasting when no players were reset — Magic numbers `12541` (sunset) and `23458` (sunrise) were hardcoded across `SleepSession.java`, `SleepManager.java`, and `PlaceholderHook.java`. These are now named constants (`SUNSET_TICKS`, `SUNRISE_TICKS`) in a shared `TimeUtil` class. - Fixed `PhantomModule` broadcasting when no players were reset — Replaced set-union allocation (creating a new `HashSet` on every call) with a simple counter loop, reducing GC pressure on busy servers. - Fixed `PhantomModule` broadcasting when no players were reset — Result is now cached in a local variable within `checkSleepCondition()`. - Fixed `PhantomModule` broadcasting when no players were reset — `topSleepersCache`, `topContributorsCache`, and `lastLeaderboardRefresh` are now updated atomically via a single `LeaderboardSnapshot` object to prevent inconsistent reads across threads. - Fixed `PhantomModule` broadcasting when no players were reset — Sleep sessions now clean themselves up when a world becomes empty, preventing unbounded session map growth on servers with many temporary worlds. - Fixed `PhantomModule` broadcasting when no players were reset — `stats.yml` no longer grows unbounded. A configurable `stats.cleanup-days` option (default: 90) purges entries for players who haven't been seen recently. - Fixed `PhantomModule` broadcasting when no players were reset — `Player.getWorld()` is never null in the Bukkit API. Removed misleading defensive checks from `VoteModule` and `SleepListener`. - Fixed `PhantomModule` broadcasting when no players were reset — `AsyncPlayerChatEvent` is always async by Bukkit contract; the check was misleading. - Fixed `PhantomModule` broadcasting when no players were reset — `sleepManager` is never null at the call site. - Fixed `PhantomModule` broadcasting when no players were reset — Changed from `Set.copyOf()` (full allocation) to `Collections.unmodifiableSet()` (view only). - Fixed `PhantomModule` broadcasting when no players were reset — The phantom-reset message now only broadcasts if at least one player's timer was actually reset.

🎨 Code Quality

- Removed unnecessary null checks on Bukkit events with `isNight(World)` helper method - Removed unnecessary null checks on Bukkit events in `SpsCommand.java` and `SleepManager.java` — proper imports added, simple class names used consistently - Removed unnecessary null checks on Bukkit events — Bukkit never fires null events; defensive checks removed from `SleepListener`

---

📂 Installation

1. Download the latest release from Releases or Modrinth. 2. Place the `.jar` file into your server's `/plugins` folder. 3. Restart or reload your server. 4. Edit `plugins/SinglePlayerSleep/config.yml` as needed. 5. Use `/sps reload` to apply configuration changes.

Requirements: - Minecraft 1.21.1+ - Java 21+ - Paper (recommended) or Spigot

> Optional: Install Optional: to enable `%sps_*%` placeholders.

---

🛠️ Commands

| Command | Description | Permission | |---|---|---| | `/sleep` | Vote to skip the night (percentage mode) | `singleplayersleep.sleep` | | `/sps reload` | Reload config and reset sessions | `singleplayersleep.admin` | | `/sps stats [player]` | View global or per-player sleep stats | `singleplayersleep.admin` | | `/sps afk` | Toggle your AFK status manually | `singleplayersleep.admin` | | `/sps version` | Show plugin info and update status | `singleplayersleep.admin` | | `/sps debug` | Toggle debug logging | `singleplayersleep.admin` |

---

🔑 Permissions

| Permission | Default | Description | |---|---|---| | `singleplayersleep.sleep` | `true` | Use `/sleep` | | `singleplayersleep.admin` | `op` | Use `/sps` and admin features | | `singleplayersleep.bypasscooldown` | `op` | Bypass sleep cooldown | | `singleplayersleep.bypassafk` | `op` | Never marked as AFK | | `singleplayersleep.stats` | `true` | View statistics (reserved) |

---

📊 PlaceholderAPI

> Requires PlaceholderAPI installed. Expansion identifier: `sps`

| Placeholder | Description | |---|---| | `%sps_sleeping%` | Current sleeping players in the viewer's world | | `%sps_required%` | Required sleepers in the viewer's world | | `%sps_is_night%` | `true/false` — is it currently night | | `%sps_is_processing%` | `true/false` — is night skip in progress | | `%sps_cooldown%` | Remaining cooldown in seconds | | `%sps_is_afk%` | `true/false` — is the player AFK | | `%sps_nights_skipped%` | Total nights skipped (global) | | `%sps_player_times_slept%` | Times this player has slept | | `%sps_mode%` | `single` or `percentage` | | `%sps_percentage%` | Required percentage |

---

🧩 Configuration Overview

Config file: `plugins/SinglePlayerSleep/config.yml`

Sleep Behavior

| Key | Default | Description | |---|---|---| | `sleep.mode` | `single` | `single` or `percentage` | | `sleep.percentage` | `50` | Required % of non-AFK players | | `sleep.delay-ticks` | `100` | Delay before night skip (20 = 1 second) | | `sleep.cooldown-seconds` | `60` | Cooldown between sleep sessions | | `sleep.clear-weather` | `true` | Clear rain/thunder after skip | | `sleep.auto-save` | `true` | Call `world.save()` after skip |

AFK System

| Key | Default | Description | |---|---|---| | `afk.enabled` | `true` | Enable AFK tracking | | `afk.timeout-seconds` | `300` | Inactivity before AFK | | `afk.exclude-from-count` | `true` | Exclude AFK players from required count | | `afk.check-interval-ticks` | `200` | How often AFK checks run |

Countdown

| Key | Default | Description | |---|---|---| | `countdown.enabled` | `true` | Enable countdown before skip | | `countdown.duration-seconds` | `5` | Countdown length | | `countdown.show-actionbar` | `true` | Show countdown in action bar | | `countdown.show-chat` | `false` | Also post countdown to chat | | `countdown.sound-on-each-tick` | `true` | Play tick sound each second |

Statistics

| Key | Default | Description | |---|---|---| | `stats.enabled` | `true` | Enable stats tracking | | `stats.persist` | `true` | Save stats to `stats.yml` | | `stats.track-per-player` | `true` | Track per-player stats | | `stats.cleanup-days` | `90` | Purge stats for players unseen this many days |

World Filtering

| Key | Default | Description | |---|---|---| | `worlds.enabled` | `["world"]` | World list | | `worlds.mode` | `whitelist` | `whitelist` or `blacklist` |

---

🤝 Contributing

Contributions are welcome!

1. Fork the repository 2. Create a feature branch: `git checkout -b feature/my-feature` 3. Commit your changes: `git commit -m "Add my feature"` 4. Push: `git push origin feature/my-feature` 5. Open a Pull Request

```bash

Clone and build

git clone https://github.com/MRsuffixx/SinglePlayerSleep.git mvn clean package

Output: target/SinglePlayerSleep-2.2.0.jar

```

---

📞 Support

- GitHub Issues - Modrinth Page

When reporting a bug, please include: Minecraft version, plugin version, server software, `config.yml`, and any error logs.

---

🗺️ Roadmap

- [ ] Bossbar progress indicator - [ ] MySQL/SQLite database support for statistics - [ ] Multi-language support - [ ] Discord webhook integration - [ ] Per-world configuration overrides

---

📃 License

Distributed under the MIT License. See LICENSE for details.

---

🏆 Credits

Minecraft: MRsuffix — Minecraft: 2.2.0 — Minecraft: 1.21.1+

> 🧡 Built with love for the Minecraft community.

Minecraft Compatibility: 2.2.0 Minecraft Compatibility: April 2026 Minecraft Compatibility: 26.1+

ADS