C로 게임 엔진을 작성하는 것이 합리적입니까? [닫은]


53

C ++이 왕처럼 보이지만, 내가 들었던 것에서 C는 여전히 게임, 특히 콘솔에서 널리 사용됩니다. 그러나 오늘날 C로 전체 게임 엔진을 작성하는 것은 비합리적입니까? C의 C ++에 비해 어떤 장점이 있습니까? 왜 누군가 C 대신 C ++를 사용하고 싶습니까?


1
콘솔 게임은 c ++ 참고를 사용합니다!
Alan Wolfe

실제로 C는 특정 규모로 게임을 작성하는 것이 더 쉬울 것이라고 생각합니다. 수만 개의 LOC는 주로 복잡한 데이터 유형없이 비트와 바이트에 집중할 수 있고 C ++에 비해 매우 빠릅니다. 그러나 특정 규모 (예 : 수십만 LOC에 도달) 후에 복잡한 데이터 유형, 더 많은 유형 안전, 예외, 템플릿 및 더 큰 데이터를 원하기 시작하는 C ++에 도달하기를 원했습니다. C ++ 이외의 것들이 C 및 C ++ 코드와 결합 될 수 있도록 스케일 (수백만).

또한 C는 ABI에서도 광범위하게 이식 가능하다는 이점을 제공하므로 기존 C 코드를 가져 와서 FFI와 같은 다른 언어로 사용하기가 훨씬 쉬워졌습니다. C ++은 이름 맹 글링, 모듈 경계를 넘어 안전하게 던질 수 없음, vtable rep가 컴파일러마다 동일하지 않음, 공급 업체마다 다른 표준 라이브러리 구현 등을 통해 다소 어색합니다. 규모에 관계없이 글을 쓰려면 시간이 오래 걸리지 만

답변:


49

그러나 오늘날 C로 전체 게임 엔진을 작성하는 것은 비합리적입니까?

합리적이지만 문제는 무엇입니까? C가 제공하는 최고의 이식성이 필요하지 않을 수도 있으며, 실제로 철학적으로 설정하지 않는 한 C ++이 제공하는 모든 기능을 포기하는 것은 부끄러운 일입니다.

C의 C ++에 비해 어떤 장점이 있습니까?

더 나은 컴파일 시간?

왜 누군가 C 대신 C ++를 사용하고 싶습니까?

나는 그것이 미적인 선택이라고 생각합니다. C는 단순하고 최소한이며 깨끗하다고 ​​느끼기 때문에 많은 사람들이 좋아합니다. C ++에는 멋진 기능이 많이 있습니다 (네임 스페이스만으로도 가치가 있습니다).


3
Id Tech 4
안경사

9
@ 조쉬 : 쉽게 디버깅!? C- 프로그램은 주로 포인터와 메모리 관리로 인해 디버그 하기 어렵다 . C ++ 프로그램 (가능한 경우 포인터와 메모리 관리를 피하는 경향이있는 진정한 C ++ 프로그래밍 관용구를 사용하는 경우) 은 디버깅 하기훨씬 쉽습니다 .
BlueRaja-대니 Pflughoeft

14
C는 단순한 필사자 만 이해할 수 있습니다. C ++은 많은 기능을 가지고 있으며 노련한 프로그래머는 매일 10 년 동안 생활에 사용하는 것에 대해 배웁니다.
Jari Komppa

13
C ++은 큰 언어이지만 공포 이야기를 읽었고 배우는 데 시간이 걸리지 않은 사람들이 주로 두려워하는 평판입니다. 배울 것이 많지만 그에 대한 대가로 많은 가치를 얻습니다. C ++을 사용하면 C가 할 수없는 많은 것을 표현할 수 있습니다.
munificent

2
@ BlueRaja-DannyPflughoeft #define malloc(x) my_malloc(x) #define free(x) my_free(x)그리고 당신은 지금 메모리를 디버깅하고 있습니다. C ++를 사용하면 메모리를 할당하는 방법 (신규, malloc, 클래스 생성자 등)이 너무 많기 때문에 언제 할당 될지 알 수 없습니다.
YoYoYonnY

59

