Thêm chức năng tập lệnh vào các ứng dụng .NET


77

Tôi có một trò chơi nhỏ được viết bằng C #. Nó sử dụng một cơ sở dữ liệu làm back-end. Đó là một trò chơi thẻ giao dịch và tôi muốn triển khai chức năng của các thẻ như một kịch bản.

Ý tôi là về cơ bản, tôi có một giao diện, ICardmà một lớp thẻ thực hiện ( public class Card056: ICard) và chứa một hàm được trò chơi gọi.

Bây giờ, để làm cho thứ có thể bảo trì / sửa đổi được, tôi muốn có lớp cho mỗi thẻ làm mã nguồn trong cơ sở dữ liệu và về cơ bản biên dịch nó trong lần sử dụng đầu tiên. Vì vậy, khi tôi phải thêm / thay đổi một thẻ, tôi sẽ chỉ thêm nó vào cơ sở dữ liệu và yêu cầu ứng dụng của tôi làm mới, mà không cần bất kỳ triển khai lắp ráp nào (đặc biệt là vì chúng ta sẽ nói về 1 cụm trên mỗi thẻ có nghĩa là hàng trăm cụm) .

Điều đó có thể không? Đăng ký một lớp từ một tệp nguồn và sau đó khởi tạo nó, v.v.

ICard Cards[current] = new MyGame.CardLibrary.Card056();
Cards[current].OnEnterPlay(ref currentGameState);

Ngôn ngữ là C # nhưng có thêm phần thưởng nếu có thể viết script bằng bất kỳ ngôn ngữ .NET nào.


1
Thật là buồn cười, tôi và một người bạn đã nghĩ đến việc viết một trò chơi thẻ giao dịch trong C # một thời gian trước, không giả sử bạn vẫn còn nguồn cho việc này? Quan tâm đến cách bạn tiếp cận điều này.
mattytommo

@mattytommo Không, đừng bỏ sót gì cả, nó đang ở giai đoạn đầu và về cơ bản chỉ hoạt động như tôi đã nêu ở trên. Ngày nay, tôi sẽ xem xét Roslyn để biên dịch C #: blog.msdn.com/b/csharpfaq/archive/2011/10/19/… - Ngoài ra, JavaScript sử dụng Jint - jint.codeplex.com
Michael Stum

à, cảm ơn, nhưng tôi đang tìm kiếm nhiều hơn để triển khai chính trò chơi thẻ giao dịch và cấu trúc bạn đã sử dụng, trái ngược với công cụ viết kịch bản. Dù sao cũng cảm ơn :)
mattytommo

Câu trả lời:


41

Giải pháp C # Script của Oleg Shilo (tại The Code Project ) thực sự là một phần giới thiệu tuyệt vời để cung cấp khả năng của script trong ứng dụng của bạn.

Một cách tiếp cận khác sẽ là xem xét một ngôn ngữ được xây dựng đặc biệt cho kịch bản, chẳng hạn như IronRuby , IronPython hoặc Lua .

IronPython và IronRuby đều có sẵn ngày hôm nay.

Để có hướng dẫn nhúng IronPython, hãy đọc Cách nhúng hỗ trợ tập lệnh IronPython vào ứng dụng hiện có của bạn trong 10 bước đơn giản .

Lua là một ngôn ngữ kịch bản thường được sử dụng trong trò chơi. Có một trình biên dịch Lua cho .NET, có sẵn từ CodePlex - http://www.codeplex.com/Nua

Codebase đó là một tài liệu tuyệt vời nếu bạn muốn tìm hiểu về cách xây dựng trình biên dịch trong .NET.

Một góc độ khác hoàn toàn là thử PowerShell . Có rất nhiều ví dụ về việc nhúng PowerShell vào một ứng dụng - đây là một dự án kỹ lưỡng về chủ đề này: Đường hầm Powershell


1
Nhân tiện, tôi đã chọn đây là câu trả lời được chấp nhận vì dù sao thì tôi cũng muốn tham gia Python và IronPython, vì vậy phương pháp IronPython phù hợp nhất với tôi .
Michael Stum

