오래된 프로그램을 새로 만들겠다는 말에는 서로 다른 바람이 섞여 있다. 답답한 화면은 바꾸고 싶고, 익숙한 동작은 그대로 두고 싶다. 코드를 걷어내는 일보다 어려운 것은 두 바람 사이에 선을 긋는 일이다. 무엇을 고쳐도 되는지 정하지 않은 채 다시 만들기 시작하면, 작은 불편을 없애려다 오래 쌓인 사용법까지 지워버릴 수 있다.
fheroes2의 공개 README는 이 질문을 떠올리게 한다. 이 프로젝트는 Heroes of Might and Magic II의 엔진을 다시 구현하는 작업이다. 문서에는 사용 환경과 인터페이스 개선이 소개되어 있고, 엔진 코드와 원작의 게임 자료가 별개라는 설명도 나온다. 여기서 흥미로운 부분은 오래된 게임의 외형보다, 같은 게임이라고 부를 수 있는 동작을 어떻게 남기느냐에 있다. 아래 예시는 프로젝트를 실행해 얻은 결과가 아닌, 이 질문을 살펴보기 위해 만든 가상의 보드게임이다.
세 번의 차례를 적어보면
종이 위에 작은 격자와 말 하나가 있다고 하자. 말은 한 차례에 두 칸 움직이고, 늪에 들어가면 다음 차례의 이동이 한 칸 줄어든다. 목표 지점에 도착하면 게임이 끝난다. 이렇게 간단한 규칙도 화면만 보고는 다 알기 어렵다. 늪에 들어간 바로 그 순간 이동이 줄어드는지, 다음 차례에 줄어드는지에 따라 같은 입력의 결과가 달라진다.
다시 만드는 쪽에서 처음 남길 것은 멋진 화면이 아니라 작은 기록이다. 시작 위치, 입력한 행동, 직후의 위치, 다음 차례의 이동 가능 거리, 종료 여부를 한 줄에 적는다. 평지로 이동하는 경우와 늪에 들어가는 경우를 나란히 놓으면, 겉으로 비슷한 장면 속에 숨어 있던 차이를 볼 수 있다. 애매한 항목은 추측해서 채우지 않고 물음표로 남겨두는 편이 낫다.
예를 들어 첫 차례에는 평지로 두 칸 이동한다. 두 번째에는 늪에 도착한다. 세 번째에는 한 칸만 이동할 수 있다. 이 짧은 연속 동작을 기존 방식과 새 방식에 똑같이 적용한다. 마지막 위치만 같다고 끝낼 수는 없다. 중간에 허용하지 않은 행동을 통과시켰다면, 우연히 같은 곳에 도착한 것이다. 사용자는 그 중간 과정을 기억하고 있다.
이런 기록은 자동 검사를 만들기 전에도 쓸모가 있다. 두 사람이 규칙을 다르게 이해했을 때 어디서 갈라졌는지 찾을 수 있기 때문이다. 한 사람은 늪의 효과가 즉시 적용된다고 읽고, 다른 사람은 다음 차례라고 읽었다면 코드부터 비교할 필요가 없다. 먼저 규칙 문장과 실제 동작 중 무엇을 기준으로 삼을지 정해야 한다.
바꿀 수 있는 것에도 이름이 필요하다
동작을 남긴다고 해서 모든 불편을 그대로 복원해야 하는 것은 아니다. 글자가 작거나 버튼이 가려지는 문제는 고칠 수 있다. 다만 변경한 항목을 같은 동작의 목록 속에 섞지 않는 것이 좋다. 이 예시에서는 말의 이동 규칙은 유지하고, 현재 이동 가능 거리를 화면에 더 분명하게 표시한다고 정할 수 있다. 규칙을 고치는 일과 규칙을 더 잘 보여주는 일이 분리된다.
반대로 늪의 효과를 한 차례 더 길게 만들고 싶다면 그것은 새로운 규칙이다. 취향에 맞는 개선일 수 있지만, 원래와 같은 결과를 낸다고 설명하면 안 된다. 변경 이유와 적용 범위를 따로 적어야 한다. 새 버전으로 저장한 진행 상태를 예전 버전에서도 열어야 하는지도 함께 생각해야 한다. 그 약속이 없다면 옛 저장 자료를 덮어쓰지 않는 쪽으로 경계를 잡을 수 있다.
이 지점에서 화면 비교만으로는 부족하다는 사실이 드러난다. 같은 그림을 보여줘도 규칙이 다를 수 있고, 다른 그림을 보여줘도 같은 규칙을 지킬 수 있다. 기존 자료를 읽고 저장하는 기능, 취소했을 때 돌아가는 위치, 잘못된 입력에 대한 반응도 사용자가 기대하는 동작의 일부다. 새 기능 목록에는 잘 적히지 않지만, 익숙함을 유지하는 데에는 이런 부분이 더 크게 작용할 수 있다.
익숙한 것을 옮기는 작은 순서
이 사고실험을 오래된 개인 도구에 적용한다면, 가장 자주 쓰는 작업 하나부터 골라볼 만하다. 입력 자료 한 개와 기대 결과 한 개를 원본 그대로 보존한다. 그다음 정상 입력, 경계에 걸린 입력, 취소한 입력을 추가한다. 모든 경우를 한 번에 모으려 하기보다, 어느 약속부터 지키려는지 보이는 크기로 시작하는 것이다.
새 구현을 비교할 때에는 달라진 결과를 모두 결함으로 처리할 필요는 없다. 의도한 변경인지, 문서에 없는 규칙을 놓친 것인지, 아직 판단하지 못한 것인지 나눠 적으면 된다. 판단하지 못한 차이는 출시 직전에 사라지는 항목이 아니다. 사용자가 실제로 의존하는 동작일 수 있으니, 확인할 사람과 기준을 정할 때까지 남겨두어야 한다.
게임 자료의 권리도 같은 방식으로 별도의 질문이다. 엔진 코드가 공개되어 있다는 사실만으로 원작의 그림과 음악을 다른 곳에 옮길 수 있는 것은 아니다. 이 글의 표지를 원작 화면 대신 새로 구성한 장면으로 만든 이유도 여기에 있다. 기술적으로 재현할 수 있다는 말과 배포할 권한이 있다는 말은 서로 다른 확인을 요구한다.
오래된 도구를 다시 만드는 일은 과거를 정리하는 작업처럼 보이지만, 실제로는 다음 사용자가 무엇을 믿어도 되는지 쓰는 작업에 가깝다. 처음에는 세 번의 차례면 충분할지 모른다. 그 세 번에서 어떤 약속을 발견했는지가 코드의 분량보다 먼저다. 지금 다시 만들고 싶은 도구가 있다면, 화면을 열기 전에 끝까지 지켜야 할 동작 하나를 먼저 적어보면 어떨까.
관련 글은 Software Engineering에서 이어 읽을 수 있습니다.
공개 원문을 참고해 AI의 도움으로 구성·작성한 글입니다. 본문의 가상 예시는 실제 수행 결과와 구분했으며, 표지는 Google Gemini로 만든 개념 일러스트입니다.



