Post Mortem : Sweet Tooth Adventure

Hello! It’s been a while since I post something to my blog. In this opportunity I’d like to tell my technical story about Sweet Tooth Adventure, a mobile game I recently made.

Brief of the Apps

Sweet Tooth Adventure is a bubble shooter mobile game. The gameplay is pretty much like other bubble shooter game you’ve found. You control the cannon to shot everything above. When there are 3 or more bubbles with the same color, those bubbles will explode. The player wins after get the candy placed among the bubbles (which have to be exploded beforehand).

This game was an idea from Mr. Dicky Jiang, the artist for this game. He asked me to assist him to do programming stuff on this game.

Technical Difficulties

Bubble shooter game is a simple game. Everybody knows about it. So no amazingly-strange and new game mechanic should be research. The biggest research for this game was the circle packing of the balls.

Oh, we are using Unity for the game engine.

Circle packing.

Every bubble on a board should snapped smoothly each other. You can’t simply shoot the bubble and stop it when collide with other bubble. The result will be quirky hanging ball. Fortunately there are tons of bubble shooter example game (even an open sourced one!).

Quirky ball placement
You don’t want this

The kind of circle packing we want was triangular packing arrangement. This kind of packing is common in bubble shooter game.

After some readings and code, I can gather the idea to snap the ball was “find the snapped position and smoothly move it to that place.”

Well, but how we know the exact snapped position? There’s a great explanation of it from Feronato’s book by using pythagorean for this problem. By knowing the height and width of the ball, we can know where’s the row and column for the distance of each ball. To find the position I could simply divide the current position by distance and round it to nearest number (using ceil or floor). Here’s some explanation about it in diagram.

Screen Shot 2015-09-20 at 20.54.30

Flood Fill

The other thing I researched was the Flood fill. It’s an algorithm to fill specific area within boundaries. In this case, the boundaries were other ball. Fortunately I have ever use this algorithm for another problem. So it’s only a matter of “tweak” the code a bit for ball colors and specific use (such as bomb ball, rainbow ball, etc)

Editor

I realized we need some kind of editor for bubble placement, for the sake of game design comfort. After some time of difficulties in the making of the editor, I gave up. I asked Mr. Dicky to simply made the drawings for each level and I’ll manually wrote the array of the level. But Mr. Dicky encourage me to finish the editor, because, yeah, it’s actually almost done. I need some time to work on it, and the editor finally can be used for level creation.

Screen Shot 2015-09-20 at 21.45.25
Sweet Tooth Adventure’s level editor

I’m glad Unity is very easy to extends.

Team Management

These tools helped us to make the game:

  1. Facebook Messenger as the main communication.
  2. Trello for the cork board everything should be done.
  3. Dropbox for asset repository. Unfortunately Mr. Dicky’s storage was full, so we also use Google Drive.
  4. Bitbucket for private repository of Git. We used SourceTree to access the repository.

At first we learned to use the tools. After some moments later we could worked together smoothly.

Some points

  1. Do not use single branch of development, so the developer can make changes and push to repository without conflict too often.
  2. So many things learned if you make the game from scratch.
  3. …but of course it’s easier to buy game template and re-skin it.
  4. Make the content easily accessed and modify by the artist or game designer.

    Screen Shot 2015-06-25 at 1.50.15 PM
    The “congratulation” words easily changed

And We are Done!

After about 6 month, we finally managed to get things done! Well.. not everything is done. Still some feature and bugs swarming around the game. We also need to improve the intuitiveness of the interaction.

And again, you can visit the game’s landing page here (Yay! Promo!). Expect the update from us. Apologize for any grammar mistake :p . Thanks for reading!

Finite State Machine

Finite State Machine adalah konsep dari perubahan state menggunakan trigger tertentu. Sebagai contoh dalam game, karakter yang melompat akan melalui state seperti ini (btw, saya menuliskan state dengan kurung kotak[] dan trigger dengan kurung biasa () ):

[Diam] -> (tekan tombol lompat) -> [Melompat]

Jika ternyata karakter bisa menembak saat melompat berarti alurnya menjadi seperti ini:

[Diam] -> (tekan tombol lompat) -> [Melompat] -> (tekan tombol tembak) -> [Menembak]