여러 제품을 출시 한 순수한 C 게임 엔진과 광범위하게 작업했기 때문에 절대적으로 가능합니다. 다음은 C 엔진과 C ++ 엔진 모두에서 일한 개인적인 경험입니다.

  1. pure-C 구조를 사용하면 구조 정렬에 대한 지식을 활용할 수 있으며이 정보를 사용하여 오브젝트 지속성 및 직렬화 계층을 빌드 할 수 있습니다. 내가 작업 한 엔진에는 구조에 대한이 메타 데이터를 자동으로 생성하는 간단한 헤더 파서가 있었으며 특정 유형의 데이터 작업을 간단하게 만들었습니다. 임의의 C ++ 헤더 파일을 파싱하는 것은 본질적으로 불가능하며 상속 및 가상 함수를 추가하자마자 메모리의 어디에 있는지 정확히 알 수있는 능력을 잃습니다
  2. 헤더 파일을 매우 간결하게 유지하고 앞으로 구조 선언을 활용할 수 있기 때문에 컴파일 시간이 상당히 단축됩니다.
  3. 템플릿과 상속을 사용하지 않고 특정 객체가 무엇이며 무엇을하고 있는지 정확히 파악하기가 매우 쉽기 때문에 디버깅을 개선 할 수 있습니다.

직렬화 된 객체에서 템플릿과 상속을 사용하는 것을 억제하는 제한된 C ++ 코드를 사용하는 것만으로도 이러한 이점을 모두 얻을 수 있었지만 C ++의 더 혼란스러운 요소가 아닌 경우 단순성을 강화하는 것이 더 쉬울 것이라는 CTO의 결정이었습니다. 유효한.

개인적으로 나는 for 루프에서 변수를 선언하는 능력과 상속을위한 많은 합법적 인 용도를 실제로 놓 쳤기 때문에 이것이 약간 극단적이라고 생각합니다. 그러나 실제로 모든 것을 고려할 때 많은 생산성이 필요하지 않았습니다.


5
C에서 상속 구현을 멈추게하는 것은 아무것도 없습니다. C99를 사용하면 for 루프에서 변수를 선언 할 수 있습니다.
jsimmons

15
포인트 3에 동의하지 않을 것입니다. C ++에서와 마찬가지로 C에서 복잡하고 디버그하기 어려운 코드를 작성하는 것이 쉽습니다. 더 나은 디버깅은 C 언어에 내재 된 것이 아닙니다.
Dan Olson

7
C ++에서는 깔끔한 코드조차 이해하기 어려울 수 있습니다. 오버로드, 템플릿, 가상 함수 및 예외로 인해 실제 제어 흐름이 정확히 무엇인지 한눈에 파악하기가 훨씬 어렵습니다.
Kylotan

6
@Dan : 더 많은 것들을 가짐으로써 C ++은 디버깅하기가 더 어렵습니다. 물론 C가되기 때문에 C만큼 디버깅하기가 쉬워진다.

실제로 C를 좋아하는 이유는 더 적습니다. 예를 들어, CI memcpy에서는 유형 시스템이 복사 ctor 및 dtor와 같은 것을 허용하지 않기 때문에 CI에서 a와 함께 비트와 바이트를 복사 할 수 있습니다 . 명시 적으로 반환하지 않으면 함수를 암시 적으로 종료 할 수 없기 때문에 주어진 코드 라인에서 부작용을 롤백 할 필요가 없다는 것을 알 수있는 코드를 작성할 수 있습니다. 예외가 발생하지 않습니다. 이 모든 너무 쉽게 데이터 구조를 작성한다 - 단지 호환 기준 A를 작성하는 C ++에 vector매우 많은 시간이 소요 ... 당신이 그것을 만들고 싶어 특히, 인

18

C ++ 및 Lua로 작성된 2D 게임 엔진을 C 및 Lua로 다시 작성하고 있습니다. 지금까지 경험은 꽤 좋았습니다. 분명히 벡터 및 행렬 연산을 수행하는 것이 C에서 멋지게 보이지는 않지만 C ++ 개발자로 10 년 이상을 보낸 후 경험이 상당히 상쾌하다는 것을 알았습니다.

C는 C ++보다 많은 장점이 있습니다.

  1. 컴파일러는 정적 초기화 시간에 코드가 실행되지 않도록합니다. 따라서 키로 사용되는 문자열과 같은 전역 데이터를 정적으로 할당하는 것이 안전합니다.
  2. 투명도. C 할당에서 변수를 할당하거나 정의해도 많은 코드가 실행되지는 않습니다. C ++은 복사 생성자를 자동으로 생성하므로 할당을 수행 할 때 실행되는 내용을 덜 제어 할 수 있습니다.
  3. 함수 이름이 엉망이되지 않아 디버깅 이 훨씬 쉬워 질 있습니다.
  4. 일반적으로 C에서 memcpy 를 사용하는 것은 좋지만 복사 생성자가 실행되지 않기 때문에 C ++에서 쉽게 문제를 일으킬 수 있습니다. memcpystd :: copy 보다 훨씬 빠르다는 것을 감안할 때 중요합니다.

