Koala 엔진은 ECS (Entity Component System)로 완전히 구현 된 게임 엔진입니다.
엔진은 ENTT를 기반으로합니다. EnTT 사용하는 다른 소프트웨어와의 통합은 간단해야합니다. 이 문서는 적어도 EnTT 와 그 용어 ( entity , registry , handle ...)에 대한 기본 지식을 가정합니다.

예제 프로젝트는 핵심 기능 중 일부를 보여줍니다. 반사 및 런타임 확장 가능성에 대한 엔진의 지원이 무엇을 제공 해야하는지에 대한 아이디어를 제공해야합니다.
엔진은 git 서브 모듈을 사용하므로 재귀 적으로 복제해야합니다.
git clone https://github.com/phisko/kengine --recursive
엔진은 MSVC 및 Mingw를 사용하여 Windows에서 테스트되었습니다.
Linux 컴파일은 GCC와 작동합니다. 글을 쓰는 시점에서 Clang은 C ++ 20의 constexpr std::string 및 std::vector 지원하지 않습니다.
엔진에는 C ++ 20 컴파일러가 필요합니다.
엔진은 2016-17 년에 열정/학생 프로젝트로 시작했습니다. 내 친구/동료들과 나는 처음부터 EC를 구현했습니다. 우리는 절대적인 유형의 안전과 명확성을 원했고, 이미 템플릿 메타 프로 그램을 사용했지만 이것은 우리가 그것에 대해 더 많이 배울 수있는 기회였습니다.
핵심 ECS가 작동하면 엔진은 게임 개발에 대해 더 많이 배우기 위해 놀이터로 바뀌 었습니다. 나는 OpenGL 렌더링, Recast/Detour와 함께 NavMeshes를 사용하는 방법, 총알을 사용하여 물리학을 설정하는 방법을 배웠다.
지금은 엔진에서 5 년 이상 일한 후 핵심 EC 자체가 더 이상이 프로젝트의 초점이 아니라는 것을 깨달았습니다. 다른 라이브러리, 특히 EnTT 훨씬 더 고급 기능을 갖춘 매우 유사한 API를 제공합니다. 그래서 나는 내부 EC를 완전히 내장하고 EnTT 로 교체하는 데 시간이 걸렸습니다. 모든 기능은 동일하게 유지되며, 이는 다른 EnTT 프로젝트와 함께 일할 수있는 유용한 도우미를 작업 할 수있는 시간을 더 많이 줄 것입니다.
엔진의 많은 부분 (스크립팅 시스템 또는 Imgui Entity 편집기)이 putils 의 반사 API를 사용합니다. 따라서 다음 샘플의 대부분의 구성 요소는 반사 가능한 것으로 정의됩니다.
엔진 코드는 세 가지 범주로 구성됩니다.
systems 특정 클래스의 객체가 아닙니다. 시스템은 단순히 실행 구성 요소가있는 엔티티 (또는 작업을 수행하는 데 필요한 다른 것)입니다. 그런 다음 엔티티는 나머지 게임 상태와 함께 registry 에 살고 있습니다. 이를 통해 사용자는 다른 엔티티와 마찬가지로 시스템을 내성적으로 지정하거나 동작을 추가 할 수 있습니다.
이 세 가지 범주는 다양한 라이브러리로 나뉩니다.
일부 라이브러리에는 서브 라이브러리가 포함되어 있습니다.
CMAKE 섹션은 이러한 라이브러리와 함께 작업하는 방법에 대해 자세히 설명합니다.
엔진에는 게임을 부트 스트랩하는 데 사용될 수있는 (상당히 많은) 사전 구축 구성 요소가있어 또는 단순히 자신의 구현을 기반으로 할 수있는 예제로 제공됩니다.
이 구성 요소는 세 가지 범주에 적합합니다.
데이터 구성 요소는 엔티티에 대한 데이터를 보유합니다.
데이터 구성 요소는 변환이나 이름과 같은 구성 요소를 생각할 때 처음으로 떠오른 것입니다.
데이터 구성 요소는 때때로 기능을 유지할 수 있습니다.
함수 구성 요소는 함수를 쿼리, 변경 또는 엔티티에 알릴 수 있습니다.
함수 구성 요소는 단순히 엔티티에 구성 요소로 연결될 수있는 팬츠의 보유자입니다. 이 정비공은 다음에 사용될 수 있습니다.
함수 구성 요소는 Base_Function에서 상속되는 유형으로 기능 서명을 템플릿 매개 변수로 제공합니다.
함수 구성 요소를 호출하려면 operator() 또는 call 기능을 사용할 수 있습니다.
entt::registry r;
const auto e = r.create();
r.emplace<main_loop::execute>(e,
[]( float delta_time) { std::cout << " Yay! " << std::endl; }
);
const auto & execute = r.get<main_loop::execute>(e); // Get the function
execute ( 0 .f); // Call it with its parameters
execute.call( 42 .f); // Alternatively메타 구성 요소는 구성 요소의 구성 요소입니다.
엔진은 "유형 엔티티"를 사용하여 사용중인 다양한 구성 요소에 대한 정보를 유지합니다. 각 유형 엔티티는 다른 구성 요소 유형을 나타내며 런타임에서 구성 요소의 속성을 쿼리하는 데 사용할 수 있습니다.
메타 구성 요소는 이러한 "유형 엔티티"에 연결되며 해당 특정 유형에 대한 일반 기능 구현을 보유합니다. 함수를 가지고 있기 때문에 함수 구성 요소와 매우 유사합니다.
예를 들어, 메타 :: imgui :: edit은 호출 될 때 주어진 엔티티에 imgui를 사용하여 "부모 구성 요소"의 속성을 그릴 메타 구성 요소입니다. 다음 코드는 e '의 이름 구성 요소를 편집 할 창이 표시됩니다.
// r is a registry with the "type entity" for `name` already setup
const auto e = r.create();
r.emplace<core::name>(e);
const auto type_entity = type_helper::get_type_entity<core::name>(r);
const auto & edit = r.get<meta::imgui::edit>(type_entity);
if (ImGui::Begin( " Edit name " ))
edit ({ r, e });
ImGui::End ();이를 일반화하면 다음 코드로 엔티티의 모든 구성 요소를 편집 할 수 있습니다.
// r is a registry with the "type entities" for all used components already setup
// e is an entity with an unknown set of components
if (ImGui::Begin( " Edit entity " ))
for ( const auto & [type_entity, edit] : r.view<meta::imgui::edit>()) {
edit ({ r, e });
}
ImGui::End ();각 라이브러리 활성화 방법에 대한 지침은 CMAKE를 참조하십시오.
generate_type_registration python 스크립트가 제공되며, 이는 엔진에 주어진 유형 세트를 등록 할 함수를 포함하는 C ++ 파일을 생성하는 데 사용할 수 있습니다.
이것은 절대적으로 의무적이지 않습니다 .
엔진은 CMAKE를 빌드 시스템으로 사용합니다. 라이브러리 생성을 단순화하기 위해 맞춤형 프레임 워크가 마련되었습니다. 루트 cmakelists는 하위 디렉토리를 반복하여 몇 가지 조건과 일치하는 경우 라이브러리로 자동으로 추가합니다.
기본 kengine 인터페이스 라이브러리가 생성되어 모든 활성화 된 라이브러리와 링크되어 클라이언트가 단순히 이와 관련하여 연결될 수 있습니다.
다음 CMAKE 옵션이 노출됩니다.
KENGINE_TESTS테스트를 구현하는 라이브러리의 테스트 실행 파일을 컴파일합니다.
KENGINE_NDEBUG디버그 코드를 비활성화합니다.
KENGINE_TYPE_REGISTRATION엔진 유형에 대한 유형 등록 코드를 생성합니다. 이는 메타 구성 요소의 구현을 제공하므로 많은 엔진의 반사 기능의 핵심입니다.
KENGINE_GENERATE_REFLECTION엔진 유형에 대한 반사 헤더를 업데이트합니다. 이들은 사전 생성되므로 엔진의 소스 코드를 수정하지 않으면 활성화 할 필요가 없습니다.
원치 않는 종속성을 구축하지 않도록 모든 라이브러리는 기본적으로 비활성화됩니다. cmake 옵션을 ON 으로써 각 라이브러리를 개별적으로 활성화 할 수 있습니다. 옵션 이름은 라이브러리 이름을 참조하십시오.
또는 KENGINE_ALL_SYSTEMS 옵션으로 모든 라이브러리를 활성화 할 수 있습니다.
서브 라이브러리는 부모 라이브러리가 활성화되어야합니다. kengine_imgui_entity_editor는 kengine_imgui가 필요합니다.
라이브러리는 엔진 루트에 대한 상대 경로에 따라 이름이 지정됩니다. 경로의 슬래시는 단순히 밑줄로 대체됩니다.
kengine_corekengine_imgui_tool이 이름은 다음과 같습니다.
kengine_core 용 KENGINE_CORE )kengine_core 매크로 KENGINE_CORE_EXPORT 사용C ++ 정의 매크로 덕분에 편집하는 동안 라이브러리의 존재를 테스트 할 수 있습니다. 이것들은 cmake 옵션과 동일한 이름을 가지고 있습니다.
# ifdef KENGINE_CORE
// The kengine_core library exists
# endif일부 라이브러리는 종속성 관리를 위해 VCPKG를 사용합니다.
루트 CMakeLists.txt 에 의해 라이브러리가 자동으로 감지되므로 새 라이브러리를 만드는 것은 매우 쉽습니다.
라이브러리는 kengine_core 에 대해 자동으로 연결됩니다. 모든 라이브러리 (예 : log_helper 및 proficing_helper)에서 사용해야하는 도우미를 제공하기 때문입니다.
서브 라이브러리는 부모와 자동으로 연결됩니다. 예를 들어 Kengine_imgui_entity_editor는 Kengine_imgui와 자동으로 연결됩니다.
라이브러리의 helpers 및 systems 의 소스 파일이 자동으로 추가됩니다. 아무것도 발견되지 않으면 라이브러리는 CMAKE 인터페이스 라이브러리가됩니다.
유형 등록 및 반사 코드는 구성 요소에 대해 자동으로 생성 될 수 있습니다. 기본적으로 라이브러리의 data 및 functions 하위 디렉토리의 모든 헤더는 Generation Scripts로 전달됩니다.
소스 파일과 마찬가지로 *.tests.cpp 파일이 있으면 라이브러리의 helpers/tests 또는 systems/tests 하위 디렉토리에있는 경우 Googletest 실행 파일이 자동으로 추가됩니다.
CMakeLists.txt 기본 라이브러리는 소스 파일이 자동으로 이루어 지므로 자체 CMakeLists.txt 가 필요하지 않아야합니다. 그러나 라이브러리에 사용자 정의 동작이 필요한 경우 (예 : 추가 소스를 추가하거나 타사 라이브러리와 연결하기 위해) 자체 CMakeLists.txt 추가 할 수 있습니다. 이 CMakeLists.txt add_library 로 호출 후 호출됩니다.
다음 변수와 함수는 CMakeLists.txt 호출하기 전에 정의됩니다.
kengine_library_name : 라이브러리 이름kengine_library_tests_name : 라이브러리의 Googletest 대상 이름link_type : 라이브러리의 링크 유형 (소스가 발견되었는지 여부에 따라 PUBLIC 또는 INTERFACE )kengine_library_link_public_libraries(libraries) : 다른 라이브러리에 대한 링크 (공개)kengine_library_link_private_libraries(libraries) : 다른 라이브러리에 대한 링크 (개인적으로)register_types_from_headers(headers) : 유형 등록 및 반사 헤더가 생성 될 수있는 헤더를 추가합니다.subdirectory_is_not_kengine_library(path) : root CMakeLists.txt 에 path kengine 라이브러리로 처리해서는 안된다는 것을 나타냅니다.