Is it possible to simplify your rendering - as that might now be eating significant time in the speed up mode (to get to your 5400X)
Is the game already threaded with the graphics on a seperate thread and working on a once (interval) copied snapshot of the game situation so the simulation only need to wait briefly for that atomic copy (should be fast and maybe only copy the render related data if that is faster)
the game is currently single threaded. one loop for drawscreen, doinput, and move_everything. the game is framerate limited to 15 frames per second. i know, 15 fps seems slow. and it is. its the slowest you can go, and still get sufficiently responsive input and smooth enough animation. so its the speed at which you'll have the maximum possible number of milliseconds (66 2/3) per frame to draw stuff and simulate stuff. and lord knows, none of us has enough frame time. even cheating to get 66ms vs 33 ms at 30fps, i'm still pressed for what i want to usually accomplish.
multi threading has not yet been considered due to keeping system requirements to a minimum for maximum compatibility. right now a directx 9 capable pc is the only system requirement - not even QueryPerformanceCounter is a requirement (yet).
it doesn't get a screen dump and then just display that. it draws the scene. once per game minute - once every 900 iterations of the main game loop, hence the 900x speed. it does 900 "turns" of input and simulation, then draws a frame. same idea for the 5400x speed, one frame drawn per game hour (once every 5400 main loop iterations). a screen dump would be faster, but then you couldn't watch the world go by in time lapse photography mode like you do now.
It sounds like you are running exactly the same simulation calculations which will result in exactly the same results as if it was run at normal speed (and it doesnt sound like its abstractable to simplify the simulation calculations)
correct. it turns off the frame rate limiter, allowing the simulation scream at full throttle. then it just draws the screen once every 900 turns, where a "turn" is one iteration of the main game loop, and represents 1/15th of a second of game time.
as for an abstraction, that may be possible. i was doing the same thing in another title the other day (a flight sim). any idea how long it takes to fly to a target 1000 miles away in an airship that does 47 mph? <g>. there i was using 100x and 1000x speeds. but it still wasn't fast enough. so i did an approximation. there it was easy, just moving a single target a long way until it gets close to something. just draw the chronometer showing mission time passing. before you know it, that 13 hour flight to target is done, and its time to lower the observation car and bombs away! accelerated time is an absolute must in any simulator. unless its one of those "real time" sims - log in once a day, water your virtual pet kind things.
but abstracting the AI would much more difficult here. you have predatory, stand your ground, and maintain distance behaviors all going on at once. and all of those use wandering and flocking as well as targeting and combat behaviors. so approximation of results is much more difficult.
in the airship sim, i didn't have to recalculate the density of helium given the altitude and temperature 15 time a second to approximate flying across europe, the way it does when running in real time. all i had to do was move the ship based on current orientation and airspeed, and check for range to targets, then fixup the altitude etc when they dropped back to real time speed. in the caveman sim, an average approximation could be done. IE given some mix of critters, on average who will have eaten whom after some given period of time. but it would not yield the same results as running the simulation in real time with full AI and modeling, the way the airship approximation does.
What kind of sensory scanning do your objects do (adjacents only ?? a box search ? something more comples)
there is no chess board like map for targets. so no map based searches such as adjacency or box search apply. targets are stored in a sparse matrix, IE a target list. sensory scanning consists of looping through the target list looking for nearby targets of interest. and nearby means looping through the list again for each target to get range. thus the (O)n^2 (or whatever it crunches out to) kinda thing going on.
How is the edge of map endcase handled. There are some tricks to get rid of the XY tests needed when doing object sensor scanning which can simplify the objects calculation some. (I had a guy doing A* change to have a boundry edge of cell blocked status to eliminate the x<0 x>maxx y<0 y>maxy that had to be tested on all the adjacency tests and for a box check it is setting the XY loop limits once instead of inside the loops
not an issue yet. environments are mostly outdoors with just trees or big rocks to navigate around. so no A* yet. just bang and turn, no avoidance or anything. works ok for now. they still kill you plenty quick (you die a LOT in this game!) <g>. i've already gone though the code and pulled all non-essentials out of the loops. about all i found was one lookup call to terrain_visual_range() that returns the max visual range based on intervening vegetation coverage (you can see far in the desert and not far in the jungle).
Depending on the complexity of the behaviors here - the old method called the Big Switch inside the main game turn object loop which flattens out
the program alot can eliminate a great deal of processing overhead. Of course it depends on how your simulation is run whether that would actually be multiple processing loops per turn (sensor+decision phase, action phase, action resolution phase).
you mean something like this?
void move_animals()
{
int a;
for (a=0; a<maxanimals; a++)
{
if (!animal[a].active) continue;
if (!animal[a].alive) continue;
if (animal[a].suprised) continue;
setstate(a);
runstate(a);
}
}
void setstate(int a)
{
int t;
t=animal[a].type;
if (animal[a].defend_location) defend_location_setstate(a);
else if (animal[a].state==FRIENDLY) friendly_setstate(a);
else if (animal[a].state==HOSTILE) hostile_setstate(a);
else if (animaltype[t].AI==ATTACK_AI) attack_setstate(a);
else if (animaltype[t].AI==MAINTAIN_DISTANCE_AI) maintain_distance_setstate(a);
else if (animaltype[t].AI==DEFEND_AI) defend_setstate(a);
else all_others_setstate(a);
}