Overview
This was my project for Introduction to Quantum Computing at UTS. A gacha game felt like the honest choice: pulling a character is already a probability distribution that resolves into one result the moment you commit to it, which is close enough to a measurement that I wanted to see what happened if I made it literal.
Honkai: Star Rail has a Quantum element, so the tribute picked itself. There
are two games in one Colab notebook. Squanventum Hunt is a grid dungeon where
you earn Stellar Jade, and the banner is where you spend it on an eighteen-card
roster. It's all Python: ipywidgets for the controls, matplotlib for the
board and the card reveals. None of the randomness happens locally. Each circuit
is an OpenQASM 2.0 string sent over HTTP to a Quokka quantum machine, and
the game waits on the measured bits before it knows what you got.
The physics behind it
A classical bit is settled: 0 or 1. A qubit isn't, until you look at it. Before measurement it's written as
|ψ⟩ = α|0⟩ + β|1⟩ with |α|² + |β|² = 1
α and β are amplitudes rather than probabilities. You square them to get the
odds, and they have to square to 1 because a measurement always returns
something. The usual picture is the Bloch sphere, with |0⟩ and |1⟩ at the
poles: latitude decides the balance between them, longitude carries the phase,
and a gate is a rotation of that point.
That last part is what I actually needed. A drop rate is a latitude, so instead of comparing a random float against a threshold, I can rotate a qubit to the right place and read it. The gate for that is RY, a rotation about the Y axis:
RY(θ) = [ cos(θ/2) −sin(θ/2) ] RY(θ)|0⟩ = cos(θ/2)|0⟩ + sin(θ/2)|1⟩
[ sin(θ/2) cos(θ/2) ]
which gives P(measuring 0) = cos²(θ/2). Turn that around and you get
θ = 2·arccos(√p) for whatever p you want. Every rate in the game comes out
of that one formula.
The other gate I use is the Hadamard, which splits a settled qubit evenly:
H|0⟩ = (|0⟩ + |1⟩)/√2
An exact 50/50, with no angle to round off. Two of them give four outcomes at 25% each.
Three mechanics, three circuits
1 · The pull. Rates are 1.3% for five-stars, 9% for four-stars, 89.7% for
everything else. That's two qubits read as a chain: |00⟩ is a five-star, |01⟩
a four-star, anything else is a three-star. The first qubit holds the chance of
not being a three-star, 0.013 + 0.09 = 0.103, so
θ₀ = 2·arccos(√0.103) ≈ 2.488 rad. The second splits that slice conditionally,
0.013 / 0.103 ≈ 0.126, so θ₁ ≈ 2.415 rad. Multiply the two and you land back
on the published rates.
OPENQASM 2.0;
qreg q[2]; // two qubits, both starting at |0>
creg c[2]; // two classical bits to catch the readout
ry(2.488) q[0]; // P(|0>) = cos^2(theta/2) = 0.103
ry(2.415) q[1]; // P(|0>) = 0.013 / 0.103
measure q -> c; // collapse both, read the bits
There's no entanglement in there, deliberately. The two qubits stay a product state, which is why the joint distribution factorises into a clean conditional chain. Entangling them would correlate the two rolls, and a banner doesn't want that.
2 · The health bar. Your HP in the dungeon isn't a number counting down.
It's a qubit, and the display shows the state itself: α|0⟩ + β|1⟩, where |0⟩
is dead and |1⟩ is alive. Those are amplitudes, so your real survival chance is
β², and you have to square your own health bar to read it. When a monster
catches you, the same rotation prepares that state and the qubit is measured.
Nothing decided the outcome beforehand.
3 · The teleport. Two Hadamards, both measured. Every basis state carries
amplitude 1/2, so each comes up a quarter of the time, and |11⟩ discards the
direction you pressed and drops you somewhere random on the map. An RY rotation
could have produced 25% too, but the Hadamard gives it exactly, without a
transcendental angle.
What's in it
- Squanventum Hunt: a 10×10 grid of stone, monsters, chests and one rare room worth far more than it looks, with a log narrating each step. Everything you fight or open pays out Stellar Jade.
- The banner: 18 cards across three rarity tiers, single and ten-pull buttons, and a collection screen that fills in as you find things. A pull costs 160 Jade, ten costs 1600, and the quantum versions run 144 and 1440. All of it is funded by the dungeon, so a bad run in the Hunt makes for a short session at the banner.
- A quantum toggle: flipping it regenerates the map at 15×15, doubles monster density from 10% to 20%, raises every reward ceiling, and swaps the health number for its amplitudes.
An honest footnote
The circuits reach the Quokka through its simulator endpoint, so I'm not claiming a superconducting chip picked your five-star. What is real is the pipeline: state preparation, gates, measurement, classical readout, the same OpenQASM you would send to hardware. The odds sit in the circuit instead of in my Python, and pointing it at a physical device would change the address and nothing else.
What I learned
Encoding a probability as an angle is the part that stuck. A 1.3% drop rate is a rotation of 2.488 radians, and once you've built something on top of that, state preparation stops being notation. The less glamorous lesson: every roll is a network round trip, so the game loop has to be designed around waiting for a response.