การวาดสถานะเริ่มต้นของบอร์ด ส่วนหน้า: เว็บและไคลเอนต์มือถือ
กฎกติกานั้นเรียบง่าย ผู้ใช้แต่ละคนสามารถเลือกหนึ่งใน 16 สีและวาดภาพหนึ่งพิกเซลที่ใดก็ได้บนผืนผ้าใบด้วย คุณสามารถทาสีพิกเซลได้มากเท่าที่คุณต้องการและด้วยสีใดก็ได้ที่คุณต้องการ แต่เพื่อที่จะทาสีพิกเซลถัดไปใหม่ คุณต้องรอ 5 นาที
จริงอยู่ กฎกล่าวไว้ว่า “โดยการประสานงานกับผู้อื่น คุณสามารถสร้างสรรค์ได้มากกว่าการกระทำเพียงลำพัง”
สิ่งที่เกิดขึ้นในช่วง 72 ชั่วโมงข้างหน้าทำให้ผู้จัดงานตกตะลึง สิ่งนี้ปรากฏบนผืนผ้าใบที่ว่างเปล่า:
แต่ละพิกเซลบนผืนผ้าใบถูกวางด้วยตนเอง ทุกไอคอน ทุกธง ทุกมีม ถูกสร้างขึ้นอย่างอุตสาหะโดยผู้คนหลายแสนคนที่ไม่มีอะไรเหมือนกันเลย ยกเว้นการเชื่อมต่ออินเทอร์เน็ต ดังนั้นไม่ทางใดก็ทางหนึ่งสิ่งที่เกิดขึ้นบน Reddit ถือได้ว่าเป็นแหล่งกำเนิดของศิลปะอย่างถูกต้อง
มันเกิดขึ้นได้อย่างไร
เป็นไปไม่ได้ที่จะอธิบายสิ่งนี้ด้วยคำไม่กี่คำ ละครนับไม่ถ้วนเกิดขึ้นบนผืนผ้าใบ - การต่อสู้การต่อสู้และสงครามบางครั้งก็ไม่ทราบสาเหตุด้วยซ้ำ พวกเขาดำเนินการในฟอรัมเล็ก ๆ ในแชทส่วนตัว มีจำนวนมากและทั้งหมดเกิดขึ้นพร้อมกัน ดังนั้นจึงเป็นไปไม่ได้ที่จะติดตามทุกอย่าง โดยทั่วไปแล้ว ผืนผ้าใบนี้ติดตามเรื่องราวนิรันดร์ของพลังทั้งสามที่จำเป็นสำหรับมนุษยชาติในการสร้าง
ผู้สร้าง
ผู้สร้างมาก่อน พวกเขาเป็นศิลปินที่ผืนผ้าใบว่างเปล่ามีแรงดึงดูดที่ไม่อาจต้านทานได้
ผู้สร้างเริ่มเปลี่ยนสีพิกเซลแบบสุ่มเพื่อดูว่าพวกเขาสามารถทำอะไรได้บ้าง ดังนั้นภาพวาดแรกจึงชวนให้นึกถึงภาพวาดในถ้ำมากขึ้น - ศิลปินเพิ่งเริ่มกางปีกออก
พวกเขาก็ตระหนักได้อย่างรวดเร็วว่าการทำงานคนเดียวและวางพิกเซลเพียงพิกเซลเดียวทุกๆ 5-10 นาที เป็นไปไม่ได้เลยที่จะสร้างสิ่งที่สำคัญขึ้นมา มีคนผูกพันที่จะทำลายงานของพวกเขา เพื่อสร้างสิ่งที่ยิ่งใหญ่กว่านั้น พวกเขาต้องร่วมมือกัน
จากนั้นมีคนแนะนำให้วาดภาพบนตาราง ซึ่งจะแสดงให้เห็นอย่างชัดเจนว่าต้องทาสีพิกเซลถัดไปที่ไหนเพื่อสร้างภาพที่สอดคล้องกัน นี่คือลักษณะที่ Dickbutt ปรากฏในส่วนล่างซ้ายของผืนผ้าใบ - มีมอินเทอร์เน็ตที่มีชื่อเสียงซึ่งเป็นผลไม้แห่งอารมณ์ขันของวัยรุ่น มันกลายเป็นการทำงานร่วมกันครั้งแรก
แต่ผู้สร้างไม่ได้หยุดเพียงแค่นั้น พวกเขาเริ่มเพิ่มองค์ประกอบต่างๆ ให้กับ Dickbutt โดยเติมสีเข้าไป สีที่ต่างกันและยังพยายามแปลงร่างมันให้เป็นดิ๊กบัตเตอร์ฟลายอีกด้วย เบื้องหลังความคิดโง่ๆ นี้เป็นสัญญาณของสึนามิเชิงสร้างสรรค์ที่กำลังจะเกิดขึ้น
อย่างไรก็ตาม สิ่งนี้ไม่ได้เกิดขึ้นในทันที ผู้สร้างรู้สึกมึนเมากับพลังของพวกเขา Pokemon Charmander ปรากฏตัวถัดจาก Dickbutt และแทนที่จะเป็นอุ้งเท้า อวัยวะเพศชายก็เริ่มโตขึ้น และอีกสองตัว
มันไม่ใช่การออกแบบอีกต่อไป ผู้สร้างบางคนพยายามอย่างยิ่งที่จะลบส่วนเพิ่มเติมที่เร้าใจออก โดยเรียกร้องให้มีงานศิลปะที่ "สะอาดตา" แต่คนอื่นๆ ก็ยังคงสานต่อผลงานของตัวเองต่อไป แต่นั่นไม่เป็นเช่นนั้น
เห็นได้ชัดว่าอิสรภาพที่มากเกินไปนำไปสู่ความสับสนวุ่นวาย ความคิดสร้างสรรค์จำเป็นต้องมีข้อจำกัดมากพอๆ กับที่ต้องการอิสรภาพ เมื่อมีคนวางพิกเซลตรงไหนก็ได้ จะไม่ทำให้เกิดความโกลาหลได้อย่างไร?
การ์เดี้ยน
ปัญหานี้ได้รับการแก้ไขอย่างรวดเร็วโดยผู้ใช้ประเภทอื่น – ผู้ดูแล พวกเขามาโดยมีเป้าหมายเดียว - เพื่อพิชิตโลกทั้งใบ
เมื่อก่อตั้งกลุ่มตามสีแล้ว พวกเขาก็เริ่มพิชิตอวกาศโดยวาดภาพให้เป็นสีใดสีหนึ่ง หนึ่งในกลุ่มแรกและใหญ่ที่สุดคือกลุ่ม Blue Corner ปรากฏที่มุมขวาล่างแพร่ระบาดเหมือนโรคระบาด ผู้ติดตามของเธอประกาศว่าด้วยวิธีนี้พวกเขาควรครอบคลุมพื้นที่ทั้งหมดของผืนผ้าใบ พวกเขาเริ่มแปลแนวคิดของตนให้กลายเป็นความจริงทีละพิกเซล และในไม่ช้าก็จับภาพพื้นที่ขนาดใหญ่ได้
Blue Corner ไม่ได้อยู่คนเดียวที่มีแรงบันดาลใจ อีกฟากหนึ่งของผืนผ้าใบมีอีกกลุ่มหนึ่งปรากฏขึ้น - มุมแดง (มุมสีแดง) ผู้เข้าร่วมระบุว่าพวกเขาเป็นผู้สนับสนุนฝ่ายซ้าย มุมมองทางการเมือง- อีกกลุ่มหนึ่ง - Green Lattice (ตาข่ายสีเขียว) - เริ่มกระจายพิกเซลสีเขียวและสีขาวไปทุกที่ เธอแสดงให้เห็นประสิทธิภาพสูง เนื่องจากเธอจำเป็นต้องวาดพิกเซลให้มากที่สุดเท่าที่ฝ่ายอื่นๆ ครึ่งหนึ่ง
เหล่าการ์เดี้ยนโจมตีผู้สร้างด้านหน้า Charmander กลายเป็นสถานที่แรกของการต่อสู้ เมื่อค้นพบว่า Blue Corner ได้เริ่มเติม Pokemon ด้วยพิกเซลสีน้ำเงินแล้ว ผู้สร้างก็ตระหนักถึงภัยคุกคามและหยุดสงครามภายใน
พวกเขาต่อสู้กลับ โดยแทนที่แต่ละพิกเซลสีน้ำเงินด้วยพิกเซลของตัวเอง แต่กำลังไม่เท่ากัน ด้วยความมุ่งมั่น Blue Corner ได้รวบรวมกองทัพที่ใหญ่กว่าผู้สร้างมาก และสิ่งเดียวที่ผู้สร้างสามารถทำได้ในสถานการณ์เช่นนี้คือการร้องขอชีวิต
และอย่างใดมันก็พลิกกระแสน้ำ The Blue Corner เริ่มถกเถียงเกี่ยวกับบทบาทของพวกเขาใน กระบวนการสร้างสรรค์- ผู้เข้าร่วมรายหนึ่งถามว่า “ในขณะที่คลื่นของเราเข้ายึดครองโลกอย่างหลีกเลี่ยงไม่ได้ เราควรแสดงความเมตตาต่องานศิลปะรูปแบบอื่นที่เราเผชิญหรือไม่”
นี่เป็นคำถามที่เกิดขึ้นไม่ช้าก็เร็วต่อหน้าทุกฝ่าย ด้วยความกระตือรือร้นในการขยายขอบเขต พวกเขาควรทำอย่างไรกับงานศิลปะที่ขวางทางพวกเขา?
นี่เป็นจุดเปลี่ยน กลุ่มที่ไร้สติได้กลายเป็นผู้พิทักษ์
แต่มันก็ยังไม่จบ
ในโลกที่เต็มไปด้วยสีนักล่า ผู้สร้างสามารถกลับไปสู่การสร้างสรรค์ของพวกเขาได้ ด้วยการเพิ่มองค์ประกอบทีละองค์ประกอบ พวกเขาเริ่มทำให้มันซับซ้อนมากขึ้น เราเริ่มเขียนข้อความโดยใช้แบบอักษรสามพิกเซล หนึ่งในการสร้างสรรค์ที่โด่งดังที่สุดคือภาคก่อนของสตาร์วอร์ส
ผู้สร้างรวมตัวกันเป็นกลุ่มที่ทำงานอยู่ โครงการทั่วไป- พวกเขาแบ่งปันกลยุทธ์และรูปแบบระหว่างกัน หนึ่งในผู้ที่ประสบความสำเร็จมากที่สุดคือกลุ่มที่สร้างแผง Windows 95 โดยมีปุ่ม Start อยู่ที่มุม
คนอื่นๆ สร้างบล็อกหัวใจเหมือนกับในวิดีโอเกมเก่าๆ อย่าง Zelda มีเพียงไม่กี่คนเท่านั้นที่เริ่มโครงการนี้ แต่คนอื่นๆ ก็เข้าร่วมอย่างรวดเร็ว และในที่สุดหัวใจที่วาดด้วยธงหลากสีก็กางไปครึ่งผืนผ้าใบ
อีกกลุ่มหนึ่งได้สร้าง Starry Night ของ Van Gogh ขึ้นใหม่
อย่างไรก็ตาม ไม่ใช่ทุกอย่างเป็นไปอย่างราบรื่น ผู้สนับสนุนที่เคยเฉลิมฉลองการสร้างสรรค์ผลงานศิลปะกลายเป็นเผด็จการที่บงการแฟชั่น พวกเขาเริ่มระบุว่าอะไรสร้างได้และสิ่งไหนสร้างไม่ได้ มันเริ่มต้นไม่นานก่อนที่ผู้สร้างจะเริ่มสร้างตามกฎเกณฑ์ของตนเอง
ฝ่ายต่างๆ หันมามองกันและกัน โดยเรียกร้องให้ผู้ติดตามของพวกเขาเข้าข้างฝ่ายในการต่อสู้ครั้งยิ่งใหญ่ พวกเขาไม่มีเวลาใส่ใจกับคำวิงวอนอันน่าสมเพชของผู้สร้างที่ต้องการอนุมัติแนวคิดเกี่ยวกับงานศิลปะใหม่
การต่อสู้ระหว่างกองหลังก็ปะทุขึ้นอย่างจริงจัง สตรีมเมอร์สดของ Twitch สนับสนุนให้ผู้ติดตามโจมตี Blue Corner และ Purple มีแผนการต่อสู้แล้ว อุทธรณ์ไปยังอารมณ์
มีการโจมตีปลอมด้วยซ้ำ โดยที่ผู้ติดตามที่มีสีเดียวกันวางพิกเซลของฝ่ายตรงข้ามไว้ภายในของตนเอง เพื่อที่พวกเขาจะได้บ่นเกี่ยวกับการละเมิดและโจมตีกลับ
อย่างไรก็ตามมากที่สุด ปัญหาใหญ่มีกฎที่เข้มงวด - ไม่สามารถขยายผืนผ้าใบได้ ทั้งฝ่ายที่ทำสงครามและผู้สร้างเริ่มตระหนักว่าพวกเขาไม่มีที่ว่างสำหรับงานศิลปะใหม่
ตั้งแต่เริ่มแรก ธงของประเทศต่างๆ ปรากฏบนผืนผ้าใบ พวกเขาเติบโตและชนกัน การต่อสู้ครั้งยิ่งใหญ่ที่แท้จริงเกิดขึ้นระหว่างธงของเยอรมนีและฝรั่งเศส เห็นได้ชัดว่าจำเป็นต้องมีตัวกลางเพื่อพัฒนาพื้นที่ใหม่
ทันใดนั้นโลกที่รอดพ้นจากการโจมตีแบบดึกดำบรรพ์ตั้งแต่แรกเริ่ม ก็พร้อมสำหรับสงครามเต็มรูปแบบ ความพยายามอย่างสิ้นหวังในการแก้ปัญหาอย่างมีชั้นเชิงทำให้ไม่มีที่ไหนเลย การพบกันในการแชท ผู้นำของผู้สร้างและผู้ปกป้องต่างตำหนิกันเท่านั้น
สิ่งที่จำเป็นคือพังพอนที่ทุกคนสามารถตกลงกันได้
เรือพิฆาต
เว็บไซต์อินเทอร์เน็ต 4chan ดึงความสนใจไปที่สิ่งที่เกิดขึ้นใน Reddit และพวกเขาก็ผ่านไปไม่ได้ ผู้ใช้เลือกสีที่ใกล้เคียงกับหัวใจมากที่สุด - สีดำ พวกเขากลายเป็นความว่างเปล่า
ขณะที่น้ำตาค่อยๆ กระจายไปทั่วพื้นผิว พิกเซลสีดำก็เริ่มปรากฏขึ้นตรงกลางผืนผ้าใบ ทำลายทุกสิ่งที่ขวางหน้า
ในตอนแรก กลุ่มอื่นๆ พยายามสร้างพันธมิตรกับพวกเขา โดยเชื่อว่าการทูตจะใช้ได้ผล แต่พวกเขาล้มเหลวเพราะเดอะวอยด์แตกต่างออกไป
ความว่างเปล่าไม่ใช่เครื่องปกป้อง ต่างจากกลุ่มอื่นๆ เธอไม่แสดงความจงรักภักดีต่อศิลปะ ผู้ติดตาม The Void ยอมรับลัทธิทำลายล้างที่เท่าเทียมภายใต้สโลแกน "The Void จะกลืนกินทุกสิ่ง" พวกเขาไม่ได้ติดต่อกับผู้อื่น พวกเขาแค่อยากจะทาให้โลกทั้งใบเป็นสีดำ
และนี่คือสิ่งที่จำเป็นจริงๆ เมื่อพบว่าตัวเองจวนจะสูญพันธุ์ ผู้เข้าร่วมโครงการทั้งหมดจึงรวมตัวกันเพื่อต่อสู้กับเดอะวอยด์เพื่อรักษางานศิลปะของพวกเขา
แต่ความว่างเปล่านั้นไม่ใช่เรื่องง่ายที่จะเอาชนะ เพราะมันจำเป็น จำเป็นต้องทำลายทุกสิ่งเพื่อให้งานศิลปะใหม่ที่ดีที่สุดสามารถเกิดใหม่จากเถ้าถ่านได้ และหากไม่มีความว่างเปล่า สิ่งนี้ก็เป็นไปไม่ได้
ดังนั้นความว่างเปล่าจึงกลายเป็นตัวเร่งให้เกิดการสร้างสรรค์ งานที่ใหญ่ที่สุดศิลปะ.
มีการต่อสู้ที่ดื้อรั้นเพื่อส่วนกลางของผืนผ้าใบตั้งแต่แรกเริ่ม ผู้สร้างอ้างสิทธิ์ในดินแดนนี้เพื่อผลงานของพวกเขา ในตอนแรกพวกเขาพยายามทำสิ่งนี้โดยใช้ไอคอน จากนั้นจึงประสานกันเพื่อสร้างปริซึมแบบเดียวกับบนปกอัลบั้ม พิงค์ ฟลอยด์ « ด้านหลังดวงจันทร์."
แต่เดอะวอยด์กินทุกอย่าง การสร้างสรรค์ครั้งแล้วครั้งเล่าได้กระตุ้นให้เธอกระหายความวุ่นวายเท่านั้น
แต่นี่คือสิ่งที่จำเป็นจริงๆ หลังจากทำลายงานศิลปะ The Void ได้บังคับให้ผู้ใช้คิดสิ่งที่ดีกว่าขึ้นมา พวกเขารู้ว่าพวกเขาสามารถเอาชนะสัตว์ประหลาดสีดำได้ พวกเขาแค่ต้องการไอเดียที่มีศักยภาพดีที่จะดึงดูดผู้ติดตามได้เพียงพอ
และความคิดนี้ก็กลายเป็นธงชาติอเมริกัน
ในวันสุดท้ายของโครงการทุกคนร่วมกันขับไล่ความว่างเปล่าออกไปให้หมด แนวร่วมถูกสร้างขึ้นจากผู้คนที่อยู่ในสถานการณ์ที่แตกต่างกันที่จะแยกออกจากกัน - จากผู้สนับสนุนและฝ่ายตรงข้ามของทรัมป์, จากพรรคเดโมแครตและรีพับลิกัน, จากชาวอเมริกันและชาวยุโรป
พวกเขามารวมตัวกันเพื่อสร้างสรรค์บางสิ่งร่วมกันในมุมเล็กๆ ของอินเทอร์เน็ต ซึ่งพิสูจน์ให้เห็นว่าในยุคที่การทำงานร่วมกันดังกล่าวดูเหมือนเป็นไปไม่ได้ พวกเขาก็ยังสามารถทำได้
คนสมัยก่อนพูดถูก
หลังจากนั้นไม่นาน การทดลอง Reddit ก็สิ้นสุดลง วันนี้เขามาพร้อมกับเรื่องราวมากมายที่เล่าผ่านการแชทหลายสิบครั้ง งานศิลปะแต่ละชิ้นที่สร้างขึ้นในโครงการนี้ถูกปกคลุมไปด้วยชิ้นใหม่หลายร้อยชิ้น ซึ่งมีเพียงไม่กี่ชิ้นเท่านั้นที่ยังคงอยู่บนผืนผ้าใบขั้นสุดท้าย
แต่สิ่งที่น่าประหลาดใจที่สุดก็คือ แม้ว่าจะไม่เปิดเผยตัวตนและไม่มีข้อห้าม แต่ก็ไม่มีสัญลักษณ์เหยียดเชื้อชาติหรือเกลียดชังมนุษย์บนผืนผ้าใบสุดท้าย มันเป็นวงจรที่สวยงามของศิลปะ ชีวิตและความตาย และเขาไม่ใช่คนแรกในประวัติศาสตร์ของเรา
เมื่อหลายพันปีก่อน เมื่อมนุษยชาติ (ของจริง ไม่ใช่แค่ใน Reddit) ยังอยู่ในช่วงเริ่มต้น นักปรัชญาฮินดูตั้งทฤษฎีว่าสวรรค์ประกอบด้วยเทพ 3 องค์ที่แข่งขันกันแต่จำเป็น ได้แก่ พระพรหมผู้สร้าง พระวิษณุผู้ปกป้อง และ พระศิวะ. ผู้ทำลาย.
แม้ว่าจะไม่มีหนึ่งในนั้น จักรวาลก็ไม่สามารถทำงานได้ การจะมีแสงสว่าง จำเป็นต้องมีความมืด การที่ชีวิตจะดำรงอยู่ได้ ความตายเป็นสิ่งจำเป็น สำหรับการสร้างสรรค์และศิลปะจะต้องมีการทำลายล้าง
หลายวันของโครงการแสดงให้เห็นว่าแนวทางนี้กลายเป็นคำทำนาย ด้วยวิธีที่น่าทึ่งที่สุด Reddit ได้พิสูจน์แล้วว่าการสร้างสรรค์ต้องใช้องค์ประกอบทั้งสามอย่าง
การวาดภาพครั้งสุดท้าย
เฟสบุ๊ค
ทวิตเตอร์
กระเป๋า
ลิงค์ดิน
ผู้ส่งสารเอฟบี
ไม่สามารถพูดได้ว่าเรื่องตลกขององค์กร 100% ในวันอารมณ์ขันนั้นประสบความสำเร็จและมีส่วนร่วม ในปีนี้ ฝ่ายบริหารของ Reddit ได้เปิดตัว Place ซึ่งเป็นผืนผ้าใบกราฟิกเชิงโต้ตอบขนาด 1,000 x 1,000 พิกเซล และส่วนที่ทุ่มเทให้กับมันโดยเฉพาะ สันนิษฐานว่าสมาชิกในชุมชนจะร่วมกันวาดภาพผืนผ้าใบนี้ตามที่ตนต้องการ แต่ด้วยเหตุนี้ สิ่งนี้จึงพัฒนาไปสู่การต่อสู้เพื่อชิงสถานที่ ซึ่งบางครั้งก็กลายเป็นการเผชิญหน้าเชิงปรัชญา แบบฝึกหัดการวาดภาพธรรมดากลายเป็นการทดลองทางสังคมที่น่าตื่นเต้น เรื่องราวได้รับการบันทึกตั้งแต่ต้นจนจบโดยบล็อก Sudoscript
กฎของสถานที่นั้นเรียบง่าย ผู้เข้าร่วมแต่ละคนสามารถเลือกหนึ่งพิกเซลจาก 16 สีและวางไว้ที่ใดก็ได้บนผืนผ้าใบ คุณสามารถวางพิกเซลได้มากเท่าที่คุณต้องการ แต่คุณต้องรอ 5 นาทีระหว่างแต่ละตำแหน่ง หลังจาก 72 ชั่วโมงนี้มาก กฎง่ายๆนำไปสู่การสร้างผืนผ้าใบส่วนรวมที่น่าทึ่ง:
แต่ละพิกเซลที่เห็นด้านบนถูกวางด้วยตนเอง ทุกไอคอน ทุกธง ทุกมีมถูกสร้างขึ้นอย่างระมัดระวังโดยผู้คนหลายพันคนที่ไม่มีอะไรเหมือนกันยกเว้นการเชื่อมต่ออินเทอร์เน็ต
ในระหว่างการสร้างสรรค์ ละคร ความคิด การต่อสู้ หรือแม้แต่สงครามมากมายก็เกิดขึ้น แต่โดยทั่วไปแล้ว ประวัติศาสตร์ของสถานที่แห่งนี้เป็นละครนิรันดร์เกี่ยวกับพลังทั้งสามที่จำเป็นสำหรับมนุษยชาติในการสร้างและสร้างสรรค์ และพัฒนาเทคโนโลยี
ผู้สร้าง
ในตอนแรกมีผู้สร้าง เหล่านี้เป็นศิลปินที่ผืนผ้าใบว่างเปล่าดูเหมือนเป็นโอกาสที่ไม่อาจต้านทานได้ ศิลปินยุคแรกวางพิกเซลแบบสุ่มเพื่อดูว่าพวกเขาสามารถทำอะไรได้บ้าง ในนาทีแรก ภาพร่างแรกก็ปรากฏขึ้น หยาบและยังไม่บรรลุนิติภาวะ มีลักษณะคล้ายกับภาพวาดในถ้ำของมนุษย์ถ้ำ
ผู้สร้างมองเห็นได้ทันทีว่าพิกเซลซ่อนพลังและศักยภาพอะไรไว้บ้าง แต่การทำงานโดยลำพัง พวกเขาสามารถวางหนึ่งพิกเซลทุกๆ 5 หรือ 10 นาที การสร้าง การวาดภาพที่มีความหมายจะใช้เวลาตลอดไป เพื่อจะวาดอะไรบางอย่าง พวกเขาต้องทำงานร่วมกัน
จากนั้นมีคนมีความคิดที่ยอดเยี่ยมที่จะใช้ตารางในการวาดภาพ ซึ่งจะวางซ้อนบนภาพวาดและแสดงว่าพิกเซลถัดไปควรอยู่ที่ใด คนแรกที่ได้รับการทดลองนี้คือมีมชื่อดังของอินเทอร์เน็ตที่พูดภาษาอังกฤษ Dickbutt และผู้อยู่อาศัยในสถานที่นั้นก็ต้องทำงาน: Dickbutt ปรากฏตัวขึ้นอย่างแท้จริงในไม่กี่นาทีที่มุมซ้ายล่างของผืนผ้าใบ การสร้างความคิดสร้างสรรค์ร่วมกันครั้งแรกปรากฏบนเว็บไซต์
จากนั้น เมื่อผู้สร้างเริ่มมึนเมาเล็กน้อยกับความเป็นไปได้ต่างๆ Pokémon Charmander ก็ปรากฏตัวขึ้น ซึ่งในไม่ช้าก็มีองคชาตแทนที่จะเป็นขา และความขัดแย้งครั้งแรกเริ่มต้นขึ้น: ผู้สร้างบางคนพยายามอย่างขยันขันแข็งที่จะทำความสะอาดภาพวาดที่ไม่เหมาะสม แต่คนอื่น ๆ ก็เพิ่มความหยาบคายอย่างต่อเนื่อง
ผู้สร้างต้องเผชิญกับปัญหาทางปรัชญาพื้นฐาน: เสรีภาพที่มากเกินไปนำไปสู่ความสับสนวุ่นวาย ความคิดสร้างสรรค์จำเป็นต้องมีข้อจำกัดพอๆ กับที่ต้องการอิสรภาพ
ผู้พิทักษ์
ผู้ใช้ประเภทอื่นปรากฏตัวขึ้นในสถานที่ซึ่งต้องจัดการกับปัญหานี้ แต่พวกเขาเริ่มต้นด้วยเป้าหมายดั้งเดิมที่มากกว่า นั่นคือการพิชิตโลก พวกเขาแบ่งออกเป็นฝ่ายตามสี พวกเขาพยายามยึดครองสถานที่นี้ หนึ่งในคนแรกคือมุมสีฟ้า เกิดขึ้นที่มุมขวาล่างและแพร่กระจายเหมือนโรคระบาด
อีกกลุ่มหนึ่งก่อตั้ง Red Corner เมื่อ ฝั่งตรงข้ามผืนผ้าใบพวกเขาเอนเอียงไปทางฝ่ายซ้ายทางการเมือง อีกกลุ่มหนึ่งที่เรียกว่า Green Grid วาดภาพผืนผ้าใบผ่านพิกเซล - เซลล์สีเขียวสลับกับเซลล์สีขาว เนื่องจากพวกเขาต้องลงสีเพียงครึ่งพิกเซล พวกมันจึงมีประสิทธิภาพมากกว่ากลุ่มอื่นๆ
ใช้เวลาไม่นานก่อนที่ฝ่ายต่างๆ จะปะทะกับผู้สร้าง Charmander กลายเป็นหนึ่งในเป้าหมายแรกของการต่อสู้ มุมสีน้ำเงินเริ่มวาดภาพโปเกมอนด้วยพิกเซลสีน้ำเงิน และผู้สร้างได้เปลี่ยนจาก "สงครามลึงค์" (ซึ่งสามารถดึงดูดจู๋ได้มากที่สุด) ไปสู่ภัยคุกคามที่ร้ายแรงยิ่งขึ้น พวกเขาต่อสู้กัน โดยวาดภาพพิกเซลสีน้ำเงินทุกอันด้วยตัวของพวกเขาเอง แต่ข้อได้เปรียบเชิงปริมาณไม่เข้าข้างพวกเขา
ดังนั้นผู้สร้างจึงยอมจำนนต่อความเมตตาของผู้ชนะและสิ่งนี้ก็ทำร้ายความรู้สึกของชาวบลูส์ ในหมู่พวกเขาปรากฏผู้ที่สงสัยในบทบาทของตนในโลกแห่งสถานที่ “คลื่นของเราจะปกคลุมโลกทั้งใบอย่างหลีกเลี่ยงไม่ได้ หากเราแสดงความเมตตาต่องานศิลปะอื่นๆ ที่เราพบเจอ” หนึ่งในกลุ่มถาม
แต่ละฝ่ายต้องเผชิญกับคำถามนี้ และทุกคนก็ตัดสินใจบันทึกภาพวาดอื่นๆ ดังนั้นคลื่นสีจึงเริ่มไหลไปรอบๆ ภาพวาดโดยไม่ได้ทาสี
นี่เป็นจุดเปลี่ยน กลุ่มที่มีสีไร้เหตุผลกลายเป็นผู้พิทักษ์ที่มีประโยชน์
แต่มันยังไม่ใช่ตอนจบที่มีความสุข
ในที่สุด คลื่นสีที่ไม่รู้จักพอก็หยุดลง และผู้สร้างก็สามารถกลับคืนสู่ความคิดสร้างสรรค์ได้ ภาพวาดมีความซับซ้อนมากขึ้นเรื่อยๆ ข้อความที่เขียนเป็นพิกเซลปรากฏขึ้น
ผู้สร้างได้จัดตั้งกลุ่มเล็กๆ โดยสร้าง subreddits ที่พวกเขาจะได้พูดคุยเกี่ยวกับศิลปะร่างและกลยุทธ์ กลุ่มที่ประสบความสำเร็จมากที่สุดกลุ่มหนึ่งวาดแถบงานในรูปแบบของ Windows 95 อีกกลุ่มหนึ่งวาดภาพสถานที่ด้วยหัวใจ
จากนั้นแวนโก๊ะก็ปรากฏตัวขึ้น
แต่มันไม่ง่ายขนาดนั้น ผู้ปกป้องกลายเป็นผู้เผด็จการโดยกำหนดรูปแบบการวาดภาพ พวกเขาตัดสินใจว่าอะไรวาดได้และอะไรวาดไม่ได้ กลุ่มต่างๆ เริ่มแบ่งแยกผู้ใช้ระหว่างกัน เรียกร้องฝ่ายต่างๆ ในขณะที่ผู้สร้างกำลังรอการอนุมัติแนวคิดใหม่ๆ
การต่อสู้ระหว่างฝ่ายปกป้องเริ่มดุเดือดมากขึ้น สตรีมเมอร์ Twitch คนหนึ่งกระตุ้นให้ผู้ติดตามของเขาโจมตี Blue กลยุทธ์การต่อสู้ได้รับการพัฒนา มีการยั่วยุด้วยซ้ำ: แฟน ๆ ที่มีสีเดียวกันเองก็วาดภาพพิกเซลสีของศัตรูในอาณาเขตของตนเพื่อที่จะมีข้อแก้ตัวสำหรับการโจมตีตอบโต้ ในขณะที่ฝ่ายต่าง ๆ ต่อสู้กันเอง ผู้สร้างก็พบว่าไม่มีที่ว่างเหลือสำหรับภาพวาดใหม่
ธงก็เริ่มปรากฏ ประเทศต่างๆ– เมื่อพวกเขาโตขึ้น พวกเขาก็มักจะชนกันอย่างหลีกเลี่ยงไม่ได้ ตัวอย่างเช่น ธงของเยอรมนีและฝรั่งเศสชนกันใน "ดินแดนที่ไม่มีมนุษย์"
ดูเหมือนว่าโลกใบเล็กนี้จวนจะเกิดสงคราม ทุกฝ่ายพยายามแก้ไขข้อขัดแย้งอย่างมีชั้นเชิง ผู้นำของผู้สร้างและผู้ปกป้องสื่อสารกันในการแชท แต่มักจะจบลงด้วยการกล่าวหาร่วมกัน
สถานที่แห่งนี้ต้องการผู้ร้ายที่ทุกคนสามารถรวมตัวกันเพื่อต่อต้านได้
เรือพิฆาต
ความว่างเปล่าได้มาเยือนแล้ว
มันเริ่มต้นด้วย 4chan ซึ่งเป็นบอร์ดรูปภาพที่มีชื่อเสียงที่สุดในโลก พวกเล่นแผลง ๆ ที่อาศัยอยู่ในนั้นสังเกตเห็นสิ่งที่เกิดขึ้นใน Reddit และไม่สามารถเพิกเฉยได้ พวกเขากลายเป็นความว่างเปล่า
จุดพิกเซลสีดำเริ่มเติบโตตรงกลางสถานที่ ในตอนแรก ฝ่ายต่างๆ พยายามที่จะสรุปสนธิสัญญากับเดอะวอยด์โดยใช้การทูต แต่พวกเขาล้มเหลว The Void ทำหน้าที่แตกต่างออกไป เธอไม่ใช่หนึ่งในผู้พิทักษ์ เธอไม่ได้ปกป้องงานศิลปะ ผู้ติดตามของเธอเทศน์ว่า The Void จะกลืนกินทุกสิ่ง พวกเขาไม่ได้รวมตัวกัน พวกเขาเพียงต้องการทาให้โลกทั้งใบเป็นสีดำ
นี่เป็นการเตะเข้าที่ตูดที่เพลสต้องการ เมื่อต้องเผชิญกับภัยคุกคามร่วมกัน ผู้สร้างและผู้ปกป้องจึงรวมตัวกันอีกครั้งเพื่อปกป้องงานศิลปะ แต่จุดประสงค์ของ the Void ไม่ใช่แค่การทำลายล้างเท่านั้น แต่ยังก่อให้เกิดงานศิลปะใหม่ที่ดีกว่าอีกด้วย
ตัวอย่างเช่น ตำแหน่งตรงกลางเป็นหนึ่งในตำแหน่งที่ผู้สร้างโต้แย้งกันมากที่สุด และเมื่อมันกลายเป็นสีดำ เหล่าผู้พิทักษ์ก็ตระหนักว่าพวกเขาจะต้องคิดไอเดียที่ดีกว่าที่จะดึงดูดผู้ติดตามให้มากพอที่จะต่อสู้กับสัตว์ประหลาดสีดำ หนึ่งในแนวคิดเหล่านี้คือธงชาติสหรัฐอเมริกา
ในวันสุดท้ายของการดำรงอยู่ของสถานที่นี้ แนวร่วมที่น่าทึ่งที่สุดได้ก่อตั้งขึ้นในนั้น ซึ่งออกแบบมาเพื่อต่อสู้กับความว่างเปล่า - มีแฟน ๆ ของทรัมป์และฝ่ายตรงข้ามของทรัมป์ รีพับลิกันและเดโมแครต ชาวอเมริกันและชาวยุโรป
การทดลอง Reddit สิ้นสุดลงในไม่ช้า ไม่มีภาพวาดเหยียดเชื้อชาติหรือสัญลักษณ์แห่งความเกลียดชังแม้แต่ภาพเดียวบนผืนผ้าใบสุดท้าย
ทวิตเตอร์
กระเป๋า
ลิงค์ดิน
ผู้ส่งสารเอฟบี
ประการแรก การกำหนดข้อกำหนดสำหรับโปรเจ็กต์ April Fool's นั้นเป็นสิ่งสำคัญอย่างยิ่ง เนื่องจากจะต้องเปิดตัวโดยไม่ต้อง "โอเวอร์คล็อก" เพื่อให้ผู้ใช้ Reddit ทุกคนสามารถเข้าถึงได้ทันที ถ้ามันทำงานได้ไม่สมบูรณ์แบบตั้งแต่เริ่มแรก มันคงไม่ดึงดูดความสนใจของคนจำนวนมากได้
- ต้องจัดให้มีการกำหนดค่าที่ยืดหยุ่นในกรณีที่เกิดปัญหาคอขวดหรือความล้มเหลวที่ไม่คาดคิด นั่นคือคุณจะต้องสามารถปรับขนาดของบอร์ดและความถี่ในการวาดที่อนุญาตได้ทันทีหากปริมาณข้อมูลมากเกินไปหรือความถี่ในการอัปเดตสูงเกินไป
"กระดาน" ควรมีขนาด 1,000x1000 แผ่นเพื่อให้ดูใหญ่มาก
ไคลเอนต์ทั้งหมดควรซิงโครไนซ์และแสดงสถานะของบอร์ดเดียวกัน ท้ายที่สุดแล้ว หากผู้ใช้ต่างกันมีเวอร์ชันที่แตกต่างกัน ก็จะเป็นการยากสำหรับพวกเขาในการโต้ตอบ
คุณต้องรองรับผู้ใช้พร้อมกันอย่างน้อย 100,000 ราย
ผู้ใช้สามารถวางหนึ่งไทล์ทุกๆ ห้านาที ดังนั้นจึงจำเป็นต้องรักษาอัตราการอัพเดตเฉลี่ย 100,000 ไทล์ต่อห้านาที (333 อัพเดตต่อวินาที)
โครงการไม่ควรส่งผลเสียต่อการดำเนินงานของส่วนอื่นๆ และฟังก์ชันอื่นๆ ของไซต์ (แม้ว่าจะมีการรับส่งข้อมูลบน r/Place สูงก็ตาม)
แบ็กเอนด์
โซลูชั่นการดำเนินงาน
ปัญหาหลักในการสร้างแบ็กเอนด์คือการซิงโครไนซ์การแสดงสถานะของบอร์ดกับไคลเอนต์ทั้งหมด มีการตัดสินใจว่าให้ลูกค้าฟังเหตุการณ์การวางตำแหน่งไทล์แบบเรียลไทม์ และสอบถามสถานะของกระดานทั้งหมดทันที การมีสถานะเต็มล้าสมัยเล็กน้อยเป็นที่ยอมรับได้หากคุณสมัครรับการอัปเดตก่อนที่จะสร้างสถานะเต็ม เมื่อไคลเอนต์ได้รับสถานะเต็ม มันจะแสดงไทล์ทั้งหมดที่ได้รับขณะรอ ไทล์ที่ตามมาทั้งหมดจะต้องปรากฏบนกระดานทันทีที่ได้รับ
เพื่อให้โครงการนี้ทำงานได้ตามคำขอ สภาพเต็มบอร์ดควรจะแล้วเสร็จโดยเร็วที่สุด ในตอนแรก เราต้องการจัดเก็บบอร์ดทั้งหมดไว้ในแถวเดียวใน Cassandra และให้แต่ละคำขออ่านแถวนั้น รูปแบบของแต่ละคอลัมน์ในบรรทัดนี้คือ:
(x, y): ('timestamp': epochms, 'author': user_name, 'color': color)
แต่เนื่องจากกระดานมีหนึ่งล้านช่อง เราจึงต้องอ่านหนึ่งล้านคอลัมน์ ในคลัสเตอร์การผลิตของเรา การดำเนินการนี้ใช้เวลานานถึง 30 วินาที ซึ่งเป็นที่ยอมรับไม่ได้และอาจส่งผลให้ Cassandra มีภาระงานมากเกินไป
จากนั้นเราตัดสินใจจัดเก็บกระดานทั้งหมดไว้ใน Redis เราใช้ฟิลด์บิตของตัวเลขสี่บิตจำนวนหนึ่งล้านตัว ซึ่งแต่ละตัวสามารถเข้ารหัสสีสี่บิตได้ และพิกัด x และ y ถูกกำหนดโดยออฟเซ็ต (ออฟเซ็ต = x + 1,000y) ในช่องบิต เพื่อให้ได้สถานะเต็มของบอร์ด จะต้องอ่านฟิลด์บิตทั้งหมด
สามารถอัปเดตไทล์ได้โดยการอัปเดตค่าที่ออฟเซ็ตเฉพาะ (ไม่จำเป็นต้องบล็อกหรือดำเนินการตามขั้นตอนการอ่าน/อัปเดต/เขียนทั้งหมด) แต่รายละเอียดทั้งหมดยังต้องถูกจัดเก็บไว้ใน Cassandra เพื่อให้ผู้ใช้สามารถค้นหาได้ว่าใครเป็นผู้วางแต่ละไทล์และเมื่อใด นอกจากนี้เรายังวางแผนที่จะใช้ Cassandra เพื่อกู้คืนบอร์ดเมื่อ Redis ขัดข้อง การอ่านกระดานทั้งหมดใช้เวลาน้อยกว่า 100 มิลลิวินาที ซึ่งค่อนข้างเร็ว
ต่อไปนี้คือวิธีที่เราจัดเก็บสีใน Redis โดยใช้ตัวอย่างบอร์ด 2x2:
เรากังวลว่าเราอาจประสบปัญหาความเร็วในการอ่านใน Redis หากไคลเอนต์จำนวนมากเชื่อมต่อหรืออัปเดตในเวลาเดียวกัน พวกเขาทั้งหมดจะส่งคำขอสถานะเต็มของบอร์ดไปพร้อมๆ กัน เนื่องจากบอร์ดเป็นตัวแทนของสถานะส่วนกลางที่ใช้ร่วมกัน วิธีแก้ปัญหาที่ชัดเจนคือการใช้แคช เราตัดสินใจแคชที่ระดับ CDN (เร็ว) เนื่องจากง่ายต่อการนำไปใช้ และแคชนั้นได้รับมาใกล้กับไคลเอนต์มากที่สุด ซึ่งช่วยลดเวลาในการรับการตอบกลับ
คำขอสถานะเต็มบอร์ดถูกแคชโดย Fastly โดยหมดเวลาเพียงเสี้ยววินาที เพื่อป้องกันไม่ให้คำขอจำนวนมากหมดเวลา เราใช้ส่วนหัวเก่าขณะตรวจสอบใหม่ รองรับ POP ประมาณ 33 POP อย่างรวดเร็วซึ่งแคชซึ่งกันและกันอย่างอิสระ ดังนั้นเราจึงคาดว่าจะได้รับคำขอสถานะบอร์ดเต็มรูปแบบสูงสุด 33 รายการต่อวินาที
เพื่อเผยแพร่การอัปเดตไปยังไคลเอนต์ทั้งหมด เราใช้บริการ websocket ของเรา ก่อนหน้านี้เราใช้มันอย่างประสบความสำเร็จในการเพิ่มพลังให้กับ Reddit.Live โดยมีผู้ใช้พร้อมกันมากกว่า 100,000 รายสำหรับการแจ้งเตือนข้อความส่วนตัวแบบ Live และคุณสมบัติอื่น ๆ การบริการยังเป็นรากฐานสำคัญของโปรเจ็กต์วันเอพริลฟูลที่ผ่านมาของเราอย่าง The Button และ Robin ในกรณีของ r/Place ลูกค้ารองรับการเชื่อมต่อ websocket เพื่อรับการอัปเดตแบบเรียลไทม์เกี่ยวกับตำแหน่งไทล์
เอพีไอ
รับสถานะเต็มกระดาน
ในตอนแรกคำขอไปที่ Fastly หากมีสำเนาบอร์ดที่ถูกต้อง ก็จะส่งคืนทันทีโดยไม่ต้องติดต่อกับเซิร์ฟเวอร์แอปพลิเคชันของ Reddit หากไม่เป็นเช่นนั้น หรือสำเนาเก่าเกินไป แอป Reddit จะอ่านกระดานทั้งหมดจาก Redis และส่งคืนไปที่ Fastly เพื่อแคชและส่งกลับไปยังไคลเอนต์
โปรดทราบว่าอัตราการร้องขอไม่เคยถึง 33 ต่อวินาที หมายความว่าการแคชด้วย Fastly มีประสิทธิภาพมากในการปกป้องแอป Reddit จากคำขอส่วนใหญ่
และเมื่อคำขอมาถึงแอปพลิเคชัน Redis ก็ตอบกลับอย่างรวดเร็ว
วาดกระเบื้อง
ขั้นตอนของการวาดกระเบื้อง:
- การประทับเวลาของตำแหน่งสุดท้ายของไทล์ของผู้ใช้จะถูกอ่านจาก Cassandra หากเป็นเวลาน้อยกว่าห้านาทีที่แล้ว เราจะไม่ทำอะไรเลยและจะส่งคืนข้อผิดพลาดให้กับผู้ใช้
- รายละเอียดไทล์เขียนถึง Redis และ Cassandra
- เวลาปัจจุบันจะถูกบันทึกใน Cassandra เป็นครั้งสุดท้ายที่ผู้ใช้วางไทล์
- บริการ websocket ส่งข้อความเกี่ยวกับไทล์ใหม่ไปยังไคลเอนต์ที่เชื่อมต่อทั้งหมด
เพื่อรักษาความสอดคล้องที่เข้มงวด การเขียนและการอ่านทั้งหมดใน Cassandra ดำเนินการโดยใช้เลเยอร์ความสอดคล้อง QUORUM
ที่จริงแล้ว เรามีการแข่งขันกันที่นี่ซึ่งผู้ใช้สามารถวางไทล์หลายอันพร้อมกันได้ ไม่มีการบล็อกในระยะที่ 1–3 ดังนั้นการพยายามจั่วแผ่นกระเบื้องพร้อมกันจึงสามารถผ่านการตรวจสอบในระยะแรกและจั่วได้ในระยะที่สอง ดูเหมือนว่าผู้ใช้บางคนค้นพบจุดบกพร่องนี้ (หรือพวกเขาใช้บอทที่เพิกเฉยต่อขีดจำกัดความถี่ของคำขอ) - และด้วยเหตุนี้ มีการวางไทล์ประมาณ 15,000 แผ่นโดยใช้มัน (~ 0.09% ของทั้งหมด)
อัตราคำขอและเวลาตอบสนองที่วัดโดยแอป Reddit:
อัตราการวางไทล์สูงสุดอยู่ที่เกือบ 200 ต่อวินาที ซึ่งต่ำกว่าขีดจำกัดโดยประมาณของเราที่ 333 แผ่น/วินาที (โดยเฉลี่ยสมมติว่าผู้ใช้ 100,000 รายวางแผ่นทุกๆ ห้านาที)
การรับรายละเอียดสำหรับไทล์เฉพาะ
เมื่อร้องขอไทล์เฉพาะ ข้อมูลจะถูกอ่านโดยตรงจาก Cassandra
อัตราคำขอและเวลาตอบสนองที่วัดโดยแอป Reddit:
คำขอนี้ได้รับความนิยมอย่างมาก นอกเหนือจากคำขอของลูกค้าทั่วไปแล้ว ผู้คนยังได้เขียนสคริปต์เพื่อดึงข้อมูลทั้งกระดานทีละไทล์ เนื่องจากคำขอนี้ไม่ได้แคชไว้ใน CDN คำขอทั้งหมดจึงให้บริการโดยแอปพลิเคชัน Reddit
เวลาในการตอบสนองต่อคำขอเหล่านี้ค่อนข้างสั้นและยังคงอยู่ที่ระดับเดิมตลอดอายุของโครงการ
เว็บซ็อกเก็ต
เราไม่มีตัวชี้วัดส่วนบุคคลที่แสดงให้เห็นว่า r/Place ส่งผลต่อบริการ websocket อย่างไร แต่เราสามารถประมาณค่าได้โดยการเปรียบเทียบข้อมูลก่อนเริ่มโครงการและหลังเสร็จสิ้น
จำนวนการเชื่อมต่อกับบริการ websocket ทั้งหมด:
โหลดพื้นฐานก่อนการเปิดตัว r/Place มีการเชื่อมต่อประมาณ 20,000 ครั้ง ยอดสูงสุดอยู่ที่ 100,000 การเชื่อมต่อ เมื่อถึงจุดสูงสุด เราอาจมีผู้ใช้ประมาณ 80,000 รายที่เชื่อมต่อกับ r/Place
ปริมาณงานบริการ Websocket:
ที่จุดสูงสุดของการโหลดบน r/Place บริการ websocket ถ่ายโอนมากกว่า 4 Gbps (150 Mbps ต่ออินสแตนซ์ รวมทั้งหมด 24 อินสแตนซ์)
ส่วนหน้า: เว็บและไคลเอนต์มือถือ
ในกระบวนการสร้างส่วนหน้าของ Place เราต้องตัดสินใจมากมาย งานที่ซับซ้อนที่เกี่ยวข้องกับการพัฒนาข้ามแพลตฟอร์ม เราต้องการให้โปรเจ็กต์ทำงานเหมือนกันบนแพลตฟอร์มหลักทั้งหมด รวมถึงเดสก์ท็อปและ อุปกรณ์เคลื่อนที่บน iOS และ Android
อินเทอร์เฟซผู้ใช้ต้องทำหน้าที่สำคัญสามประการ:
- แสดงสถานะของบอร์ดแบบเรียลไทม์
- อนุญาตให้ผู้ใช้โต้ตอบกับบอร์ด
- ทำงานบนทุกแพลตฟอร์ม รวมถึงแอปพลิเคชันบนมือถือ
ออบเจ็กต์หลักของอินเทอร์เฟซคือแคนวาส และ Canvas API ก็เหมาะอย่างยิ่งสำหรับอินเทอร์เฟซนี้ เราใช้องค์ประกอบ
วาดภาพผืนผ้าใบ
ผืนผ้าใบต้องสะท้อนสถานะของบอร์ดแบบเรียลไทม์ จำเป็นต้องวาดทั้งกระดานเมื่อโหลดหน้าและเสร็จสิ้นการอัปเดตที่มาจากเว็บซ็อกเก็ต องค์ประกอบแคนวาสที่ใช้อินเทอร์เฟซ CanvasRenderingContext2D สามารถอัปเดตได้สามวิธี:
- สี รูปภาพที่มีอยู่บนผืนผ้าใบโดยใช้ DrawImage()
- วาดรูปทรงโดยใช้ วิธีการที่แตกต่างกันแบบฟอร์มการวาดภาพ ตัวอย่างเช่น fillRect() เติมสีลงในสี่เหลี่ยม
- สร้างวัตถุ ImageData และวาดลงบนผืนผ้าใบโดยใช้ putImageData()
ตัวเลือกแรกไม่เหมาะกับเราเนื่องจากเราไม่มีกระดานในรูปแบบของภาพที่เสร็จแล้ว ซึ่งเหลือตัวเลือกที่ 2 และ 3 วิธีที่ง่ายที่สุดคือการอัปเดตแต่ละไทล์โดยใช้ fillRect() : เมื่อมีการอัปเดตมาถึงผ่าน websocket เราก็เพียงวาดรูปสี่เหลี่ยมขนาด 1x1 ที่ตำแหน่ง (x, y) โดยทั่วไปวิธีนี้ใช้งานได้ แต่ไม่สะดวกในการวาดสถานะเริ่มต้นของบอร์ด เมธอด putImageData() ดีกว่ามาก: เราสามารถกำหนดสีของแต่ละพิกเซลในออบเจ็กต์ ImageData เดียวและวาดทั้งผืนผ้าใบได้ในคราวเดียว
การวาดสถานะเริ่มต้นของบอร์ด
การใช้ putImageData() จำเป็นต้องกำหนดสถานะของบอร์ดเป็น Uint8ClampedArray โดยที่แต่ละค่าเป็นตัวเลขแปดบิตที่ไม่ได้ลงนามในช่วง 0 ถึง 255 แต่ละค่าแสดงถึงช่องสี (แดง เขียว น้ำเงิน อัลฟา) และแต่ละค่า pixel ต้องมีสี่องค์ประกอบในอาร์เรย์ ผืนผ้าใบ 2x2 ต้องใช้อาร์เรย์ 16 ไบต์ โดยที่สี่ไบต์แรกแสดงถึงพิกเซลด้านซ้ายบนของผืนผ้าใบ และสี่ไบต์สุดท้ายแสดงถึงพิกเซลด้านขวาล่าง
นี่คือวิธีที่พิกเซลแคนวาสเชื่อมโยงกับการเป็นตัวแทน Uint8ClampedArray:
สำหรับผืนผ้าใบของโปรเจ็กต์ของเรา เราต้องการอาร์เรย์สี่ล้านไบต์ - 4 MB
ในแบ็กเอนด์ สถานะของบอร์ดจะถูกจัดเก็บเป็นฟิลด์บิตสี่บิต แต่ละสีจะแสดงด้วยตัวเลขตั้งแต่ 0 ถึง 15 ซึ่งช่วยให้เราบรรจุพิกเซลสองพิกเซลลงในแต่ละไบต์ได้ หากต้องการใช้สิ่งนี้บนอุปกรณ์ไคลเอนต์ คุณต้องทำสามสิ่ง:
- ถ่ายโอนข้อมูลไบนารีจาก API ของเราไปยังไคลเอนต์
- แกะข้อมูล
- แปลงสีสี่บิตเป็น 32 บิต
ในการถ่ายโอนข้อมูลไบนารี เราใช้ Fetch API ในเบราว์เซอร์ที่รองรับ และในส่วนที่ไม่สนับสนุนเราก็ใช้ XMLHttpRequestโดยที่ responseType ตั้งค่าเป็น “arraybuffer”
ข้อมูลไบนารีที่ได้รับจาก API มีสองพิกเซลในแต่ละไบต์ ตัวสร้าง TypedArray ที่เล็กที่สุดที่เรามีช่วยให้คุณสามารถทำงานกับข้อมูลไบนารีในรูปแบบของหน่วยไบต์เดียว แต่สิ่งเหล่านี้ใช้งานบนอุปกรณ์ไคลเอนต์ได้ยาก ดังนั้นเราจึงแตกแพ็กข้อมูลเพื่อให้ทำงานได้ง่ายขึ้น กระบวนการนี้ง่ายดาย: เราวนซ้ำข้อมูลที่แพ็ก ดึงบิตลำดับสูงและลำดับต่ำออกมา จากนั้นคัดลอกพวกมันลงในไบต์เดี่ยว ๆ ลงในอาร์เรย์อื่น
สุดท้ายต้องแปลงสีสี่บิตเป็น 32 บิต
โครงสร้าง ImageData ที่เราจำเป็นต้องใช้ putImageData() ต้องการให้ผลลัพธ์สุดท้ายเป็น Uint8ClampedArray พร้อมไบต์ที่เข้ารหัสช่องสีตามลำดับ RGBA ซึ่งหมายความว่าเราจำเป็นต้องทำการคลายการบีบอัดอีกครั้ง โดยแบ่งแต่ละสีออกเป็นไบต์ของช่องส่วนประกอบ และวางไว้ในดัชนีที่ถูกต้อง การเขียนสี่ครั้งต่อพิกเซลไม่สะดวกนัก แต่โชคดีที่มีอีกทางเลือกหนึ่ง
อ็อบเจ็กต์ TypedArray เป็นตัวแทนอาร์เรย์ของ ArrayBuffer เป็นหลัก มีข้อแม้ประการหนึ่งที่นี่: อินสแตนซ์ TypedArray หลายรายการสามารถอ่านและเขียนไปยังอินสแตนซ์ ArrayBuffer เดียวกันได้ แทนที่จะเขียนค่าสี่ค่าลงในอาร์เรย์ 8 บิต เราสามารถเขียนค่าหนึ่งค่าลงในอาร์เรย์ 32 บิตได้! ด้วยการใช้ Uint32Array ในการเขียน เราสามารถอัปเดตสีไทล์ได้อย่างง่ายดายเพียงอัปเดตดัชนีอาร์เรย์เดียว อย่างไรก็ตาม เราต้องจัดเก็บจานสีของเราตามลำดับไบต์ขนาดใหญ่ (ABGR) เพื่อให้ไบต์ไปอยู่ในตำแหน่งที่ถูกต้องโดยอัตโนมัติเมื่ออ่านโดยใช้ Uint8ClampedArray
กำลังประมวลผลการอัปเดตที่ได้รับผ่าน websocket
เมธอด DrawRect() นั้นดีสำหรับการอัปเดตแต่ละพิกเซลเมื่อได้รับ แต่มีจุดอ่อนประการหนึ่ง นั่นคือ การอัปเดตจำนวนมากที่มาถึงพร้อมกันอาจทำให้เบราว์เซอร์ช้าลง และเราเข้าใจดีว่าการอัปเดตสถานะของบอร์ดอาจเกิดขึ้นบ่อยมาก ดังนั้นปัญหาจึงต้องได้รับการแก้ไขด้วยวิธีใดวิธีหนึ่ง
แทนที่จะวาดภาพแคนวาสใหม่ทันทีทุกครั้งที่ได้รับการอัปเดตผ่าน websocket เราตัดสินใจที่จะดำเนินการดังกล่าวเพื่อให้สามารถอัปเดต websocket ที่มาถึงในเวลาเดียวกันเป็นชุดและแสดงผลพร้อมกันได้ เพื่อให้บรรลุเป้าหมายนี้ จึงมีการเปลี่ยนแปลง 2 ประการ:
- หยุดใช้ DrawRect() - เราพบแล้ว วิธีที่สะดวกอัปเดตหลายพิกเซลในแต่ละครั้งโดยใช้ putImageData()
- การถ่ายโอนการเรนเดอร์แคนวาสไปยังลูป requestAnimationFrame
ด้วยการย้ายการเรนเดอร์ไปยังลูปแอนิเมชั่น เราสามารถเขียนการอัปเดต websocket ไปยัง ArrayBuffer ได้ทันทีในขณะที่เลื่อนการเรนเดอร์จริงไปด้วย การอัปเดต websocket ทั้งหมดที่มาถึงระหว่างเฟรม (ประมาณ 16 ms) ได้รับการจัดกลุ่มและแสดงผลพร้อมกัน ต้องขอบคุณการใช้ requestAnimationFrame หากการเรนเดอร์ใช้เวลานานเกินไป (นานกว่า 16 ms) จะส่งผลต่ออัตราการรีเฟรชแคนวาสเท่านั้น (แทนที่จะลดประสิทธิภาพของเบราว์เซอร์ทั้งหมด)
การโต้ตอบกับผืนผ้าใบ
สิ่งสำคัญคือต้องทราบว่าจำเป็นต้องใช้ Canvas เพื่อให้ผู้ใช้สามารถโต้ตอบกับระบบได้สะดวกยิ่งขึ้น สถานการณ์การโต้ตอบหลักคือการวางไทล์บนผืนผ้าใบ
แต่การเรนเดอร์ทุกพิกเซลอย่างแม่นยำในระดับ 1:1 จะเป็นเรื่องยากอย่างยิ่ง และเราจะไม่หลีกเลี่ยงข้อผิดพลาด ดังนั้นเราจึงต้องการการซูม (ใหญ่!) นอกจากนี้ ผู้ใช้จำเป็นต้องสามารถนำทางไปยังผืนผ้าใบได้อย่างง่ายดาย เนื่องจากมีขนาดใหญ่เกินไปสำหรับหน้าจอส่วนใหญ่ (โดยเฉพาะเมื่อใช้การซูม)
ซูม
เนื่องจากผู้ใช้สามารถวางไทล์ทุกๆ ห้านาที ข้อผิดพลาดในการวางตำแหน่งจึงน่าหงุดหงิดเป็นพิเศษสำหรับพวกเขา จำเป็นต้องใช้การซูมขนาดเพื่อให้กระเบื้องมีขนาดใหญ่เพียงพอและสามารถวางในตำแหน่งที่ถูกต้องได้อย่างง่ายดาย สิ่งนี้สำคัญอย่างยิ่งกับอุปกรณ์หน้าจอสัมผัส
เราใช้การซูม 40 เท่า กล่าวคือ แต่ละไทล์มีขนาด 40x40 เราห่อองค์ประกอบ