• 2009-10-08

    Company Capitalism

    [caption id="attachment_2253" align="alignnone" width="300" caption="오늘 업어온 따끈따끈한 노랑둥이"]오늘 업어온 따끈따끈한 노랑둥이[/caption]

    EBS 다큐멘터리 "신뢰가 자본이다" 에 따르면, 국부의 80%가 사회적 자본(Social Capitalism) - 구성원들이 상호 신뢰를 통해 자발적이며 솔직하게 협력해서 이루어내는 능력-이라고 한다. 그렇다면 여러 파트와 유관 부서로 구성된 게임 개발 프로젝트도 비슷한 규칙이 적용되지 않을까 하는 생각이 들었다.

    예를 들면 믿음직스럽지 못한 입코딩 개발자가 와서 "이러 저러한 이유로 A안으로 가야 한다"라고 말하면, 금방 A안의 약점을 머리속으로 리스트업해서 "그 안은 이러 저러한 문제가 있는데 생각은 해봤으며 대안이 있느냐?" 라든지  "이상적인 경우에는 맞는 이야기지만 현실적으로 어렵다"라고 하다가, 소모적인 논쟁 또는 감정 싸움이 발생하거나 어색한 침묵이 흐르다가 결국 아무 것도 해결되지 않고 서로 뒤돌아서서 욕만 하는 걸로 끝나는 경우가 종종 있다.

    반명 전적으로 믿고 있는 개발자가 비슷한 이야기를 꺼냈다면, 열의 아홉은 그가 내가 지금 막 떠올린 약점조차도 이미 파악했을 것이며, 문제가 생기더라도 어떻게든 해결할 것이라는 암묵적 신뢰 속에 동의하지 않을까. 후자 쪽이 빠른 의사 결정을 통해 신속하게 문제가 해결될 것이라는 것은 명백하다.

    보통 게임 개발은 실력보다는 커뮤니케이션이라고 하는게 아마 이런 이야기를 두루두루 일컫는 말일 게다. 싸가지없는 천재 개발자보다는 평범해도 성실한 개발자를 리더들이 선호하는 이유도 비슷할테고. (그래도 난 성실한 천재 개발자가 좋다. 후후)

    자. 여기까지 동의하신다면, 조직의 리더들은 무엇을 해야 할까? 를 상상해보자.

    보통 A급 개발자들을 케어하고 B/C급 개발자들은 폭주할 때까지 안심하고 버려두는 경우가 많을 것이다. 다만 개개인의 역량의 높낮이나 멋진 프로세스, 성과에 따른 인센티브, 근태 체크보다 중요한 것이 있지 않을까. 예를 들면, 어디에서 신뢰의 고리가 깨졌으며, 그 고리를 잇기 위해서는 무엇을 해야 하는가? 에 대한 고민 말이다. 자주 신뢰를 깨뜨리는 개발자는 능력을 떠나서 빨리 조치를 취해야 하며, 실무는 물론 팀 내외적으로 연결 고리 역할에 충실한 사람들에게 더 많은 유무형의 인센티브를 줘야 할 것이다. 이런 이유로 최근 몇 년째 중재자 - 네트워크 이론에서 허브의 역할을 하는 - 의 도입에 대해서 강력하게 주창하고 있는데,  '현실적인 이유로' 잘 먹혀들지 않고 있는게 사실이다. ^^;;

    요즘 이 허브의 역할에 대해서 개인적으로 연구 중인데, 조만간 아래와 같은 이야기들을 잘 풀어서 정리해보고 싶다.

    • 강력한 신뢰 네트워크를 가진 허브들이 흔들릴 때가 바로 조직의 위기이다..
    • 어떤 조직을 흔들려면 허브를 공격하면 된다..
    • 튼튼한 팀을 꾸리거나 재정비할 때에는 기존의 허브를 공략한 후, 강력한 대형 허브를 하나 더 얻는다..
    • 불만쟁이 허브는 재빨리 제거한다..

    이렇게 쓰다 보니 웬지 내가 그런 허브인 듯 하지만, 사실은 그냥 거대 허브 몇 개에 빨대를 꽂고 연명하는 말단 이파리(leaf)에 불과한 개발자일 뿐이다. 헷헷.

  • 2009-10-07

    Ray the limited edition

    [caption id="attachment_2249" align="alignnone" width="300" caption="분노의 그레이"]분노의 그레이[/caption]

    I'm back again!

    최근 건강 문제도 있고 자체 검열도 많아져서 절필 비슷한 상태가 꽤 오래 지속되었다. 다행히 많은 분들의 관심과 배려로, 기본 스탯은 꽤 회복된 상태이지만, 요양 라이프는 더 지속될 전망이다. 여기 저기가 아프고 쑤셔서 다소 민감해진 데다가, 이제 하루만 출근만 해도 체력적으로 버거운 상태에 도달, 고민 끝에 조만간 1-2개월 정도 푹 쉴 계획이다. 최근 과로로 의식불명에 빠진 개발자가 지인의 친구 회사분이든지, 또 지병으로 젊은 나이에 운명을 달리하신 게임 개발자분의 이야기를 가까이서 접할 수 있어, 참 남의 일 같지가 않다. 이 자리를 빌어 고인의 명복을 빌어 본다.

    HP가 떨어진 삶이 계속되면서, 내가 한정된 에너지를 누구에게 또는 어디에 쏟아야 하는지 명백하게 알 수 있었다.

    어쨌거나 이제는 이런 네거티브한 상념에 발목잡히기엔 내 인생의 비트&마이크로초가 아까우므로, 그냥 just:ignore 해버리고 오로지 health regeneration rate 를 높이는 데 주력할 계획이다. 김포 평야에서 자전거를 몰고 나가 금빛 벼물결 속에서 원기옥도 좀 모으고, 다양한 분야의 책도 많이 읽을 계획이고, 뜸했던 블로깅도 재개해서, 최근 3개월 동안 축적해둔 다양한 분야의 Draft들을 하나씩 공개해 보도록 하겠다.

    휴가 기간 동안 한정된 시간을 어떻게 잘 활용할 것인가?가 앞으로의 당면 과제 되겠다. 이른바 기간 한정판 레이옷인 셈이다. 클클.

  • 2009-07-27

    Back to Wordpress.com

    [caption id="attachment_2242" align="alignnone" width="300" caption="배고픈 길냥이 오형제"]배고픈 길냥이 오형제[/caption]

    호스팅 만료 한 달을 앞두고, 다시 wordpress.com 으로 전격 이사를 왔다.

    국내의 정치적 핍박을 참지 못하고 사이버 망명길에 오르기엔, 여긴 그저 조회수 낮은 힘없는 일개 프로그래머의 해우소일 뿐이지만, 그래도 최근 MB족들의 하는 꼬라지를 보면 언제 호스팅이 날아가고 데이터가 악의 손아귀에 들어갈 지 모를 터다.

    어쨌거나 설치형 워드프레스(이하 WP)에서 호스팅형으로 돌아갈 때 가장 걸리는 것은 바로 첨부 파일이다. 비록 WP가 XML 기반의 Export/Import 를 지원하긴 하지만 첨부 파일까지 자동으로 옮겨주지는 않기 때문이다. 그래서 처음 생각한 건 각종 이미지들을 구글의 피카사웹으로 올린 후, 그 URL을 찾아서 XML파일을 교체한다는 아이디어였다.

    일단 첨부파일들을 모두 다운받아서 피카사 업로더를 이용해서 올린 후, 구글 피카사웹 API 샘플을 이용하니 손쉽게 URL을 알아낼 수 있었다. 주의할 점이라면 한글로된 앨범 이름을 위해서 유니코드를 써야 한다는 것 정도가 샘플과의 유일한 차이였다.

    
    def get_picasa_urls(email,password,wp_album):
    
        gd_client = gdata.photos.service.PhotosService()
        gd_client.email = email
        gd_client.password = password
        gd_client.source = 'wordpress_attachment_exporter'
        gd_client.ProgrammaticLogin()
    
        print 'picasa web connected'
    
        dic = {}
    
        albums = gd_client.GetUserFeed(user='default')
    
        print len(albums.entry), 'albums found'
    
        for album in albums.entry:
    
            if album.title.text != wp_album:
                print 'skipping album', unicode(album.title.text,'utf-8')
                break
    
            print unicode(album.title.text), 'album found'
    
            #print 'title: %s, number of photos: %s, id: %s' % (album.title.text,album.numphotos.text, album.gphoto_id.text)
            photos = gd_client.GetFeed('/data/feed/api/user/default/albumid/%s?kind=photo' % (album.gphoto_id.text))
            for photo in photos.entry:
                #print '  Photo:', photo.title.text, ' id:', photo.gphoto_id.text, ' url:', photo.content.src
                dic[unicode(photo.title.text,'utf-8')] = unicode(photo.content.src,'utf-8')
    
        print len(dic), 'images in picasa'
    
        return dic
    

    그다음 한 일은 내보내기한 XML 파일의 기존 URL을 위에서 찾아낸 새 URL로 교체하는 것인데, 정규식을 활용해보기로 했다. 문제는 이렇게 했는데도 실제로 미리보기가 안된다는 것이었는데, 아마도 flickr나 피카사 모두 직접 링크를 지원하지 않는 모양이었다. 그래서 어쩔 수 없이 모든 첨부파일을 손으로 하나씩 WP.com 으로 업로드한 후 그 URL을 적용하기로 했다.

    아래는 최종 버전.

    
    import re
    import codecs
    
    # configuration
    wp_export_xml = '/Volumes/data/Downloads/wordpress.2009-07-25.xml'
    attachment_ext = 'jpg|JPG|gif|GIF|png|PNG|bmp|BMP|doc|docx'
    attachment_url_pattern = 'http://reiot[^"\'<>]+?\.(%s)'%attachment_ext
    attachment_filename_pattern = re.compile('[^/=]+?\.(%s)'%attachment_ext)
    wpcom_prefix = 'http://boxcatstudio.files.wordpress.com/2009/07/'
    
    attachments = {}
    
    # faster than open().read().encode('utf-8')
    lines = codecs.open(wp_export_xml,"r","utf-8").read()
    itr = re.compile(attachment_url_pattern).finditer(lines)
    for m in itr:
        orig_url = m.group()
        new_url = wpcom_prefix + attachment_filename_pattern.search(orig_url).group()
        attachments[orig_url] = new_url
    
    print len(attachments), 'attachments found'
    
    i = 1
    
    for orig_url in attachments.keys():
        new_url = attachments[orig_url]
        print '[%d/%d] %s => %s'%(i,len(attachments),orig_url,new_url)
        lines = lines.replace(orig_url,new_url)
        i = i + 1
    
    out_xml = codecs.open(wp_export_xml+".converted.xml","w","utf-8")
    out_xml.write(lines)
    out_xml.close()
    
    

    정규식은 항상 볼 때마다 새로운 느낌이 들어서, 꽤 시간이 많이 걸렸다. 또 큰 파일에서 유니코드로 빠르게 읽으려면 codecs 모듈이 좋댄다.

  • 2009-07-22

    Most Valuable Asset


    우유 먹는 그레이
    우유 먹는 그레이

    건강을 잃으면 모든 것을 잃는다고 누가 그랬나. 그 말이 정답. 일단 체력 회복을 최고 우선 순위에 올려 두고 살고 있으니, 너무 걱정마시길.

    시간 여유가 좀 생기면서 나의 관심은 아이폰에서 트위터 및 SNS 웹게임들로 옮겨 가고 있다. 며칠 전부터는 다시 구글 app engine 을 뒤적거리면서 트위터 기반의 zynga clone를 구상해보고 있는 중이다.  task queue 가 생겨났으니 이제 slow turn 게임들은 클라우드로 옮겨 가는 것이 가능해진 셈이다.

    웹 동네의 구조들을 보면 memcached 같은 미들웨어들을 적극 활용하고 있다. 게임에서도 coord 같은 것들은 마련해두면 서버간 통신이라든지 DB 장비 구매 비용을  꽤나 줄일 수 있을 것 같다. 이런거나 만들면서 놀면 재미있을텐데..

    2009년은 정말 다이나믹한 해로 기억될 것 같다. 개인적으로도, 사회 생활에서도, 국가적으로도 더 이상 슬픈 일은 없었으면 한다.

  • 2009-05-21

    Idogame

    매출 1조짜리 기업 NHN에서 출시한 아이두 게임과 게임 오븐에 대한 짧은 생각:

    • 하루 최고 동접 1000명을 찍으면 한달에 300만원을 지급한다? 한게임 유입자수 풀을 키우려는 전략이겠지만, 너무 짜다. 돈은 현재의 2배 정도로 늘리되, in game ad를 무조건 탑재하도록 하면 윈윈이 되지 않을까.
    • 정말 이걸로 돈을 벌려면, 접속 시간을 최대한 늘이는 게임 또는 특정 시간의 접속 비율을 높이는 방향으로 게임을 디자인해야 할 것이다. (자꾸만 동접 늘리는 트릭만 구상하는 레이옷..)
    • 게임오븐 IDE은 .NET이 아니라 Native C++으로 만들어졌고, 루아(luabind)로 서버 및 클라이언트를 개발한다. 놀라운 점은 IDE 자체적으로 스크립트 디버깅이 가능한데, 브레이크 포인트라든지 콜스택, watch를 모두 지원한다는 것. (dev.naver.com/opensource에다가 이것만 따로 무료로 공개해주면 좋으련만!!!)
    • 네트워킹 역시 루아로 이루어지는데, key-value로 된 메시지를 보내거나 SyncObject라고 해서 자동적으로 테이블을 상대편으로 복제할 수 있다. 얘들도 __newindex 로 루아 테이블 내부 값의 생성, 삭제 및 변동을 추적했을까나~
    • 사실 게임 오븐으로 만든 서버를 어떻게 호스팅하는가? 가 가장 궁금하다. 그냥 서버 exe 를 적당한 서버로 배포해서 실행하지는 않을테니, 여기에 설마 클라우드 개념이 들어갔을까? 흐흠..