LuaInterface là một trình thông dịch lua cũng hoạt động tuyệt vời.
RCIX

Tôi đã triển khai C # Script trong một hệ thống quy trình làm việc vào ngày 09 tháng 11. Nó hoạt động rất tốt đối với chúng tôi.
David Robbins

8

Bạn có thể sử dụng IronRuby cho việc đó.

Nếu không, tôi khuyên bạn nên có một thư mục nơi bạn đặt các tập hợp được biên dịch sẵn. Sau đó, bạn có thể có một tham chiếu trong DB đến hợp ngữ và lớp, và sử dụng phản chiếu để tải các hợp ngữ thích hợp trong thời gian chạy.

Nếu bạn thực sự muốn biên dịch trong thời gian chạy, bạn có thể sử dụng CodeDOM, sau đó bạn có thể sử dụng phản chiếu để tải lắp ráp động. Bài viết tài liệu của Microsoft có thể hữu ích .


7

Nếu bạn không muốn sử dụng DLR, bạn có thể sử dụng Boo (có trình thông dịch) hoặc bạn có thể xem xét dự án Script.NET (S #) trên CodePlex . Với giải pháp Boo, bạn có thể chọn giữa các tập lệnh đã biên dịch hoặc sử dụng trình thông dịch và Boo tạo ra một ngôn ngữ kịch bản đẹp, có cú pháp linh hoạt và ngôn ngữ có thể mở rộng thông qua kiến ​​trúc trình biên dịch mở của nó. Tuy nhiên, Script.NET trông cũng đẹp và bạn có thể dễ dàng mở rộng ngôn ngữ đó cũng như một dự án mã nguồn mở của nó và sử dụng Trình tạo trình biên dịch rất thân thiện ( Irony.net ).


6

Bạn có thể sử dụng bất kỳ ngôn ngữ DLR nào, cung cấp một cách để thực sự dễ dàng lưu trữ nền tảng tập lệnh của riêng bạn. Tuy nhiên, bạn không cần phải sử dụng ngôn ngữ script cho việc này. Bạn có thể sử dụng C # và biên dịch nó với nhà cung cấp mã C #. Miễn là bạn tải nó trong AppDomain của chính nó, bạn có thể tải và tải nó xuống nội dung của bạn.


5

Tôi khuyên bạn nên sử dụng LuaInterface vì nó đã triển khai đầy đủ Lua, nơi có vẻ như Nua chưa hoàn thành và có khả năng không triển khai một số chức năng rất hữu ích (coroutines, v.v.).

Nếu bạn muốn sử dụng một số mô-đun Lua được đóng gói sẵn bên ngoài, tôi khuyên bạn nên sử dụng thứ gì đó dọc theo dòng 1.5.x trái ngược với loạt 2.x xây dựng mã được quản lý hoàn toàn và không thể hiển thị C API cần thiết.


5

Tôi đang sử dụng LuaInterface1.3 + Lua 5.0 cho ứng dụng NET 1.1.

Vấn đề với Boo là mỗi khi bạn phân tích cú pháp / biên dịch / đánh giá mã của mình một cách nhanh chóng, nó sẽ tạo ra một tập hợp các lớp boo, do đó bạn sẽ bị rò rỉ bộ nhớ.

Mặt khác, Lua không làm điều đó, vì vậy nó rất ổn định và hoạt động tuyệt vời (tôi có thể chuyển các đối tượng từ C # sang Lua và ngược lại).

Cho đến nay tôi vẫn chưa đưa nó vào PROD, nhưng có vẻ rất hứa hẹn.

Tôi đã gặp sự cố rò rỉ bộ nhớ trong PROD khi sử dụng LuaInterface + Lua 5.0 , do đó tôi đã sử dụng Lua 5.2 và liên kết trực tiếp vào C # với DllImport. Bộ nhớ bị rò rỉ bên trong thư viện LuaInterface.

Lua 5.2: từ http://luabinaries.sourceforge.nethttp://sourceforge.net/projects/luabinaries/files/5.2/Windows%20Libraries/Dynamic/lua-5.2_Win32_dll7_lib.zip/download

Sau khi tôi làm điều này, tất cả các lỗi rò rỉ bộ nhớ của tôi đã biến mất và ứng dụng rất ổn định.


4

Ứng dụng chính mà bộ phận của tôi bán làm một cái gì đó rất giống để cung cấp các tùy chỉnh của khách hàng (có nghĩa là tôi không thể đăng bất kỳ nguồn nào). Chúng tôi có một ứng dụng C # tải các tập lệnh VB.NET động (mặc dù bất kỳ ngôn ngữ .NET nào cũng có thể được hỗ trợ dễ dàng - VB được chọn vì nhóm tùy chỉnh đến từ nền tảng ASP).

Sử dụng CodeDom của .NET, chúng tôi biên dịch các tập lệnh từ cơ sở dữ liệu, sử dụng VB CodeDomProvider(khó chịu là nó mặc định là .NET 2, nếu bạn muốn hỗ trợ các tính năng 3.5, bạn cần phải chuyển một từ điển có "CompilerVersion" = "v3.5" vào hàm tạo của nó ). Sử dụng CodeDomProvider.CompileAssemblyFromSourcephương pháp để biên dịch nó (bạn có thể chuyển cài đặt để buộc nó chỉ biên dịch trong bộ nhớ.

Điều này sẽ dẫn đến hàng trăm tập hợp trong bộ nhớ, nhưng bạn có thể đặt tất cả mã của các lớp động lại với nhau thành một tập hợp duy nhất và biên dịch lại toàn bộ khi có bất kỳ thay đổi nào. Điều này có lợi thế là bạn có thể thêm cờ để biên dịch trên đĩa với PDB khi bạn đang thử nghiệm, cho phép bạn gỡ lỗi thông qua mã động.


4

Vâng, tôi đã nghĩ về điều đó, nhưng tôi sớm nhận ra rằng một ngôn ngữ dành riêng cho miền (DSL) khác sẽ hơi quá.

Về cơ bản, họ cần phải tương tác với trò chơi của tôi theo những cách có thể không đoán trước được. Ví dụ: một lá bài có thể có quy tắc "Khi lá bài này bắt đầu chơi, tất cả lính chưa đọc của bạn được +3 tấn công chống lại kẻ thù bay, ngoại trừ khi kẻ thù được ban phước". Khi các trò chơi thẻ giao dịch được dựa theo lượt, Trình quản lý GameState sẽ kích hoạt các sự kiện OnStageX và cho phép các thẻ sửa đổi các thẻ khác hoặc GameState theo bất kỳ cách nào mà thẻ cần.

Nếu tôi cố gắng tạo DSL, tôi phải triển khai một tập hợp tính năng khá lớn và có thể liên tục cập nhật nó, điều này sẽ chuyển công việc bảo trì sang một phần khác mà không thực sự loại bỏ nó.

Đó là lý do tại sao tôi muốn ở lại với một ngôn ngữ .NET "thực" để về cơ bản có thể chỉ kích hoạt sự kiện và cho phép thẻ thao túng trò chơi theo bất kỳ cách nào (trong giới hạn của bảo mật truy cập mã).


(Không cần phải cờ này; trong khi điều này phải là một bản cập nhật bình luận / câu trả lời, nhưng grandfathered từ trước đó là những tùy chọn)

3

Phiên bản tiếp theo của .NET (5.0?) Đã nói nhiều về việc mở "trình biên dịch như một dịch vụ" sẽ làm cho những thứ như đánh giá tập lệnh trực tiếp có thể thực hiện được.


2
Đúng. Mặc dù Roslyn vẫn đang trong quá trình phát triển, Mono.CSharp (có sẵn trên NuGet) đóng gói tất cả các chức năng tương tự.
Eric Falsken

Thêm bản cập nhật để giữ các tùy chọn phù hợp: Nền tảng trình biên dịch .NET ("Roslyn") hiện có sẵn. Vì vậy, nó là một sự thay thế khả thi cho tất cả những cái khác được đề cập. github.com/dotnet/roslyn .
Riv
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.