IRC logs for #openttd on OFTC at 2022-02-12
⏴ go to previous day
00:26:38 *** Kitrana1 has joined #openttd
00:31:35 *** Kitrana has quit IRC (Ping timeout: 480 seconds)
00:40:46 *** sla_ro|master has quit IRC ()
01:39:34 *** yoltid[m] has quit IRC (Server closed connection)
01:39:41 *** yoltid[m] has joined #openttd
01:59:53 *** ChanServ sets mode: +v tokai
02:02:36 *** WormnestAndroid has joined #openttd
02:06:49 *** tokai|noir has quit IRC (Ping timeout: 480 seconds)
02:17:29 *** WormnestAndroid has quit IRC (Read error: No route to host)
02:17:43 *** WormnestAndroid has joined #openttd
03:35:06 *** Wormnest has quit IRC (Quit: Leaving)
03:36:06 *** jeremy[m] has quit IRC (Server closed connection)
03:36:09 *** jeremy[m] has joined #openttd
03:36:22 *** leward[m] has quit IRC (Server closed connection)
03:36:24 *** leward[m] has joined #openttd
04:06:14 *** debdog has quit IRC (Ping timeout: 480 seconds)
04:07:37 *** D-HUND is now known as debdog
05:39:34 *** Soni has quit IRC (Server closed connection)
06:17:58 *** zzy2357[m] has quit IRC (Server closed connection)
06:18:00 *** zzy2357[m] has joined #openttd
07:13:10 *** natalie[m] has quit IRC (Server closed connection)
07:13:15 *** natalie[m] has joined #openttd
07:44:03 *** andythenorth has joined #openttd
07:55:47 *** OsteHovel_ has quit IRC (Quit: Leaving)
07:56:05 *** OsteHovel_ has joined #openttd
07:56:27 *** OsteHovel_ is now known as OsteHovel
07:56:30 *** sla_ro|master has joined #openttd
07:56:50 *** OsteHovel has joined #openttd
07:58:37 *** gelignite has joined #openttd
07:58:45 *** andythenorth has quit IRC (Quit: andythenorth)
08:00:26 *** andythenorth has joined #openttd
08:13:58 *** milek7_ has joined #openttd
08:13:58 *** milek7 has quit IRC (Server closed connection)
08:17:20 <nielsm> wouldn't it make sense to change the return type of this function to an enum actually telling what it means
08:18:05 <nielsm> right now the function name contains zero hint at what true/false returns mean, or rather you'd assume true meant that processing was successful and false that there is some problem with the orders
08:22:08 *** gelignite has quit IRC (Quit: Stay safe!)
08:26:26 *** jottyfan has joined #openttd
08:40:37 <nielsm> but since it actually also calls UpdateOrderDest, maybe it should return (or fill in) a structure about the order updates needed
09:09:58 *** ciet[m] has quit IRC (Server closed connection)
09:10:10 *** ciet[m] has joined #openttd
09:12:54 *** jeeg[m] has quit IRC (Server closed connection)
09:13:09 *** jeeg[m] has joined #openttd
10:15:11 <TrueBrain> hopefully that is not breaking existing workflows, but it shouldn't :P
10:21:30 <TrueBrain> now who dares to approve that PR? :P
10:29:08 *** andythenorth has quit IRC (Quit: andythenorth)
10:36:03 <nielsm> trying to detangle the movement code for ships, which I'd think was about the simplest, and it's already plenty confusing
10:36:05 *** OsteHovel_ has joined #openttd
10:36:36 <nielsm> it seemed like the easiest place to start, since ships have nearly no dependencies on what other vehicles do, only when exiting depots actually
10:41:23 <nielsm> and by detangle I mean strictly split the "decdide what to do" from the "actually do it"
10:41:54 <reldred> what are you thinking with boats?
10:42:36 <nielsm> like just those three lines: check if an action is possible, decide to take it and modify the current state, and then also update the GUI
10:43:08 *** OsteHovel has quit IRC (Ping timeout: 480 seconds)
10:44:08 <nielsm> and then after that, do some more checks for more possible variations of the action, and maybe jump down to the reversing logic
10:44:40 <nielsm> reldred: I'm exploring an idea for parallelising (multithreading) part of the vehicle movement code
10:45:28 <reldred> so we can yell at people who cry about openttd not being multithreaded? :)
10:45:37 <nielsm> the idea is that if the logic to decide what to do can be split from the logic that actually modifies the game state, then the parts deciding what to do can be run multithreaded, and hopefully that can move most of the heavy calculations to parallel processing
10:46:16 <nielsm> in other words, while all vehicles are deciding what to do, none of them modify the world state
10:55:15 <SpComb^> are boats the only vehicles that can do that while remaining deterministic enough for multiplayer?
10:55:32 <nielsm> no, all vehicles should be able to do that
10:55:47 <nielsm> but ships should be easiest to do it with for the first experiment
10:55:58 <SpComb^> isn't there some kind of ordering dependence if two vehicles conflict on exactly the same tick?
10:57:06 <nielsm> I'm splitting the Vehicle::Tick() function into PrepareTick() and ExecuteTick(), such that PrepareTick() must fill in a "plan", and ExecuteTick() must attempt to execute that plan, if it's still possible to do
10:57:33 <nielsm> if ExecutePlan() can't execute the plan because something conflicts, then it returns a "retry" state, and the vehicle gets put back in queue
10:57:59 <nielsm> the PrepareTick() function is run in parallel, but the ExecuteTick() is run in serial (deterministic order)
10:59:23 <_dp_> Tile loop may be another simple target to multithread as tiles are mostly self-contained
10:59:38 <nielsm> that's an entirely separate project
11:00:37 <nielsm> although a thread pool/work queue of sorts is needed for either, and could probably be shared code
11:03:12 <Rubidium> tiles are mostly selfcontained... until it comes to flooding, where they conflict with vehicles. Though growing trees of "greening" bare land should be self-contained
11:04:03 <nielsm> yeah for tiles you'd need to collect all the tiles that need to be serially processed in a list and do those afterwards, or something
11:04:21 <nielsm> I think town building tiles also produce cargo in their tick function
11:04:34 <Rubidium> yes, they do... NewGRF callback
11:05:04 <nielsm> and growing trees check the surrounding tiles for their land/tree status, iirc
11:05:40 <Rubidium> industry tiles produce cargo as well
11:05:41 <_dp_> Rubidium, isn't vehicle just destroyed when it's flooded? that creates no conflict since there is no need to be concerned about that vehicle
11:06:11 <_dp_> well, I guess it may conflict with pathfinder but not in the tile loop itself
11:06:30 *** christoph[m]12 has quit IRC (Server closed connection)
11:06:32 *** christoph[m]12 has joined #openttd
11:06:35 <Rubidium> unless one your computer it hasn't left the to-be-flooded tile yet, and on my computer it has left it (vice versa for entering)
11:06:49 <nielsm> the order the tile loop processes tiles in, could that cause tiles "close enough to matter for tree growth" to be processed in the same tick? I think maybe they won't?
11:07:22 <nielsm> Rubidium: in that case you already have a desync before the tile loop
11:08:03 <nielsm> running the tile loop in parallel with anything other than itself would be a recipe for disaster
11:09:25 <Rubidium> the tile loop is pseudo random, so no guarantees about locality
11:10:15 <_dp_> but that pseudo random is like 1 sequence for the entire game, if not for all games
11:10:18 <nielsm> nah, it's not really random, it uses some specific ordering that guarantees each tile is processed exactly one every 256 ticks
11:10:31 <_dp_> may be possible to make sure it doesn't iterate local
11:11:03 <_dp_> also it applies to chunks of tiles so it may be non-local simply because of those chunks
11:11:21 <_dp_> and even if it's not it can be easily changed
11:11:56 <_dp_> just split into 16x16 chunks and only loop one tile per tick
11:12:01 <_dp_> may already work that way
11:14:36 <nielsm> if I go into the scenario editor on a blank, flat map, and clear 32x32 tiles from the north corner of the map, it looks like that regrows to grass one tile per tick
11:16:32 *** frosch123 has joined #openttd
11:17:52 <_dp_> hm, looks like it's different sequence for each chunk rn...
11:18:32 <_dp_> whatever, even if it's totally random can split into like 8x8 and never tick neighbouring chunks at the same time
11:19:38 <nielsm> the tree growth is one of the major reasons you'd want to parallelise tile ticks, so making sure there won't be conflicts in that is central
11:20:22 <_dp_> well, 8 tiles of distance should be enough to isolate tree growth as I understand it
11:20:35 <Rubidium> trees "only" affect the tiles directly around them (just like water) as far as I can see
11:21:24 <_dp_> btw, flooding is also quite time-consuming
11:21:57 <_dp_> empty 4k water map takes like 10ms each frame just doing "flooding"
11:22:13 <nielsm> oh right, I always forget, the other major reason trees are problematic, maybe even bigger reason: they add a ton of noise to the save game data, making it compress poorly
11:22:21 <_dp_> though that should be possible to optimize even without mt xD
11:23:30 <Rubidium> and maybe tweak it a bit, so there is some more distance between the tiles in the same tick
11:23:46 <_dp_> Rubidium, with 8x8 chunks no need to revert it, just tweak a little
11:23:50 *** pothyurf[m] has quit IRC (Server closed connection)
11:23:58 *** pothyurf[m] has joined #openttd
11:24:17 <nielsm> right, if the tile loop uses the same order for every 256x256 chunk of map, then you could also just put each 256x256 chunk into a job queue for threading
11:24:47 <nielsm> so original size or smaller maps would not multithread, though long maps like 64x1024 would
11:25:42 <Rubidium> not necessarily... is the northern, southern, eastern and western point are "randomly" chosen to be in that iterations set of tiles without a chunck, you still have a big problem
11:28:23 <Rubidium> so you need to split it in for example 64x64 chunks and then group them by their location in a 128x128 block. First run all the northern chunks, then all the southern, etc. That way you can prevent any issues between them
11:28:34 <Rubidium> though it complicates your code a bit
11:29:03 <nielsm> hmm... anyone know the pathfinders enough to know if they are idempotent or they may alter the vehicle state in some cases?
11:30:09 <frosch123> is the tileloop really worth optimising? it's resource usage is pretty much constant during a game
11:30:25 <frosch123> so you already know at game start whether your computer can handle it, or whether you should use a more reasonably sized map
11:30:29 <_dp_> why 64? that's exactly what I said with 8x8, 4 8x8 make 16x16, one tile is iterated per chunk, loop 8x8 sub-chunks is same order every tick, 8x8 can have random order inside
11:30:39 <frosch123> vehicle usage otoh grows during a game
11:30:45 <_dp_> that guarantees at lest 8 tiles of distance between every tile in same tick
11:32:46 <_dp_> frosch123, on large maps it kinda is. it may be static but if takes 1/3 of the frame that's 50% less stuff you can add
11:32:54 <frosch123> nielsm: the pathfinders do not directly change the vehicles, but ofc they cause the vehicles to reverse or pick tracks. the other way around: signal states, track reservations and station slot reservations affect the pathfinders
11:32:54 <_dp_> also it's a relatively easy target
11:32:58 <Rubidium> frosch123: tile loop as well... more industries, more houses, more trees
11:34:03 <frosch123> i accept "more houses". industries are suposed to mostly stay constant. trees are meant to be constant, but probably aren't :)
11:34:23 *** WormnestAndroid has quit IRC (Read error: Connection reset by peer)
11:34:36 *** WormnestAndroid has joined #openttd
11:35:18 <_dp_> hmm... do newgrfs have callbacks that work in a tile loop?
11:35:19 <frosch123> _dp_: i would think tileloop is the hardest thing to change, because there are so many different things in it
11:35:28 <frosch123> vehicles are pretty homogenous ni comparision
11:35:43 <_dp_> not that may and they are all very localized
11:35:59 <_dp_> though newgrfs would complicate that a lot
11:36:03 <Rubidium> frosch123: if you don't use industries they'll roughly stay constant, as there are ones that close. If you use the industries they are significantly less likely to close. So only new industries pop up
11:37:02 <frosch123> Rubidium: iirc there is some "desired amount of industries" in the industry code. they do not open unlimited
11:37:22 <_dp_> yeah, code tries to keep industry density the same
11:37:51 <nielsm> frosch123: as long as the pathfinders can be called as much as I want without affecting world state, I'm fine
11:37:53 <Rubidium> then I must have been spawning a lot of oil rigs in my last serious game ;)
11:38:07 <frosch123> _dp_: the tileloop contains all the animation callbacks, which modify animation state and can also read animations state from other tiles
11:38:12 <michi_cc> YAPF does global caching though to get speed.
11:38:23 <_dp_> oil rigs spawn is pretty much broken
11:38:28 <nielsm> oh... so YAPF is troublesome there
11:38:59 <frosch123> yes, i also expect that running pathfinders in parallel does not really work. the caches would need locking, and that would probably kill the performance
11:39:17 <michi_cc> The cache itself it supposed to be idempotent. If a different processing order results in a different cache contents, it's a bug. Still would need locking of course.
11:39:25 <_dp_> frosch123, if it can't read further than 8 tiles it's not a problem
11:40:00 <Rubidium> pathfinders do not seem to change the state of their vehicles; at least it's all const "Vehicle" * in there (except for CountShipProc. I haven't checked for things that get rid of the constness
11:40:25 <frosch123> _dp_: it may be that 4x4 houses affect exactly 9 tiles :p
11:40:38 <nielsm> yeah updating the path cache would need locking
11:40:43 <frosch123> and 2x2 houses :/ oof
11:41:06 <michi_cc> Path cache would need some read/write locking.
11:41:17 <_dp_> I'm more worried about related objects, that can easily get into trouble especially with perm storage
11:41:40 <frosch123> nielsm: on the plus side, track reservations and signal states are not part of the pf cache (afaik)
11:41:45 <michi_cc> If you don't cache, you don't need to bother with MT performance either :)
11:42:22 <frosch123> _dp_: good point, the animation callback can change the town storage
11:43:41 <frosch123> so yes, from a newgrf pov: parallel drawing yes, parallel vehicle acceleration yes, parallel tileloop hell no
11:44:23 *** Thedarkb1-T60 has joined #openttd
11:44:25 <michi_cc> Put perm storage writes into a queue to be executed in order afterwards?
11:44:40 *** Thedarkb-T60 has quit IRC (Read error: Connection reset by peer)
11:44:44 <_dp_> well, hell no in like 1% of cases
11:44:56 <_dp_> though detecting that would be a pita
11:44:59 <frosch123> michi_cc: newgrf would need memory intrinsics for locking then :p
11:45:05 <michi_cc> With the queue an overlay during the current CB chain to simulate instant writes.
11:45:10 <Rubidium> TileLoop chunking is not going to work... the HOUSE_DESTRUCTION callback is ran from the tile loop, any other house VA can get the nearest house matching some criteria... so the house getting destroyed changes that
11:45:11 <frosch123> imagine a animation callback incrementing a town register
11:46:27 <nielsm> frosch123 good, my idea is that track reservations go into the "plan", and during serial execution of the plans, if a train's planned new reservation will clash with another that was just taken, the train goes back to the "retry" queue
11:46:31 <_dp_> well, there is always an option to lock for callbacks ;)
11:46:41 <Rubidium> town register is still "local"-ish, destroing the last house of a type is global
11:46:59 <michi_cc> Just define NewGRF to have ARM-like memory order, not x86-like order :p
11:47:00 <frosch123> _dp_: locking is not good enough. you also have to sequence them deterministically
11:47:04 <frosch123> otherwise you will desync
11:47:22 <_dp_> yeah, well, there is always an option of that...
11:48:12 <_dp_> loop callback tiles separately basically
11:50:31 <michi_cc> nielsm: This would occasionally result in different train routing from the current state if reservations/signals outside the direct next path segment would change the decision. Might result in more blocked trains in high-throughput scenarios (i.e. balancer style things), but as players can't reliably enforce pathfinding order anyway, you can probably just say "eh what" to it.
11:52:23 <_dp_> actually, even without callbacks TileLoop_Town will need some tweaking as it changes town state
11:57:10 <nielsm> michi_cc: yeah I know it will result in different behaviour for things, that's just a "deal with it" thing
11:57:38 <nielsm> now, can VehicleEnterTileProc implementations alter state... like do any tiles do funny stuff when a vehicle touches them?
11:59:49 <nielsm> VehicleEnter_Track certainly alters the vehicle state
12:00:04 <nielsm> (for trains entering/leaving depot)
12:11:27 <nielsm> and ditto entering bridge tiles
12:11:41 <TrueBrain> owh ... despite smoke-tests working fine .. I forgot that buildx images have to be pushed immediately, as otherwise they are lost in the void .. ugh .. I need to rethink my GitHub Actions workflow :P
12:59:45 <nielsm> I wonder if this ugly, ugly workaround is still really needed, now that ships need to arrive at a docking tile belonging to the station. presumably stations without docks won't have docking tiles either
13:14:05 <nielsm> yeah if a station doesn't have dock facility, the orders list will show "(Can't use station)" in red, and the order gets skipped immediately the dock facility goes away
13:19:23 <frosch123> doesn't look like sf issues still exist :)
13:21:30 *** Alkel_U3 has quit IRC (Quit: maintenance)
13:22:50 *** Alkel_U3 has joined #openttd
13:24:45 <TrueBrain> and where we did port FlySpray bugs, I do not think we ported sf issues over :P
13:25:24 <frosch123> that diff is weird... had_vehicle_of_type is only used for the first-vehicle-arrives-news
13:25:35 <frosch123> so using it in the order code is super weird
13:27:31 *** andythenorth has joined #openttd
13:28:19 <frosch123> hmm, looks like it was used in the past to distinguish buoys from docks
13:29:45 <frosch123> ah, i have a theory: if a buoy was deleted and turned into a grey sign, a ship would have seen it as "not a buoy" and start unloading
13:30:29 <frosch123> nielsm: i think that fix was about arriving at deleted-but-still-grey-sign buoys
13:31:23 *** Gustavo6046 has joined #openttd
13:33:49 <frosch123> it todays code the deleted-buoy case would hit the OT_GOTO_WAYPOINT case 10 lines up
13:33:52 <nielsm> yeah, buoy orders are now waypoint orders, so you can't have a "go to buoy" order anyway
13:33:59 <frosch123> so i think the FACIL_DOCK thing is no longer needed there
13:34:33 <nielsm> ships do still head for deleted buoys until the sign disappears, but they skip to next order once getting within the 3 tile distance
13:35:11 <frosch123> i assume deleted-buoy/waypoint-signs cannot be turned into real stations :)
13:36:12 <andythenorth> hmm who was doing newgrf docks?
13:36:31 <nielsm> if I build a buoy, bomb it, then build a docks where it was, the buoy sign remains and the dock gets its own sign
13:43:25 <_dp_> wonder how well will multithreading work in mp
13:43:41 <_dp_> if server is too good it kinda falls apart once slower clients start dropping
13:43:59 <_dp_> and slower clients probably have less cores
13:44:06 <nielsm> yeah... I'd probably put a client setting for max threads to use
13:44:32 <nielsm> ("client" setting, also applicable to servers, but not a game setting)
13:45:16 <nielsm> also so if you run multiple servers on the same hardware, you can prevent them from all trying to use all the threads
13:48:52 <_dp_> yeah, also I'm kinda afraid of mt support making it less performant per thread
13:49:13 <_dp_> so with multiple servers it will need better hardware to run the ssame
13:51:52 <_dp_> though maybe ppl will stop spamming those useless servers :p
14:03:08 <_dp_> on the other hand, mt should be better at spreading the load across servers
14:21:33 <peter1138> Oops, I did a ride, and then I did a (bit of) cake.
14:28:08 <nielsm> am I reading right that the ShipAccelerate function returns false if the ship does not have enough "accumulated movement" to actually move in the world?
14:28:36 <nielsm> or just false if the ship is at zero speed for some reason?
14:28:44 <andythenorth> @peter1138 can't do newgrf docks on a bike :P
14:29:40 <nielsm> Vehicle::progress is the "sub-pixel" movement?
14:33:10 <peter1138> andythenorth, nice, all hand drawn or algorithmic?
14:35:17 <andythenorth> hand drawn, but with compositing
14:36:14 *** AlbertSteve[m] has joined #openttd
14:41:57 <frosch123> nielsm: yes, progress is increase every tick. when it wraps around the vehicle moves a world coordinate
14:42:06 <frosch123> however, sometimes "progress" is just reset back to zero
14:42:15 <frosch123> so it's not really monotonous
14:45:18 <nielsm> pushed a WIP code dump here, just if anyone cares to look how I'm trying to structure it
15:25:07 *** andythenorth has quit IRC (Quit: andythenorth)
15:31:25 *** glx is now known as Guest192
15:31:25 *** ChanServ sets mode: +v glx_
15:32:49 *** andythenorth has joined #openttd
15:33:33 *** Guest192 has quit IRC (Ping timeout: 480 seconds)
15:36:49 *** Smedles has joined #openttd
15:37:27 <peter1138> I remember I once split ticks into vehicle types and it was faster for me, but slower for others...
15:48:02 <nielsm> it's probably situational
15:49:48 <nielsm> I've been thinking it might overall be better for performance and memory usage to have separate pools for each vehicle type, doing large block allocations for in-place construction, but that could be troublesome for the VehicleID management
15:57:31 *** jottyfan has quit IRC (Quit: jottyfan)
16:12:01 <nielsm> hmm, implicit orders are a bit troublesome here, if two vehicles sharing orders arrive at a station at the same tick, and maybe both want to add an implicit order, or maybe one wants to add and the other wants to remove, what happens then
16:18:53 <frosch123> pool item creation must be sequenced deterministically, so can't really parallelise that
16:22:34 <nielsm> how is it handled currently when vehicle A reaches a new station that turns into an implicit order, and vehicle B sharing orders with A is on a later order index, does vehicle A then insert the new implicit order and update the current_implicit_order_index on all vehicles sharing orders?
16:25:50 <nielsm> hmm... I guess maybe the planning part doesn't really need to handle orders, it just needs to figure out what the new destination is, if any
16:26:08 <nielsm> so walk but don't modify (or plan to modify) the orders list
16:36:19 <FLHerne> just remove implicit orders from the game :p
16:36:34 <FLHerne> all they do is confuse newbies and break CargoDist
16:36:58 <nielsm> more like, they were added because cargodist needs them for the capacity planning
16:37:16 <FLHerne> well, I mean remove implicit stops in general
16:37:27 <FLHerne> I'm sure the SRNW people will be sad
16:40:14 <_dp_> remove cargodist while at it :p
17:26:47 <Eddi|zuHause> the only way to sensibly remove implicit stops is to make all orders non-stop
17:29:45 <Eddi|zuHause> there could certainly be improvements in handling implicit orders, but i never really played with them, or my networks were always too "sane"
17:44:20 *** Wormnest has joined #openttd
17:49:47 <andythenorth> cargodist considered harmful?
17:50:07 <TrueBrain> isn't any aspect of OpenTTD considered harmful at some point in time?
17:52:59 *** Flygon has quit IRC (Quit: A toaster's basically a soldering iron designed to toast bread)
18:10:10 <nielsm> union { OrderList *orders; Order *old_orders; };
18:10:24 <nielsm> afaik they then just appear right in the enclosing namespace (i.e. the class)
18:11:47 <frosch123> is there a reason it's a union? does the savegames do pointer magic that relies on them being on the same address?
18:16:22 <TrueBrain> the conversion code reads really weird because of the union :P
18:16:33 <nielsm> but I suppose saving those 8 bytes of memory per vehicle for something only used by a tiny minority of players, very rarely, for less than a second at a time, makes some sense
18:16:36 <TrueBrain> BuT iT sAvEs A pOiNtEr
18:17:10 <TrueBrain> but, you can always read the old value in a global value, as many other conversions do
18:18:04 <TrueBrain> currently the orders are fixed in an afterload function, which already loaded all vehicles
18:18:08 <nielsm> I think it fills all the vehicle structures and then fixes up the orders, not loads one vehicle then fixes its orders
18:18:13 <TrueBrain> but I guess you can fix it up per vehicle too; we do that on many other places :)
18:18:19 <nielsm> I think all vehicles+orders need to be loaded before it's possible
18:18:42 <nielsm> since it probably has to do with shared orders resolution and such
18:18:50 <TrueBrain> v->AddToShared(v->orders.list->GetFirstSharedVehicle());
18:23:10 <nielsm> orders.old is referenced in total 5 lines
19:28:17 *** jottyfan has joined #openttd
19:59:38 *** andythenorth has quit IRC (Quit: andythenorth)
20:04:08 *** andythenorth has joined #openttd
20:44:04 *** snail_UES_ has joined #openttd
21:15:42 *** jottyfan has quit IRC (Quit: jottyfan)
21:50:58 *** snail_UES_ has quit IRC (Quit: snail_UES_)
22:11:07 *** frosch123 has quit IRC (Quit: be yourself, except: if you have the opportunity to be a unicorn, then be a unicorn)
22:35:43 *** sla_ro|master has quit IRC ()
23:17:48 *** nielsm has quit IRC (Ping timeout: 480 seconds)
23:23:13 *** snail_UES_ has joined #openttd
23:27:44 *** andythenorth has quit IRC (Quit: andythenorth)
continue to next day ⏵