颱風天在家很無聊,來宣傳一下自家的軟體吧

三年前進了目前的公司,剛開始只有兩個傻逼工程師,還有兩個出資的老闆
趁著裝潢辦公室的同時,每周一次的會議都在討論將來要走的方向

一開始是想做物聯網,跟電梯相關的,想想這個應該很有趣
但是發現在大陸這樣的東西已經被很多大公司包了,而且黨政關係不好,也進不去
美國那邊的也差不多,於是這個案子就先擱置

然後那時候突然又談到計程車的app,沒錯,就是大陸的滴滴打車的前身
那時候的Uber也剛起步,但是評估的結果就是在台灣做這個實在是太多限制
所以又擱置了這個案子

之後討論了好久,不知道是誰說想做一個交友的app
這一次幾乎沒有反對的聲音,於是乎就開始進駐新辦公室
同時也開始找了一些人脈,找了一些舊識組了一個小團隊
開始打造app的前後端
那時候參考的目標就是LINE PLAY的模式
但是我們要做的是寫實風格,同時是3D的real time render的新型態的交友軟體
一堆傻逼就這樣開始這一段冒險
做到後面,問題實在越來越多,老闆也有自己的想法和意見
團隊又有許許多多的合作問題,搞到最後實在是有點力不從心
但是終於還是把第一個版本弄了出來,Android/iOS都弄出來了
也上架了,準備開始推廣app
正要開始規劃的時候,突然間老闆來開會,宣布這個案子要終止,所有相關人員要轉到其他專案

這是哪招

當時的心裡實在不是很舒服,但是想想家裡嗷嗷待哺的兩個小孩,美麗的老婆都靠著每個月那份微薄的薪水過日子
再苦的日子也是要撐過去啊,不然要怎樣
所以只好就依照老闆的指示,忍痛就自行了斷第一個產品

接著,老闆開了新竹的辦公室,開始準備進軍半導體廠的軟體專案,我就開始規劃整個程式系統架構
interview新同事,接著開始和對方的人員密集開會討論專案的開發事項
半年後,新竹辦公室日漸茁壯,一個專案一個專案順利的開啟
新竹台北兩地跑倒是也很快就適應了這樣的生活,過去的傷痛也就漸漸的淡忘

但是,命運之神終究是要考驗我的
台北的老闆對於某個idea一直很想把它實現出來
去年中找我討論後,也和大老闆協調把我抽回台北帶新的專案
這一次要做的又是另外一個領域的app
對於這樣的挑戰,我還是欣然接了下來
於是又開始了找人組團隊,訓練新同事,找尋開發工具的過程
很幸運的,這次被我騙進來的團隊成員都是相當優秀,雖然沒什麼開發經驗,但是憑藉著他們的努力,還有團隊合作
之中當然還是不意外發生一些動亂,不過也算是順利擺平了
app終於完成了

這一次我們做了時尚聊天的女裝app
叫做 ConFASHION ("時尚告解")

整個app的概念就是搜集台灣目前最受歡迎的一些網路服裝品牌
只要使用這個app就可以看到上萬件的衣服,不需要安裝數十個不同的品牌app
更方便的是,當你看到一件喜歡的衣服,馬上就可以找到你的朋友討論

強者我朋友對這樣的模式叫做
服裝界的LINE

這樣好用的app想要推薦給大家
下載網址:http://pics.ee/eUY







只是這一次不知道接下來還會發生什麼事情
讓我們接著看下去吧

貼圖上架了

故事的開始是這樣的話說半個月前,我們開始規劃貼圖功能時,一直為了要找誰畫貼圖而煩惱突然想到臉書的好友 Red Soda 有相關的經驗厚臉皮的我馬上找他來幫忙於是,ConFashion貼圖上架了,趕快介紹朋友一起來聊聊穿搭時尚吧https://play.google.com/store/apps/details?id=com.ais.cherry

Posted by ConFashion on 2015年6月29日

如何擁有白金之星的能力

在一個忙碌過後的午茶時間,fb跳出了一個訊息,Xdite要開redmine的課程了,雖然我和他完全不認識,雖然都是寫程式卻又完全不同領域,不過
想想自己公司內部用了Redmine一年多了,總是覺得哪裡怪怪的,於是打定主意要排除萬難去上課,當然最重要的就是算計怎麼讓老闆出錢,於是趁著一次專案會議後,馬上跟他提出自己想要充電的想法,去上個專案管理的課程對以後對公司也是有幫助的,嘴炮了一堆終於得到首肯,也順利的完成報名手續

