DEV Community

Mate Technologies
Mate Technologies

Posted on

🎲 Building DiceForge: A Modern Dice Rolling Simulator with Python & Tkinter

Dice Rolling Simulator

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

Let’s break it down.

🧰 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

We start by configuring the main window and enabling themed widgets.

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")
Enter fullscreen mode Exit fullscreen mode

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)

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:

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)
Enter fullscreen mode Exit fullscreen mode

The results are displayed in a read-only Text widget, showing:

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")

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 🎲

Top comments (0)