Studi Kasus - Membuat Doodle Google Stanisław Lem

Marcin Wichary
Marcin Wichary

Halaman beranda Google adalah lingkungan yang menarik untuk membuat kode. Hal ini memiliki banyak batasan yang menantang: fokus khusus pada kecepatan dan latensi, harus memenuhi berbagai jenis browser dan bekerja dalam berbagai kondisi, dan… ya, kejutan dan kesenangan.

Saya berbicara tentang Google doodle, ilustrasi khusus yang terkadang menggantikan logo kami. Meskipun hubungan saya dengan pena dan kuas telah lama memiliki rasa yang khas dari perintah penahanan, saya sering berkontribusi pada yang interaktif.

Setiap doodle interaktif yang saya kode (Pac-Man, Jules Verne, World's Fair) – dan banyak yang saya bantu – sama-sama futuristik dan anachronis: peluang besar untuk aplikasi yang tidak realistis dari fitur Web canggih… dan pragmatisme yang keras dari kompatibilitas lintas browser.

Kami belajar banyak dari setiap doodle interaktif, dan game mini Stanisław Lem terbaru tidak terkecuali, dengan 17.000 baris kode JavaScript yang mencoba banyak hal untuk pertama kalinya dalam sejarah doodle. Hari ini, saya ingin membagikan kode tersebut kepada Anda – mungkin Anda akan menemukan sesuatu yang menarik di sana, atau menunjukkan kesalahan saya – dan membahasnya sedikit.

Lihat kode doodle Stanisław Lem »

Hal yang perlu diingat adalah halaman beranda Google bukan tempat untuk demo teknologi. Dengan doodle, kami ingin merayakan orang dan peristiwa tertentu, dan kami ingin melakukannya menggunakan seni terbaik dan teknologi terbaik yang dapat kami gunakan – tetapi jangan pernah merayakan teknologi hanya demi teknologi. Artinya, Anda harus melihat dengan cermat bagian apa pun dari HTML5 yang dipahami secara luas yang tersedia, dan apakah hal itu membantu kami membuat doodle menjadi lebih baik tanpa mengganggu atau mengaburkan doodle.

Jadi, mari kita bahas beberapa teknologi Web modern yang ada dalam doodle Stanisław Lem – dan beberapa yang tidak ada.

Grafik melalui DOM dan kanvas

Kanvas sangat andal dan dibuat untuk hal-hal yang ingin kita lakukan dalam doodle ini. Namun, beberapa browser lama yang kami minati tidak mendukungnya – dan meskipun saya benar-benar berbagi kantor dengan orang yang menyusun excanvas yang sangat bagus, saya memutuskan untuk memilih cara yang berbeda.

Saya menyusun mesin grafis yang memisahkan primitif grafis yang disebut “rects”, lalu merendernya menggunakan kanvas, DOM jika kanvas tidak tersedia.

Pendekatan ini memiliki beberapa tantangan yang menarik – misalnya, memindahkan atau mengubah objek di DOM memiliki konsekuensi langsung, sedangkan untuk kanvas, ada momen tertentu saat semuanya digambar secara bersamaan. (Saya memutuskan untuk hanya memiliki satu kanvas, dan menghapusnya serta menggambar dari awal dengan setiap frame. Terlalu banyak, secara harfiah, bagian yang bergerak di satu sisi – dan di sisi lain tidak cukup kompleks untuk menjamin pemisahan menjadi beberapa kanvas yang tumpang-tindih dan memperbaruinya secara selektif.)

Sayangnya, beralih ke kanvas tidak semudah mencerminkan latar belakang CSS dengan drawImage(): Anda kehilangan sejumlah hal yang tersedia secara gratis saat menggabungkan semuanya melalui DOM – yang paling penting adalah pelapisan dengan z-index, dan peristiwa mouse.

Saya telah memisahkan z-index dengan konsep yang disebut “bidang”. Doodle menentukan sejumlah bidang – dari langit yang jauh di belakang, hingga kursor mouse di depan semuanya – dan setiap aktor dalam doodle harus memutuskan bidang mana yang dimaksud (koreksi plus/minus kecil dalam bidang dapat dilakukan dengan menggunakan planeCorrection).

Dengan rendering melalui DOM, bidang hanya diterjemahkan menjadi z-index. Namun, jika merender melalui kanvas, kita perlu mengurutkan persegi panjang berdasarkan bidangnya sebelum menggambarnya. Karena melakukannya setiap kali akan menghabiskan banyak biaya, urutan hanya dihitung ulang saat aktor ditambahkan atau saat aktor berpindah ke bidang lain.

Untuk peristiwa mouse, saya juga memisahkannya… Untuk DOM dan kanvas, saya menggunakan elemen DOM mengambang tambahan yang sepenuhnya transparan dengan z-index tinggi, yang fungsinya hanya untuk bereaksi terhadap mouse over/out, klik, dan ketukan.

Salah satu hal yang ingin kami coba dengan doodle ini adalah mematahkan dinding keempat. Mesin di atas memungkinkan kita menggabungkan aktor berbasis kanvas dengan aktor berbasis DOM. Misalnya, ledakan di bagian akhir berada di kanvas untuk objek dalam alam semesta dan di DOM untuk halaman beranda Google lainnya. Burung, yang biasanya terbang berkeliling dan terpotong oleh maskara bergerigi seperti aktor lainnya, memutuskan untuk tidak menimbulkan masalah selama tingkat pengambilan gambar, dan duduk di tombol I’m Feeling Lucky. Cara melakukannya adalah dengan membuat burung keluar dari kanvas dan menjadi elemen DOM (dan sebaliknya nanti), yang saya harap akan sepenuhnya transparan bagi pengunjung.

Kecepatan frame

Mengetahui kecepatan frame saat ini, dan bereaksi saat kecepatan frame terlalu lambat (dan terlalu cepat) adalah bagian penting dari mesin kami. Karena browser tidak melaporkan kembali kecepatan frame, kita harus menghitungnya sendiri.

Saya mulai menggunakan requestAnimationFrame, kembali ke setTimeout lama jika yang pertama tidak tersedia. requestAnimationFrame dengan cerdik menghemat CPU dalam beberapa situasi – meskipun kita melakukannya sendiri, seperti yang akan dijelaskan di bawah – tetapi juga memungkinkan kita mendapatkan kecepatan frame yang lebih tinggi daripada setTimeout.

Menghitung kecepatan frame saat ini itu sederhana, tetapi dapat mengalami perubahan drastis – misalnya, kecepatan frame dapat turun dengan cepat saat aplikasi lain menggunakan komputer untuk sementara. Oleh karena itu, kami menghitung kecepatan frame “rolling” (rata-rata) hanya di setiap 100 tick fisik dan membuat keputusan berdasarkan hal tersebut.

Keputusan seperti apa?

  • Jika kecepatan frame lebih tinggi dari 60 fps, kami akan membatasinya. Saat ini, requestAnimationFrame di beberapa versi Firefox tidak memiliki batas atas pada kecepatan frame, dan tidak ada gunanya membuang CPU. Perhatikan bahwa kita sebenarnya membatasi kecepatan frame pada 65 fps, karena error pembulatan yang membuat kecepatan frame sedikit lebih tinggi dari 60 fps di browser lain – kita tidak ingin mulai melakukan throttling secara tidak sengaja.

  • Jika kecepatan frame lebih rendah dari 10 fps, kita cukup memperlambat mesin, bukan menghapus frame. Ini adalah proposisi yang merugikan, tetapi saya merasa bahwa melewatkan frame secara berlebihan akan lebih membingungkan daripada hanya memiliki game yang lebih lambat (tetapi masih koheren). Ada efek samping bagus lainnya dari hal itu – jika sistem melambat untuk sementara, pengguna tidak akan mengalami lompatan aneh karena mesin berusaha mengejar. (Saya melakukannya dengan sedikit perbedaan untuk Pac-Man, tetapi kecepatan frame minimum adalah pendekatan yang lebih baik.)

  • Terakhir, kita dapat mempertimbangkan untuk menyederhanakan grafis saat kecepatan frame menjadi sangat rendah. Kami tidak melakukannya untuk doodle Lem, kecuali kursor mouse (selengkapnya di bawah), tetapi secara hipotetis, kita dapat menghilangkan beberapa animasi yang tidak relevan agar doodle terasa lancar bahkan di komputer yang lebih lambat.

Kita juga memiliki konsep centang fisik dan centang logis. Yang pertama berasal dari requestAnimationFrame/setTimeout. Rasio dalam gameplay normal adalah 1:1, tetapi untuk mempercepat, kita hanya menambahkan lebih banyak jeda logis per jeda fisik (hingga 1:5). Hal ini memungkinkan kita melakukan semua perhitungan yang diperlukan untuk setiap tanda logika, tetapi hanya menetapkan yang terakhir sebagai yang memperbarui hal-hal di layar.

Membuat tolok ukur

Asumsi dapat (dan memang, pada awalnya) dibuat bahwa kanvas akan lebih cepat daripada DOM setiap kali tersedia. Hal ini tidak selalu benar. Saat melakukan pengujian, kami mendapati bahwa Opera 10.0–10.1 di Mac, dan Firefox di Linux sebenarnya lebih cepat saat memindahkan elemen DOM.

Dalam dunia yang sempurna, doodle akan secara diam-diam menjalankan benchmark pada berbagai teknik grafis – elemen DOM dipindahkan menggunakan style.left dan style.top, menggambar di kanvas, dan mungkin bahkan elemen DOM dipindahkan menggunakan transformasi CSS3

– lalu beralihlah ke salah satu yang memberikan kecepatan frame tertinggi. Saya mulai menulis kode untuk itu, tetapi mendapati bahwa setidaknya cara saya melakukan benchmark cukup tidak dapat diandalkan dan memerlukan banyak waktu. Waktu yang tidak kita miliki di halaman beranda – kami sangat memperhatikan kecepatan dan ingin doodle muncul secara instan serta gameplay dimulai segera setelah Anda mengklik atau mengetuk.

Pada akhirnya, pengembangan Web terkadang bermuara pada keharusan melakukan apa yang harus Anda lakukan. Saya melihat ke belakang untuk memastikan tidak ada yang melihat, lalu hanya meng-hardcode Opera 10 dan Firefox dari kanvas. Di kehidupan berikutnya, saya akan kembali sebagai tag <marquee>.

Menghemat CPU

Anda tahu teman yang datang ke rumah Anda, menonton final musim Breaking Bad, membocorkan ceritanya kepada Anda, lalu menghapusnya dari DVR Anda? Anda tidak ingin menjadi orang seperti itu, bukan?

Jadi, ya, analogi terburuk. Namun, kami juga tidak ingin doodle kami menjadi orang yang seperti itu. Fakta bahwa kami diizinkan masuk ke tab browser seseorang adalah hak istimewa, dan menimbun siklus CPU atau mengganggu pengguna akan membuat kami menjadi tamu yang tidak menyenangkan. Oleh karena itu, jika tidak ada yang bermain dengan doodle (tidak ada ketukan, klik mouse, gerakan mouse, atau penekanan tombol), kita ingin aplikasi tersebut akhirnya tidur.

Kapan?

  • setelah 18 detik di halaman beranda (game arcade menyebutnya mode menarik)
  • setelah 180 detik jika tab memiliki fokus
  • setelah 30 detik jika tab tidak memiliki fokus (misalnya, pengguna beralih ke jendela lain, tetapi mungkin masih menonton doodle sekarang di tab yang tidak aktif)
  • segera jika tab menjadi tidak terlihat (misalnya, pengguna beralih ke tab lain di jendela yang sama – tidak ada gunanya membuang siklus jika kita tidak dapat dilihat)

Bagaimana cara mengetahui tab saat ini memiliki fokus? Kita melampirkan diri ke window.focus dan window.blur Bagaimana kita tahu tab terlihat? Kita menggunakan Page Visibility API baru dan bereaksi terhadap peristiwa yang sesuai.

Waktu tunggu di atas lebih toleran daripada biasanya untuk kami. Saya menyesuaikannya dengan doodle khusus ini, yang memiliki banyak animasi standby (terutama langit dan burung). Idealnya, waktu tunggu akan dibatasi pada interaksi dalam game – misalnya, tepat setelah mendarat, burung dapat melaporkan kembali ke doodle bahwa sekarang ia dapat tidur – tetapi pada akhirnya saya tidak menerapkan hal itu.

Karena langit selalu bergerak, saat tertidur dan bangun, sketsel tidak hanya berhenti atau dimulai – sketsel melambat sebelum dijeda, dan sebaliknya untuk melanjutkan, meningkatkan atau menurunkan jumlah jeda logika per jeda fisik sesuai kebutuhan.

Transisi, transformasi, peristiwa

Salah satu keunggulan HTML adalah Anda dapat membuatnya lebih baik sendiri: jika ada sesuatu yang tidak cukup baik dalam portofolio HTML dan CSS reguler, Anda dapat menggunakan JavaScript untuk memperluasnya. Sayangnya, hal ini sering kali berarti Anda harus memulai dari awal. Transisi CSS3 sangat bagus, tetapi Anda tidak dapat menambahkan jenis transisi baru atau menggunakan transisi untuk melakukan hal lain selain menata gaya elemen. Contoh lainnya: Transformasi CSS3 sangat cocok untuk DOM, tetapi saat beralih ke kanvas, Anda tiba-tiba sendirian.

Masalah ini, dan lainnya, adalah alasan doodle Lem memiliki mesin transisi dan transformasi sendiri. Ya, saya tahu, tahun 2000 memanggil, dll. – kemampuan yang saya buat tidak sekuat CSS3, tetapi apa pun yang dilakukan mesin, semuanya dilakukan secara konsisten dan memberi kita lebih banyak kontrol.

Saya memulai dengan sistem tindakan (peristiwa) sederhana – linimasa yang memicu peristiwa di masa mendatang tanpa menggunakan setTimeout, karena pada titik tertentu waktu coretan dapat terpisah dari waktu fisik karena semakin cepat (maju cepat), lebih lambat (frekuensi frame rendah atau tertidur untuk menghemat CPU), atau berhenti sepenuhnya (menunggu gambar selesai dimuat).

Transisi hanyalah jenis tindakan lainnya. Selain gerakan dan rotasi dasar, kami juga mendukung gerakan relatif (misalnya, memindahkan sesuatu 10 piksel ke kanan), hal-hal kustom seperti getaran, dan juga animasi gambar keyframe.

Saya telah menyebutkan rotasi, dan hal itu juga dilakukan secara manual: kita memiliki sprite untuk berbagai sudut objek yang perlu diputar. Alasan utamanya adalah rotasi CSS3 dan kanvas memperkenalkan artefak visual yang kami anggap tidak dapat diterima – dan selain itu, artefak tersebut bervariasi di setiap platform.

Mengingat bahwa beberapa objek yang berputar terpasang ke objek berputar lain – salah satu contohnya adalah tangan robot yang terhubung ke lengan bawah, yang sendirinya terpasang ke lengan atas yang berputar – ini berarti saya juga perlu membuat transform-origin sederhana dalam bentuk pivot.

Semua ini adalah pekerjaan yang solid yang pada akhirnya mencakup dasar-dasar yang telah ditangani oleh HTML5 – tetapi terkadang dukungan native tidak cukup baik dan inilah saatnya untuk menciptakan kembali roda.

Menangani gambar dan sprite

Mesin tidak hanya untuk menjalankan doodle, tetapi juga untuk mengerjakannya. Saya telah membagikan beberapa parameter debug di atas: Anda dapat menemukan sisanya di engine.readDebugParams.

Spriting adalah teknik terkenal yang juga kami gunakan untuk membuat coretan. Hal ini memungkinkan kita menghemat byte dan mengurangi waktu pemuatan, serta mempermudah pramuat. Namun, hal ini juga mempersulit pengembangan – setiap perubahan pada gambar akan memerlukan pembuatan ulang (sebagian besar otomatis, tetapi masih rumit). Oleh karena itu, mesin mendukung pengoperasian pada gambar mentah untuk pengembangan serta sprite untuk produksi melalui engine.useSprites – keduanya disertakan dengan kode sumber.

Doodle Pac-Man
Sprite yang digunakan oleh doodle Pac-Man.

Kami juga mendukung pramuat gambar seiring berjalannya waktu dan menghentikan doodle jika gambar tidak dimuat tepat waktu – lengkap dengan status progres palsu. (Faux karena, sayangnya, bahkan HTML5 tidak dapat memberi tahu kita berapa banyak file gambar yang telah dimuat.)

Screenshot grafik pemuatan dengan status progres yang di-rig.
Screenshot grafik pemuatan dengan status progres yang di-rig.

Untuk beberapa scene, kita menggunakan lebih dari satu sprite tidak sebanyak untuk mempercepat pemuatan menggunakan koneksi paralel, tetapi hanya karena batasan 3/5 juta piksel untuk gambar di iOS.

Di mana HTML5 sesuai dengan semua ini? Tidak banyak yang ada di atas, tetapi alat yang saya tulis untuk membuat spriting/pemangkasan adalah semua teknologi Web baru: kanvas, blob, a[download]. Salah satu hal menarik tentang HTML adalah bahwa HTML secara perlahan menyerap hal-hal yang sebelumnya harus dilakukan di luar browser; satu-satunya bagian yang perlu kita lakukan di sana adalah mengoptimalkan file PNG.

Menyimpan status di antara game

Dunia Lem selalu terasa besar, hidup, dan realistis. Ceritanya biasanya dimulai tanpa banyak penjelasan, halaman pertama dimulai dengan medias res, dengan pembaca harus menemukan jalannya sendiri.

Cyberiad tidak terkecuali dan kami ingin mereplikasi perasaan tersebut untuk doodle. Kita mulai dengan mencoba tidak menjelaskan cerita secara berlebihan. Bagian besar lainnya adalah pengacakan yang kami rasa sesuai dengan sifat mekanis alam semesta buku; kami memiliki sejumlah fungsi bantuan yang menangani pengacakan yang kami gunakan di banyak tempat.

Kami juga ingin meningkatkan replayability dengan cara lain. Untuk itu, kita perlu mengetahui berapa kali doodle selesai sebelumnya. Solusi teknologi yang secara historis benar untuk hal tersebut adalah cookie, tetapi hal itu tidak berfungsi untuk halaman beranda Google. Setiap cookie akan meningkatkan payload setiap halaman, dan sekali lagi, kami sangat memperhatikan kecepatan dan latensi.

Untungnya, HTML5 memberi kita Penyimpanan Web, yang mudah digunakan, sehingga kita dapat menyimpan dan mengingat jumlah pemutaran umum dan adegan terakhir yang diputar oleh pengguna – dengan lebih banyak kemudahan daripada yang diizinkan cookie.

Apa yang kami lakukan dengan informasi ini?

  • kami menampilkan tombol maju cepat, yang memungkinkan pengguna melewati cutscene yang telah dilihat sebelumnya
  • kita menampilkan item N yang berbeda selama final
  • kami sedikit meningkatkan tingkat kesulitan pengambilan gambar
  • kami menampilkan sedikit easter egg probability dragon dari cerita yang berbeda pada pemutaran ketiga dan berikutnya

Ada sejumlah parameter debug yang mengontrol hal ini:

  • ?doodle-debug&doodle-first-run – berpura-puralah bahwa ini adalah pengujian mesin perdana
  • ?doodle-debug&doodle-second-run – berpura-puralah bahwa ini adalah operasi kedua
  • ?doodle-debug&doodle-old-run – berpura-puralah bahwa ini adalah lari lama

Perangkat sentuh

Kami ingin doodle terasa nyaman di perangkat sentuh – perangkat yang paling modern cukup canggih sehingga doodle berjalan dengan sangat baik, dan mengalami game melalui ketukan jauh lebih menyenangkan daripada dengan mengklik.

Beberapa perubahan awal pada pengalaman pengguna perlu dilakukan. Awalnya, kursor mouse adalah satu-satunya tempat yang menyampaikan bagian cutscene/non-interaktif sedang berlangsung. Kemudian, kita menambahkan sedikit indikator di sudut kanan bawah, sehingga kita tidak perlu mengandalkan kursor mouse saja (mengingat kursor tidak ada di perangkat sentuh).

Normal Sibuk Dapat diklik Diklik
Dalam proses
Pointer normal yang sedang diproses
Pointer sibuk yang sedang diproses
Pointer yang dapat diklik untuk pekerjaan yang sedang berlangsung
Pointer yang diklik untuk pekerjaan yang sedang berlangsung
Final
Pointer normal akhirv
Pointer sibuk akhir
Pointer akhir yang dapat diklik
Pointer yang diklik terakhir
Kursor mouse selama pengembangan, dan yang setara dengan versi akhir.

Sebagian besar fitur dapat langsung digunakan. Namun, pengujian kegunaan secara spontan dan cepat dari pengalaman sentuh kami menunjukkan dua masalah: beberapa target terlalu sulit ditekan, dan ketukan cepat diabaikan karena kita baru saja mengganti peristiwa klik mouse.

Memiliki elemen DOM transparan yang dapat diklik secara terpisah sangat membantu di sini, karena saya dapat mengubah ukurannya secara terpisah dari visual. Saya memperkenalkan padding tambahan 15 piksel untuk perangkat sentuh dan menggunakannya setiap kali elemen yang dapat diklik dibuat. (Saya juga menambahkan padding 5 piksel untuk lingkungan mouse, hanya untuk membuat Mr. Fitts senang.)

Untuk masalah lainnya, saya hanya memastikan untuk melampirkan dan menguji pengendali awal dan akhir sentuh yang tepat, bukan mengandalkan klik mouse.

Kami juga menggunakan properti gaya yang lebih modern untuk menghapus beberapa fitur sentuh yang ditambahkan browser WebKit secara default (sorot ketuk, info ketuk).

Dan bagaimana cara mendeteksi apakah perangkat tertentu yang menjalankan doodle mendukung sentuhan? Secara lambat. Daripada mencari tahu sebelumnya, kita hanya menggunakan IQ gabungan untuk menyimpulkan bahwa perangkat mendukung sentuhan… setelah kita mendapatkan peristiwa awal sentuhan pertama.

Menyesuaikan kursor mouse

Namun, tidak semuanya berbasis sentuh. Salah satu prinsip panduan kami adalah menempatkan sebanyak mungkin hal dalam dunia doodle. UI sidebar kecil (maju cepat, tanda tanya), tooltip, dan bahkan, kursor mouse.

Bagaimana cara menyesuaikan kursor mouse? Beberapa browser memungkinkan perubahan kursor mouse dengan menautkan ke file gambar khusus. Namun, hal ini tidak didukung dengan baik dan juga agak membatasi.

Jika bukan ini, lalu apa? Nah, mengapa tidak menjadikan kursor mouse sebagai aktor lain dalam doodle? Cara ini berfungsi, tetapi disertai dengan sejumlah ketentuan, terutama:

  • Anda harus dapat menghapus kursor mouse native
  • Anda harus cukup mahir dalam menjaga kursor mouse tetap sinkron dengan kursor "sebenarnya"

Yang pertama itu rumit. CSS3 memungkinkan cursor: none, tetapi juga tidak didukung di beberapa browser. Kita perlu melakukan beberapa hal: menggunakan file .cur kosong sebagai penggantian, menentukan perilaku yang konkret untuk beberapa browser, dan bahkan melakukan hard code pada browser lain dari pengalaman apa pun.

Yang lainnya relatif sepele, tetapi dengan kursor mouse yang hanya merupakan bagian lain dari dunia doodle, kursor tersebut juga akan mewarisi semua masalahnya. Tantangan terbesarnya? Jika kecepatan frame doodle rendah, kecepatan frame pointer mouse juga akan rendah – dan hal itu memiliki konsekuensi yang mengerikan karena pointer mouse, sebagai ekstensi alami tangan Anda, harus terasa responsif apa pun yang terjadi. (Orang-orang yang pernah menggunakan Commodore Amiga kini mengangguk dengan keras.)

Salah satu solusi yang agak rumit untuk masalah tersebut adalah memisahkan kursor mouse dari loop update reguler. Kita melakukannya – di alam lain tempat saya tidak perlu tidur. Solusi yang lebih sederhana untuk masalah ini? Cukup kembali ke kursor mouse native jika kecepatan frame bergulir turun di bawah 20 fps. (Di sinilah kecepatan frame rolling berguna. Jika kita bereaksi terhadap kecepatan frame saat ini, dan jika terjadi osilasi sekitar 20 fps, pengguna akan melihat kursor mouse kustom yang selalu disembunyikan dan ditampilkan.) Hal ini akan membawa kita ke:

Rentang kecepatan frame Perilaku
>10fps Perlambat game agar lebih banyak frame yang tidak dihapus.
10–20fps Gunakan kursor mouse native, bukan kursor kustom.
20–60fps Operasi normal.
>60fps Batasi agar kecepatan frame tidak melebihi nilai ini.
Ringkasan perilaku yang bergantung pada kecepatan frame.

Oh, dan kursor mouse kita berwarna gelap di Mac, tetapi berwarna putih di PC. Mengapa? Karena perang platform membutuhkan bahan bakar bahkan di alam semesta fiksi.

Kesimpulan

Ini bukan mesin yang sempurna, tetapi tidak berusaha menjadi sempurna. Aplikasi ini dikembangkan bersama doodle Lem, dan sangat spesifik untuknya. Tidak masalah. “Pengoptimalan yang terlalu dini adalah akar dari semua kejahatan”, seperti yang diucapkan Don Knuth, dan saya tidak percaya bahwa menulis mesin secara terpisah terlebih dahulu, dan hanya menerapkannya nanti adalah hal yang masuk akal – praktik ini memberi tahu teori sebanyak teori memberi tahu praktik. Dalam kasus saya, kode dihapus, beberapa bagian ditulis ulang berulang kali, dan banyak bagian umum diperhatikan setelahnya, bukan sebelum fakta. Namun, pada akhirnya, apa yang kita miliki di sini memungkinkan kita melakukan hal yang kita inginkan – merayakan karier Stanisław Lem dan gambar oleh Daniel Mróz dengan cara terbaik yang dapat kita pikirkan.

Semoga penjelasan di atas dapat menjelaskan beberapa pilihan desain dan kompromi yang perlu kita buat – dan cara kita menggunakan HTML5 dalam skenario tertentu di dunia nyata. Sekarang, mainkan kode sumber, coba, dan beri tahu kami pendapat Anda.

Saya melakukannya sendiri – gambar di bawah ini ditayangkan dalam beberapa hari terakhir, menghitung mundur ke dini hari 23 November 2011 di Rusia, yang merupakan zona waktu pertama yang melihat doodle Lem. Mungkin hal yang konyol, tetapi seperti coretan, hal-hal yang tampak tidak penting terkadang memiliki makna yang lebih dalam – penghitung ini benar-benar merupakan “pengujian stres” yang bagus untuk mesin.

Screenshot jam hitung mundur dalam doodle Lem.
Screenshot jam hitung mundur dalam doodle Lem.

Dan itulah salah satu cara untuk melihat siklus proses doodle Google – berbulan-bulan bekerja, berminggu-minggu melakukan pengujian, 48 jam untuk menyiapkannya, semuanya untuk sesuatu yang dimainkan orang selama lima menit. Setiap baris JavaScript dari ribuan baris tersebut berharap bahwa 5 menit tersebut akan menjadi waktu yang bermanfaat. Selamat menikmati.