From Concept to Code: Implementation Details
In Part 1, I covered why I built this time management system and the overall architecture. Now let’s get our hands dirty with the actual implementation. If you want to follow along with the complete source code, everything is available on GitHub.
The RCON Connection: Talking to Minecraft
The heart of this system is the RCON (Remote Console) protocol—Minecraft’s way of accepting external commands. <RCON – Minecraft Wiki>
Here’s what makes it work:
Setting Up RCON Communication
First, you need to enable RCON in your Minecraft server’s server.properties:
enable-rcon=true
rcon.port=25575
rcon.password=your_secure_password
The RCON client handles authentication and command execution. Every interaction follows this pattern:
- Open TCP connection to the Minecraft server
- Send authentication packet
- Execute command
- Receive and parse response
- Close connection (or keep alive for efficiency)
The protocol uses a specific packet structure with request IDs, packet types, and payload data. Getting this wrong means silent failures or cryptic errors, so proper error handling is crucial.
Command Execution in Practice
When you click “Give Item” in the web interface, here’s what happens under the hood:
# Simplified flow
def execute_custom_command(player, command_template):
# Replace {player} placeholder with actual player name
actual_command = command_template.replace('{player}', player)
# Send via RCON
response = rcon_client.execute(actual_command)
# Log and return result
return response
For multi-command sequences (like giving multiple items or teleporting then changing game mode), the system executes each command in order, waiting for confirmation before proceeding to the next.
The Background Monitor: Keeping Track of Time
The most critical component is the background timer that monitors player activity. This runs in a separate thread and wakes up every 60 seconds:
The Monitoring Loop
def monitor_players():
while True:
# Get list of online players from Minecraft
online_players = get_online_players_via_rcon()
for player in online_players:
# Load player data from database
player_data = db.get_player(player)
# Calculate time played today
time_today = calculate_daily_playtime(player_data)
# Check against their limit
if time_today >= player_data.daily_limit:
kick_player_with_message(player)
elif time_today >= (player_data.daily_limit - 5):
send_warning(player, minutes_left=5)
# Update session tracking
db.update_player_session(player)
sleep(60)
Handling Session Tracking
One tricky aspect is accurately tracking sessions. When a player joins:
- Record
current_session_starttimestamp - Mark
is_online = True - Increment session counter
When they disconnect (either voluntarily or kicked):
- Calculate session duration
- Add to
time_played_today - Update
total_time_played - Store session record for historical data
- Mark
is_online = False
The challenge? Detecting when players disconnect naturally versus being kicked by the system. The solution involves checking the RCON player list and comparing against the database state—if someone’s marked online but not in the RCON list, they’ve disconnected.
The Configuration System: Making It Flexible
One design goal was avoiding hard-coded commands. Everything lives in custom_commands.json:
{
"items": [
{
"name": "Diamond Sword",
"icon": "🗡️",
"command": "give {player} diamond_sword{Enchantments:[{id:sharpness,lvl:5}]} 1",
"description": "Enchanted diamond sword"
}
],
"commands": [
{
"name": "Teleport Home",
"type": "multi",
"commands": [
"tp {player} 0 64 0",
"title {player} subtitle {\"text\":\"Welcome home!\",\"color\":\"green\"}"
]
}
]
}
The Config Editor
The web-based config editor parses this JSON and renders a clean interface for modifications. When you save changes:
- Validate JSON structure
- Write to file atomically (to prevent corruption)
- Reload config into memory
- Invalidate any cached command mappings
This means you can add new items, modify commands, or adjust settings without restarting the application or touching code.
Database Schema
SQLite provides the perfect balance of simplicity and functionality for this use case. The schema tracks three main entities:
Players Table
Stores core player information—username, daily time limit, current playtime, session state, and historical totals.
Sessions Table
Historical record of every login/logout, including duration and disconnect reason. This data is gold for understanding usage patterns.
Settings Table
Key-value pairs for system-wide configuration like default time limits, warning thresholds, and RCON connection details.
Frontend: Making It Usable
The web interface needed to be something my wife could use without calling me for help.
That meant:
Real-Time Updates
JavaScript polls the API every few seconds to refresh the player list and time remaining. AJAX requests keep the page responsive without full reloads.
Toast Notifications
Every action—executing a command, kicking a player, saving config—triggers a toast notification. Immediate feedback is crucial for non-technical users.
Responsive Design
Works on desktop, tablet, and mobile. Sometimes you need to check on things from your phone, and the interface adapts beautifully.
Modal Dialogs
Adding players, editing limits, and confirming destructive actions all use modals. This keeps the interface clean while preventing accidental clicks.
The Docker Setup: Easy Deployment
The docker-compose.yml ties everything together:
services:
minecraft:
image: itzg/minecraft-server
ports:
- "25565:25565"
- "25575:25575"
environment:
EULA: "TRUE"
RCON_PASSWORD: "${RCON_PASSWORD}"
volumes:
- ./minecraft-data:/data
timemanager:
build: .
ports:
- "5000:5000"
environment:
RCON_HOST: "minecraft"
RCON_PORT: "25575"
RCON_PASSWORD: "${RCON_PASSWORD}"
volumes:
- ./data:/app/data
depends_on:
- minecraft
The beauty of this setup:
- Minecraft server and time manager run in isolated containers
- They can communicate through Docker’s internal network
- One
.envfile manages all sensitive config - Volumes persist data across container restarts
depends_onensures proper startup order
Deploying Your Own Instance
Want to run this yourself? Here’s the quick-start:
- Clone the repository:
git clone https://github.com/MichalHajduch85/Minecraft_TimeManager/
cd Minecraft_TimeManager
- Set up environment variables:
cp .env.example .env
# Edit .env with your RCON password and settings
- Start everything:
docker-compose up -d
- Access the dashboard: Open
http://localhost:5000in your browser - Configure your first player: Connected players are added automatically, you can set their daily time limits through the web interface
The GitHub repository includes full documentation, example configurations, and troubleshooting guides.
.post scriptum
Building this tool scratched multiple itches—solving a real parental challenge, learning new technologies, and creating something actually useful. The fact that it’s now maybe helping other parents manage screen time, makes it even more rewarding.
If you’re running a local Minecraft server and dealing with time management challenges, give it a try. If you’re a developer looking to learn Flask, Docker, or RCON integration, the codebase is well-commented and ready for exploration.
Check out the complete source code on GitHub, star the repo if you find it useful, and feel free to contribute improvements or report issues.
Questions? Improvements? Bug reports? Open an issue on GitHub. I’m always interested in making this tool better and hearing how others are using it.



Leave a Reply