Là thực hiện ngôn ngữ kịch bản của riêng bạn khả thi?


21

Tôi đang mã hóa một trò chơi đánh bại trong C ++ và đã đến lúc triển khai kịch bản cho các sự kiện, trình kích hoạt, đoạn cắt cảnh, v.v. Tôi đã đọc trên internet và nhận được một chút thông tin. Giải pháp lựa chọn đầu tiên của tôi sẽ là thực hiện ngôn ngữ kịch bản của riêng tôi giống như ngôn ngữ trong Cave Story . Tôi đã thấy đề xuất này nhưng hầu hết các poeple đề nghị lua nhưng điều đó dường như không phù hợp với kiểu lập trình của tôi.

Bạn đã thực hiện ngôn ngữ kịch bản của riêng bạn? Tại sao bạn chọn tự cuộn thay vì sử dụng một cái hiện có? Những tài nguyên nào bạn đã tham khảo trong quá trình phát triển?


43
Nguyên tắc cá nhân của tôi là: nếu bạn cần hỏi người khác liệu có nên tự mình thực hiện hay không, thì đó không phải là một ý kiến ​​hay.
sam hocevar

2
Lưu ý rằng nếu bạn triển khai ngôn ngữ của mình, mọi người phải học nó và hy vọng rằng không có lỗi trong trình thông dịch của bạn, trong khi các ngôn ngữ như Lua phổ biến hơn và ít có khả năng gặp lỗi hơn.
Nick Caplinger

2
@NickCaplinger đánh vào đầu nó. Tự mình sử dụng nghĩa là không có tài liệu, không có cộng đồng, không có hướng dẫn của bên thứ ba, không có StackExchange, v.v. Bất kể những tiến bộ nhỏ nào bạn có được trong cú pháp hoặc tích hợp sẽ vượt trội hơn do thiếu hỗ trợ trừ khi bạn là nhà phát triển thực sự nổi tiếng với hàng triệu người hâm mộ.
Sean Middleditch

4
Cũng ghi nhớ công cụ. Đây là vấn đề của tôi với D, Rust, Dart, v.v ... Cú pháp của bạn là vô nghĩa. Bạn cần một trình soạn thảo thích hợp, làm nổi bật, "Intellisense" (hoàn thành mã), chẩn đoán tốt, hỗ trợ tái cấu trúc, hỗ trợ tài liệu nội tuyến, v.v. để thực sự có giá trị. Không đề cập đến tất cả các tính năng ngôn ngữ thực tế, tích hợp, hiệu quả, và như vậy.
Sean Middleditch

1
Nếu bạn là lập trình viên C ++ và bạn không thích LUA, thay vào đó hãy thử JavaScript.
zeel

Câu trả lời:


42

Số Ít nhất, có lẽ không.

Đây là một trường hợp rất thường xuyên của việc phát minh lại bánh xe là phát triển trò chơi, một sai lầm vẫn còn khá phổ biến.

Nếu bạn đang hỏi câu hỏi này, bạn rất có thể bị ảnh hưởng bởi những gì người khác làm, vì vậy hãy nhìn vào những gì Epic Games vừa làm với Unreal Engine:

  • UE3 có một điều UnrealScript tùy chỉnh, kỳ lạ, không được tối ưu hóa, khó gỡ lỗi,
  • Nếu tin đồn là sự thật, sự hỗ trợ của nó đang bị xóa trong UE4 , có lợi cho các DLL C ++ có thể tải lại nóng.

Bạn có nghĩ rằng bạn có thể làm tốt hơn Epic?

Tạo ngôn ngữ progamming thuộc về người tạo ngôn ngữ lập trình , không phải kỹ sư trò chơi.

