News:

SimuTranslator
Make Simutrans speak your language.

Better power production

Started by Václav, May 19, 2026, 03:06:17 PM

Previous topic - Next topic

0 Members and 3 Guests are viewing this topic.

Václav

If I remember correctly, it was discussed long time ago (before my pause) but I hope that it may be discussed again and with better result - that would lead to change.

But on other hand, it could be already changed. So, please, don't be rude, if this topic is useless.

It is unfortunate that all power plants have the same production - that wind power plant produce the same power like big stable sources like coal, (in some paksets) nuclear or so. It does not give a sense.

May it be that power production may be improved by people and post transported to power plant, but if power transforming station calls production only 100 MW at all time, it is not good situation.

So, there are two ways how to achieve it:
- allow to build more power transforming stations in dat file of power plant
- allow to build more power transforming stations by size of power plant
- allow to set various power production in dat file of power plant (and let transforming station convert power from power plant 1:1)

And secondary idea:
- new dat file option: stable_source (would be interesting mostly in Extended) that would have options "0" (solar), "1" (wind) and "2" (stable). Solar sources would accept game time (may be simplified to turned on between 6:00 and 18:00 or so - and turned off in rest of day). Wind sources would generated more power in some areas or seasons. Stable sources would generate the same amount of power at all times.

Chybami se člověk učí - ale někteří lidé jsou nepoučitelní

makie

Standard or Extended?

In standard transforming stations simple connect power plant with the network.
For power plants all the rules apply as for normal factories.

Václav

Quote from: makie on May 19, 2026, 03:41:04 PMStandard or Extended?
Mostly Extended, but some parts also Standard.

Chybami se člověk učí - ale někteří lidé jsou nepoučitelní

prissi

The power supplied to the network depends only on the generating capability of the factory (in standard, btu the code is old enough, that it may be in extended). When a power station produces 100%, the electricity is proportional to the production value. However, if there is not enough demand, not all is sent. So in principle, more than one player could connect to the same plant.

(Since one loses extra power, it is best to have everything on one large network.)

And factories only consume according to their production and the power available at that moment. But factories rarely produce with full power, since they also slow down whenever their storage gets filled etc.

Extended has also cities as consumers. But otherwise, I think the code is similar or coudl be adapted from standard without many changes.

All extra power is lost. If you have more than one transormer connectedd

victor_18993

#4
[EN]

Following up on Václav's idea, I looked into how power generation works in the code, and I think it helps to split the request into two separate things, because one of them is already possible and the other represents a genuine gap in the engine.

Different production based on plant type: already possible.

A power plant's output is already proportional to its production value: in [tt]fabrik_t::update_scaled_electric_demand()[/tt] the supplied power scales with [tt]prodbase[/tt]. So a pakset can already make a nuclear plant produce more than a wind farm simply by giving it a higher production value in the .dat. If pak64 has them all at the same power output, that is a pakset balancing decision, not an engine limitation.

Intermittent/time-variable sources: not possible today.

What the engine genuinely cannot do is a source whose production varies over time—solar only during the day, fluctuating wind. Every producer maintains a constant supply. This is the part I think is worth adding, because it changes the gameplay in an interesting way: you need a stable base load plus something to cover the peaks, or a certain overcapacity/backup.

The good news is that the power grid already handles the consequences: [tt]powernet_t[/tt] calculates a normalized demand and consumers scale their consumption based on it ([tt]get_normal_demand()[/tt]), so when an intermittent source drops, the deficit is already automatically distributed to consumers. No new consumer logic is needed.

Proposed design (minimal, backward compatible)
  • A new optional .dat field on the power plant building, e.g., [tt]power_variation = constant | daily[/tt]. The default [tt]constant[/tt] is the current behavior, so old paks and saves won't be broken.
  • Modulate the injected supply by a deterministic factor derived from the world clock: [tt]daily[/tt] follows the day/night cycle (near zero at night, peak at noon). Since it comes from the world time and not an RNG, it stays deterministic and network-safe.
  • Everything downstream (grid balancing, consumer boost) is reused unchanged.

Before writing any code, I would like to get your thoughts on a few points:
  • Should the variation curve be fixed for each type in the engine, or configurable from the .dat file (min/max, maybe a simple schedule)?
  • Should it reuse the existing day/night cycle or have its own period?
  • Would you prefer it to start only with [tt]daily[/tt] (solar) as a minimal first step and leave wind for later?

If this direction is acceptable, I will prepare a patch. Thanks.



[ES]

