2010-06-13 2 views
1

현재 C++로 3D 액션/RPG 게임을 개발 중입니다. 게임의 AI를 프로그래밍하기위한 스크립팅 언어를 선택하는 데 조언이 필요합니다. 우리 팀은 modding 배경에서 왔고, 실제로 우리는 여전히 Gothic 게임 모드에서 작업을 마무리하고 있습니다. 그 게임 (우리도 영감을 얻었습니다)에서 언어 DAEDALUS (피라 냐 바이트 (Piranha Bytes)가 만든 게임의 제작자)가 사용되었습니다. Here is a full description of said language.게임용 스크립팅 언어 선택 및 구현

주된 점은 클래스보다 인스턴스를 사용한다는 점입니다. 게임 엔진이 닫혀 있으므로이 언어의 내부 구현에 대해서만 추측 할 수 있지만 스크립팅 언어에서 가장 중요한 것은 (이상적으로는 비슷하지만 바람직하게는 DAEDALUS보다 강력 함) 사실입니다. 클래스, 인스턴스 및 인스턴스 (인스턴스의 인스턴스)와 같은 사실상 3 가지 '클래스 분리'가 있음을 알 수 있습니다.

예제를 제공하면 원하는 것을 이해하는 것이 더 쉬울 것이라고 생각합니다. 정규 NPC를 가져 가라.

CLASS C_NPC 
{ 
    VAR INT  id        ;  // absolute ID des NPCs 
    VAR STRING name   [5]    ;  // Namen des NPC 
    VAR STRING slot       ;   
    VAR INT  npcType       ;   
    VAR INT  flags       ;   
    VAR INT  attribute  [ATR_INDEX_MAX] ;   
    VAR INT  protection  [PROT_INDEX_MAX];   
    VAR INT  damage   [DAM_INDEX_MAX] ;   
    VAR INT  damagetype      ; 
    VAR INT  guild,level      ;   

    VAR FUNC mission   [MAX_MISSIONS] ;   
    var INT  fight_tactic     ;   
    VAR INT  weapon       ;   

    VAR INT  voice       ;   
    VAR INT  voicePitch      ;   
    VAR INT  bodymass      ;   

    VAR FUNC daily_routine     ;  // Tagesablauf 
    VAR FUNC start_aistate     ;  // Zustandsgesteuert 

    // **********************     
    // Spawn          
    // **********************     
    VAR STRING spawnPoint      ;  // Beim Tod, wo respawnen ? 
    VAR INT  spawnDelay      ;  // Mit Delay in (Echtzeit)-Sekunden 

    // **********************     
    // SENSES         
    // **********************     
    VAR INT  senses       ;  // Sinne 
    VAR INT  senses_range     ;  // Reichweite der Sinne in cm 

    // **********************     
    // Feel free to use       
    // **********************     
    VAR INT  aivar   [50]   ;      
    VAR STRING wp        ;   

    // **********************     
    // Experience dependant      
    // **********************     
    VAR INT  exp        ;  // EXerience Points 
    VAR INT  exp_next      ;  // EXerience Points needed to advance to next level 
    VAR INT  lp        ;  // Learn Points  
}; 

그런 다음, 당신은 또한 (일부 기본값을 설정하는) 프로토 타입을 정의 할 수 있습니다 : 우선 당신은 엔진 내부의 (클래스 또는 구조)를 반영한다 (이해) 정의 된 클래스가 있습니다. 그러나 실제로 정의 어떻게 NPC는 다음과 같이이다 : 당신이 볼 수 있듯이