Phải mất nhiều năm và một năm để một ngôn ngữ trở nên hoàn thiện và bộ công cụ đi kèm của nó (trình biên dịch, trình liên kết, trình thông dịch, trình gỡ lỗi ..) có thể sử dụng được. Ngày nay bạn có rất nhiều giải pháp khả dụng trong tay nên hoàn toàn không có lý do thực sự để bắt đầu một điều mới từ đầu, ít nhất là không nếu mục tiêu chỉ đơn giản là tạo ra một trò chơi. Giai đoạn.

Để trả lời các câu hỏi phụ của bạn, không, vì những lý do này, tôi chưa bao giờ thực hiện ngôn ngữ kịch bản của riêng mình. Nhưng tôi đã chịu đựng rất nhiều với một số người nửa nướng. Bởi vì chúng được tạo ra với một tính năng rất hẹp được đặt ra trong tâm trí, chúng luôn có những điều kỳ quặc nhỏ bé khiến bạn phát điên. Thông thường, bạn sẽ thấy mình mất rất nhiều thời gian chỉ để cố gắng khắc phục giới hạn ngôn ngữ thay vì chỉ làm trò chơi của bạn.

Nếu lý do bạn muốn tạo ngôn ngữ là vì nó được sử dụng cho những người không biết lập trình rất tốt hoặc nếu bạn tin rằng bạn cần ngôn ngữ đó vì bạn muốn một thứ gì đó rất đặc trưng cho miền, hãy để tôi nói với bạn những điều này cũng lý do xấu. Bạn có thể viết một API cấp độ rất cao với các chức năng đó do_what_they_say_and_say_what_they_do()và một số mã soạn sẵn rất đơn giản cho thấy cách sử dụng cơ bản của nó. Người dùng không có kỹ thuật của bạn sẽ rất vui khi học một chút về lập trình và bạn sẽ rất vui khi không bị giới hạn bởi một số ngôn ngữ được triển khai kém.

Vì vậy, vì điều này nghe có vẻ hơi đột ngột hoặc thậm chí khắc nghiệt, tôi sẽ nói rằng có một trường hợp có thể có ý nghĩa: nếu bạn muốn tìm hiểu cách tạo ra một ngôn ngữ kịch bản. Nhưng làm ơn, làm ơn, nếu bạn làm như vậy: đừng ép người khác sử dụng nó.

Chỉnh sửa

Tôi vừa xem danh sách lệnh Cave Story mà bạn đã liên kết. Ôi:

<ECJx:y      [EC?] Jump           @ Jump to event Y if any npc with ID X is present

Tôi không muốn thể hiện sự thiếu tôn trọng với nhà phát triển đằng sau Cave Story, nhưng đây là một ví dụ hoàn hảo về danh sách lệnh đơn giản bị đột biến trong ngôn ngữ kịch bản tùy chỉnh không kiểm soát được. Điều này có thể vẫn có thể sử dụng được cho một nhà phát triển hoặc một nhóm rất nhỏ, nhưng ở giai đoạn này tôi khuyên bạn nên chuyển sang một ngôn ngữ Turing đầy đủ và được thử tốt (ví dụ: Lua), nơi bạn có thể làm:

if (npc.id == x) then
    jump_to_event(y)
end

Điều này sẽ làm cho mọi thứ dễ dàng hơn rất nhiều khi, ví dụ, bạn sẽ cần một điều kiện phức tạp hơn:

if (npc.id == x) or (npc.type == "enemy") then
    jump_to_event(y)
end

21
+1 "Tạo ngôn ngữ progamming thuộc về người tạo ngôn ngữ lập trình, không phải kỹ sư trò chơi." Câu nói này không thể chính xác hơn. Đã tham gia một lớp khái niệm ngôn ngữ lập trình được dạy bởi một chàng trai cuồng nhiệt với ngôn ngữ lập trình, những người này là một giống khác nhau. Một lớp học khiến tôi nhận ra số lượng lý thuyết và toán học CS tạo ra một ngôn ngữ lập trình thực sự. Điều này khiến tôi đánh giá cao những người này và bộ kỹ năng của họ hơn nữa. Họ để tôi tạo ra các trò chơi, tôi tránh xa họ và để họ tạo ra các ngôn ngữ.
Dean Knight