Quote from: prissi on May 22, 2026, 11:48:21 AMLa energía suministrada a la red depende únicamente de la capacidad de generación de la fábrica (en estándar, pero el código es lo suficientemente antiguo como para que pueda serlo en la versión extendida). Cuando una central eléctrica produce al 100%, la electricidad es proporcional al valor de producción. Sin embargo, si no hay suficiente demanda, no se envía toda. Por lo tanto, en principio, más de un jugador podría conectarse a la misma planta.
(Dado que se pierde energía adicional, lo mejor es tener todo en una gran red).
Y las fábricas solo consumen según su producción y la energía disponible en ese momento. Pero las fábricas rara vez producen a plena potencia, ya que también reducen su velocidad cuando se llena su almacenamiento, etc.
La versión extendida también tiene ciudades como consumidoras. Pero por lo demás, creo que el código es similar o podría adaptarse del estándar sin muchos cambios.
Toda la energía adicional se pierde. Si tienes más de un transformador conectado

Siguiendo la idea de Václav. Miré cómo funciona la generación de energía en el
código, y creo que conviene separar la petición en dos cosas distintas, porque una
ya es posible y la otra sí es un hueco real del motor.

Producción distinta por tipo de planta - ya es posible

La salida de una central ya es proporcional a su valor de producción: en
[tt]fabrik_t::update_scaled_electric_demand()[/tt] la potencia suministrada escala
con [tt]prodbase[/tt]. Así que un pakset ya puede hacer que una nuclear produzca más
que una eólica simplemente dándole un valor de producción mayor en el .dat. Si en
pak64 todas dan lo mismo, eso es una decisión de balance del pakset, no un límite
del motor.

Fuentes intermitentes / variables en el tiempo - hoy no es posible

Lo que el motor realmente no puede hacer es una fuente cuya salida varíe con el
tiempo: solar solo de día, eólica fluctuante. Todo productor inyecta una oferta
constante. Esta es la parte que creo que vale la pena añadir, porque cambia la
jugabilidad de forma interesante: necesitas una base estable más algo para cubrir
los picos, o algo de sobrecapacidad/respaldo.

Lo bueno es que la red eléctrica ya gestiona las consecuencias: [tt]powernet_t[/tt]
calcula una demanda normalizada y los consumidores escalan su consumo con ella
([tt]get_normal_demand()[/tt]), así que cuando una fuente intermitente cae, el
déficit ya se reparte entre los consumidores automáticamente. No hace falta lógica
nueva de consumo.

Diseño propuesto (mínimo, retrocompatible)
  • Un nuevo campo opcional en el .dat del edificio de la central, p.ej.
    [tt]power_variation = constant | daily[/tt]. Por defecto [tt]constant[/tt] =
    comportamiento actual, de modo que paksets y saves antiguos no se ven afectados.
  • Modular la oferta inyectada por un factor determinista derivado del reloj del
    mundo: [tt]daily[/tt] sigue el ciclo día/noche (casi cero de noche, pico al
    mediodía). Al venir del tiempo del mundo y no de RNG, se mantiene determinista y
    seguro en red.
  • Todo lo de aguas abajo (balanceo de red, boost del consumidor) se reutiliza sin
    cambios.

Antes de escribir código me gustaría tu opinión sobre unos puntos:
  • ¿La curva de variación debería ser fija por tipo en el motor, o configurable
    desde el .dat (min/max, quizá un horario simple)?
  • ¿Debería reutilizar el ciclo día/noche existente, o tener su propio periodo?
  • ¿Prefieres que empiece solo con [tt]daily[/tt] (solar) como primer paso mínimo y
    deje la eólica para después?

Si este enfoque es aceptable, preparo un parche. Gracias.


En la vida todo son vivencias y cada una de ellas nos hace mas grandes,¿Como de grande eres tu? :)

Isaac Eiland-Hall

[EN] Welcome back to the forum! I have modified your message. I think you may have gotten distracted part-way through. I did the following:

1. Translated one of the duplicated Spanish sections to English
2. Added [EN]/[ES] tags
3. Removed extraneous quote since you are replying to the last message in the thread - it's right there.
4. Removed greeting/closing - your forum profile is attached to your comment
5. I did leave the translated quote in the [ES] section :)

ES] ¡Bienvenido de nuevo al foro! He modificado tu mensaje. Creo que te has distraído a mitad de camino. He hecho lo siguiente:

