문제

C#으로 작성된 작은 게임이 있습니다.데이터베이스를 백엔드로 사용합니다.그것은 a입니다 트레이딩 카드 게임, 카드의 기능을 스크립트로 구현하고 싶었습니다.

내 말은 본질적으로 인터페이스가 있다는 것입니다. ICard, 카드 클래스가 구현하는 것(public class Card056: ICard) 여기에는 게임에서 호출되는 함수가 포함되어 있습니다.

이제 유지 관리/수정 가능하게 만들기 위해 각 카드의 클래스를 데이터베이스의 소스 코드로 갖고 기본적으로 처음 사용할 때 컴파일하고 싶습니다.따라서 카드를 추가/변경해야 할 때 어셈블리 배포가 필요 없이 데이터베이스에 카드를 추가하고 애플리케이션을 새로 고치도록 지시합니다(특히 카드당 어셈블리 1개에 대해 이야기하므로 수백 개의 어셈블리를 의미하므로). .

그게 가능합니까?소스 파일에서 클래스를 등록한 다음 인스턴스화합니다.

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

언어는 C#이지만 모든 .NET 언어로 스크립트를 작성할 수 있는 경우 추가 보너스가 제공됩니다.

도움이 되었습니까?

해결책

Oleg Shilo의 C# 스크립트 솔루션(The Code Project))은 애플리케이션에 스크립트 기능을 제공하는 방법에 대한 훌륭한 소개입니다.

다른 접근 방식은 다음과 같이 스크립팅을 위해 특별히 제작된 언어를 고려하는 것입니다. 철루비, IronPython, 또는 루아.

IronPython과 IronRuby는 모두 오늘부터 사용할 수 있습니다.

IronPython 내장에 대한 가이드는 다음을 참조하세요.IronPython 스크립트 지원을 기존 앱에 포함시키는 간단한 10단계 방법.

Lua는 게임에서 흔히 사용되는 스크립트 언어입니다.CodePlex에서 사용할 수 있는 .NET용 Lua 컴파일러가 있습니다. http://www.codeplex.com/Nua

.NET에서 컴파일러를 구축하는 방법을 배우고 싶다면 해당 코드베이스를 읽어보면 좋습니다.

전혀 다른 각도로 시도해 보는 것입니다 파워셸.PowerShell을 애플리케이션에 포함시키는 수많은 예가 있습니다. 다음은 해당 주제에 대한 철저한 프로젝트입니다.파워셸 터널

다른 팁

IronRuby를 사용할 수도 있습니다.

그렇지 않으면 미리 컴파일된 어셈블리를 배치할 디렉터리가 있는 것이 좋습니다.그런 다음 DB에 어셈블리 및 클래스에 대한 참조가 있을 수 있으며 리플렉션을 사용하여 런타임에 적절한 어셈블리를 로드할 수 있습니다.

실제로 런타임에 컴파일하려면 CodeDOM을 사용하고 리플렉션을 사용하여 동적 어셈블리를 로드할 수 있습니다. 도움이 될 수 있는 Microsoft 설명서 문서.

