News:

Simutrans.com Portal
Our Simutrans site. You can find everything about Simutrans from here.

The meaning of life minus one

Started by jamespetts, March 13, 2009, 12:04:00 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

jamespetts

I have been testing how the speed is calibrated in Simutrans for the development of Simutrans-Experimental, and thought that people might be interested in the information that I have come up with.

At 10kph, the number of ticks per tile is 41. That is: vehicles travel 1 tile per 4.1 ticks of game speed for every kilometer per hour that they travel.
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

prissi

#1
At which setting for the bits_per_month and show_month? Because those two determine the meaning of "tick". Or do you mean the internal ms?

Otherwise: Straight tile, 255 steps, diagonal 127 steps. Speed is (kph*1024)/80kph=kph*12,8. One step takes 1/4096 speed*ms.

=> kph*12.8/(4096*255) = tiles/ms, that means 8,162s per kmh and tile.

jamespetts

I did mean internal ms. And thank you very much for the information - 4.096 is very close to the 4.1 that I measured. Very useful - thank you :-)
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

jamespetts

Prissi,

I have now written the code for this: I should be very grateful if you could tell me if I am doing anything terribly wrong. The following code is part of the laden() method in simconvoi.cc:


double journey_time = welt->get_zeit_ms() - last_departure_time;
// Manhattan distance
double journey_distance;

if(fahr[0]->get_pos().get_2d().x < fahr[0]->last_stop_pos.x || fahr[0]->get_pos().get_2d().y < fahr[0]->last_stop_pos.y)
{
         journey_distance = (fahr[0]->last_stop_pos.x - fahr[0]->get_pos().get_2d().x) + (fahr[0]->last_stop_pos.y - fahr[0]->get_pos().get_2d().y) * 255;
}
else
{
journey_distance = (fahr[0]->get_pos().get_2d().x - fahr[0]->last_stop_pos.x) + (fahr[0]->get_pos().get_2d().y - fahr[0]->last_stop_pos.y ) * 255;
}
double unadjusted_speed = journey_distance / journey_time;
uint32 average_speed = unadjusted_speed / (12.8 / 4096);


Have I correctly interpreted your mathematics?
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

prissi

Not completely, as diagonals tiles have a different length than normal tiles. Also I am not sure, why you are calculating with the internal steps. THis should be needed nowhere and just bloats up the numbers. Maybe, if you could tell me what you hope to achieve by this, I could give you hints.

And as I said, the actual speed in game depends very much on your setting of bit_per_month and show_month.

jamespetts

Thank you for your reply :-) The reason that I want the average speed is to use as part of the new revenue model in Simutrans-Experimental. The idea is that there will be a new "average speed" graph in the convoy and line windows, and that the speed bonus will be based on the average speed for the previous month (or the current month if not available for the previous month), rather than the vehicle's maximum speed (with the values in speedbonus.tab adjusted accordingly).

Do you think that I should use something other than welt->get_zeit_ms() to obtain the timing data, then? Thank you very much for the offer of hints - much appreciated :-)
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

prissi

I would just suggest to record the last speed between halts as also the last position is recorded. You must be careful, that those numbers survice saving loading (currently they would not). Other than that the fastest possible time is given in the above formula, and empirical factors would be ok too.

For the numbers of tiles driven since last stop you can take the count of route_t -1.

jamespetts

#7
Prissi,

I am aware of the saving/loading position: I have created a special separate system for versioning Simutrans-Experimental saved games that gives a specific Simutrans-Experimental version in addition to the normal version, and I have made sure that the timings and average speeds are indeed loaded and saved.

I am not quite clear on what you mean by "the last speed between halts" here. What I am currently planning to do is something very similar to the present system, where the distance and average speed is calculated for each hop.

Thank you for the suggestion for using the number in route_t - 1; I shall try that and see whether that works better (with the above formula, the speeds all seem far too low). One advantage of using a system of Manhattan distance divided by time, however, is that the lesser number of steps in a diagonal tile would seem to be counterbalanced by the fact of using the Manhattan distance, which would not be true of the route distance. Also, using route_t - 1 would seem not to create a sufficient incentive to create direct routes.

Edit: I have now found a formula that works effectively:


const double journey_time = (welt->get_zeit_ms() - last_departure_time) / 4096;
// Manhattan distance
const uint32 journey_distance = abs(fahr[0]->get_pos().get_2d().x - fahr[0]->last_stop_pos.x) + abs(fahr[0]->get_pos().get_2d().y - fahr[0]->last_stop_pos.y);
const uint16 average_speed = (journey_distance / journey_time) * 20;
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

prissi

There is already a function abs_distance() that takes 2D koordinates and gives their manhattan distance btw ...

jamespetts

Ahh, I didn't realise that. Thank you. But, hmm, in that case, why is it not used in the vehikel_t::calc_gewinn method, where the following code is used instead:


const koord zwpos = ware.get_zwischenziel()->get_basis_pos();
const long dist = abs(zwpos.x - start.x) + abs(zwpos.y - start.y) - (abs(end.x - zwpos.x) + abs(end.y - zwpos.y));


(Or this in older versions, maintained as a comment:)


const long dist = abs(end.x - start.x) + abs(end.y - start.y);


?
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

prissi

BEcause this is older than the method. Historic reasons. I introduced this when I renovated the routefinder.

jamespetts

Ahh, I see :-) I understand now. Thank you.
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.