2P by GN⁺ | ★ favorite | 댓글 1개
  • 1969년 고등학생 Jim Storer가 만든 첫 Lunar Landing 게임에서 최적 착륙 연료 스케줄을 검증하던 중, 실제로는 착륙해야 할 순간을 게임이 비행 중으로 잘못 판정하는 버그가 드러남
  • 문제의 전략은 70초간 엔진을 끄고, 10초 동안 164.31426784 lbs/sec, 이후 최대 200 lbs/sec로 태우는 suicide burn이며, 게임은 거친 착륙과 미착륙 상승 사이의 부드러운 착륙을 놓침
  • 원래 코드는 단순 Euler 적분이 아니라 Tsiolkovsky 로켓 방정식과 Taylor 급수를 사용해 10초 턴의 운동을 계산했으며, 1969년 PDP-8 환경의 고등학생 작업으로는 상당히 정교함
  • 버그의 원인은 지면 접촉 전 궤적의 최저점을 근사하는 식에서 제곱근 내부 분모의 2로 나누기가 빠진 것으로, 최저점 도달 시간이 일관되게 과소추정됨
  • 빠진 factor of two를 고치고 0.05초 보정을 제거하면 suicide burn 결과가 1.66 MPH까지 개선되지만, 1 MPH 미만의 완벽한 착륙에는 Taylor 급수 2항 근사와 착륙 시점 재계산 한계가 남아 있음

1969년 Lunar Landing과 최적 착륙 탐색

  • Jim Storer는 Neil Armstrong의 달 착륙 몇 달 뒤, Massachusetts의 Lexington High School 학생으로 첫 Lunar Landing 게임을 작성함
  • 1973년에는 이 게임이 “by far and away the single most popular computer game”으로 불릴 정도로 널리 퍼짐
  • 게임은 텍스트 기반이며, 달 착륙선의 모든 운동은 수직 방향으로만 진행됨
  • 플레이어는 시뮬레이션상 매 10초마다 태울 연료량을 정하고, 달 표면에 최대한 부드럽게 착륙해야 함
  • 최적 연료 스케줄을 찾는 과정에서 이론적으로 가장 좋은 전략이 게임 안에서는 제대로 동작하지 않았음
    • 실제로는 착륙선이 표면에 닿는 상황임
    • 게임은 표면에 닿지 않았다고 잘못 판정함
    • 최종 원인은 거의 55년 동안 눈에 띄지 않은 누락된 divide by two였음

최소 연료 착륙과 suicide burn

  • 최소 연료로 착륙하려면 가능한 한 짧은 시간 안에 내려와야 함
  • 최적 전략은 처음에는 엔진을 꺼 속도를 키우고, 마지막 가능한 순간에 최대 추력으로 감속해 표면에 닿는 순간 속도를 0에 가깝게 만드는 방식임
  • Kerbal Space Program 커뮤니티는 이런 전략을 suicide burn이라고 부름
    • 타이밍이 매우 빡빡하고 오류 여지가 거의 없기 때문임
  • 시행착오와 수동 이진 탐색으로 찾은 스케줄은 다음과 같음
    • 70초 동안 연료를 태우지 않음
    • 다음 10초 동안 164.31426784 lbs/sec로 연료를 태움
    • 이후 최대치인 200 lbs/sec로 연료를 태움
  • 게임은 1 MPH 미만을 완벽한 착륙으로 간주함
  • 이 스케줄에서는 3.5 MPH 이상으로 착륙해 “could be better” 판정을 받음
  • 그런데 연료량을 0.00000001 lbs/sec만 더 태우면 표면에 닿지 않고 114 MPH로 상승함
  • 거친 착륙미착륙 상승 사이에 있어야 할 부드러운 착륙 판정이 사라져 있었음

예상보다 정교했던 물리 계산

  • 처음에는 오늘날 게임에서도 흔한 Euler 적분을 예상함
    • 시간 구간 시작점의 힘을 계산함
    • F=ma로 가속도를 구함
    • 해당 시간 구간 동안 가속도가 일정하다고 가정함
  • 실제 Lunar Landing 코드는 이보다 더 정교했음
  • Jim Storer는 Tsiolkovsky rocket equation의 정확한 해를 사용함
  • 로그 계산에는 Taylor 급수 전개를 적용함
    • 인자의 최대값은 0.1212임
    • 5개 항으로 6자리 이상 정확도를 냄
  • 대수적 단순화로 반올림 오차도 줄임
  • Jim Storer는 당시 미적분과 Taylor 급수 같은 개념에 익숙했고, 물리학자였던 아버지가 방정식 유도에 도움을 준 것으로 기억함
  • suicide burn이 최적이 되는 이유도 이 로켓 방정식에서 나오며, 이 부분은 버그의 원인이 아니었음