+1, tôi không biết ngôn ngữ kịch bản tùy chỉnh, nhưng rõ ràng chính xác những gì đang diễn ra ở lua và đó là nơi khả năng sử dụng là quan trọng
RhysW

1
Không có gì kỳ diệu về cái này hay cái kia làm cho không thể học cả hai. Unreal có thể loại bỏ UnrealScript nhưng chúng giúp tăng cường đáng kể và điền vào Kismet để trở thành một ngôn ngữ kịch bản hình ảnh có khả năng và hoàn chỉnh. Họ đã không xóa UnrealScript vì đó là một thất bại, họ đã xóa nó vì nó đã bị lỗi thời bởi các tính năng khó khăn hơn đáng kể (C ++ tải lại nóng, Kismit cập nhật). Đừng hiểu điều này có nghĩa là tôi không đồng ý với quan điểm của bạn: viết ngôn ngữ của riêng bạn là một sự lãng phí rất lớn thời gian, một nguồn lỗi và là nguyên nhân của những đường cong học tập lớn, v.v.
Sean Middleditch

2
@ ott-- Tôi cũng không sợ, quan điểm của tôi là việc mở rộng ký hiệu này sẽ khiến nó ngày càng phức tạp hơn, trong khi việc sử dụng một ngôn ngữ phù hợp ở nơi đầu tiên sẽ giúp ích về lâu dài. Chi phí không liên quan so với mức độ dễ sử dụng trong trường hợp đó, IMHO.
Laurent Couvidou

1
Lưu ý rằng UnrealScript được thay thế bằng Blueprints (nhưng tôi đã đặt cược với các đồng nghiệp của mình rằng nó sẽ trở lại). DLL tải nóng là một tính năng trực giao.
sam hocevar

9

Bạn đã tạo ngôn ngữ kịch bản của riêng mình chưa và tại sao bạn lại chọn tự viết thay vì sử dụng ngôn ngữ hiện có?

Tôi có, mặc dù tôi đã mượn cú pháp từ các ngôn ngữ khác. Nói chung, đó là một trải nghiệm học tập tuyệt vời và trong trường hợp của tôi không khó lắm vì ngôn ngữ rất đơn giản.

Tôi đã làm điều đó chủ yếu vì tôi muốn sử dụng cú pháp kiểu C thông thường cho các tập lệnh của mình, vì mọi người trong nhóm đều quen thuộc với nó.

Tôi cũng thích tìm hiểu một chút về việc triển khai các ngôn ngữ lập trình và vì tôi chỉ cần một tập hợp con rất đơn giản của các tính năng (biến, số học, điều kiện, vòng lặp và gọi các hàm trong trò chơi hoặc coroutines) nên tôi đã quyết định dùng thử.

Những tài nguyên nào bạn đã tham khảo trong quá trình phát triển?

Tài nguyên chính của tôi là cuốn sách này:

nhập mô tả hình ảnh ở đây

Tôi quản lý để học đủ từ cuốn sách này để thực hiện:

  • Một lexer: gần như không quan trọng bằng cách sử dụng các biểu thức thông thường, chỉ cần sử dụng Regex.Match để xác định và phân tách mã thông báo.
  • Trình phân tích cú pháp gốc đệ quy: về cơ bản là một hàm cho mỗi quy tắc trong ngữ pháp và một số phương thức trợ giúp để tìm kiếm và tiêu thụ mã thông báo. Tôi nhìn vào đặc tả ngữ pháp C # cho cảm hứng. Phần khó nhất là xử lý các ưu tiên số học và toán tử quan hệ mà không đi vào đệ quy vô hạn.
  • Trình thông dịch AST: sử dụng mẫu thiết kế của khách truy cập, tôi duyệt qua cây được tạo từ trình phân tích cú pháp và thực hiện đệ quy từng nút lệnh.

