괴토

무엇이 좋은 퍼즐을 만드는가?

지금 Lara Croft GO와 Monument Valley 2가 모바일 스토어에서 무료 이벤트를 하고 있다. 두 게임 모두 수준 높은 퀄리티를 자랑하는 퍼즐 게임이다. 게임을 플레이하면서 이런 퍼즐게임은 어떻게 만드는 것인지, 레벨 디자인은 어떻게 하는지 궁금했다.

내가 가장 좋아하는 유튜브 채널 중 하나인 Game maker’s toolkit의 Mark brown이 플레이어가 잘 만들어진 퍼즐을 풀 때 어떤 요소가 있었는지 본인만의 방식으로 풀어두었길래 정리해 보았다.

1. Mechanics - 규칙과 제약

Mechanics은 게임이 어떻게 돌아가는지 규정하는 규칙과 제약을 의미한다. 이 mechanics으로 퍼즐을 만들 수 있다. 따라서 mechanics가 퍼즐의 수와 난이도를 결정한다. mechanics을 증강시키기 위해 다양한 요소를 이용할 수 있는데, 이런 요소는 임시적일 수도 있고, 계속 mechanics에 포함될 수도 있다.

2. Catch - 문제

Catch는 얼핏 보면 해결하기 불가능해 보이는 문제를 의미한다. 플레이어는 퍼즐 풀기를 시도하면서 몇 가지 액션 조합을 사용한다. 이때 이 액션 조합들이 논리적으로 충돌해 목표까지 갈 수 없다는 것을 깨달았을 때 catch를 발견한다. 이 때 플레이어는 액션 조합의 순서를 바꾸거나 해결 방법을 완전히 바꾸는 식으로 다시 접근한다.

3. Revelation - 발견

플레이어는 catch를 해결하기 위해서 생각의 틀을 깨려고 하거나 mechanics에 대해 다시 고민한다. 플레이어가 해결책을 찾아낸 순간이 Revelation이다. 이 때 플레이어는 스스로 똑똑하다고 느낄 수 있다(이게 퍼즐 게임의 실질적인 보상이라고 생각한다). 이렇게 찾아낸 해결책은 플레이어의 무기가 되고 다음 문제를 풀 때 사용할 수 있게 된다.

4. Assumption - 추정

Assumption 이란 플레이어가 이렇게 하면 문제를 풀 수 있겠지하고 예상하는 것이다. 퍼즐은 플레이어가 assumption 을 통해 catch를

Out of the box

나는 제품이나 라이브러리의 태그라인을 읽을 때 out of the box란 구문이 보이면 더 관심을 갖는다. Out of the box란 따로 설정없이 바로 사용할 수 있다는 뜻이다. 비슷한 단어로 automagically도 있다. 이런 태그라인을 가진 것들은 어떻게 동작하는지 몰라도 사용자의 목적에 도달하도록 해준다.

사용자는 학습을 통해 무의식적으로 물건의 멘탈모델을 그린다. 멘탈모델은 추상적일수도 있고 구체적일수도 있다. 멘탈모델이 실제 제품과 비슷할수록 사용자는 제품을 더 이해한 것이고, 제품을 더 활용할 수 있다. 멘탈모델이 구체적이여야 물건을 제대로 사용할 수 있다면, 사용자는 많은 학습을 필요로 한다. 이게 진입장벽이다. 물건을 사용할 때 설정이 필요하다는 것은 사용자의 멘탈모델에 물건의 부분적인 원리가 있어야 한다는 뜻이다.

Out of the box 제품들은 사용하기 쉽다. 쉬운만큼 심플하다. 그래서 만들기도 쉬워보인다. 하지만 심플한 제품도 내부는 매우 복잡할 수 있다. 단순해 보이도록 만드는 것은 매우 어렵다. 기능만 가진 제품과 그걸 잘 포장한 제품이 시장에서 어떤 평가를 받았는지 우리는 이미 잘 알고 있다.

Onkalo

쿠푸왕과 진시황이 그들의 무덤을 지으면서 두려워했던 것들 중 하나는 도굴꾼의 침입이다. 오늘날에도 누군가의 침입을 원하지 않는 새로운 건축물이 만들어지고 있다. 핀란드에 있는 방사능 폐기물 저장소, 온칼로(Onkalo)다.

