paint-brush
Hệ thống khả năng phức tạp hơn nhưng quy trình làm việc của Gamedev mượt mà hơn – Bằng cách nào?từ tác giả@pastaman
1,150 lượt đọc
1,150 lượt đọc

Hệ thống khả năng phức tạp hơn nhưng quy trình làm việc của Gamedev mượt mà hơn – Bằng cách nào?

từ tác giả Vladimir Popov9m2024/02/08
Read on Terminal Reader

dài quá đọc không nổi

Hệ thống khả năng của War Robots đã trải qua một quá trình phát triển đáng kể, chuyển từ cấu trúc đơn giản sang mô hình phức tạp. Hệ thống mới trao quyền cho các nhà thiết kế trò chơi và giảm sự phụ thuộc vào các lập trình viên, dẫn đến khả năng cơ khí đa dạng hơn và trải nghiệm người chơi phong phú hơn.
featured image - Hệ thống khả năng phức tạp hơn nhưng quy trình làm việc của Gamedev mượt mà hơn – Bằng cách nào?
Vladimir Popov HackerNoon profile picture


Xin chào! Tôi là Vladimir Popov, Nhà phát triển khách hàng của Dự án Robot chiến tranh. Tại thời điểm viết bài, War Robots đã xuất hiện được vài năm và hàng chục mech mới đã xuất hiện trong trò chơi trong thời gian này. Đương nhiên, khả năng đa dạng của robot rất quan trọng, bởi vì nếu không có chúng, robot sẽ mất đi tính độc đáo, điều này khiến trò chơi trở nên thú vị hơn.


Trong bài đăng này, tôi sẽ chia sẻ cách hoạt động của hệ thống khả năng chơi trò chơi trong trò chơi của chúng tôi – và nó đã phát triển như thế nào. Và để làm cho mọi thứ dễ tiếp cận hơn, tôi sẽ giải thích mọi thứ bằng những thuật ngữ đơn giản và không có quá nhiều chi tiết kỹ thuật.


Các khả năng đã từng được thực hiện như thế nào

Trước tiên, hãy đi sâu vào lịch sử dự án và xem xét cách triển khai cũ hơn không còn được sử dụng nữa.


Trước đây, các khả năng được thiết kế theo cách rất tầm thường: chúng có một bộ phận được gắn vào robot. Đây là một cấu trúc trong đó người lập trình viên mô tả đầy đủ cách thức hoạt động của khả năng này: cả dòng chảy của nó và cách nó tương tác với các khả năng khác. Tất cả logic được mô tả bên trong một thành phần và nhà thiết kế trò chơi có thể chỉ cần gắn logic này vào robot và định cấu hình các tham số nếu cần. Điều đáng nói là không thể thay đổi dòng khả năng – nhà thiết kế trò chơi chỉ có thể thay đổi các thông số và thời gian.


Một khả năng cũ chỉ có thể tồn tại ở hai trạng thái: hoạt động và không hoạt động, và mỗi trạng thái có thể được chỉ định hành động cho nó.




Hãy xem một ví dụ về khả năng “Jammer” mà robot “Stalker” sở hữu trước đây; nó hoạt động như thế này:


  1. Nếu khả năng đang hoạt động, một hình ảnh động sẽ được hiển thị và robot sẽ chuyển sang trạng thái gây nhiễu; ở trạng thái này, những người khác không thể nhắm vào robot đang kích hoạt khả năng.
  2. Nếu khả năng không hoạt động, không có gì xảy ra.
  3. Khi cố gắng kích hoạt một khả năng, chúng tôi đã kiểm tra xem liệu đã hơn n giây trôi qua kể từ lần kích hoạt cuối cùng hay chưa.
  4. Việc hủy kích hoạt tự động xảy ra sau m giây.


Trong một thời gian dài, chức năng này là đủ đối với chúng tôi, nhưng theo thời gian, cả nhà thiết kế trò chơi và lập trình viên không còn hài lòng với cách tiếp cận này nữa: các lập trình viên khó hỗ trợ những khả năng này vì mã đã trở nên quái dị; điều này liên quan đến một chuỗi kế thừa rất dài, trong đó mọi tình huống đều phải được mô tả. Ngoài ra, các nhà thiết kế trò chơi thiếu tính linh hoạt - để thực hiện bất kỳ thay đổi nào đối với một khả năng, họ phải yêu cầu các nhà lập trình sửa đổi, ngay cả khi một khả năng liền kề có cùng chức năng.


Nhập hệ thống khả năng mới

