Alat pengembangan
Jangan coba menciptakan ulang roda (sepenuhnya)!

Keputusan
Di artikel tentang awal mulanya mungkin kamu sudah membaca bahwa saya memutuskan untuk membuat game.
Ada sangat banyak cara untuk melakukan hal seperti itu, dan setiap situasi butuh pendekatan yang berbeda. Satu-satunya yang saya tahu 100% adalah game-nya harus berupa petualangan point and click old school dalam 2D.
Dengan begitu banyak alat pengembangan langsung gugur, tapi masih ada beberapa pertanyaan:
- Pakai bahasa pemrograman apa?
- Di platform apa game ini harus berjalan?
- Engine atau framework apa yang akan dipakai?
- Forum dukungan?
Bahasa pemrograman
Saya sudah bisa memakai PHP, C#, Python, Javascript, Node, Blitz 3D, Monkey X, Monkey 2. Dengan dua bahasa terakhir saya sudah pernah membuat prototipe. Tapi pengembang bahasa itu berhenti, jadi saya tidak lagi yakin hasilnya akan baik dan waktu itu saya juga berhenti.
Jadi harus bahasa yang sederhana dan bisa diandalkan. Saya suka kesederhanaan dan juga tidak punya waktu untuk benar-benar menguasai bahasa baru.
Engine
Game engine seperti Unreal Engine ada untuk membuat pekerjaan jauh lebih mudah. Karena itu pencarian saya dimulai dengan mempelajari daftar lengkap https://en.wikipedia.org/wiki/List_of_game_engines.
Banyak yang langsung gugur karena saya tidak mau mengeluarkan uang untuk engine, setidaknya bayar sekali saja tidak masalah. Tapi jelas bukan konstruksi lisensi yang aneh dan tidak jelas seperti yang dibuat beberapa engine. Saya juga ingin engine itu masih aktif dikembangkan dan bukan C atau C++. Dan tentu saja 2D.
Ya, Unreal Engine juga bisa 2D, tapi itu bertentangan dengan prinsip saya ’less is more’. Engine seperti itu punya terlalu banyak fungsi yang tidak akan saya pakai dan hanya bisa rusak. Karena itu engine seperti itu juga gugur.
- Adventure Game Studio
- Windows, dan saya tidak bisa membuat semua yang saya bayangkan di sana.
- Construct
- Masalah lisensi, terlalu mahal, dan bayar bulanan
- Flixel
- Saya tidak mau memakai ActionScript
- GameMaker Studio
- Terlalu tua, masalah lisensi, dan menurut saya kurang keren haha
- LÖVE
- Mantap! Tapi masih saya teliti
- Monkey X
- Dulu saya mulai dengan ini, tapi sudah tidak ada dukungan lagi
- Pygame
- Menarik, tapi akhirnya bukan ini
- HaxeFlixel
- Tidak, pokoknya tidak
- Cocos2d
- Menarik, tapi tidak, menurut saya kurang sederhana
- Godot
- Menarik, tapi tidak, menurut saya kurang sederhana
- Unity
- Masalah lisensi
Kesimpulannya, ternyata saya memang ingin membuat sesuatu sendiri. Harus punya lisensi terbuka MIT atau yang mirip, dan serbaguna. Dari riset ternyata beberapa engine di atas memakai SDL2, dan saya harus tahu lebih banyak soal itu.
SDL2
Kalau kamu mencari tahu bagaimana software dan hardware bekerja sama untuk menggerakkan gambar di layar lewat kartu grafis (dan suara), kamu akan melihat bahwa Windows memakai DirectX, Ubuntu OpenGL, dan Mac Metal/Vulkan. Dan Windows serta Mac juga bisa memakai OpenGL…
Jadi setiap platform punya library sendiri yang ditulis dalam bahasanya sendiri. Sangat merepotkan, karena kamu tidak mau menulis ulang kode untuk setiap platform. Yang kamu mau adalah menulis kode 1 kali dan jalan di mana saja.
Solusi untuk masalah ini adalah library https://www.libsdl.org. Library ini gratis dengan lisensi yang tepat, dan dengan kode yang sama kamu bisa memakai semua platform. SDL2 ditulis dalam C, dan ada beberapa binding yang memungkinkan SDL2 dipakai di bahasa pemrograman lain.
Karena saya tidak mau memakai C, saya mencoba seluruh daftar binding:
- C
- Menurut saya tidak praktis
- C#
- Gugur, karena di rumah saya memakai Mac
- GO
- Sebenarnya saya suka dan sederhana, tapi harus di-compile setiap kali
- Haskell
- Mengerikan, sama sekali bukan yang saya cari
- Rust
- Eh, ini terlalu sulit, tiba-tiba saya harus memprogram secara fungsional
- Lua
- Menarik dan sederhana
- Python
- Entah kenapa tidak cocok, dan saya juga malas harus memasang TAB di mana-mana.
- Nim
- Sepertinya tidak ada yang memakainya
Di titik ini yang tersisa adalah GO dan Lua, dan di pencarian engine sebelumnya saya sudah melihat LÖVE.
LÖVE
Framework https://love2d.org memenuhi semua syarat saya.
Saya tidak menyebutnya engine tapi framework, karena isinya hanya fungsi-fungsi yang memakai SDL2 secara dasar. Dan itu persis yang saya cari, semua poin saya terpenuhi:
- Ada forum di mana semua orang masih suka membantu dan ramah.
- Framework-nya sederhana (less is more).
- Bahasa Lua sederhana dan sudah dipakai bertahun-tahun.
- Target platform tempat game ini akan berjalan.
function love.draw()
love.graphics.print("Hello: Signal From The Stars", 400, 300)
end
Lua