上午的課程其實我大概都運用過了,下午講的應該才是我想要的亮點,首先我對於milestone的用法很是贊同,老實說現在開發的專案都是類似打帶跑的游擊戰作戰方式,隨時會面對新的issue和軟硬體整合的課題,所以目標都不會定很遠,但是以往過往的經驗,一個milestone都是以alpha、beta等方式來制定,但是顯然現在已經不適合這種傳統的方式了,因為需求隨時會變,老闆也常常會亂入,所以我一直都在思考如何運用專案的管理方法,讓team member能夠更快地掌握目前最需要開發的issue,xedit提出以一兩個禮拜來制定milestone的方法,應該是很適合我自己的團隊使用的

另外就是與git的配合,我覺得這個也是很多programmer的痛,因為常常需要在浩瀚的code海找出同事修改的東西,或者要翻找一些歷史經驗,常常都是只能靠著殘存的記憶,偏偏這些記憶都會被隔壁公司的美女給占滿,所以每次找code都會很辛苦,而且如果是下tag的方式,雖然比較文明一點,但是每次要下什麼tag,光是想名字就很傷腦筋,現在這麼方式就很方便,反正git開branch不用錢啊,那就儘量開,只要照著redmine的issue no.去開,既快又方便,找一些過去的記錄也方便,同事之間的討論也有個記錄,真是一個很棒的方法,光這一點,我就覺得這堂課很值錢了

於是回來的路上就在思考接下來該如何在公司內部推展這項新的業務,緊接著三天的端午節假日,我就在家裡試著先以本身負責的cloud專案試做,發現這樣真的蠻直覺的,對於團隊開發上應該可以利用redmine和git的完美配合,得到更快速地開發效果

三天假期後第一天上班馬上招集人馬將這個新方法做個介紹,不過我想對於我們這種遠距離開發的團隊所面對的問題,應該還是缺乏什麼,突然想起了好像一直說要架的聊天系統一直都晾在那邊,於是只好趕緊找個空擋將系統架了起來,還好使用上並沒有遇上太大的問題,雖然一開始gitlab不太配合,不過發現應該是版本太舊的關係,於是花了兩個小時升級後,也順利的登入hipchat了,於是乎,這一年來的一些困擾終於得到解決

過去面對開發專案的時候,有時候會覺得就像是八仙過海一樣,要各顯神通才有辦法將一些牛鬼蛇神的怪物解決

但是真實的情況就是像是這樣,老是被一場又一場的傾盆大雨澆熄了戰鬥的火苗

上完這堂課之後,感覺自己就像得到白金之星的替身使者了,感覺很那個啦

build failed when link mongo c++ driver

這幾天忙著升級到maverick
xcode也升級到5.0
然後開始將之前寫的server程式重新編譯
之前用了一些library都順利轉到新的os上了
包含poco library、boost、mysql、thrift等等
唯獨一個mongo c++ driver老是失敗
後來加上c++11的參數後也順利編譯成功
只是在link的時候老是出現以下錯誤

  Undefined symbols for architecture x86_64:
  "mongo::Status::~Status()", referenced from:
      mongo::BSONArrayBuilder::fill(mongo::StringData const&) in icService.o
  ld: symbol(s) not found for architecture x86_64
  clang: error: linker command failed with exit code 1 (use -v to see invocation)

這到底是什麼問題,重新編譯了幾次,換了無數的參數還是一樣,最後我懷疑是編譯器相容性的問題
於是我只好去翻一下source code,把Status::~Status()給找出來,在base底下發現了這支程式

namespace mongo {

    /**
     * Status represents an error state or the absence thereof.
     *
     * A Status uses the standardized error codes -- from file 'error_codes.h' -- to
     * determine an error's cause. It further clarifies the error with a textual
     * description. Optionally, a Status may also have an error location number, which
     * should be a unique, grep-able point in the code base (including assert numbers).
     *
     * Example usage:
     *
     *    Status sumAB(int a, int b, int* c) {
     *       if (overflowIfSum(a,b)) {
     *           return Status(ErrorCodes::ERROR_OVERFLOW, "overflow in sumAB", 16494);
     *       }
     *
     *       *c = a+b;
     *       return Status::OK();
     *   }
     *
     * TODO: expand base/error_codes.h to capture common errors in current code
     * TODO: generate base/error_codes.h out of a description file
     * TODO: check 'location' duplicates against assert numbers
     */
    class MONGO_CLIENT_API Status {
    public:
        // Short-hand for returning an OK status.
        static inline Status OK();

        /**
         * Builds an error status given the error code, a textual description of what
         * caused the error, and a unique position in the where the error occurred
         * (similar to an assert number)
         */
        Status(ErrorCodes::Error code, const std::string& reason, int location = 0);
        Status(ErrorCodes::Error code, const char* reason, int location = 0);

          inline Status(const Status& other);
        inline Status& operator=(const Status& other);
        inline ~Status();


        /**
         * Returns true if 'other's error code and location are equal/different to this
         * instance's. Otherwise returns false.
         */
        bool compare(const Status& other) const;
        bool operator==(const Status& other) const;
        bool operator!=(const Status& other) const;

