Nhật ký dự án Car Racing - điều kì diệu

Thursday, September 3, 2009 5 phản hồi

David bảo chúng tôi phải tạo ra điều kì diệu. Yes, điều kì diệu là viết một game đua xe trên iPhone được estimate trong 6 tháng bởi một công ty chuyên làm game khá nổi tiếng - và chúng tôi sẽ phải làm trong 45 calendar days.

Chúng tôi bắt đầu từ những con số khá nghèo nàn.
1 Technical architect (Khoa) + 2 developer (Đạo, Chương). Trong 3 người chỉ có 2 người có kinh nghiệm lập trình trên iPhone trong 2-3 tháng.
Ngày thứ 1: chúng tôi bắt đầu từ những game engine 3D trên iPhone. Chúng tôi chọn SiO2 vì thấy có khá nhiều game sử dụng nó và cộng đồng LTV cũng khá đông đảo.

Ngày thứ 2: Chúng tôi thực hiện các thử nghiệm nhỏ: load mô hình 3D + thực hiện các chuyển động vật lý + đưa ra các mô hình điều khiển xe bằng việc tác động lực.

Ngày thứ 5: mọi chuyện có vẻ trở nên khó khăn. Đầu tiên là việc load xe và đặt vào terrain. Xe luôn bị rơi xuyên thủng mặt đất. Kế tiếp là việc load mô hình 3D sử dụng script Python chạy trên blender. SiO2 support mạnh cho blender, nhưng lại yếu đối với các 3D design tool khác. Mọi mô hình 3D phải được export ra định dạng sio2 trước khi được load vào game. Đội ngũ 3D design của chúng tôi không quen sử dụng công cụ này nên đây là một trở ngại rất lớn.

Ngày thứ 7: áp lực bắt đầu khá nặng nề. Chúng tôi đã load được mô hình xe đơn giản nhất - chỉ có 4 bánh - 1 thân và 2 trục, điều khiển xe chạy được trên iPhone. Tuy nhiên, còn quá nhiều câu hỏi hóc búa phải trăn trở: thắng xe như thế nào, tăng tốc ra sao, chuyển số cho xe như thế nào? Không có ai có kiến thức về xe ô tô, động lực học cơ bản cũng quên sạch.

Ngày thứ 8: tôi quyết định phải đọc lại những kiến thức vật lý cơ bản và bắt đầu từ 3 định luật Newton. Very stupid.

Buổi sáng ngày thứ 9: tôi nghĩ trong đầu: tại sao phải là SiO2. Sao không tìm thử một hướng mới. Tôi mò mẫm trong các search engine và vô tình tìm được một tutorial sample cho game đua xe ở Unity engine. Hura! có vẻ bắt đầu thuận lợi.
Chiều: phát hiện ra Unity3D có version cài trên Windows. Bắt đầu cài đặt và sau đó run thử tutorial. Cool! diễn tiến khá tốt đẹp - xe chạy smooth, có cả âm thanh, thắng và gài số tự động.

Ngày thứ 10: họp team và chia task. Công việc cần làm bao gồm:
+ Đọc hiểu script để điều khiển xe
+ Tìm hiểu cấu trúc 3D của xe trong game và yêu cầu nhóm design giúp chúng tôi để có 1 mô hình xe khác cho việc thử nghiệm
+ Tìm hiểu cách hiện thực GUI trên Unity để hiện thực một số màn hình

Ngày thứ 12: chúng tôi hiểu tương đối về cách điều khiển xe và giờ đây có thể thay đổi được cả terrain và mô hình xe. Một thành công vượt ngoài mong đợi.


Ngày thứ 14: chúng tôi gặp khó khăn khi đưa game chạy trên iPhone. Mô hình 3D khá nặng và code chưa được optimize nên chỉ cần vừa start game là bị crash. Mặc dù game chạy khá cool trên desktop và web.


Ngày thứ 15: bắt tay vào research các tips để optimize performance. Chúng tôi có may mắn quen với một người bạn đã từng làm game trên Unity (Hạo - cty Halovi). Bạn đã giúp chúng tôi khá nhiều trong việc tư vấn optimize performance cho game.

Ngày thứ 17: tôi collect lại tất cả các tips and tricks để optimize performance cho Unity iPhone và đưa vào một checklist. Chúng tôi bắt tay optimize từng điểm, từng điểm một. Ngay cả phép cộng, trừ, nhân, chia trên script cũng phải được cân nhắc và review từng dòng. Ví dụ: a / 2 sẽ chậm hơn a * 0.5, ...