Vì vậy, chúng tôi nhận ra rằng cần phải thay đổi điều gì đó. Do đó, chúng tôi đã phát triển một hệ thống mới, trong đó mỗi khả năng được thể hiện dưới dạng một tập hợp nhiều đối tượng liên quan. Chức năng được chia thành các khả năng trạng thái và các thành phần trạng thái.


Làm thế nào nó hoạt động? Mọi khả năng đều có một đối tượng chính. Đối tượng trung tâm này kết nối các đối tượng khả năng khác với thế giới bên ngoài và ngược lại; nó cũng đưa ra tất cả các quyết định chính.


Có thể có bất kỳ số lượng trạng thái. Về cơ bản, trạng thái trong lần lặp này không khác nhiều so với trạng thái hoạt động/không hoạt động trong phiên bản cũ, nhưng giờ đây có thể có bất kỳ số lượng trạng thái nào và mục đích của chúng đã trở nên trừu tượng hơn. Chúng tôi sẽ lưu ý rằng một khả năng chỉ có thể có một trạng thái hoạt động tại một thời điểm.


Sự đổi mới chính so với hệ thống cũ là các thành phần: một thành phần mô tả một số hành động và mỗi trạng thái có thể có số lượng thành phần bất kỳ.


Các khả năng mới hoạt động như thế nào? Một khả năng chỉ có thể ở một trong các trạng thái; đối tượng chính chịu trách nhiệm chuyển đổi chúng. Các thành phần liên kết với một trạng thái phản ứng với việc kích hoạt/hủy kích hoạt trạng thái đó và tùy thuộc vào điều này, có thể bắt đầu thực hiện một số hành động hoặc ngừng thực hiện hành động đó.


Tất cả các đối tượng đều có thể tùy chỉnh được; nhà thiết kế trò chơi có thể kết hợp các trạng thái và thành phần theo ý muốn, từ đó tạo ra một khả năng mới từ các khối được cài đặt sẵn. Giờ đây, các lập trình viên chỉ cần nhập vào hình ảnh để tạo thành phần hoặc trạng thái mới, điều này giúp việc viết mã dễ dàng hơn nhiều: họ làm việc với các thực thể nhỏ, mô tả một số thành phần đơn giản và không còn tự xây dựng khả năng nữa – các nhà thiết kế trò chơi hiện đang làm việc này.


Dòng chảy đã trở thành như thế này:

  1. Đối tượng chính kích hoạt trạng thái đầu tiên
  2. Trạng thái kích hoạt tất cả các thành phần của nó
  3. Trạng thái xác định thời điểm khả năng được chuyển sang trạng thái khác
  4. Đối tượng chính hủy kích hoạt trạng thái trước đó
  5. Trạng thái trước đó vô hiệu hóa các thành phần của nó
  6. Đối tượng chính kích hoạt một trạng thái mới
  7. Trạng thái mới kích hoạt các thành phần của nó


Sau đó, thủ tục này được lặp đi lặp lại. Để dễ sử dụng, một trạng thái không chỉ đóng vai trò là nơi chứa thành phần mà còn xác định thời điểm chuyển sang trạng thái khác và yêu cầu đối tượng chính thực hiện chuyển đổi. Theo thời gian, điều này hóa ra vẫn chưa đủ đối với chúng tôi và sơ đồ khả năng đã được chuyển thành như sau:




Đối tượng, trạng thái và thành phần chính vẫn giữ nguyên vị trí của chúng nhưng các phần tử mới cũng được thêm vào.


Điều đầu tiên khiến bạn chú ý là chúng tôi đã thêm các điều kiện vào từng trạng thái và thành phần: đối với các trạng thái, những điều kiện này xác định các yêu cầu bổ sung để rời khỏi trạng thái; đối với các thành phần, chúng xác định liệu thành phần đó có thể thực hiện hành động của nó hay không.


Hộp chứa điện tích chứa các điện tích, sạc lại chúng, ngừng sạc lại nếu cần thiết và cung cấp điện tích cho các trạng thái sử dụng.


Bộ đếm thời gian được sử dụng khi một số trạng thái phải có thời gian thực hiện chung nhưng thời gian thực hiện của chính chúng không được xác định.


Điều quan trọng cần lưu ý là tất cả các đối tượng khả năng đều là tùy chọn. Về mặt kỹ thuật, để có khả năng hoạt động, chỉ cần một đối tượng chính và một trạng thái.


Giờ đây, mặc dù thực tế không có nhiều khả năng được xây dựng hoàn chỉnh mà không có sự tham gia của các lập trình viên, nhưng việc phát triển nói chung đã trở nên rẻ hơn đáng kể, bởi vì các lập trình viên giờ đây chỉ cần viết những thứ rất nhỏ: ví dụ: một trạng thái mới hoặc hai thành phần – phần còn lại được tái sử dụng.