지면 접촉 판정이 까다로운 이유

  • 로켓 방정식은 착륙선이 지면에 닿기 전까지는 잘 동작함
  • 고체 물체 간 충돌은 동역학 엔진에서 어려운 영역이며, Lunar Landing도 지면 접촉 판정에서 가장 큰 난관을 만남
  • 10초 턴의 시작과 끝만 확인해서는 충분하지 않음
    • 시작 시점에는 하강 중일 수 있음
    • 끝 시점에는 상승 중일 수 있음
    • 중간에 표면 아래로 내려갔다가 다시 올라왔을 수 있음
  • 이 경우 프로그램은 시간을 되감아 더 이른 접촉 시점을 찾아야 함
  • 자연스러운 검사 지점은 속도가 0이 되는 궤적의 최저점
  • 로켓 방정식에서 이 최저점을 기본 수학 함수만으로 닫힌 형태로 표현할 수는 없음
    • 각주에서는 Lambert W가 필요하다고 설명함
  • 로그의 Taylor 급수 앞 몇 항만 쓰면 근사할 수 있음
    • 처음 두 항만 사용하면 문제가 2차 방정식으로 단순화됨
    • 고등학교 수준의 quadratic formula를 사용할 수 있음
    • 10초 턴 범위에서는 약 0.1% 이내 정확도를 기대할 수 있음

대체 2차 공식과 수치 안정성

  • Jim Storer의 코드에는 제곱근이 분자가 아니라 분모에 있는 형태가 등장함
  • 이는 일반적인 2차 공식이 아니라, 제곱근이 아래에 오는 대체 형태의 quadratic formula와 일치함
  • 이 대체 형태에는 중요한 수치적 장점이 있음
    • 지면 접촉을 감지한 뒤 실제 접촉 시간을 찾을 때도 Taylor 급수를 잘라 2차 방정식으로 근사함
    • 일반 형태는 2차항 계수가 0일 때 0으로 나누는 문제가 생김
    • 로켓 추력이 중력과 정확히 균형을 이루면 이런 상황이 발생함
    • 표면 근처에서 떠 있거나 천천히 내려오는 플레이어에게 흔할 수 있음
  • 추력이 중력에 가까우면 일반 형태는 분자에서 catastrophic cancellation이 생기고, 작은 분모가 오차를 키움
  • 대체 형태는 2차항이 0인 선형 방정식 상황에서도 잘 동작함
  • 1969년 고등학생이 이런 형태를 재유도했거나 배웠다는 점은 당시 환경을 고려하면 인상적임

실제 버그: 빠진 factor of two

  • 식을 직접 유도해 비교하자 Jim Storer의 코드와 거의 같았지만, 제곱근 내부 분모에 있어야 할 2가 빠져 있었음
  • 이 누락은 식을 유도하는 과정이나 컴퓨터에 입력하는 과정에서 생긴 단순 오류일 가능성이 있음
  • 당시 MACSYMA는 막 시작된 지 1년밖에 되지 않았고, 고등학교에서 사용할 수 있는 환경도 아니어서 유도는 종이와 연필로 해야 했음
  • 이 버그 때문에 최저점까지의 시간이 일관되게 과소추정
  • 코드는 두 가지 방식으로 이를 보정함
    • 0.05초를 추가함
    • 새롭고 더 가까운 위치에서 다시 추정함
  • 하지만 특정 suicide burn 상황에서는 이 보정 때문에 착륙 시점을 놓침
    • 첫 추정은 착륙선이 표면 위에서 아직 하강 중인 시점임
    • 두 번째 추정은 최저점을 지나 상승 중인 시점임
    • 두 시점 사이가 0.05초보다 짧아질 수 있음