그 외에도 C 사고 방식에 들어가면 많은 장점이 있습니다. C ++에서 나는 종종 약간 지나치게 일반화되고 추상적 인 것을 스스로 발견합니다. CI에서는 일반적으로 get-set 메소드와 같은 것을 잘라 내고 동적 배열을 사용하는 대신 고정 크기 배열을 미리 할당합니다. 종종 C에서 더 짧고 더 쉽게 디버깅 된 코드로 끝납니다. 데이터 구조는 일반적으로 디버거에서 더 평평하고보기 쉽습니다.

공정하게 말하면 나는 C에서 독점적으로 앱을 만들지 않을 것입니다. 그것이 효과가있는 이유는 C를 매우 잘 보완 할 수있는 Lua와 같은 고급 언어와 결합하여 C가 그렇게 강하지 않았습니다.

Id 소프트웨어는 CI로 대부분의 엔진을 씁니다 . C로 작성된 성 Wolfenstein으로 돌아 가기를 볼 수 있습니다 .

평범한 배열에 비해 C 대 C ++의 확장 성STL 벡터의 단점에 대한 내 경험에 대해 썼습니다 .


11
참고로, 내가 확인 한 모든 인스턴스 (즉, darwin gcc 및 vc2008)에서 std :: copy는 두 유형이 모두 POD 인 경우 memcpy 호출로 컴파일됩니다.
BRaffle

3
또한 RE : STL 벡터 대 일반 배열, 벡터의 멋진 부분을 사용하고 반복자가 아닌 일반 C 포인터를 사용하지 않는 이유는 무엇입니까? & myvector [N] 만하면됩니다. C 코드가 메모리 할당을 동일한 방식으로 수행한다고 가정하면 두 세계에서 가장 좋습니다. 또는 for 루프에서 BOOST_FOREACH를 확인하십시오. C보다 훨씬 간단합니다.
BRaffle

1
std :: copy memcpy에 대한 팁을 주셔서 감사합니다. 나는 몰랐다. 몇 년 전 Alexandrescu가 이것을 치료했을 때는 그렇지 않았습니다. C ++ 반복자 정보 그것은 주로 철학에 관한 것입니다. 저는 C ++이 내가 일하는 사람들을 위해 프로그래밍하는 방법과 C ++ 기능을 활용하는 방법을 프로그래밍하려고합니다. STL 컨테이너와 같은 일부 C ++ 개선 사항이 이전 C 방식으로 수행하는 것보다 항상 낫지는 않다는 것이 주로 지적되었습니다.
Erik Engheim

7

다른 사람이 지적했듯이 C ++은 서있을 수있는 큰 어깨 (BOOST, STL 등)의 이점을 제공합니다. 결국 개인적인 선택이지만 사용 가능한 리소스 때문에 C ++을 선택합니다. C ++에 사용하고 싶지 않은 기능이 있으면 사용하지 마십시오.


1
상용 및 사내 게임 엔진의 99 %가 다양한 이유로 (성능 보장, 디버깅 가능성, 스레드 안전성, 제어) 부스트 및 STL을 사용하지 않습니다.
Kaj

42
통계의 99 %가 구성됩니다.
BRaffle

모든 통계를 인용하는 것이 다소 규칙적인 것 같습니다.
Matt Jensen 2016 년

3

요즘에는 누구나 C를 독점적으로 사용한다고 생각하지 않으며 일반적으로 고급 언어와 혼합되어 있습니다.

C로 프로그래밍하면 C ++로 프로그래밍하는 것보다 몇 가지 이점이 있습니다. C ++ 사용자에게 보이지 않는 많은 작업을 수행 할 수 있으므로주의하지 않으면 성능이 저하 될 수 있습니다. 캐시 사용과 관련하여 C ++ 도 끔찍할 있으며, 이로 인해 성능이 다시 저하 될 수 있습니다.

