NTs Apps. 한국어 Contact

The bug museum

A place to actually touch the broken version. Most write-ups end at "there was a bug and here is the fix", which leaves the reader with nothing, because they never met the bug.

Exhibit one — try it

Below is the hit test exactly as it shipped. Press right on the green arc: it counts as a miss. Flip the switch and the same screen runs the fixed version. The two look identical — one comparison operator apart.

Buggy — try pressing the green arc

A game shipped with its hit test inverted

딱 멈추기 (4시간 게임 1회차)

What happened
초록 구역을 정확히 눌러도 실패하고, 정반대를 눌러야 성공했습니다.

Why
각도 차이를 −π..π 로 접은 뒤 '구역 반폭보다 작은가'를 봐야 하는데 부등호를 반대로 썼습니다. 화면에는 구역이 제대로 그려지고 바늘도 제대로 돌기 때문에, 눌러 보면 '내가 못 맞혔나' 로 보입니다.

How it surfaced
브라우저로는 못 잡았습니다. 확인용 창이 가려져 있으면 애니메이션이 멈춰서, 그 화면에서 확인할 수 있는 것은 '첫 프레임이 그려졌다'까지였습니다. 규칙만 떼어 node 에서 재 보고 나왔습니다.

The fix
부등호를 뒤집고, 0도를 넘는 자리까지 포함해 판정 검사 10항목을 남겼습니다.

Full post

A CSS fix that erased a different button

사이트 전체

What happened
고스트 버튼이 흰 배경에 흰 글자로 안 보였습니다. 고쳤더니 이번에는 기본 버튼이 까만 배경에 까만 글자가 됐습니다.

Why
<button> 에 남는 브라우저 기본 배경을 지우려고 button.btn 규칙을 넣었는데, 그 선택자의 특이도가 .btn-primary 보다 높아서 primary 의 배경색까지 함께 지웠습니다.

How it surfaced
둘 다 사용자가 먼저 봤습니다. 첫 번째는 캐시된 옛 CSS 때문에 고쳐 배포한 뒤에도 화면이 그대로였고, 그래서 '고쳤다'고 잘못 말할 뻔했습니다.

The fix
:where() 로 감싸 특이도를 0 으로 만들었습니다. 그리고 게이트에 button.btn 원시 선택자 금지 검사를 넣고, 일부러 되돌려서 실제로 잡히는지 확인했습니다.

Full post

Holes that appeared every time the wave went up

매치 시즈

What happened
우측 하단에 블록도 장애물도 없는 빈 칸 세 개가 남았습니다.

Why
판이 오를 때 침식을 한 겹 벗기는데, 그 뒤에 블록을 내려 채우지 않았습니다. 매치로 벗길 때는 지우기 → 중력 → 리필 경로를 타지만 판 상승은 그 경로를 타지 않았습니다.

How it surfaced
실기기 제보로 알았습니다. 그리고 잡는 과정에서 검증에서 세 번 틀렸습니다 — 검사가 210초 동안 단 한 번만 돌았고(통과 횟수를 안 세면 0회 통과도 통과로 보입니다), 실패한 패치를 성공으로 보고했고, 엉뚱한 곳을 의심했습니다.

The fix
'빈 칸에는 반드시 침식이 있어야 한다'는 불변식을 세우고, 자동 플레이 중 계속 확인하는 모드를 만들었습니다. 시드 세 개 × 600여 회 통과, 수정 전에는 세 시드 모두 위반했습니다.

Full post

Why keep these

All three have one thing in common: they looked fine on screen. The inverted hit test drew its arc and needle correctly, the invisible button still occupied its space, and the holes stayed unnoticed until a later match touched that column.

So each fix left a check behind. And each check was itself checked by breaking the code again on purpose — one of them failed to catch anything the first time. A check that cannot catch its own bug is not a check.

The build notes are in the dev log, and what each genre needs is here.