instance BAU_900_Ricelord (Npc_Default) //Inherit from prototype Npc_Default 
{ 
    //-------- primary data -------- 

    name  = "Ryzowy Ksiaze"; 
    npctype  = NPCTYPE_GUARD; 
    guild  = GIL_BAU;  
    level  = 10; 
    voice  = 12; 
    id   = 900; 

    //-------- abilities -------- 
    attribute[ATR_STRENGTH]  = 50; 
    attribute[ATR_DEXTERITY] = 10; 
    attribute[ATR_MANA_MAX]  = 0; 
    attribute[ATR_MANA]   = 0; 
    attribute[ATR_HITPOINTS_MAX]= 170; 
    attribute[ATR_HITPOINTS] = 170; 

    //-------- visuals -------- 
    //    animations 
    Mdl_SetVisual  (self,"HUMANS.MDS"); 
    Mdl_ApplyOverlayMds (self,"Humans_Arrogance.mds"); 
    Mdl_ApplyOverlayMds (self,"HUMANS_DZIDA.MDS"); 
    //   body mesh  ,bdytex,skin,head mesh  ,headtex,teethtex,ruestung 
    Mdl_SetVisualBody (self,"Hum_Body_CookSmith",1,1,"Hum_Head_FatBald",91 , 0,-1); 

    B_Scale (self); 
    Mdl_SetModelFatness(self,2); 

    fight_tactic = FAI_HUMAN_STRONG; 

    //-------- Talente --------          
    Npc_SetTalentSkill (self,NPC_TALENT_1H,1); 


    //-------- inventory --------          

     CreateInvItems (self, ItFoRice,10); 
     CreateInvItem (self, ItFoWine); 
     CreateInvItems(self, ItMiNugget,40); 
     EquipItem (self, Heerscherstab); 

     EquipItem (self, MOD_AMULETTDESREISLORDS); 

     CreateInvItem (self, ItMi_Alchemy_Moleratlubric_01); 
     //CreateInvItem (self,ItKey_RB_01); 

     EquipItem (self, Ring_des_Lebens); 

    //-------------Daily Routine------------- 
    daily_routine = Rtn_start_900; 

}; 

FUNC VOID Rtn_start_900() 
{ 
    TA_Boss   (07,00,20,00,"NC_RICELORD"); 
    TA_SitAround (20,00,24,00,"NC_RICELORD_SIT"); 
    TA_Sleep  (24,00,07,00,"NC_RICEBUNKER_10"); 
}; 

는, 인스턴스 선언은 값을 설정하고 내에서 함수를 호출, 더 생성자 함수와 같다. 이것은 여전히 ​​많은 문제를 제기하지 않을 것입니다. 하나 이상의 문제가 아니라면이 인스턴스를 여러 개 복사하십시오. 예를 들어, 여러 개의 BAU_900_Ricelord을 생성 할 수 있으며 각자 자신의 AI 상태, 히트 포인트 등을 추적합니다.

이제는 인스턴스가 int (NPC의 ID로 표시 될 수도 있음) (스크립트 내에서) 표현식 BAU_900_Ricelord을 사용할 때마다 int 변수에만 할당 할 수 있고 NPC에서 작동하는 대부분의 함수는 해당 int 값을 사용합니다. 그러나 직접 hitpoints 등을 수정하려면 var C_NPC npc = GetNPC(Bau_900_Ricelord); npc.attribute[ATR_HITPOINTS] = 10;과 같은 것을해야합니다. 즉, 그것을 나타내는 실제 C_NPC 객체를 얻습니다.

마침내 요약하면 알 수있는 스크립팅 언어에서 이러한 종류의 동작을 얻는 것이 가능한지, 아니면 내 자신을 만들 필요가 있습니까? 아니면 NPC와 그들의 행동을 그렇게 표현하는 더 좋은 방법이있을 수도 있습니다. 저를위한 스크립팅을위한 이상적인 언어는 C# 일 것입니다. 단순히 그 언어를 좋아하지만 어쨌든 C#에서 비슷한 종류의 동작을 시도하거나 구현하는 것이 가능하거나 실제로 가능하지는 않습니다.

많은 감사합니다.

+0

C#은 CLR로 컴파일되므로 일반적으로 "스크립팅"을 위해 사용하면 안됩니다. – alternative

+0

내 명명 규칙을 용서해주십시오.이 경우 스크립트 코드는 엔진 코드의 일부가 아니고 스크립트 코드의 일부가 아니므로 스크립트가 실제로 컴파일 된 경우 더 좋을 것이라고 생각합니다 (DAEDALUS의 경우도 마찬가지 임) –

답변

1

언어로 지원되는 3 레벨의 클래스/인스턴스를 원하지만 실제로는 1 개만 있으면 도움이 될 것입니다.

정적 언어는 일반적으로 컴파일 타임에 정의 된 '클래스'와 런타임에 클래스에서 생성되는 '인스턴스'의 두 가지 레벨을 갖습니다. 이것은 실제로 얼마나 많은 클래스를 미리 알고, 실제로 얼마나 많은 인스턴스가 있는지를 아는 것은 비실용적이라는 것을 알고 있다면 실용적입니다. 클래스는 쿠키 커터가되고 인스턴스는 쿠키입니다.