1. Traducir al inglés una de las secciones duplicadas en español
2. Añadir las etiquetas [EN]/[ES]
3. Eliminar la cita superflua, ya que estás respondiendo al último mensaje del hilo (está justo ahí arriba).
4. Eliminar el saludo y la despedida (tu perfil del foro ya va adjunto a tu comentario)
5. Sí que he dejado la cita traducida en la sección en español :)

prissi

The time is purely cosmetical. Even on a server, people could play with three days/months, and normal month length and no time display. So that is something which is probably not happening.

Furthermore, the randomish fluctuations are against the idea that "in principle" is should be possible to determistically balance everything. Solar and wind in Simutrans is a little like printing money anyway, so these tend to be rather weak.

Furthermore, Simutrans power plants never need maintenance and never break down anyway.

victor_18993

Quote from: prissi on July 13, 2026, 01:50:48 PMThe time is purely cosmetical. Even on a server, people could play with three days/months, and normal month length and no time display. So that is something which is probably not happening.
Furthermore, the randomish fluctuations are against the idea that "in principle" is should be possible to determistically balance everything. Solar and wind in Simutrans is a little like printing money anyway, so these tend to be rather weak.
Furthermore, Simutrans power plants never need maintenance and never break down anyway.

[EN]
Thanks, that clarifies the main issue.
I understand that the visible day/night cycle is cosmetic and therefore should not influence the simulation, especially because different clients may use different display settings.
My intention was not to introduce client-dependent behaviour or random failures. A possible alternative would be a fully deterministic production profile based only on synchronized world ticks, independent of the visual day/night cycle. For example, a power plant could have an optional periodic production curve with a known minimum, maximum and period. This would remain predictable and network-safe, although I understand that it may still not fit the intended level of abstraction of Simutrans Standard.
Your point about maintenance and breakdowns is also relevant: intermittent generation alone would add realism only to one part of a highly abstracted power system.
In that case, would you consider a deterministic periodic production profile unsuitable in principle for Standard, or is the main objection specifically its connection to the cosmetic day/night cycle?
[ES]
Gracias, esto aclara el principal problema.
Entiendo que el ciclo visual de día y noche es cosmético y que, por tanto, no debería influir en la simulación, especialmente porque diferentes clientes pueden utilizar configuraciones visuales distintas.
Mi intención no era introducir comportamientos dependientes del cliente ni fallos aleatorios. Una alternativa sería un perfil de producción completamente determinista, basado únicamente en los ticks sincronizados del mundo e independiente del ciclo visual. Por ejemplo, una central podría tener opcionalmente una curva periódica con un mínimo, un máximo y un periodo conocidos. Seguiría siendo predecible y segura para las partidas en red, aunque comprendo que podría no encajar con el nivel de abstracción previsto para Simutrans Standard.
También es pertinente lo que comentas sobre el mantenimiento y las averías: añadir únicamente generación intermitente introduciría realismo solo en una parte de un sistema eléctrico muy abstracto.
En ese caso, ¿considerarías que un perfil periódico y determinista tampoco sería apropiado en principio para Standard, o la principal objeción es concretamente su conexión con el ciclo cosmético de día y noche?
En la vida todo son vivencias y cada una de ellas nos hace mas grandes,¿Como de grande eres tu? :)

Václav

Well, after some time passed from sending of original post ..., may it be that all needed is change of way how available electric power, station output or transformators work is displayed.

So, let's say that station dialogue would show:
- installed output (as is eritten in dat file)
- current/real output (as currently is showed, in MWh or so)

Wires would show:
- electric power capacity (well, rather installed output of powerstations connected to network)
- electric power production (real output of powerstations connected to network)
- electric power consumption (how much is taken by other factories)

I think that new dialogues may help better understanding of electric power network. But ideas for seasonal power stations (wind, solar) still may be added at least for Expansion.

Chybami se člověk učí - ale někteří lidé jsou nepoučitelní

victor_18993

I agree that improving the displayed information may be the better direction for Standard.
The useful next step would be to check which of these values are already available in
fabrik_t and
powernet_t, and whether this can be implemented only in the information windows without changing the simulation.
I will wait for Prissi's answer regarding deterministic production profiles before doing anything on that side.
En la vida todo son vivencias y cada una de ellas nos hace mas grandes,¿Como de grande eres tu? :)

prissi

I do not think that power fluctuations add much to the game. Your maintenance is per month. Hence, the income is also averaged over a month. So a fluctuating power essentially equals a lower mean power.

Even more, since coal or oil are made scare commodities, especially in pak128 for power stations, and thus power is anyway intermittant from coal at least.