온칼로는 지질학적으로 18억년동안 안정적인 곳 지하 500m 깊이에 약 100년동안 방사능 폐기물을 저장한 후 닫힐 예정이다. 이런 폐기물들은 10만년이 지나야 위험성이 사라진다. 온칼로의 목적은 이 10만년동안 인간이나 다른 생명체로부터 폐기물을 안전하게 격리시키는 것이다. 때문에 온칼로는 폐쇄된 후 완전히 묻힐 예정이다. 온칼로가 지상에 노출된다면 지구는 더 이상 생명체가 살 수 없는 행성이 되고 말 것이다.

온칼로는 긴 시간이 지나면 아예 사람들에게 잊혀질 것이다. 그러나 외부인의 침입이 없으리라고는 장담할 수 없다. 먼 훗날 누군가 온칼로를 발견했다면, 이것이 무엇인지 이해할 수 있을까? 이들에게 이 곳은 위험한 장소니 돌아가라고 어떻게 경고할 수 있을까? 당신이 하려고 하는 그 행동이 돌이킬 수 없는 끔찍한 결과를 만들어 낼 것이라고 어떻게 알릴 수 있을까? 그들이 이 경고의 진심을 의심없이 받아들이도록 하려면 어떤 방법이 필요할까?

글이나 그림을 남겨 경고하는 방법은 통하지 않는다. 언어도 다를 것이고 문자도 다를 것이다. 지금과 비교해서 얼마나 문명이 발달해 있을지 알 수 없다. 어떤 경고나 표식이 이들에게 어떤 영향을 미칠지도 알 수 없다. 접근을 두려워하게 만들 수 있겠지만, 도리어 호기심을 불러일으킬 수도 있다. 발견자는 인류가 아닌 새로운 지적 생명체 일 수도 있다. 모든 생명체가 이해할 수 있는 보편적인 의사소통 방식은 존재할까?

10만년은 정말 긴 시간이다.

Let's encrypt 클라이언트 직접 구현하기

일반적으로 Let’s encrypt로부터 SSL 인증서를 발급받기 위해 certbot처럼 이미 구현된 클라이언트를 이용한다. 이런 클라이언트들은 잘 만들어졌고 사용하기 편리하지만 동작을 내가 원하는대로 고칠 수 없다. Let’s encrypt의 클라이언트를 직접 구현해보면서 ACME v2 프로토콜의 동작 흐름을 살펴보았다. 클라이언트가 인증서를 얻기까지는 다음과 같은 과정이 필요하다.

  1. URL 목록 가져오기
  2. 초기 nonce 값 얻기
  3. 계정 생성 (Account 생성)
  4. 인증서 주문 (Order 생성)
  5. 도메인 권한 증명 (Authorization의 Challenge 만족시키기)
  6. 주문 마무리
  7. 인증서 다운로드

1. URL 목록 가져오기

먼저 ACME 서버의 Directory 객체를 GET 호출하는 것으로 시작한다. Directory는 이후 과정에서 호출해야하는 URL들을 담고 있다. Let’s encrypt의 directory를 호출하는 주소는 https://acme-v02.api.letsencrypt.org/directory 다. Let’s encrypt는 클라이언트를 테스트하는 용도로 사용할 수 있도록 staging 주소도 제공한다.

1
2
3
4
5
{
"newNonce": string
"newAccount": string
"newOrder": string
}
  • "newNonce"는 2번 과정에 사용한다.
  • "newAccount"는 3번 과정에 사용한다.
  • "newOrder"는 4번 과정에 사용한다.

2. 초기 nonce 값 얻기

ACME 프로토콜에서 Directory 요청(1번 과정)과 newNonce 요청(2번 과정)을 제외한 모든 요청은 JWS header에 nonce 값이 있어야 한다. 리플레이 공격을 막기위해서다. JWS header가 무엇인지는 바로 아래에서 알아보자. 첫 nonce는 newNonce의 GET 호출 응답의 'replay-

결제 서비스 선택하기

