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

Published: (January 4, 2026 at 11:46 PM EST)
3 min read
Source: Dev.to

Source: Dev.to

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

🧰 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:

  1. Dashboard – Intro text and feature list
  2. 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 🎲

Back to Blog

Related posts

Read more »