Tôi đã dừng lại ở đó vì hầu hết mọi thứ tôi cần đều đã hoạt động, ngoại trừ một điều - gọi và mang lại kết quả trên các xác chết Unity3D từ sâu trong trình thông dịch đệ quy. Để giải quyết vấn đề đó, tôi đã phải thoát khỏi sự đệ quy, và một lần nữa chuyển sang cuốn sách. Lần này tôi đã kết thúc thêm:

  • Trình biên dịch: một khách truy cập khác, nhưng thay vì thực thi mã, nó tạo ra một danh sách các lệnh nhỏ, nguyên tử từ mỗi nút của AST (tức là ngôn ngữ lắp ráp tùy chỉnh dựa trên ngăn xếp đơn giản). Các hoạt động như vòng lặp while hoặc điều kiện if, được chuyển đổi thành nhãn và hướng dẫn kiểu goto. Lúc này tôi cũng viết đoạn script đã biên dịch vào đĩa dưới dạng tệp nhị phân.
  • Trình thông dịch mã byte: chỉ đơn giản lặp lại qua một danh sách hướng dẫn phẳng. Không có đệ quy, giờ đây nó dễ dàng tích hợp với các coroutines Unity3D.

Toàn bộ quá trình mất khoảng 2 tuần từ không có kiến ​​thức, và rất nhiều niềm vui :)

PS: Cuối cùng, tôi cũng muốn thêm đánh dấu cú pháp và intellisense cho ngôn ngữ tùy chỉnh của mình trên các công cụ của chúng tôi. Scintilla là một vị cứu tinh trong vấn đề này. Tôi đã sử dụng trình bao bọc sau đây:

http://scintillanet.codeplex.com/


5

Tôi đã thấy đề xuất này nhưng hầu hết các poeple đề nghị lua nhưng điều đó dường như không phù hợp với kiểu lập trình của tôi.

OK, chúng ta hãy thử điều này từ một góc độ khác: Lua mà bạn không thích là gì? Nó có phải là một cái gì đó dễ dàng sửa chữa, hoặc nó là một cái gì đó cơ bản?

Ví dụ: sử dụng các từ khóa như then/do/endđể biểu thị khối mã thay vì các dấu ngoặc nhọn kiểu C / C ++ tốt. Nếu đó là vấn đề của bạn ... đó là điều bạn có thể khắc phục. Tất cả những gì bạn cần làm là xác định phương ngữ Lua nhỏ của riêng bạn và viết một công cụ chuyển đổi đơn giản sẽ chuyển cú pháp cú pháp xoăn của bạn thành Lua thực tế.

Bạn có muốn + = trong một số hình thức? Đó cũng dễ dàng là điều bạn có thể làm trong một hệ thống tiền xử lý. Chỉ cần biến các tuyên bố của các hình thức expr1 += expr2thành expr1 = expr1 + expr2.

Cấp, bạn sẽ phải tìm cách phát hiện xem một cặp niềng răng xoăn đại diện cho một bảng hay một do/endcặp. Và bạn phải treo hệ thống tiền xử lý của bạn vào Lua bằng cách ghi đè dofile, loadstringvà các chức năng thư viện Lua tiêu chuẩn khác. Nhưng cuối cùng tất cả đều có thể làm được.

Nếu các vấn đề nhỏ như đó là mối quan tâm của bạn và bạn quá thích một kiểu lập trình để thay đổi cách viết mã (lưu ý: đây thường là một chất lượng khủng khiếp để làm lập trình viên), thì đây là một cách thay thế khả thi hơn nhiều so với chỉ đơn giản viết ngôn ngữ của riêng bạn. Điều này sẽ mất có thể một vài tuần nhiều nhất . So sánh điều đó với những năm sẽ dành cho một ngôn ngữ phù hợp, với sự hỗ trợ gỡ lỗi phong phú và tương tự.