서비스에 결제 기능을 붙히기 위해 어느 결제 서비스가 적절할 지 찾아봤다. 해외 카드를 받을 수 있어야 하기 때문에 국내 결제 서비스는 고려도 하지 않았다. 요구사항은 이렇다.

  • 한국 계좌나 호주 계좌로 송금할 수 있어야 한다
  • 호주 계정 생성시 ID를 필수로 받지 않아야 한다. 나에겐 호주 계좌는 있지만, ID가 없다.
  • 정기 결제를 지원해야 한다. 직접 구현해 본 경험은 있어서 만드려면 만들 순 있겠지만, 이미 기능을 제공한다면 그걸 그냥 이용하는게 좋다.
  • 수수료가 낮을수록 좋다. 돈을 못 벌어도 요금을 지불해야하는 Chargebee같은 서비스는 제외.
  • UI를 커스터마이징할 수 있으면 좋다. 완벽히 못한다면 최대한 할 수 있는게 좋다.

Paypal

수수료: 국내 결제일 때 2.9% + $0.30, 국외 결제일 때 4.4% + $0.30

국내 결제라는 말은 내 페이팔 계정과 결제 카드가 같은 국가여야 저 수수료라는 의미다.한국 내 결제가 아니다. 페이팔은 솔루션의 종류가 많다. 어느 것을 적용해야 적절한 지 보고 선택해야 하는데, 이게 너무 귀찮다. 사용자가 꼭 페이팔 계정이 있지 않아도 된다. 하지만 정기 결제 기능을 사용하려면 사용자가 반드시 paypal 유저여야 하는 것 같다. 문서만 봤을땐 RESTful API도 제공하는데, 페이팔이 제공하고 있는 데모는 전부 결제시 paypal hosted page를 통한다. 결국 UI는 커스터마이징할 수 없다.

Stripe

수수료: 2.9% + $0.30

지원하는 국가의 수가 적다. 하지만 호주 계정을 만들 때 ID를 받지 않는다. UI 커스터마이징도 거의 완벽하게 가능하다. 모든 것이 개발자 친화적이다. 문서가 매우 잘 되어있고, SDK도 깔끔하다. 결제 기능을 연동할 때 어떤 흐름으로 개발하는지 잘 알고 있는 것 같다.

Billsby

수수료: $50000까지는 무료. 이후부터 0.8%

신생 회사다. 오픈 전에 Product hunt에서 보고 뉴스레터를 등록했더니, 최근 베타 코드가 날아와서 이것도 고려해봤다. UI

타자기 치는 원숭이

수 많은 행성들 가운데 지구에 생명체가 생긴 이유는 이 행성이 뭘 잘 했기 때문이 아니다. 우주에는 무수히 많은 경우의 수가 존재한다. 그 중 일부가 우연히 생명을 탄생시킬 수 있는 환경에 있었고, 지구는 그 중 하나일 뿐이다. 우리 인류가 과거에 무언가 열심히 노력했기 때문에 높은 지능을 가지도록 진화하게 된 것이 아니다. 현생 인류 이전까지 수 많은 돌연변이가 있었고, 높은 지능을 가진 돌연변이가 환경에 더 잘 적응할 수 있었다. 우리는 긴 시간동안 지능 향상 돌연변이가 축적된 결과다.

이런 생각은 백 년 전 ‘무한 원숭이 정리’로 처음 제시되었다. 원숭이에게 타자기를 주고 아무거나 입력하게 시킬 때, 무한한 수의 원숭이와 무한한 시간이 주어진다면 프랑스 국립 박물관의 모든 책을 정확하게 찍어낼 것임이 거의 확실하다는 정리다. 여기서 ‘거의 확실하다’는 확률의 극한 값이 100%라는 의미다.

‘무한 원숭이 정리’에서 첫 책을 찍어낸 원숭이가 또 다른 책을 찍어낼 확률이 다른 원숭이보다 높을까? 아니다. 최근 세렌디피티(우연한 과학적 발견)의 극대화를 위해 실험실 예산을 어떻게 배분해야하는지를 탐구하는 연구가 있었다. 연구는 모든 실험실에 예산을 골고루 분배했을 때 세렌디피티가 가장 높아진다는 결과를 보여주었다. 무작위로 랜덤하게 배분하는 방법도 답이 아니였고, 과거 성과가 좋은 실험실에 집중해서 배분하는 방법도 답이 아니였다.

시도의 횟수가 무한하면 아주 작은 확률이라도 반드시 발생한다. 시도의 횟수가 적당히만 많아도 평범하지 않은 결과가 발생한다. 그럼에도 불구하고 우리는 운을 감지하지 못한다. 결과의 원인을 계속 분석하며 패턴을 찾으려고 한다.

