คำถามติดแท็ก memory-efficiency

วิธีการจัดระเบียบและจัดเก็บข้อมูลเพื่อให้ใช้หน่วยความจำในปริมาณที่น้อยที่สุดเท่าที่จะเป็นไปได้ในขณะที่ยังคงประโยชน์อย่างเต็มที่


8
พวกเขาจะทำอย่างไร: กระเบื้องนับล้านใน Terraria
ฉันได้สร้างเอ็นจิ้นเกมคล้ายกับTerrariaซึ่งส่วนใหญ่เป็นสิ่งที่ท้าทายและในขณะที่ฉันคิดว่าส่วนใหญ่แล้วฉันไม่สามารถคาดเดาได้ว่าพวกเขาจัดการกับกระเบื้องที่สามารถโต้ตอบ / เก็บเกี่ยวได้นับล้าน เกมมีในครั้งเดียว การสร้างไทล์ประมาณ 500,000 แผ่นนั่นคือ 1 ใน 20 ของสิ่งที่เป็นไปได้ในTerrariaในเครื่องยนต์ของฉันทำให้อัตราเฟรมลดลงจาก 60 เหลือประมาณ 20 ถึงแม้ว่าฉันจะยังคงแสดงเฉพาะไพ่ในมุมมองเท่านั้น ใจคุณฉันไม่ได้ทำอะไรกับกระเบื้องเพียงแค่ทำให้พวกเขาอยู่ในความทรงจำ อัปเดต : รหัสถูกเพิ่มเพื่อแสดงว่าฉันทำสิ่งต่าง ๆ อย่างไร นี่เป็นส่วนหนึ่งของชั้นเรียนที่จัดการกับกระเบื้องและดึงพวกเขา ฉันเดาว่าผู้ร้ายคือส่วน "foreach" ซึ่งวนซ้ำทุกอย่างแม้แต่ดัชนีที่ว่างเปล่า ... public void Draw(SpriteBatch spriteBatch, GameTime gameTime) { foreach (Tile tile in this.Tiles) { if (tile != null) { if (tile.Position.X < -this.Offset.X + 32) …

6
เราจะแก้ปัญหาความต้องการหน่วยความจำวิดีโอขนาดใหญ่ในเกม 2D ได้อย่างไร
เราจะแก้ปัญหาความต้องการหน่วยความจำวิดีโอขนาดใหญ่ในเกม 2D ได้อย่างไร เรากำลังพัฒนาเกม 2D (Factorio) ใน allegro C / C ++ และเรากำลังเผชิญปัญหากับการเพิ่มความต้องการหน่วยความจำวิดีโอเมื่อเนื้อหาของเกมเพิ่มขึ้น ขณะนี้เรารวบรวมข้อมูลทั้งหมดเกี่ยวกับรูปภาพที่จะถูกใช้ก่อนทำการครอบตัดรูปภาพเหล่านี้ให้มากที่สุดเท่าที่จะทำได้และจัดระเบียบให้เป็นแผนที่ขนาดใหญ่ให้แน่นที่สุด แผนที่เหล่านี้จะถูกเก็บไว้ในหน่วยความจำวิดีโอขนาดขึ้นอยู่กับข้อ จำกัด ของระบบ ปัจจุบันมักจะมี 2 ภาพสูงสุด 8192x8192 ดังนั้นพวกเขาต้องการหน่วยความจำวิดีโอ 256Mb ถึง 512Mb ระบบนี้ใช้งานได้ดีสำหรับเราเช่นเดียวกับการปรับแต่งที่เหมาะสมและแยกเธรดการแสดงผลและการอัปเดตเราสามารถดึงภาพหลายหมื่นภาพบนหน้าจอใน 60 fps; เรามีวัตถุมากมายบนหน้าจอและการอนุญาตให้ซูมออกขนาดใหญ่เป็นข้อกำหนดที่สำคัญ เนื่องจากเราต้องการเพิ่มมากขึ้นอาจมีปัญหากับข้อกำหนดหน่วยความจำวิดีโอดังนั้นระบบนี้อาจไม่สามารถใช้งานได้ หนึ่งในสิ่งที่เราต้องการลองคือมีแผนที่หนึ่งที่มีรูปภาพที่พบบ่อยที่สุดและที่สองเป็นแคช ภาพจะถูกย้ายไปที่นั่นจากบิตแมปหน่วยความจำตามความต้องการ มีสองปัญหาเกี่ยวกับวิธีการนี้: รูปวาดจากบิตแมปหน่วยความจำไปยังบิตแมปวิดีโอช้าอย่างเจ็บปวดใน allegro มันเป็นไปไม่ได้ที่จะทำงานกับวิดีโอบิตแมปที่นอกเหนือจากเธรดหลักใน allegro ดังนั้นจึงไม่สามารถใช้งานได้จริง ต่อไปนี้เป็นข้อกำหนดเพิ่มเติมบางประการที่เรามี: เกมดังกล่าวจะต้องถูกกำหนดไว้ดังนั้นปัญหาด้านประสิทธิภาพ / เวลาในการโหลดจะไม่สามารถเปลี่ยนแปลงสถานะของเกม เกมดังกล่าวเป็นแบบเรียลไทม์และเร็ว ๆ นี้จะเป็นผู้เล่นหลายคนเช่นกัน เราจำเป็นต้องหลีกเลี่ยงแม้แต่การพูดติดอ่างที่เล็กที่สุดในค่าใช้จ่ายทั้งหมด เกมส่วนใหญ่เป็นโลกที่เปิดกว้างอย่างต่อเนื่อง การทดสอบประกอบด้วยการวาดภาพสไปรต์ 10,000 ชุดเป็นชุดขนาดตั้งแต่ …


2
A * มีประสิทธิภาพแม้ในขณะที่อุปสรรคกำลังเคลื่อนที่หรือไม่?
ฉันเพิ่งเริ่มเรียนรู้เกี่ยวกับการค้นหาเส้นทางและได้มองหาอัลกอริทึม A * และข้อกังวลหลักของฉันคือมันเป็นตัวอย่างทั้งหมดที่ฉันได้เห็นแสดงอุปสรรคแบบคงที่มันคำนวณรอบ ถ้าฉันมีอุปสรรคในการเคลื่อนไหวให้พูดตัวละครอื่น ๆ ตัวอย่างเช่นการเคลื่อนที่ไปรอบ ๆ และตัวละครนั้นต้องหาทางไปรอบ ๆ ฉันคิดว่าฉันจะต้องใช้อัลกอริทึมในแต่ละเฟรม แต่ฉันกังวลว่าจะค่อนข้างแพง สำหรับฮาร์ดแวร์ในการประมวลผลแต่ละเฟรมสำหรับนักแสดงเคลื่อนไหวแต่ละคน ดังนั้น A * ยังคงมีประสิทธิภาพเพียงพอที่จะใช้เมื่อใดก็ตามที่มีการเคลื่อนย้ายสิ่งกีดขวางด้วยหรือมีวิธีอื่นในการค้นหาเส้นทางที่จัดการกับสิ่งกีดขวางที่เคลื่อนที่ได้มากกว่า

1
เหตุใดฉันจึงควรพิจารณาสร้างและใช้กลุ่มออบเจ็กต์แทนการสร้างวัตถุใหม่ในทันที
ฉันได้อ่านเกี่ยวกับรูปแบบนี้หลายครั้ง (จากมุมมองแนวปฏิบัติที่ดีที่สุด): การจัดสรรหน่วยความจำ : แทนที่จะสร้างวัตถุใหม่ในทันทีให้พิจารณาสร้างและใช้กลุ่มวัตถุเสมอ มันจะช่วยให้การกระจายตัวของหน่วยความจำน้อยลงและทำให้ตัวเก็บขยะทำงานน้อยลง อย่างไรก็ตามฉันไม่รู้ว่าที่จริงแล้วมันหมายถึงอะไร ฉันจะใช้มันได้อย่างไร ตัวอย่างเช่นฉันสามารถสร้างอินสแตนซ์ของการGameObjectใช้InstantiateUnity ได้หรือไม่ Instantiate(prefab, new Vector3(2.0F, 0, 0), Quaternion.identity); การใช้งานนี้หมดกำลังใจหรือไม่? มันหมายความว่าอะไร?

3
รูปแบบการจัดสรรหน่วยความจำที่ใช้ในการพัฒนาเกม
ฉันได้ทำการวิจัยการสร้างวิธีการจัดสรรของตัวเอง (ซึ่งจะสนับสนุนสิ่งต่าง ๆ เช่นพูลหน่วยความจำและการทำโปรไฟล์) อย่างไรก็ตามเมื่อฉันทำการวิจัยต่อไปฉันได้มองหาวิธีการนี้ในการพัฒนาเกม ฉันสามารถใช้เทคนิคการจัดสรรหน่วยความจำแบบใดและทำไมจึงเป็นเทคนิคที่ดี

3
คุณเตรียมตัวอย่างไรสำหรับเงื่อนไขหน่วยความจำไม่เพียงพอ?
นี้จะเป็นเรื่องง่ายสำหรับเกมที่มีขอบเขตกำหนดไว้อย่างดี แต่คำถามคือเกี่ยวกับเกม sandbox ที่ที่ผู้เล่นจะได้รับอนุญาตให้สร้างและสร้างอะไร เทคนิคที่เป็นไปได้: ใช้พูลหน่วยความจำที่มีขีด จำกัด สูงสุด ลบวัตถุที่ไม่ต้องการเป็นระยะ ๆ จัดสรรจำนวนหน่วยความจำเพิ่มเติมที่จุดเริ่มต้นเพื่อให้สามารถเป็นอิสระในภายหลังเป็นกลไกการกู้คืน ฉันจะบอกว่าประมาณ 2-4 MBs สิ่งนี้มีแนวโน้มที่จะเกิดขึ้นในแพลตฟอร์มมือถือ / คอนโซลซึ่งหน่วยความจำมักจะถูก จำกัด ไม่เหมือนกับพีซีขนาด 16 GB ของคุณ ฉันสมมติว่าคุณสามารถควบคุมการจัดสรร / การจัดสรรคืนหน่วยความจำได้อย่างสมบูรณ์และไม่มีการรวบรวมขยะ นั่นเป็นเหตุผลที่ฉันกำลังติดแท็กสิ่งนี้เป็น C ++ โปรดทราบว่าฉันไม่ได้พูดถึงรายการ C ++ ที่มีประสิทธิภาพ 7 "เตรียมพร้อมสำหรับเงื่อนไขหน่วยความจำไม่เพียงพอ"แม้ว่าจะเกี่ยวข้องกัน แต่ฉันต้องการดูคำตอบเพิ่มเติมเกี่ยวกับการพัฒนาเกมซึ่งคุณมักจะควบคุมสิ่งที่มากกว่า สิ่งที่เกิดขึ้น เพื่อสรุปคำถามคุณจะเตรียมตัวอย่างไรสำหรับเงื่อนไขหน่วยความจำไม่เพียงพอสำหรับเกมแซนด์บ็อกซ์เมื่อคุณกำหนดเป้าหมายแพลตฟอร์มด้วยคอนโซลหน่วยความจำ / อุปกรณ์เคลื่อนที่ จำกัด

1
ข้อเสียใด ๆ ในการส่งออกไฟล์เสียงที่ความเร็วสองเท่าจากนั้นมีการเล่นเอ็นจิ้นเกมที่ความเร็วครึ่ง
ฉันต้องการลดขนาดไฟล์และเพลงในเกมของฉันและ SFX ใช้เวลาอย่างมาก ถ้าฉันสร้างเพลงหรือเอฟเฟกต์เสียงที่ 120bpm จากนั้นจึงใช้จังหวะและระดับเสียงสองเท่าโดยใช้โปรแกรม DAW หรือสแตนด์อโลนจากนั้นบันทึกไฟล์เสียงความเร็วสองเท่าใหม่มันจะกลายเป็นขนาดไฟล์ต้นฉบับเพียงครึ่งเดียว ลดลงครึ่งหนึ่ง) จากนั้นฉันก็ใช้โปรแกรมเกมของฉัน (Unity) เพื่อเล่นไฟล์เสียง 240bpm ที่ความเร็วครึ่งหนึ่งดังนั้นตอนนี้มันฟังดูเป็นปกติ ไม่มีสิ่งประดิษฐ์หรือการบิดเบือน ดังนั้นนี่คือคำถาม: ฉันเสียสละอะไรเช่นพลังการประมวลผลเพื่อเล่นด้วยความเร็วครึ่งเดียวหรือไม่? ฉันกำลังโหลดไฟล์ที่มีขนาดเพียงครึ่งเดียวดังนั้นต้องมีการแลกเปลี่ยนบางอย่างใช่มั้ย ฉันมีความรู้สึกไม่มีใครในใจที่ถูกต้องของพวกเขาจะทำเช่นนี้ แต่ทำไมไม่

4
การจัดสรรหน่วยความจำแบบไดนามิกและการจัดการหน่วยความจำ
ในเกมเฉลี่ยมีหลายร้อยหรือหลายพันวัตถุในฉาก มันถูกต้องสมบูรณ์ในการจัดสรรหน่วยความจำสำหรับวัตถุทั้งหมดรวมถึงปืนนัด (กระสุน) แบบไดนามิกผ่านการเริ่มต้นใหม่ () ? ฉันควรสร้างพูลหน่วยความจำสำหรับการจัดสรรแบบไดนามิกหรือไม่จำเป็นต้องกังวลกับสิ่งนี้? เกิดอะไรขึ้นถ้าแพลตฟอร์มเป้าหมายเป็นอุปกรณ์เคลื่อนที่ จำเป็นต้องมีผู้จัดการหน่วยความจำในเกมมือถือไหม? ขอขอบคุณ. ภาษาที่ใช้: C ++; ขณะนี้ได้รับการพัฒนาภายใต้ Windows แต่มีแผนที่จะให้บริการในภายหลัง

2
วิธีที่ดีในการจัดการ AI แบบ offscreen หรือไม่
ตัวอย่างเช่น: สมมติว่ามี 10 ห้องในโลก และสมมุติว่าโลกนี้มีผู้อยู่อาศัย 10 รายการ และแต่ละเอนทิตี้ก็มี "กิจวัตรประจำวัน" ของตัวเองซึ่งมันทำหน้าที่บางอย่างในห้องและอาจนำทางระหว่างห้องด้วย เนื่องจากผู้เล่นสามารถอยู่ในห้องเดียวในเวลาเดียวเป็นวิธีที่ดีในการติดตามการกระทำที่หน่วยงานอื่นกำลังดำเนินการในห้องอื่นนอกจอ? ตัวเลือกที่ตรงไปตรงมาที่สุดคือการตรวจสอบแต่ละเอนทิตี 10 แห่งในทุกเฟรมตรวจสอบตำแหน่ง / สถานะของตนและพิจารณาว่าเอนทิตีควรอยู่ในห้องที่ผู้เล่นตั้งอยู่ในเวลาใดก็ตาม (สิ่งนี้รู้สึกได้ถึงทรัพยากรที่หนักมากโดยเฉพาะเมื่อจำนวนห้อง / นิติบุคคลเพิ่มขึ้น) อีกทางเลือกหนึ่งคือการติดตามเวลาที่ผ่านไปตั้งแต่เริ่มเกมจากนั้นแต่ละหน่วยงานจะตรวจสอบว่ารูปแบบของมันตัดกับห้องที่ผู้เล่นเปิดอยู่หรือไม่และตรวจสอบกับเวลาหรือไม่ เอนทิตีควรจะอยู่ในห้องเดียวกันในเวลานี้เอนทิตีที่มีรูปแบบไม่ตัดกับห้องปัจจุบันที่ผู้เล่นตั้งอยู่ไม่ทำอะไรจนกว่าผู้เล่นจะเข้าสู่ห้องที่รูปแบบของพวกเขาตัดกันและ ณ จุดนั้นคำนวณหรือไม่ พวกเขาควรจะทำให้ (แต่ถ้าพวกเขามีปฏิสัมพันธ์กับห้องพวกเขาจะต้องตรวจสอบสถานะของห้องที่ตัดเส้นทางเพื่อกำหนดตำแหน่งของพวกเขา ณ จุดนั้นในเวลาที่ไม่ดีเสมอ) ตัวเลือกที่สามที่ฉันเข้ามาคืออันดับแรกต้องดูเส้นทางที่ตัดกันตำแหน่งผู้เล่น (ดังที่อธิบายไว้ก่อนหน้านี้) อย่างที่สองเมื่อเข้าห้องตรวจสอบว่าผู้เล่นอยู่ในห้องนั้นหรือไม่ถ้าไม่ใช่เพื่อตรวจสอบเฉพาะ สถานะของห้องและใช้เวลานานเท่าใดในการไปยังห้องถัดไป ตัวอย่างเช่นนักการภารโรง NPC เข้าห้องตรวจสอบสถานะของห้องเห็นว่ามีการรั่วไหลของผู้เล่นคำนวณเวลาที่ใช้ในการทำความสะอาดและระยะเวลาที่ต้องใช้เส้นทางเป็นต้นและจนกว่าจะมีการพูดถึง เวลาเนื่องจากการเข้าห้องถัดไปเราจะตรวจสอบว่าผู้เล่นอยู่ในห้องหรือไม่เท่านั้น ตำแหน่งที่แน่นอนของ NPC สำหรับจุดประสงค์ในการเรนเดอร์จะคำนวณเฉพาะเมื่อผู้เล่นเข้าสู่ห้อง หลังจากระดมสมองซักพักฉันมาถึงตัวเลือกที่สาม แต่ฉันสงสัยว่าบางทีอาจมีวิธีที่รู้จักหรือดีกว่าในการจัดการสิ่งต่าง ๆ เหล่านี้

3
มีเอกสารใดบ้างที่เปรียบเทียบ / เปรียบเทียบการปรับใช้มาตรฐานไลบรารี C ++ [ปิด]
ปิด. คำถามนี้เป็นคำถามปิดหัวข้อ ไม่ยอมรับคำตอบในขณะนี้ ต้องการปรับปรุงคำถามนี้หรือไม่ อัปเดตคำถามเพื่อให้เป็นไปตามหัวข้อสำหรับ Game Exchange Stack Exchange ปิดให้บริการใน4 ปีที่แล้ว (นี่ไม่ใช่การเขียนโปรแกรมเกมต่อ แต่ฉันแน่ใจว่าฉันถามเรื่องนี้ดังนั้นฉันจะได้รับการบอกว่าจะไม่ปรับให้เหมาะสมก่อนที่จะถึงแม้ว่าประวัติศาสตร์บอกเราทุกเกมใหญ่จบลงด้วยความกังวลเกี่ยวกับสิ่งเหล่านี้.) มีเอกสารใดบ้างที่สรุปความแตกต่างของประสิทธิภาพและโดยเฉพาะอย่างยิ่งการใช้หน่วยความจำระหว่างการใช้งานไลบรารีมาตรฐาน C ++ แตกต่างกันหรือไม่? รายละเอียดของการใช้งานบางอย่างได้รับการคุ้มครองโดย NDA แต่การเปรียบเทียบระหว่าง STLport กับ libstdc ++ เทียบกับ libc ++ กับ MSVC / Dinkumware (เทียบกับ EASTL?) ดูเหมือนว่าจะมีประโยชน์อย่างมาก โดยเฉพาะฉันกำลังมองหาคำตอบสำหรับคำถามที่ชอบ: หน่วยความจำค่าใช้จ่ายเกี่ยวข้องกับคอนเทนเนอร์มาตรฐานเท่าไร? คอนเทนเนอร์ใดมีถ้าทำการจัดสรรแบบไดนามิกโดยการประกาศเท่านั้น std :: string ทำการคัดลอกเมื่อเขียนหรือไม่? การเพิ่มประสิทธิภาพสตริงสั้น ๆ ? เชือก? std :: deque ใช้บัฟเฟอร์วงแหวนหรือไม่?

1
วิธีการได้รับประโยชน์จาก cpu แคชในเอ็นจิ้นเกมเอนทิตีคอมโพเนนต์ระบบ?
ฉันมักจะอ่านในเอกสารประกอบเครื่องมือเกมของ ECS ซึ่งเป็นสถาปัตยกรรมที่ดีสำหรับการใช้แคช cpu อย่างชาญฉลาด แต่ฉันไม่สามารถคิดได้ว่าเราจะได้ประโยชน์จาก cpu cache ได้อย่างไร หากส่วนประกอบถูกบันทึกในอาร์เรย์ (หรือพูล) ในหน่วยความจำต่อเนื่องเป็นวิธีที่ดีในการใช้ cpu cache แต่ถ้าเราอ่านส่วนประกอบตามลำดับ เมื่อเราใช้ระบบพวกเขาต้องการรายการเอนทิตีซึ่งเป็นรายการเอนทิตีที่มีส่วนประกอบที่มีประเภทเฉพาะ แต่รายการเหล่านี้ให้ส่วนประกอบในวิธีการสุ่มไม่ใช่ตามลำดับ ดังนั้นวิธีการออกแบบ ECS เพื่อเพิ่มการเข้าชมแคชสูงสุด? แก้ไข: ตัวอย่างเช่นระบบ Physic ต้องการรายการเอนทิตีสำหรับเอนทิตีที่มีส่วนประกอบ RigidBody และ Transform (มีพูลสำหรับ RigidBody และพูลสำหรับคอมโพเนนต์การแปลง) ดังนั้นลูปสำหรับการอัพเดตเอนทิตีจะเป็นดังนี้: for (Entity eid in entitiesList) { // Get rigid body component RigidBody *rigidBody = entityManager.getComponentFromEntity<RigidBody>(eid); // Get transform component …

1
ความแตกต่างใน glDrawArrays และ glDrawElements
ในขณะที่สดชื่นใจของฉันกับ OpenGL ES ฉันมาข้ามและglDrawArraysglDrawElements ฉันเข้าใจว่ามีการใช้งานอย่างไรและเข้าใจว่าทำไมจึงแตกต่างกัน สิ่งที่ฉันดูเหมือนจะไม่เข้าใจก็คือฉันไม่สามารถดูวิธีการglDrawElementsบันทึกการโทรแบบดึง ( การบันทึกการโทรแบบดึงเป็นคำอธิบายที่กล่าวถึงในหนังสือส่วนใหญ่ที่ฉันได้อ่าน ลองนึกภาพสถานการณ์ง่าย ๆ ที่ฉันพยายามวาดรูปสี่เหลี่ยมโดยใช้รูปสามเหลี่ยม 2 รูป ฉันจะต้องมีชุดของ 6 จุดยอดใช้glDrawArraysในขณะที่ใช้glDrawElementsฉันต้องการเพียง 4 นอกเหนือจากอาร์เรย์ดัชนีที่มี 6 องค์ประกอบ รับข้างต้นนี่คือสิ่งที่ฉันไม่เข้าใจ: จะglDrawElementsบันทึกการเรียกสายได้อย่างไรถ้ายังต้องการใช้อาร์เรย์ดัชนี (ดัชนี 6 ตัวในกรณีสี่เหลี่ยม) เพื่อจัดทำดัชนีลงในอาร์เรย์จุดสุดยอดของฉันที่มี 4 องค์ประกอบ (6 ครั้ง) พูดอีกอย่างว่าหมายความว่าglDrawElementsยังคงต้องมีการดึงสายเรียกเข้าทั้งหมด 6 ครั้งglDrawArraysใช่ไหม จะใช้glDrawElementsพื้นที่ประหยัดได้อย่างไรถ้าใครยังคงต้องมี 2 อาร์เรย์คือหนึ่งสำหรับจุดยอดและอีกหนึ่งสำหรับดัชนี? ในกรณีของการวาดรูปสี่เหลี่ยมจัตุรัสจากรูปสามเหลี่ยม 2 รูปแบบเพื่อความง่ายจำนวนการเรียกแบบดึงglDrawElements(จำนวน 4 รายการในอาร์เรย์จุดยอดและ 6 รายการในแถวลำดับดัชนี) และglDrawArrays(6 รายการเฉพาะในจุดสุดยอดอาร์เรย์) ต้องแยกกันหรือไม่? ขอบคุณ

6
Game Objects ที่อยู่นอกมุมมองกล้องใช้ทรัพยากรคอมพิวเตอร์ / มือถือใน Unity หรือไม่?
ในความเป็นเอกภาพขอให้เราสมมติว่าฉันมี Game Objects บางอย่างในฉากของฉันที่มองไม่เห็นด้วยกล้องและไม่แสดงผลในขณะที่เกมกำลังทำงาน Game Objects เหล่านี้จะใช้ทรัพยากรคอมพิวเตอร์ / มือถือหรือไม่เมื่อเกมทำงาน? ฉันจะหารายละเอียดเกี่ยวกับการใช้งานแบบนี้ได้ที่ไหน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.