Quick answer: Shoot-em-ups break at the level of single frames and single pixels, so a written report rarely explains an unfair death. Capture the active bullet pattern and phase, the boss state, the player hitbox and graze radius, the nearest bullet distance, and the scroll offset with every report, then reproduce with a fixed seed and recorded input.
A shoot-em-up, or shmup, can put over a thousand bullets on screen while the player threads a one-pixel hitbox through gaps the size of a sprite edge. When something is off by a frame or a few pixels, it is the difference between a fair death and a player who quits convinced the game cheated. These bugs are timing dependent, almost impossible to describe in words, and they vanish the instant the screen clears. This post covers the bullet pattern, hitbox, grazing, and scrolling defects that define the genre, and how capturing dense per-frame state turns vague unfair-death complaints into tickets you can actually fix.
Why shmup bugs are hard to catch
Shmups live and die by precision, and that precision is exactly what makes their bugs slippery. A pattern might only misbehave on its third loop, or only when two emitters overlap, or only at a specific scroll position deep into a stage. By the time a player notices and reaches for a report button the moment is already gone and the bullet field has cleared, leaving nothing for your team to inspect. Without your game recording what the screen looked like a moment before the report, you are reconstructing a fraction of a second from a fuzzy human memory.
The genre also leans on dense, fast-evolving state as a feature. Hundreds of projectiles, scripted emitters, and constant directional change make a good shmup thrilling, but they also make defects intermittent and resistant to casual reproduction. A death that only happens when a boss enters phase three while sixty bullets are on screen is not something a tester can casually trigger on demand. The only reliable path is to treat the bullet field and player state as first-class data and capture it automatically at the instant of the report.
Bullet pattern defects
Bullet patterns are scripted emitters with angles, speeds, spawn rates, and timing offsets, and any of those values can break. Common defects include a pattern that fires too fast because a delta-time calculation degraded at low framerate, a spiral that drifts because an angle accumulator was never wrapped, or bullets that spawn at the wrong origin because an emitter was parented to a boss part that moved. Players experience these as unfair or chaotic difficulty, but to your team they are concrete logic errors that need the emitter id, the pattern phase, and the elapsed pattern time to diagnose.
Boss fights amplify pattern bugs because they chain many emitters across multiple phases. A phase transition that does not clear the previous emitters leaves orphaned bullets that should not exist, while a phase that triggers early because a health threshold was crossed during a screen clear can skip an entire attack. Capturing the boss phase, its health percentage, the active emitter list, and the on-screen bullet count when a report arrives gives engineers the exact pattern state, turning an unfair death complaint into a precise, fixable ticket instead of an argument about whether the report is even real.
Hitboxes, grazing, and scrolling
Hitbox correctness is the heart of the genre. Shmups use a player hitbox much smaller than the sprite, and players build muscle memory around its exact size and position. If the hitbox is offset, scaled wrong at a particular resolution, or lagging the sprite by a frame, players report deaths that looked impossible. Grazing systems that reward skimming bullets make this worse, since a graze radius bug can deny earned points or trigger grazes from bullets that were nowhere near. Logging the hitbox center, the graze radius, and the nearest bullet distance at the moment of death is essential.
Scrolling ties everything to position over time. Most shmups scroll the stage automatically and spawn enemies at scroll markers, so a scroll speed bug shifts every spawn out of sync. Players may report that an enemy appeared too late to dodge or that a checkpoint loaded them into an unwinnable wall of bullets. Pause-and-resume, slowdown on dense frames, and resolution-dependent scaling all interact with scroll position. Capturing the current scroll offset, the scroll speed, and the active spawn markers lets your team line the report up against the stage script and find exactly where it diverged.
Setting it up with Bugnet
Bugnet is built to carry the dense, structured state a shmup produces. Wire the in-game report button so it fills custom fields with the on-screen bullet count, the current boss phase and health, the active pattern id and phase time, the player hitbox position, the graze radius, and the scroll offset whenever a report is submitted. Because Bugnet stores these as searchable custom fields on one dashboard, you can later filter for every report with over eight hundred bullets, or every death tied to a specific boss phase, and find the systemic issue instead of reading isolated complaints one at a time.
Occurrence grouping is especially valuable here, because a single bad pattern produces a flood of near-identical reports. Bugnet folds those duplicates into one issue with a count, so a frame-perfect spawn bug that kills hundreds of players shows up as one high-occurrence ticket you can prioritize immediately. Pair that with player attributes such as resolution and refresh rate, and a hitbox offset that only appears at a certain display setting becomes obvious from the dashboard. The in-game button captures the bullet field automatically, so players report with one tap and you receive the exact frame.
Building a reproduction workflow
Determinism is the foundation of shmup debugging. Because patterns and scrolling are scripted against time and a seed, you can make stages fully replayable by fixing the random seed and recording the player input stream. When a report arrives carrying its seed, input log, and scroll offset, an engineer can fast-forward to the exact moment and step frame by frame through the bullet field. This is far more reliable than asking the player which boss they were on and trying to die in the same spot by hand, which almost never reproduces the original conditions.
On top of capture, build a triage loop driven by your custom fields. Cluster reports by boss phase, pattern id, or bullet count, then reproduce the largest cluster first since it likely points at a single shared defect. Keep stress stages in your test suite that drive bullet counts to the designed ceiling, and run them every build to catch density regressions and projectile pool exhaustion before players hit them. With deterministic replay and data-driven triage, shmup QA becomes a measured, frame-accurate process rather than a guessing game played against your most demanding fans.
Make it part of how you ship
The studios that ship tight, fair shmups are the ones that record the bullet field and player state every frame and ship that state with the report. Capture the pattern phase, the nearest bullet distance, the graze radius, and the scroll offset, and the unfair deaths your players report become reproducible, fixable tickets rather than forum arguments. Bake the capture into your report button from the first prototype so the data is there when difficulty tuning gets serious and the bullet counts climb toward their ceiling.
Treat every unfair-death report as a gift of telemetry you could not otherwise gather, because your players reach combinations of pattern, scroll, and timing that no internal tester will. Instrument your emitters, hitboxes, and scroll system now, route the structured reports into one dashboard, and your next round of shmup feedback will let you fix problems before your sharpest players ever feel them. A fair shmup is a trusted shmup, and trust is built one reproducible bug at a time.
In a shmup, a frame and a pixel decide everything. Capture the bullet field and hitbox state automatically, and unfair deaths turn into tickets you can fix.