Hãy tóm tắt các thành phần khả năng của chúng tôi:


  • Đối tượng chính thực hiện các chức năng của một máy trạng thái. Nó cung cấp cho các trạng thái và thành phần thông tin về thế giới và cung cấp cho thế giới thông tin về các khả năng. Đối tượng chính đóng vai trò là mối liên kết giữa các trạng thái, thành phần và các bộ phận dịch vụ của khả năng: phí và bộ hẹn giờ bên ngoài.


  • Trạng thái lắng nghe các lệnh kích hoạt và hủy kích hoạt từ đối tượng chính và theo đó, kích hoạt và hủy kích hoạt các thành phần, đồng thời yêu cầu đối tượng chính chuyển sang trạng thái khác. Trạng thái xác định khi nào cần chuyển sang trạng thái tiếp theo; để làm điều này, nó sử dụng điều kiện bên trong của nó: liệu người chơi có nhấp vào nút khả năng hay không, liệu một thời gian nhất định đã trôi qua kể từ khi kích hoạt trạng thái hay chưa, v.v. và các điều kiện bên ngoài được liên kết với trạng thái.


  • Thành phần này lắng nghe các lệnh kích hoạt và hủy kích hoạt từ trạng thái và thực hiện một số hành động: rời rạc hoặc dài hạn. Các hành động có thể hoàn toàn khác: chúng có thể gây sát thương, chữa lành vết thương cho đồng minh, bật hoạt ảnh, v.v.


  • Điều kiện kiểm tra trạng thái của phần tử mong muốn và báo cáo điều này cho trạng thái hoặc thành phần. Điều kiện có thể phức tạp. Một trạng thái không yêu cầu chuyển sang trạng thái khác nếu điều kiện không được đáp ứng. Thành phần này cũng không thực hiện hành động nếu điều kiện không được đáp ứng. Điều kiện là một thực thể tùy chọn; không phải mọi khả năng đều có chúng.


  • Hộp chứa điện tích chứa điện tích, sạc lại, ngừng sạc khi cần thiết và cung cấp điện tích cho các tiểu bang. Nó được sử dụng trong khả năng đa năng, khi bạn cần cho phép người chơi sử dụng nó nhiều lần, nhưng không quá n lần liên tiếp.


  • Bộ đếm thời gian được sử dụng khi một số trạng thái có khoảng thời gian chung nhưng không biết mỗi trạng thái đó sẽ kéo dài bao lâu. Bất kỳ trạng thái nào cũng có thể bắt đầu hẹn giờ trong n giây. Tất cả các trạng thái liên quan đều đăng ký sự kiện kết thúc bộ hẹn giờ và thực hiện điều gì đó khi nó kết thúc.


Bây giờ hãy quay lại sơ đồ khả năng. Chức năng của nó đã thay đổi như thế nào?


  1. Khi bắt đầu trò chơi, đối tượng chính chọn trạng thái đầu tiên và kích hoạt nó
  2. Trạng thái kích hoạt tất cả các thành phần của nó
  3. Thành phần này kiểm tra xem điều kiện đã được đáp ứng chưa và chỉ sau đó mới thực hiện một hành động
  4. Trạng thái bắt đầu kiểm tra điều kiện chuyển sang trạng thái khác
  5. Nếu điều kiện được đáp ứng và điều kiện bổ sung liên kết với nó được thỏa mãn, trạng thái sẽ yêu cầu đối tượng chính chuyển sang trạng thái khác
  6. Đối tượng chính vô hiệu hóa trạng thái này và kích hoạt trạng thái khác
  7. Toàn bộ quy trình được lặp lại


Các quốc gia có thể sử dụng phí như một điều kiện chuyển tiếp bổ sung. Nếu quá trình chuyển đổi như vậy xảy ra, số lượng điện tích sẽ giảm. Các quốc gia cũng có thể sử dụng bộ đếm thời gian chung. Trong trường hợp này, tổng thời gian thực hiện chúng sẽ được xác định bằng bộ đếm thời gian và mỗi trạng thái riêng lẻ có thể kéo dài bất kỳ lúc nào.


UI khả năng

Chúng tôi đã không phát minh lại hoàn toàn bánh xe cho các giao diện người dùng khả năng mới.


Đối tượng chính có giao diện người dùng riêng. Nó xác định một số thành phần phải luôn có trong giao diện người dùng và không phụ thuộc vào trạng thái hiện đang hoạt động.