Penjelasan tentang state pattern yang lengkap ada di buku http://gameprogrammingpatterns.com/state.html. Di buku tersebut dijelaskan daripada membuat state pada satu kode yang memiliki banyak flag dan if, lebih baik state dipisah menjadi per kelas.

Desain dari FSM menggunakan kelas

Alasan setiap state dipisah menjadi kelas dikarenakan pada satu state maka kelas akan memiliki perilaku yang berbeda. Seperti contoh di atas, saat melompat karakter tidak menampilkan gambar diam. Input yang diberikan pada kondisi tersebut juga akan berbeda.

Desain FSM dengan kelas dapat diilustrasikan sebagai berikut:

gambaran state machine

Controller merupakan kelas yang menghubungkan antara tampilan (gambar, animasi, suara, dsb). Dengan menggunakan FSM, controller dipecah lagi menjadi modul-modul state terpisah. Sebagai contoh StateJump, StateIdle, dan seterusnya. Kelas FiniteStateMachine  bertugas mengembalikan state yang sedang digunakan, melaksanakan perintah saat masuk (in), dan keluar (out) dari state. Seluruh perubahan state dan pemberian trigger dikendalikan sendiri oleh masing-masing state yang mengimplementasikan interface IState.

Setiap state disimpan dalam sebuah kelas CharacterStates dalam bentuk statik. Hal ini memungkinan state untuk dipanggil secara flyweight. (Walaupun begitu, state juga bisa melakukan return kelas state yang baru untuk menghindari satu state dipakai bersamaan).

Masing-masing state tersebut diberi akses langsung ke controller untuk mengatur gambar yang ditampilkan, serta input yang diinginkan.

Jika diperhatikan, kelas-kelas state hanyalah sebuah sub controller sekaligus model dari kelas controller. Dengan desain seperti ini, setiap state dapat dikerjakan secara terpisah.

Link github project StateMachine dapat dilihat di sini: https://github.com/igrir/StateMachine

Konsep memprogram di Unity

Coding di Unity bisa menggunakan 3 bahasa pemrograman. Kamu bisa memilih C# (baca: si-sharp), Javascript, atau Boo (mirip Python). Ketiga bahasa ini didukung penuh dan masing-masing dapat memanggil library yang dimiliki Unity. Untuk kemudahan dalam penulisan di buku ini maka seluruhnya akan dijelaskan menggunakan C#.

Unity menggunakan component based dalam pendekatan pemrogramannya. Bagi kamu yang sudah terbiasa dengan object oriented programming (OOP) mungkin akan terasa aneh pada awalnya. Untuk menjembatani antara ketidakbiasaan ini saya akan menjelaskan persamaan dan perbedaan keduanya. Pertama-tama saya akan mengilustrasikan penggunaan OOP.

Object Oriented Programming

Suatu hari kamu ingin membuat sebuah game petualangan. Kamu memiliki sebuah petarung sebagai karakter dari pemain. Kamu membayangkan petarung memiliki nyawa (health point) dan bisa bergerak. Kemudian kamu membuat sebuah kelas Karakter untuk mengakomodir semua itu.

Petarung [Attribut: (integer) healthPoint. Method: move()]

Tidak berapa lama kemudian kamu mulai membayangkan untuk membuat monster yang harus diserang oleh petarung kamu. Monster juga memiliki memiliki nyawa dan bisa bergerak. Karena memiliki kesamaan sifat tersebut maka kamu membuat kelas induk bernama Makhluk, sedangkan kelas Monster dan Petarung merupakan anak dari kelas Makhluk. Desain kelas kamu kemudian menjadi seperti ini:

Makhluk [Attribut: (integer) healthPoint. Method: move()]
  +<inherit> Petarung
  +<inherit> Monster

Agar dapat mengalahkan monster, petarung kamu harus bisa menyerang dengan cara melakukan sihir. Maka kamu membuat metode sihir() di kelas Petarung.

Makhluk [Attribut: (integer) healthPoint. Method: move()]
  +<inherit> Petarung [Method: sihir()]
  +<inherit> Monster

Monster yang kamu buat pun bisa menyerang dengan sihir.

Makhluk [Attribut: (integer) healthPoint. Method: move()]
  +<inherit> Petarung [Method: sihir()]
  +<inherit> Monster [Method: sihir()]

Karena kamu menganggap semua anak Makhluk dapat menyihir maka kamu mendesain ulang susunan kelas menjadi seperti ini:

Makhluk [Attribut: (integer) healthPoint. Method: move(), Method: sihir()]
  +<inherit> Petarung
  +<inherit> Monster

Tak lama kemudian kamu membuat sebuah karakter Hantu yang hanya bisa bergerak, tapi tidak memiliki health point namun bisa menyihir. Kamu bisa merombak lagi desain kelas-kelas kamu menggunakan interface Health… atau mengganti kelas induknya… dan sebagainya.

Component Based

Daripada memecah setiap karakter, kenapa tidak memecah fungsionalnya saja? Sebagai contoh, Petarung memiliki komponen HealthMove, dan Magic. Kemudian Monster memiliki komponen yang sama dengan karakter. Sedangkan untuk karakter Hantu kamu cukup menambahkan komponen Move dan Magic saja. Berarti kamu cukup membuat 3 komponen saja sebagai berikut:

Health
Move
Magic

Keuntungan Menggunakan Component Based

Component based terasa lebih sederhana. Selain itu di Unity setiap komponen akan terlihat terpisah di window Inspector. Kamu juga bisa mengedit variabel yang dibuat public pada window ini. Hal ini sangat penting untuk melakukan balancing pada permainan kamu.

Screen Shot 2015-03-16 at 4.31.17 PM
Script “UlarControl” ada di window Inspector dan dapat diedit variabel public nya seperti “Rotate Speed”, “Speed Ratio”, dan sebagianya untuk kebutuhan balancing

Selain itu jika kamu memiliki karakter baru, katakanlah Kucing, kamu cukup menambahkan komponen bergerak. Mudah sekali bukan?

 

 

Bahan bacaan lain yang menarik untuk menjelaskan tentang penggunaan component based ini bisa kamu lihat di tautan berikut:

http://gamedevelopment.tutsplus.com/articles/unity-now-youre-thinking-with-components–gamedev-12492


[[Daftar Isi]]

GUI

Unity memiliki fitur membuat GUI yang bisa digunakan pada game 2D maupun 3D. Di subbab ini akan dibahas gambaran umum GUI dan penggunaannya.

GUI

GUI merupakan singkatan dari Graphical User Interface. Kegunaannya sebagai tampilan masukan dari pemain. Di Unity pembuatan GUI bisa digunakan di sub menu GameObject > UI.

Screen Shot 2015-03-12 at 12.12.11 AM
Beragam UI yang disediakan

 

 

Pengenalan UI

Sebagai perkenalan, mari kita coba dengan membuat komponen UI baru berupa Button.

Screen Shot 2015-03-12 at 12.25.20 AM
Game object yang baru dibuat

GameObject UI yang baru akan muncul di window Hierarchy; antara lain Canvas, Button yang tadi kita pilih, dan EventSystem. EventSystem digunakan oleh UI untuk mendeteksi masukan seperti sentuhan, kontrol, dan sebagainya. Penggunaan UI lebih banyak digunakan di dalam Canvas.

Canvas bertindak sebagai representasi dari tampilan layar. Jika dilihat pada window Game, posisi UI yang berada di dalam kanvas akan sesuai dengan posisi kanvas.Screen Shot 2015-03-12 at 12.27.25 AMSetiap game object UI memiliki komponen bernama Rect Transform. Pada komponen ini UI memiliki pengaturan dimensi. Pada komponen ini juga terdapat fitur Anchor Presets. Fitur ini berguna untuk memposisikan komponen relatif terhadap ukuran kanvas. Hal ini berguna untuk ukuran layar yang berbeda-beda sehingga game yang dibuat memiliki posisi GUI yang konsisten.

Anchor Presets
Anchor Presets

Informasi Detail

Penjelasan lebih detail mengenai penggunaan GUI bisa kamu temui di link berikut:

  1. Unity New GUI Tutorial
  2. Modul UI Unity
  3. UI Reference

 

[[Daftar Isi]]

Memulai Proyek

Yes! Let’s get started! Di bab ini kita akan membahas tentang menu dan fitur-fitur yang ada di Unity. Kemudian setelah itu kamu akan disuguhi struktur folder-folder yang disiapkan dalam membuat game supaya rapi. Di bagian akhir saya akan menunjukkan konsep memprogram component based yang ada di Unity.

Di buku ini saya menggunakan C# sebagai bahasa pemrogramannya karena saya sudah terbiasa menggunakan bahasa ini.

[[Daftar Isi]]