Tanshaydar'ın Mekânı
Başka bir şey yok
Kategori: Neon Town, Oyun Geliştirme, Unity

[Neon Town] Basit Bir Hata Beni Ne Maceralara Sürükledi

Veya, Neonların Altında Öngörülemeyen Problemler ile.
Neon Town geliştirme süreci üzerine daha fazla yazmam gerekiyor ve bu eksikliği aslında teknik detayları paylaşarak kapatmayı planlıyor(d)um.
Bu noktada da geçen haftalarda atlattığım süreci, başıma gelenleri anlatmam belki uygun bir başlangıç olur. Bu yazı, bir talihsiz serüvenler dizisi gibi arka arkaya verdiğim aptalca kararların ve gözden kaçırdığım önemli teknik detayların en sonunda gelip beni ısırmasını anlatacaktır. İçinde teknik detaylar olmakla beraber, daha çok kendime kızdığım durumlardan bahsediyor olacağım.

Gerçi önce bilmeyenler için Neon Town’ın ne olduğundan kısaca bahsetmem daha uygun olacak sanırım.
2015 yılının ortalarında freelance oyun programlama işi almıştım. Sonra o oyun iptal oldu. Her ne kadar benimle alâkası olmadığı söylense de, ben hâlen daha işin içinde benim halt yemem var diye düşünüyorum. Her neyse. Sonra o proje değişti ve bugünkü hâlini alacak şekilde yeniden başladı.

Bu süreçte belli başlı sebeplerden dolayı geliştirmeye birkaç kere ara verildi; ama genel olarak programcı olarak başladığım noktadan, lider programcıya, oradan da oyun mekanikleri ile hayati kararların beraber verildiği bir ekip üyesine dönüştüm. Tabii ki Lead Programmer dışında bir credits ekranı yerim olmayacak; ama oyun geliştirmeye isim yapmak veya para kırmak için girenlerin sonunun ne olduğuna dair sayfalarca yazabilirim kendi tecrübemden. Her neyse.

Pekâlâ, konuya geri dönelim. Her şey, ben oyuna dinamik gölgelendirme ekledikten sonra başladı (onunla alâkalı da uzun bir yazı yazacağım). Bu dinamik gölgelendirmenin ne olduğuna dair şöyle ufak bir görsel verebilirim.

Priestess isimli boss’un asasını salladığında oluşan gölgelendirmeyi görebiliyorsunuzdur sanırım. Bununla beraber collider’ların hepsi de animasyonlarla beraber güncelleniyor. Normalde bu sistemi yapmak istemiyordum, çünkü zordu, çünkü çok iş gerektiriyordu, çünkü iyi bir planlama gerektiriyordu, falan filan, ve açıkçası çok fazla hata üretmesi muhtemel bir senaryoydu (ki öyle de oldu). Benjamin bana yapılıp yapılamayacağını sorduğunda çok iş dedim ve salladım. Sonra kendimi çok üretken hissettiğim bir Cuma akşamı oturup yapmaya başladım.

En başta yaptığım sistemde pek bir cache mekaniği kullanmadığım için her sahnenin yüklenmesi sırasında aşağı yukarı bir iki saniyelik gecikme oluyordu. Ama ecnebilerin dediği gibi don’t fix it, if it ain’t broken (çalışıyorsa elleme) mantığı ile öylece bıraktım, çünkü aşağı yukarı istenen sonuçları veriyordu. Sonra o sistemde herhangi bir hataya karşı dinamik olarak boşlukları doldurabilmesi için bir kod parçası ekledim, ve oraya da öyle bir durumla karşılaşıp karşılaşmadığını anlamak için bir debug mesajı koydum. (sprite is null. Mesaj buydu. Çok önemli bir ayrıntı.)