수정 후 결과와 남는 한계

  • 누락된 factor of two를 추가하고 0.05초 보정을 제거하면 suicide burn 결과가 개선됨
  • 수정 후 최선의 suicide burn은 1.66 MPH 착륙 속도를 보임
    • 1 MPH 미만의 완벽한 착륙까지는 약 3/4 지점까지 가까워짐
  • 완벽하지 않은 이유는 여전히 Taylor 급수의 처음 두 항만 사용하기 때문임
  • 최저점이 표면 아래라고 판단한 뒤에는, 처음 표면에 닿는 시간을 다시 찾아야 함
    • 이 과정도 유사한 근사를 사용함
    • 추가 반복이 도움이 될 수 있음
  • 버그를 고친 상태에서는 시간을 과대추정하므로, 시간을 되돌아가야 할 수 있음
    • 이 경우 2차 방정식의 다른 해를 선택해야 할 수도 있음
  • 더 단순하게는 Taylor 급수 한 항만 써서 Newton’s method와 비슷한 방식으로 처리할 수 있음
  • 속도 크기가 특정 임계값 아래로 내려가면 멈추고, 그때의 고도로 착륙 여부를 판단하는 방법도 가능함
  • 다만 이런 변경은 코드를 더 복잡하게 만들며, 원래 게임은 이미 충분히 재미있게 플레이 가능했음

버그가 오래 남을 수 있었던 이유

  • 부드러운 착륙 자체는 가능함
    • 14번째 턴을 낮은 고도와 낮은 속도로 끝냄
    • 15번째 턴에서 낮은 추력을 사용함
    • 150초 이후 어딘가에서 착륙함
  • 문제가 되는 것은 약 148초에 끝나는 이론적 최대 추력 suicide burn
  • 전체적으로 이 코드는 1969년 PDP-8에서 18세 고등학생이 작성한 작업으로 매우 인상적임
  • 당시에는 고등학교에서 컴퓨터 과학을 가르치기 전이었고, Newton 방법으로 추정을 반복 개선하거나 catastrophic cancellation을 걱정하는 수치 계산 개념도 널리 알려져 있지 않았음
  • 버그가 거의 55년간 눈에 띄지 않은 이유는, 버그가 있어도 게임이 어렵고 재미있으며 부드러운 착륙도 가능했기 때문임
  • 단순히 이기는 것을 넘어 최적 전략을 찾으려는 시도가 작은 불일치를 이해하는 과정으로 이어짐

댓글과 토론