        /**
         * Returns true if 'other's error code is equal/different to this instance's.
         * Otherwise returns false.
         */
        bool compareCode(const ErrorCodes::Error other) const;
        bool operator==(const ErrorCodes::Error other) const;
        bool operator!=(const ErrorCodes::Error other) const;

        //
        // accessors
        //

         inline bool isOK() const;

         inline ErrorCodes::Error code() const;

         inline std::string codeString() const;

         inline std::string reason() const;

         inline int location() const;

        std::string toString() const;

        //
        // Below interface used for testing code only.
        //

         inline AtomicUInt32::WordType refCount() const;

    private:
         inline Status();

        struct ErrorInfo {
            AtomicUInt32 refs;             // reference counter
            const ErrorCodes::Error code;  // error code
            const std::string reason;      // description of error cause
            const int location;            // unique location of the triggering line in the code

            static ErrorInfo* create(ErrorCodes::Error code,
                                     const StringData& reason, int location);

            ErrorInfo(ErrorCodes::Error code, const StringData& reason, int location);
        };

        ErrorInfo* _error;

        /**
         * Increment/Decrement the reference counter inside an ErrorInfo
         *
         * @param error  ErrorInfo to be incremented
         */
        static inline void ref(ErrorInfo* error);
        static inline void unref(ErrorInfo* error);
    };

    MONGO_CLIENT_API inline bool operator==(const ErrorCodes::Error lhs, const Status& rhs);

    MONGO_CLIENT_API inline bool operator!=(const ErrorCodes::Error lhs, const Status& rhs);

    //
    // Convenience method for unittest code. Please use accessors otherwise.
    //

    MONGO_CLIENT_API std::ostream& operator<<(std::ostream& os, const Status& status);
    MONGO_CLIENT_API std::ostream& operator<<(std::ostream& os, ErrorCodes::Error);

}  // namespace mongo

#include "mongo/base/status-inl.h"

我想大概是inline這個東西卡到陰了,所以迅速將所有的inline全部幹掉,重新編譯後再link就解掉這個問題了
為了到達這一步足足搞了好幾天,損失數十個小時的工作效能
不過也很慶幸,還好mongodb是open source的,不然不就準備放生了嗎?

Make Thrift

Make Thrift的過程都很順利,但是在install ruby gem的時候卻發生了問題

  Successfully built RubyGem
  Name: thrift
  Version: 0.9.0.1
  File: thrift-0.9.0.1.gem
gem install thrift-*.gem
ERROR:  Could not find a valid gem 'thrift-*.gem' (>= 0) in any
repository
rake aborted!

不過事實上要解決只要修改一下Rakefile即可
gem install fails on zsh
切換目錄到lib/rb
編輯Rakefile
搜尋下面這段:

unless sh 'gem', 'install', 'thrift-*.gem'

改成這段

unless sh 'gem', 'install', Dir.glob('thrift-*.gem').last

然後存檔離開,重新下make install應該就可以解決這個問題了

不過因為我對ruby不熟,不知道是否可以讓ruby透過thrift成功運作
或許不久的將來可以試試看

MagicStreet人物細部設定

每個人物角色的動作:
站立
走路上下左右四個方向

人物分成幾個可分解組合的部份,方便重覆組合運用
頭、頭上戴的物品、身體、衣服、褲子、鞋子、手上拿的、背後背的物品

Magic Street

遊戲名稱:Magic Street(魔法商店街)
簡單描述:魔法世界的商店模擬遊戲企畫
顯示方式:橫向卷軸
遊戲資源:金錢(建設新商店,買賣商品)、RUBY(快速完成道具)
遊戲畫風:8bit 復古造型,類似底下的造型

遊戲人種:人類、精靈、矮人、亡靈、巨魔、野蠻人、半獸人、骷髏
遊戲職業:騎士、武士、拳手、弓箭手、遊俠、魔法師、牧師、僧侶
商店類型:食品類、武器類、麻法類、加工類、藥草類、防具類、礦石類、醫療類、書籍類、旅館類、遊樂類、競技類、交通工具類
特殊任務:購物任務、城鎮防守任務
網路功能:朋友互送資源,結盟
需要技術:2D橫向卷軸技術、人物產生器、商店編輯器、人物行為模式控制程式
支援平台:ios 5.0 up
後端DB:mysql or mongodb
所需開發人員:美術X1,程式X1
開發時程:6個月

美術開發工具:photoshop
美術輸出格式:png

程式開發工具:xcode、cmake
網路連結Lib:thrift、facebook sdk、google sdk
連結資料庫Lib:poco c++、mongodb c client sdk
圖像顯示Lib:cocos-x 2d lib
音樂、音效輸出Lib:cocos-x 2d lib