🎲 Building DiceForge: A Modern Dice Rolling Simulator with Python & Tkinter
Source: Dev.to

If you’ve ever needed a quick way to roll dice for tabletop games, probability experiments, or just for fun, building your own dice roller is a great weekend project.
In this post, we’ll walk through DiceForge, a polished dice‑rolling simulator built with Python, Tkinter, and ttk, featuring:
- A clean, modern UI
- Configurable dice counts and sides
- Instant roll results and totals
- Light & dark mode support
- A tab‑based layout using
ttk.Notebook
🧰 Tech Stack
- Python 3 – Core logic
- Tkinter – GUI framework (built into Python)
- ttk / sv_ttk – Themed widgets & modern styling
- random – Dice roll generation
No external APIs. No databases. Just clean, local Python.
🧠 App Overview
DiceForge is structured as a single‑window desktop app with two main tabs:
- Dashboard – Intro text and feature list
- Dice Roller – Where the magic happens
The UI is responsive, readable, and designed to feel closer to a modern app than a default Tkinter window.
🚀 Application Setup
import tkinter as tk
import ttk
import sv_ttk
root = tk.Tk()
root.title("DiceForge - Dice Rolling Simulator")
root.geometry("900x620")
sv_ttk.set_theme("light")
The sv_ttk library gives us a cleaner base theme, which we later extend with custom styles.
🎛 Global State with Tkinter Variables
Tkinter’s variable classes make state management simple:
dark_mode_var = tk.BooleanVar(value=False)
dice_count_var = tk.IntVar(value=1)
dice_sides_var = tk.IntVar(value=6)
These variables automatically stay in sync with widgets like spinboxes and checkbuttons.
🌗 Light & Dark Mode Toggle
Dark mode is handled by dynamically reconfiguring ttk styles and the root background:
def toggle_theme():
style.theme_use("clam")
if dark_mode_var.get():
root.configure(bg="#2E2E2E")
style.configure("TLabel", background="#2E2E2E", foreground="white")
else:
root.configure(bg="#FFFFFF")
style.configure("TLabel", background="#FFFFFF", foreground="black")
This approach keeps the UI consistent without rebuilding widgets.
📑 Tabbed Layout with Notebook
We use ttk.Notebook to separate concerns cleanly:
tabs = ttk.Notebook(root)
tabs.pack(expand=True, fill="both", padx=20, pady=20)
dashboard_tab = ttk.Frame(tabs)
roller_tab = ttk.Frame(tabs)
tabs.add(dashboard_tab, text="Dashboard")
tabs.add(roller_tab, text="Dice Roller")
Each tab is its own Frame, making the layout modular and easy to extend later.
⚙️ Dice Configuration Controls
The dice settings use Spinbox widgets so users can’t input invalid types:
dice_spin = ttk.Spinbox(
settings_card,
from_=1,
to=100,
textvariable=dice_count_var
)
This keeps validation simple and UX friendly.
🎲 Rolling the Dice
Here’s the heart of the app:
import random
def roll_dice():
count = dice_count_var.get()
sides = dice_sides_var.get()
rolls = [random.randint(1, sides) for _ in range(count)]
total = sum(rolls)
# Display results (example)
result_text = f"{count}d{sides}: " + ", ".join(map(str, rolls))
result_text += f"\nTotal: {total}"
result_widget.configure(state="normal")
result_widget.delete("1.0", tk.END)
result_widget.insert(tk.END, result_text)
result_widget.configure(state="disabled")
The results are shown in a read‑only Text widget, displaying:
- Dice notation (
XdY) - Individual rolls
- Final total
Perfect for quick checks or repeated testing.
🧾 Status Bar Feedback
A subtle but important UX touch: a status bar.
status_var = tk.StringVar(value="Ready")
status_bar = ttk.Label(root, textvariable=status_var, anchor="w")
status_bar.pack(side="bottom", fill="x")
This gives instant feedback for actions like rolling dice or switching themes.
✨ Polished Styling
Custom button styling helps important actions stand out:
style.configure(
"Action.TButton",
font=("Segoe UI", 11, "bold"),
background="#4CAF50"
)
Small details like this make a huge difference in perceived quality.
🏁 Final Thoughts
DiceForge is a great example of how far you can push Tkinter with thoughtful layout and styling. It’s:
- Beginner‑friendly
- Easily extendable (advantage/disadvantage rolls, presets, history)
- A solid foundation for packaging with PyInstaller
If you’re learning Python GUI development, this project hits a sweet spot between approachable and polished.
Happy rolling 🎲