따라서 전통적인 C ++ 방식이 아닌 C 형 방식으로 게임의 성능 결정적인 부분을 작성하면 이점이 있습니다. 최근 몇 년 동안 실제로 C로 전체 게임을 작성하는 사람에 대해 들어 본 적이 없습니다.

iPhone과 같은 일부 플랫폼에서 C ++를 사용하면 특정 킬로바이트 단위로 실행 파일 크기를 늘릴 수 있습니다 (죄송합니다, 죄송합니다). 이는 일부 iPhone 개발자가 C와 Objective를 혼합하여 코드를 작성하는 이유입니다 -씨.


3

오늘 C ++ 대신 C로 게임 엔진을 작성하는 것이 합리적이지 않은 몇 가지 이유를 더 알려 드리겠습니다 : STL 및 BOOST.

list상자 밖으로 작동하는 코드에 의존 할 수 있고 작성할 필요가없는 또 다른 구현을 작성하는 것이 어떻게 가치가 있는지 상상할 수 없습니다 .


1
큰 스튜디오에서 실제로 부스트를 사용합니까? STL 사용조차도 이식성 때문에 여전히 논쟁 중입니다. 최소한 콘솔 엔진의 경우.
slicedlime

2
개인적으로 저는 c ++ / lua 상호 작용 ( gamedev.net/reference/programming/features/CPPLuaExport/… 참조 )에 Boost.FunctionTypes를 사용 하고 균일 한 난수 생성 (입자 시스템 용)을 위해 Boost 난수 라이브러리를 사용하고 있습니다. 또한 Boost.Foreach는 깔끔합니다. BTW, 누가 큰 스튜디오에서 BOOST를 사용하지 않습니까? 그들은 처음부터 자신의 STL 라이브러리를 작성할 수있는 인력을 가지고 있습니다.
Loris

1
물론 C와 비슷한 라이브러리가 있다는 것도 알고 있습니다.
jsimmons

2
많은 사람들이 게임에서 부스트를 사용한다고 생각합니다. 그러나 그것은 우리 중 많은 사람들의 요구 사항과는 거리가 멀다.
Dan Olson

6
사람들, 당신이 믿는 것은 무의미합니다 : 당신 은 알고 있거나 모르고 있습니다.
o0 '.

3

C로 게임 엔진을 작성하는 것은 합리적입니다. 빠르고 여러 시스템에 이식 할 수 있습니다. 예를 들어 NDK를 사용하여 Android에 사용할 수 있습니다. iPhone에 사용할 수 있습니다 (목표 c는 c의 확장 일뿐입니다). Linux, Mac 또는 Windows와 같은 주요 OS에 사용할 수도 있습니다. c에 익숙하다고 생각되면 시도해보십시오.


2

물론 합리적입니다. 나는 개인적으로 그것을하지 않을 것이고, 내가 알고있는 대부분의 C 팬들은 실제로 C와 같은 코드를 .cpp 파일로 작성합니다. 그러나 언어는 실제로 중요하지 않은 곳과 충분히 유사합니다.

왜 누군가가 이것을하기로 선택했는지에 관해서는 대부분 안티 C ++ 철학에 달려 있다고 생각합니다. 개인적으로 나는 이것이 여전히 "C- 스타일 C ++"보다 C를 선택하는 좋은 이유라고 생각하지 않습니다. typedef struct craziness는 C를 피할 수있는 충분한 이유이며, 다른 많은 것들이 있습니다.

불행히도 C와 C ++는 우리가 다룰 때 상당히 끔찍한 언어입니다. 이것이 사람들이 최근 몇 년 동안 스크립트로 많은 코드를 작성하려고 시도한 이유 중 하나입니다.

C에서 일하는 사람들의 예를 찾고 있다면 오래 전에 C를 버린 것을 읽은 것을 기억하면서 id를 무시할 수 있습니다. Cryptic Studios (Star Trek Online)는 C에서 모든 엔진 개발을 수행합니다. 내가 알 수있는 한, 그것은 어떤 유리한 이점보다 철학 때문입니다.


0

예, 아니오 예, 몇 년 전에 해왔지만 멍청한 터미널의 플레이어가있는 Linux (Linux가 아닌) 64 비트 원격 서버에서 3D로 실행하려면 게임이 필요했습니다. 사소한 것이 아니었다. C는 좋을 수 있습니다. LUA를 통합하고 싶지만 결국 C ++에서 작동하도록 루아를 얻었으므로 가능하다고 말하지만 그렇게하지 마십시오.


