

Screwsmith
OyunVidaları sök, renkleri ayır, makinelerin katmanlarını keşfet.
TEKNOLOJİ
Unity ile geliştirdiğimiz mobil oyunlardan: deterministik seviye üretimi, çözücüyle zorluk ölçümü, okunabilirlik denetimi, sunucuda doğrulanan simülasyon.
KISA CEVAP
AMG Yazılım, Unity ve C# ile mobil bulmaca ve casual oyunlar geliştiriyor. Tilting Jar ve Puzzle Reveal App Store’da yayında; Screwsmith, SUNTHREAD, WARDLIGHT ve BEEing geliştirmede, One Shot ise bir prototip. Seviyeleri deterministik üretiyor, çözücüyle ölçüyor ve raporu depoda tutuyoruz: WARDLIGHT’ta taranan 3200 seviyenin tamamı çözülebilir ve yeniden üretimde bayt bayt aynı.
Mobil oyunlarımızı Unity ve C# ile geliştiriyoruz; Tilting Jar, Puzzle Reveal, SUNTHREAD, WARDLIGHT, Mosquito ve BEEing Unity 6 üzerinde. Durumlarını olduğu gibi yazıyoruz:
Bu sayfadaki rakamlar oyunların depolarındaki README, plan, ilerleme ve rapor dosyalarından alındı.
Herkes aynı seviyeyi oynamıyorsa ne zorluk ayarlanabilir ne de bir hata raporu yeniden açılabilir. Bu yüzden seviye üretimini tekrarlanabilir kuruyoruz:
seed = (uint)(level * 2654435761).System.Random yerine xorshift32 ile üretiliyor, böylece her platformda ve her Unity sürümünde çıktı aynı.Determinizmi oyun mantığını motordan ayırarak koruyoruz. Screwsmith.Core ve Wardlight.Core katmanlarında hiç UnityEngine referansı yok ve bunu asmdef zorunlu kılıyor. SUNTHREAD ve WARDLIGHT üreticileri önce Node’da referans olarak yazıldı; C# portu golden fixture’larla bayt bayt karşılaştırılıyor. Screwsmith’te seviye üretimi ve ölçümü -batchmode ile, editör penceresi açılmadan komut satırından koşuyor.
Mükemmel oyuna göre ölçülen zorluk yanıltıcı, çünkü neredeyse her seviye mükemmel oyunla geçiliyor. Screwsmith’in çözücüsü bu yüzden iki sayı üretiyor: mükemmel oyunda gereken en az ray yuvası ve makul bir insanın seviyeyi ne sıklıkla kaybettiği. Çözücü her seviyeyi 24 kez sığ bir stratejiyle oynuyor; kayıp oranı zorluk puanının baskın terimi (×11). 200 pişirilmiş seviyenin 157’si hedef banda tam isabet etti, 34’ü bir bant saptı. Eğri kasıtlı: 1–35 arasında ortalama insan kayıp oranı %0,8, seviye 36 bilinçli bir duvar (%37,5), 101–200 arası %34.
SUNTHREAD’de soru farklı: oyuncu gerçekten karar veriyor mu? WARDLIGHT motorunda 400. seviyede hamlelerin %100’ü zorunluydu. SUNTHREAD’in üreticisi beş kapı koyuyor: tek çözüm, silinemeyen ipuçları, yalnız isimlendirilmiş kurallarla ilerleyen insan tarzı bir çözücü, %35–70 bandında zorunlu hamle oranı ve son beş seviyeyle aynı kural kümesini reddeden bir parmak izi. Ölçülen oran 0,44 ile 0,79 arasında, ortalama 0,59.
Puzzle Reveal’da ilk sürümün formülü oyunu üçüncü seviyeden sonra kazanılamaz yapıyordu. 50 seviye elle ayarlandı; zorluk yöneticisi %65 kazanma oranını hedefliyor.
Bir seviyenin çözülebilir olması, oyuncunun onu okuyabildiği anlamına gelmiyor. Screwsmith’teki ReadabilityAudit piksel gerçeklerini oyun testinden önce yakalıyor: tahtayı gerçek cihaz çözünürlüğünde bir RenderTexture’a çiziyor ve seviyeyi oynarken her durumda yeniden ölçüyor.
Undo için de aynı yaklaşım geçerli. Çözücü geri dönerken oyunun kendi undo’sunu kullandığı için buradaki bir hata ölçümleri de bozuyor. UndoAudit.Run 200 seviyenin her birinde 60 hamleye kadar rastgele geçerli hamle yapıyor ve hamle öncesi tahtayı geri alma sonrasıyla karşılaştırıyor. Denetime güvenmeden önce bozuk bir simülasyona karşı başarısız olduğunu UseLegacyCrateUndo ve corruptSnapshot ile gösterdik.
Mosquito’da benzer bir kalite kapısı yedi ekranda ve altı cihaz çözünürlüğünde taşma arıyor.
One Shot günde tek atışla oynanan rekabetçi bir fizik bulmacası ve şu an bir prototip. Rekabetin şartı, aynı sahnenin herkeste birebir aynı davranması; kayan noktalı fizik ise motorlar ve derleyiciler arasında sapabiliyor.
Simülasyon çekirdeği UnityEngine’den bağımsız yazıldı ve CI bunu zorunlu tutuyor. Aynı .cs dosyaları üç çalışma zamanında derleniyor: Unity Mono, IL2CPP oyuncu derlemesi ve .NET 10 sunucu. 20 altın fixture üçünde de bayt bayt aynı sonucu veriyor.
Atış, girdi kaydıyla sunucuya gidiyor ve verify-shot onu yeniden simüle ediyor. Dürüst atış geçiyor; sahte bir "1 µm isabet" uyuşmazlık olarak işaretleniyor ve liderlik tablosu sunucunun sayısını tutuyor; imkânsız bir girdi kaydı reddediliyor. shots tablosunda user_id + scene_seed benzersiz, ikinci deneme 409 alıyor; spoiler duvarı Supabase RLS ile kapalı. Görsel smoke testleri sahneyi PNG’ye çizip boş olmadığını denetliyor ve dört gerçek görsel hatayı bu yolla yakaladı.
Son sözü sunucuya bırakma ilkesi başka oyunlarda da var: BEEing’de skor makullük denetimi ve sunucu zamanlı çevrimdışı kazanç, Mosquito’da skor ve kapılar Supabase Edge Function’larında doğrulanıyor.
Unity’den mağazaya giden yolda tek bir eksik ayar, uygulamanın açılışta çökmesi demek. Puzzle Reveal’da 13 numaralı derlemedeki açılış çökmesinden sonra zincir betiklendi: derleme, görsel testler, build numarası, iOS dışa aktarma ve Info.plist kapıları (AdMob kimliği, ATT metni, SKAdNetwork) tek komutta; bir kapı düşerse zincir duruyor. Bu yaklaşım sonraki oyunlarda da kullanılıyor. Tilting Jar’da Unity → Xcode → pod install adımları tek komutta yürüyor ve AdMob kimliği eksikse derleme durduruluyor.
Reklam ve satın alma katmanlarını sağlayıcıdan bağımsız kuruyoruz. Tilting Jar’da anahtar boşken oyun sahte bir mağazayla çalışıyor. WARDLIGHT’ta reklam, satın alma, analitik ve bulut senkron arayüz arkasında; oyun editörde tek SDK olmadan açılıyor. Bulut ve analitik için SDK yerine UnityWebRequest ile REST kullanıldı, çünkü IL2CPP’de güvenli ve paketi şişirmiyor.
Teklif motoru da ölçüme dayanıyor. Tilting Jar’da "reklamları kaldır" ancak beş geçiş reklamı gerçekten görüldüyse öneriliyor, ödüllü reklam hiç engellenmiyor ve ilerleme hiçbir zaman paraya kilitlenmiyor. İndirme, gelir ya da elde tutma garantisi vermiyoruz; ekonomi ve entegrasyon kapsamı ayrıca değerlendiriliyor.
Evet. WARDLIGHT’ta oyna.html prototipindeki seviye üreticisi Node’a birebir çıkarıldı ve altın referans oldu; tek değişiklik, duvar saatine bağlı arama sınırının sabit bir işlem tavanıyla değiştirilmesiydi. C# portu bu referansa karşı EditMode testlerinde karşılaştırılıyor. Prototip aşamasında temel döngüyü, kontrol hissini ve oyuncunun kararlarını değerlendiriyoruz; tam üretime geçiş bu değerlendirmeden sonra kararlaştırılıyor.
Raporla. WARDLIGHT’ta taranan 3200 seviyenin 3200’ü çözülebilir; aynı seviyeler iki kez üretildiğinde çıktı bayt bayt aynı. SUNTHREAD’de 320 seviyenin her biri JSON’dan yeniden kurulup beş adımda test ediliyor ve sonuç sıfır hata. Raporlar depoda duruyor ve istendiği an yeniden koşuyor. Screwsmith’te kazanan her aday, gönderilmeden önce kanıt aramasıyla bir kez daha doğrulanıyor.
Evet; analitik olaylarını sorunuza göre kuruyoruz. WARDLIGHT’ta müşteri tam olarak bunu sordu: uygulama hangi seviyede arka plana atıldı, oyuncu kaçıncı denemede yakalandı. Arka plana geçiş hem OnApplicationPause hem OnApplicationFocus üzerinden dinleniyor, çünkü Run-In-Background açıkken HOME tuşu pause değil focus üretiyor; olay tek kez loglanıyor. level_fail_caught deneme sayısını taşıyor.
Oyuna göre değişiyor; bazen hiç gerekmiyor. Screwsmith’in Günlük Tezgâhı tarihten tohumlanıyor, sunucu ve hesap istemiyor. Tilting Jar ilerlemeyi iCloud’a yedekliyor ve alan bazında en iyi değerle birleştiriyor. Sunucu kullanan oyunlarımızda Supabase var: BEEing’de 7 migration ve 14 Edge Function skor denetimi, çevrimdışı kazanç ve remote config’i taşıyor; WARDLIGHT Supabase ve Firebase’e SDK yerine REST ile bağlanıyor.
Dil sayısı kapsamın bir parçası olarak belirleniyor. Tilting Jar beş dilde (TR, EN, DE, ES, FR) ve dili otomatik algılıyor. BEEing için mağaza ekran görüntüleri, fragmanlar ve ASO metinleri altı dilde hazır: 8 sahne × 6 dil, telefon ve tablet için ayrı. Screwsmith’in Türkçe ve İngilizce mağaza metinleri Apple’ın karakter sınırlarına göre yazıldı.
Motordan bağımsız C# katmanları EditMode’da, oynanış PlayMode’da test ediliyor. WARDLIGHT’ta 40/40 EditMode testi, SUNTHREAD’de 27 EditMode ve 34 PlayMode testi yeşil. BEEing’de 152 EditMode, 123 simülasyon ve 23 kooperatif smoke testi var; bir PolicyBot üç persona ile yedi gün oynayıp değişmezleri kontrol ediyor. Mosquito’da 25 PlayMode testi bir otopilot botuyla koşuyor.
Size. App Store ve Google Play geliştirici hesapları, sunucu ve servis hesapları sizin adınıza açılır. Teslimde kaynak kodun tamamını, tasarım dosyalarını ve tüm erişimleri size devrederiz.
Hayır. Kullanıcı ekranlarını ve yönetim paneli ekranlarını projenize özel olarak tasarlayıp sıfırdan geliştiririz. Böylece panel, sizin iş akışınıza göre çalışır.
İLGİLİ STÜDYO NOTLARI


Vidaları sök, renkleri ayır, makinelerin katmanlarını keşfet.

Cam kavanoza şeker istifliyorsun. Kavanozun kendi aklı var.


Sabahın ilk ışınısın. Uyuyan bahçeden tek bir ışık ipliği geçiriyorsun.


Karanlık bir zindandan tek bir ışık çizgisiyle kaçıyorsun. Fener alevleri canların.


Her gün tek atışla oynanan rekabetçi fizik bulmacası.


Parça parça açılan bir görsel bulmaca.
Bir tanışma görüşmesiyle başlarız. Kapsamı ve takvimi birlikte netleştirir, size yazılı bir teklif göndeririz.
hello@amgsoftwarestudio.com