I have recently received from a friend the Macintosh game Civilization IV. I’m a regular fan of this kind of games, and from time to time I dust of my old copy of Alpha-Centaury to play a game.
The problem of Civilization IV was visible on the requirements on the box: it requires a G5 or a newer intel processor. This is quite a steep requirement for a turn based game. I can understand that a RTS or are FPS game would require some serious processing power and a good graphic card, but a turn based game?
Still I installed the game, downloaded the latest version and ran it. The game ran reasonably fine (it crashed once), but was unbearably slow. Why? My laptop is by far no powerhouse, Rise of Nations, a RTS with 3D effects ran perfectly fine. Civilization IV also includes some eye candy, like a three dimentional view, but nothing that impressive and nothing justifying the absurd processing requirements. OK, units are animated and so are the rivers and the sea. Now can I turn it off and play?
Actually I don’t even understand the need to run in full-screen mode and re-implement a windowing system with panes and all the stuff. It makes no sense to have an RTS where you can still use your e-mail program or chat with friends, but a turn based game? The fact they even added the option to display a clock in the interface is an indication of the way people play. In the case of Civilization, the people at Fireaxis have reimplemented a window system and done a shoddy job of it – basically the interface runs slower than Java applications.
The internals of the game are partially written in Python, I don’t know to what extent the fact that a scripting langage is used can be blamed for the bad performance. When the game crashed, I got a stack trace, that revealed some strange stuff: what the hell is going on in the RaiseException
function?
0 | com.aspyr.civ4 | 0x009d0074 | _ZNSt14__tree_deleterISt4pairIKPKvmESt20__base_value_compareIS2_mSt4lessIS2_EESaIS4_EE7destroyEPNSK_4nodeE + 1019616 |
1 | com.aspyr.civ4 | 0x00074004 | RaiseException + 263364 |
2 | com.aspyr.civ4 | 0x00074f48 | RaiseException + 267272 |
3 | com.aspyr.civ4 | 0x00a05cb0 | _ZNSt14__tree_deleterISt4pairIKPKvmESt20__base_value_compareIS2_mSt4lessIS2_EESaIS4_EE7destroyEPNSK_4nodeE + 1239836 |
4 | com.aspyr.civ4 | 0x009fd300 | _ZNSt14__tree_deleterISt4pairIKPKvmESt20__base_value_compareIS2_mSt4lessIS2_EESaIS4_EE7destroyEPNSK_4nodeE + 1204588 |
5 | com.aspyr.civ4 | 0x0006e27c | RaiseException + 239420 |
6 | com.aspyr.civ4 | 0x00a05edc | _ZNSt14__tree_deleterISt4pairIKPKvmESt20__base_value_compareIS2_mSt4lessIS2_EESaIS4_EE7destroyEPNSK_4nodeE + 1240392 |
7 | com.aspyr.civ4 | 0x00074ce8 | RaiseException + 266664 |
8 | org.python.python | 0x98a8c8e0 | PyObject_Call + 48 |
9 | org.python.python | 0x98aec35c | PyEval_GetFuncDesc + 2268 |
10 | org.python.python | 0x98aebd4c | PyEval_GetFuncDesc + 716 |
11 | org.python.python | 0x98ae9414 | PyEval_EvalCode + 9612 |
12 | org.python.python | 0x98aebedc | PyEval_GetFuncDesc + 1116 |
13 | org.python.python | 0x98aebd34 | PyEval_GetFuncDesc + 692 |
14 | org.python.python | 0x98ae9414 | PyEval_EvalCode + 9612 |
15 | org.python.python | 0x98aebedc | PyEval_GetFuncDesc + 1116 |
16 | org.python.python | 0x98aebd34 | PyEval_GetFuncDesc + 692 |
17 | org.python.python | 0x98ae9414 | PyEval_EvalCode + 9612 |
18 | org.python.python | 0x98aea5e4 | PyEval_EvalCodeEx + 2132 |
19 | org.python.python | 0x98aa1530 | PyFunction_SetClosure + 3436 |
20 | org.python.python | 0x98a8c8e0 | PyObject_Call + 48 |
21 | org.python.python | 0x98aeb9a0 | PyEval_CallObjectWithKeywords + 256 |
22 | com.aspyr.civ4 | 0x00244810 | RaiseException + 2165968 |
23 | com.aspyr.civ4 | 0x00243f0c | RaiseException + 2163660 |
24 | com.aspyr.civ4 | 0x00243864 | RaiseException + 2161956 |
25 | com.aspyr.civ4 | 0x004e2b00 | RaiseException + 4911040 |
26 | com.aspyr.civ4 | 0x004e0330 | RaiseException + 4900848 |
27 | com.aspyr.civ4 | 0x004e1d78 | RaiseException + 4907576 |
28 | com.aspyr.civ4 | 0x0045d430 | RaiseException + 4364528 |
29 | com.aspyr.civ4 | 0x004e5a28 | RaiseException + 4923112 |
30 | com.aspyr.civ4 | 0x0073e854 | RaiseException + 7384340 |
31 | com.aspyr.civ4 | 0x0073e01c | RaiseException + 7382236 |
32 | com.aspyr.civ4 | 0x0073e0a0 | RaiseException + 7382368 |
33 | com.aspyr.civ4 | 0x006ebd5c | RaiseException + 7045660 |
34 | com.aspyr.civ4 | 0x006da4c8 | RaiseException + 6973832 |
35 | com.aspyr.civ4 | 0x006e70c0 | RaiseException + 7026048 |
36 | com.aspyr.civ4 | 0x006e72b0 | RaiseException + 7026544 |
37 | com.aspyr.civ4 | 0x00629960 | RaiseException + 6250016 |
38 | com.aspyr.civ4 | 0x0061f028 | RaiseException + 6206696 |
39 | com.aspyr.civ4 | 0x00492500 | RaiseException + 4581824 |
40 | com.aspyr.civ4 | 0x0023d954 | RaiseException + 2137620 |
41 | com.aspyr.civ4 | 0x004e009c | RaiseException + 4900188 |
42 | com.aspyr.civ4 | 0x00002664 | 0x1000 + 5732 |
43 | com.apple.HIToolbox | 0x931ea554 | DispatchEventToHandlers(EventTargetRec*, OpaqueEventRef*, HandlerCallRec*) + 692 |
44 | com.apple.HIToolbox | 0x931e9cac | SendEventToEventTargetInternal(OpaqueEventRef*, OpaqueEventTargetRef*, HandlerCallRec*) + 372 |
45 | com.apple.HIToolbox | 0x931e9b28 | SendEventToEventTargetWithOptions + 40 |
46 | com.apple.HIToolbox | 0x931f0e9c | ToolboxEventDispatcherHandler(OpaqueEventHandlerCallRef*, OpaqueEventRef*, void*) + 704 |
47 | com.apple.HIToolbox | 0x931ea7a4 | DispatchEventToHandlers(EventTargetRec*, OpaqueEventRef*, HandlerCallRec*) + 1284 |
48 | com.apple.HIToolbox | 0x931e9cac | SendEventToEventTargetInternal(OpaqueEventRef*, OpaqueEventTargetRef*, HandlerCallRec*) + 372 |
49 | com.apple.HIToolbox | 0x931f0a60 | SendEventToEventTarget + 40 |
50 | com.apple.HIToolbox | 0x932317a0 | ToolboxEventDispatcher + 92 |
51 | com.apple.HIToolbox | 0x9323172c | HLTBEventDispatcher + 16 |
52 | com.apple.HIToolbox | 0x9322fce4 | RunApplicationEventLoop + 148 |
53 | com.aspyr.civ4 | 0x00002714 | 0x1000 + 5908 |
54 | com.aspyr.civ4 | 0x000028a4 | 0x1000 + 6308 |
55 | com.aspyr.civ4 | 0x00002184 | 0x1000 + 4484 |
56 | com.aspyr.civ4 | 0x00001fb4 | 0x1000 + 4020 |
As today, the “scripting language” terminology is not a valid one anymore.
Fact is that the EVE Online game is mostly Python and is quietly fast. I do not know what they have done with Civ4 but I agree that it is a heavy ressource hog, and not a stable one. Don’t know why, really.
EVE Online is using a modified version of python though, stackless python, which is quite efficient. I don’t know what kind of python VM is used in Civ IV. I think python is used for all the application logic, 3d rendering is usually still good old C++
http://www.eve-online.com/faq/faq_07.asp