0

가능한 좋은 대답이 "둘 다 사용"일 수 있습니까?

내가 panda3d 프로젝트를 최적화 할 수 있다고 들었을 때 일부 cython을 사용하여 병목 현상을 없애거나 해당 부분을 다시 코딩 할 수 있습니다.

대부분의 경우 최적화해야 할 부분은 많은 반복 및 중첩 또는 많은 숫자 컴퓨팅이있는 부분이므로 C를 사용하여 두 언어를 모두 사용하는 것이 공정한 타협은 하나입니다. 많은 저수준 프로그래밍이 포함 된 부품의 경우 속도가 필요한 부분에 대해서는 C ++ 언어를 잘못 사용하고 게임의 나머지 부분에는 C ++을 잘못 사용할 수 없습니다.

이상적으로는 높은 수준을 염두에두고 엔진의 빠른 부분을 수행 한 다음 훨씬 적은 중첩 / 루프를 사용하는 스크립팅 언어 또는 C ++를 사용하십시오.

물론 엔진을 특별한 종류의 게임에 전용으로 사용하는 경우를 제외하고 개발자가해야 할 모든 게임에 적합한 엔진을 만들 수는 없습니다 ...

그러나 경험이 풍부한 게임 개발자 나 경험이없는 개발자가 아니기 때문에 당연한 조언을하지 마십시오. 저는 C가 게임만큼 큰 프로젝트를 위해 좋고 빠른 C ++ 코드를 작성하면서 빠른 코드를 작성하도록 강요한다고 생각합니다 다른 것입니다 ...


0

C는 John Carmack 에서 근무했으며 C 를 사용하면 많은 이점을 얻을 수 있지만 이점을 얻을 때까지 시간이 걸릴 수 있습니다.

여기 에서 C로 작성된 게임 엔진 목록을 찾을 수 있습니다 . 어쩌면 소스 코드를 통해 C 게임 엔진을 수행하는 방법에 대한 통찰력을 얻을 수 있습니다.


0

C 코드는 일반적으로 유효한 C ++ 코드입니다.

C ++의 주요 문제는 그것을 잘못 사용하고 있습니다 ( Linus Torvalds는이 이유로 인해 싫어합니다. 도서관 이식성에 관한 다른 문제가 있었으므로 구매시 운영 체제 수준에서 일하고 있으며 모든 무작위로 작업을 수행 할 수 있어야합니다 거기에 칩).

예를 들어 c ++ std :: vector <> (또는 유사한 컨테이너)보다 cstyle array []를 사용하는 것의 이점은 거의 없습니다.

벡터는 타입 안전하며 경계 검사가 가능합니다 (배열 확인 메소드를 사용하지 않더라도 get () 또는 []를 사용하여 요소에 액세스 할 수는 있지만 포인터로 카트를 옮기지 않고 크기를 쿼리 할 수 ​​있습니다).

그러나 예를 들어 생성자에서 기본 크기를 선언하지 않으면 벡터 가 느려질 있습니다. 벡터에 물건을 추가하면 크기를 조정해야 할 경우 속도가 느려질 수 있습니다. C ++ 11은 균일 한 초기화 (이제 동일한 구문을 사용하여 벡터를 선언하고 초기화 할 수 있음)와 같은 많은 장점을 추가하고 복사를 피할 수있는 이동 생성자가 있습니다. 어떤 이유로 malloc을 사용하지 않고 다른 것을하고 싶다면 자신만의 사용자 정의 이니셜 라이저를 만들 수도 있습니다.

또는 크기를 조정 해야하는 경우에도 벡터를 사용하여 더 쉽게 수행 할 수 있습니다. malloc을 엉망으로 만들거나 수동으로 복사하는 등의 작업을 수행 할 필요가 없습니다.

C ++은 객체 지향 코드를 제공합니다. 컴파일 할 때 코드를 다루는 인간을위한 추상화이기 때문에 효율적입니다. 생성자와 같은 것들로 인해 객체 생성 속도가 느려질 수 있습니다. 그러나 기본값을 설정하려면 생성자가 필요하거나 생성자를 사용하지 않고 (()를 생략하여) 객체를 초기화 할 수 있습니다.

그러나 객체 지향은 프로그래밍 게임을 훨씬 쉽게 만듭니다. 게임은 종종 물건을 다룹니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.