Logo resmi Lua
Saya tinggal belajar Lua, jadi apa yang kamu lakukan? Kamu pergi ke rumah orang tua untuk mencetak seluruh manual Lua… Mereka tidak terlalu senang.
Akhirnya ternyata bahasanya begitu sederhana sampai saya tidak butuh manualnya.
Menurut saya Lua bisa dianggap sebagai wrapper yang berbicara dengan C. Keuntungan lainnya, kamu tidak perlu terus menunggu compiler setelah setiap perubahan kode.
Tentu ada juga kekurangannya, misalnya tidak secepat C, tapi itu bukan masalah.
Target
Game Signal From The Stars minimal harus berjalan di Mac, Windows, dan iOS (iPad). Nanti Nintendo Switch, Ubuntu, dan Android akan ditambahkan. Kemungkinan juga bisa berjalan di Xbox dan PlayStation, tapi tidak langsung out of the box.
Gambar
Game ini juga akan punya gambar, dan untuk itu awalnya saya memakai program Aseprite, karena ada mode pixel perfect. Itu gaya tertentu yang saya pakai. Tapi belakangan saya beralih ke Adobe Photoshop. Nanti saya akan menulis artikel tentang itu.
Semua gambar lalu diproses secara optimal lewat TexturePacker https://www.codeandweb.com/texturepacker, lalu hasilnya diproses lagi dengan script.
Script
Dibutuhkan beberapa script terpisah untuk merapikan hal-hal tertentu. Sebagian besar dalam Lua, tapi nanti akan bertambah terus.
Shell
#!/bin/bash
cd ../
luacheck --no-cache --config scripts/.luacheckrc src
cd src/lib/engine3/scripts/
echo "UNIT TEST"
./unittest.sh
echo "INTEGRATION TEST"
./integrationtest.sh
Node
Pilihan Node hanya karena ada modul yang bisa membaca file Adobe Photoshop (https://github.com/meltingice/psd.js). Masih saya pakai, dan mengubah file Photoshop menjadi aset dan Atlas untuk game.
Kalau waktu itu saya menemukan hal yang sama di Python, saya tidak akan memakai Node. Entah kenapa Node dengan miliaran library-nya tidak benar-benar cocok dengan yang saya cari, mengingatkan saya sedikit pada neraka DLL di Windows.
Python
Saya menyesal tidak menulis lebih banyak Python. Di bawah ini adalah satu-satunya script yang saya pakai di Python saat ini, tapi penting. Dengan ini saya bisa menemukan garis luar dari file .png transparan dan menyederhanakan koordinatnya.
# python3 outline.py
# pip3 install pillow
# pip3 install opencv-python
import sys
import cv2
import numpy as np
import json
import os
import argparse
def find_outer_contours(image_path, simplify=0):
img = cv2.imread(image_path, cv2.IMREAD_UNCHANGED)
mask = img[:, :, 3] > 0
contours, _ = cv2.findContours(mask.astype(np.uint8), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
min_contour_size = 5
filtered_contours = [contour for contour in contours if cv2.contourArea(contour) > min_contour_size]
if simplify > 0:
simplified_contours = []
for contour in filtered_contours:
epsilon = simplify * cv2.arcLength(contour, True)
simplified_contour = cv2.approxPolyDP(contour, epsilon, True)
simplified_contours.append(simplified_contour)
return simplified_contours
else:
return filtered_contours
def draw_and_save_contours(contours, output_path, original_size):
img = np.zeros((original_size[1], original_size[0]), dtype=np.uint8)
cv2.drawContours(img, contours, -1, (255), thickness=1)
cv2.imwrite(output_path, img)
def contour_coordinates_to_json(contours):
contour_coordinates_list = []
for contour in contours:
contour_coordinates = []
for point in contour:
x, y = point[0]
contour_coordinates.append([int(x), int(y)])
if len(contour_coordinates) % 2 != 0:
contour_coordinates.append([contour_coordinates[-1][0], contour_coordinates[-1][1]])
contour_coordinates_list.append(contour_coordinates)
return json.dumps(contour_coordinates_list)
def apply_convex_hull(contours):
combined_contour = np.concatenate(contours)
hull = cv2.convexHull(combined_contour)
return [hull]
def create_rectangles(contours):
rectangles = []
for contour in contours:
x, y, w, h = cv2.boundingRect(contour)
rectangles.append((x, y, x + w, y + h))
return rectangles
def rectangles_to_json(rectangles):
json_output = json.dumps(rectangles)
return json_output
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Find outer contours of a transparent image.')
parser.add_argument('image_path', type=str, help='Path to the image file.')
parser.add_argument('--simplify', type=float, default=0.01, help='Simplify factor for contour approximation. Set to 0 to disable simplification.')
parser.add_argument('--hull', action='store_true', help='Apply convex hull to the contours.')
parser.add_argument('--rects', action='store_true', help='Return contour x1,y2,x2,y2 outline rects')
parser.add_argument('--output_path', type=str, default='', help='Path to save the output image. If not provided, the image will not be saved.')
args = parser.parse_args()
image_path = args.image_path
original_img = cv2.imread(image_path, cv2.IMREAD_UNCHANGED)
original_size = (original_img.shape[1], original_img.shape[0])
contours = find_outer_contours(image_path, simplify=args.simplify)
if args.hull:
contours = apply_convex_hull(contours)
if args.output_path:
draw_and_save_contours(contours, output_path, original_size)
if args.rects:
rectangles = create_rectangles(contours)
json_output = rectangles_to_json(rectangles)
print(json_output)
else:
json_output = contour_coordinates_to_json(contours)
print(json_output)
Git
Semuanya dilacak dan disimpan di git dan BitBucket, karena BitBucket punya beberapa repo privat (gratis).
Editor
Saya sudah mencoba beberapa editor, tapi secara pribadi Visual Studio Code yang paling cocok untuk saya. Tentu dengan beberapa ekstensi.
- Code Runner
- Love2D Support
- Markdown Preview Enhanced
- reStructuredText Syntax highlighting
- vscode-lua
Dengan begitu saya bisa menjalankan ulang game dengan satu tekan tombol, dan kalau perlu melakukan debug. Syntax highlighting juga sangat melegakan untuk saya. Auto-complete sebenarnya tidak pernah saya pakai.
Menulis cerita
Dan sekarang bagian anehnya. Kamu mungkin berpikir Word, LibreOffice, Markdown… Tapi saya menulisnya dalam file reStructuredText (.rst).
===========================
Scene 20: Nederland - Intro
===========================
.. image:: ../project/story/scene/20/resources/scene20.png
:width: 100%
.. contents::
:depth: 1
.. raw:: pdf
PageBreak
Omschrijving
============
Een bos in Nederland in de len...
Semua file .rst ada di berbagai folder, dan dengan script di bawah saya mengekspornya ke PDF. Lalu mencetaknya.
Tentang petualangan ini tentu saja nanti saya akan menulis artikel.
#!/bin/bash
set -e
source config
if [ -n "$1" ]; then
TARGET_SCENE="$1"
TARGET_PDF="scene_${TARGET_SCENE}.pdf"
echo "Generating PDF for scene $TARGET_SCENE"
else
echo "Generating all PDF files"
fi
mkdir -p ../temp/docs/
for dir in ../project/story/scene/*; do
SCENE_NUMBER=$(basename "$dir")
PDF_NAME="scene_${SCENE_NUMBER}.pdf"
if [ -z "$TARGET_PDF" ] || [ "$PDF_NAME" = "$TARGET_PDF" ]; then
echo -e "Create: $PDF_NAME"
# merge *.rst scene files
first_iteration=true
TEMP_FILE=$(mktemp tempfile.XXXXXX)
for md_file in $(ls "${dir}"/*.rst | sort); do
TEMP_CONTENT=$(mktemp /tmp/tempcontent.XXXXXX)
if $first_iteration; then
first_iteration=false
else
item_number=$(basename "$md_file" .rst | cut -d'-' -f1)
item_description=$(basename "$md_file" .rst | sed -E 's/^[0-9]+-//; s/-/ /g')
title=""
# inventory item ends with 9
if [ ${#item_number} -eq 6 ] && [[ "$item_number" == *"9" ]]; then
title="$item_number $item_description (inventory)"
else
title="$item_number $item_description"
fi
title_length=${#title}
separator=$(printf '=%.0s' $(seq 1 $title_length))
echo -e "$title\n$separator\n" >> "$TEMP_CONTENT"
fi
cat "$md_file" >> "$TEMP_CONTENT"
echo -e "\n\n.. raw:: pdf\n\n PageBreak\n" >> "$TEMP_CONTENT"
cat "$TEMP_CONTENT" >> "$TEMP_FILE"
rm "$TEMP_CONTENT"
done
rst2pdf --footer="###Page### | ###Title###" "$TEMP_FILE" --output="../temp/docs/${PDF_NAME}"
rm "$TEMP_FILE"
if [ $# -eq 1 ]; then
echo "Opening $PDF_NAME..."
open "../temp/docs/${PDF_NAME}"
fi
fi
done
if [ $# -eq 0 ]; then
echo -e 'Create: concept_document.pdf'
rst2pdf --footer="###Page### | ###Title###" ../project/story/concept-document.rst --output="../temp/docs/concept_document.pdf"
echo -e 'Create: story_notes.pdf'
rst2pdf --footer="###Page### | ###Title###" ../project/story/notes.rst --output="../temp/docs/story_notes.pdf"
fi
Diagram
Seluruh cerita tentu berisi teka-teki, dan saya membuatnya terlihat secara visual untuk diri sendiri dengan program gratis (https://app.diagrams.net).
Yaml
Supaya semuanya bisa disusun dengan mudah di awal, saya memilih untuk tidak menghabiskan waktu membuat editor game. Seluruh game disusun dengan file .yaml yang diubah menjadi json dan dipakai di dalam game.
Gambaran
Kalau kamu melihat semua yang sudah saya tulis sejauh ini, hasilnya adalah skema di bawah.
Di situ ada engine3 dan game, yang akan saya jelaskan di postingan lain.
Diagram alat yang akhirnya dipakai