Mỗi trạng thái có cặp riêng trong giao diện người dùng và giao diện người dùng trạng thái chỉ được hiển thị khi trạng thái của nó hoạt động. Nó nhận dữ liệu về trạng thái của nó và có thể hiển thị nó theo cách này hay cách khác. Ví dụ: trạng thái thời lượng thường có thanh và văn bản trong giao diện người dùng hiển thị thời gian còn lại.


Trong trường hợp trạng thái đang chờ lệnh bên ngoài để tiếp tục một khả năng, giao diện người dùng của nó sẽ hiển thị một nút và việc nhấn nút đó sẽ gửi lệnh đến trạng thái.





Ví dụ về khả năng

Chúng ta sẽ xem xét cách các khả năng hoạt động bằng các ví dụ cụ thể; đầu tiên, chúng ta hãy nhìn vào một robot có tên là “Người điều tra”. Chúng tôi có bốn trạng thái nối tiếp nhau – phía trên các trạng thái bạn có thể thấy hiển thị của chúng trong giao diện người dùng. Đối với hai trong số chúng, chúng ta cũng thấy các thành phần thuộc về chúng; hai trạng thái còn lại đơn giản là không có thành phần.


Đây là dòng chảy của khả năng:

  1. Tất cả bắt đầu với trạng thái “WaitForClick”. Tại thời điểm này, khả năng này không làm gì cả; nó chỉ chờ lệnh.


  2. Ngay khi nhận được lệnh như vậy, đối tượng chính sẽ chuyển trạng thái. Trạng thái hoạt động tiếp theo là “WaitForGrounded”.


  3. Trạng thái này có một số thành phần và do đó, khi được kích hoạt, robot sẽ nhảy và phát âm thanh cũng như hoạt ảnh. Trong số những thứ khác, khi trạng thái hoạt động, robot bị ảnh hưởng bởi hiệu ứng Jammer, hiệu ứng này cấm nhắm vào robot.


  4. Khi robot hạ cánh, khả năng của nó sẽ chuyển sang trạng thái tiếp theo.


  5. Trạng thái này có ba thành phần: Âm thanh và Jammer vốn đã quen thuộc, cũng như Shake, khiến máy ảnh rung lên đối với tất cả người chơi trong bán kính n .


  6. Vì trạng thái này có Duration nên nó hoạt động trong n giây, sau đó kỹ năng sẽ chuyển sang trạng thái tiếp theo.


  7. Trạng thái cuối cùng cũng đi kèm với Thời lượng, nhưng nó không có bất kỳ thành phần nào: nó đang trong thời gian hồi chiêu thông thường.


  8. Sau khi hoàn thành, khả năng sẽ trở lại trạng thái đầu tiên.





Một ví dụ khác là “Phantom”. Nó rất giống Người điều tra, nhưng có một số sắc thái:


  1. Chúng tôi bắt đầu với WaitForClick.


  2. Sau đó, Thời lượng, trong đó dịch chuyển được cài đặt, các chỉ số của máy được thay đổi, đồng thời âm thanh và hoạt ảnh được phát.


  3. Sau đó: DurationOrClick, trong đó các chỉ số của máy được thay đổi, hoạt ảnh và FX được phát.


  4. Nếu một cú nhấp chuột được thực hiện, chúng ta sẽ chuyển sang một Khoảng thời gian khác, trong đó mech dịch chuyển tức thời, thay đổi chỉ số và hoạt ảnh, FX và âm thanh được phát.


  5. Sau trạng thái này (hoặc sau khi hết thời gian cho DurationOrClick), chúng ta chuyển sang Duration.


Sự khác biệt chính ở đây là chúng ta thấy các trạng thái có phân nhánh: DurationOrClick chuyển sang trạng thái A nếu thời gian được chỉ định đã trôi qua hoặc chuyển sang trạng thái B nếu trước đó người chơi đã nhấn nút khả năng.



Kết luận

Mặc dù có vẻ như hệ thống của chúng tôi đã phát triển từ một thứ đơn giản thành một thứ khá phức tạp, nhưng sự thay đổi này đã đơn giản hóa cuộc sống của cả lập trình viên và nhà thiết kế trò chơi. Hiện nay chủ yếu cần sự hỗ trợ từ các lập trình viên khi thêm các thành phần nhỏ, trong khi nhóm thành viên sau trong nhóm đã có được quyền tự chủ cao hơn và giờ đây có thể lắp ráp một cách độc lập các khả năng mới từ các trạng thái và thành phần hiện có. Là một phần thưởng khác, đồng thời, người chơi cũng nhận được lợi nhuận dưới dạng khả năng đa dạng và phức tạp hơn của các mech.