Alternative delivery payment rates?

Got an idea for OpenTTD? Post it here!

Moderator: OpenTTD Developers

Post Reply
sinkingmist
Engineer
Engineer
Posts: 4
Joined: 21 Nov 2014 13:34

Alternative delivery payment rates?

Post by sinkingmist »

TL;DR
Delivery Payment changed from:

Code: Select all

Rate * Distance (modified by days taken)
To:

Code: Select all

Base Fee + Lower Rate * Distance (modified by days taken)
Base Fee might have a small minimum distance requirement (e.g. 5 tiles)

Full Post
I really enjoy OpenTTD but one thing that always bugs me is how delivery payments currently work.
As it is, short routes make very little money (or turn a loss), while longer routes generate ridiculous amounts of money that floods your bank with millions of pounds very quickly.
So I've tended to just setup one of these lucrative long routes at the start, which then funds all my other construction (and the unprofitable short routes).

But this could be resolved with a change to how delivery payments work.
As things stand, your income is based primarily on distance:

Code: Select all

Rate * Distance (modified by days taken)
While the cost consists of a fixed term ("station time") and a variable distance term ("travel time") - there's also the initial infrastructure cost, but that too has a fixed term ("station cost") and variable distance term ("rail cost").

Station time consists of the time taken to enter the station, unload, load, then leave the station. This remains whether the route is short or long.
And, because income depends on distance, station time isn't "billable" so to speak. In order to maximise money, you must minimise station time, which is done by having long routes.
Hence, short routes making no profits, long routes making ludicrous money.

However, if we change income to also have fixed and variable components...

Code: Select all

Base Fee + Lower Rate * Distance (modified by days taken)
We can make short routes more profitable, and long routes not as profitable, thus achieving better balance.
A slight minimum distance could be implemented if abuse of the base fee is a concern, though I personally don't think that will be any more of a problem than super long routes are now.

Simply adding a base fee and lowering rates across board shouldn't be a huge coding challenge?
Alberth
OpenTTD Developer
OpenTTD Developer
Posts: 4763
Joined: 09 Sep 2007 05:03
Location: home

Re: Alternative delivery payment rates?

Post by Alberth »

There are two stumbling blocks here

1. Changing the current algorithm breaks all games.
2. Different people want different calculations. Just dig up discussions on payments, and see how everybody is against the current payment model, and fails to find a universally agreed new model.

The first point is easy to fix, there should be a fallback to the original algorithm when there is no new one or it is not selected.
The second point indicates to me that you should not code this in OpenTTD itself (one would have to code a zillion different payment models), a game script should get this under its control so it can be coded by everybody in whatever way they want.

So extend the GS API to handle such economic deliveries in some way. It would make lots of people happy.
Please prove it's not a huge coding challenge.
Being a retired OpenTTD developer does not mean I know what I am doing.
Eddi
Tycoon
Tycoon
Posts: 8271
Joined: 17 Jan 2007 00:14

Re: Alternative delivery payment rates?

Post by Eddi »

i vaguely remember there being a NewGRF-y way to customize payment.
Alberth
OpenTTD Developer
OpenTTD Developer
Posts: 4763
Joined: 09 Sep 2007 05:03
Location: home

Re: Alternative delivery payment rates?

Post by Alberth »

NewGRFs have the advantage that they are relatively fast in computing the answer, I think. However, they don't have an overview of the entire world.
I am afraid you'd end up with a disaster like the current industries all locally trying to decide the global direction

A GS is probably slower (so perhaps you need some generic payment formula code where the GS can set parameters and policies), but it has a chance of keeping an overview of the world, and payments nicely integrate with goal oriented scripts.
Being a retired OpenTTD developer does not mean I know what I am doing.
Panando
Engineer
Engineer
Posts: 43
Joined: 06 Aug 2014 00:43

Re: Alternative delivery payment rates?

Post by Panando »

It actually wouldn't be hard to make a patch. It would just entail modifying the function 'GetTransportedGoodsIncome' in economy.cpp

Where it currently says:

Code: Select all

return BigMulS(dist * time_factor * num_pieces, cs->current_payment, 21);
Would be changed to something like:

Code: Select all

return BigMulS((5 + dist / 2) * time_factor * num_pieces, cs->current_payment, 21);
That change would generally halve the payment, but add a 'handling fee' equivalent to delivering a distance of 5 tiles (10 tiles at the halved rate).

So at a technical level, it's not hard to modify the formula - it also wouldn't be particularly difficult to add an option. The issue is thus not a technical one, but rather a problem of reaching agreement.


Incidentally I disagree most strongly with implementing something like this as a game script. The reason is that at present (and I don't know if it's ever intended to change) only one GS can be used at a time. If someone already has a 'must have' GS to shore up some weak point in the game mechanics, such as a city growth GS then they can't use a payment model GS. It seems to me that the point of a Game Script is not really for fixing gameplay mechanics. My objection would rather evaporate if it were possible to use multiple GS at once.
Alberth
OpenTTD Developer
OpenTTD Developer
Posts: 4763
Joined: 09 Sep 2007 05:03
Location: home

Re: Alternative delivery payment rates?

Post by Alberth »

Panando wrote:It actually wouldn't be hard to make a patch. It would just entail modifying the function 'GetTransportedGoodsIncome' in economy.cpp

Where it currently says:

Code: Select all

return BigMulS(dist * time_factor * num_pieces, cs->current_payment, 21);
Would be changed to something like:

Code: Select all

return BigMulS((5 + dist / 2) * time_factor * num_pieces, cs->current_payment, 21);
That change would generally halve the payment, but add a 'handling fee' equivalent to delivering a distance of 5 tiles (10 tiles at the halved rate).

