ประสบการณ์สร้างเกมจริงจังครั้งแรก
ไอเดียมันเริ่มมาจากทวีตนี้
ควรมี flash game ถีบเนยสดได้แล้ว คือจับเวลา 1 นาที ให้เราพิมพ์คำว่าถีบเนยสดให้ได้มากที่สุด แล้วแมวเนยสดก็หน้าน่วมๆไปด้วยไรงี้ เก็บสถิติด้วย
— แม็คคลี่ (@McKiEz) December 14, 2013
(ว่าแต่ใครมันจุดกระแส #ถีบเนยสด ฟระ Orz)
เลยจัดการซะคืนนั้นเลย … ถ้าไล่ดูตาม commit log จะเห็นว่าใช้เวลาไป 2 เดือนพอดีจนปิดโปรเจคได้ ก็นับว่าใช้เวลาเยอะโขอยู่กับโปรเจคขำๆ
ทำให้รู้เลยว่า ส่วนที่ยากที่สุดของการทำเกมนั้น ไม่ใช่การ coding ไม่ใช่การ debug แต่เป็นการออกแบบ game play ให้น่าสนใจ ผู้เล่นต้องรู้สึกว่าไม่ยากเกินความสามารถ ในขณะเดียวกัน เมื่อเล่นจบแล้วก็ยังกลับมาเล่นซ้ำๆ ได้อีกโดยไม่เบื่อ
ซึ่งเวลาส่วนใหญ่ที่หมดไปก็เพราะเจ้าเนี่ยแหละ จริงๆ ถ้าดูตาม log อย่างละเอียดแล้วลองคำนวณเวลาที่ใช้ จะพบว่าโปรเจคนี้ทำเสร็จภายใน 42 ชั่วโมง (บวกลบไม่เกิน 10%) ถ้ามีไอเดียเจ๋งๆ เกี่ยวกับ game play เตรียมไว้อยู่แล้ว
แต่ก่อนที่จะไปดูการออกแบบเกมนี้ ลองเรียนรู้จากเกมอื่นๆ ก่อน
Flappy Bird
- infinity - เล่นได้เรื่อยๆ จนกว่าจะพลาดหรือเบื่อ
- social - อวดคะแนนแข่งเพื่อน
- reflex - ตอบสนองทันทีต่อสิ่งใหม่
(เกาะกระแสซักหน่อยครับ) เกมนี้ใช้ระบบที่เรียบง่ายมากๆ คือพานกบินลอดท่อไปเรื่อยๆ ลอดผ่านได้ 1 ท่อก็เพิ่ม 1 คะแนน อย่างไรก็ตามเกมประเภทนี้จะสุ่มด่านใหม่มาให้เสมอ ผู้เล่นแต่ละคน (หรือแม้แต่คนเดียวกันเมื่อเล่นรอบใหม่) ก็จะพบกับด่านที่ไม่เหมือนเดิม การเพิ่มคะแนนแบบไม่เกี่ยวข้องกับความยากของด่านจึงเหมาะสม เพราะจะกดดันให้เล่นเกมซ้ำๆ เผื่อฟลุ๊คเจอด่านง่ายแล้วได้คะแนนเยอะโดยออกแรงไม่มากไปกว่าเดิมนัก ซึ่งการเล่นซ้ำๆ (ด้วยความโมโหว่าทำไมคะแนนไม่ขึ้นซักที 555) จะย้อนกลับมาช่วยให้เราเรียนรู้ระบบเกมและฝึกประสาทตอบสนอง ส่งผลให้ผู้เล่นได้คะแนนง่ายขึ้นเรื่อยๆ ตามเวลาที่ฝึก ยิ่งผสมกับการนับคะแนนตรงไปตรงมา (1 ท่อ = 1 คะแนน) ยิ่งทำให้เรากะถูกว่าต้องใช้ความพยายามเพิ่มอีกแค่ไหนเพื่อจะทำคะแนนให้ชนะเพื่อนได้
Super Hexagon
- goal set - เกมตั้งจุดมุ่งหมายให้แล้ว
- social - แต่จะแข่งกับเพื่อนก็ได้
- reflex - ตอบสนองทันทีต่อสิ่งใหม่
แนวคิดของเกมนี้ก็ง่ายเช่นเดียวกัน คือพาเจ้าตัวสามเหลี่ยมวิ่งวนคอยหลบไม่ให้โดนกำแพงอัดแบน และใช้ “เวลาที่อยู่รอด” เป็นคะแนนนั่นเอง งานนี้ไม่ต้องคิดมากว่าจะเลือกท่าหลบให้ให้สวยงามได้คะแนนโบนัสเพิ่มหรือเปล่า เช่นเดียวกับ Flappy Bird คือต้องฝึกเยอะๆ ฝึกไปเรื่อยๆ และแม้ว่าจะกำหนดเวลาผ่านด่านไว้ที่ 60 วินาที แต่ถ้าจะทำคะแนนไว้อวดเพื่อน ก็สามารถเล่นต่อหลัง 60 วินาทีนั้นไปได้เรื่อยๆ ครับ
Jubeat
- goal set - เกมตั้งจุดมุ่งหมายให้แล้ว
- social - แต่จะแข่งกับเพื่อนก็ได้
- rhythm - เกมเข้าจังหวะ
Jubeat เป็นเกมแนวดนตรีที่จะให้กดปุ่ม 16 ปุ่ม (บน grid ขนาด 4x4) ตามจังหวะของแต่ละปุ่ม แต่ละเพลงมีรูปแบบที่ตายตัว แถมเกมยัง cap แต้มไว้ที่หนึ่งล้านแต้มเสมอไม่ว่าจะเป็นเพลงยากหรือง่าย ดังนั้นรูปแบบการฝึกจะไม่เหมือน 2 เกมข้างบนเท่าไหร่ เช่นฝึกซ้ำบ่อยๆ เฉพาะรูปแบบที่ยาก ไปจนถึงการจำรูปแบบจังหวะของเพลงทั้งเพลง เกมแบบนี้ต้องให้คนรักในความ perfect จริงๆ มาเล่น ไม่งั้นคงรู้สึกเหมือนฟินไม่สุด
The Typing of the Dead
- goal set - เกมตั้งจุดมุ่งหมายให้แล้ว
- co-op - ร่วมมือกันเล่นได้
- reflex - ตอบสนองทันทีต่อสิ่งใหม่
จริงๆ เกมนี้จะนับเป็นแนวกึ่ง rhythm กึ่ง reflex ก็ได้ เพราะเราไม่ได้สนใจแค่ตัวอักษรที่โผล่มาให้พิมพ์เพียงอย่างเดียว ในบางจังหวะเราสามารถจำว่าต้องยิงซอมบี้ตัวไหนก่อน เพื่อในกลับมาเล่นด่านเดิมด้วยคะแนนที่สูงขึ้นได้ จุดเด่นอีกอย่างในเกมแบบนี้คือความสามารถในการร่วมมือกันเล่น ที่ผู้เล่นต้องสมดุลระหว่างการยิงรัวๆ กันโดนซอมบี้กัดตาย กับการเหลือซอมบี้ไว้ให้เพื่อนร่วมทีมยิงเพื่อให้คะแนนไม่ห่างกันนักด้วย (หรือใครเป็นพวกซาดิสม์ ชอบทำคะแนนให้ห่างกันเยอะๆ ก็ไม่ว่ากัน 55+)
Diablo II
- goal set - เกมตั้งจุดมุ่งหมายให้แล้ว
- co-op - ร่วมมือกันเล่นได้
- leveling - ตัวละคร/ด่านมีพัฒนาการ
ผมจำได้เลยว่าตอนอยู่ม.ต้นเล่น Diablo II ก็รู้สึกหนุกดีนะ เดินผ่านด่านไปเรื่อยๆ ไม่คิดอะไรมาก ถ้าตรงไหนดูยากก็กลับไปเล่นด่านเก่าอัพเลเวลซักหน่อย เพื่อที่จะได้ใช้ท่าใหม่ๆ ตีมอนได้แรงขึ้น เล่นไปเล่นมาก็รู้สึกว่า เอ๊ะทำไมเหมือนฟาร์มเลเวลได้ช้าลง ค่าประสบการณ์สำหรับเลเวลถัดไปที่เพิ่มขึ้นเร็วเป็นเอกซ์โพเนนเชียลก็ยังไม่น่าทำให้รู้สึกได้ขนาดนี้ จนเมื่อได้อ่านสูตรการคิดค่าประสบการณ์ที่ได้จากมอนตัวนึงแล้วถึงบางอ้อ ความต่างของเลเวลมอนกับผู้เล่นก็มีผลต่อค่าประสบการณ์ด้วย นั่นทำให้ผมรู้สึกประทับใจในรายละเอียดและความเชื่อมโยงกันของค่าต่างๆ ภายในเกม ไม่ใช่การที่ developer สักแต่คิดว่าใส่ factor นี้เข้ามาแล้วเกมมันน่าจะสนุกขึ้น ซึ่งในความเป็นจริงเกมมันอาจจะสนุกขึ้น 10 นาที แต่หลังจากนั้นก็กลายเป็นหายนะเพราะเสียสมดุลไปเรียบร้อย
จริงๆ ตอนเอาไอเดียมาแปลงเป็น game play ก็ไม่ได้ไล่คิดถึงเกมอื่นเยอะขนาดนี้หรอก (เอ หรือมันจะเป็น unconscious?) แต่อยากได้แบบ infinity+leveling และคิดว่าต้องปรับแน่ๆ ดังนี้
- เกมฝึกพิมพ์ภาษาไทยยากมาก ทั้ง font เล็ก ทั้งสระบนล่าง … ทำภาษาอังกฤษง่ายกว่า
- 1 นาทีจะว่านานก็นานเกินไปสำหรับเกมฝึกพิมพ์ ยิ่งเจอแต่คำซ้ำๆ นี่ยิ่งน่าเบื่อ
- แต่ 1 นาทีก็สั้นเกินไปถ้า random คำมาได้ไม่ซ้ำกันเลย
- เลยคิดว่าทำเป็นระบบหัวใจดีกว่า พิมพ์ไม่ทันก็โดนโจมตี หัวใจหมดเมื่อไหร่ก็จบเกม
- ถึงแม้ส่วนกริยาจะไม่ซ้ำจากการ random แล้ว แต่ให้พิมพ์ชื่อ (@neizod) บ่อยๆ ก็เบื่อได้เช่นกัน เลยทำระบบเก็บคำกริยาหลายๆ คำไว้ก่อน แล้วค่อยพิมพ์ชื่อเมื่อต้องการจบประโยค
- อนึ่ง ในความเป็นจริงเกมก็ไม่ได้มี word list ใหญ่ขนาดนั้น เลยหาแผนมารับมือเวลาเจอคำซ้ำไม่ให้รู้สึกเบื่อ คือเมื่อพิมพ์ศัพท์ซ้ำจะทำการดึงคำนั้นออกจากประโยคที่กำลังสร้างซะเลย
ตอนนี้ก็ได้ game play หลักมาครบแล้ว ซึ่งเอาจริงๆ prototype พวกนี้ให้ทำ 3-4 วันก็เสร็จ
แต่ก่อนหน้านั้นก็มีสิ่งที่สำคัญไม่แพ้กัน คือการเลือก engine สำหรับโปรเจคนี้ครับ
- เลือกเป็นเว็บเพราะทำ GUI ได้ง่ายและเร็วสุด (จริงๆ คือเป็นอยู่แค่เว็บ 555+)
- ตอนแรกก็ว่าจะใช้ canvas เพราะทุกอย่างสามารถยัดเป็น JavaScript ล้วนเลยได้ แต่ก็จะไม่ได้ฝึก CSS อีกทั้งเกมนี้ยังเป็นแบบ text-base ไม่ใช่เกมตัวละครลุยด่าน เลยคิดว่าเล่นกับ DOM ดีกว่า
- จะเล่นกับ DOM ทั้งที ก็ต้อง jQuery และ
position: absolute
สิครัช - ถ้า JavaScript เขียนสั้นๆ ก็พอไหว แต่มาเขียนซับซ้อนๆ แบบนี้ CoffeeScript เถอะครัฟ จะได้ไม่เป็นภาระ @plynoi
- ไม่ได้ใช้ framework อื่นใดช่วยอีกเพราะไม่ค่อยรู้จัก + learning curve ท่าทางจะสูงน่าดู รอลุยโปรเจคนี้เสร็จพลังวัตรน่าจะกระโดดข้ามไปอีกขั้น
- ไม่อยากแตะ database เท่าไหร่เพราะต้องใช้ host แยก ไม่งั้นก็ไปขอ AppEngine ที่ตอนนี้เก็บครบโควต้าแล้ว
- เลยกะว่าเอาง่าย เล่นเกมเสร็จก็ทวีตคะแนนซะเลย ใครจะโกงก็ช่างมัน (แต่ประสบการณ์ก็บอกว่าไม่ค่อยมีใครโกงหรอก เท่าที่สังเกตจาก Temple Run)
- พอไม่แตะ database ทุกอย่างเป็น static หมด ก็หา host ง่ายขึ้นจม แต่มีที่เดียวที่ผุดมาในใจคือ GitHub Pages
พอรู้ spec env ครบก็สบายใจไปกว่าครึ่งแล้ว
จุดต่อมาคือระบบคิดคะแนนต่างๆ (ที่อู้ไปเป็นเดือนเพราะคิดส่วนนี้ไม่ออก) การจะออกแบบตรงนี้ได้ถ้ารู้จักแนวโน้มกราฟแบบต่างๆ จะได้เปรียบพอสมควร ผลสุดท้ายผมออกแบบดังนี้
- ค่าหลักของเกมคือคะแนน ซึ่งควรคิดตามจำนวนตัวอักษรต่อคำที่พิมพ์เข้าไป เช่น kick ได้ 4 คะแนน เพราะมี 4 ตัวอักษร
- อย่างไรก็ตาม การคิดคะแนนที่ 1 ตัวอักษร = 1 คะแนน อาจทำให้เบื่อได้ และยังไม่ได้ใช้ประโยชน์จากการบังคับพิมพ์ชื่อ (@neizod) เท่าไหร่ด้วย
- คิดว่าอีกปัจจัยที่ควรจะมีผลต่อคะแนนคือเลเวล (เหมือนเกมอื่นๆ) ยิ่งผู้เล่นเลเวลสูงก็น่าจะได้คะแนนเยอะ เลยเอาคะแนนที่ได้ไปคูณด้วยเลเวลเมื่อพิมพ์จบประโยค
- แต่ก็ไม่อยากให้ผู้เล่นเก็บคำศัพท์ไว้เป็น 20 คำแล้วค่อยจบประโยคเพื่อคูณคะแนนตูมเดียว เลยให้แค่คำแรกของประโยคที่ได้คูณเลเวลเต็มๆ คำถัดๆ มาก็คูณกับค่าเลเวลที่ลดลงเรื่อยๆ จนคำท้ายๆ ไม่ได้ประโยชน์จากการเก็บดองคำศัพท์ไว้ไม่ยอมสร้างเป็นประโยคซักที
- ส่วนการเพิ่มเลเวลนั้นก็คิดจากคะแนน ตรงนี้ไม่อยากให้คะแนนต่อเลเวลเป็นกราฟเส้นตรง เพราะจะทำให้ตัวคูณเพิ่มเร็วมาก และเนื่อจากไม่ค่อยชอบกราฟกำลังสอง เลยเลือกค่าคะแนนสำหรับเพิ่มเลเวลต่อไปเป็นแบบเอกซ์โพเนนเชียลซะ
- หัวใจลดได้ก็ย่อมเพิ่มได้ ง่ายสุดไม่คิดอะไรแล้ว เลเวลเพิ่มเมื่อไหร่ หัวใจเพิ่มเมื่อนั้น (เชื่อว่าระบบการเพิ่มเลเวลถูกออกแบบมาเป็นอย่างดี 555+)
- แต่แน่นอนว่าเพิ่มเลเวล = เพิ่มความยาก ในที่นี้ก็คือเพิ่มจำนวนคำศัพท์บนหน้าจอให้ออกมาเท่ากับเลเวล และเพิ่มความเร็วให้มันทีละนิดๆ
ถ้าแม่น math หน่อย ระบบพวกนี้ implement เข้าไปไม่นานครับ ดีไม่ดีเร็วกว่าออก prototype ข้างบนอีก ปัญหาคือจะทำได้เร็วๆ นี่ต้องไอเดียบรรเจิดมาก ควรหา paper ด้านจิตวิทยาและการออกแบบเกมอ่านตุนไว้เป็นอย่างยิ่ง :p
พอ core ทั้งหลายเสร็จแล้ว ก็แต่งสวยครับ
- จริงๆ ก็อยากให้เจ้าแมวสดโดนชก/ถีบหน้าน่วมนะ แต่มันทำยากซะเหลือเกิน เลยเลือกๆ อารมณ์มาตรฐานที่เว็บมันมีให้มาให้แทน ได้มา 8-9 แบบก็น่าจะพอ
- พื้นหลังนี้ก็เลือกนานเหมือนกัน คิดไว้ว่าอยากได้โทนสว่างๆ ก็เลือกเหลืองอ่อน เลยได้น้ำเงินอ่อนติดมาด้วยในตอนแรก (สีคู่ตรงข้ามกันพอดี) ทำไปทำมาได้สีแดงตอนจบเกมมาด้วย เลยต้องเลื่อนสีน้ำเงินให้ออกไปฟ้าๆ หน่อย โทนสีจะได้เป็นรูปสามเหลี่ยม
- ตอนแรกไม่ได้คิดว่าจะเอาเจ้าแมวสดมาไว้ด้านล่าง แต่จะเอาไว้เป็น background เลย ซึ่งคิดไปคิดมาก็คงไม่เหมาะเพราะรบกวนสมาธิผู้เล่นเกินไป เลยย้ายมาอยู่มุมล่างขวา ด้านที่คำศัพท์ต่างๆ พรั่งพรูออกมานั่นเอง
- ทำให้พวก status ผู้เล่นอย่างคะแนนสะสม/เลเวล/หัวใจที่ตอนแรกวางไว้ว่าจะให้กระจัดกระจายตามขอบต่างๆ ของจอ ถูกจับมาอัดรวมกันไว้เป็นกล่องทางด้านซ้ายในสไตล์เดียวกัน
- ที่เหลือก็จับปุ่มโน่นนี่นั่นยัดเข้ามาไม่ให้มันดูโล่ง
- สุดท้ายคือ tutorial เกม หัวใจสำคัญที่ขาดไม่ได้แม้เกมจะง่ายแค่ไหน ใครจะไม่ดูก็ช่างเขาแต่เราจะพรีเซนต์!
หลังจาก implement เสร็จหมดก็ได้ฤกษ์ปล่อยเกม ตามไปเล่น (ด้วยความรัก) ได้ที่ neizod.github.io/kick เลยครับ \(;w ;)/
author