모든 것은 만들어진 것이다

나사에서 1966년 발행한 Assessing Technology Transfer에는 이런 구절이 있다.

수명의 관점에서 인류의 마지막 5만년을 보면, 진보의 속도를 쉽게 알 수 있다. 5만년의 시간은 800명의 수명으로 환산된다. 그러나 이 800명 중 650명은 동굴 또는 그보다 못한 곳에서 살았고, 마지막 70명만이 타인과 효과적으로 소통할 수 있는 수단을 가졌으며, 마지막 6명만이 인쇄물을 보거나 온도를 측정할 수 있었고, 마지막 4명만이 시간을 정확히 잴 수 있었고, 마지막 2명만이 전기모터를 사용했다. 우리의 물질 세계를 구성하는 대부분의 것들은 마지막 800번째 사람의 수명 내에 개발된 것들이다.

언어와 문자, 종교, 이념과 사상, 경제 체제, 사회 시스템, 지명과 도로와 건물, 사람의 생애주기까지 모든 것들이 의도했든 하지 않았든 우리와 같은 누군가가 만들어낸 것이다. 그것도 아주 최근에 만든 것들이다. 지금까지 우리는 시간의 길이를 과장해서 생각했기 때문에 이런 것들이 전통이 있고, 절대적인 가치라고 생각한다. 14세기 고려 말기를 살던 사람은 지금 우리와 매우 먼 것처럼 느껴지지만, 실제로는 아주 작은 시간적 차이 때문에 만나지 못했다. 하지만 이들과 우리는 사는 방식과 환경이 매우 다른데, 이것은 우리를 둘러싼 모든 것들이 생긴지 얼마 되지 않았음을 보여주는 증거다.

인류의 역사는 아직 무척 짧다. 인류 최초의 건물은 약 12000년 전에 세워졌는데, 지금 우리가 사용하는 달력의 연도에 10000을 더하면 인류 진보의 시간과 맞아 떨어진다. 올해를 2020이 아니라 12020년으로 보면 인류의 역사에서 지금 우리가 어디 쯤 있는지 조금 더 알기 쉽다. 자연적으로 존재했고, 지금까지 항상 있어왔으며, 영원히 변하지 않는 것은 없다. 우리가 당연하다 여겼던 모든 것들은 결국 우리가 만든 것이다. 그럼에도 우리의 생각과 행동은 이 틀에 갖혀있다.

확률과 인간의 마음

Google play music과 같은 음악 재생 프로그램에는 당신이 여태껏 들었던 음악을 기반으로 재생목록을 만들어주는 기능이 있다. Google play music의 경우 이 기능을 I’m feeling lucky mix라고 한다. 만약 앞서 들었던 음악이 없는 상태에서 이 기능을 이용하면 어떻게 될까? 프로그램은 완전히 랜덤하게 음악을 들려줄 수 밖에 없다. 첫 음악으로 재즈가 나왔다고 하자. 수동으로 음악을 선택하지 않고 계속 I’m feeling lucky mix로만 음악을 듣는다면 점점 재즈만 나올 확률이 높아질 것이다. 당신의 취향과 무관하게 말이다!

아주 오래전에 같은 내용의 글을 이전 블로그에 올렸었다. 지금 보면 이것은 카오스 이론에 대한 이야기다. 지프의 법칙과는 연관 짓기 어렵다. 하지만 조금 더 확장해서 생각해 볼 가치가 있는 현상이다.

로또 추첨은 매 회차가 독립시행이다. 앞선 회차의 결과들이 다음 회차에 전혀 영향을 미치지 않는다. 지금까지 36번 공이 많이 뽑혔다고 해서 이번주 토요일에 36이 또 나올 확률이 높아지지 않는다. 우리 주변에도 로또처럼 독립시행인 사건이 많다. 하지만 독립시행 사건에 사람의 마음이 개입하면서 종속시행이 된다. 로또로 치자면 36이 나올수록 36이 또 나올 확률이 점점 높아지게 변한다.

