Feb 14, 2014

ประสบการณ์สร้างเกมจริงจังครั้งแรก

ไอเดียมันเริ่มมาจากทวีตนี้


(ว่าแต่ใครมันจุดกระแส #ถีบเนยสด ฟระ 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 ;)/

Feb 7, 2014

พื้นที่สำหรับความผิดพลาด

วันก่อนเห็นทวีตนี้



จะบอกว่าไม่เห็นด้วยก็คงจะพูดได้ไม่เต็มปาก เพราะการตีความ "อำนาจ" ในการ "ทำอะไรก็ได้" ของเด็กและผู้ใหญ่นั้นต่างกันไกลลิบ

เมื่อเป็นเด็กเราต้องการความสามารถในการทำอะไรก็ได้ โดยไม่ต้องกังวลถึงทรัพยากร ไม่ว่าจะเป็นความรู้ความสามารถ หรือทรัพย์สินเงินทอง

หลายคนโชคดีหน่อย เกิดมาในตระกูลเศรษฐี ก็มีของเล่นได้หลากหลายชิ้นกว่าเพื่อนๆ

หลายคนขยันหน่อย มีความสามารถโดดเด่น ก็มีชื่อเสียงได้รับการยอมรับจากเพื่อนๆ

แต่ส่วนมากที่ไม่ได้โชคดีอย่างนั้น ก็ย่อมได้แต่ไผ่ฝันในสิ่งที่อยากทำ โดยคิดว่าพอโตเป็นผู้ใหญ่แล้วอุปสรรคต่างๆ คงหายไป ไม่ว่าจะด้วยความรู้ความสามารถที่มากขึ้นตามกาลเวลา หรือด้วยทุนทรัพย์ที่สามารถหามาได้อย่างไม่ยากเย็น

โดยที่ไม่ได้คิดถึงสิ่งที่ต้องแลกมา คือพื้นที่สำหรับความผิดพลาด

ตอนเด็กที่เราเล่นบอลกับเพื่อน จะเตะบอลหลุดนอกกรอบซักกี่ครั้งก็ได้ แต่ถ้าโตมาเป็นนักฟุตบอลอาชีพแล้ว แค่เตะบอลหลุดนอกกรอบเพียงครั้งก็อาจทำให้อนาคตในเส้นทางนี้ดับลงได้

...

จริงๆ จะเทียบอย่างนี้ทั้งหมดก็คงไม่ถูกเท่าไหร่ เพราะถ้าตอนเด็กดันเตะบอลหลุดนอกกรอบในนัดที่มีแมวมองมาคัดตัว ก็อาจทำให้เราพลาดโอกาสที่จะอยู่บนเส้นทางนักฟุตบอลอาชีพได้เช่นกัน

แค่อยากจะบอกว่า ถ้ามันมีโอกาสที่จะให้เราผิดพลาดได้ อย่ารอช้าที่จะลองผิดลองถูกให้เต็มที่

เพราะเราไม่รู้ว่าจะได้มีโอกาสผิดพลาดโดยไม่เจ็บตัวอีกเมื่อไหร่

Feb 1, 2014

อำนาจ

Power tends to corrupt, and absolute power corrupts absolutely. Great men are almost always bad men.

-- Lord Acton

ถ้าเริ่มรู้สึกว่าตัวเองมีอำนาจมากเหลือล้น สามารถตัดสินใจแทนคนอื่นได้ เมื่อจะลงมือทำอะไรก็ไม่มีใครขัดใจ พึงระวังไว้ให้ดี

หึหึหึ