I see that there has been a great deal of discussion on this since I last had time to look at this thread: my apologies. Thank you very much to all those who have contributed to this discussion, especially Ranran for the coding and design work.
Consist ordersI think that it is better for basic/default reversing not to require explicit consist orders. This is for a number of reasons. Firstly, as Ranran points out, this requires quite a lot of overhead for what should be a simple and default operation. Secondly, the basic design of the consist orders feature is that it should be possible (and indeed normal) for these to be blank (i.e. a NULL pointer), only containing any data where the player explicitly specifies this. This would be unworkable for reversing, which is a default behaviour. Thirdly, where trains reverse is not always determinable in advance, as it is possible (for example) that changes made by a player to the track layout whilst a convoy is running its schedule will affect whether a train needs to reverse at any given station. Even without this inherent indeterminacy, there would be a very large amount of computational overhead (and coding work) to operate and devise an algorithm that could reliably predict where a train would have to reverse.
We will have to take into account reversing when working on the consist order feature. I believe that we already have a datum for whether a convoy is reversed or in its default direction. So long as we have an algorithm that can extract from the current consist order and its reversed datum what its forward order is, it is possible to apply consist orders to trains either in the forward or reverse direction without having reversing as a consist order in itself. It is noteworthy that reversing is in principle an issue for consist orders, however, and this issue will need more careful consideration when that feature comes to be coded.
Front/rear cabs and the "bidirectional" parameterI believe that I have briefly addressed some of these issues in the other thread about the basic coupling constraints. This is a useful idea. I can see that this does have the potential to improve the sophistication with which various rail vehicles are specified in paksets.
One query about the question of whether a vehicle is bidirectional: in the UK, there was for a time a rather well known train (the LNER "Coronation") running with an observation saloon at the end of it like this:

Obviously, this carriage has to be:
(1) at the back of the train; and
(2) facing in the right direction
for each trip. What would happen in reality is that, at each end of the journey (from London to Scotland), the carriage would be detached from the back of the train, turned on a turntable, and attached to the other end of the train for the return trip. We have one of these carriages in Pak128.Britain, and at present it is marked as "bidirectional=0", which simply forces the whole rake to turn around in a similar way to what happens in Simutrans-Standard, which is the current intended behaviour of setting bidirectional=0 (the vehicle can only face in one direction). How is this meaning of bidirectional=0 intended to be accommodated in the new reordering system?
I note incidentally Vladki's comment on the topic of bidirectionality, and this does seem sensible in principle and consistent with the original intention of this datum.
One comment about the symbol for brake vans. The current system of constraints allows for brake vans or brake carriages that require some specific vehicles (usually passenger carriages) to be placed before them. This is normally the case in Pak128.Britain-Ex for brake ended passenger carriages. Some brake carriages (such as passenger full brake carriages or goods brake vans) do not require any particular thing (or anything at all) before them. I wonder whether this might be represented in the symbols by coding the former type to have the same end shape as an intermediate carriage on the left, and the brake ended symbol on the right? This would clarify how these brake ended carriages are intended to work, I think.
Names for the .dat file parametersI can see that an explicit reference to a driver's cab may potentially be misleading, especially for very modern driverless trains. Perhaps "allow_at_front" together with the existing "can_lead_from_rear" might suffice - or is there some role for the existing "can_lead_from_rear" datum that you envisage that is distinct from your new driver's cab settings? The "can_lead_from_rear" parameter was always intended to be used specifically where the rear of a train had a driver's cab or some other means of being able to reverse without reordering the consist at all, so it is not immediately clear that a new parameter on top of this for a rear cab should be needed.
Brake vans/guard cabsI note Vladki's comments about brake vans and what he describes as "guard cabs" (this phrase is not used in relation to UK railways, but may well be a translation of a term that is used on railways in other parts of the world).
The position in relation to brake vans is actually quite complex. Before automatic brakes, trains used to have a brake on the locomotive (usually the tender of a steam locomotive) and one or more brake vans or carriages in the train. One of these brake vans or carriages would normally be at the back of the train so that the guard could know whether the train had divided and see along the whole length of the train. It was also better to apply the brakes at the very rear of the train before applying them in the locomotive so that the couplings of the wagons/carriages behind the brake van did not become loose and run into the brake carriage. This was more important for freight wagons with chain couplings than for passenger carriages with screw couplings, although very early passenger carriages actually had chain couplings (usually with more links than the late 19th century and later standard of three links). Passenger trains, which travelled at higher speeds and therefore needed more brake force, would often have two brake carriages (giving three braked vehicles in the train including the locomotive), and the other brake carriage might be in the middle or at the front of the train, and would be staffed by an "under-guard". However, in the early days, this practice was not universal: in the mid-19th century, for example, the London and South-Western Railway routinely put a single brake carriage in the middle of passenger trains and none at the end.
After the introduction of continuous braking, under guards were abolished, and trains would generally have one guard, who would travel in the rear brake carriage. It was normal for trains to have brake carriages at the front and rear of the train, and for the one at the front of the train to be unoccupied. If a train split on its route, each portion of the train would normally have a front and rear brake carriage. Indeed, the Board of Trade preferred trains to have a brake carriage at each end so that passengers had some buffer zone against a collision, although they seemed to tolerate the practice of adding extra carriages ("swingers" as they were sometimes called) to the ends of trains, usually without an additional brake carriage, to deal with high demand during busy periods.
In modern times (from circa the 1960s/1970s onwards), the idea that the guard's compartment should be at the back of the train was significantly relaxed, and trains started having only a single carriage with a guard's compartment, as here:
47653 18 6 89 1 by
dave gommersall, on Flickr
or here:
Indomitable by
RobT653, on Flickr
In more modern times (the 1980s/1990s onwards), trains without any guards at all started emerging, which reduced the staffing cost considerably.
There may be something to be said for giving some consideration to how we deal with brake carriages/vans more carefully. One thing that we need to be able to do is work out how many guards are on any given train so as to work out what the staffing cost should be for them (this is not currently done). In particular, we need to be able to distinguish between:
(1) old trains, where every brake carriage had to have a guard, and only brake carriages had any brake force (this is easy);
(2) intermediate era trains, where all carriages have equal brake force, and the whole train has only one guard; and
(3) modern trains, where all carriages have equal brake force and the train has no guard.
Case (2) is perhaps the most challenging. Currently, we deal with the requirement to have a brake carriage at the end of the train simply by using specific constraints for each type of carriage. This is very arduous to code and is very prone to error, but it has the advantage at least of keeping like carriages with like carriages. It does not provide any way of calculating the number of guards for which a player should be paying for any given train, however.
An alternative approach would be to code this more abstractly: but if one were doing that, one would need to be able to specify more clearly which carriages were compatible with which other carriages in abstract terms, and this would require the same sort of more sophisticated coupling constraint (parameters for vacuum brake, air brake, Clark & Webb chain brake, electric train heating, steam heat, etc.) as discussed some months ago on the basic couple constraint thread, and is similar to the constraint group idea proposed by Ranran. If vehicle compatibility were thus defined, the question of what vehicle must be at the rear of a train is fairly easy to solve by simply providing vehicles that cannot be at the rear with the very simple "next[0]=any" constraint as currently used for goods wagons. For the economic purpose of working out how many guards should be required, one would add a single additional parameter "single_guard_cost". This would, if set to a non-zero value, add this amount to the fixed monthly cost of the whole train, but would not do so more than once even if multiple carriages were set with this parameter. In the case of multiple carriages with a different non-zero cost, the mean average would be taken.
The older trains which have guards present in every vehicle with a brake force can be dealt with using the existing code by simply giving these vehicles a higher fixed cost to represent the cost of the guard. Likewise, modern vehicles that require no guard can simply be set not to have a higher fixed cost. One additional thing that might be useful to allow more modern train formations is a parameter that requires a train to have one vehicle somewhere with a "single_guard_cost" parameter that is non-zero, but it does not matter where in the train that this is situated. This would be part of the algorithm for determining whether a train is in a valid formation. One simple way of doing this is to have a .dat file parameter, "requires_guard"; if any vehicle on the train has this as 1, at least one vehicle on the train must have a non-zero "single_guard_cost", or a vehicle otherwise marked as having a guard by the requires_guard parameter being -1 (but set in the .dat file by a more user friendly method, a parameter "has_guard=1", which would then be encoded as requires_guard=-1). One question that I have yet to resolve is how this could be represented to the player in the UI. Perhaps Ranran might have some ideas as to this?
I do not think that a maximum brake distance parameter is helpful; for trains that do not have continuous brakes, this is unnecessary as, in the current code, the train will just have to go very slowly so that it can brake in time for the next signal that might be at danger, which is a penalty enough. For trains that do have continuous brakes, this is not sufficient, as the braking distance is not relevant to whether the train has to have a guard at all (and accommodation for a guard).
Reversal algorithmVladki's ideas are interesting, but may need some revision to take into account what we actually do with brake carriages/vans as discussed above. We may need to finalise this before exploring Vladki's algorithms in detail, although an initial overview of them looks promising (although I am not sure why the front vehicle should be rotated even if it is bidirectional).
We will, especially when convoy re-combination is implemented, have to be able to cope with situations such as this:

or this

In both cases, these units would reverse without any re-ordering.
As I believe discussed in the thread on the basic couple constraint, I believe that there is already a flag indicating whether a train is in forward or reverse orientation. This should be retained.
I agree with Vladki that we do need to be able to accommodate double headed trains; I believe that the existing algorithm does this, albeit as hard coded special case.
Next/prev constraints and reversingThis is an interesting question raised by Ves. Currently, on reversal, the next/prev constraints are not affected in any way, and the formation is technically invalid, but this does not matter, as the validity of the formation is checked only in the depot, and a vehicle is automatically re-ordered to its forward state whenever it enters a depot.
With convoy re-combination, this may need to be reconsidered. There are two possible solutions: either automatically reverse the effect of next/prev constraints (and this may require some complexity: I have not calculated all the permutations of this) when a train is reversed, or, using the flag to determine whether the train is reversed, produce a copy of the train, re-order that to the forward direction and then check that copy when considering validity This will need to be considered with some care before we progress much further with the convoy recombination work.
Rendering issuesThis is a complex and extremely challenging issue. There are standards for how vehicles should be aligned in this pakset, and they were produced when this alignment did not matter because there was no code for reversing some vehicles but not others. Actually re-rendering every single rail vehicle in the pakset would take many years of work and is not feasible in the foreseeable future.
One possible solution is to have a reverse offset: a certain number of pixels in the x and y directions in which vehicles in a pakset (or a specific vehicle) are shifted in each of its 8 orientations if marked as reversed. I am not sure quite how difficult that this would be to code, and it would take a considerable time to calibrate, but it is likely to be less work than re-rendering the whole pakset. I have not looked into this in any detail to assess the viability.
I am grateful to Ranran for pointing out this unfortunate issue. I am not sure whether any other paksets (Pak256.Ex?) are or are not affected by this.
Constraint groupsThis is definitely a good idea in principle. May I suggest that this should work in a more similar way to the way constraints to create more abstract constraint classes to allow for things such as vacuum braked vehicles being unable to couple to air braked vehicles or unbraked vehicles, but being able to couple to other vacuum braked vehicles or vehicles that have both vacuum and air brakes fitted? There may also be some sense in separating the front/rear constraints so that, for example, a vehicle with vacuum brakes requires another vacuum braked vehicle in front, but can connect to an unbraked vehicle in the rear, to make up a partially fitted train (as was common in 20th century goods trains, for instance).