Mã hóa dựa trên dữ liệu
Mỗi điều bạn đề cập là một cái gì đó có thể được chỉ định trong dữ liệu. Tại sao bạn đang tải aspecificmap
? Bởi vì cấu hình trò chơi nói rằng đó là cấp độ đầu tiên khi người chơi bắt đầu một trò chơi mới hoặc vì đó là tên của điểm lưu hiện tại trong tệp lưu của người chơi mà họ vừa tải, v.v.
Làm thế nào để bạn tìm thấy aspecificmap
? Bởi vì nó nằm trong tệp dữ liệu liệt kê id bản đồ và tài nguyên trên đĩa của chúng.
Chỉ cần có một bộ tài nguyên "cốt lõi" đặc biệt nhỏ, khó hợp pháp hoặc không thể tránh được mã hóa cứng. Với một chút công việc, điều này có thể được giới hạn trong một tên tài sản mặc định được mã hóa cứng giống như main.wad
hoặc tương tự. Tập tin này có khả năng có thể được thay đổi trong thời gian chạy bằng cách chuyển một đối số dòng lệnh cho trò chơi, hay còn gọi là game.exe -wad mymain.wad
.
Viết mã dựa trên dữ liệu dựa trên một vài nguyên tắc khác. Ví dụ, người ta có thể tránh việc các hệ thống hoặc mô-đun yêu cầu một tài nguyên cụ thể và thay vào đó đảo ngược các phụ thuộc đó. Đó là, không thực hiện DebugDrawer
tải lên debug.font
trong mã khởi tạo của nó; thay vào đó, đã DebugDrawer
xử lý tài nguyên trong mã khởi tạo của nó. Tay cầm đó có thể được tải từ tệp cấu hình trò chơi chính.
Như một ví dụ cụ thể từ cơ sở mã của chúng tôi, chúng tôi có một đối tượng "dữ liệu toàn cầu" được tải từ cơ sở dữ liệu tài nguyên (theo mặc định là ./resources
thư mục nhưng có thể bị quá tải với một đối số dòng lệnh). ID cơ sở dữ liệu tài nguyên của dữ liệu toàn cầu này là tên tài nguyên được mã hóa cứng cần thiết duy nhất trong cơ sở mã (chúng tôi có những người khác vì đôi khi các lập trình viên trở nên lười biếng, nhưng cuối cùng chúng tôi vẫn sửa / xóa chúng. Đối tượng dữ liệu toàn cầu này có đầy đủ các thành phần với mục đích duy nhất là cung cấp dữ liệu cấu hình. Một trong các thành phần là thành phần UI Global Data chứa các thẻ điều khiển tài nguyên cho tất cả các tài nguyên UI chính (phông chữ, tệp Flash, biểu tượng, dữ liệu bản địa hóa, v.v.) trong số một số mục cấu hình khác. Khi nhà phát triển UI quyết định đổi tên tài sản UI chính từ /ui/mainmenu.swf
thành/ui/lobby.swf
họ chỉ cập nhật dữ liệu tham khảo toàn cầu đó; không có mã động cơ cần phải thay đổi cả.
Chúng tôi sử dụng dữ liệu toàn cầu này cho tất cả mọi thứ. Tất cả các nhân vật có thể chơi, tất cả các cấp độ, giao diện người dùng, âm thanh, tài sản cốt lõi, cấu hình mạng, tất cả mọi thứ. (tốt, không phải tất cả mọi thứ , nhưng những thứ khác là lỗi cần sửa.)
Cách tiếp cận này có rất nhiều lợi thế khác. Đối với một, nó làm cho đóng gói tài nguyên và bó không thể thiếu cho toàn bộ quá trình. Các đường dẫn mã hóa cứng trong công cụ cũng có xu hướng có nghĩa là các đường dẫn tương tự đó phải được mã hóa cứng trong bất kỳ tập lệnh hoặc công cụ nào đóng gói tài sản trò chơi và sau đó các đường dẫn đó có thể không đồng bộ. Thay vào đó, dựa vào một tài sản cốt lõi và chuỗi tham chiếu duy nhất từ đó, chúng ta có thể xây dựng một gói tài sản với một lệnh như thế bundle.exe -root config.data -out main.wad
và biết rằng nó sẽ bao gồm tất cả các tài sản mà chúng ta yêu cầu. Hơn nữa, vì trình đóng gói sẽ chỉ theo dõi các tài liệu tham khảo tài nguyên, chúng tôi biết rằng nó sẽ chỉ bao gồm các tài sản mà chúng tôi yêu cầu và bỏ qua tất cả các phần thừa còn lại tích lũy trong suốt vòng đời của dự án (cộng với chúng tôi có thể tự động tạo danh sách đó lông tơ để cắt tỉa).
Một trường hợp góc khó khăn của toàn bộ điều này là trong các kịch bản. Làm cho công cụ điều khiển dữ liệu dễ dàng về mặt khái niệm, nhưng tôi đã thấy rất nhiều dự án (sở thích với AAA) trong đó các tập lệnh được coi là dữ liệu và do đó "được phép" sử dụng các đường dẫn tài nguyên một cách bừa bãi. Đừng làm vậy. Nếu một tệp Lua cần một tài nguyên và nó chỉ gọi một hàm như thế textures.lua("/path/to/texture.png")
thì đường dẫn tài sản sẽ gặp nhiều rắc rối khi biết rằng tập lệnh yêu cầu /path/to/texture.png
phải hoạt động chính xác và có thể coi kết cấu đó không được sử dụng và không cần thiết. Các tập lệnh nên được xử lý như bất kỳ mã nào khác: bất kỳ dữ liệu nào chúng cần bao gồm các tài nguyên hoặc bảng phải được chỉ định trong mục nhập cấu hình mà công cụ và đường ống tài nguyên có thể kiểm tra các phụ thuộc. Thay vào đó, dữ liệu có nội dung "tải tập lệnh foo.lua
" sẽ nói "foo.lua
và cung cấp cho nó các tham số này "trong đó các tham số bao gồm bất kỳ tài nguyên cần thiết nào. Ví dụ: nếu tập lệnh ngẫu nhiên sinh ra kẻ thù, hãy chuyển danh sách kẻ thù có thể vào tập lệnh từ tệp cấu hình đó. Sau đó, công cụ có thể tải trước kẻ thù với cấp độ ( vì nó biết danh sách đầy đủ các sinh sản có thể) và đường ống tài nguyên biết bó tất cả kẻ thù với trò chơi (vì chúng được tham chiếu chắc chắn bởi dữ liệu cấu hình). Nếu các tập lệnh tạo ra các chuỗi tên đường dẫn và chỉ gọi một load
hàm thì không công cụ cũng như đường ống tài nguyên có bất kỳ cách nào để biết cụ thể tài sản nào mà tập lệnh có thể tải.