Ngày thứ 19: game đã chạy được trên iPhone nhưng với FPS bằng 5, siêu giật và gần như không điều khiển được. Lại tiếp tục tìm trick optimize performance và optimize tiếp.

Ngày thứ 21: xe có thể chạy trên iPhone với FPS bằng 15. Điều khiển khá smooth. Nhưng tiếc thay, xe chỉ có thể chạy với 4 bánh và 2 trục, terrain thì gần như chỉ là một mặt phẳng.
Chúng tôi buộc phải nhờ cầu viện của bộ phận design. Mô hình phải được tối ưu hơn nữa. Càng ít polygon càng tốt, càng ít texture càng tốt. Chỉ có một câu phát biểu duy nhất trong lập trình game: phải cân bằng 2 yếu tố "đẹp" và "nhanh".

Ngày thứ 23: bắt đầu có những mâu thuẫn nhỏ. Mâu thuẫn lớn nhất xuất phát từ việc: các anh design cho rằng đã optimize hoàn toàn mô hình 3D, xe chỉ có 6K polygons. Tại sao khi load xe trong Unity lại có thể là 112K triangles?
Phải tìm cách giải quyết conflict và chỉ ra điểm cần optimize tiếp theo. Có vẻ sự sống của chúng tôi đang bi đát.

Ngày thứ 24: tôi đã giải thích được vì sao có sự khác biệt giữa số polygon trong Maya và trong Unity. Nguyên nhân xuất phát từ mô hình lý thuyết về texture mapping.
Lại họp nhóm - và lần này có cả 3D design group. Chúng tôi biết các anh cũng rất mệt vì đã support chúng tôi rất nhiều.
Cuộc họp giải quyết được khá nhiều vấn đề, và cơ bản chúng tôi biết cần optimize thêm những gì, làm sao để đo được kết quả số polygons thực tế trên game từ một mô hình 3D.

Ngày thứ 25: buộc phải release một bản demo trên web cho khách hàng review - vì version hiện tại chưa thể chạy được trên iPhone smooth.

Ngày thứ 27: chúng tôi đã có một version chạy với FPS = 15 trên iPhone với mô hình xe và terrain khá ổn. Tuy nhiên sau một vài thay đổi nhỏ, FPS lại rớt về 5. Very stupid.

Ngày thứ 28: phát hiện được một trick để optimize về physic của Unity. Đây là một bước tiến khá vượt bực. Chúng tôi giảm số frame vật lý xuống để làm tăng FPS và đã thành công. Tuy nhiên việc control xe có chút khó khăn vì frame vật lý không còn liên tục nữa.

Ngày thứ 29: optimize script để làm cho việc control xe smooth hơn bằng cách phân tách các hàm xử lý vào Update và FixedUpdate hợp lý.

Ngày thứ 30: bắt tay vào làm GUI cho các màn hình game. Hoàn thiện kịch bản.

Từ ngày thứ 31-34: chỉ hoàn tất kịch bản game và fix các bug về mô hình, control xe smooth hơn.

Ngày thứ 35: add thêm âm thanh cho game: tiếng xe chạy, tiếng va chạm vào tường.

Ngày thứ 36: phát hiện ra deployment guideline của mình thiếu đoạn jailbreak iPhone. Hì hục hết buổi sáng và nửa buổi chiều để jailbreak iPhone. Từ đó về sau, chúng tôi tự hào có thể jailbreak iPhone trong 5 phút.

Ngày thứ 37: chúng tôi không thể deploy cho khách hàng bằng cách sử dụng jailbreak iPhone. Họ bảo rằng cách này quá khó. Thật sự, Apple có support cách deploy AdHoc distribution cho beta user - sử dụng iTunes. Chỉ cần có UID của iPhone + provisioning profile (một dạng certificate để iTunes nhận dạng và install application).
Chiều: loay hoay mãi không deploy được mặc dù nghĩ rằng đã làm đúng tất cả các step. Stuck!

Đến gần 10h tối, thì cũng deploy thành công bằng AdHoc distribution. Viết mail thông báo cho onshore PM.

1 AM: bật mail công ty để check xem có tin gì mới. Problem: Onshore PM không deploy được theo kiểu AdHoc mặc dù mình đã đăng kí UID iPhone của họ với Apple và cung cấp đúng provisioning profile. Lúc chiều chính xác mình đã deploy thành công với iPhone 3G, 2G và 3GS. Wtf's happenning?