About a different display, just go ahead.

victor_18993

Taking up the "different display" you were fine with, I added a small read-only electricity summary to the power plant information window.

The patch only changes the presentation. It does not change the simulation, economy, power-generation rules or saved-game data, and it adds no random fluctuations.

For factories where is_electricity_producer() is true, the existing production information now includes:

QuoteElectricity production
 - Current output: X MW
 - Available output: Y MW
 - Grid demand: Z%
 - Last month: A MW
 - Power status: STATE

Values

  • Current output uses get_power(): the electricity currently delivered to the grid.
  • Available output uses get_power_supply(): the capacity currently offered by the plant, including its work level and any passenger or mail boost.
  • Grid demand is current output divided by available output. Since get_power() is derived from the available supply multiplied by the network's normalised demand, the percentage does not exceed 100%. It is only shown when available output is greater than zero, avoiding division by zero.
  • Last month uses the existing get_stat(1, FAB_POWER) monthly average.

Power status

The status deliberately reports only states that can be determined reliably:

  • Not connected to a power line — the plant is not connected to the power network.
  • No production available — the plant currently offers no generating capacity.
  • No power delivered — generating capacity is available, but no electricity is currently being delivered to the grid.
  • In operation — electricity is currently being delivered.

I avoided inferred causes such as missing materials or insufficient grid demand because the existing values do not always allow the GUI to distinguish those cases reliably.

Compatibility and translations

No new persistent data is added, so saved games are unaffected. The block refreshes through the window's existing update mechanism while it remains open.

All new visible strings pass through translator::translate(). I used the dedicated key Power status instead of the existing generic Status, because some translations of the generic key are specific to stops and would be incorrect in a factory window.

Patch size and testing

The patch changes only src/simutrans/simfab.cc, adding 41 lines inside fabrik_t::info_prod().

It builds cleanly. I also tested it with a coal power plant connected to a working grid:

QuoteCurrent output: 341 MW
Available output: 341 MW
Grid demand: 100%
Last month: 148 MW
Power status: In operation

demanda electrica info.png

The figures matched the transformer and power-line information windows.

One existing limitation remains: as with the current "Power (MW)" chart, values are displayed as whole MW, so a plant producing less than 1 MW may appear as 0 MW.

Patch attached. I can adjust the labels or their order if you prefer a different presentation.
En la vida todo son vivencias y cada una de ellas nos hace mas grandes,¿Como de grande eres tu? :)

prissi

That window is already so big, I would prefer another tab visible only for power producers with the info.

Also please reuse the strings from the trasnformers, since otherwise translations will take very long.

victor_18993

Reworked after your reply — thank you. Both points were correct, and the second one made the patch considerably smaller.
The electricity figures are no longer part of the production section. They now live in a separate tab, added only when the factory satisfies

info electricidad.png
is_electricity_producer(). Normal factories therefore see no change, and the existing production text remains untouched.
The implementation reuses the same conditional-tab pattern already used by the factory window for its "Details" tab, so only a small amount of GUI code was required.
It also adds no new translation strings.
While looking for the strings used by the transformer window, I found that
pumpe_t::info() already displays exactly the relevant figures for the same power-producing factory. The new tab therefore reuses its existing translation keys:
Net ID: %p
Generation: %.0f MW
Power (MW): %.0f
Usage: %.0f %%

They represent:
These strings already have translations in German, Spanish, French and Dutch.
The ten strings from my first patch have therefore been removed. Two of the proposed values were also duplicates of information already represented by the engine:
  • My "Grid demand" was the existing "Usage" value.
    pumpe_t::get_power_consumption() returns
    net->get_normal_demand(), while
    get_power() is calculated from the available supply and that fixed-point demand. The new value had therefore only reproduced an existing one.
  • My "Current output" was the existing "Power (MW)" value.
    FAB_POWER is recorded using
    set_stat(get_power(), FAB_POWER), and "Power (MW)" is already the label used for that curve in the chart.
I removed "Last month", because the existing
FAB_POWER chart already displays the monthly history. I also removed the status block, because it would have required six new translation keys.
I did not reuse the generic
Status key: in
en.tab it is translated as "Stop status", so it is specific to transport stops and would be misleading in a factory window.
The text is generated by a new const, read-only
fabrik_t::info_power() method, following the existing
info_prod() and
info_conn() pattern. The factory window refreshes it through its existing per-frame update mechanism.
There is no division in the new code. It uses the existing fixed-point network demand value and shifts already used by the power system. The network-specific rows are omitted when no transformer is connected.
The patch does not modify:
  • simulation or economic behaviour;
  • electricity production or demand rules;
  • powernet_t;
  • savegames or serialisation;
  • network synchronisation;
  • paksets or
    .dat parameters;
  • persistent factory data.