하지만 궁극적으로 완전히 다른 클래스와 인스턴스의 개념을 제쳐두고 클래스가 (a) 새로운 것들을 생성 할 수 있고 (b) 새로운 것들을 행동해야합니다. 그 차례로 새로운 것들을 창조 할 수도 있습니다.

C++ 및 Java와 같은 언어에서 우리는 일반적으로 (a) 클래스 생성자가 정의한 속성 집합을 사용하여 메모리 블록을 할당하고 (b) 해당 클래스의 메서드 (예 : v-table을 통해). 그러나 그 안에있는 모든 메소드 참조를 포함하여 객체를 복사 할 수 있습니다. 그 중 하나는 객체의 '인스턴스'에 대한 생성자입니다. 이것은 prototype-based programming이며 '클래스'가 인스턴스로 계산되는 새 객체를 만드는 방법을 제공한다는 점을 제외하고는 다른 객체와 완전히 동일하다는 점에서 매우 간단한 상속 모델을 제공합니다.

세상에서 가장 유명한 스크립팅 언어 (아마도 세계에서 가장 유명한 언어)가 프로토 타입 상속을 제공합니다. Javascript는 내가 언급하고있는 것이며 개발자에게 널리 알려지고 오늘날 매우 적극적으로 작업 할 수있는 이점이있는 게임에 퍼가기에 적합한 좋은 선택입니다. 온라인에서 많은 자습서가 있지만 다양한 상속 접근법을 다루는 방법은 here입니다. 특히 익숙해지기까지는 시간이 좀 걸릴 수 있습니다. 특히 클래스/인스턴스 구분이 명확한 기존 OO 백그라운드에서 왔지만 차이점을 배우고 장단점을 평가할 가치가 있습니다.

+0

좋아요! 이것은 내가 찾고 있었던 바로 그 것이다! 감사! –

3

C#을 스크립팅 언어로 사용할 수 있습니다. 외에도 C#을에서

는 루아는 게임 스크립트 언어로 매우 인기가

귀하의 NPC의 예는 다음과 같이 해결할 수

:

  • 는 NPC 클래스는를 만들 상속합니다없는 baseclass의 NPC가 만들기 특정 특성/동작을 가진 맞춤 npc
  • 상속 된 클래스의 인스턴스 만들기
+2

+1 LUA. 그것은 쉽고 효율적이며, 나는 그것을 갈 것입니다. –

+0

네,하지만 모든 NPC가 같은 NPC 클래스의 복사본이기 때문에 NPC 클래스를 상속 받기를 원하지 않습니다. 단지 다른 값을 가지고 있습니다. 내가해야 할 일은 다음과 같은 것이다 : (pseudo-pseudo-code) 'NPC npc = new NPC(); npc.name = "임의의 남자"; NpcMgr.AddNpc (npc, "RndGuy"); ' 다음 여러 인스턴스에서 그를 산란? 음, 어쩌면 그것은 좋은 관리 코드의 경우 일 수도 있지만, 나는 여전히 (그 모든 npc.'를 사용하여 그것을 관리자에게 복사하기 전에 변수에 저장하는 ...) 중복되는 것이라고 느낍니다. 'NPC RndGuy {name = "Random Guy"}' 등등 ... –

+0

미리 작성된 npc를 반환하는 npc 클래스에 정적 함수를 만들 수 있습니다. 예 : 정적 npc CreateBadGuy() {npc baddy = 새 npc(); baddy.name = "나쁜 사람"; baddy.score = 100; 등 반환 baddy; } – Toad

1

자바 스크립트를 사용합니다. Chrome에서 사용되는 V8 자바 스크립트 엔진을 구현하는 게임 엔진에서 직접 작업하고 있습니다.구현하기가 쉽고 Javascript는 완전히 프로토 타입 기반 인 그런 종류의 매우 강력한 언어입니다.

+0

감사합니다! 그 생각은 절대로 나에게 일어나지 않을 것입니다! 나는 그것을 조사 할 것이다 –

+0

나의 엔진을위한 부호를 여기에서 보게 자유롭게 느끼십시오; http://github.com/qard/jsgame 지금은 기본적으로 OpenGL, GLU, GLUT 및 OpenAL을 직접 래핑하는 것입니다. 각 라이브러리를 별도의 전역 개체에 저장하므로 전역을 너무 많이 오염시키지 않습니다. –

관련 문제