IRC logs for #openttd on OFTC at 2020-01-05
            
00:00:31 *** frosch123 has quit IRC
00:00:50 <Samu> Name Total CPU [unit, %] Self CPU [unit, %]
00:00:50 <Samu> || - std::_Partition_by_median_guess_unchecked<Town const * *,std::_Ref_fn<`GUIList<Town const *,char const *>::Sort'::`9'::<lambda_1> > > 3677 (63,70%) 6 (0,10%)
00:00:59 <Samu> Name Total CPU [unit, %] Self CPU [unit, %]
00:00:59 <Samu> || - std::_Insertion_sort_unchecked<Town const * *,std::_Ref_fn<`GUIList<Town const *,char const *>::Sort'::`9'::<lambda_1> > > 1974 (34,20%) 1 (0,02%)
00:01:10 <Samu> Name Total CPU [unit, %] Self CPU [unit, %]
00:01:10 <Samu> || - std::_Debug_lt_pred<std::_Ref_fn<`GUIList<Town const *,char const *>::Sort'::`9'::<lambda_1> > &,Town const * &,Town const * &,0> 4701 (81,44%) 10 (0,17%)
00:01:17 <Samu> the 3 that took most time
00:01:37 <LordAro> stop measuring debug
00:01:42 <Samu> :(
00:02:37 <floodious> yeah the debug version also includes various sanity checks and is dramatically slower... a "better" algorithm can sometimes suddenly be worse when optimization is enabled since the "better" algo is less possible to optimize
00:02:50 <floodious> never profile debug code, ever ever ever
00:03:03 <floodious> assert(_NDEBUG)
00:03:38 <LordAro> also just the optimisations the compiler can do in general
00:04:14 <Samu> w->OnHundredthTick doesn't feel like it's on every 100 ticks, but every 1 tick
00:04:26 <floodious> does it reset the reference?
00:04:34 <LordAro> Samu: well look at the code, work it out
00:04:36 <floodious> reference/count/etc
00:04:43 <LordAro> random statements here aren't helping
00:05:00 <LordAro> it certainly *should* be every 100 ticks
00:05:25 <Samu> what ticks, real time ticks?
00:06:19 <FLHerne> ?
00:06:36 <Samu> how is it measuring the ticks?
00:06:40 <glx> game ticks
00:06:51 <Samu> doesn't look like that
00:06:57 <floodious> virtual void Window::OnHundredthTick() {} /* Called once every 100 (game) ticks. */
00:07:23 <Samu> when game is paused, then yeah, it seems to be every 100 ticks
00:07:32 <floodious> it's a virtual function, so ensure the particular override[s] are functioning correctly (calling parent?)
00:07:35 <Samu> when it's running, it's doing every frame
00:07:45 <Samu> and it takes those said 5500 ms
00:07:57 <floodious> which object is w?
00:08:06 <Samu> the towngui window
00:08:21 <floodious> TownDirectoryWindow?
00:08:46 <Samu> openttd.exe!TownDirectoryWindow::OnHundredthTick() Line 959
00:08:46 <Samu> at D:\OpenTTD\OpenTTD GitHub\OpenTTD\src\town_gui.cpp(959)
00:09:09 <LordAro> not something i can replicate - the loop definitely calls OnHundredthTick (for every window) every 100 ticks
00:09:19 <floodious> other implementations don't seem to do anything fancy
00:09:47 <floodious> they all get called from the same sources which are responsible for the interval... which is at...
00:10:19 <LordAro> yeah, putting in a print at 959 still only results in an output every 100 ticks
00:10:48 <LordAro> so i don't know what you've done Samu, but it's either Windows only (exceedingly unlikely), or you've broken it in some way
00:11:05 <Samu> i put TICC/TOCC
00:11:14 <Samu> nothing else
00:11:39 <floodious> openttd_main(argc, argv) > VideoDriver_Win32::MainLoop() > UpdateWindows() > TownDirectoryWindow::OnHundredthTick()
00:12:05 <floodious> UpdateWindows() seems the only caller
00:12:36 <floodious> window.cpp ln 3179
00:12:48 <Samu> https://i.imgur.com/BZdDrYt.png
00:12:53 <Samu> and the debug.h
00:13:14 <floodious> it's using milliseconds realtime
00:13:16 <floodious> not using game ticks
00:13:33 <floodious> so if the measured game speed or framerate drops, it might call more often since the same actual time has passed
00:13:49 <LordAro> Samu: that is not OnHundredthTick
00:13:50 <floodious> static uint32 last_realtime_tick = _realtime_tick; uint delta_ms = _realtime_tick - last_realtime_tick; last_realtime_tick = _realtime_tick;
00:14:00 <floodious> opps why did i paste that
00:14:02 <LordAro> that is BuildSortTownList, which among other things, is called by OnPaint
00:14:14 <LordAro> so yeah, that function is called every tick
00:14:43 <Samu> OnPaint? never once I got it being called by the OnPaint
00:15:04 <Samu> it's always onHundrethTick, which is strage
00:15:27 <LordAro> hmm, OnPaint is guarded by an if
00:15:29 <LordAro> but still
00:15:37 <floodious> the bug is here: hundredth_timer.SetInterval(3000); // Historical reason: 100 * MILLISECONDS_PER_TICK
00:15:40 <floodious> it assumes 30 fps
00:15:44 <floodious> it's a constant
00:15:51 <floodious> it does not adapt to varied frame rate
00:16:12 <floodious> the slower the frame rate, the more it gets called per frame
00:16:16 <glx> oh nice spot
00:16:36 <glx> and more calls increase slow down
00:16:44 <LordAro> ah
00:16:45 <floodious> exponential bubble
00:16:58 <LordAro> something that got missed when GUI was split from gameloop
00:17:03 <Samu> forgive me i couldn't explain miself
00:17:13 <LordAro> or perhaps intentional, and the town directory window is doing The Wrong Thing
00:17:17 <LordAro> can't remember
00:17:28 <floodious> so we just need to fill the value instead of from the constant, re-compute every N frames (1000?) from the min FPS counter value
00:17:48 <Samu> seems u guys got this now, guess I'm off to bed
00:17:55 <Samu> take care
00:18:14 <floodious> or whatever... ten seconds = 3000 frames
00:18:26 <floodious> just use ten seconds then
00:18:32 *** Samu has quit IRC
00:19:57 <glx> window_timer.SetInterval(MILLISECONDS_PER_TICK); <-- this one may be wrong when everything is slower
00:20:26 <floodious> if it's still constant, it's still wrong
00:20:43 <glx> but it's less visible, it just set windows dirty
00:21:33 <floodious> GUI updates need to either happen: 1) in real-time factors, once per frame at most (limiting) or 2) upon only required updates, like if a string changes you _must_ mark it dirty to redraw on the next frame, or else immediately if it can't be updated based upon dirty state
00:21:37 <floodious> so a constant is the problem
00:21:55 <floodious> can't be a constant, must be computed from actual time, and limited to once per graphical redraw
00:22:15 <floodious> no point updating the status of a pure GUI element multiple times per screen update
00:22:34 <floodious> except in cases where there are side-effects, which ought to be moved elsewhere in the code
00:24:08 <floodious> set dirty is ... usually inherently once per frame, but it depends what is being redundantly re-set as dirty
00:24:44 <floodious> if the cost is even "bool dirty = true", multiply that by a billion and you have a problem
00:37:54 *** Wolf01 has quit IRC
00:41:25 <floodious> if as i said the factor were updated every ten seconds, that would set the worst-case recovery time from a low FPS event
00:41:33 <floodious> so it's probably better to use more like 100 ms or similar
00:41:59 <floodious> then if FPS is measured as 1/100th FPS for an instant, it'll only delay redraw 100 ms
00:43:07 <floodious> it should also be clamped both ways: only one update per frame (never until redraw finishes) and at some maximum rate set by the user such as 30 FPS or whatever
00:43:31 <floodious> otherwise the same problem exists when FPS runs too high, CPU time requirements build proportionately or worse
00:47:54 <nielsm> uh... are you imagining the thing runs on a separate thread?
00:48:07 <nielsm> because it does not, the entire UI is synchronous with the game code
00:48:19 <nielsm> when the UI is drawing, the game is not running behind it
00:49:17 <nielsm> how about this addition... https://0x0.st/znMo.png
00:49:27 <glx> on the driver side it's threaded IIRC
00:50:22 <nielsm> well, the server does not show GUI :P
00:52:55 <nielsm> https://github.com/nielsmh/OpenTTD/compare/fios-hover...nielsmh:fios-moredrives
00:53:04 <nielsm> probably won't PR that as-is
00:53:37 <nielsm> (especially since I don't know the full consequences of the windows version defs change)
01:19:32 *** nielsm has quit IRC
01:30:07 *** Flygon has joined #openttd
01:31:49 *** supermop_Home_ has joined #openttd
01:32:08 <supermop_Home_> yo Pikka
01:32:17 <Pikka> yoyo!
01:33:01 <supermop_Home_> hows it going down there?
01:33:16 <supermop_Home_> hopefully not too smokey where you are?
01:34:12 <Pikka> not too bad here. we're not getting the worst of it this far north...
01:52:19 *** Wormnest has quit IRC
02:06:40 <supermop_Home_> sounds pretty bad in the news we get here
02:10:34 <Pikka> it is
02:11:30 <Pikka> about once a week they get a 40 degree day and it kicks all the fires back up again... most of Victoria and NSW is at least under threat
02:14:23 <Pikka> 20+ people killed, hundreds of houses, millions of animals. good times and not at all climate change in action...
02:34:54 * Pikka bbl
02:34:55 *** Pikka has quit IRC
02:48:39 *** Progman has quit IRC
03:03:10 *** snail_UES_ has quit IRC
04:24:15 <floodious> it doesn't need a separate game thread, although that would be probably way more efficient due to multi-core processors it would need a ton of mutex stuff to be added to ensure it's thread-safe
04:25:08 <floodious> but the game loop might only take a short bit of time far less than 1ms, while each video frame is at least 33.333 ms, so if you're doing GUI updates every 1/10th ms that is a huge amount of unneeded processing overhead
04:25:45 <floodious> so therefore ANY GUI/video processing MUST happen no more frequently than 1/30*1000 ms
04:26:34 <floodious> the whole GUI related section should have "if (last_frame < frame_count) { last_frame = frame_count; ... }
04:26:56 <floodious> to ensure no graphical process occurs more than once per individual frame
04:28:31 <floodious> or a boolean can be used, set-only-if-clear on one side and clear-only-if-set on the other
04:29:55 <floodious> bool fresh_frame, draw() { if (!fresh_frame) fresh_frame = true; ... }
04:30:25 <floodious> UpdateWindows() { if (fresh_frame) { fresh_frame = false; ... }
04:32:03 <floodious> if they're the same thread that'll always be oscillating the state of the bool
04:33:33 <floodious> if you mean the video code uses v-sync or waits until at least 1/30*1000 ms has passed... that would severely impact the maximal performance of the gameloop, limiting it to no more than 30 cycles per second
04:34:22 <floodious> "fast forward" would only work by decreasing precision and jumping ahead in larger steps, still 30 cycles per second
04:36:04 <floodious> that would also directly tie framerate to game-time, such that lower framerates would slow down the passage of time, such that if for example it took longer to redraw the screen, gameplay would slow proportionately
04:36:43 <floodious> along with all related activities... which would explain the symptom of the cursor moving slowly when the gameloop takes too much time to process AI
04:38:16 <floodious> normally UI interaction is handled independent from processing functions like the gameloop, so the user interaction with the UI (real-time, user space) doesn't get negatively impacted as the CPU becomes bogged down doing game stuff
04:41:07 <floodious> normally you'd run the game-loop as core stuff, and between game cycles check if the frame-time has elapsed, then if so redraw and do all GUI update stuff (1/30*1000 ms)
04:41:38 <floodious> meanwhile the UI would be threaded to ensure stuff like the cursor position on screen isn't linked to processing load
04:42:27 <floodious> so the command "button clicked" would pass via its own thread, triggering mutex locks where needed to modify game-thread data... then the game/draw thread would process and update the screen
04:43:56 <floodious> to my knowledge most modern games worked that way since forever, since it wasn't possible to thread openGL or similar, all updates had to be single-threaded
04:44:37 <floodious> they still had independent timings for gameloop + redraw, and usually a UI thread separate from the game thread
04:45:10 <floodious> so you couldn't miss a button press or similar
04:47:28 <floodious> it's normally something like while (running) { while (gametime < realtime) { gameloop(); } redraw(); }
04:48:37 <floodious> the inner-loop (priority #1) is the core game functions and screen updates are secondary "in between"
04:52:09 <floodious> if gameloop() and redraw() both require 1 ms, but each game tick is 30 ms, redraw() will be called approximately 30 times per each real video frame (at 30 fps)
04:52:47 <floodious> 30 times for every single gameloop() call, which would total 31 ms, so gameloop() would happen twice in a row sometimes
04:57:24 *** D-HUND has joined #openttd
05:00:47 *** debdog has quit IRC
05:03:56 <floodious> fresh_frame is usually called "dirty" :)
05:19:26 *** glx has quit IRC
05:44:08 <floodious> cursor bug with win32_v.cpp is because DrawMouseCursor() is only called during idle, which is mutually exclusive with GameLoop() calls and ticks
05:44:22 <floodious> maybe
05:49:10 <floodious> nope, that's called from UpdateWindows() and the main loop idle
06:01:12 *** tokai|noir has joined #openttd
06:01:12 *** ChanServ sets mode: +v tokai|noir
06:08:09 *** tokai has quit IRC
06:21:53 <floodious> moving the DrawMouseCursor() call outside the gameloop tick check (with its own independent check at 16 ms) solves the cursor slowing, partially, but the main cause is that the heavy processing in the game loop isn't threaded, so during any single heavy function the cursor position is locked without updating
06:22:24 <floodious> threaded independently from UI, i mean
06:45:14 <dwfreed> separating game updates from graphics is not trivial; most games don't even bother with it, because it's easier to optimize the heavy processing
06:45:56 <floodious> it becomes a headache when stuff like AI is as heavy as in openttd, when the mouse cursor or UI interaction becomes so latent
06:46:16 <floodious> i'm not talking about game vs. graphics, i'm talking game vs. UI
06:46:24 <dwfreed> UI is graphics
06:46:27 <floodious> no
06:46:33 <floodious> UI is nothing to do with graphics
06:46:41 <floodious> UI is user interface, input from the user
06:46:48 <floodious> doesn't matter what's on screen
06:47:03 <floodious> stuff like the window message loop
06:47:20 <dwfreed> say input, then, not UI, because UI refers to what's on screen
06:47:35 <dwfreed> the buttons and the toolbars, etc
06:47:42 <floodious> right now that interferes with the gameloop, although it has priority, the gameloop is blocking on the window loop, so while a single heavy function is processing in gameloop(), UI is blocked completely
06:47:46 <floodious> that's unnatural
06:47:56 <floodious> UI refers to the window message loop, always
06:48:00 <floodious> GUI is what you are thinking
06:48:28 <dwfreed> either way, you're talking about user input, so just say that
06:48:32 <floodious> which is more honestly "graphical + user interface"
06:48:39 <floodious> UI = user interface = user input
06:49:40 <dwfreed> so why can't you use user input, so it's more clear what you're referring to, if they're all equal
06:49:54 <floodious> if it helps, assume I meant "U = user, I = input"
06:50:11 <floodious> if i mean graphics, I'll say "GUI"
06:50:48 <floodious> anyway even so, separating the UI message loop from the gameloop and redraw is hairy as it is
06:51:09 <dwfreed> which is why most games don't do it
06:51:30 <floodious> most games don't do so, since the gameloop doesn't normally do heavy processing in a single thread but launches additional threads for stuff like large file import/export and so on
06:51:54 <floodious> a lot of programs suffer from blocking the UI during processing, which sucks
06:52:21 <dwfreed> factorio doesn't, for example (which caused a huge issue when 0.17 first came out on macOS, because the message queue was receiving a ton of irrelevant messages)
06:56:57 <floodious> in this case the issue looks to be that the UpdateWindows() is synchronous with GameLoop(), so when heavy processing happens in UpdateWindows(), the game + UI + redraw all grind to a halt
06:57:34 <floodious> neither is tied to real graphical frame updates, they can happen freely between redraws as far as I can see
06:58:58 <floodious> haven't gotten to the graphical side yet
07:01:41 <floodious> I thought at first that limiting UpdateWindows() and making it asynchronous with GameLoop() and the UI window loop might help... obviously the source of the problem is the heavy processing itself, but it presents a symptom that reveals a larger design issue that brings to mind many other existing symptoms like cursor lag
07:27:35 <floodious> it seems all drawing is also single-threaded, only the OS level blit is threaded
07:31:18 <floodious> so this code is indeed bugged, but not in terms of "doesn't meet aims of design", rather the design was faulty to begin with
07:31:19 <floodious> hundredth_timer.SetInterval(3000); // Historical reason: 100 * MILLISECONDS_PER_TICK
07:31:33 <floodious> the 100th is of real-time, not game ticks
07:32:03 <floodious> but it's synchronous with game ticks and does not adapt to frame-rate
07:33:55 <floodious> question is, should the windows update every N game ticks, or every N milliseconds real-time, or some relationship to frames displayed (which is always synchronous with game ticks ATM, which is always synchronous with real-time)
07:34:14 <floodious> there is no scaling at all
07:37:32 *** Smedles has joined #openttd
08:23:12 *** snail_UES_ has joined #openttd
08:30:21 <floodious> I think in this case the 100th needs to be of game ticks, not the period of time a game tick _should_ take, but actually once every 100 successful ticks
08:31:07 <floodious> to achieve that, UpdateWindows() requires a tick count variable incremented once per actual game tick, regardless of how long that took or what the real-time clock is
08:31:53 <floodious> when the game-time slows, the portions of UpdateWindows() which rely on game-time will also slow proportionately
08:32:16 <floodious> which makes perfect sense for stuff like updating the town list to display changes in population
08:32:36 *** Progman has joined #openttd
08:34:53 <floodious> some clarification would be beneficial too, such as defining _realtime_tick is "real-time in milliseconds", nothing to do with "game-time"
08:35:38 <floodious> it happens to be incremented when GameLoop() executes, but is AFAIK just real-time ms
08:39:38 *** andythenorth has joined #openttd
08:39:40 <andythenorth> o/
08:39:57 <floodious> you missed all my flooding the channel with ranting, hurray!
08:40:06 <floodious> congratulations!
08:42:52 <floodious> i'd change _realtime_tick to _realtime_ms
08:49:09 <floodious> or just fix the comment: The elapsed real time in ms, updated once per GameLoop() tick.
08:50:33 <floodious> unfortunately even that's hazy, since it's also forcibly updated from within modal loop(s?)
08:56:32 *** snail_UES_ has quit IRC
08:59:54 *** WormnestAndroid has quit IRC
09:00:16 *** WormnestAndroid has joined #openttd
09:06:26 *** sla_ro|master has joined #openttd
09:25:43 *** HerzogDeXtEr has joined #openttd
09:35:59 *** nielsm has joined #openttd
09:44:34 *** Smedles has quit IRC
09:46:16 *** Smedles has joined #openttd
10:01:54 <floodious> some heightmap progress: https://i.imgur.com/a6x8rz8.png (10k x 10k, 9 quads out of 24 total, still missing all additional river data, only rivers present are lower-right delta pair)
10:02:38 *** WormnestAndroid has quit IRC
10:02:50 *** WormnestAndroid has joined #openttd
10:10:20 *** Mazur has joined #openttd
10:14:00 <nielsm> morning
10:14:47 <andythenorth> moin nielsm
10:52:34 *** Wolf01 has joined #openttd
10:53:29 *** Lejving_ has joined #openttd
10:58:24 *** supermop_Home_ has quit IRC
10:59:00 *** Mazur has quit IRC
11:04:02 *** Lejving has quit IRC
11:04:02 *** Wolf01 has quit IRC
11:04:02 *** D-HUND has quit IRC
11:04:02 *** lpx has quit IRC
11:04:02 *** Osai has quit IRC
11:09:24 *** debdog has joined #openttd
11:09:56 *** Osai has joined #openttd
11:09:56 *** Wolf01 has joined #openttd
11:10:52 *** andythenorth has quit IRC
11:14:17 *** lpx has joined #openttd
11:14:59 <DorpsGek_III> [OpenTTD/OpenTTD] astetyn opened issue #7901: Train prefers service in depot over station https://git.io/Jeh7q
11:19:18 <DorpsGek_III> [OpenTTD/OpenTTD] nielsmh commented on issue #7901: Train prefers service in depot over station https://git.io/Jeh7q
11:27:51 <DorpsGek_III> [OpenTTD/OpenTTD] astetyn commented on issue #7901: Train prefers service in depot over station https://git.io/Jeh7q
11:34:58 <DorpsGek_III> [OpenTTD/OpenTTD] nielsmh commented on issue #7901: Train prefers service in depot over station https://git.io/Jeh7q
11:44:24 <DorpsGek_III> [OpenTTD/OpenTTD] astetyn commented on issue #7901: Train prefers service in depot over station https://git.io/Jeh7q
11:46:35 <michi_cc> nielsm: Changing the NTDDI_VERSION etc defines has no effect itself, but it means that the minimal SDK version for compiling increases (no problem there due to c++11 anyway) and that you can accidentally create an exe that only runs on newer windows.
11:59:05 *** Samu has joined #openttd
12:33:35 *** frosch123 has joined #openttd
12:48:06 *** zvxb has joined #openttd
12:59:56 *** Execthts has quit IRC
13:00:13 <Samu> hi
13:11:41 *** Exec has joined #openttd
14:23:31 *** NGC3982 has quit IRC
14:28:16 *** Flygon has quit IRC
14:52:53 *** andythenorth has joined #openttd
14:55:42 <andythenorth> yo
15:02:47 <nielsm> try out something: https://0x0.st/znGz.png
15:03:25 <nielsm> for comparison: https://0x0.st/znGK.png
15:03:34 <nielsm> (though different font, try to ignore that)
15:05:49 <nielsm> because that "Min ' ' ' ' Max" scale markings has been annoying me for a long time, it looks bad
15:24:05 *** glx has joined #openttd
15:24:05 *** ChanServ sets mode: +v glx
15:26:23 *** Mazur has joined #openttd
15:30:22 <DorpsGek_III> [OpenTTD/OpenTTD] nielsmh opened pull request #7902: Wedge volume control sliders https://git.io/Jejfp
15:32:21 <andythenorth> aliased edges bother me greatly
15:32:26 <andythenorth> goes it throw out limitation?
15:33:02 <nielsm> ?
15:33:13 <nielsm> making an AA fill will be problematic I think
15:33:29 <andythenorth> yes I agree :)
15:33:36 <andythenorth> are wedges widely used?
15:33:43 * andythenorth looking for examples to steal from
15:34:20 <nielsm> volume control from my music player: https://0x0.st/znDD.png
15:34:36 <andythenorth> oof https://f90.co.uk/assets/images/labs/mac-php-js-volume-control/desktop-home.jpg
15:34:57 <andythenorth> https://www.land-of-web.com/wp-content/uploads/2012/02/1324.jpg
15:35:45 <nielsm> hm this probably looks better: https://0x0.st/znDk.png
15:35:48 <andythenorth> let's see
15:35:52 <andythenorth> yes
15:35:59 <andythenorth> I just wondered about using vertical bars of increasing height
15:36:07 <andythenorth> probably more work than a triangle shape :D
15:36:41 * andythenorth photoshop
15:39:55 <andythenorth> basic improvement https://dev.openttdcoop.org/attachments/download/9595/volume-slider-1.png
15:42:41 <andythenorth> majority of UI controls I can find seem to be a bar, not a wedge, more space efficient
15:42:51 <andythenorth> I'm on the fence, the current one does suck
15:42:57 <LordAro> nielsm: yeah, just the one non-aliased edge looks better
15:43:10 <LordAro> though andy's improvement is better
15:43:40 <andythenorth> the min-max marker positions are the real issue?
15:43:58 <andythenorth> also it's non-discrete :D
15:44:20 <andythenorth> but the markers make it look like it should be discrete
15:44:52 <LordAro> a very basic improvement would be to remove the min-max strings
15:44:55 <LordAro> they don't add anything
15:45:16 <nielsm> https://0x0.st/znD5.png
15:46:11 <LordAro> looks blurry somehow
15:46:17 <andythenorth> mute and active speaker icons? o_O https://tr4.cbsistatic.com/hub/i/r/2016/10/05/a7dba7dd-32a0-4e48-aaec-ab97f219e753/resize/1200x/061ddf8281dfbdd21c7ac03e0381d40e/macsoundeckel092016.jpg
15:46:54 <andythenorth> oof the proportions of the window :)
15:47:13 <andythenorth> new jukebox? o_O
15:49:14 <nielsm> https://0x0.st/znDR.png
15:49:29 <LordAro> :+1:
15:49:54 <glx> yeah colour is better in this one
15:50:24 <nielsm> considering making a general DrawFramePolygon thing for this that selects shade of each outline depending on angle
15:50:29 <andythenorth> does it feel right to use?
15:50:40 <andythenorth> seems like it might not feel like it's in a track
15:51:39 <andythenorth> this was...unintuitive :P http://jsfiddle.net/onigetoc/j010vxc0/
15:53:45 <DorpsGek_III> [OpenTTD/OpenTTD] nielsmh updated pull request #7902: Wedge volume control sliders https://git.io/Jejfp
15:54:14 <andythenorth> https://lyonsden.net/wordpress_s/wp-content/uploads/2019/05/IMG_20190504_143428-1024x768.jpg
15:54:21 <glx> andythenorth: and it's not fully sync
15:54:38 <nielsm> actually, my GfxFillPolygon function fails in a weird way with FILLRECT_CHECKER mode and I don't understand why
15:54:39 <andythenorth> https://image.shutterstock.com/image-vector/knob-button-volume-slider-bar-260nw-619693832.jpg
15:55:07 <andythenorth> let's see
15:55:26 <andythenorth> must be something in the ultimate UI source http://www.dasprogramm.co.uk/
15:57:11 <andythenorth> still looks fresh, 60 years old http://www.dasprogramm.co.uk/shop/braun/view/50
15:57:48 <LordAro> andythenorth: nice
15:58:14 <LordAro> nothing really beats the look of audio equipment from that era
15:59:14 <peter1138> nielsm, bottom of wedge should be horizontal.
15:59:16 <andythenorth> nope
15:59:18 <peter1138> Oh.
15:59:22 <peter1138> The image changed.
15:59:39 <nielsm> and in RTL: https://0x0.st/znkz.png
15:59:41 <andythenorth> hmm all the RL audio gear has rotary knobs, but they're crap on screens
15:59:49 <peter1138> I had a late lunch. It was salad. With a couple of bao buns.
16:00:29 <LordAro> nielsm: i wonder whether the controls should be reversed in RTL
16:00:50 <LordAro> RTL languages aren't just "reverse everything"
16:00:51 <nielsm> 1x scale: https://0x0.st/znki.png
16:02:18 <nielsm> today's bike shed: volume sliders
16:02:19 <nielsm> :D
16:02:22 <peter1138> LordAro, no but if that's how the slider currently operates, the wedge needs to be correct :-)
16:04:59 <andythenorth> lol edition https://dev.openttdcoop.org/attachments/download/9596/volume-slider-1.png
16:05:21 <LordAro> andythenorth: :D
16:05:32 <peter1138> LGBTQ
16:05:35 * andythenorth back to trains
16:05:45 <andythenorth> peter1138: no blue or purple or pink
16:06:13 <nielsm> well that slider implies that more volume is greener
16:06:15 <nielsm> is that really true?
16:06:19 <andythenorth> we could do a nyan cat version
16:07:06 <peter1138> Bah at this Doom level.
16:08:29 <nielsm> and in TTD DOS: https://0x0.st/znkK.png
16:08:53 <nielsm> it has a "VU meter" indicating roughly how many notes are active in music playback atm
16:09:17 <peter1138> Has a slowly descending circular room with monsters spawning, nowhere to hide...
16:09:35 <peter1138> Are we missing the meter? Heh
16:09:55 <glx> we used to have it, but it was static IIRC
16:11:26 <nielsm> it would be very hard to implement with the current music driver model
16:11:26 <LordAro> it had been broken for a very long time
16:12:32 <glx> https://github.com/OpenTTD/OpenTTD/commit/ba7611ed131b0f99dae4ca974aa1cf9c6114b6f5#diff-1cb7ff4f0ed8c7e4020679ea03e670d6
16:13:13 <andythenorth> I miss that VU meter :)
16:13:29 <peter1138> Not too hard to add it back, then ;-)
16:13:33 <andythenorth> also the slider control tracks look better at that zoom level
16:13:51 <andythenorth> when I say 'I miss it', I haven't played the midi track for about 10 years :P
16:13:55 * andythenorth should declare
16:14:01 <nielsm> yeah the sprite font 1x gui sliders look fine
16:14:21 <nielsm> but it doesn't scale well to vector fonts or 2x gui
16:14:29 <andythenorth> nope
16:14:43 <andythenorth> I should scale my eyes, then switch back to 1x zoom
16:15:55 <andythenorth> just 18.99 https://www.amazon.co.uk/Professional-Headband-Magnifier-Magnifying-battery/dp/B01D86CQF4
16:22:58 <peter1138> Just use 640x480.
16:24:44 <andythenorth> let's see
16:25:50 <peter1138> 640x480 on a 14" screen, mind you.
16:26:31 <andythenorth> minimum monitor resolution I can do is 1024x640
16:26:34 <andythenorth> much easier to read
16:26:41 <andythenorth> can't fit much in tho :)
16:29:42 <andythenorth> photoshop at 1024x640 :P
16:29:47 <andythenorth> it's all just palettes
16:29:56 <andythenorth> no room for image
16:39:18 *** supermop_Home has joined #openttd
16:39:28 <supermop_Home> hi andy
16:39:53 <supermop_Home> ooops i left this game on all night unpaused
16:39:56 <andythenorth> yo
16:42:01 <supermop_Home> maybe i'll buy myself a rhino license this year
16:48:23 *** NGC3982 has joined #openttd
16:49:16 <milek7_> nielsm: why it would be hard?
16:49:23 <milek7_> can't just MxMixSamples write last sample to some global var?
16:49:45 <nielsm> not really when the music driver outputs to a hardware midi port
16:50:00 <nielsm> or when the music driver otherwise doesn't play through the same mixer as the rest
16:50:26 <nielsm> in fact, only the fluidsynth driver uses the game's mixer for output, everything else plays around it
16:51:25 <milek7_> huh, does anybody still have hardware midi?
16:51:34 <nielsm> me :)
16:53:44 <nielsm> a while ago someone also posted on the issue tracker about using extmidi with aplaymidi (which sends to a hardware port) having issues with skipping tracks causing hanging notes
16:54:08 <nielsm> (which is expected since extmidi just kills the process it spawned mercilessly)
16:56:00 <milek7_> how even extmidi works when music is in tar archive?
16:56:32 <nielsm> unpacks it I assume
16:56:44 <nielsm> similar to how the dos music decoder does
16:57:05 <nielsm> actually I don't think music in a tar archive is supported
16:57:06 <LordAro> in theory it could just read the file via offsets - tar is just a container after all
17:04:02 <frosch123> LordAro: rule of thumb for rtl: if the reversed thing looks weird to you, it's probably correct
17:04:18 <LordAro> frosch123: quite possibly
17:04:43 <LordAro> relatedly, i notice #6666 is still open
17:07:33 <frosch123> https://material.io/design/usability/bidirectionality.html <- that explicitly mentions the volume slider
17:09:00 <frosch123> LordAro: 7480 is merged though
17:09:40 <LordAro> the issue was apparently not fully fixed
17:47:44 <nielsm> bad ideas: https://wiki.openttd.org/User:Nielsmh/New_music_set_format
17:50:46 <nielsm> https://www.tt-forums.net/viewtopic.php?p=1228200#p1228200 wow hamachi, haven't heard that in a long time
17:51:08 <frosch123> cat is uncompressed wav/voc, isn't it?
18:00:32 *** Wormnest has joined #openttd
18:14:19 <andythenorth> so vehicle groups...and extended vehicle info / backstory thing? o_O
18:14:46 <andythenorth> or maybe the extended vehicle info / popup window thing is the only way to get to the variants?
18:14:48 <andythenorth> o_O
18:14:53 <nielsm> frosch123 not quite, it's just an archive file
18:15:05 <nielsm> that's most famous for containing sampled sound effects
18:15:17 <nielsm> but it also used for the music data in the DOS version
18:15:42 <frosch123> ah, so you want to store midi inside cat?
18:15:51 <nielsm> no, it _is_ stored inside cat :)
18:16:14 <nielsm> DOS TTD has gm.cat, adlib.cat, roland.cat containing music in various formats
18:16:41 <frosch123> ok, well my point was, i hope you do not want to store gigabytes of uncompressed cd audio
18:16:47 <nielsm> yeah no
18:17:48 <andythenorth> stream it!
18:17:56 <andythenorth> full circle, reverse engineer spotify!
18:18:19 <andythenorth> did Ludde actually build spotify, or just work there?
18:18:30 <nielsm> I want to add sampled music support at some point (have a WAV file proof of concept somewhere) but whether bananas would want to host music sets containing a gigabyte of flac files is another question :P
18:18:50 <andythenorth> sponsored edition :P
18:19:40 <LordAro> :D
18:19:47 <andythenorth> oh OpenTTD has scrolled to the N-most corner of the map and won't come out
18:19:48 <andythenorth> lolz
18:19:55 <andythenorth> I did change newgrfs in this game though
18:21:45 <DorpsGek_III> [OpenTTD/OpenTTD] nielsmh commented on pull request #7902: Wedge volume control sliders https://git.io/Jejkv
18:23:20 <LordAro> andythenorth: there are several things i might expect changing newgrfs to cause
18:23:33 <LordAro> affecting controls is not one of them
18:24:19 <andythenorth> it might be a bug reported before, I didn't look :)
18:24:24 <andythenorth> such diligence
18:24:35 <LordAro> sounds like stuck keyboard input
18:24:38 <LordAro> try pressing keys
18:26:53 <milek7_> 'Do not mirror media playback buttons and the media progress indicator as they refer to the direction of tape being played, not the direction of time. ' [https://material.io/design/usability/bidirectionality.html]
18:27:16 <andythenorth> nah it's some scroll issue
18:27:20 <andythenorth> I restarted, it's gone
18:28:31 <frosch123> milek7_: there was an older site which showed hardware vhs players with mirrored buttons
18:28:59 <andythenorth> oof
18:29:07 * andythenorth wonders about daylength
18:29:45 <frosch123> just wait until daylength is solved like subsidiaries
18:30:07 <andythenorth> looking if GS API has GSCheat
18:30:19 <andythenorth> might be looking wrong, can't see it
18:30:28 <andythenorth> GSDate is get, not set
18:30:30 <frosch123> it definitely has not
18:30:59 <andythenorth> I did have a patched client that reset the year on a tick-tock basis
18:31:01 <andythenorth> so 2:1
18:31:09 <andythenorth> but I lost the patch and Eddi claims it wasn't him
18:31:49 <andythenorth> I wonder if resetting every month would mess up newgrf less :P
18:32:39 <frosch123> maybe you can read up on leap seconds, and learn from those issues
18:32:40 <milek7_> it made X-axis on graphs wrong
18:34:13 <nielsm> okay checkering fixed https://0x0.st/zndk.png
18:34:59 <andythenorth> hmm
18:35:08 <andythenorth> nielsm: that's neat :)
18:35:17 * andythenorth has a cdist link that won't go away
18:35:35 <andythenorth> can I traverse the linkgraph somehow and sever the node? :P
18:35:54 * andythenorth imagines the savegame is not human readable
18:36:16 <andythenorth> I've been waiting about 50 years for cdist to learn there's no acceptance at the station it's sending stuff to
18:38:06 <LordAro> is the linkgraph saved?
18:40:13 <andythenorth> I assume so, as this link is persisting across restarts?
18:40:33 <andythenorth> oof 19fps
18:40:36 <andythenorth> 100% CPU
18:40:42 <andythenorth> this savegame might be dead
18:40:47 <FLHerne> andythenorth: Are you sure it doesn't actually exist?
18:40:56 <FLHerne> e.g. some train hiding in a depot, or refit orders
18:41:05 <andythenorth> there's a 'refit any available' at the pickup
18:41:15 <andythenorth> but that wasn't the cause
18:41:23 <FLHerne> Or locos with annoying small-amount-of-mail capacity :P
18:41:34 <andythenorth> I accidentally sent 1 train with Coal Tar wagon to the station 50 years ago
18:41:50 <andythenorth> I've since deleted that train, but the link persists because of 'refit any available' on the other trains
18:42:02 <andythenorth> it's not a bug, just annoying
18:42:11 <andythenorth> the fix would be to delete the route and rebuild it
18:42:52 <andythenorth> ok, 100 years of game, 133 trains, 37 RVs 77 ships 7 aircraft
18:43:01 <andythenorth> 20fps isn't really fun though, so might be time to stop
18:43:07 <andythenorth> I guess I broke it :)
18:45:19 <nielsm> okay looks like recolour and concave shapes both work: https://0x0.st/znd7.png
18:45:29 <andythenorth> :)
18:45:35 <andythenorth> going to do soviet flag etc?
18:45:40 <andythenorth> overlaid?
18:46:04 <nielsm> was just the first example I could think of that used recolour mode :P
18:46:26 * andythenorth wonders if FIRS is the cause of the fps issues
18:46:36 <andythenorth> it does a lot of stupid things
18:46:56 <nielsm> hey, I have a patch that can help diagnose that!
18:47:19 <nielsm> starface: https://0x0.st/zndC.png
18:47:25 <nielsm> (the code)
18:49:13 <andythenorth> the fps is pretty closely correlated with redrawing dirty blocks
18:49:19 <andythenorth> unless that's confirmation bias
18:49:36 <andythenorth> FIRS industries tend to have animation per tile, even if it's not doing much
18:49:41 <nielsm> yeah that's what I also kind of get when I try newgrf_profile on FIRS 3
18:49:43 <andythenorth> so 2-3 industries on screen kills fps
18:49:51 <nielsm> it spends a lot of time getting sprites for the tiles
18:49:53 <andythenorth> but also a busy train junction absolutely murders fps
18:50:08 <nielsm> some very deep callbacks
18:52:27 <DorpsGek_III> [OpenTTD/OpenTTD] nielsmh updated pull request #7902: Wedge volume control sliders https://git.io/Jejfp
18:53:09 <DorpsGek_III> [OpenTTD/OpenTTD] JGRennison opened pull request #7903: Fix: Assertion failure when post road-works cleanup removes all road pieces https://git.io/Jejkd
18:54:59 <andythenorth> hmm I could increase all the vehicle speeds to compensate for the fps
18:55:50 <andythenorth> @calc 87 * (1/0.6)
18:55:50 <DorpsGek> andythenorth: 145
18:55:56 <milek7_> variable length tick?
18:55:58 <andythenorth> 145mph train instead of 87mph
18:56:10 <andythenorth> oh but now it's 18fps
18:56:24 <andythenorth> @calc 18/34
18:56:24 <DorpsGek> andythenorth: 0.529411764706
18:56:35 <andythenorth> @calc 87 * (1/0.53)
18:56:35 <DorpsGek> andythenorth: 164.150943396
18:56:37 <andythenorth> hmm
18:58:05 <andythenorth> making everything transparent doesn't seem to help
18:58:10 <DorpsGek_III> [OpenTTD/OpenTTD] nielsmh approved pull request #7903: Fix: Assertion failure when post road-works cleanup removes all road pieces https://git.io/Jejkj
18:58:17 <andythenorth> is transparency applied after resolving all the sprites?
18:59:57 <nielsm> oh, no wonder I don't remember that setting (mod_road_rebuild) being there, it doesn't exist in the settings GUI
19:00:06 <nielsm> just a secret bonus feature
19:06:10 <nielsm> bonus-bonus feature I kind of want to make with this polygon filling function, later: replace some of the icon sprites used in text (close button X, other window caption buttons, the vehicle/transport mode icons) with vector shapes that can be rendered to a sprite of appropriate size for the selected font sizes
19:28:23 * andythenorth wonders about benchmarking same OpenTTD game on different OS / hardware
19:28:48 <andythenorth> not sure how we'd control for variation
19:30:07 <nielsm> hmm... maybe do something similar to "timedemo" in quake engine
19:30:47 <nielsm> enable "benchmarkgame" mode from console and give a number of ticks, the next savegame you load will disable interaction and run for that many ticks on fast forward
19:30:59 <nielsm> then go back to main menu and print the time taken in the console
19:31:16 <andythenorth> kind of wondering if I should switch to Windows
19:31:17 <nielsm> AI and GS should not be loaded in that mode either
19:31:31 <andythenorth> or if this is just crap hardware
19:33:29 <Samu> terron only thinks of crashing on my custom openttds :(
19:33:40 <Samu> have yet to have this crash on an official build
19:34:16 <LordAro> nielsm: isn't that basically how the ai regression tests work?
19:34:22 <LordAro> (except with the null video driver)
19:34:36 <nielsm> LordAro yeah :)
19:35:06 <LordAro> not sure if that runs on fast forward though
19:35:07 <nielsm> but for other benchmarking you probably do want to test the video output as well
19:35:17 <LordAro> mm
19:35:31 <nielsm> along with what happens when sprites need to be requested and so on
19:36:15 <andythenorth> https://dev.openttdcoop.org/attachments/download/9597/slow_on_macos.zip
19:36:21 <andythenorth> runs around 0.7x most of the time
19:36:30 <andythenorth> sometimes 0.5x
19:36:36 <andythenorth> occasionally 1x
19:36:45 <andythenorth> it's slow enough to no longer be fun, everything lags
19:37:09 <andythenorth> in an area with no trains / industry it's 1x trivially, so my system can run the game
19:38:01 <andythenorth> I'm running self-compiled nightly, I should try it in 1.10 beta
19:40:07 <Samu> im not reporting this anymore
19:43:14 <andythenorth> official beta is better fps
19:43:38 <floodious> did anyone look at that timing bug?
19:43:51 <floodious> i discovered the issue: there is no game tick reference in the game, at all
19:43:52 <floodious> zero
19:43:54 <LordAro> floodious: no one wrote anything on the issue, so no
19:44:22 <floodious> the only reference is real-time-ms, which happens to be "updated each game tick", but otherwise has nothing at all to do with game ticks
19:44:40 <floodious> so the solution: need to add a game-tick counter to be referenced to by code that needs to execute every N game ticks
19:45:10 <nielsm> you haven't looked hard enough
19:45:36 <floodious> and i suggested fixing the comment on the existing ms reference counter: _realtime_tick = The elapsed real time in ms, updated once per GameLoop() tick.
19:45:37 <nielsm> date_func.h has uint16 _tick_counter
19:45:46 <DorpsGek_III> [OpenTTD/OpenTTD] DorpsGek pushed 1 commits to master https://git.io/JejLJ
19:45:46 <DorpsGek_III> - Update: Translations from eints (by translators)
19:46:00 <floodious> who updates _tick_counter
19:46:06 <nielsm> the game loop
19:46:29 <floodious> so it's not available outside, but can be used in UpdateWindows()
19:46:39 *** Wormnest has quit IRC
19:47:01 <floodious> so solution: #1) fix comment on _realtime_tick #2) replace any code intended to execute N ticks with _tick_counter
19:47:21 <floodious> _realtime_tick has nothing to do with game time
19:47:38 <floodious> anything using it as a reference for elapsed in-game time will fail, and is bugged
19:48:40 <floodious> any arbitrary amount of ms can pass during a single tick
19:49:44 <nielsm> andythenorth: I'm able to run that game at 200+ fps
19:49:56 <andythenorth> ok
19:50:12 <andythenorth> do you have some huge CPU?
19:50:15 <nielsm> although I am missing the chips_objs.grf, and the iron horse version you included seems to be wrong
19:50:44 <nielsm> core i5-4460 3.2 ghz
19:50:49 <andythenorth> chips should be on bananas, and the horse has just been reload many times
19:51:58 <nielsm> nope chips_objs.grf is not on bananas it seems
19:52:14 <andythenorth> oh
19:52:18 *** jlx_ has joined #openttd
19:52:20 <andythenorth> that's odd :)
19:52:24 <andythenorth> is your build self-compiled?
19:52:50 <nielsm> yes
19:53:16 *** WormnestAndroid has quit IRC
19:53:27 *** WormnestAndroid has joined #openttd
19:53:30 <andythenorth> I am getting better results with the official binary, maybe I've got debug turned up
19:55:22 <andythenorth> how do I compile with NO_DEBUG_MESSAGES?
19:56:38 <andythenorth> -DNO_DEBUG_MESSAGES=1
19:56:39 <andythenorth> ?
20:02:35 <andythenorth> can't find NO_DEBUG_MESSAGES anywhere in the repo to crib from :)
20:05:04 <floodious> i'm able to reproduce the game slowdown with the version i have, displaying town directory
20:05:55 <floodious> the whole thing runs at slug pace, but by replacing _realtime_tick delta_ms with a new delta_ticks computed from _tick_counter, it doesn't exponentially spiral to a halt
20:06:43 <floodious> i'm only getting pulses where sorting the list takes 500ms +
20:07:13 <nielsm> it makes sense for the town directory to re-sort on game time and not real time, since towns' data change in game time and not real time
20:07:31 <floodious> yes, so i set it to 100 ticks, not 100*ms_per_tick
20:08:14 <floodious> since each tick atm is taking 25 ms, and rendering/sorting the town list is 500 ms++
20:08:21 <floodious> so tick = ~525 ms
20:10:47 <andythenorth> nielsm: what fps do you get when you open train list in that save?
20:11:17 <andythenorth> also when did we gain a plot of the fps? :o
20:12:55 <floodious> displaying timing graphs: https://i.imgur.com/byCoSkq.png (looks like it claims 1032 ms pulses, i was reading averages)
20:14:54 <nielsm> https://0x0.st/znn5.jpg
20:16:17 <floodious> on a 2k map with 1500+ towns population 1.5 million? :)
20:17:02 <floodious> i misread that, pop = 3 mil
20:17:31 <nielsm> I'm just testing andy's save here
20:18:02 <floodious> could it be settings?
20:18:10 <andythenorth> https://dev.openttdcoop.org/attachments/download/9598/vehicle-window-windowshade-fps.m4v
20:18:25 <nielsm> no it's probably differences between the video output on windows and mac
20:19:14 <floodious> doesn't it use the same renderer (sse2 blit?) and only the bitmap blitter is actually different?
20:19:19 <nielsm> well okay shading/unshading shouldn't affect video output
20:19:51 <andythenorth> the mac performance is known to be very poor
20:20:44 <floodious> i know xcode is hell to work with because they're even more picky than gcc, and loaded with bugs in their c++ implementations
20:21:09 <floodious> but the underlying systems in my experience have performed near identically
20:21:19 <LordAro> last time i checked xcode uses clang...
20:21:55 <floodious> not just clang itself, but the other elements of their IDE with error detection and such failing or locking up on perfectly valid code
20:22:16 <nielsm> yeah though it's their own special version of clang
20:22:27 <nielsm> but afaik several of the clang main committers are employed at apple
20:22:48 <LordAro> apple is one of the founding "members" of clang
20:23:58 <nielsm> andythenorth: when you do that shade/unshade, do any of the game loop timings change, or just the rendering timing that you have the graph of up?
20:25:05 <andythenorth> possibly, I'll video
20:25:55 <nielsm> if it's just 2 ms extra in total but it causes fps to drop from 33-34 down to 16-17 then there's something weird with timing or time slices or vsync going on
20:26:41 <nielsm> i.e. it crosses some threshold that makes something decide to skip every second chance of processing a frame
20:33:23 <andythenorth> https://dev.openttdcoop.org/attachments/download/9599/vehicle-window-windowshade-fps-2.m4v
20:33:26 <andythenorth> inconclusive imho
20:36:42 <floodious> town dir: even with the 100 tick mod, sorting by name or rating is still getting sporadic peaks of 80 ms
20:38:05 <floodious> that's obviously not due to OnHundredthTick since i set the interval = 1e9 and it never gets called
20:38:14 *** HerzogDeXtEr has quit IRC
20:38:47 <floodious> population sort peaks at 8 ms instead
20:40:46 <floodious> nope, double-checked, it's OnHundredthTick
20:42:16 *** Arveen2 has quit IRC
20:43:39 <floodious> triple check: it isn't OnHundredthTick... wtf
20:53:12 <Samu> hi
20:53:14 <Samu> :p
20:57:42 <floodious> most sorting seems to be triggered by forcerebuild calls via changes to towns
20:58:40 <floodious> a limit could be imposed by marking a "rebuild needed" flag and only checking and actually rebuilding in the OnHundredthTick trigger
21:00:10 <nielsm> probably a good idea yes
21:00:28 <floodious> obviously the heavy lifting is mistakenly being directly applied elsewhere, somehow... i'm switching to debug since the compiler inlined too much stuff and breakpoints weren't working right
21:02:44 <floodious> it's triggered in OnPaint() too
21:03:18 <floodious> town_gui.cpp ln 951: if (this->towns.NeedRebuild()) this->BuildSortTownList();
21:03:28 <floodious> so commenting that line out might solve it
21:04:48 <Samu> in 1.9.3 there's no issue
21:05:33 <floodious> the fact redraw triggers a rebuild is a severe bug
21:05:47 <floodious> so just commenting that ln 951 fixes it
21:06:01 <floodious> it draws the existing (old) list, and the rebuild happens on a timer
21:06:39 <floodious> the heavy pulses then only happen every 100 ticks, which i've also fixed the timebase (ticks, not realtime ms)
21:07:11 <Samu> line 951 is a }
21:07:29 <floodious> well, the if (this->towns.NeedRebuild()) this->BuildSortTownList();
21:07:37 <floodious> in whatever revision, whatever line it moves to
21:07:39 <Samu> 949
21:08:27 <floodious> it improves redraw performance in normal situations since you're only wanting to redraw to fill that area on the screen, not "update" the list
21:09:15 <Samu> testing
21:10:15 <floodious> in my GUIs I use window buffers so such updates are fast blitter copies instead of manually redrawing into a single canvas bitmap, but with too many windows open that causes memory issues... modern OSes also use buffers in the hardware, since you have GPUs with several gigs and window buffers take 100s of megs at most generally
21:10:31 <floodious> that only matters when redraw is also expensive
21:11:09 <Samu> i suspect it's the query box
21:11:51 <floodious> what is?
21:12:55 <floodious> unchecking the query triggers a smaller spike (31%?) for me too, but that doesn't seem like a major issue ... it might make sense to also delay the rebuild from the query change too
21:13:20 <floodious> but that would introduce UI latency
21:13:26 <floodious> usually considered bad
21:14:00 <floodious> unchecking, unfocusing i mean
21:15:45 <Samu> gonna reroll to before https://github.com/OpenTTD/OpenTTD/pull/7621
21:15:48 <Samu> rebase
21:15:50 <nielsm> the ottd display model does work with dirty rectangles
21:16:12 <floodious> https://i.imgur.com/AjToOG2.png
21:16:19 <nielsm> when a window/widget is asked to repaint, it can check the _cur_dpi (afaik) for the dirty rectangle
21:17:02 <floodious> the issue is repaint was triggering heavy lifting (rebuilding / sorting the list), and since we have the existing old list that can just be redrawn anyway
21:17:23 <floodious> if the list wasn't yet built, that may be an issue
21:17:43 <floodious> but dirty rects wouldn't optimize away needing to re-fill the graphical content of the town directory window
21:18:08 <floodious> if something dirtied the rect, triggering the redraw
21:18:32 <floodious> window buffer could optimize away the redraw itself, making it a fast copyblit, but that's it
21:19:03 <nielsm> true
21:19:22 <nielsm> there isn't any good way to allocate a back buffer and render to instead
21:19:34 <nielsm> in fact that would require massive gymnastics
21:20:03 <floodious> i have a quite nice implementation, but yeah given the existing openttd structure, wouldn't want to jump in that
21:21:34 <nielsm> the best long term solution would probably be to scrap the entire current display pipeline and replace with something opengl or such, and maybe make every window be a texture on its own
21:21:42 <Samu> erm how do I rebase to a build in the past?
21:21:54 <Samu> somehow I can't do it again
21:22:20 <nielsm> how many commits do you want to put on top of it?
21:22:31 <Samu> 0
21:22:43 <nielsm> then it's not a rebase
21:22:45 <Samu> want to go to before https://github.com/OpenTTD/OpenTTD/commit/196d586849684e62aa9a40093f2a1ce60e1cd53f#diff-294725a20bc5c3ec869659c417143f65
21:23:03 <nielsm> if you just want to build an older version, use "git checkout revisionhash"
21:23:12 <Samu> ah, i see
21:24:27 <Samu> testing the commit before that
21:24:30 <Samu> see if it's slow
21:27:02 *** frosch123 has quit IRC
21:30:55 <Samu> nop, it's much faster
21:32:01 <Samu> there's the occasional spike, but much less noticeable
21:34:03 <Samu> how do i get out of this detached head mode?
21:34:24 <nielsm> checkout master
21:34:28 <nielsm> or whatever branch you want
21:36:16 *** mreow has joined #openttd
21:37:02 <mreow> hi. im using firs, i wonder, why cant i get farm supplies nor fruits to load in my train?
21:37:20 <mreow> do i have to supply the bulk terminal with something?
21:37:25 <Samu> oh snap, there was an easier way with visual studio
21:37:37 <mreow> (oops sorry if its dev chan)
21:37:47 <nielsm> mreow no, they produce without any input
21:37:47 <andythenorth> mreow: do you have wagons for those cargos?
21:37:56 <mreow> i think i do have
21:38:19 <mreow> i mean, it does indeed look like these wagons dont allow this cargo but huh
21:38:24 <andythenorth> hmm
21:38:29 <andythenorth> this keeps coming up on reddit
21:38:44 <mreow> oh i think why
21:39:08 <mreow> i didnt refit them
21:39:14 <mreow> i just bought the carts
21:39:16 <Samu> now with Commit 196d5868
21:39:18 <Samu> testing
21:39:27 <nielsm> mreow yeah that can do it
21:39:46 <mreow> i think that was that, thanks
21:39:51 <mreow> yep, totally :D
21:40:00 <nielsm> good news: in next version (will be 1.10) if you filter the purchase list by vehicles that carry a specific cargo, they auto-refit to that cargo on purchase
21:40:23 <nielsm> you can try 1.10 beta2 already now :)
21:40:32 <Samu> uggg, i found the faulty commit
21:41:10 <Samu> https://github.com/OpenTTD/OpenTTD/commit/196d586849684e62aa9a40093f2a1ce60e1cd53f
21:41:30 <mreow> im too lazy :D
21:41:32 <Samu> this causes all the lag in town directory
21:41:45 <floodious> mreow, the standard wagons can't carry non-standard cargo, and the system is a bit tricky to navigate because all the parts you need are more or less independent
21:42:20 <mreow> i mean, i had the wagons for that but i just didnt refit them properly; i bought them and left it like that
21:42:22 <floodious> to carry NARS cargo, you need a NARS compatible wagon/rolling stock set
21:42:51 <floodious> yep, refitting is a pain too, the orders happen backward if you use "refit at station" it needs to occur on a separate order before the loading order
21:43:24 <DorpsGek_III> [OpenTTD/OpenTTD] SamuXarick commented on issue #7899: Slow framerates with town list window https://git.io/JepK9
21:43:27 <floodious> on the same order "stop at station, refit to cargo, full load cargo" it refits last, so it'll sit and never load
21:43:59 <DorpsGek_III> [OpenTTD/OpenTTD] LordAro approved pull request #7903: Fix: Assertion failure when post road-works cleanup removes all road pieces https://git.io/JejqN
21:44:10 <DorpsGek_III> [OpenTTD/OpenTTD] LordAro merged pull request #7903: Fix: Assertion failure when post road-works cleanup removes all road pieces https://git.io/Jejkd
21:45:27 <mreow> oh, i didnt know you can do tricks like that
21:45:46 <floodious> sadly i've found in my limited experience it's 100% about tricks, never so simple as you think at first
21:47:15 <andythenorth> floodious: 'refit at station with full load' works fine
21:47:23 <andythenorth> any case where it doesn't is a bug
21:47:52 <floodious> i'd need to test it, but it never worked on a single order for me
21:48:18 <andythenorth> my orders always look like this https://dev.openttdcoop.org/attachments/download/9600/refit-orders.png
21:48:36 <floodious> possibly a bug in specific newgrfs
21:48:46 <andythenorth> the 'no loading' is required for cargodist btw
21:48:51 <andythenorth> in case the audience is wondering
21:48:57 <andythenorth> it prevents backlinks being created
21:50:23 <mreow> ho huh hmm
21:50:34 <DorpsGek_III> [OpenTTD/OpenTTD] LordAro commented on pull request #7902: Wedge volume control sliders https://git.io/JejmT
21:50:38 <floodious> very complicated for a sandbox game :)
21:51:07 <DorpsGek_III> [OpenTTD/OpenTTD] LordAro approved pull request #7900: Add: Highlight item under mouse in file browser https://git.io/JejmL
21:51:29 <DorpsGek_III> [OpenTTD/OpenTTD] LordAro merged pull request #7894: Fix #7587: Crash when loading saves with waypoints with invalid locations https://git.io/JexpT
21:51:30 <DorpsGek_III> [OpenTTD/OpenTTD] LordAro closed issue #7587: Loading old waypoints from savegame version 72 causes crash https://git.io/fjWZr
21:51:44 *** supermop_Home has quit IRC
21:51:47 <andythenorth> oof tech tree progression is hard
21:51:48 <DorpsGek_III> [OpenTTD/OpenTTD] LordAro merged pull request #7884: Fix #6667: Also recalculate bridge costs for 'spectated' AI companies https://git.io/JeA1Y
21:51:49 <DorpsGek_III> [OpenTTD/OpenTTD] LordAro closed issue #6667: Incorrect costs in bridge list after joining an AI company https://git.io/Jejmt
21:52:20 <DorpsGek_III> [OpenTTD/OpenTTD] LordAro merged pull request #7843: Industry directory cargo filtering https://git.io/Jei1a
21:53:04 *** supermop_Home has joined #openttd
21:53:32 <andythenorth> is there a hotkey for 'stop replacing vehicles'?
21:53:53 <andythenorth> clearing out auto-replace rules is the worst yak-shaving currently in the game
21:54:22 <floodious> did anyone adopt my tick timebase + redraw bug triggers town directory rebuild+resort changes? i'd need to create a github account to add my solution to the git comment thread or remember some existing account
21:54:52 <floodious> https://github.com/OpenTTD/OpenTTD/issues/7899
21:55:37 <LordAro> floodious: as we quite often have to tell Samu, anything said in irc is emphemeral - if it's not in an issue, it's going to get forgotten
21:55:44 <floodious> or should i go through the whole process of reporting that as a separate bug
21:56:06 <LordAro> i think it's probably a separate bug
21:56:19 <floodious> two infact, although they're all related to the same symptom
21:56:20 <LordAro> even if the fix for one might fix the other as well
21:56:36 <glx> floodious: I think the idea of really using ticks for tick stuff is good, but it should be said on github ;)
21:56:48 <floodious> the thread linked reported a symptom/cause which triggered the bugs i've fixed
21:56:53 <floodious> bah fine i'll make an account
21:58:48 <glx> oh and you can even open a PR if you have a fix :)
21:59:14 <floodious> if i learn how first
21:59:33 <floodious> git... ugggh
22:00:29 <glx> fork openttd to your github account, clone your fork to your machine, do your changes and commit them to a branch, push to github, open a pull request
22:00:58 <glx> first 2 steps needed only once ;)
22:01:46 <supermop_Home> andythenorth: how complex are the auto replace schemes you have going on at any given time?
22:04:40 <floodious> yes i know how to do the work itself, but how to actually get git working, successfully open firewall ports to make my version of git work correctly, successfully apply the patch to the proper branch and build a single, clean commit into a pull request is the real issue
22:04:47 <floodious> all that overhead = modern git tools
22:05:01 <nielsm> git can work over just outgoing https
22:05:07 <nielsm> or outgoing ssh
22:05:09 <floodious> i have 100% whitelist
22:05:15 <floodious> no connections not directly authorized
22:05:39 <floodious> the git toolchain has tens of different tools
22:05:52 <floodious> error reporting on a failure is a smug "something happened"
22:06:28 <nielsm> if you run git over ssh, it'll use the system ssh client and work through pipes
22:07:11 <floodious> i know... a week later after i get it all working, last time i tried to local clone the tree i ended up just grabbing the archive file since days later i couldn't get the git toolchain working
22:07:27 <floodious> anyway i'll just write an issue(s) to start
22:11:19 <andythenorth> supermop_Home: just Horse makes a lot of upgrades necessary :(
22:11:56 <supermop_Home> how often do you need to stop an upgrade?
22:12:37 <milek7_> floodious: i think all that problems are self-imposed ;)
22:12:52 <andythenorth> supermop_Home: when the list of old ones gets too long :)
22:13:25 <andythenorth> my current group has 12 old upgrades
22:13:26 <andythenorth> :P
22:15:11 <mreow> im curious, how much do you make in openttd in say, 1950-1960? if anyone plays in that period... like basically, first 10 starting years or something
22:17:08 <andythenorth> supermop_Home: should I? o_O https://en.wikipedia.org/wiki/Brighton_Belle
22:20:05 <floodious> milek7_, we should all be using whitelist-only, that's the only true secure method
22:20:09 *** sla_ro|master has quit IRC
22:20:18 <floodious> yes, certainly self imposed, but git is written by filthy non-secure methods
22:20:40 <floodious> it assumes a wild&free access to ports for network i/o
22:21:25 <milek7_> i prefer my system to not fight me trying to run anything
22:21:35 <LordAro> i'd be surprised if it used anything other than ssh/http as specified
22:21:38 <floodious> mreow, it's possible to get into millions quite easily, depending upon specific cargo, distances, running costs, etc
22:22:00 <mreow> oh, i clearly suck then
22:22:10 <floodious> nah, it depends so much on exact settings
22:22:18 <mreow> no breakage
22:22:32 <floodious> sometimes you can have only a few trains making millions, and the same trains with slightly different settings are in the red instead due to high running cost
22:22:50 <mreow> complex
22:23:02 <mreow> ive had million making lines much much latex
22:23:04 <mreow> later
22:23:19 <floodious> the game doesn't have even a simplified supply&demand economy, so cost vs. fees aren't balanced dynamically
22:24:51 <mreow> tho ive heard payments change over time? floodious
22:25:01 <floodious> normally for example people get mad that ordering some TV off amazon costs $100 to ship, but they fly the same distance themselves paying $800 even though they weight nearly the same, nearly same volume
22:25:36 <mreow> never heard of that tbh
22:25:44 <mreow> i mean, people complaining like that
22:26:05 <floodious> oh they do, there is a reason amazon's focus is on getting shipping costs as low as possible
22:26:27 <floodious> but that's real-world economics, which are far more complicated than the simple supply-side drive in ttd
22:27:19 <floodious> my point is for example grayhound bus service always made money by shipping packages, even if most people thought they were a passenger company, the passenger service never made enough on its own due to limited demand
22:27:50 <floodious> recently grayhound tried to redefine themselves as "a passenger company", and they went out of business in large areas of north america because of that
22:28:11 <floodious> the passenger service was run at a net negative, which attracted business to the profitable shipping parts
22:28:22 <floodious> by trying to turn a profit on passenger service, the whole company failed
22:28:57 <floodious> PHB optimization "everything must be a profit!" "cancel/fire the tech-support division!"
22:29:40 <mreow> im not really in american stuff
22:29:51 <floodious> i don't know any euro/asia examples
22:29:56 <mreow> i dont even think we've got amazon here lol
22:29:57 <FLHerne> mreow: The quick-win way to make all the money is to build airports in largeish cities at opposite corners of the map
22:30:00 <mreow> i mean, we've got warehouses
22:30:31 <floodious> mail in ttd pays high, so shipping mail long distances by plane usually makes you instant billions
22:30:45 <FLHerne> Set up buses or trains with "transfer and leave empty" orders at those airports and "no unloading" anywhere else
22:30:49 <FLHerne> Hey, infinite money
22:31:00 <mreow> wait lemme try that
22:31:10 <mreow> hah
22:31:17 <FLHerne> Of course, because it's easy and not really fun once you've one it once, most people don't bother
22:31:55 <floodious> yeah with a real supply/demand economy model, that would fail when your competitors drove passenger service profit to zero margins
22:32:23 <FLHerne> "Competitive" multiplayer servers usually have other metrics, like growing a single town or delivering a given amount of cargo
22:33:11 <FLHerne> And single-player tends to be either "historically accurate" or "just *how* complex can the signalling get?!"
22:33:16 <floodious> another major problem with ttd is the running cost computation isn't fuel-based, so you can climb super high mountains cheaply, it's almost always cheaper to go in a straight line than the long-way-round
22:33:18 <milek7_> i feel that game trying real to have realish economy mode would be too obtuse and boring
22:33:38 <floodious> just like real life!
22:33:54 <FLHerne> I mean, I think most players *do* start by trying to make lots of money
22:33:54 <floodious> where we spend all our time creating models in games to make them more like real life...
22:34:18 <FLHerne> And it's fun, until you've discovered all the ways to do it, and then it's too easy :P
22:34:34 <floodious> lol imagine writing a newgrf that created hobby programmers who you had to supply with ramen + mountain dew to create the openttd inside openttd inside openttd
22:35:24 <floodious> sometimes realistic models bring about a new appreciation for realities and encourage learning though, which some people find very fascinating while sand-box gaming is boring
22:35:27 <floodious> (myself)
22:37:50 <mreow> wut lol is that steam powered plane
22:38:17 <floodious> microsoft's flightsim on steam
22:38:34 <floodious> AKA steam-powered plane
22:38:42 <floodious> ms.steam-powered
22:38:48 <floodious> like ms.pacman
22:39:01 <milek7_> FSX refresh or something new?
22:40:24 <Samu> i found something! line 429 of town_cmd.cpp InvalidateWindowData(WC_TOWN_DIRECTORY, 0, 1);
22:40:39 <Samu> it sets data to 1
22:41:03 <Samu> switch(data) case TDIWD_FILTER_CHANGES:
22:41:08 <Samu> seems wrong
22:41:17 <Samu> there was no filter changes
22:41:41 <Samu> it's using the wrong invalidator, if I'm reading this correctly
22:41:44 *** WormnestAndroid has quit IRC
22:41:53 <floodious> yes i saw that when stepped through, but i have no idea how that's supposed to work
22:42:00 <floodious> it didn't seem to be working correctly
22:42:03 <glx> I guess it's a line from before the filter Samu, so quite possible
22:43:40 <DorpsGek_III> [OpenTTD/OpenTTD] floodious opened issue #7904: Tick-based UpdateWindows() calls use incorrect real-time ms https://git.io/Jejmx
22:44:08 <Samu> it should be calling this->towns.ForceResort();
22:44:25 <Samu> but it's calling this->towns.ForceRebuild();
22:44:43 <glx> let me check the code globally :)
22:48:04 <floodious> samu, so you're adopting my "comment out to fix" stuff? should i post an issue for it too?
22:48:22 <Samu> i wonder how many different "data" values are passed to towndirectory
22:48:41 <glx> Samu: ok I'm checking all calls and fixing where needed
22:51:24 <mreow> openttd is so hypnotising
22:57:06 <glx> Samu: https://github.com/OpenTTD/OpenTTD/compare/master...glx22:town_dir
23:01:31 *** Mazur has quit IRC
23:02:03 <DorpsGek_III> [OpenTTD/OpenTTD] floodious opened issue #7905: TownDirectoryWindow::OnPaint() triggers large (>50ms) redraw times https://git.io/JejYt
23:04:26 *** rtrdd has joined #openttd
23:07:03 *** zvxb has quit IRC
23:07:03 *** rtrdd has quit IRC
23:09:12 <supermop_Home> andythenorth: I still don't see any DVTs, 08s, etc in IH 2.3.0
23:09:24 <supermop_Home> what am i doing wrong here
23:21:21 <floodious> it might be a good idea to replace all the naive c-style uint values with something like a type-safe ticks_t or realtime_ms_t
23:21:22 <Samu> gonna test
23:21:33 <floodious> but that might be a large refactor
23:21:58 <floodious> also might require using structs and operators instead of base types
23:22:36 *** Pikka has joined #openttd
23:22:36 <floodious> since using tick_t = uint32; isn't type-safe, and i'm not aware c++11/etc has any force-type-safety feature for typedef/using
23:22:45 <LordAro> i was gonna say
23:22:57 <LordAro> using structs sounds tedious though
23:23:12 <floodious> it's a pain, why can't they implement a typesafe keyword
23:23:25 <floodious> c++20...
23:23:54 <floodious> the arguments have been "because that's redundant" "we should replace everything like enum class and make it inherently typesafe without the option"
23:24:00 *** WormnestAndroid has joined #openttd
23:24:01 <floodious> 20 years later
23:24:02 <LordAro> C++20 has already been finalised, i think :p
23:24:08 <floodious> i know, gah
23:24:36 <floodious> just add a keyword you buggers... if programmers are using variables named "typesafe" that should be their problem, what a dumb variable name
23:24:40 <LordAro> and i'm not aware of any existing proposal for type safety in that way, which makes C++23 rather unlikely as well
23:24:51 * LordAro hands floodious some _Bools
23:25:03 <glx> yeah and C++17 is still waiting for support ;)
23:25:04 * floodious hands back some ints x = -1
23:25:19 <floodious> _Bool x = -1
23:25:21 <floodious> yey
23:27:03 <Samu> glx, you didn't add a case TDIWD_FILTER_RESORT:, will it use default?
23:27:25 <LordAro> floodious: https://godbolt.org/z/ijtVSD i am a bit disappointed that there isn't even a warning
23:27:28 <glx> yeah it will go to default
23:27:35 <LordAro> Samu: that's how default works, yes
23:27:44 <Samu> ok
23:28:10 * floodious hands LordAro a typedef enum { true = 0, false, maybe } _Bool;
23:30:40 <Samu> glx [img]https://i.imgur.com/FHW1Bpd.png - problem solved!
23:31:28 <LordAro> problem improved, anyway
23:31:30 <DorpsGek_III> [OpenTTD/OpenTTD] glx22 opened pull request #7906: Fix #7899, 196d5868: don't trigger filter changes more than expected https://git.io/JejYP
23:34:02 <DorpsGek_III> [OpenTTD/OpenTTD] LordAro approved pull request #7906: Fix #7899, 196d5868: don't trigger filter changes more than expected https://git.io/JejY1
23:34:33 <andythenorth> supermop_Home: check the 'Joker' parameter?
23:34:37 <andythenorth> it's supposed to default to on
23:34:46 <andythenorth> Pikka bob
23:34:47 <glx> I guess some other windows have similar issue (magic values are bad ;) )
23:34:59 <Pikka> bordig
23:35:07 <andythenorth> I was thinking
23:35:12 <andythenorth> NARS Horse
23:35:12 <Pikka> uhoh
23:35:19 <andythenorth> 1920-1990, and 5x daylength :P
23:35:27 <andythenorth> 4 generations
23:35:33 <andythenorth> :P
23:35:34 *** Samu has quit IRC
23:35:44 <Pikka> why daylength?
23:36:45 <andythenorth> longer game :)
23:37:20 <andythenorth> probably 1.5x would be enough :P
23:38:41 <DorpsGek_III> [OpenTTD/OpenTTD] JGRennison commented on issue #7905: TownDirectoryWindow::OnPaint() triggers large (>50ms) redraw times https://git.io/JejYt
23:41:15 <DorpsGek_III> [OpenTTD/OpenTTD] floodious commented on issue #7905: TownDirectoryWindow::OnPaint() triggers large (>50ms) redraw times https://git.io/JejYt
23:41:27 <Pikka> 4 generations... big steam, huge steam, F7s, GP38s?
23:42:23 <supermop_Home> andythenorth: i don't have such a parameter
23:42:34 <supermop_Home> just roster and capacity
23:46:22 <DorpsGek_III> [OpenTTD/OpenTTD] JGRennison commented on issue #7905: TownDirectoryWindow::OnPaint() triggers large (>50ms) redraw times https://git.io/JejYt
23:46:43 <supermop_Home> andythenorth https://imgur.com/a/fhE3DqR
23:46:44 *** WormnestAndroid has quit IRC
23:46:53 <DorpsGek_III> [OpenTTD/OpenTTD] floodious commented on issue #7905: TownDirectoryWindow::OnPaint() triggers large (>50ms) redraw times https://git.io/JejYt
23:48:03 <DorpsGek_III> [OpenTTD/OpenTTD] floodious commented on issue #7905: TownDirectoryWindow::OnPaint() triggers large (>50ms) redraw times https://git.io/JejYt
23:48:36 *** WormnestAndroid has joined #openttd
23:50:02 <DorpsGek_III> [OpenTTD/OpenTTD] LordAro commented on issue #7905: TownDirectoryWindow::OnPaint() triggers large (>50ms) redraw times https://git.io/JejYt
23:50:04 <DorpsGek_III> [OpenTTD/OpenTTD] nielsmh merged pull request #7900: Add: Highlight item under mouse in file browser https://git.io/Jepid
23:51:30 <DorpsGek_III> [OpenTTD/OpenTTD] LordAro merged pull request #7906: Fix #7899, 196d5868: don't trigger filter changes more than expected https://git.io/JejYP
23:51:31 <DorpsGek_III> [OpenTTD/OpenTTD] LordAro closed issue #7899: Slow framerates with town list window https://git.io/JepK9
23:51:54 <DorpsGek_III> [OpenTTD/OpenTTD] floodious commented on issue #7905: TownDirectoryWindow::OnPaint() triggers large (>50ms) redraw times https://git.io/JejYt
23:54:53 <DorpsGek_III> [OpenTTD/OpenTTD] JGRennison commented on issue #7905: TownDirectoryWindow::OnPaint() triggers large (>50ms) redraw times https://git.io/JejYt
23:55:17 *** mreow has quit IRC
23:56:31 <DorpsGek_III> [OpenTTD/OpenTTD] floodious commented on issue #7905: TownDirectoryWindow::OnPaint() triggers large (>50ms) redraw times https://git.io/JejYt
23:57:28 <andythenorth> supermop_Home: o_O https://dev.openttdcoop.org/attachments/download/9601/2-3-0.png
23:57:47 <andythenorth> Action 14 sometimes gets cached, what happens if you restart OpenTTD?