So at a technical level, it's not hard to modify the formula - it also wouldn't be particularly difficult to add an option. The issue is thus not a technical one, but rather a problem of reaching agreement.
It will take less than a week until someone will claim "dist / 2" is not good, it has to be "dist / 3" (or "2 * dist / 3", etc etc).

Since the original formula was designed for 256x256 maps, your new formula will break game play at other (probably mostly smaller) map sizes. If you invent a new formula, it has to work everywhere, not just for your style and mapsize.

As for reaching agreement, it's impossible. OpenTTD is a game that everybody plays in a different way, with different focus. Different game play styles have different needs for this formula. In other words, while in your game play style, the formula may be considered broken, other styles require the formula as it is, or an entirely different one. Any change has to cover the needs of everyone. (Else it becomes a game of repeatedly replacing some random formula by some random other formula, a game that can be played forever, but tires very quickly.)
Panando wrote:Incidentally I disagree most strongly with implementing something like this as a game script. The reason is that at present (and I don't know if it's ever intended to change) only one GS can be used at a time.
I find this a very weak argument. I fully agree the current situation is not optimal. Iirc, the reason to limit the GS to a single script was that at the time, it was completely unclear whether it would have any use beyond the game tutorial, there is only one world to control so how many game scripts would you need?, and there is the issue of conflicting game scripts (one game script wants X, another wants Y, where X != Y), how do you solve that other than by integrating both scripts into one?.

On the other hand, I think payments is a world-wide problem, where you need to have an overview of the overall goal and situation. A game script is exactly aimed at that area.
As a counter question, how would you ever make a game script that does control payment then? (Think eg a ContractGS, where the player gets paid only for contracts he makes.)
Panando wrote:If someone already has a 'must have' GS to shore up some weak point in the game mechanics, such as a city growth GS then they can't use a payment model GS.
I think you're underestimating flexibility of scripts. If you make access to this payment formula available to a game script, scripts will change, and adopt the new possibilities. It's quite likely that city growth scripts will extend to payments if they can do that.

How are you going to ever manage a script with combined city growth and payments in your do-not-make-payment-tweakable-in-game-script solution?

As a note, I very much doubt "dist" is the only thing one would want to change. There are probably many more hooks in the financial sub-system that are of interest for game scripts in general (ie all players, not just city growth players). The trick is going to be to make a scripting interface with enough hooks and tweaking options that everybody can make his economic model.
Panando wrote:It seems to me that the point of a Game Script is not really for fixing gameplay mechanics.
I don't see the current gameplay mechanics as broken. Play a traditional (no newgrf, and other fancy settings) game at 256x256, and you'll find the mechanics work quite nicely.

Build a big network, with focus on 'build', and the finances work out nicely too, since the only criterium is to have enough money to build anything that is desired. The current payment model works fine for that.

In your style of playing, the payment is sub-optimal, perhaps a lot. That does not make it broken in the general sense, it just shows there should be additional tweaking options to improve the game-experience for your style of playing.
Being a retired OpenTTD developer does not mean I know what I am doing.
sinkingmist
Engineer
Engineer
Posts: 4
Joined: 21 Nov 2014 13:34

Re: Alternative delivery payment rates?

Post by sinkingmist »

Thanks for all the replies.
andythenorth wrote:Modify CashDrainGS http://www.tt-forums.net/viewtopic.php?f=65&t=71606
This is probably the easiest way to get what I want.
User avatar
fonso
President
President
Posts: 945
Joined: 13 Oct 2007 08:28

Re: Alternative delivery payment rates?

Post by fonso »

I somewhat disagree with the direction this is going. In the general case you want payment to happen for every delivery. Game scripts aren't event driven, so there currently is no way of executing a piece of script in response to a game event like cargo delivery. CashDrain hacks around that by aggregating the payments at the end of each month, but meh ...

Direct responses to game events are usually the domain of NewGRFs and we actually have a hook for cargo payment there, see http://newgrf-specs.tt-wiki.net/wiki/Ac ... 11.2C12.29 . OK, this is rather crude, but maybe the newgrf experts could come up with a more elaborate "callback" solution there.
The guy on the picture is not me, it's Alonso.
User avatar
fonso
President
President
Posts: 945
Joined: 13 Oct 2007 08:28

Re: Alternative delivery payment rates?

Post by fonso »

What is that "Custom profit calculation" callback in "Callback flags (1A)", actually? Isn't that exactly what we're looking for? Actually, in GetTrasnportedGoodsIncome, you have this section:

Code: Select all

	/* Use callback to calculate cargo profit, if available */
	if (HasBit(cs->callback_mask, CBM_CARGO_PROFIT_CALC)) {
		uint32 var18 = min(dist, 0xFFFF) | (min(num_pieces, 0xFF) << 16) | (transit_days << 24);
		uint16 callback = GetCargoCallback(CBID_CARGO_PROFIT_CALC, 0, var18, cs);
		if (callback != CALLBACK_FAILED) {
			int result = GB(callback, 0, 14);

			/* Simulate a 15 bit signed value */
			if (HasBit(callback, 14)) result -= 0x4000;

			/* "The result should be a signed multiplier that gets multiplied
			 * by the amount of cargo moved and the price factor, then gets
			 * divided by 8192." */
			return result * num_pieces * cs->current_payment / 8192;
		}
	}
So, yes, a NewGRF can already do a custom profit calculation and that will be used instead of the standard one if it exists. If some newgrf needs some extra input to do that we should talk about specifics now.
The guy on the picture is not me, it's Alonso.
Post Reply

Return to “OpenTTD Suggestions”

Who is online

Users browsing this forum: No registered users and 14 guests