Megapack: Cách Factorio giải quyết vấn đề nhiều người chơi 200 người chơi

Megapack: Cách Factorio giải quyết vấn đề nhiều người chơi 200 người chơi
Vào tháng XNUMX năm nay, tôi đã tham gia với tư cách là một cầu thủ trong Sự kiện MMO KatherineOfSky. Tôi nhận thấy rằng khi số lượng người chơi đạt đến một con số nhất định, cứ sau vài phút, một số người trong số họ lại "ngã ngựa". May mắn cho bạn (nhưng không phải cho tôi), tôi là một trong những người chơi đó mỗi lầnngay cả với một kết nối tốt. Tôi coi đó như một thử thách cá nhân và bắt đầu tìm kiếm nguyên nhân của vấn đề. Sau ba tuần gỡ lỗi, thử nghiệm và sửa chữa, lỗi cuối cùng đã được sửa, nhưng hành trình không hề dễ dàng.

Các vấn đề trong trò chơi nhiều người chơi rất khó theo dõi. Chúng thường xảy ra trong các thông số mạng rất cụ thể và trong các trạng thái trò chơi rất cụ thể (trong trường hợp này là hơn 200 người chơi). Và ngay cả khi một sự cố có thể được tái tạo, nó cũng không thể được gỡ lỗi đúng cách vì việc chèn các điểm ngắt sẽ dừng trò chơi, làm hỏng bộ hẹn giờ và thường khiến kết nối hết thời gian do hết thời gian chờ. Nhưng nhờ sự kiên trì và một công cụ tuyệt vời được gọi là vụng về Tôi đã có thể tìm ra những gì đang xảy ra.

Nói tóm lại, do lỗi và việc triển khai mô phỏng trạng thái trễ không đầy đủ, khách hàng đôi khi rơi vào tình huống phải gửi gói mạng trong một chu kỳ đồng hồ, bao gồm các hành động do người chơi nhập để chọn khoảng 400 thực thể trò chơi ( chúng tôi gọi nó là "megapacket"). Sau đó, máy chủ không chỉ cần nhận chính xác tất cả các hành động đầu vào này mà còn gửi chúng cho tất cả các máy khách khác. Nếu bạn có 200 khách hàng, điều này nhanh chóng trở thành một vấn đề. Liên kết đến máy chủ nhanh chóng bị tắc nghẽn, dẫn đến các gói bị mất và một loạt các gói được yêu cầu lại. Việc trì hoãn các hành động đầu vào sau đó sẽ khiến nhiều khách hàng bắt đầu gửi các megapacket và trận tuyết lở của họ thậm chí còn mạnh hơn. Những khách hàng thành công quản lý để phục hồi, tất cả những người còn lại đều thất bại.

Megapack: Cách Factorio giải quyết vấn đề nhiều người chơi 200 người chơi
Vấn đề khá cơ bản và tôi phải mất 2 tuần để khắc phục. Nó khá kỹ thuật, vì vậy tôi sẽ giải thích các chi tiết kỹ thuật thú vị bên dưới. Nhưng trước tiên, bạn cần biết rằng kể từ phiên bản 0.17.54, được phát hành vào ngày 4 tháng XNUMX, trước sự cố kết nối tạm thời, chế độ nhiều người chơi đã trở nên ổn định hơn và việc ẩn trễ ít lỗi hơn (ít phanh và dịch chuyển tức thời hơn). Ngoài ra, tôi đã thay đổi cách ẩn độ trễ trong chiến đấu và hy vọng điều này sẽ giúp chúng mượt mà hơn một chút.

Gói nhiều người chơi - Chi tiết kỹ thuật

Nói một cách đơn giản, nhiều người chơi trong một trò chơi hoạt động như sau: tất cả các máy khách mô phỏng trạng thái của trò chơi bằng cách chỉ nhận và gửi đầu vào của người chơi (được gọi là "hành động đầu vào" Thao tác nhập liệu). Nhiệm vụ chính của máy chủ là chuyển Thao tác nhập liệu và đảm bảo rằng tất cả khách hàng thực hiện các hành động giống nhau trong cùng một chu kỳ. Bạn có thể đọc thêm về điều này trong bài viết. FFF-149.