4 AM: search hoài nhưng vẫn stuck - vì thấy mình đã apply hết các trick tìm được rồi. Đi ngủ.

Ngày thứ 38: bị áp lực từ onshore và khách hàng. Với tất cả thông tin họ cung cấp, vẫn không tìm ra được vấn đề do đâu.
Lại một đêm ngồi làm đến 4 AM. Không dám check mail sợ bị áp lực không research tiếp được. Bật mail lên ghi vài dòng suggestion: "đề nghị backup solution hack iPhone và deploy bằng SSH. Onshore cần thử gấp cách này và cho chúng tôi kết quả, để xử lý những tình huống phát sinh khác"

Ngày thứ 39: vô vọng, kiệt sức. Vậy mà trước khi vô công ty phải refresh lại cái mặt để anh em nhìn vô không thấy nản. Chỉ có một câu nói còn ám ảnh mãi trong đầu: phải đốt cháy chính mình thì mới có thể truyền lửa cho người khác được. Lửa ơi trong tôi, xin đừng tắt.

Bật mail thì nghe tin Jeremy deploy thành công bằng cách jailbreak iPhone 3G và 3GS. Một chút hy vọng lóe lên. Dù sao thì cũng không phải cùng đường. Mặc dù vậy, khách hàng vẫn không happy.
Lại phải tìm tiếp. Thức đến 3 AM thì đuối. Có đọc được loáng thoáng 2 cách tạo application ID trên Apple là static và wildcard. Wildcard có nghĩa là dùng tên có * để đăng ký. Ví dụ: com.pyco.*, static là tên chính xác.
Đọc nhưng không remote vô được máy MAC ở công ty để làm.

Ngày thứ 40: buổi sáng, build cái app theo cách dùng wildcard app ID. Nhưng phải đợi onshore PM đến chiều, vì lệch múi giờ. Send app lúc 1 h chiều, ngồi đợi.
3h PM: Nicolas gõ qua MSN. Congratulation, it's working. You're the best.
Thở phào nhẹ nhỏm. Muốn hét lên Eureka, nhưng sợ bà con nói mình khùng.

CTO phải nhảy vào can thiệp vì project quá quan trọng. Nhưng lúc Gilbert vừa định kêu mình vào conference thì problem đã xử xong.
Buổi tối, ngồi support onshore deploy với bản build mới đến gần 11h mới về nhà. Oải, chỉ muốn ngủ.

Ngày thứ 41: âm thanh của xe bị chê. Hic, phải ngồi mở Youtube lên coi xe Ferrari chạy thế nào. Từ nhỏ tới lớn không coi đua xe, không biết nó gầm rú ra sao để làm cho chính xác.
Define solution + apply âm cho xe rú từ nhỏ đến to, từ to đến nhỏ. Làm hoài vẫn không giống. Nicolas chỉ nói: tao thấy mày làm hoài nó cũng chẵng khác biệt mấy.
Team ai cũng oải. Mặt mình lúc đó nhìn chắc cũng bi kịch lắm nên anh em nó mua cơm tối cho ăn mà cứ đòi cho free. Hic, quyết định của mình lúc đó: anh em về nhà relax đi, oải hết rồi. Mình ở lại confirm với Nicolas chút rồi về.

Sau một hồi discuss, quyết định phải code để cho onshore thấy hiệu ứng âm thanh như họ yêu cầu. Đến 11h thì xong task. Nicolas bảo: âm thanh vậy tao thấy được rối á. Về nhà.

Ngày thứ 42: fix thêm một số effects và chỉnh lại một chút về GUI cho hoàn hảo. Game coi như xong.

Ngày thứ 43: nghỉ lễ 2-9. Không dám về nhà vì ở quê không online được. Ngồi nhà nhưng tâm trạng thấp thỏm.

Ngày thứ 44: không có feedback mới. Khách hàng đã happy.

Ngày thứ 45: game được đem triễn lãm ở showroom.

Kết thúc! chúng tôi đã làm nên điều kì diệu như vậy đó. Cảm ơn rất nhiều nhé mọi người. Đặc biệt là Chương và Đạo - những người đã đóng góp rất lớn vào sự thành công của dự án. Anh em chúng ta đã trải qua những tháng ngày thử thách, nhưng cũng rất vui. OT mà đi nhậu thịt chó, uống rượu - thì còn gì bằng, đúng không nào?