Nếu các vấn đề của bạn lớn hơn vấn đề này (toàn cầu là mặc định, do đó yêu cầu bạn sử dụng localở mọi nơi), một số vấn đề này có thể được quản lý (chỉ đơn giản là khai báo toàn cầu mới là lỗi, thông qua việc sử dụng các môi trường và siêu dữ liệu đã thay đổi). Nếu bạn ghét các chức năng như các đối tượng hạng nhất, coroutines, bộ sưu tập rác hoặc các yếu tố cơ bản khác của Lua ... thì tốt, bạn đang ở trong địa ngục do chính bạn tạo ra;)

Và nếu bạn thực sự, thực sự muốn trở nên khó tính về nó, bạn có thể viết ngôn ngữ của riêng bạn mà bạn biên dịch thành Lua. Vì vậy, ít nhất bạn sẽ có thể tận dụng thời gian chạy Lua được kiểm tra rất tốt, API Lua đặc biệt và các cơ sở Lua cơ bản khác, tất cả từ ngôn ngữ! Lua của bạn. Điều này sẽ mất thời gian, nhưng nó vẫn sẽ không phải là những năm bạn dành cho việc khác.


Đối với tôi, có vẻ như tôi chỉ có thể mã hóa các chức năng nếu tôi sử dụng Lua. Cảm giác như tôi chỉ đang di chuyển mã.
Skiperic

1
@skiperic: Tôi không biết ý của bạn là gì. Bạn có thể đưa ra một ví dụ không?
Nicol Bolas

Xem câu trả lời của Laurent ở trên.
bỏ qua

2
@skiperic: Điều đó không thực sự giải thích những gì bạn quan tâm. Bạn có thể mã trong Lua? Vâng. Và vấn đề là ...?
Nicol Bolas

1
@BartekBanachewicz: Ngay cả khi chấp nhận rằng đó là API C, nó vẫn vượt trội so với nhiều API kịch bản dựa trên C ++ mà tôi đã thấy. Đó là API kịch bản duy nhất tôi thực sự sẽ xem xét sử dụng raw , không có chất kết dính tự động nào đó.
Nicol Bolas

3

Để bổ sung cho các câu trả lời khác, đây không phải là một tùy chọn nhị phân nghiêm ngặt. Trong một ngôn ngữ kịch bản lệnh hiện có, bạn cũng có thể tạo Ngôn ngữ cụ thể của miền . Ưu điểm của phương pháp này là:

  • Bạn thực sự không phải gặp rắc rối với ngữ pháp chính thức, trình phân tích cú pháp, triển khai các trình soạn thảo tùy chỉnh, v.v.
  • Bạn đang nhận được hầu hết lợi ích của việc triển khai một ngôn ngữ kịch bản chuyên biệt, nghĩa là một sự trừu tượng hóa bổ sung, cụ thể cho trò chơi của bạn.
  • so với homebrew: người dùng đã làm quen với ngôn ngữ kịch bản bạn chọn sẽ ngay lập tức có thể sử dụng DSL của bạn.
  • so với ngôn ngữ hiện có: người dùng không quen thuộc với ngôn ngữ kịch bản sẽ chỉ cần kiến ​​thức về DSL để điều chỉnh trò chơi của bạn.

Nhược điểm chính là bạn sẽ thiết kế DSL với các ràng buộc của ngôn ngữ "cơ sở" của bạn.


2

có thể có ý nghĩa tùy thuộc vào cơ chế của trò chơi của bạn. Một số trò chơi với cơ chế đủ đơn giản có thể sử dụng ngôn ngữ được dịch để tự cứu mình khỏi một số mã hóa Lua / Python quá phức tạp, nhưng mức tiết kiệm phức tạp có thể không đáng giá quá nhiều. Chẳng hạn, một trong những trò chơi Novel tương tác đó có thể dễ dàng sử dụng một công cụ viết kịch bản tùy chỉnh.