Runtime testing
I tested the patch in a running game.
One detail may be useful for anyone testing electricity code: a coal plant without coal reports zero production, and a sawmill without wood does not request electricity. Under
BL_CLASSIC,
set_power_demand() is gated by
currently_requiring_power.
For that reason, I tested with a wind farm, which requires no input goods, and a sawmill supplied through a working freight connection.
Observed results:
No transformer:
Generation: 0 MW
Power (MW): 0
No Net ID or Usage rows
Transformer connected, no consumer demand:
Net ID shown
Generation: 256 MW
Power (MW): 0
Usage: 0 %
Consumer connected and operating:
Generation: 256 MW
Power (MW): 11–19
Usage: 4–7 %

The values were consistent with each other; for example,
19 / 256 = 7.4%, displayed as
7%.
The wind farm receives the new electricity tab. The sawmill, which consumes electricity but does not produce it, correctly does not.
Optional chart-colour hunk
The patch contains one additional, independent hunk.
The three electricity curves in the factory chart are all green and are distinguished mainly by brightness. The two closest entries were the maximum-boost reference using palette colour
137 and the demand reference using
COL_DARK_GREEN, colour
136.
I changed the maximum-boost reference to colour
140, the pure green within the
136–143 palette ramp, to separate it further from both neighbouring curves.
This is a legibility preference, not a bug fix. I checked the palette RGB values and confirmed that the previous colours were distinct, although visually close.
The electricity tab does not depend on this change. If the existing chart colours should remain unchanged, that hunk can be omitted independently.
Existing translation formatting issue
In English, a blank line appears between some rows because
en.tab stores:
Generation: %.0f MW\n
with a newline inside the translation, while the caller also inserts a separator.
pumpe_t::info() behaves identically, so the new tab deliberately matches the existing transformer window in every language.
This cannot safely be corrected only in the C++ code because, for example, the German translation does not contain the embedded newline. Removing the caller's separator would therefore join the German rows together. It would need to be corrected through
translator.simutrans.com.
En la vida todo son vivencias y cada una de ellas nos hace mas grandes,¿Como de grande eres tu? :)

prissi

You are very fast. Thank you. I mean, if needed, you can still add new translations to base.tab (in the src folder).

I added your patch as r12082. I think there are no new strings in your patch, if I understand correctly.

victor_18993

Thank you, prissi. I am trying to make good use of the momentum while I get to know the codebase better.

I also checked the merged version visually: the new electricity tab appears only for power producers, works both with and without a connected power network, and the displayed values follow the actual load. Normal factories and electricity consumers do not receive the additional tab.

No new translations were needed, since the existing strings are reused as you suggested.
Thanks again for reviewing it and adding it as r12082.
En la vida todo son vivencias y cada una de ellas nos hace mas grandes,¿Como de grande eres tu? :)

Andarix

If no transformer is present, a generation reading of 0 isn't very useful or rather, it is incorrect.
When a power plant is powered, it does generate electricity, it simply doesn't output it without a transformer.

In this case, I would prefer a "no transformer present" indication.

victor_18993

I understand the point, and from the player's perspective, showing
Generation: 0 MW when there is no transformer can indeed be confusing.
The power plant may still be available to produce electricity, but the interface does not clearly explain that the real issue is the lack of a connection to the power network. A specific message indicating that no transformer is connected could explain the situation better than simply showing several zero values.
However, this patch has already been reviewed and accepted by Prissi, and it is now part of the incorporated changes. For that reason, before preparing any further modification, I think Prissi should decide whether this proposed UI change fits what Simutrans Standard is intended to show.
If he considers the proposal appropriate, I can then prepare a small follow-up patch to improve the information shown to the player, without changing the simulation itself.
En la vida todo son vivencias y cada una de ellas nos hace mas grandes,¿Como de grande eres tu? :)

prissi

I found this confusing too. I think the power station and the transformer could display different numbers, like the power actual generated for the station and the the power used by the transformer as well.

victor_18993

As this patch has already been accepted, I have opened a separate topic for the follow-up improvement and the new translation string:

https://forum.simutrans.com/index.php/topic,23989.msg213205.html#msg213205
En la vida todo son vivencias y cada una de ellas nos hace mas grandes,¿Como de grande eres tu? :)