Here is a Todo list related to technical enhancements of the code
Teleport() is called whenever Tux has to go from one level to an other one. However,
when Tux is only crossing a level's boundary, this is not a real "teleporting" (mainly because
Tux goes from one level to one of its neighbor).
For example, in standard Teleport, we have to:
And in specific Teleport, we have to :
Once done, we can remove all the calls to reset_visible_levels() that are executed just before calling Teleport()
Additional note: It seems that after Tux crossed a level's boundary, there is some glitch in the computation of Tux's speed. To be checked...
When the lightbonus of a level is set to 0, then the level is not lighted. This is due to the following test in calculate_light_strength(): -> "if (light_sources[i].strength == 0) break"
This test is used to find the end of the light_sources list. Replacing the end of list value by "-1" should avoid that bug.
At each frame, a list of light sources is built. This list contains "static" light sources (obstacles emitting light) and "dynamic" ones (Tux and bots).
The static light sources are found by browsing all obstacles on all visible levels, at each frame. This is evidently sub-optimal.
A list of static light sources could be added to the level struct. This list can be built, for example, when a level becomes visible.
When a bot is wandering along waypoints, it stores the next waypoint to reach in a "nextwaypoint" attribute. The "nextwaypoint" is defined by an index in the list of the current level's waypoints.
After a bot has crossed a level's boundary (for example when the bot is hunting an enemy), the "nextwaypoint" value does then no more points to the right waypoint, the bot will then not get back to its old position, and moreover the bot can also traverses all its current new level in order to try to reach the new waypoint now pointed by "nextwaypoint".
Several solutions here:
This function is called many many times per frame. It could be worth to avoid calling normalize_vect(), which is quite CPU costly.
Virtual gps positions
Blitting list generation
In order to sort-insert an object inside the blitting list, resolve_virtual_position() is called before the norm's computation. During the rendering of this object, resolve_virtual_position() is called a second time, to compute the position where to render the object (the blitting list only stores the object's index).
Proposition: store a gps or a moderately_finepoint inside the blitting list.
Since we remove level interfaces, a great bunch of calls to update_virtual_position() / resolve_virtual_position() was added. Thus, there should be a lot of calls to transform exactly the same position. This has to be checked by storing the parameters of each call, in a file (for one unique frame), sort that file, and count duplicate lines.
If it is found that it would be worth optimizing it (profiling could be needed, here), the idea could be to:
However, it should be first checked if all the fdrpg code can be changed so that it only uses virtual positions defined relatively to Tux's level. If not, it's eventually possible to store virtual positions defined relatively to all visible levels.
Colldet (DLC) optimization
Since an obstacle can be several tiles wide, and since an obstacle is only stored in one tile (the tile containing the center of the obstacle), the DLC algorithm has to scan an area that is also several tiles wider than needed. This is ever worst for SLC. DLC/SLC being called many many times per frame, it's worth optimizing them.
The optimal code would be a line-tracing algorithm, to only scan the tiles traversed by the line (here, a 4-connected derivative of Bresenham would be needed). However, it then needs a change in the way we associate obstacles to tiles, so that each tile has a reference to all obstacles contained by this tile.
Additional note: When DLC is called by the pathfinder, it computes the intersection between the obstacles and a wide-line. This wide-line is simulated by artificially enlarging the bounding-box of the obstacles. So, a special care of this trick has to be taken.
Bullets collision detection
If a line-tracing algorithm is used in DLC, we can also use it to replace the current bullet collision detection.
Indeed, a collision detection based on line-tracing will be able to easily return the nearest object in collision, and that's exactly what is needed for bullets.
To be adapted since level interfaces were removed
The following section described several things that should be adapted or changed due to the removal of the level interfaces
This function checks if Tux or a bot is near enough to a door to open it.
However, the code does only take into account characters that are on the same level than the door.
If a door is very near a level's border, then the code does miss the characters on the neighbor levels that could potentially be near enough to open the door.
The game currently does not have an actual animation system. This means it is difficult to control exactly when and how the frames of an animation are displayed. fluzz will have to elaborate on this...
For various scripting and storytelling purposes, it would be very useful to have events occur after a certain arbitrary delay. This can be done through a function that takes two arguments: a number of seconds, and arbitrary lua code. There are two main ways this issue can be approached:
The first method may lack accuracy and is affected by the framerate (an issue on weaker systems), while the second one is less reliable and may have strange side effects. We'll have to see what suits our needs.