Nếu trò chơi của bạn liên quan đến một công cụ vật lý, các thành phần trò chơi khác nhau và sự phức tạp khác nhau của các nhân vật và khả năng, bạn chắc chắn nên xem xét việc xem xét các ngôn ngữ kịch bản hiện có khác, vì vậy bạn không tranh giành để thêm các tính năng cần thiết vào tùy chỉnh của mình hoặc sửa lỗi nó Mặc dù Lua rất có thể là nhanh nhất, nhưng có nhiều người khác mà bạn có thể thích hơn cho cú pháp của họ và nhiều người trong số họ khoe khoang về việc họ dễ dàng tích hợp với C. Python, Ruby và Angelscript như thế nào. (Hãy đề cập đến những người khác trong các ý kiến)

Nếu bạn đảm bảo các ngôn ngữ như vậy chỉ được sử dụng cho "điều khiển logic" (nghĩa là xử lý một trường hợp va chạm cụ thể cho một số loại đối tượng nhất định, như ngọn lửa chạm vào khối băng) thì hiệu suất sẽ khó xảy ra. Tất nhiên, mặt khác, nếu bạn sử dụng chúng cho mã thường xuyên hơn (tạo thuật toán kiểm tra va chạm tùy chỉnh chạy từng khung hình) thì nhiều khả năng sẽ làm bạn thất vọng.


1
Lua cũng là một ngôn ngữ kịch bản rất phổ biến trong phát triển trò chơi.
Philipp

Yup, Lua được sử dụng ở mọi nơi, nhưng OP lưu ý rằng anh ta không thực sự thích nó nhiều. Sở thích của phong cách mã hóa có thể quan trọng.
Katana314

1
" Ví dụ, một trong những trò chơi Tiểu thuyết tương tác đó có thể dễ dàng sử dụng một công cụ viết kịch bản được viết tùy chỉnh. " Rõ ràng là bạn chưa thấy Inform . Thực sự, ngay cả đối với những cuộc phiêu lưu văn bản, không có điểm nào tạo nên ngôn ngữ của riêng bạn.
Nicol Bolas

1
@ Katana314: " Sở thích về phong cách mã hóa có thể quan trọng. " Thành thực mà nói, thế giới sẽ tốt hơn nếu các lập trình viên xuống ngựa cao về "phong cách mã hóa". Tất cả chúng ta sẽ là những lập trình viên tốt hơn nếu chúng ta ngừng nghĩ rằng <chèn ngôn ngữ ưa thích vào đây> về cơ bản tốt hơn <chèn ngôn ngữ ưa thích ở đây>. Sử dụng các ngôn ngữ mà bạn có thể không thích cú pháp xây dựng ký tự và giúp tránh loại suy nghĩ lỗi này.
Nicol Bolas

1

Tôi nói, đi cho nó. Trong một bản lý lịch, nó sẽ là một chương trình bổ sung về khả năng. Mặc dù vậy, hãy ghi nhớ, bạn cần khả năng đó trước tiên. Nó sẽ không dễ dàng, nó sẽ khá khó khăn. Có những cuốn sách về chủ đề này và các hướng dẫn trực tuyến cũng vậy, nhưng cuối cùng, nó sẽ đến với bạn và sự hiểu biết của bạn về cách trình biên dịch hoạt động, và cách mã được phân tích và dịch.

Làm cho shure bạn bắt đầu đơn giản, kiểm tra thường xuyên và giữ lý tưởng của bạn. Nhưng hãy luôn nhớ rằng, LUA luôn ở đó vì bạn.


1
Tôi đoán câu hỏi ở đây là nếu mục tiêu là làm một trò chơi, hoặc để làm một cái gì đó có vẻ tốt trong một bản lý lịch.
Tridus
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.