Vì máy chủ phải đưa ra quyết định về những hành động cần thực hiện, hành động của người chơi sẽ di chuyển theo con đường sau: hành động của người chơi -> ứng dụng khách trò chơi -> mạng -> máy chủ -> mạng -> ứng dụng khách trò chơi. Điều này có nghĩa là mỗi hành động của người chơi chỉ được thực hiện sau khi nó đã thực hiện một hành trình khứ hồi qua mạng. Do đó, trò chơi sẽ có vẻ chậm kinh khủng, vì vậy gần như ngay lập tức sau khi xuất hiện nhiều người chơi trong trò chơi, một cơ chế che giấu sự chậm trễ đã được giới thiệu. Ẩn độ trễ mô phỏng đầu vào của người chơi mà không xem xét hành động của những người chơi khác và việc ra quyết định của máy chủ.

Megapack: Cách Factorio giải quyết vấn đề nhiều người chơi 200 người chơi
Factorio có trạng thái trò chơi trạng thái trò chơi là trạng thái hoàn chỉnh của bản đồ, người chơi, thực thể và mọi thứ khác. Nó được mô phỏng một cách xác định trong tất cả các máy khách dựa trên các hành động nhận được từ máy chủ. Trạng thái trò chơi là thiêng liêng và nếu nó bắt đầu khác với máy chủ hoặc bất kỳ ứng dụng khách nào khác, thì quá trình giải đồng bộ hóa sẽ xảy ra.

Nhưng trạng thái trò chơi chúng tôi có một tình trạng chậm trễ Trạng thái trễ. Nó chứa một tập con nhỏ của trạng thái chính. Trạng thái trễ không thiêng liêng và chỉ đại diện cho một bức tranh về trạng thái của trò chơi sẽ như thế nào trong tương lai dựa trên thông tin đầu vào từ người chơi Thao tác nhập liệu.

Để làm điều này, chúng tôi giữ một bản sao của Thao tác nhập liệu trong hàng đợi trễ.

Megapack: Cách Factorio giải quyết vấn đề nhiều người chơi 200 người chơi
Đó là, khi kết thúc quy trình ở phía máy khách, hình ảnh trông giống như thế này:

  1. Ứng dụng Thao tác nhập liệu tất cả người chơi trạng thái trò chơi cách các hành động đầu vào này được nhận từ máy chủ.
  2. Xóa mọi thứ khỏi hàng đợi trễ Thao tác nhập liệu, theo máy chủ, đã được áp dụng cho trạng thái trò chơi.
  3. Xóa bỏ Trạng thái trễ và thiết lập lại nó để nó trông giống hệt như trạng thái trò chơi.
  4. Áp dụng tất cả các hành động từ hàng đợi trì hoãn để Trạng thái trễ.
  5. Dựa trên dữ liệu trạng thái trò chơi и Trạng thái trễ kết xuất trò chơi cho người chơi.

Tất cả điều này được lặp đi lặp lại trong mọi biện pháp.

Quá khó? Đừng thư giãn, đó không phải là tất cả. Để bù đắp cho các kết nối Internet không đáng tin cậy, chúng tôi đã tạo hai cơ chế:

  • Bỏ qua tick: khi máy chủ quyết định rằng Thao tác nhập liệu sẽ được thực hiện trong chiến thuật của trò chơi, sau đó nếu anh ta chưa nhận được Thao tác nhập liệu một số người chơi (ví dụ: do độ trễ tăng lên), anh ta sẽ không đợi mà sẽ thông báo cho khách hàng này “Tôi không tính đến việc bạn Thao tác nhập liệu, Tôi sẽ cố gắng thêm chúng vào thanh tiếp theo. Điều này được thực hiện để do sự cố kết nối (hoặc với máy tính) của một người chơi, quá trình cập nhật bản đồ không bị chậm đối với những người khác. Điều đáng chú ý là Thao tác nhập liệu không bị bỏ qua, mà chỉ đơn giản là hoãn lại.
  • Độ trễ khứ hồi đầy đủ: Máy chủ cố gắng đoán độ trễ khứ hồi giữa máy khách và máy chủ là bao nhiêu đối với từng máy khách. Cứ sau 5 giây, nó thương lượng độ trễ mới với máy khách nếu cần (tùy thuộc vào cách hoạt động của kết nối trong quá khứ) và tăng hoặc giảm độ trễ khứ hồi tương ứng.