Teknik açıklama olarak, runtime sırasında sprite verisini okuyarak bir PolygonCollider2D component’i oluşturuyor, bunun verisini var olan bir GameObject’e ekliyor, sonra da o collider’ın nokta verisini gölge oluşturan nesneye aktarıyordum. Normalde bu işi Awake fonksiyonunda (oyun başında çalışan fonksiyon) yaptığım için her şey zaten cache edilmiş durumda oluyordu o runtime instance’ı için; ama hadi gözümden kaçtı bir şey oldu diyelim, o noktada da (C#) Dictionary’de olmayan verileri o anda yaratıp ekliyordum. Birinci ve en büyük hatayı burada yaptım, tüm sprite’ları dosyadan teker teker bir listeye ekleyip oradan yaratıyordum bu veriyi. Şimdi düşününce, işin ameleliği bir yana, bu kadar kötü bir tasarım kararını nasıl vermişim bilmiyorum. Yani kafam güzeldi filan diyeceğim de uzun süredir alkol ile aram yok. Bilemedim. Neyse.

Ve beklenen patlama, birkaç hafta sonrasında geldi. Benjamin bana “aga bu çalışmıyor” dediğinde, “nasıl la” tepkisi dışında bir şey veremedim. Dedim video çek, bir de bana log dosyasını gönder, “Ask and you shall receive” gibi bir durum oldu ve log dosyası milyonlarca satıra ulaşmıştı…

Siz hiç 2.6 GB log dosyası gördünüz mü? Ben gördüm. Aynı hata satırı birkaç milyon defa geçiyor. Çok güzel, değil mi 🤦

Hatayı araştırdığımda, beni inanılmaz şekilde yanlış yönlendiren bir cevaba ulaştım. Unity’ye import edilen Sprite dosyalarının Read/Write enabled olmadığı durumlarda böyle bir problem oluşturduğunu gördüm o cevapta. Kendi import ayarlarımda bunu açmamış olmamın sebebi, zaten her şeyin oyun başlamadan önce ‘initialization time‘da yapılmasıydı. Ayriyetten, read/write açık olan Sprite’lar iki kat yer kaplıyor RAM’de, ve batching pek mümkün olmuyor. Gerek var mı? Yok demiştim, ama bu hata ile karşılaşınca o Yok bir anda Hmmm‘a dönüşüverdi, eğer hata bundan ibaretse tüm dinamik işlemlerde kullanılan Sprite’ları Read/Write enabled yaparım olur biter dedim, inanılmaz zeki bir biçimde. Kafa zehir ya. Yani zaten 1GB altında RAM kullanıyor oyun, o kadar sağlam optimizasyon yapmışım. Bazen o kadar zekice (!) düşünüyorum ki, bir şey haddini aştığında zıddına inkılab eder sözünce aptalca işler yapıyorum. Neyse, gidip tüm Sprite’ların import ayarlarında Read/Write enabeld yaptım, üstüne bir de yürümüşken MipMaps açayım dedim (bu nasıl aklıma geldi hiçbir fikrim yok!), el değmişken girişelim işte ne var dedim, ve build almaya başladım.

İkinci ve daha büyük patlama burada yer aldı.

Bakın, geçenlerde şöyle bir tivit atmıştım.

Yani build boyutu 800 MB altına düşürmüştüm. Bu son yaptığım değişiklikler üzerine yeni build almaya çalıştığımda Unity hata verdi. Vay efendim neymiş, maksimum dosya büyüklüğü 4GB olmalıymış da, benim dosyam 17 GB’a ulaşmışmış da…

17 GB mı? Hmmm 🤔
Burada bir yanlışlık var, hem de çok büyük bir yanlışlık var.
Birincisi, daha önce böyle bir hata ile asla karşılaşmadım. İkincisi, Library klasörü bile o kadar büyük değildi, ne oluyor?!?!

Bir başka arama patlattığımda Unity geliştiricilerinin neden 4GB kısıtını değiştirmediğini, ve buna nelerin sebep olabileceğini öğrendikten sonra, kendi yaptığım hataları fark etmeye başladım. Birincisi, mipmaps açmam dosya formatını neredeyse üç katından fazlasına çıkarıyordu; ikincisi ise neredeyse tüm spritesheet dosyaları NPOT (non power of two) idi. POT demek, Power of Two, yani ikinin katları demek. Ekran kartları matris benzeri sistemler kullandıkları için oyunlarda texture ve sprite dosyaları her zaman 2 üzeri bir şey boyutunda olmalı, yani 512×512, 1024×1024 filan. Bunları görmüşsünüzdür zaten. İkinci olay ise, bu boyuttaki dosyaların texture sıkıştırma algoritmaları tarafından sıkıştırılabilir olmasıdır. Bir sprite veya texture dosyası NPOT olduğunda, yani mesela 517*347 gibi bir boyuta sahip olduğunda, hem sıkıştırma algoritması çalışmıyor, hem de ekran kartı tarafından işlenmesi iki-iki buçuk kat kadar zorlaşıyor.

Çözüm olarak ise bana Asset Bundle kullan dediler. Asset Bundle güzel bir çözüm, güçlü bir çözüm, ama böyle dinamik bir oyunda kullanabilmek için fazla statik. Ayrıca projenin geldiği aşamada sistemi ona geçirmek, astarı yüzünden pahalıya gelen bir iş. Hayır, bunu işten kaçtığım, salladığım için söylemiyorum. Asset Bundle üzerine adam akıllı bir tutorial bile yok. Herkes ekrana sadece tek bir sprite koyup SD ve HD versiyonlarını Asset Bundle değiştirerek iki farklı versiyonu oynatabilmeyi gösteriyor. O kadarını video filan izlemeden, sadece Unity dokümantasyonuna bakarak ben de yaparım. Gelmişmiş, kompleks bir kullanım vakası yok hiçbir yerde. Belki de Unity’nin en büyük problemi bu, giriş seviyesi için inanılmaz güzel dersler, tutorial’lar, dokümanlar varken, gelişmiş ve kompleks kullanım için neredeyse hiçbir veri yok.

Projenin bitmesine az bir vakit kala, böyle önemli bir ayrıntının gözümden kaçmış olduğunu görmek kendimi sorgulamama sebep oldu; ama hâlen neden şimdiye kadar böyle bir hata almamış olduğuma cevap değildi.

Şimdi… Biraz daha geçmişe gitme zamanı…

2D oyun yaparken birinci kural, atlaslama kullanmaktır. Yanisi, karakterin her animasyonu, hareketi, tepkisi vs. için elinizde yüzlerce resim varken, bunları teker teker dosyadan okuyup yükleme yapmak oyunu Harddisk ne kadar hızlıysa o kadar hızlı çalıştırmak demektir. Bu da genelde 5 FPS civarı bir şey olur. İsterseniz en hızlı SSD’de çalışın, hâlen tüm sistemde en yavaş iş dosya okuma yazma işidir. O yüzden tüm bu kullanılacak resimleri alırsınız, büyük bir atlas dosyasına koyarsınız (yani aslında büyük çözünürlükte tek bir resim dosyası), bu dosya sadece bir kere harddisk’ten okunur, ondan sonra istediğiniz tüm sprite’lar teker teker bu resim üzerinde bulunur ve işlenir. Bu haliyle, RAM ve VRAM’de daha fazla yer tutmaya başladığı için streaming gibi farklı uygulamalara gitmeniz gerekir ki, 2D oyunları HD yapmanın ne kadar zor olduğu konusunda çoğu insanın hiçbir fikri yok. Yani, iki seçenek kalıyor elinizde: Ya oyun kasacak, ya da yüksek miktarda kaynak tüketeceksiniz. Her iki durumda da oyuncu bakıp “bunu yapan programcının ben…” diye bir tepki verecek. Dolayısıyla, kolay gelsin.

Her neyse, ben bu olayı çözmüştüm. Unity’nin kendi içinde Sprite Packer olayı vardı, 5.4’te mi ne gelmişti. Aynı karakter veya düşman için kullanılacak tüm dosyalara bir etiket veriyorsunuz ve Unity kendi içinde bir Atlas yaratıyor tüm bu sprite dosyalarını kullanarak. Sonrasında oyunda sadece bu dosyalar yükleniyor. Yaratılan atlaslar hem POT (power of two) boyutlarında, hem de Unity’nin kullandığı sıkıştırma algoritması ile yaratılıyor. Yani hem boyut düşük, hem ekran kartını iyi kullanıyor, hem de az önce bahsettiğim problemleri bir şekilde aşmış oluyorsunuz.

Tabii benim bu Sprite Packer’ı kullanırken devasa bir proje ile çalışıyor olmamın getirdiği her iki sürümde bir Unity’nin Sprite Packer çalışırken çökmesi gibi problemler baya sıkıntı yarattı.

Unity’ye açtığım hata raporlarının sayısı biraz daha fazla. Forumlarda ve QA sitesinde Sprite Packer hataları ile çok zorladım adamları.

Önünde sonunda Unity bu hataları halletti ve ben uzun ve sıkıntılı bir süreç sonunda tüm sprite’larımı bir kendi atlaslarına koymayı başardım. Hatta ve hatta kendi Sprite Packer Policy’mi yazdım (TanselsAwesomeSpritePackerPolicy). Buraya kadar da her şey iyi gidiyordu. Derken Unity, 2017 sürümlerinde Sprite Atlas diye yeni bir şey getirdi ve atlaslamanın geleceğinin bu olacağını söyledi. Hadi len oradan dedim ve bir daha dönüp bakmadım. Elimde çalışan bir sistem vardı zaten. Vardı.

Son buildi almaya çalışırken 17 GB hatasını almamın sebebinin aslında ne olduğunu fark ettiğimde iş işten geçmişti. Olay şu:

  1. Sprite Packer ile atlas yaptığım için normal Sprite’larımın POT (power of two) olup olmaması önemli değildi, zira atlas dosyası zaten POT oluyordu.
  2. Sprite import ayarlarında read/write enabled seçilirse, Unity’nin Sprite Packer’ı bu dosyaları atlaslamıyordu.
  3. Atlaslanmayan tüm dosyalar build içerisine doğrudan olduğu gibi konuluyordu.
  4. Dolayısıyla benim 900 MB’ı aşmayan build boyutum bir anda 20 GB’lara çıkmıştı.
  5. Read/Write enabled seçili olmazsa dinamik gölgelendirme ve collision’u yapamayacaktım.
  6. Sprite Packer hiçbir şekilde read/write enabled dosyaları almıyordu.
  7. Hâliyle sıkıştırılamayan ve atlaslanamayan dosyalar, bir de Mipmaps gelince işin içine, hayvani boyutlara ulaşıyordu.
  8. Unity’nin maksimum 4GB verdiği dosya boyutunu 4 defa aşıyor, build alamıyordum.

Ben de bu hâle geldim.

Sonrasında oturdum ve düşündüm. Dedim ki kendi kendime, madem teknoloji ilerliyor ve madem yapmak istediğimi yapmamın yolu bu teknolojiyi kullanmaktan geçiyor, o zaman ben de Sprite Packer’ı geride bırakır ve Sprite Atlas’a geçerim. Öyle karar verdim ben de, sonrasında da gördüm ki, Sprite Packer zaten Legacy konumuna düşmüş. Yani artık üzerine hiçbir geliştirme yapılmadğı gibi, ilerleyen sürümlerde de editörden tamamen kaldırılacaktı. Çok güzel.

Sprite Atlas ile alâkalı dokümanlar, videolar, açıklamalar o kadar alâkasız ve saçma ki, kullanıp kullanamayacağımdan emin değilim. Hiçbir manuelde veya tutorial’da yazmayan mesele şu ki, bir sprite’ı atlas içine aldığımda otomatik olarak runtime sırasında referans olarak kullanılıp kullanılmadığı. Yani atlas dosyası yaratıp, istediğim tüm sprite’ları içine koyduğumda bu iş çözülecek mi? Yoksa benim oturup kodla runtime sırasında istediğim sprite’ı, atlas dosyasınan okuyup elle yerleştirmem mi gerekiyor. Kafamda deli sorular. Bu mesele çok can sıkıcı olacaktı. Bir başka mesele ise, 8192×8192 boyutunu aştığımda, ikinci sayfaya geçip geçmeyeceği. Bu bilgiler hiçbir yerde yazmıyor ve benim eski Sprite Packer kullanımım sırasında bir boss’un sprite’ları 4-5 sayfa olabiliyordu.

Aradığım tüm cevapları bir Kore’li bir oyun geliştiricinin birkaç yüz defa izlenmiş YouTube videosunda buldum. Sprite Atlas, boyutun aşılması durumunda ikinci sayfaya geçebiliyordu, ve atlas yaratıldığı anda oyun motoru normal sprite dosyalarını kullanmayı bırakıp, tüm referansları atlasa taşıyordu. Yaşasın.

Mutlu sona doğru adım adım.

Tüm sistemi Sprite Atlas’a çevirdikten sonra hemen bir build aldım ve bunda da başarılı oldum. Üstüne üstlük, Sprite Atlas yeni API ile birlikte read/write enabled atlas yaratmama, atlasın Mipmap’ini çıkarmama da izin veriyordu. Yeni teknolojiye geçme konusunda inadım yüzünden bütüm bu özellikleri kaçırmışım ve boş yere vakit harcamışım aslında. Her şey çok güzel olacak.

Sprite Atlas’a geçmem ile birlikte build alma sırasındaki hız artışını fark ettim. Sprite Packer kullandığım zamanlarda projeye yeni sprite eklemem ve çıkarmam hemen yeni packing işlemini tetikliyordu ve projeye dâhil olmayacak, test amaçlı dosyalar bile bana vakit kaybı olarak dönüyordu. Sprite Atlas ise sadece atlas dosyalarındaki sprite’lara yapılan değişiklikleri takip ettiği için sorunsuz çalışıyordu. Yeni buildi gönderip tüm problemlerin çözüleceğini düşünüyordum ki…

Hacım bu oyun yüklenmiyor“, aldığım ilk tepki oldu. Oyunda kullanılacak ve seviyelerden bağımsız tüm obje ve pool’ları “initializaiton time”‘a koyduğum için, oyunun açılışında yüklenmesi gereken her şeyi yükleyen bir sistem yazmıştım. O sistem birkaç dakikadan fazla sürüyormuş. Bilgisayar oyunlarında artık birkaç dakikalık yükleme ekranları kabul edilebilir bir şey değil. Hâliyle Benjamin’e biraz beklemesini söyledikten sonra kendim şu dinamik gölgelendirme ve çarpışma olayına yeni bir yaklaşım yapmaya karar verdim.

Madem artık elimde bir atlas dosyası var, amele gibi tüm sprite’ları bir listeye koymak yerine doğrudan atlastan okuyup tüm verileri yaratıp bir obje içinde cache’lerim, oradan da kullanırım dedim. Bunun üstüne bir de şahane bir editör script’i yazdıktan sonra (bir başka yazıda bu işlemin teknik detaylarına değineceğim), tüm düşman ve karakterleri bu işlemden geçirip yeni bir build aldım. Bir karakterin oyunun açılışında kullanacağı tüm sprite’lara özel PolygonCollider2D çıkarması, ve buradaki nokta verisini kullanıp gölge şekli çıkarması bazı karakterlerde birkaç dakika sürerken, artık karakter başına 0.002 saniye sürer duruma geldi. Bunu da paralelleştirince, açılış ve yükleniş ekranlarına etkisi maksimum 0.1 saniye oldu. Genel runtime sırasında etkisi ise sıfır. Bu defa kendimi aşmıştım. Hem dinamik çarpışma ve gölgelendirme sistemi eklemiştim oyuna, hem de kaynak tüketimini minimumda tutmuştum.

Ta ki, o meşhur hata gelene kadar.

Kullanılan silahlardan birinin son seviye atağı sırasında oyun kilitleniyordu. O iş bende deyip hemen loglara girdim ve ufak bir debug işlemi yaptım. Problem hâlen dinamik gölgelendirme script’inden kaynaklanıyordu. Script’i kapatırsam, oyun normal çalışmaya devam ediyor, açarsam, hep o son saldırı sırasında oyun kilitleniyordu.

Ama… ama çözmüştüm!

Bu defa derin bir hata ayıklama işine giriştim. Tüm karakterleri, silahları, düşmanları teker teker test ettim. Hata sürekli belli bir silahın son seviye atağında ortaya çıkıyordu. Ona özel bir durum yazdım, dinamik olarak her şeyi yaratmaya çalıştım, olmuyor ve olmuyordu.

Sonrasında hangi sprite için bu problemi çıkardığını bilirsem belki çözebilirim diye düşündüm ve sprite’ı ayıklamaya çalıştım. İlgili animasyon başladığında sprite is null dedi bana. Tanıdık geldi mi?

Bu problem ilk hata ile aynı.

Ve problem şu: Son ataktaki efektleri güncellediğim sırada ilgili animasyonu güncellemeyi unutmuş, hâliyle eski sprite dosyasını silerken animasyondaki sprite referanslarını da silmiştim. Dolayısıyla, animasyon oynamaya başladığında olmayan bir sprite’a erişmeye çalışıyor, ben ise o olmayan sprite’ın verisine erişmeye çalışıyordum ve tüm oyun buradaki hatalar yüzünden donuyordu. Animasyon dosyasını güncelledim ve… Tüm hatalar bir anda ortadan kalktı.

Yani ben tüm bu maceraya, animasyon dosyası içindeki hatadan dolayı atılmıştım. Kendimi o kadar aptal hissettim, kendime o kadar kızdım ki işin olumlu tarafından bakamadım bir süre. Şimdi, işin olumlu tarafından bakarsam eğer:

  1. Sprite Packer gibi eski bir teknolojiden kurtulup Sprite Atlas gibi yeni bir teknolojiye geçtim ve büyük oranda faydasını gördüm.
  2. Bahane ile kötü olan dinamik çarpışma ve gölgelendirme sistemini yeniden düzenleyip, üzerine bir editör extension yazıp, çok daha pefrormanslı ve minimum kaynak tüketir, ve dahi stabil hâle getirdim.
  3. Unity’ye yeni bir hata raporu açtım. Sprite Atlas’ta da Sprite Packer’da yaşadığım problemler var, bütün sprite’ları bir kerede atlaslamaya kalkışırsam out of memory deyip çöküyor editor. Hatanın sebebini buldular ve bir sonraki sürümde bunu da düzeltecekler. O arada ben tüm atlas dosyalarını teker teker işledim, problemsiz oldu.
  4. Kullanmayacak olsam da Asset Bundle nedir, ne değildir, nasıl kullanılır, öğrenmiş oldum.
  5. Unity’den banlanan eski hesabımdan bu yana, yeni hesabımla tekrar QA sitesinde moderatör oldum.

Ve en önemlisi de, bir işe başlarken iyi bir planlama ile başlamak gerekiyor. Sonrasında zor bir problem ile karşılaştığınızda, çözüm ararken gelecek cevap böyle olabiliyor:

Adam haklı.

Gökhan Doğramacı da Unity ile ilgilenen bir profesyonel, ve yakın bir arkadaşım. Problemlerle boğuşurken çözüm olarak bunu sunması burnumdan duman solumama sebep olduysa da, bir sonraki oyunda zannedersem böyle bir yöntem izlemem gerekecek. Bazı şeylere en başında iyi karar vermek gerekiyor, proje çok ilerlediği durumda geri dönüş yapamıyorsunuz ve verdiğiniz bazı kararların etrafından dolaşmanız gerekebiliyor. Bazı oyunların neden sürekli ertelendiğini, neden kısa sürede bitip çıkmadığını biraz anlamışsınızdır sanırım.

Neon Town’a oyun programcısı olarak ilk başladığım dönemde çok şey bildiğimi zannetsem de, bu 3 yıla yakın süre boyunca çok şey öğrendim, bir o kadar da tecrübesiz olduğumu gördüm. Artık Unity’nin editörünü kullanmakta ve sağladığı özelliklere erişme, ve ördüğü duvarlara da workaround üretme konusunda yetkin bir hâle geldim. Bu yazı da geldiğim bu noktaya nasıl geldiğimin ufak bir özeti olabilir, zira bu ne ilk, ne de son problemdi. Mesela daha geçen hafta 2017.4 serisi LTS olduğu için ona geçmek konusunda yaşadığım problemler bir başka yazının konusu bile olabilir.

Asıl güzel olan ise Unity ile yeniden aynı yola girdik. Ben Sprite atlaslama konusunda bug açıyorum, onlar da güncelleme yayınlıyorlar.

Ka bir tekerlektir dostum, ve döner.

Anafikir olarak ise, sanırım birkaç şey söylenebilir.

Birincisi, hata ayıklamak bazen zordur ve size gerçek sebebten önce başka hataları gösterip sizi yoldan saptırabilir. Bu durumda da öyle oldu. Aslında çok basit, çok temel, çözülmesi bir dakikadan az sürecek bir hata bana birkaç haftaya mal oldu. Tüm hataları çözdükten sonra bile asıl hatayı görememiştim.

İkincisi ise, hayır gibi görünende şer, şer gibi görünende hata vardır. Vesileyle çok daha iyi bir sisteme geçiş yaptım. Zamanında yapmam gereken tüm düzenleme ve güncellemeleri uyguladım ve çok daha iyi çalışan, performanslı, ve stabil bir sistem oluşturdum.

Ben şu yapay zekâ sıkıntılarını çözmeye döneyim en iyisi.

3 şey demişler
  1. Merakla bekliyorum abi saygılar.

    Kenan 15 Mayıs '18 tarihinde | Cevapla
  2. Selam Tansel abi sistem toplayacağım ileri ki zamanlarda. Masaüstü bilgisayarların başıma açmış olduğu sorunlardan dolayı, öneğin everest güç kaynağımın birkaç parçamı yakması yüzünden soğudum. Tam da bir şeyler yapmaya çalıştığım bir dönemdi. Algoritma temelimi oturtmaya çalışıyordum. Photoshop after effects gibi programlardan logo tasarımlarıyla uğraşıyordum. Benim için iyi olmadı tabi. Entegre sistemlere yönelmek istiyorum. Imac gibi. Fiyatı tuzlu haliyle ama bir sorun yaratacağını düşünmüyorum. Sizce nasıl bir sistem toplamalıyım? Laptop almaya bile razıykm yeterki masaüstü olmasın. Bıktım artık. Kasayı taşımak ayrı bir dert. Parçasında sorun çıktığında garantiye gidip gelmesi ayrı bir dert.

    Murat 18 Haziran '18 tarihinde | Cevapla
    • Merhaba Murat,

      Geliştiriciler için masaüstü bilgisayar olmazsa olmazdır. Hiçbir zaman bir dizüstü bilgisayardan aynı performansı ve esnekliği alamazsın. Şanssız bir süreç olmuş seninkisi, onu anlayabiliyorum; ama yine de masaüstünden vazgeçmek için bu kadar acele etme, zira bir dizüstü bilgisayarda yaşayabileceğin sorunlar çok daha fazla ve çözülmesi pek de mümkün olmayan sorunlar oluyor.

      İlle de dizüstü alacağım diyorsan, Monster alabilirsin. Hem yerli, hem yüksek sistem barındırıyor.

      Masaüstü için teknobiyotik masaüstü hazırlama sihirbazını öneririm, ben kendi masaüstümü zamanında öyle kurmuştum, halen canavar gibi.

      Tanshaydar 21 Haziran '18 tarihinde |

Söz uçar yazı kalır