DLR을 사용하고 싶지 않다면 다음을 수행하십시오. Boo(통역사가 있음)를 사용하세요. 아니면 고려해 볼 수도 있겠네요 CodePlex의 Script.NET(S#) 프로젝트.Boo 솔루션을 사용하면 컴파일된 스크립트 또는 인터프리터 사용 중에서 선택할 수 있으며 Boo는 개방형 컴파일러 아키텍처를 통해 유연한 구문과 확장 가능한 언어를 갖춘 멋진 스크립트 언어를 만듭니다.하지만 Script.NET도 보기 좋고 오픈 소스 프로젝트뿐만 아니라 해당 언어도 쉽게 확장할 수 있으며 매우 친숙한 컴파일러 생성기(Irony.net).

자신만의 스크립팅 플랫폼을 매우 쉽게 호스팅할 수 있는 방법을 제공하는 DLR 언어 중 하나를 사용할 수 있습니다.그러나 이를 위해 스크립팅 언어를 사용할 필요는 없습니다.C#을 사용하고 C# 코드 공급자로 컴파일할 수 있습니다.자체 AppDomain에 로드하기만 하면 마음껏 로드하고 언로드할 수 있습니다.

나는 사용하는 것이 좋습니다 Lua인터페이스 Nua가 완전하지 않고 일부 매우 유용한 기능(코루틴 등)을 구현하지 않는 것처럼 보이는 Lua를 완전히 구현했기 때문입니다.

외부에 미리 포장된 Lua 모듈 중 일부를 사용하려면 완전히 관리되는 코드를 작성하고 필요한 C API를 노출할 수 없는 2.x 시리즈와 달리 1.5.x 계열을 사용하는 것이 좋습니다.

NET 1.1 애플리케이션에 LuaInterface1.3 + Lua 5.0을 사용하고 있습니다.

Boo의 문제는 코드를 즉시 구문 분석/컴파일/평가할 때마다 일련의 boo 클래스를 생성하므로 메모리 누수가 발생한다는 것입니다.

반면에 Lua는 그렇게 하지 않으므로 매우 안정적이고 훌륭하게 작동합니다(C#에서 Lua로 또는 그 반대로 객체를 전달할 수 있습니다).

지금까지는 아직 PROD에 넣지 않았지만 매우 유망해 보입니다.

LuaInterface + Lua 5.0을 사용하는 PROD에서 메모리 누수 문제가 발생했습니다., 따라서 Lua 5.2를 사용하고 DllImport를 통해 C#에 직접 연결했습니다. 메모리 누수는 LuaInterface 라이브러리 내부에서 발생했습니다.

루아 5.2:~에서 http://luabinaries.sourceforge.net 그리고 http://sourceforge.net/projects/luabinaries/files/5.2/Windows%20Libraries/Dynamic/lua-5.2_Win32_dll7_lib.zip/download

이 작업을 수행한 후에는 모든 메모리 누수가 사라졌고 애플리케이션은 매우 안정적이었습니다.

내 부서에서 판매하는 기본 애플리케이션은 클라이언트 사용자 정의를 제공하는 것과 매우 유사한 기능을 수행합니다(즉, 소스를 게시할 수 없음을 의미).우리는 동적 VB.NET 스크립트를 로드하는 C# 응용 프로그램을 보유하고 있습니다(모든 .NET 언어는 쉽게 지원될 수 있지만 사용자 지정 팀은 ASP 배경에서 왔기 때문에 VB를 선택했습니다).

.NET의 CodeDom을 사용하여 VB를 사용하여 데이터베이스에서 스크립트를 컴파일합니다. CodeDomProvider (귀찮게도 기본값은 .NET 2입니다. 3.5 기능을 지원하려면 "CompilerVersion" = "v3.5"인 사전을 생성자에 전달해야 합니다.)사용 CodeDomProvider.CompileAssemblyFromSource 컴파일하는 방법(설정을 전달하여 메모리에서만 강제로 컴파일하도록 할 수 있습니다.

이렇게 하면 메모리에 수백 개의 어셈블리가 생성되지만 모든 동적 클래스의 코드를 단일 어셈블리에 통합하고 변경 사항이 있을 때 전체를 다시 컴파일할 수 있습니다.이는 플래그를 추가하여 디스크에서 컴파일할 수 있다는 장점이 있습니다. PDB 테스트할 때 동적 코드를 통해 디버깅할 수 있습니다.

예, 그것에 대해 생각해 보았지만 다른 DSL(Domain-Specific-Language)이 너무 과하다는 것을 곧 깨달았습니다.

본질적으로 그들은 예측할 수 없는 방식으로 내 게임 상태와 상호 작용해야 합니다.예를 들어, 카드에는 "이 카드가 플레이에 들어오면 적이 축복을 받을 때를 제외하고 날아다니는 적에 대해 모든 언데드 하수인이 +3 공격력을 얻습니다."라는 규칙이 있을 수 있습니다.트레이딩 카드 게임은 턴 기반이므로 GameState Manager는 OnStageX 이벤트를 실행하고 카드에 필요한 방식으로 카드가 다른 카드나 GameState를 수정하도록 합니다.

DSL을 만들려고 하면 상당히 큰 기능 세트를 구현하고 지속적으로 업데이트해야 하므로 실제로 제거하지 않고도 유지 관리 작업이 다른 부분으로 옮겨집니다.

이것이 바로 제가 본질적으로 이벤트를 발생시키고 카드가 어떤 방식으로든(코드 액세스 보안의 한계 내에서) 게임 상태를 조작할 수 있도록 "실제" .NET 언어를 사용하고 싶었던 이유입니다.

.NET의 다음 버전(5.0?)에서는 직접적인 스크립트 평가와 같은 작업을 가능하게 하는 "서비스로서의 컴파일러"를 여는 것에 대해 많은 논의가 있었습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top