Bản thân các cơ chế này khá đơn giản, nhưng khi chúng được sử dụng cùng nhau (điều này thường xảy ra với các sự cố kết nối), logic mã trở nên khó quản lý và có nhiều trường hợp cạnh. Ngoài ra, khi các cơ chế này bắt đầu hoạt động, máy chủ và hàng đợi trễ phải triển khai chính xác một chức năng đặc biệt. Hành động đầu vào được gọi là Dừng lạiMovementInTheNextTick. Nhờ vậy, trong trường hợp có sự cố kết nối, nhân vật sẽ không tự chạy (ví dụ: dưới gầm tàu ​​hỏa).

Bây giờ tôi cần giải thích cho bạn cách hoạt động của lựa chọn thực thể. Một trong những loại đã qua Hành động đầu vào là một sự thay đổi trong trạng thái lựa chọn của một thực thể. Nó cho mọi người biết thực thể mà người chơi di chuột qua. Như bạn có thể thấy, đây là một trong những tác vụ nhập liệu thường xuyên nhất do khách hàng gửi, vì vậy, để tiết kiệm băng thông, chúng tôi đã tối ưu hóa hành động này để chiếm ít dung lượng nhất có thể. Điều này được triển khai như sau: khi mỗi thực thể được chọn, thay vì lưu trữ tọa độ bản đồ tuyệt đối, có độ chính xác cao, trò chơi sẽ lưu trữ phần bù tương đối có độ chính xác thấp từ lựa chọn trước đó. Điều này hoạt động tốt vì lựa chọn chuột thường xảy ra rất gần với lựa chọn trước đó. Điều này dẫn đến hai yêu cầu quan trọng: Thao tác nhập liệu không bao giờ được bỏ qua và phải được thực hiện theo đúng thứ tự. Những yêu cầu này được đáp ứng cho trạng thái trò chơi. Nhưng vì nhiệm vụ Trạng thái trễ trong việc "trông đủ tốt" cho người chơi, họ không hài lòng ở trạng thái trì hoãn. Trạng thái trễ không tính đến nhiều trường hợp ranh giớiliên quan đến việc bỏ qua đồng hồ và thay đổi độ trễ truyền khứ hồi.

Bạn đã có thể đoán nơi này sẽ đi. Cuối cùng, chúng ta bắt đầu thấy nguyên nhân của vấn đề siêu gói. Gốc rễ của vấn đề là logic lựa chọn thực thể dựa trên Trạng thái trễvà trạng thái này không phải lúc nào cũng chứa thông tin chính xác. Vì vậy, megapacket được tạo ra như thế này:

  1. Người chơi đang gặp sự cố kết nối.
  2. Các cơ chế để bỏ qua các chu kỳ và điều chỉnh độ trễ truyền khứ hồi phát huy tác dụng.
  3. Hàng đợi trạng thái trễ không tính đến các cơ chế này. Điều này khiến một số hành động bị loại bỏ sớm hoặc chạy sai thứ tự, dẫn đến kết quả không chính xác. Trạng thái trễ.
  4. Người chơi không gặp sự cố kết nối và mô phỏng tới 400 chu kỳ để bắt kịp máy chủ.
  5. Trong mỗi chu kỳ, một hành động mới được tạo và chuẩn bị gửi đến máy chủ, làm thay đổi lựa chọn thực thể.
  6. Máy khách gửi một megapacket gồm hơn 400 thay đổi lựa chọn thực thể tới máy chủ (và với các hành động khác: trạng thái kích hoạt, trạng thái đi bộ, v.v. cũng gặp sự cố này).
  7. Máy chủ nhận được 400 hành động đầu vào. Vì nó không được phép bỏ qua một hành động đầu vào nào, nên nó hướng dẫn tất cả các máy khách thực hiện các hành động này và gửi chúng qua mạng.

Điều trớ trêu là cơ chế được thiết kế để tiết kiệm băng thông dẫn đến các gói mạng khổng lồ.

Chúng tôi đã giải quyết vấn đề này bằng cách khắc phục tất cả các trường hợp cập nhật và trì hoãn hỗ trợ hàng đợi. Mặc dù mất khá nhiều thời gian, nhưng cuối cùng cũng đáng để hoàn thành tốt hơn là dựa vào các bản hack nhanh chóng.

Nguồn: www.habr.com

Thêm một lời nhận xét