근근이 매출을 유지하는 식당이 방송에 나온 것도 아닌데 갑자기 손님이 많아진다. 손님의 방문이 독립시행에서 종속시행으로 변하는 순간이다. 이전에 왔다간 손님 중 누군가가 다른 사람에게 영향력을 미쳤기 때문이다. 해외여행을 갈 때, 맛집을 검색해서 가보면 온통 한국인 뿐이다. 누군가 우연히 아무곳이나 들렀고 자신의 블로그에 글을 남겼다. 사람들은 식당을 검색하고 이 글을 읽고 또 글을 남긴다.

주식차트도 비슷하다. 과거의 데이터는 미래 주가를 예측하는데에 아무런 도움이 되지 못한다. 하지만 누군가가 ‘이런 패턴일 때는 주가가 떨어진다’라고 한다면, 실제로 그런 패턴이 나타났을 때 사람들은 주가가 떨어질 것이라고 생각해서 주

파레토 법칙

흔히 80/20의 법칙이라고도 불리는 파레토 법칙은 결과의 80%는 원인의 20%로부터 일어나는 현상을 가리킨다. 파레토 법칙은 분야를 막론하고 거의 모든 곳에서 매우 다양한 스케일로 존재한다. 소프트웨어도 예외는 아니다. 제품 사용 시간의 80%는 전체 기능의 가장 핵심적인 20%에 집중되어 있다.

나머지 80% 기능을 포기해도 괜찮다는 이야기가 아니다. 이 80%의 기능이 없다면 온전한 제품이라 부를 수 없다. 그러나 우리는 자원이 한정된 환경에 있기 때문에 효율을 고려해야한다. 핵심 기능은 조금만 개선되어도 사용자가 쉽게 눈치채는 반면, 나머지 기능은 갑자기 없어져도 잘 모른다. 잘 쓰이지도 않는 하위 80%의 기능을 개선하기보단 핵심적인 20%에 우리의 시간과 노력을 쏟는 게 낫다.

사이드 프로젝트는 극단적인 자원 부족 환경에 놓여있다. 처음부터 모든 사용자를 만족시키려고 다양한 선택지를 제공하다가는 아무것도 완성하지 못한다. 20%의 핵심 기능만 제공하는 초창기 제품은 거의 프로토타입에 가까울 수도 있을 것이다. 그러나 조금 부족하더라도 계속해서 제품을 개선하는 모습을 보여준다면 사용자들은 당장 나머지 80% 기능이 없더라도 같이 만들어나간다는 느낌을 줄 수 있을지도 모른다.

가능한 작게 만들자

해커톤이 좀 익숙해지고 나서는 참가할 때마다 팀원들에게 최대한 작게 만들자고 제안한다. 욕심을 버리고 현실적으로 생각해서 뭐라도 데모 때 보여줄 수 있는 걸 완성하려면 이 방법 밖에 없다. 눈속임으로 동작하는 것처럼 보이는게 아니라 정말로 구현하는 것이기 때문에 예상치 못한 복병이 항상 숨어있다. 그래서 시간이 부족하다. 시간이 남는 경우는 거의 없다.

작게 만들자는 제안이 수용되지 않았는데 뭔가 완성된 경우는 없었다. 회의와 토론에 시간을 전부 쓰기 때문이다. 작게 만들기로 약속했더라도 얼마나 작게 만들 것인지는 조금씩 생각이 다른데, 이런 약속이 없다면 구현은 뒷전이고 정말 행사가 끝날 때까지 회의만 한다.

모든 것이 익숙하더라도 단 하나의 챌린지가 있으면 일이 어떻게 될 지 모른다. 해커톤에서는 모든 것이 챌린지다. 처음 보는 사람들끼리 만나 커뮤니케이션이 쉽지 않다. 팀원들의 기술 스택도 일정하지 않다. 마감까지 시간도 짧다. 환경도 열악하다. 와이파이 안 터지면 정말 망한다. 지금 만들고 있는 사이드 프로젝트도 정말 단 하나의 기능만 한다. 하지만 그 하나의 기능이 나에겐 상당히 도전적이다. 그래서 기술적인 문제 때문에 생각보다도 더 오래걸리고 있다.

완벽하고자 하는 욕심을 버려야한다. 내가 표현하고 싶은 가장 핵심적인 부분에만 집중하자. 제품을 더 좋게 할 수 있는 아이디어가 많지만, 핵심 가치에 직접적인 도움이 되지 않는다면 잠시 내려놓아야 한다.