➟ Go back to September 2008.
➟ Proceed to November 2008.
| In these blog entries, you will find information on the things that I am currently working on. Whatever you read in recent entries does not necessarily describe things that are available for public download. The sole purpose of this blog is to inform you about the progress on development which will eventually - that is, in the future - result in an actual release of those features. Do not mistake this blog for a changelog. |
After some more tests have been conducted regarding the new loading mechanism, some changes have been made to the sound subsystem and the scoring.
Version 0.8.9.0 has been made available today as the hopefully last intermediate release before 0.9. To be honest, the road between 0.8 and 0.9 was expected to be around three weeks, while it is appearing to be slightly more than two months now.
The viewing distance was previously neither saved nor loaded in the main menu, which has been fixed now. I have additionally spotted a bug concerning the automatically generated normals for cylinders. As it appears, the cylinder is always flat, indicating that the normals are not applied correctly. I have not found the reason yet, but will look into it.
A severe bug has been detected which forced the program to crash when passing a station at which one should have stopped. A bugfix version 0.8.9.1 has been made available.
A have taken a deeper look into the current cylinder problems. As it appears, the normals were correctly computed. However, the light illuminated the cylinders from the opposite direction. I was able to realize that it was in fact the global light direction which was reversed all the time. The fact that this went unnoticed for so long is simply due to the fact that the normal computation for regular polygons reversed the direction of the normals, canceling those two bugs out in most cases. There have been some reports about wrong colors in X object files, which can be probably attributed to this as X files can specify normals explicitly. Either way, I have corrected the reversed directions now.
I also noticed that if cylinders approximate pyramids, smooth shading fails to work. As it appears, there is some sort of a leftward twist in the lighting contribution measured from bottom to top. Additionally, while the top and bottom interpolate nicely, the area in-between can exhibit very different colors on either side of an edge. I was about to blame the vertex normals again, but could not find a problem with them. Then I noticed that the tesselation of the side polygons was slightly visible and conducted an experiment: I manually tesselated the polygons into triangles. As a polygon with four vertices can be tesselated in two distinct ways into two triangles, I tried both of these possibilities and realized that one of them resulted in a leftward color twist and the other one in a rightward twist. My conclusion is that OpenGL does not handle shading correctly for primitives other than the triangle as its underlying mechanisms obviously tesselate the polygon into triangles. The only way I can currently think of of getting rid of the twists would be to tesselate each side polygon of the cylinder into four triangles so that symmetry can be achieved along the vertical axis. However, I have currently no intents to do so as the effect only occurs if the lower and upper radii in the cylinder commands are very distinct or if one of them approaches zero. Most of the times though, the cylinder command is being used to create prisms, which are unaffected of the behavior described. And if flat shading is being used instead of smooth shading, every works as expected.
In the case the folder indicated by Structure.Signal in route files could not be found, the route parser previously crashed. This has been fixed now and an error message is generated instead.
When I played around with lighting in the last few days, I changed the default ambient and diffuse lights for easier debugging, but did not change the values back for subsequent releases. As such, previous versions used different default lighting conditions than usual, which could cause some routes to appear too dark or otherwise different. The bugfix release 0.8.9.3 fixes this back to the usual conditions.
The in-game menu has been implemented as a simplistic, scrollable menu, controllable via up/down keys, return and escape in the default configuration. Jumping the train to other stations is possible now. While it technically works and signalling appears to be correct even when jumping back and forth, ahead of the previous train and so on, some adjustments will still need to be made to various train settings in order to allow for the plugins and the scoring system to work as intended.
The @Height command in RW routes is now processed a little differently than the CSV counterpart. Apparently, BVE implicitly adds 0.3 to every height command, and as such, the initial absolute height for RW routes is 0.3, which was not previously employed by openBVE. Additionally, the digital indicator used in the panel.cfg, which I assumed was left-aligned, has been changed to being right-aligned, given that the image is wider than the clip to be extracted.
The behavior of the deceleration parameter in the train.dat has been changed to reflect the maximum service brake pressure instead of the maximum emergency brake pressure, which was the previous behavior.
Some additional changes have been made to default values used in the train.dat parser. As some trains using the automatic air brake have unrealistic combinations of main reservoir maximum pressure and brake cylinder maximum pressure, the more realistic behavior of openBVE's brake system simulation either forced trains to tremendously slowly release brakes in such a situation, or to operate the brakes with lower pressure than the design pressure, depending on the normal brake pipe pressure as configured by the parser. I tend to use a reduced brake pipe pressure now in these cases as otherwise, the trains exhibiting those settings were basically unplayable as the brakes did not release in any acceptable amount of time. As such, the brakes will now release quicker but cannot operate at their design pressure whenever the brake cylinder pressure is greater than the minimum main reservoir pressure, leading to weaker brakes. Of course trains properly configured will not expose such problems and are unaffected. Either way, the normal brake pipe pressure can now be explicitly configured in the train.dat.
A new AI is currently being created, internally dubbed the BetterHumanDriverAI, compared to its predecessor, the SimplisticHumanDriverAI. The newer one has some sort of a memory and remembers its observations on resulting acceleration for every power and brake notch. As such, it can even decide to apply power when it actually wants to decelerate, for example on an incline. The new heuristics are also being complemented with more random behavior and personality, giving different results on each run. Smooth acceleration and deceleration near zero speed are also employed for more passenger comfort. I also want to affect the driving style based on station lateness and other factors, resulting in a more human behavior depending on the circumstances. Currently though, the new AI is only able to brake for speed and signal limits and does not do much else yet.
I have spot that the temporary ATS-P speed limit restriction as previously implemented does not work like that in BVE. While I assumed it to be a transponder affecting the train from the point the train passes it, in BVE, the train instead brakes to the speed limit so that upon passing the point, the limit is already reached. I have changed the behavior now. In addition to that, the ATS-P brake curve has been further remodeled. Another change is that I decided to make the motor brake as strong as the physical brake as the train.dat does not distinguish between the two as for the deceleration parameter. As such, the motor brake force was too weak on some trains, while I guess that it will now be too strong on others.
For older RW routes, the AtsSn, AtsP and PLimit commands have been implemented now. Even though they are undocumented, BVE 2 still supports them and as it seems, my implementation is about all right. The Work parameter in Track.Transponder (or Track.Tr) commands is now also supported after I finally found out what it does.
The new AI has an interesting kind of memory now. While it is able to observe the acceleration output for all power and brake notches, it is able to plan in advance which one will be best to use. Nonetheless, I think that for the time being the old AI will suffice and I am going to work on the more important things due to time constraints.
Full support for translations is in progress. I have adjusted all in-game messages to work with the new system and have completed the Start a new game section of the main menu.
Support for RW route comments (descriptions) has been added. Additionally, as I have spot that the simulation starts at 00:00:00 for routes which do not employ an explicit arrival time for the first station, I have changed the starting time to derive from the departure time for these cases.
There where some people who initially offered their help for developing openBVE, which I reclined as I did not and still do not need any assistance for programming. In the case those people felt useless, I have now put up a new bug tracking page on the homepage which will give anyone interested something to do in order to speed up fixing compatibility issues before version 1.0 can be released.
Translation support has been added to the Review last game and Customize controls sections, as well as to the loading dialog.
Translation support is now also available within the Options section. If I did not miss anything, then support for translation should be complete now.
Forced stop signals used by some stations whenever the departure time is not yet reached where previously assigned for all signals from the beginning of the station up to the beginning of the next station. This has now been changed to the first signal after the stop point only in order to make stations which employ signals within the station area work as intended.
Track.RailStart has been given an additional error message compared to Track.Rail if the rail to be started already exists. In the main menu, an import and export feature has been added for the control setup, allowing to easily save the configuration to external files or load from them. Furthermore, effective sound ranges have been slightly reduced.
Fixed a bug related to the processing of the Cycle.Ground(idx).Params command.
Version 0.9.0 has been released today. As the new AI is not yet complete, it is not included in this release.
I have decided to devote some time to investigating an X file interpretation ambiguity issue. In DirectX object files (X files), meshes are associated mesh materials. A mesh material basically defines attributes like colors and textures and employs a list telling to which faces of a mesh the material should apply to. I have observed that some files containing, say four faces, often use one material, but instead of assigning that material to all four faces, they only assign it to one face, leaving the other three faces without an assigned material. The Microsoft specification does not explicitly say what should happen in such cases and instead leaves this open to interpretation. As such, all faces which are not assigned a material are currently rendered as solid white, which from my point of view, is a faithful implementation. However, in order to increase compatibility with existing BVE material, I am going to investigate how BVE (or actually DirectX) handles such cases. I expect to reproduce the behavior for most cases, but am confident that I will be unable to achieve reproduction for all cases.
My first conclusions. If a mesh contains exactly one mesh material list, which in turns contains exactly one mesh, the situation is quite straight forward. All faces are assigned that material, whether they have been explicitly flagged to use this material or not. This is a very common situation encountered with X files in existing BVE material. However, I went a little further. When using one mesh material list containing two or more materials, the situation becomes ridiculous. Of course all faces explicitly assigned a material will have that material. All others though either copy one of the two or more materials or are assigned pure white. If not white and one material is selected, the behavior is rather random. And with random I do not mean only unpredictable, but I mean random, as in randomly generated. The behavior is in fact different each time you load the object! I guess that the folks at Microsoft are in fact absolutely uncapable of writing a solid parser. Either way, given this result I am not investigating the situation any further. Theoretically, one could also try to analyze what happens if two or more mesh material lists are used, each containing one or more materials. But I am stopping here. For all faces not explicitly assigned a mesh, I will simply use the first material encountered and will properly document the behavior for my X file specification. As said, usually, either all faces in existing X files are explicitly assigned, or only one mesh material list with one mesh is being used, which seems to create an unambiguous result, and adding support for that will certainly suffice.
The Keisei route, and also the ATS-Sn/P Test Line route, in which I have observed problems with X files, are now rendered properly and look quite good. However, I am spotting more and more incompatibilities regarding form and crack geometry. Obviously, my reverse engineering conducted a few months ago was all but successful. BVE Trainsim is in fact a black box. Whatever happens inside is completely shielded to the outside world, including developers, who struggle to produce content for it. As with X files, I am confident that I will be able to improve compatibility, but am more than certain that I will not be able to reproduce BVE's behavior to 100 percent. Either way, the new X format behavior is available with 0.9.0.1.
Due to negative feedback, I have changed the motor deceleration behavior back to the old implementation which bases the maximum amount of motor deceleration on the peak acceleration at either of the power notches.
I have spot one more interoperability issue regarding Linux/Mac support. Previously, while file name case insensitivity was provided by openBVE, I had missed to add the required code to the train.dat parser. As such, the train.dat was being searched for case-sensitively, which could render some trains unplayable. I have changed this now and also searched the whole source code again for more case-sensitivity problems. I could not find any further ones.
I still don't know on which values BVE Trainsim bases the motor deceleration. The deceleration value as set in the train.dat is definately too high for some trains, while even the peak acceleration from either power notch is too low. I have made a compromise for the time being and have now set the motor deceleration to be half-way between the brake deceleration and the peak acceleration. Furthermore, I have observed that the notifications for fly-by normal and zooming have been reversed on more time, which is now fixed.
I have added a few more size-variations of the image used for the handle indicators. The language configurations can now specify reverser, power, brake, single handle, doors and security system lamp indicators individually in order to match the length of the texts used.
I am currently reworking the functions UpdateCar and UpdateCarSectionElement in TrainManager.cs which are used to move, rotate and change states of car objects (e.g. needles, exterior and so) and calculate the absolute world coordinates and orientations for all polygons employed. The rework is long overdue as the functions still use 2D vector + pitch geometry which was used before I decided to rework everything into full 3D vector geometry. Additionally, these functions execute function scripts associated to the objects in order to obtain the state to be displayed, the angle to rotate by, etc. I have decided to do this now for multiple reasons. First of all, the current architecture only allows one function script to be associated to an object, thus either state change, rotation, movement, etc., while for version 1.1, I need arbitrary combinations of those. The second reason is that currently, rotation does not employ any damping. In BVE panels, cab elements can be configured to use under-damped and over-damped oscillation. The latter one is currently simulated via adding some arithmetics to the rotation function script, but is susceptible to imprecisions on low frame rates which can cause elements like wipers or clock needles to suddenly jump around in an uncontrolled fashion. The former one, under-damped oscillation, is currently not possible at all. By reworking the code, I am thereby also adding support for these kinds of oscillation directly without needing to detour to modifications in the function scripts. The rework simplifies many of the calculations employed and will increase performance. So far, state changes are the only thing that work again, while all other things, like rotation (needles etc.), are disabled at the moment.
Rotating car elements have been integrated again, as well as LEDs. As I have been reported a slightly different behavior of the ATC system compared to BVE Trainsim, I have reworked some parts of it. To be more precise, the first Track.Limit command in front of the train is being looked for so that the ATC system can brake the train as to have achieved the imposed speed limit by the time the train passes the point where the command is placed. Previously, ATC would only start to brake when passing that point.
As I have redistributed some DLL files without permission of the proprietors up to now, I am currently preparing a release which is free of such material, asking users to download it themselves. The preparation of the removal of this material and writing the required download instructions for users wasted around 6 to 8 hours of my precious time.
Version 0.9.0.5 has been released today as the first version which is distributed with binaries that have been solely written by myself. Some icons have also been removed from the public distribution.
I have changed the behavior of the SetSignal function which is called to inform plugins about the state of the upcoming section. The previous behavior was to call SetSignal whenever a section had been passed by the train. Now, it is also called whenever the upcoming section changes its aspect. This allows trains to receive updates without the need of beacons. Some routes require this sort of "continuous transmission" in order to work correctly, which was not previously the case. I could also get the Tokyo Metro Hanzomon Line to finally work thanks to this change.
The black box has been added the state of the reverser. Additionally, I have corrected my previously wrong interpretation of the sound array handling in the Elapse call made to train plugins. While I needed to previously suppress the first Elapse call regarding processing the sound array, I do not need to do so any longer as the sounds seem to perfectly work now.
I spent nearly all work on increasing the plugin compatibility. The Track.Beacon command is now handled differently when its section parameter is set to -1, which will now always reference the next red section if there is any. Additionally, the Track.PointOfInterest command has been expanded to include a customizable message which is displayed whenever moving to the point.
I tested lots of routes and fixed some minor things to release 0.9.0.10 today. Besides that, nothing much did happen.
The behavior of SetSignal has been further adjusted. In addition to that, I have worked on the compatibility transponder objects. Some of them are now a little more detailed and do not use alpha transparency any longer, but screendoor transparency in order to increase performance.
The Track.Stop command has been expanded to account for different amount of cars. A station can thus have more than one Track.Stop command now. This makes the same route usable with trains of different length. Additionally, the Track.Buffer command has been added which represents a buffer stop in the route with which the train can collide. Besides these additions, a bug in the signal subsystem has been fixed, which was initialized incorrectly when a preceding train was present in the route. The bug could cause a signal to suddenly jump to red, simply because that was the desired initial state, but incorrectly initialized to something else before. Furthermore, the EB system will now only be active when traveling above 15 km/h, where previously, it would also be active even when standing still.
I have changed the behavior of the SetColor, SetEmissiveColor and SetTransparentColor commands in the B3D/CSV parser. Instead of applying the data to all faces in the mesh, the commands will now only affect the faces that were already created, leaving subsequent faces at their defaults. Finally, I enabled full-screen motion blur in the main menu after I made some adjustments to the rendering procedure. Now, the effect seems to work on all systems, while it previously crashed on some. The performance impact will of course vary from system to system. On my primary test computer, it is about 10 percent. There are currently three intensities selectable, which will still need their fine-tuning.
The compatibility signals, signal posts, speed posts, stop posts and transponders will now be affected by the Track.Brightness command so that these objects will appear darker in tunnels etc instead of at their full brightness. The damping for the clock needles in BVE 2 panels has been adjusted a bit so that the needles converge faster. I have also included default lighting conditions now, even though they are not the same as in BVE.
Not much happened today. However, I have added some more checks to the train.dat parser in order to detect invalid arguments.
I made some slight changes to the beacon-plugin interaction regarding SetSignal and SetBeaconData calls.
I have changed the behavior of the pattern renewal and immediate stop transponders for ATS-P slightly. If they reference a section after the immediately following one, but the immediately following one is red, these transponders will be inactive in order to not interfer with the brake curve for the immediately following signal. Besides that, I spent much time on writing documentation, namely parts for the CSV route file and tutorials regarding the proper use of transponders.
There was a bug with the brake control systems (lock-out valve and delay-filling control) which prevented non-motor cars from applying their air brakes when traveling above the brake control speed, which resulted in weak brake performance. The bug has been fixed now.
Slight adjustments have been made to the scoring system which will now penalize overspeed and station lateness less intense than before. Furthermore, the AtsPluginProxy.dll has been updated and will now try to call LoadLibraryA if LoadLibraryW previously failed. This makes plugins available on Windows without support for Unicode, such as Windows 95/98/Me.
A bug with the accurate object disposal has been fixed. Previously, the starting and ending track positions for an object were not calculated correctly because object rotation was not taken into account. This could cause an object to disappear even when still in visible range, which defeated the purpose of accurate object disposal.
Transponders created via Track.Tr (Track.Transponder) and beacons created via Track.Beacon are now unified. This means that the built-in security systems are also fed by Track.Beacon commands and that likewise, the plugins are also fed by Track.Tr commands. This seems to be the way BVE Trainsim does it, and thus has been changed this way to improve compatibility, even though the scenario of mixing those commands is not widely employed. As for signalling, any departure signal of a terminal station will now stay red for the player's train.
The BVE 4 signal glow texture loading procedure has been refined. First of all, pure white is now preserved in textures, while previously, pure white became transparent. Second, the current blur algortihm has been changed to a pure box blur algorithm with variable radius, currently set to 4 pixels.
I have started to reorganize the way polygons are stored. Instead of storing all attributes like color, emissive color, transparent color, blend modes, etc. for every polygon, I am trying to use an object-oriented approach to store only those attributes that are actually needed. Hopefully, this will reduce memory requirements considerably, but I am expecting a performance impact. As such, I do not know yet whether I will actually keep this new approach, but will need to make performance tests once conversion is complete. Source code adaption will take a while though and I have only achieved a small part so far.
A bug in the X file parser has been corrected which did not process empty lists in text files correctly.
I finalized the code changes regarding the way polygons are internally stored. I now have SolidColorPolygon, TexturedPolygon, ScreendoorPolygon and ComplexPolygon classes instead of a single Polygon structure. Surprisingly, I did not encounter performance differences on neither of my three test systems, nor any reductions in memory consumption.
I have profiled the executables of the current development version using the object-oriented approach to store polygons and an older version, and my observations seem to hold. Both versions have a nearly equivalent memory footprint. To compare: A single SolidColorPolygon in the new approach consumes 9 bytes plus vertex data plus .NET object and GC overhead, while the previous implementation consumed 29 bytes per polygon plus vertex data regardless of the type of the polygon. It seems that the overhead due to object-orientation and GC heap defeats the savings entirely, which is something I do not fully understand giving the difference of 20 bytes per polygon.
Due to the fact that the new approach is much harder to maintain code-wise, I will revert back to the old implementation, which makes the last three days mainly a waste of time. Although, I learned how to save 2 bytes of the previous 29 bytes per polygon, making the new requirement only 27 bytes. Congratulations.
➟ Go back to September 2008.
➟ Proceed to November 2008.
|
|