godot-cpp 10과 Conan으로 Godot에 C++ 라이브러리 붙이기, flecs로 입자 10만 개 시뮬레이션
- godot-cpp 10.0부터 단일 릴리스가 Godot 4.3 이상 모든 버전과 호환됨.
api_version빌드 옵션으로 대상 버전을 고르면 해당 버전 API에서 C++ 클래스를 생성하며, ConanCenter에서 받을 수 있음 - GDExtension은 공식 Godot 빌드에 공유 라이브러리(.dll, .so, .dylib, 웹은 .wasm)를 런타임에 로드하는 방식이고, 엔진 모듈은 엔진 자체를 컴파일해 플랫폼별 편집기와 익스포트 템플릿까지 직접 배포해야 함
- 예제로 flecs ECS 라이브러리를 써서 Godot 씬 안에서 입자 10만 개를 시뮬레이션함. 매 프레임 엔티티 위치를 MultiMesh 버퍼로 복사하는 구조
- godot-cpp는 template_debug, template_release, editor 세 타깃으로 컴파일되고, .gdextension 파일이 debug/release feature tag를 플랫폼별 라이브러리 경로에 매핑함
- Hacker News에서 Linux 배포 시 libstdc++ 버전 문제와 링커 버저닝 스크립트가 필요하다는 지적이 나왔고, 저자가 글에 주의사항을 추가함
Hacker News opinions
Linux에 배포할 거면 버저닝 스크립트 빼먹으면 안 됨. Godot이 쓰는 구버전 배포판으로 빌드하거나 링커 버저닝 스크립트로 심볼을 숨겨야 하는데, 안 그러면 사용자 머신에서 유령 같은 충돌이 남.
맞는 지적이라 글에 주의사항 추가했음. Linux용 확장 배포할 때 꼭 염두에 둬야 하는 부분임.
Rust 쓰면 godot-rust 바인딩이 꽤 좋음. tokio나 async Rust까지 그대로 쓸 수 있고, godot-iroh처럼 iroh로 P2P 네트워킹 하는 예제도 있음.
나도 godot-rust 팬임. Rust 라이브러리 아무거나 Godot에 붙일 수 있는 게 큼.
엔티티 위치를 MultiMesh 버퍼에 복사하는 부분, C++와 Godot 경계 때문에 제로카피가 불가능한 건가?
경계 자체보다는 flecs 데이터를 MultiMesh가 기대하는 레이아웃으로 바꾸는 변환 비용 때문이라고 봄. 레이아웃을 다르게 하면 줄일 수도 있겠지만 완전 제로카피가 가능한지는 확인 안 해봤음.
결국 CMake 스크립트에 파이썬에 괴상한 C++ 코드까지 써야 함. 좀 귀찮지만 그게 현실임. 요점은 호환된다는 거지 권장 방식이라는 게 아님.
Linux에선 libstdc++ 정적 링크하고 -fvisibility=hidden 주니까 해결됐는데, 예외가 경계를 넘어야 할 때 다시 물렸음.
C++로 넘어가기 전에 GDScript나 C# 코드 프로파일링은 뭘로 함? C#은 엔진에 사실상 없어서 Rider나 Superluminal 씀. Godot이 NIH가 좀 심한 듯.
GDScript는 진짜 느림. Lua보다도 느리고, UI 이벤트 처리나 계층 구조 정도에나 쓸 만함. GDExtension에서도 힙 할당이 쉽게 터짐.
RTS 만들다가 GDScript 성능 한계에 부딪혀서 무거운 로직을 C++ 시뮬레이션으로 옮겼음. 귀찮지만 결과는 확실하고, Godot은 메뉴와 대사 처리에만 씀.
왜 C#이 아니라 C++ 씀? C#이 GDScript만큼 편한데. C# 쪽도 플랫폼 제약이 있어서 콘솔은 Native AOT로 안 덮임.
C++26 리플렉션으로 비슷한 걸 만들고 있음. 몇 줄 보일러플레이트로 어떤 언어든 C++ 라이브러리를 수명 안전하게 쓸 수 있게 하는 게 목표임.
Steam에 게임 배포할 때 엔진 모듈 빌드도 선택지가 됨? 아니면 GDExtension이 표준임?
GDExtension이 표준 가는 길임. 다만 커스텀 Godot 빌드도 흔하고 배포에 문제 없음. 암호화된 빌드를 만들려면 직접 빌드해야 함.
C++ 런타임은 ABI 때문에 공유 라이브러리로 못 내보냄. 배포판 libstdc++ 버전과 충돌하니까 정적 링크하거나 버저닝 스크립트를 써야 함. API가 C 기반이면 문제 없음.