Hacker News 의견들
  • 2009년에 Jim Storer가 최초의 Lunar Lander 게임을 만든 사람이라는 걸 알아내고 인터뷰했으며, 이후 게임의 역사도 정리했음
    나중에 그가 소스 코드까지 제공해 줘서 정말 멋졌음
    https://technologizer.com/2009/07/19/lunar-lander/index.html
    가장 좋아하는 대목은 Storer가 “고등학교를 졸업한 뒤로는 그 게임을 다시 생각해 본 적이 없었다. 몇 달 전 누군가 이 일로 이메일을 보내기 전까지는, 내가 고등학교 때 만든 것 말고 다른 Lunar Lander 게임이 있다는 사실도 전혀 몰랐다”고 한 부분임
    • 이 글에 포함되어 영광임. Lander(1990) 를 원래 Windows 2.x용으로 만들었음
      1989년에 Lotus Notes 관련 일자리에 지원했을 때 면접관 Tim Halvorsen에게 Lander 게임을 보여줬고, 그는 “멋진데, Windows 3에서 돌려보자”고 했음
      처음엔 아직 출시 전인 Windows 3를 볼 수 있어서 좋다고 생각했지만, 곧 “Windows 3는 모든 걸 보호 모드에서 실행하니, 포인터가 범위를 벗어나면 즉시 죽을 것”이라며 테스트해 보자고 했음
      실행되는 내내 조마조마했지만 다행히 Lander는 죽지 않았고 Tim도 만족했으며, 결국 그 일을 얻어 커리어가 완전히 바뀌었음
    • Lunar Lander보다 앞선 기계식 착륙 게임도 있었음
      사진은 못 찾겠지만 기억으로는 이런 기계와 비슷했음
      https://content.invisioncic.com/r322239/monthly_10_2015/post...
      다만 지형과 구덩이가 있었고, 불이 들어온 구덩이에 착륙해야 했음. 우주선이 구덩이 중앙 버튼을 누르면 불이 꺼지고 다른 구덩이에 불이 들어왔고, 조준이 나쁘면 가장자리에 부딪혀 기울면서 실패했음
      다시 생각해 보니 조작은 UFO 캐처처럼 위에서 정렬한 뒤 “land”를 누르는 방식이었을 수도 있음. 예전 Disneyland Main Street Arcade에 있었음
    • 고등학교 때 프로그래밍을 배우면서 따라 만들어 보려 했던 초기 게임 중 하나가 Lunar Lander였음: Java 애플릿으로 만든 https://github.com/celwell/space-landing
  • 문제의 줄은 08.10으로 보임
    글에서 “1969년 고등학교 3학년으로서는 인상적”이라고 여러 번 말한 게 조금 이상했음. 우주 시대에 자란 기술 지향적인 사람들에게는 엄청난 영향을 줬을 것 같고, 예전 영화 October Sky도 떠오름
    원문 인터뷰에서 게임 제작자가 미적분에 능했다고 하니, 우주나 로켓에 관심과 재능이 있었다면 달 착륙 게임 프로그래밍을 시도하는 것도 자연스러워 보임
    [1]: https://www.cs.brandeis.edu/~storer/LunarLander/LunarLander/...
    • 1969년 미국에서 컴퓨터에 접근할 수 있던 고등학생은 대략 수백 명 수준이었고, 컴퓨터 활용 능력이 있던 학생은 더 적었음
      우주 시대가 영감을 줬을 수는 있지만, 당시 일반 대중에게 컴퓨터는 사실상 존재하지 않았고 소프트웨어 개발도 널리 알려진 직업이 아니었음. 미국에서 컴퓨터과학 전공이 생긴 것도 1962년이니, 1969년 고등학교 3학년이었다는 점은 꽤 주목할 만함
    • 1969년에 고등학생이었고, 미적분도 어느 정도 알았고, 프로그래밍에 매우 관심이 있었음
      큰 공대가 있는 꽤 큰 도시의 대형 고등학교에 다녔지만, 가장 큰 장벽은 컴퓨터 접근성이었음
      학교에는 원격 메인프레임에 연결된 텔레타이프가 있었고, 친구들과 밤에 쓸 수 있는 대학 컴퓨터 몇 대를 찾았지만 대부분 카드 리더와 라인 프린터뿐이었고 그래픽 단말은 전혀 없었음
      당시에는 기술, 관심, 접근성이 함께 갖춰진 조합이 꽤 드물었을 것임
    • 어떤 언어로 작성됐는지 궁금했는데, 이 게임 관련 글을 보니 FOCAL이라는 언어였음
      https://retro365.blog/2021/12/02/bits-from-my-personal-colle...
      FOCAL에 대한 Wikipedia:
      https://en.wikipedia.org/wiki/FOCAL_(programming_language)
    • 원글 작성자임. “1969년 고등학교 3학년으로서는 인상적”이라는 표현이 이상하게 느껴질 수 있다는 점은 이해하지만, 이 게임을 만들려면 필요한 게 꽤 많았음
      고등학교 물리에서 자유물체도부터 시작해 중력과 추력이라는 두 힘을 다루는 것까지는 물리 A를 받는 평균적인 학생도 할 수 있음
      하지만 중력은 중심까지의 거리, 즉 계속 바뀌는 값에 의존함. 120마일 상공에서 시작하지만 변화가 크지 않으니 상수로 근사할 수 있다는 걸 알아야 함
      추력이 연소율의 함수로 어떻게 작동하는지도 난해함. 연료 유량을 두 배로 하면 배기가스 속도도 두 배가 되는지, 이상기체법칙 PV=nRT에서 P와 T가 어떻게 바뀌는지 같은 문제가 생김
      그래서 물리학자인 아버지에게 물어보고, 로켓 엔진 특성과 치올콥스키 로켓 방정식을 찾아냈다면 그 자체로 고등학교 3학년에게는 인상적임
      속도에서 위치로 가려면 적분해야 하고, FLOG() 호출을 테일러 급수로 바꿔 항별 적분하는 발상을 평균적인 물리 A 학생이 할지는 모르겠음
      테일러 급수 항을 몇 개 써야 하는지, 수렴하는지 같은 세부도 까다로움. Jim이 이 미묘한 점을 생각했다면 대단하고, 그냥 5개 항이면 많아 보인다고 썼을 가능성도 있음
      달 근처 시뮬레이션은 됐다고 해도 지면 충돌을 어떻게 감지할지도 문제임. 고도가 0이 되는 해를 직접 풀기보다, 회전 중 정확히 한 번 생기는 속도 0 지점을 보는 방식은 꽤 창의적임
      원하는 델타-V를 주면 필요한 연료량을 구하려고 로켓 방정식을 뒤집는 것도 고등학교 수학과 미적분만으로는 막힘. 실제로는 Lambert W 같은 새 함수가 필요함
      결국 테일러 급수로 5차 다항식을 풀어야 하니 3, 4, 5차 항을 버려 2차식으로 만드는 결정을 해야 함. 평소 동역학 계산 때는 버리지 않았던 항을 여기서는 버려도 된다고 판단한 건 서로 다른 상황에 다른 근사 수준을 쓸 수 있음을 이해했다는 뜻이라 인상적임
      또한 이차방정식의 대체 형태를 어떻게든 쓴 걸 보면 그냥 찾아서 베낀 수준은 아니었을 수 있음
    • 최초의 Lunar Lander 게임으로 유명하지만, 정말 인상적인 부분은 사용된 수치해석 기법이었음
  • 1970년대 중반에 Adage 그래픽 단말용 2D 벡터 그래픽 달 착륙 게임을 만들었음
    수평으로 빠르게 진입한 뒤 LEM 측면 추진기와 주 엔진 버튼으로 감속해 수직 착륙해야 했고, 너무 빠르거나 연료가 떨어지면 분화구가 생겼으며, 착륙 품질에 따라 하나 이상의 미국 국기가 꽂혔음
    몇 년 전 소스 코드가 가치도 없고 재사용될 일도 없다고 생각해 유일한 사본을 버렸는데, 나중에 역사적으로 꽤 이른 그래픽 게임이었고 간단한 에뮬레이션으로 되살릴 수 있었음을 깨닫고 후회했음
    • “수평 착륙”이 아니라 “수직 착륙”을 말하려던 것임
  • 첫 프로그래밍 책에 이 게임의 BASIC 버전이 있었지만 제대로 실행하지 못했음
    25년 뒤 다시 보니 버그가 말도 안 되게 많고 로직도 “440 IF GOTO 450”처럼 꼬여 있어 놀랐음
    결국 어른이 된 뒤 다시 작성했지만 [1], 어린 시절의 나는 성공할 가능성이 없었음. 지금도 그 잊힌 스페인 출판사 내부에서 거의 작동하던 코드가 어떻게 최종판 같은 모습으로 변했는지 궁금함
    [1] https://7c0h.com/blog/new/moon_landing_in_basic.html
    • “가능성이 없었다”는 말로는 부족할 정도임
      이런 BASIC 코드는 1960~70년대에 뿌리가 있었고, 당시 코드가 실리던 인쇄 잡지와 코드 모음집에서는 편집자가 강한 권한을 가졌음
      소스 코드를 한 글자도 바꾸지 않고 그대로 실어야 한다는 인식이 약해서, 편집자들이 “명백한” 오타나 편집상 판단이라고 생각하며 소스 코드를 “신중하게” 고치곤 했음
      1980년대부터 업계 전반의 개선이 시작되고 인쇄물에서 소스 코드를 건드리면 안 된다는 인식이 퍼지기까지 이 교훈은 천천히, 고통스럽게 학습됐음
      이런 흐름이 BBS의 부상을 촉진하고, 인쇄 매체가 소스 코드 배포를 쥐고 있던 힘을 약화시켰는지도 궁금함. 인쇄 매체 권력자들이 “자기” 콘텐츠 일부에 대해 외부인이 절대적 통제를 갖는 걸 더 열어줬다면 다른 역사가 가능했을지도 모름
      어릴 때는 어른의 도움 없이 학교와 지역 도서관의 프로그래밍 책 몇 권만 보고 코딩을 시작했는데, 손으로 입력한 수많은 프로그램이 비슷하게 오류투성이였음에도 계속 코딩을 붙잡고 있었던 게 신기할 정도임
    • 재미있게 읽었음. 어릴 때 C64가 게임 관련 이미지를 코드 몇 줄만으로 “마법처럼” 로드하는 걸 보며, 그 이미지가 어딘가 내부에 그냥 들어 있다고 생각한 적이 있음
      “440 IF GOTO 450” 같은 꼬인 로직에 대해 조금 덧붙이면, 책의 일부 코드는 분명 정리가 필요하지만 당시 가정용 컴퓨터의 일반적인 BASIC은 줄 번호만 다루고 분기문도 매우 제한적이었을 가능성이 큼
      사용한 BASIC은 구조적 프로그래밍을 지원하는 듯한데, 당시 가정용 컴퓨터에서는 매우 드물었음. 1984년 C64 잡지가 구조적 프로그래밍의 놀라움을 독자에게 소개하는 긴 연재를 최소 3호에 걸쳐 실었을 정도임
      IF 문의 제약이 심해서 GOTO를 쓰는 어셈블리식 조건 분기가 매우 흔하고 사실상 필요했음
      IF 중첩은 불가능했고, 여러 IF를 조합하려면 선택되지 않은 부분을 점프해서 건너뛰어야 했음. Commodore/C64 BASIC, 사실상 Microsoft BASIC에는 ELSE조차 없어서 보통 부정 조건과 점프로 ELSE 분기를 흉내 냈음
      C64 BASIC에는 같은 줄의 다른 문도 THEN에 속하는 특이한 동작이 있었음. 예를 들어 10 IF A=1 THEN PRINT “FOO” : PRINT “BAR”는 A=1일 때 FOO BAR를 출력하고, 아니면 아무것도 출력하지 않음
      물론 제한된 한 줄에 문장을 다 넣을 수 있을 때만 가능했음. 다른 BASIC 방언은 PRINT “BAR”를 ELSE 밖으로 보기도 해서 문법적으로는 더 깔끔하지만, 방언이 제공하는 기능에 따라 덜 편할 수 있었음
      오늘날 당연하게 여기는 편의성과 엄격함은 없었음. C64 BASIC은 구현상의 산물 같은 기묘한 특성이 많아 특히 “지저분하게” 느껴졌음. 예컨대 모든 함수는 실제로 필요 없더라도 인자를 가져야 해서, 남은 메모리를 출력하려면 의미 없는 ?FRE(123) 같은 식으로 써야 했음
    • 아마 편집 과정의 복사/붙여넣기 오류, 마감, 품질 보증 부재가 뒤섞인 결과였을 것임
  • 연료 최적의 부드러운 착륙 전략은 “suicide burn”의 정확한 형태에는 맞지 않아 무시된 것 같지만, t=70초에 164.31426784 lbs/second를 입력하고 이후 200 lbs/second 입력 중 하나를 199.99999999 lbs/second로 바꾸는 방식일 것 같음
    199.99999999를 더 일찍 “플레이”할수록 좋으니, 완전 탐색으로 부드러운 착륙이 되는 가장 이른 입력을 고르면 됨
    • 버그의 본질은 착륙선이 표면에 닿은 시점을 찾는 데 어려움이 있다는 것임
      게임이 착륙을 인식하려면 약 0.05초 동안 고도가 0보다 작아야 함. 그 시간 동안 추력이 200이나 199라면, 고도가 그만큼 오래 음수가 되려면 고도 0 지점에서 속도가 1MPH보다 커야 함
      버그를 고쳐도 코드는 여전히 최저점을 근사할 뿐임. 착륙을 감지한 뒤에도 실제 착륙 시각, 즉 속도가 아니라 고도가 0이 되는 시점을 계산해야 하고, 이것도 근사를 사용함
      그래서 시간은 조금 어긋날 수 있음. 마지막 시간 단계에서 200이나 199로 연소 중이면 가속도가 커서 아주 작은 시간 오차도 큰 속도 오차로 이어짐
      대신 10 lbs/sec 정도로 연소하면 0.08초쯤 어긋나도 속도 변화가 크지 않음
  • 순진하게 작성한다면 특별한 공식을 쓰지 않고 매 프레임 새 질량 기준으로 질량과 가속도를 다시 계산하고, 각 프레임 경계에서 지면과의 교차를 계산했을 것임
    프레임률이 낮을수록 이 방식의 정확도가 떨어진다는 뜻인지, 아니면 실제 방정식을 쓰는 재미 때문인지 궁금함
    원래 프레임률에서 두 방식의 차이가 얼마나 체감됐을지도 궁금함
    • 생각하는 의미의 그래픽 출력이나 프레임률은 없었음. 출력은 이런 식으로 인쇄되어 나왔을 것임
      https://www.cs.brandeis.edu/~storer/LunarLander/LunarLander/...
      질량과 가속도를 10초 간격으로만 갱신하면 엄청나게 부정확해짐
    • 원글 작성자임. 나도 그 순진한 방식을 예상했고, 글에서는 오일러 방법으로 설명했음
      물리적 정확도 측면에서는 특히 표면 근처에서 연료 연소율이 높으면 질량이 꽤 크게 변함. 하지만 게임의 난이도나 재미, 플레이어 전략 측면에서는 큰 차이가 없을 것 같음
      실제로 BASIC computer games 책의 다른 달 착륙 시뮬레이션 중 하나는 그런 순진한 접근을 쓰는 것으로 보임
      10초가 너무 길다면 사용자 인터페이스의 한 턴은 그대로 10초로 두고, 내부적으로는 각 턴을 1초짜리 시간 단계 10개처럼 더 잘게 나눌 수 있음
      기존 게임도 특정 부분에서는 실제로 그렇게 하므로, 물리 시뮬레이션이 항상 10초 전체가 아니라 임의의 시간 S를 입력받도록 되어 있음
  • 1960년대에 PDP-1에서 Spacewar를 해본 기억 때문에 잠시 헷갈렸고, 착륙 게임도 있었다고 잘못 기억했음
    하지만 착륙 게임은 없었고, Storer가 최초였음. 관련 흥미로운 역사는 여기 있음
    https://www.acriticalhit.com/moonlander-one-giant-leap-for-g...
  • “로켓 방정식 때문에 suicide burn이 최적이 된다”는 표현은 엄밀히는 맞지 않음
    연료를 태우며 기체가 가벼워지는 효과를 계산하지 않아도, 즉 여기서 로켓 방정식이 하는 일을 빼도 suicide burn은 여전히 최적임
    진짜 이유는 suicide burn이 중력 손실을 최소화하기 때문임
    https://en.wikipedia.org/wiki/Gravity_loss
    • 원글 작성자임. 맞음, 단순화해서 말했음
      의도는 동역학에 로켓 방정식과 중력이라는 두 부분이 있고, 이 둘이 선형으로 더해진다는 것이었음. 중력 때문에 생긴 추가 속도는 로켓 방정식의 델타-V를 늘려 없애야 함
      중력 델타-V는 중력가속도 곱하기 시간이므로 시간을 최소화해야 함
      놀랍게도 로켓 방정식에서는 시간이 얼마나 걸리는지, 어떤 연소 순서를 쓰는지, 일정한 속도로 계속 태우는지 짧고 강한 분사로 태우는지가 중요하지 않음
      그래서 최소 연료로 속도 0 착륙을 하려면 가능한 가장 짧은 시간에 착륙하면 됨
  • PDP-11용인 것 같은 천공 테이프 롤을 아직 갖고 있고, 거기에 “Lunar Lander”라고 적혀 있는데 누구에게 줘야 할지 모르겠음
    • Internet Archive나 Computer History Museum이 좋을 듯함. 관심 가질 만한 곳 추천은 @textfiles에게 물어보면 됨
  • 꽤 놀라움. 1970년대 중반 누군가 Wang 2200 BASIC으로 포팅한 뒤 이 게임을 해본 기억이 있음
    직접 착륙 방법을 알아내지는 못했지만, 처음 몇 턴은 관성으로 가다가 최대 추력을 거는 기술을 누군가 보여줬던 건 기억남. 당시에는 “suicide burn”이라는 용어는 기억나지 않음. 아마 Kerbal Space Program이 유명해진 뒤 나중에 생긴 말일 수도 있음
    1970년대 중반 Berkeley의 Lawrence Hall of Science에서도 단말 몇 대에서 이 달 착륙 게임이 돌아가던 기억이 있음. 어떤 컴퓨터에서 실행 중이었는지는 모름
    이 프로그램의 소스 코드는 본 적이 없고, 수학이 이렇게 정교한지도 전혀 몰랐음. 당시에는 너무 어려서 이해하지 못했을 것이고, 솔직히 지금도 이해할 수 있을지는 모르겠음
    • 1973년 초 Lawrence에서 아마 ADM-3 단말로 Lunar Lander를 할 수 있었던 기억이 있음. 보통 남자 십대들이 몰려 있었음
      게임용 키오스크 모드의 한 “기능”은 타이밍을 잘 맞춘 Ctrl-C로 키오스크 모드를 빠져나가 다른 게임을 할 수 있었다는 점임
      우연이었을까, 아니면 초기 해커들에게 던져진 미끼였을까?