Orthogonal Income Patch
Moderator: OpenTTD Developers
- SquireJames
- Tycoon
- Posts: 1863
- Joined: 07 Aug 2004 11:56
- Skype: squirejames5
- Location: Stoke-on-Trent
- Contact:
Re: Orthogonal Income Patch
This will still result in the age old "nothing competes with Airlines" especially in Multiplayer.
Re: Orthogonal Income Patch
Yes. But it is not my fault, that game is addicted to airplanes. I have some ideas, how to balance it, but this thread is not about.SquireJames wrote:This will still result in the age old "nothing competes with Airlines" especially in Multiplayer.
I need little advice, how to query available to everyone, already introduced and not expired engine.
I tried to use
Code: Select all
FOR_ALL_ENGINES(e) if (e->flags & ENGINE_AVAILABLE)
but seems that it returns all engines available for certain climate, not only those available for current date.
Is it any easy way to query engines which can be purchased by any company?
Formerly known as: McZapkie
Projects: Reproducible Map Generation patch, NewGRFs: Manpower industries, PolTrams, Polroad, 600mm narrow gauge, wired, ECS industry extension, V4 CEE train set, HotHut.
Another favorite games: freeciv longturn, OHOL/2HOL.
Projects: Reproducible Map Generation patch, NewGRFs: Manpower industries, PolTrams, Polroad, 600mm narrow gauge, wired, ECS industry extension, V4 CEE train set, HotHut.
Another favorite games: freeciv longturn, OHOL/2HOL.
- planetmaker
- OpenTTD Developer
- Posts: 9432
- Joined: 07 Nov 2007 22:44
- Location: Sol d
Re: Orthogonal Income Patch
The build vehicle code must obviously know, so look there: (build_vehicle_gui.cpp:1120). This will build the actual list of available engines. It's a method of the build vehicle window (similar exist for other vehicle types):McZapkie wrote:Yes. But it is not my fault, that game is addicted to airplanes. I have some ideas, how to balance it, but this thread is not about.SquireJames wrote:This will still result in the age old "nothing competes with Airlines" especially in Multiplayer.
I need little advice, how to query available to everyone, already introduced and not expired engine.
I tried to useCode: Select all
FOR_ALL_ENGINES(e) if (e->flags & ENGINE_AVAILABLE)
but seems that it returns all engines available for certain climate, not only those available for current date.
Is it any easy way to query engines which can be purchased by any company?
Code: Select all
void GenerateBuildRoadVehList()
{
EngineID sel_id = INVALID_ENGINE;
this->eng_list.Clear();
const Engine *e;
FOR_ALL_ENGINES_OF_TYPE(e, VEH_ROAD) {
EngineID eid = e->index;
if (!IsEngineBuildable(eid, VEH_ROAD, _local_company)) continue;
if (!HasBit(this->filter.roadtypes, HasBit(EngInfo(eid)->misc_flags, EF_ROAD_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD)) continue;
*this->eng_list.Append() = eid;
if (eid == this->sel_engine) sel_id = eid;
}
this->sel_engine = sel_id;
}
Code: Select all
bool IsEngineBuildable(EngineID engine, VehicleType type, CompanyID company)
(I didn't know by heart either. Usage of the xterms and editor's grep function quickly gives the answer. Make use of it I simply started to grep the whole source for 'purchase' )
OpenTTD: manual | online content | translations | Wanted contributions and patches
#openttdcoop: blog | wiki | public server | DevZone | NewGRF web translator
DevZone - home of the free NewGRFs: OpenSFX | OpenMSX | OpenGFX | Swedish Rails | OpenGFX+ Trains|RV|Industries|Airports|Landscape | NML
Re: Orthogonal Income Patch
I know about this routine, but it need to put CompanyID.planetmaker wrote:It seems to use IsEngineBuildable (engine.cpp:1046). This checks availability for each engine:McZapkie wrote: Is it any easy way to query engines which can be purchased by any company?Code: Select all
bool IsEngineBuildable(EngineID engine, VehicleType type, CompanyID company)
I need to know every engines potentially available for any company, even if no company is established.
Should I use OWNER_DEITY?
Formerly known as: McZapkie
Projects: Reproducible Map Generation patch, NewGRFs: Manpower industries, PolTrams, Polroad, 600mm narrow gauge, wired, ECS industry extension, V4 CEE train set, HotHut.
Another favorite games: freeciv longturn, OHOL/2HOL.
Projects: Reproducible Map Generation patch, NewGRFs: Manpower industries, PolTrams, Polroad, 600mm narrow gauge, wired, ECS industry extension, V4 CEE train set, HotHut.
Another favorite games: freeciv longturn, OHOL/2HOL.
- planetmaker
- OpenTTD Developer
- Posts: 9432
- Joined: 07 Nov 2007 22:44
- Location: Sol d
Re: Orthogonal Income Patch
Availability *does* differ between companies. The preview is given only to one company. And that can build that vehicle one or two earlier than anyone else.McZapkie wrote:I know about this routine, but it need to put CompanyID.planetmaker wrote:It seems to use IsEngineBuildable (engine.cpp:1046). This checks availability for each engine:McZapkie wrote: Is it any easy way to query engines which can be purchased by any company?Code: Select all
bool IsEngineBuildable(EngineID engine, VehicleType type, CompanyID company)
I need to know every engines potentially available for any company, even if no company is established.
Should I use OWNER_DEITY?
Also: if you're interested in existing and possibly existing vehicles, availability does not necessarily cut it: vehicles may be not available anymore - but they might still roam the tracks, road, air and oceans.
OpenTTD: manual | online content | translations | Wanted contributions and patches
#openttdcoop: blog | wiki | public server | DevZone | NewGRF web translator
DevZone - home of the free NewGRFs: OpenSFX | OpenMSX | OpenGFX | Swedish Rails | OpenGFX+ Trains|RV|Industries|Airports|Landscape | NML
Re: Orthogonal Income Patch
I know, but need "standard" availability, without all those "preview" bonuses.planetmaker wrote: Availability *does* differ between companies. The preview is given only to one company.
I want to take into account all vehicles available to purchase in a given time without previews
and without those old, declined from purchase list.
I build such query:
Code: Select all
FOR_ALL_CARGOSPECS(update_cargo) {
engine_count = 1;
roll_avg = 0;
FOR_ALL_ENGINES(e) {
eid = e->index;
if (IsEngineBuildable(eid, VEH_TRAIN, OWNER_DEITY)) {
maxs = e->GetDisplayMaxSpeed();
if (maxs > 0) {
uint32 refit_mask = GetUnionOfArticulatedRefitMasks(eid, true); // & _standard_cargo_mask;
if (HasBit(refit_mask, update_cargo->Index())) {
engine_count++;
roll_avg += maxs;
}
//...
update_cargo->average_max_speed = roll_avg / engine_count;
It works fine with VEH_SHIP and VEH_ROAD, but not with VEH_TRAIN.
Of course, to avoid "0" fot wagons, I changed table/engines.h and defined max speed for all wagons: 265 for standard, 336 for monorail, 640 for maglev.
If I start in 1950, average_max_speed for all is 413 km/h -?
In 2040, average_max_speed are even lower - 394, except oil which is still 413. Note, that only VEH_TRAIN are taken into account,
in fact only train cars, no locomotives.
Any advise, what is messed up?
Formerly known as: McZapkie
Projects: Reproducible Map Generation patch, NewGRFs: Manpower industries, PolTrams, Polroad, 600mm narrow gauge, wired, ECS industry extension, V4 CEE train set, HotHut.
Another favorite games: freeciv longturn, OHOL/2HOL.
Projects: Reproducible Map Generation patch, NewGRFs: Manpower industries, PolTrams, Polroad, 600mm narrow gauge, wired, ECS industry extension, V4 CEE train set, HotHut.
Another favorite games: freeciv longturn, OHOL/2HOL.
Re: Orthogonal Income Patch
obviously, changing table/engines.h is the wrong way, because NewGRFs may still give you 0 speed vehicles. also, you need to take wagonspeedlimits setting into account.
why do you initialize engine count with 1 instead of 0?
also, a matter of style:
useto avoid nesting ifs
and eid and maxs should be declared as local variables to the block.
why do you initialize engine count with 1 instead of 0?
also, a matter of style:
use
Code: Select all
if (!condition) continue;
and eid and maxs should be declared as local variables to the block.
Re: Orthogonal Income Patch
I did my own research and came to conclusion that present formula for calculating cargo income is really OK. It has really nice properties. The bump on the "income vs distance" plot is OK too: lengthening a route increases profit but at some point the profit begin to decrease because cargo is getting too old on such long routes. Fine for me.
Perhaps one thing may be corrected - the bump could be more slight. It can be achieved by altering the "time vs income" formula (known as "cargo payment rates"). When the factor reaches the magic limit 32, decaying should start slowing down and slightly evaporate in the end. Something like this: (compare to http://wiki.openttd.org/Cargo_income, first plot)
I also investigated the new McZapkie's formula (the one from the patch) and I must say it's really bad. See: There are many issues.
McZapkie, perhaps you didn't test your formula very well, probably because you are using Excel which is not good for the task. I advise you to use some mathematical tool like Matlab/Octave. I did my plots in Octave. The script is short and clear:
Perhaps one thing may be corrected - the bump could be more slight. It can be achieved by altering the "time vs income" formula (known as "cargo payment rates"). When the factor reaches the magic limit 32, decaying should start slowing down and slightly evaporate in the end. Something like this: (compare to http://wiki.openttd.org/Cargo_income, first plot)
I also investigated the new McZapkie's formula (the one from the patch) and I must say it's really bad. See: There are many issues.
McZapkie, perhaps you didn't test your formula very well, probably because you are using Excel which is not good for the task. I advise you to use some mathematical tool like Matlab/Octave. I did my plots in Octave. The script is short and clear:
don't worry, be happy and checkout my patches
Re: Orthogonal Income Patch
In my opinion it is not OK, especially if you play at large maps with low density of resources, or if start date is in at beginning of XIX centuryadf88 wrote:present formula for calculating cargo income is really OK
(generally early start date need large and sparse map to bring proper scale for city size in later stages of the game).
It is problematic to make profitable long routes with ships and horse carriages (especially if infrastructure costs are on).
It is OK in 1950, but not in a dilligence era.
I can set running/maintenance costs low enough, but it will result in later unlimited growth of income - well known issue related to openttd economy.
Present formula is also not OK, because is not monotonic: in case of slow transport, you gain large profit for very short AND very long distances, and drop at medium distance.
Additionally there is issue with cargodist long distance hopping, mentioned elsewhere by KeldorKatarn.
Thank you for testing. If you mean payment vs time graph, it is valid only for original formula which rely on time and distance only.adf88 wrote: I also investigated the new McZapkie's formula (the one from the patch) and I must say it's really bad. See:
My new older formula was using velocity, thus standard graph produces strange values
(velocity was very low for 20 tiles and 200 days).
Instead of this, income from 1 piece across 200 tiles would give more reliable values.
The real issue was predicted by Eddi - using exponential function without floats is overcomplicated,
with to many magic constants to play around.
-------------------------------------------------
Now I'm working on better and more compact model with payment calculations consist of two parts:
distant/velocity dependent part and time difference penalty part.
What we need for payment function is:
1. limited growth of payment vs distance
2. penalty, if delivery time is much longer then expected
3. payment ratio adapted to vehicle epoch.
My proposal is, for point 1, to make following formula income depend on distance d and cargo time in transit t
- instead of substracting, use dividing.
(for readability I skipped amount and base constant)
Such formula is represented by olive-green below.
It is typical payment curve, it is compatible with old curve and is scalable with velocity.
For point 2 and 3, my proposal is to use old subtracting formula, however instead of cargo in transit time, use difference between
carried and expected transit time:
Expected transit time is calculated as manhattan distance between source and target, divided by rolling average speed specific for given cargo.
Rolling average speed will be updated every year as weighted average of available for such cargo vehicles and previous year average.
Weight of previous year average should be enough to accumulate changes over several years, instead of abrupt change when new fast model appear in purchase menu.
Resultant income is an multiplier of I(t,d) - growth curve 1. and possible penalty 2, where penalty P(t,d,v_cargo_avg)
depend on existing vehicle set.
Now, imagine 2-horse carriage in 1800. Instead of original orange line, you have superposition of growth curve 1 (olive-green line)
and penalty 2.
You have eGRVTS set and Sailing Ships set, average speed for passengers is about 21 km/h.
Therefore, you can safely use 2-horse carriage (20 kmph) up to 500 tiles distance, see dotted light green line,
but of course you would be penalised if effective speed is low because horse is very old, or tired due to lack of sheds maintenance.
(however 4-horse carriage would be safer for long distances, because its maximal speed 26 kmph guarantee shorter trip then expected travel time, even in case of failures and other obstacles).
If your long/medium distance link is served correctly, nobody should complain if you are using horse power, if no-one invented steam train yet.
In a middle of XX century, if expected average speed is about 160 km/h, horse carriage can still be used only at low distances, as in original game (see solid light green line).
Please note, that calculating penalty as difference between expected and performed transit time, instead of plain transit time,
give you opportunities to design more sophisticated transport networks, for example if freight locomotive is faster then average coal speed,
saved time can be used to prioritising passenger trains (which must conquer with airplanes) prior to the freight trains.
(original game Cargodays1 parameter is very low to be significant for old payment model).
It is a common arguments - cargo is perishable, thus penalty must be proportional to the transit time.lengthening a route increases profit but at some point the profit begin to decrease because cargo is getting too old on such long routes
Such arguing is not valid in a century long time scale, because "perishability" term is not fixed.
Nowadays we pay for fresh food delivered by airplanes. Because we have opportunity to do that.
Our ancestors paid for canned food delivered by ships and trains.
Their ancestors paid for grain, delivered by horse carriage and sail ships from Ukraine to Sweden, and salted herrings delivered in opposite way.
In my model payment adapt to the used vehicle set. I think this is better idea then infamous inflation.
Even if average cargo speed is elevated by airplanes/maglevs etc, you can still use slower means of transport, but in limited range.
Increase of "needs for speeds" is not directly date-related, but newgrf set related.
If you have an unrealistic vehicle set with (for some reason) very slow futuristic vehicles, it should work fine
PS: spreadsheet with new2 model is here:
https://docs.google.com/spreadsheet/ccc ... sp=sharing
PS2. I'm using google spreadsheets because they are easy to share. Personally I'm using Matlab and Origin, but not for www sharing.
=============================
Of course, I done it just for testing purposes. I want to take wagon speed limits into account, pity that there is possibility to define 0 speed in newgrf. Both options are overlapping.Eddi wrote:obviously, changing table/engines.h is the wrong way, because NewGRFs may still give you 0 speed vehicles. also, you need to take wagonspeedlimits setting into account.
The best would be take locomotives (all) and powered units (refit matched) if wagon speed limits are off,
and wagons speeds, if on. But additional option of unlimited speed hardcoded in newgrf need to take locomotives into account
even if wagon limits are on.
Not a really big issue, it is an average speed including also other means of transport.
Formerly known as: McZapkie
Projects: Reproducible Map Generation patch, NewGRFs: Manpower industries, PolTrams, Polroad, 600mm narrow gauge, wired, ECS industry extension, V4 CEE train set, HotHut.
Another favorite games: freeciv longturn, OHOL/2HOL.
Projects: Reproducible Map Generation patch, NewGRFs: Manpower industries, PolTrams, Polroad, 600mm narrow gauge, wired, ECS industry extension, V4 CEE train set, HotHut.
Another favorite games: freeciv longturn, OHOL/2HOL.
Re: Orthogonal Income Patch
I discussed with McZapkie about the new income model on polish OTTD forum.
In my opinion the current income algorithm is not bad, but it realy needs some extensions for largest maps.
The simplest way to achieve interesting effects is slowing down the cargo ageing process for maps greater than 512 tiles. This solution is easy for implementation and effects will be easily predictable - no dependencies to vehicle parameters or limits...
BTW - this strange constant value 32 in current incoming rate algorithm should be changed to 0 (zero), because of abnormal high incomes generated on extremelly long distances...
In my opinion the current income algorithm is not bad, but it realy needs some extensions for largest maps.
The simplest way to achieve interesting effects is slowing down the cargo ageing process for maps greater than 512 tiles. This solution is easy for implementation and effects will be easily predictable - no dependencies to vehicle parameters or limits...
BTW - this strange constant value 32 in current incoming rate algorithm should be changed to 0 (zero), because of abnormal high incomes generated on extremelly long distances...
Re: Orthogonal Income Patch
Because it is rolling average and previous value is taken into account (in future, there will be a weight parameter instead of 1).Eddi wrote:why do you initialize engine count with 1 instead of 0?
But I encountered strange problem during wagons query.
If have following check (forgive my pascalish style, I will fix it later):
Code: Select all
FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) {
eid = e->index;
if (IsEngineBuildable(eid, VEH_TRAIN, OWNER_DEITY)) {
maxs = e->GetDisplayMaxSpeed();
if (maxs > 0) {
int pe = Engine::Get(eid)->GetPower();
uint32 refit_mask = GetUnionOfArticulatedRefitMasks(eid, true) & _standard_cargo_mask;
bool iscargo = HasBit(refit_mask, update_cargo->Index());
if (_settings_game.vehicle.wagon_speed_limits) { //count only vehicles refittable to cargo
if (iscargo) {
engine_count++;
roll_avg += maxs;
}
}
else if ( ( (pe!=0) && !(e->CanCarryCargo()) ) || ((pe!=0) && iscargo ) ) { //count lok || refittable dmu/emu
engine_count++; //locomotives counts instead of wagons
roll_avg += maxs;
//....end of loops
In case of enabled wagon_speed_limits, engine_count should be 1 (there is one wagon for each cargo at the beginning),
but for passengers I got two, and for other cargo - three!
Where are hidden wagons?
Filtering in purchase menu shows predicted 1 type for each cargo.
Formerly known as: McZapkie
Projects: Reproducible Map Generation patch, NewGRFs: Manpower industries, PolTrams, Polroad, 600mm narrow gauge, wired, ECS industry extension, V4 CEE train set, HotHut.
Another favorite games: freeciv longturn, OHOL/2HOL.
Projects: Reproducible Map Generation patch, NewGRFs: Manpower industries, PolTrams, Polroad, 600mm narrow gauge, wired, ECS industry extension, V4 CEE train set, HotHut.
Another favorite games: freeciv longturn, OHOL/2HOL.
Re: Orthogonal Income Patch
Not perticularly aimed at you TadeuszD, but can anyone explain to me why you need longer routes in a bigger world?TadeuszD wrote:In my opinion the current income algorithm is not bad, but it realy needs some extensions for largest maps.
I fail to understand the apparently assumed(?) 1-to-1 connection between big world and longer routes. Isn't a very viable alternative to simply have more short routes on a bigger world?
Just let the payment drop to 0 after say 256 or 512 tiles or so.
Even today in our fast real world, there are very few points in the world where all cargo of some type originates from or it brought to.
Re: Orthogonal Income Patch
Assuming CargoDist ist turned on and you're building your rail routes as a network. Why would passengers travelling >512(>256) tiles pay less?Alberth wrote:I fail to understand the apparently assumed(?) 1-to-1 connection between big world and longer routes. Isn't a very viable alternative to simply have more short routes on a bigger world?
Just let the payment drop to 0 after say 256 or 512 tiles or so.
Re: Orthogonal Income Patch
The answer is simple. In small world all industries are located in small distances. In bigger world, necessary industries (i.e. coal mine and power station) can be located at a greater distance. If you can not find industries located close enough to each other, you business will fall down due to no incomes.Alberth wrote:I fail to understand the apparently assumed(?) 1-to-1 connection between big world and longer routes. Isn't a very viable alternative to simply have more short routes on a bigger world?
So, the income algorithm should be scaled to map size. Of course, the scaling mechanism need not be linear. For example, if map size grows 2x, the income algorithm can be scaled 1,5x or 1,41x.
Re: Orthogonal Income Patch
First of all, please define "small/big world" and "short/long route".Alberth wrote:Isn't a very viable alternative to simply have more short routes on a bigger world?
For example, which map is bigger,
this:
or this:
?
Even yesterday in our slow real world, there were many points in the world where all cargo of some type originates from or it brought to,Alberth wrote: Even today in our fast real world, there are very few points in the world where all cargo of some type originates from or it brought to.
for example silk, tea, latex, spices etc
Formerly known as: McZapkie
Projects: Reproducible Map Generation patch, NewGRFs: Manpower industries, PolTrams, Polroad, 600mm narrow gauge, wired, ECS industry extension, V4 CEE train set, HotHut.
Another favorite games: freeciv longturn, OHOL/2HOL.
Projects: Reproducible Map Generation patch, NewGRFs: Manpower industries, PolTrams, Polroad, 600mm narrow gauge, wired, ECS industry extension, V4 CEE train set, HotHut.
Another favorite games: freeciv longturn, OHOL/2HOL.
Re: Orthogonal Income Patch
it's not just about size of the world, also about density.
for a long time now i wanted to introduce "scale factors" into the game, where certain aspects of the game are increased or decreased.
e.g.
(this is totally independent from which function you use to calculate the payment)
for a long time now i wanted to introduce "scale factors" into the game, where certain aspects of the game are increased or decreased.
e.g.
- daylength
- industry/town production
- cargo age for payment
- distance for payment
- vehicle (airplane) ranges
- ...
(this is totally independent from which function you use to calculate the payment)
Re: Orthogonal Income Patch
I encountered strange problem during wagons query. In case of enabled wagon_speed_limits, engine_count should be 1 (there is one wagon for each cargo at the beginning),
but I got three, because all wagons are initialised with same game start date, thusreturns three wagons in 1950.
Mono and Maglevs wagons are not available directly for user at the beginning, because tracks are not available.
How to filter out these wagons? May I perform query across all companies?
but I got three, because all wagons are initialised with same game start date, thus
Code: Select all
IsEngineBuildable(eid, VEH_TRAIN, OWNER_DEITY)
Mono and Maglevs wagons are not available directly for user at the beginning, because tracks are not available.
How to filter out these wagons? May I perform query across all companies?
Formerly known as: McZapkie
Projects: Reproducible Map Generation patch, NewGRFs: Manpower industries, PolTrams, Polroad, 600mm narrow gauge, wired, ECS industry extension, V4 CEE train set, HotHut.
Another favorite games: freeciv longturn, OHOL/2HOL.
Projects: Reproducible Map Generation patch, NewGRFs: Manpower industries, PolTrams, Polroad, 600mm narrow gauge, wired, ECS industry extension, V4 CEE train set, HotHut.
Another favorite games: freeciv longturn, OHOL/2HOL.
Who is online
Users browsing this forum: No registered users and 38 guests